From 7ad2b536c21f906c2a75bb773ceefa143eb56f11 Mon Sep 17 00:00:00 2001 From: Anton Staykov Date: Fri, 12 Jun 2026 11:46:29 +0200 Subject: [PATCH 1/4] Refreshed demo content --- build/demo-report/New-DemoReport.ps1 | 131 ++++++++++++++++++++++++++- src/react/static/demo/index.html | 20 ++-- 2 files changed, 143 insertions(+), 8 deletions(-) diff --git a/build/demo-report/New-DemoReport.ps1 b/build/demo-report/New-DemoReport.ps1 index 399b6614fd..3f7b41ffb3 100644 --- a/build/demo-report/New-DemoReport.ps1 +++ b/build/demo-report/New-DemoReport.ps1 @@ -30,7 +30,17 @@ param( [string]$InputJsonPath, [Parameter(Mandatory = $true)] - [string]$OutputHtmlPath + [string]$OutputHtmlPath, + + # Optional secondary report. When supplied, the Network and AI pillars (all + # their tests + the matching summary counts) are overlaid from this report, + # replacing that data in the primary -InputJsonPath. Everything else + # (Identity / Devices / Data / SecOps, tenant identity, dashboard overview) + # is kept from the primary report. Brought tests are fully scrubbed of the + # source tenant's identifiers (emails, IPs, domain, brand, GUID). + [Parameter(Mandatory = $false)] + [ValidateScript({ Test-Path $_ -PathType Leaf })] + [string]$SourceJsonPath ) # Set up paths @@ -76,6 +86,125 @@ Write-Host "Loading JSON report from: $InputJsonPath" -ForegroundColor Cyan # Load the JSON report $jsonContent = Get-Content -Path $InputJsonPath -Raw | ConvertFrom-Json -Depth 100 +# --------------------------------------------------------------------------- +# Optional: overlay the Network + AI pillars from a secondary source report. +# Real exports often have far richer Network (Global Secure Access / Internet +# Access) and AI pillars than the curated demo input. When -SourceJsonPath is +# supplied we drop the primary report's Network/AI tests, bring in every +# Network/AI test from the source, and copy the matching summary counts. This +# also drives the home-page SWG defense-layer graphic, which keys off specific +# Network TestIds. +# +# Because the source is a *real* tenant, every brought test is fully scrubbed +# here (emails -> demouser@contoso.com, IPv4 -> 203.0.113.x, tenant +# domain/brand/GUID -> Contoso) before it is merged, in addition to the normal +# anonymization passes that run later. +# --------------------------------------------------------------------------- +if ($PSBoundParameters.ContainsKey('SourceJsonPath')) { + $bringPillars = @('Network', 'AI') + Write-Host ("Overlaying {0} pillar(s) from source: {1}" -f ($bringPillars -join ' + '), $SourceJsonPath) -ForegroundColor Cyan + $sourceContent = Get-Content -Path $SourceJsonPath -Raw | ConvertFrom-Json -Depth 100 + + function Get-PillarSet { + param($Test) + $p = $Test.TestPillar + if ($null -eq $p) { return @() } + if ($p -is [System.Array]) { return @($p) } + return @($p) + } + + $isBrought = { + param($test) + $pillars = Get-PillarSet $test + foreach ($x in $pillars) { if ($bringPillars -contains $x) { return $true } } + return $false + } + + $keptTests = @($jsonContent.Tests | Where-Object { -not (& $isBrought $_) }) + $broughtTests = @($sourceContent.Tests | Where-Object { & $isBrought $_ }) + + # Re-tag brought tests to the intersection of their pillars and the pillars + # we overlay. This drops non-brought tags (e.g. "Data" on a ["Data","AI"] + # test, so it doesn't surface on the sample-owned Data page) while keeping + # brought tags (e.g. a ["Network","AI"] test stays on both pages). + foreach ($test in $broughtTests) { + $kept = @(Get-PillarSet $test | Where-Object { $bringPillars -contains $_ }) + $test.TestPillar = if ($kept.Count -eq 1) { $kept[0] } else { $kept } + } + + # --- Full scrub of source-derived (real tenant) content --- + $demoTenantId = 'aaaabbbb-0000-cccc-1111-dddd2222eeee' + $srcTenantId = [string]$sourceContent.TenantId + $srcDomain = [string]$sourceContent.Domain + $srcName = [string]$sourceContent.TenantName + $srcBrand = if ($srcDomain -match '^([^.]+)\.') { $matches[1] } else { $srcName } + + $script:__emailAliases = @{} + $script:__emailNext = 1 + $script:__ipAliases = @{} + $script:__ipNext = 10 + + $scrub = { + param([string]$text) + if ([string]::IsNullOrEmpty($text)) { return $text } + + # Emails -> deterministic demouser@contoso.com (leave demo/Microsoft as-is). + $text = [regex]::Replace($text, '[A-Za-z0-9._%+\-]+@[A-Za-z0-9.\-]+\.[A-Za-z]{2,}', { + param($m) + $e = $m.Value + if ($e -match '(?i)@(contoso\.com|contoso\.onmicrosoft\.com|microsoft\.com)$') { return $e } + if (-not $script:__emailAliases.ContainsKey($e)) { + $script:__emailAliases[$e] = "demouser$($script:__emailNext)@contoso.com" + $script:__emailNext++ + } + return $script:__emailAliases[$e] + }) + + # IPv4 -> deterministic TEST-NET (RFC 5737) 203.0.113.x. + $text = [regex]::Replace($text, '\b(?:\d{1,3}\.){3}\d{1,3}\b', { + param($m) + $ip = $m.Value + if (-not $script:__ipAliases.ContainsKey($ip)) { + $script:__ipAliases[$ip] = "203.0.113.$($script:__ipNext)" + $script:__ipNext++ + } + return $script:__ipAliases[$ip] + }) + + if ($srcTenantId) { $text = $text -replace [regex]::Escape($srcTenantId), $demoTenantId } + # Any onmicrosoft tenant remnants -> contoso.onmicrosoft.com. + $text = $text -replace '(?i)[A-Za-z0-9-]+\.onmicrosoft\.com', 'contoso.onmicrosoft.com' + # Remaining references to the source domain (URLs, bare host names) -> contoso.com. + if ($srcDomain) { $text = $text -replace ('(?i)[A-Za-z0-9.\-]*' + [regex]::Escape($srcDomain)), 'contoso.com' } + if ($srcName) { $text = $text -replace ('(?i)' + [regex]::Escape($srcName)), 'Contoso' } + if ($srcBrand) { $text = $text -replace ('(?i)\b' + [regex]::Escape($srcBrand) + '\b'), 'contoso' } + + return $text + } + + foreach ($test in $broughtTests) { + foreach ($field in 'TestResult', 'TestDescription', 'SkippedReason') { + if (($test.PSObject.Properties.Name -contains $field) -and ($test.$field -is [string])) { + $test.$field = & $scrub $test.$field + } + } + } + + $jsonContent.Tests = @($keptTests + $broughtTests) + + # Overlay the summary counts for each brought pillar. + foreach ($pil in $bringPillars) { + $jsonContent.TestResultSummary."${pil}Passed" = $sourceContent.TestResultSummary."${pil}Passed" + $jsonContent.TestResultSummary."${pil}Total" = $sourceContent.TestResultSummary."${pil}Total" + } + + Write-Host ("Brought {0} test(s) across {1}; scrubbed {2} email(s) and {3} IP(s)" -f ` + $broughtTests.Count, ($bringPillars -join '/'), $script:__emailAliases.Count, $script:__ipAliases.Count) -ForegroundColor Cyan + foreach ($pil in $bringPillars) { + Write-Host (" {0} summary now {1}/{2}" -f $pil, $jsonContent.TestResultSummary."${pil}Passed", $jsonContent.TestResultSummary."${pil}Total") -ForegroundColor Cyan + } +} + Write-Host "Anonymizing report data..." -ForegroundColor Cyan # Anonymize tenant information diff --git a/src/react/static/demo/index.html b/src/react/static/demo/index.html index 180331f887..1acaf6b006 100644 --- a/src/react/static/demo/index.html +++ b/src/react/static/demo/index.html @@ -16,9 +16,9 @@ `),f2=d.stack.split(` `),g2=e3.length-1,h2=f2.length-1;1<=g2&&0<=h2&&e3[g2]!==f2[h2];)h2--;for(;1<=g2&&0<=h2;g2--,h2--)if(e3[g2]!==f2[h2]){if(g2!==1||h2!==1)do if(g2--,h2--,0>h2||e3[g2]!==f2[h2]){var k2=` `+e3[g2].replace(" at new "," at ");return a2.displayName&&k2.includes("")&&(k2=k2.replace("",a2.displayName)),k2}while(1<=g2&&0<=h2);break}}}finally{Na=!1,Error.prepareStackTrace=c2}return(a2=a2?a2.displayName||a2.name:"")?Ma(a2):""}__name(Oa,"Oa");function Pa(a2){switch(a2.tag){case 5:return Ma(a2.type);case 16:return Ma("Lazy");case 13:return Ma("Suspense");case 19:return Ma("SuspenseList");case 0:case 2:case 15:return a2=Oa(a2.type,!1),a2;case 11:return a2=Oa(a2.type.render,!1),a2;case 1:return a2=Oa(a2.type,!0),a2;default:return""}}__name(Pa,"Pa");function Qa(a2){if(a2==null)return null;if(typeof a2=="function")return a2.displayName||a2.name||null;if(typeof a2=="string")return a2;switch(a2){case ya:return"Fragment";case wa:return"Portal";case Aa:return"Profiler";case za:return"StrictMode";case Ea:return"Suspense";case Fa:return"SuspenseList"}if(typeof a2=="object")switch(a2.$$typeof){case Ca:return(a2.displayName||"Context")+".Consumer";case Ba:return(a2._context.displayName||"Context")+".Provider";case Da:var b2=a2.render;return a2=a2.displayName,a2||(a2=b2.displayName||b2.name||"",a2=a2!==""?"ForwardRef("+a2+")":"ForwardRef"),a2;case Ga:return b2=a2.displayName||null,b2!==null?b2:Qa(a2.type)||"Memo";case Ha:b2=a2._payload,a2=a2._init;try{return Qa(a2(b2))}catch{}}return null}__name(Qa,"Qa");function Ra(a2){var b2=a2.type;switch(a2.tag){case 24:return"Cache";case 9:return(b2.displayName||"Context")+".Consumer";case 10:return(b2._context.displayName||"Context")+".Provider";case 18:return"DehydratedFragment";case 11:return a2=b2.render,a2=a2.displayName||a2.name||"",b2.displayName||(a2!==""?"ForwardRef("+a2+")":"ForwardRef");case 7:return"Fragment";case 5:return b2;case 4:return"Portal";case 3:return"Root";case 6:return"Text";case 16:return Qa(b2);case 8:return b2===za?"StrictMode":"Mode";case 22:return"Offscreen";case 12:return"Profiler";case 21:return"Scope";case 13:return"Suspense";case 19:return"SuspenseList";case 25:return"TracingMarker";case 1:case 0:case 17:case 2:case 14:case 15:if(typeof b2=="function")return b2.displayName||b2.name||null;if(typeof b2=="string")return b2}return null}__name(Ra,"Ra");function Sa(a2){switch(typeof a2){case"boolean":case"number":case"string":case"undefined":return a2;case"object":return a2;default:return""}}__name(Sa,"Sa");function Ta(a2){var b2=a2.type;return(a2=a2.nodeName)&&a2.toLowerCase()==="input"&&(b2==="checkbox"||b2==="radio")}__name(Ta,"Ta");function Ua(a2){var b2=Ta(a2)?"checked":"value",c2=Object.getOwnPropertyDescriptor(a2.constructor.prototype,b2),d=""+a2[b2];if(!a2.hasOwnProperty(b2)&&typeof c2<"u"&&typeof c2.get=="function"&&typeof c2.set=="function"){var e3=c2.get,f2=c2.set;return Object.defineProperty(a2,b2,{configurable:!0,get:__name(function(){return e3.call(this)},"get"),set:__name(function(a3){d=""+a3,f2.call(this,a3)},"set")}),Object.defineProperty(a2,b2,{enumerable:c2.enumerable}),{getValue:__name(function(){return d},"getValue"),setValue:__name(function(a3){d=""+a3},"setValue"),stopTracking:__name(function(){a2._valueTracker=null,delete a2[b2]},"stopTracking")}}}__name(Ua,"Ua");function Va(a2){a2._valueTracker||(a2._valueTracker=Ua(a2))}__name(Va,"Va");function Wa(a2){if(!a2)return!1;var b2=a2._valueTracker;if(!b2)return!0;var c2=b2.getValue(),d="";return a2&&(d=Ta(a2)?a2.checked?"true":"false":a2.value),a2=d,a2!==c2?(b2.setValue(a2),!0):!1}__name(Wa,"Wa");function Xa(a2){if(a2=a2||(typeof document<"u"?document:void 0),typeof a2>"u")return null;try{return a2.activeElement||a2.body}catch{return a2.body}}__name(Xa,"Xa");function Ya(a2,b2){var c2=b2.checked;return A2({},b2,{defaultChecked:void 0,defaultValue:void 0,value:void 0,checked:c2??a2._wrapperState.initialChecked})}__name(Ya,"Ya");function Za(a2,b2){var c2=b2.defaultValue==null?"":b2.defaultValue,d=b2.checked!=null?b2.checked:b2.defaultChecked;c2=Sa(b2.value!=null?b2.value:c2),a2._wrapperState={initialChecked:d,initialValue:c2,controlled:b2.type==="checkbox"||b2.type==="radio"?b2.checked!=null:b2.value!=null}}__name(Za,"Za");function ab(a2,b2){b2=b2.checked,b2!=null&&ta(a2,"checked",b2,!1)}__name(ab,"ab");function bb(a2,b2){ab(a2,b2);var c2=Sa(b2.value),d=b2.type;if(c2!=null)d==="number"?(c2===0&&a2.value===""||a2.value!=c2)&&(a2.value=""+c2):a2.value!==""+c2&&(a2.value=""+c2);else if(d==="submit"||d==="reset"){a2.removeAttribute("value");return}b2.hasOwnProperty("value")?cb(a2,b2.type,c2):b2.hasOwnProperty("defaultValue")&&cb(a2,b2.type,Sa(b2.defaultValue)),b2.checked==null&&b2.defaultChecked!=null&&(a2.defaultChecked=!!b2.defaultChecked)}__name(bb,"bb");function db(a2,b2,c2){if(b2.hasOwnProperty("value")||b2.hasOwnProperty("defaultValue")){var d=b2.type;if(!(d!=="submit"&&d!=="reset"||b2.value!==void 0&&b2.value!==null))return;b2=""+a2._wrapperState.initialValue,c2||b2===a2.value||(a2.value=b2),a2.defaultValue=b2}c2=a2.name,c2!==""&&(a2.name=""),a2.defaultChecked=!!a2._wrapperState.initialChecked,c2!==""&&(a2.name=c2)}__name(db,"db");function cb(a2,b2,c2){(b2!=="number"||Xa(a2.ownerDocument)!==a2)&&(c2==null?a2.defaultValue=""+a2._wrapperState.initialValue:a2.defaultValue!==""+c2&&(a2.defaultValue=""+c2))}__name(cb,"cb");var eb=Array.isArray;function fb(a2,b2,c2,d){if(a2=a2.options,b2){b2={};for(var e3=0;e3"+b2.valueOf().toString()+"",b2=mb.firstChild;a2.firstChild;)a2.removeChild(a2.firstChild);for(;b2.firstChild;)a2.appendChild(b2.firstChild)}});function ob(a2,b2){if(b2){var c2=a2.firstChild;if(c2&&c2===a2.lastChild&&c2.nodeType===3){c2.nodeValue=b2;return}}a2.textContent=b2}__name(ob,"ob");var pb={animationIterationCount:!0,aspectRatio:!0,borderImageOutset:!0,borderImageSlice:!0,borderImageWidth:!0,boxFlex:!0,boxFlexGroup:!0,boxOrdinalGroup:!0,columnCount:!0,columns:!0,flex:!0,flexGrow:!0,flexPositive:!0,flexShrink:!0,flexNegative:!0,flexOrder:!0,gridArea:!0,gridRow:!0,gridRowEnd:!0,gridRowSpan:!0,gridRowStart:!0,gridColumn:!0,gridColumnEnd:!0,gridColumnSpan:!0,gridColumnStart:!0,fontWeight:!0,lineClamp:!0,lineHeight:!0,opacity:!0,order:!0,orphans:!0,tabSize:!0,widows:!0,zIndex:!0,zoom:!0,fillOpacity:!0,floodOpacity:!0,stopOpacity:!0,strokeDasharray:!0,strokeDashoffset:!0,strokeMiterlimit:!0,strokeOpacity:!0,strokeWidth:!0},qb=["Webkit","ms","Moz","O"];Object.keys(pb).forEach(function(a2){qb.forEach(function(b2){b2=b2+a2.charAt(0).toUpperCase()+a2.substring(1),pb[b2]=pb[a2]})});function rb(a2,b2,c2){return b2==null||typeof b2=="boolean"||b2===""?"":c2||typeof b2!="number"||b2===0||pb.hasOwnProperty(a2)&&pb[a2]?(""+b2).trim():b2+"px"}__name(rb,"rb");function sb(a2,b2){a2=a2.style;for(var c2 in b2)if(b2.hasOwnProperty(c2)){var d=c2.indexOf("--")===0,e3=rb(c2,b2[c2],d);c2==="float"&&(c2="cssFloat"),d?a2.setProperty(c2,e3):a2[c2]=e3}}__name(sb,"sb");var tb=A2({menuitem:!0},{area:!0,base:!0,br:!0,col:!0,embed:!0,hr:!0,img:!0,input:!0,keygen:!0,link:!0,meta:!0,param:!0,source:!0,track:!0,wbr:!0});function ub(a2,b2){if(b2){if(tb[a2]&&(b2.children!=null||b2.dangerouslySetInnerHTML!=null))throw Error(p2(137,a2));if(b2.dangerouslySetInnerHTML!=null){if(b2.children!=null)throw Error(p2(60));if(typeof b2.dangerouslySetInnerHTML!="object"||!("__html"in b2.dangerouslySetInnerHTML))throw Error(p2(61))}if(b2.style!=null&&typeof b2.style!="object")throw Error(p2(62))}}__name(ub,"ub");function vb(a2,b2){if(a2.indexOf("-")===-1)return typeof b2.is=="string";switch(a2){case"annotation-xml":case"color-profile":case"font-face":case"font-face-src":case"font-face-uri":case"font-face-format":case"font-face-name":case"missing-glyph":return!1;default:return!0}}__name(vb,"vb");var wb=null;function xb(a2){return a2=a2.target||a2.srcElement||window,a2.correspondingUseElement&&(a2=a2.correspondingUseElement),a2.nodeType===3?a2.parentNode:a2}__name(xb,"xb");var yb=null,zb=null,Ab=null;function Bb(a2){if(a2=Cb(a2)){if(typeof yb!="function")throw Error(p2(280));var b2=a2.stateNode;b2&&(b2=Db(b2),yb(a2.stateNode,a2.type,b2))}}__name(Bb,"Bb");function Eb(a2){zb?Ab?Ab.push(a2):Ab=[a2]:zb=a2}__name(Eb,"Eb");function Fb(){if(zb){var a2=zb,b2=Ab;if(Ab=zb=null,Bb(a2),b2)for(a2=0;a2>>=0,a2===0?32:31-(pc(a2)/qc|0)|0}__name(nc,"nc");var rc=64,sc=4194304;function tc(a2){switch(a2&-a2){case 1:return 1;case 2:return 2;case 4:return 4;case 8:return 8;case 16:return 16;case 32:return 32;case 64:case 128:case 256:case 512:case 1024:case 2048:case 4096:case 8192:case 16384:case 32768:case 65536:case 131072:case 262144:case 524288:case 1048576:case 2097152:return a2&4194240;case 4194304:case 8388608:case 16777216:case 33554432:case 67108864:return a2&130023424;case 134217728:return 134217728;case 268435456:return 268435456;case 536870912:return 536870912;case 1073741824:return 1073741824;default:return a2}}__name(tc,"tc");function uc(a2,b2){var c2=a2.pendingLanes;if(c2===0)return 0;var d=0,e3=a2.suspendedLanes,f2=a2.pingedLanes,g2=c2&268435455;if(g2!==0){var h2=g2&~e3;h2!==0?d=tc(h2):(f2&=g2,f2!==0&&(d=tc(f2)))}else g2=c2&~e3,g2!==0?d=tc(g2):f2!==0&&(d=tc(f2));if(d===0)return 0;if(b2!==0&&b2!==d&&(b2&e3)===0&&(e3=d&-d,f2=b2&-b2,e3>=f2||e3===16&&(f2&4194240)!==0))return b2;if((d&4)!==0&&(d|=c2&16),b2=a2.entangledLanes,b2!==0)for(a2=a2.entanglements,b2&=d;0c2;c2++)b2.push(a2);return b2}__name(zc,"zc");function Ac(a2,b2,c2){a2.pendingLanes|=b2,b2!==536870912&&(a2.suspendedLanes=0,a2.pingedLanes=0),a2=a2.eventTimes,b2=31-oc(b2),a2[b2]=c2}__name(Ac,"Ac");function Bc(a2,b2){var c2=a2.pendingLanes&~b2;a2.pendingLanes=b2,a2.suspendedLanes=0,a2.pingedLanes=0,a2.expiredLanes&=b2,a2.mutableReadLanes&=b2,a2.entangledLanes&=b2,b2=a2.entanglements;var d=a2.eventTimes;for(a2=a2.expirationTimes;0=be2),ee=" ",fe2=!1;function ge2(a2,b2){switch(a2){case"keyup":return $d.indexOf(b2.keyCode)!==-1;case"keydown":return b2.keyCode!==229;case"keypress":case"mousedown":case"focusout":return!0;default:return!1}}__name(ge2,"ge");function he2(a2){return a2=a2.detail,typeof a2=="object"&&"data"in a2?a2.data:null}__name(he2,"he");var ie=!1;function je2(a2,b2){switch(a2){case"compositionend":return he2(b2);case"keypress":return b2.which!==32?null:(fe2=!0,ee);case"textInput":return a2=b2.data,a2===ee&&fe2?null:a2;default:return null}}__name(je2,"je");function ke2(a2,b2){if(ie)return a2==="compositionend"||!ae2&&ge2(a2,b2)?(a2=nd(),md=ld=kd=null,ie=!1,a2):null;switch(a2){case"paste":return null;case"keypress":if(!(b2.ctrlKey||b2.altKey||b2.metaKey)||b2.ctrlKey&&b2.altKey){if(b2.char&&1=b2)return{node:c2,offset:b2-a2};a2=d}a:{for(;c2;){if(c2.nextSibling){c2=c2.nextSibling;break a}c2=c2.parentNode}c2=void 0}c2=Je2(c2)}}__name(Ke2,"Ke");function Le2(a2,b2){return a2&&b2?a2===b2?!0:a2&&a2.nodeType===3?!1:b2&&b2.nodeType===3?Le2(a2,b2.parentNode):"contains"in a2?a2.contains(b2):a2.compareDocumentPosition?!!(a2.compareDocumentPosition(b2)&16):!1:!1}__name(Le2,"Le");function Me2(){for(var a2=window,b2=Xa();b2 instanceof a2.HTMLIFrameElement;){try{var c2=typeof b2.contentWindow.location.href=="string"}catch{c2=!1}if(c2)a2=b2.contentWindow;else break;b2=Xa(a2.document)}return b2}__name(Me2,"Me");function Ne(a2){var b2=a2&&a2.nodeName&&a2.nodeName.toLowerCase();return b2&&(b2==="input"&&(a2.type==="text"||a2.type==="search"||a2.type==="tel"||a2.type==="url"||a2.type==="password")||b2==="textarea"||a2.contentEditable==="true")}__name(Ne,"Ne");function Oe2(a2){var b2=Me2(),c2=a2.focusedElem,d=a2.selectionRange;if(b2!==c2&&c2&&c2.ownerDocument&&Le2(c2.ownerDocument.documentElement,c2)){if(d!==null&&Ne(c2)){if(b2=d.start,a2=d.end,a2===void 0&&(a2=b2),"selectionStart"in c2)c2.selectionStart=b2,c2.selectionEnd=Math.min(a2,c2.value.length);else if(a2=(b2=c2.ownerDocument||document)&&b2.defaultView||window,a2.getSelection){a2=a2.getSelection();var e3=c2.textContent.length,f2=Math.min(d.start,e3);d=d.end===void 0?f2:Math.min(d.end,e3),!a2.extend&&f2>d&&(e3=d,d=f2,f2=e3),e3=Ke2(c2,f2);var g2=Ke2(c2,d);e3&&g2&&(a2.rangeCount!==1||a2.anchorNode!==e3.node||a2.anchorOffset!==e3.offset||a2.focusNode!==g2.node||a2.focusOffset!==g2.offset)&&(b2=b2.createRange(),b2.setStart(e3.node,e3.offset),a2.removeAllRanges(),f2>d?(a2.addRange(b2),a2.extend(g2.node,g2.offset)):(b2.setEnd(g2.node,g2.offset),a2.addRange(b2)))}}for(b2=[],a2=c2;a2=a2.parentNode;)a2.nodeType===1&&b2.push({element:a2,left:a2.scrollLeft,top:a2.scrollTop});for(typeof c2.focus=="function"&&c2.focus(),c2=0;c2=document.documentMode,Qe2=null,Re2=null,Se=null,Te2=!1;function Ue2(a2,b2,c2){var d=c2.window===c2?c2.document:c2.nodeType===9?c2:c2.ownerDocument;Te2||Qe2==null||Qe2!==Xa(d)||(d=Qe2,"selectionStart"in d&&Ne(d)?d={start:d.selectionStart,end:d.selectionEnd}:(d=(d.ownerDocument&&d.ownerDocument.defaultView||window).getSelection(),d={anchorNode:d.anchorNode,anchorOffset:d.anchorOffset,focusNode:d.focusNode,focusOffset:d.focusOffset}),Se&&Ie(Se,d)||(Se=d,d=oe(Re2,"onSelect"),0Tf||(a2.current=Sf[Tf],Sf[Tf]=null,Tf--)}__name(E2,"E");function G(a2,b2){Tf++,Sf[Tf]=a2.current,a2.current=b2}__name(G,"G");var Vf={},H=Uf(Vf),Wf=Uf(!1),Xf=Vf;function Yf(a2,b2){var c2=a2.type.contextTypes;if(!c2)return Vf;var d=a2.stateNode;if(d&&d.__reactInternalMemoizedUnmaskedChildContext===b2)return d.__reactInternalMemoizedMaskedChildContext;var e3={},f2;for(f2 in c2)e3[f2]=b2[f2];return d&&(a2=a2.stateNode,a2.__reactInternalMemoizedUnmaskedChildContext=b2,a2.__reactInternalMemoizedMaskedChildContext=e3),e3}__name(Yf,"Yf");function Zf(a2){return a2=a2.childContextTypes,a2!=null}__name(Zf,"Zf");function $f(){E2(Wf),E2(H)}__name($f,"$f");function ag(a2,b2,c2){if(H.current!==Vf)throw Error(p2(168));G(H,b2),G(Wf,c2)}__name(ag,"ag");function bg(a2,b2,c2){var d=a2.stateNode;if(b2=b2.childContextTypes,typeof d.getChildContext!="function")return c2;d=d.getChildContext();for(var e3 in d)if(!(e3 in b2))throw Error(p2(108,Ra(a2)||"Unknown",e3));return A2({},c2,d)}__name(bg,"bg");function cg(a2){return a2=(a2=a2.stateNode)&&a2.__reactInternalMemoizedMergedChildContext||Vf,Xf=H.current,G(H,a2),G(Wf,Wf.current),!0}__name(cg,"cg");function dg(a2,b2,c2){var d=a2.stateNode;if(!d)throw Error(p2(169));c2?(a2=bg(a2,b2,Xf),d.__reactInternalMemoizedMergedChildContext=a2,E2(Wf),E2(H),G(H,a2)):E2(Wf),G(Wf,c2)}__name(dg,"dg");var eg=null,fg=!1,gg=!1;function hg(a2){eg===null?eg=[a2]:eg.push(a2)}__name(hg,"hg");function ig(a2){fg=!0,hg(a2)}__name(ig,"ig");function jg(){if(!gg&&eg!==null){gg=!0;var a2=0,b2=C2;try{var c2=eg;for(C2=1;a2>=g2,e3-=g2,rg=1<<32-oc(b2)+e3|c2<w2?(x2=u2,u2=null):x2=u2.sibling;var n3=r2(e4,u2,h3[w2],k3);if(n3===null){u2===null&&(u2=x2);break}a2&&u2&&n3.alternate===null&&b2(e4,u2),g3=f2(n3,g3,w2),m3===null?l3=n3:m3.sibling=n3,m3=n3,u2=x2}if(w2===h3.length)return c2(e4,u2),I2&&tg(e4,w2),l3;if(u2===null){for(;w2w2?(x2=m3,m3=null):x2=m3.sibling;var t3=r2(e4,m3,n3.value,k3);if(t3===null){m3===null&&(m3=x2);break}a2&&m3&&t3.alternate===null&&b2(e4,m3),g3=f2(t3,g3,w2),u2===null?l3=t3:u2.sibling=t3,u2=t3,m3=x2}if(n3.done)return c2(e4,m3),I2&&tg(e4,w2),l3;if(m3===null){for(;!n3.done;w2++,n3=h3.next())n3=q2(e4,n3.value,k3),n3!==null&&(g3=f2(n3,g3,w2),u2===null?l3=n3:u2.sibling=n3,u2=n3);return I2&&tg(e4,w2),l3}for(m3=d(e4,m3);!n3.done;w2++,n3=h3.next())n3=y2(m3,e4,w2,n3.value,k3),n3!==null&&(a2&&n3.alternate!==null&&m3.delete(n3.key===null?w2:n3.key),g3=f2(n3,g3,w2),u2===null?l3=n3:u2.sibling=n3,u2=n3);return a2&&m3.forEach(function(a3){return b2(e4,a3)}),I2&&tg(e4,w2),l3}__name(t2,"t");function J2(a3,d2,f3,h3){if(typeof f3=="object"&&f3!==null&&f3.type===ya&&f3.key===null&&(f3=f3.props.children),typeof f3=="object"&&f3!==null){switch(f3.$$typeof){case va:a:{for(var k3=f3.key,l3=d2;l3!==null;){if(l3.key===k3){if(k3=f3.type,k3===ya){if(l3.tag===7){c2(a3,l3.sibling),d2=e3(l3,f3.props.children),d2.return=a3,a3=d2;break a}}else if(l3.elementType===k3||typeof k3=="object"&&k3!==null&&k3.$$typeof===Ha&&Ng(k3)===l3.type){c2(a3,l3.sibling),d2=e3(l3,f3.props),d2.ref=Lg(a3,l3,f3),d2.return=a3,a3=d2;break a}c2(a3,l3);break}else b2(a3,l3);l3=l3.sibling}f3.type===ya?(d2=Tg(f3.props.children,a3.mode,h3,f3.key),d2.return=a3,a3=d2):(h3=Rg(f3.type,f3.key,f3.props,null,a3.mode,h3),h3.ref=Lg(a3,d2,f3),h3.return=a3,a3=h3)}return g2(a3);case wa:a:{for(l3=f3.key;d2!==null;){if(d2.key===l3)if(d2.tag===4&&d2.stateNode.containerInfo===f3.containerInfo&&d2.stateNode.implementation===f3.implementation){c2(a3,d2.sibling),d2=e3(d2,f3.children||[]),d2.return=a3,a3=d2;break a}else{c2(a3,d2);break}else b2(a3,d2);d2=d2.sibling}d2=Sg(f3,a3.mode,h3),d2.return=a3,a3=d2}return g2(a3);case Ha:return l3=f3._init,J2(a3,d2,l3(f3._payload),h3)}if(eb(f3))return n2(a3,d2,f3,h3);if(Ka(f3))return t2(a3,d2,f3,h3);Mg(a3,f3)}return typeof f3=="string"&&f3!==""||typeof f3=="number"?(f3=""+f3,d2!==null&&d2.tag===6?(c2(a3,d2.sibling),d2=e3(d2,f3),d2.return=a3,a3=d2):(c2(a3,d2),d2=Qg(f3,a3.mode,h3),d2.return=a3,a3=d2),g2(a3)):c2(a3,d2)}return __name(J2,"J"),J2}__name(Og,"Og");var Ug=Og(!0),Vg=Og(!1),Wg=Uf(null),Xg=null,Yg=null,Zg=null;function $g(){Zg=Yg=Xg=null}__name($g,"$g");function ah(a2){var b2=Wg.current;E2(Wg),a2._currentValue=b2}__name(ah,"ah");function bh(a2,b2,c2){for(;a2!==null;){var d=a2.alternate;if((a2.childLanes&b2)!==b2?(a2.childLanes|=b2,d!==null&&(d.childLanes|=b2)):d!==null&&(d.childLanes&b2)!==b2&&(d.childLanes|=b2),a2===c2)break;a2=a2.return}}__name(bh,"bh");function ch(a2,b2){Xg=a2,Zg=Yg=null,a2=a2.dependencies,a2!==null&&a2.firstContext!==null&&((a2.lanes&b2)!==0&&(dh=!0),a2.firstContext=null)}__name(ch,"ch");function eh(a2){var b2=a2._currentValue;if(Zg!==a2)if(a2={context:a2,memoizedValue:b2,next:null},Yg===null){if(Xg===null)throw Error(p2(308));Yg=a2,Xg.dependencies={lanes:0,firstContext:a2}}else Yg=Yg.next=a2;return b2}__name(eh,"eh");var fh=null;function gh(a2){fh===null?fh=[a2]:fh.push(a2)}__name(gh,"gh");function hh(a2,b2,c2,d){var e3=b2.interleaved;return e3===null?(c2.next=c2,gh(b2)):(c2.next=e3.next,e3.next=c2),b2.interleaved=c2,ih(a2,d)}__name(hh,"hh");function ih(a2,b2){a2.lanes|=b2;var c2=a2.alternate;for(c2!==null&&(c2.lanes|=b2),c2=a2,a2=a2.return;a2!==null;)a2.childLanes|=b2,c2=a2.alternate,c2!==null&&(c2.childLanes|=b2),c2=a2,a2=a2.return;return c2.tag===3?c2.stateNode:null}__name(ih,"ih");var jh=!1;function kh(a2){a2.updateQueue={baseState:a2.memoizedState,firstBaseUpdate:null,lastBaseUpdate:null,shared:{pending:null,interleaved:null,lanes:0},effects:null}}__name(kh,"kh");function lh(a2,b2){a2=a2.updateQueue,b2.updateQueue===a2&&(b2.updateQueue={baseState:a2.baseState,firstBaseUpdate:a2.firstBaseUpdate,lastBaseUpdate:a2.lastBaseUpdate,shared:a2.shared,effects:a2.effects})}__name(lh,"lh");function mh(a2,b2){return{eventTime:a2,lane:b2,tag:0,payload:null,callback:null,next:null}}__name(mh,"mh");function nh(a2,b2,c2){var d=a2.updateQueue;if(d===null)return null;if(d=d.shared,(K2&2)!==0){var e3=d.pending;return e3===null?b2.next=b2:(b2.next=e3.next,e3.next=b2),d.pending=b2,ih(a2,c2)}return e3=d.interleaved,e3===null?(b2.next=b2,gh(d)):(b2.next=e3.next,e3.next=b2),d.interleaved=b2,ih(a2,c2)}__name(nh,"nh");function oh(a2,b2,c2){if(b2=b2.updateQueue,b2!==null&&(b2=b2.shared,(c2&4194240)!==0)){var d=b2.lanes;d&=a2.pendingLanes,c2|=d,b2.lanes=c2,Cc(a2,c2)}}__name(oh,"oh");function ph(a2,b2){var c2=a2.updateQueue,d=a2.alternate;if(d!==null&&(d=d.updateQueue,c2===d)){var e3=null,f2=null;if(c2=c2.firstBaseUpdate,c2!==null){do{var g2={eventTime:c2.eventTime,lane:c2.lane,tag:c2.tag,payload:c2.payload,callback:c2.callback,next:null};f2===null?e3=f2=g2:f2=f2.next=g2,c2=c2.next}while(c2!==null);f2===null?e3=f2=b2:f2=f2.next=b2}else e3=f2=b2;c2={baseState:d.baseState,firstBaseUpdate:e3,lastBaseUpdate:f2,shared:d.shared,effects:d.effects},a2.updateQueue=c2;return}a2=c2.lastBaseUpdate,a2===null?c2.firstBaseUpdate=b2:a2.next=b2,c2.lastBaseUpdate=b2}__name(ph,"ph");function qh(a2,b2,c2,d){var e3=a2.updateQueue;jh=!1;var f2=e3.firstBaseUpdate,g2=e3.lastBaseUpdate,h2=e3.shared.pending;if(h2!==null){e3.shared.pending=null;var k2=h2,l2=k2.next;k2.next=null,g2===null?f2=l2:g2.next=l2,g2=k2;var m2=a2.alternate;m2!==null&&(m2=m2.updateQueue,h2=m2.lastBaseUpdate,h2!==g2&&(h2===null?m2.firstBaseUpdate=l2:h2.next=l2,m2.lastBaseUpdate=k2))}if(f2!==null){var q2=e3.baseState;g2=0,m2=l2=k2=null,h2=f2;do{var r2=h2.lane,y2=h2.eventTime;if((d&r2)===r2){m2!==null&&(m2=m2.next={eventTime:y2,lane:0,tag:h2.tag,payload:h2.payload,callback:h2.callback,next:null});a:{var n2=a2,t2=h2;switch(r2=b2,y2=c2,t2.tag){case 1:if(n2=t2.payload,typeof n2=="function"){q2=n2.call(y2,q2,r2);break a}q2=n2;break a;case 3:n2.flags=n2.flags&-65537|128;case 0:if(n2=t2.payload,r2=typeof n2=="function"?n2.call(y2,q2,r2):n2,r2==null)break a;q2=A2({},q2,r2);break a;case 2:jh=!0}}h2.callback!==null&&h2.lane!==0&&(a2.flags|=64,r2=e3.effects,r2===null?e3.effects=[h2]:r2.push(h2))}else y2={eventTime:y2,lane:r2,tag:h2.tag,payload:h2.payload,callback:h2.callback,next:null},m2===null?(l2=m2=y2,k2=q2):m2=m2.next=y2,g2|=r2;if(h2=h2.next,h2===null){if(h2=e3.shared.pending,h2===null)break;r2=h2,h2=r2.next,r2.next=null,e3.lastBaseUpdate=r2,e3.shared.pending=null}}while(!0);if(m2===null&&(k2=q2),e3.baseState=k2,e3.firstBaseUpdate=l2,e3.lastBaseUpdate=m2,b2=e3.shared.interleaved,b2!==null){e3=b2;do g2|=e3.lane,e3=e3.next;while(e3!==b2)}else f2===null&&(e3.shared.lanes=0);rh|=g2,a2.lanes=g2,a2.memoizedState=q2}}__name(qh,"qh");function sh(a2,b2,c2){if(a2=b2.effects,b2.effects=null,a2!==null)for(b2=0;b2c2?c2:4,a2(!0);var d=Gh.transition;Gh.transition={};try{a2(!1),b2()}finally{C2=c2,Gh.transition=d}}__name(vi,"vi");function wi(){return Uh().memoizedState}__name(wi,"wi");function xi(a2,b2,c2){var d=yi(a2);if(c2={lane:d,action:c2,hasEagerState:!1,eagerState:null,next:null},zi(a2))Ai(b2,c2);else if(c2=hh(a2,b2,c2,d),c2!==null){var e3=R2();gi(c2,a2,d,e3),Bi(c2,b2,d)}}__name(xi,"xi");function ii(a2,b2,c2){var d=yi(a2),e3={lane:d,action:c2,hasEagerState:!1,eagerState:null,next:null};if(zi(a2))Ai(b2,e3);else{var f2=a2.alternate;if(a2.lanes===0&&(f2===null||f2.lanes===0)&&(f2=b2.lastRenderedReducer,f2!==null))try{var g2=b2.lastRenderedState,h2=f2(g2,c2);if(e3.hasEagerState=!0,e3.eagerState=h2,He2(h2,g2)){var k2=b2.interleaved;k2===null?(e3.next=e3,gh(b2)):(e3.next=k2.next,k2.next=e3),b2.interleaved=e3;return}}catch{}finally{}c2=hh(a2,b2,e3,d),c2!==null&&(e3=R2(),gi(c2,a2,d,e3),Bi(c2,b2,d))}}__name(ii,"ii");function zi(a2){var b2=a2.alternate;return a2===M2||b2!==null&&b2===M2}__name(zi,"zi");function Ai(a2,b2){Jh=Ih=!0;var c2=a2.pending;c2===null?b2.next=b2:(b2.next=c2.next,c2.next=b2),a2.pending=b2}__name(Ai,"Ai");function Bi(a2,b2,c2){if((c2&4194240)!==0){var d=b2.lanes;d&=a2.pendingLanes,c2|=d,b2.lanes=c2,Cc(a2,c2)}}__name(Bi,"Bi");var Rh={readContext:eh,useCallback:P2,useContext:P2,useEffect:P2,useImperativeHandle:P2,useInsertionEffect:P2,useLayoutEffect:P2,useMemo:P2,useReducer:P2,useRef:P2,useState:P2,useDebugValue:P2,useDeferredValue:P2,useTransition:P2,useMutableSource:P2,useSyncExternalStore:P2,useId:P2,unstable_isNewReconciler:!1},Oh={readContext:eh,useCallback:__name(function(a2,b2){return Th().memoizedState=[a2,b2===void 0?null:b2],a2},"useCallback"),useContext:eh,useEffect:mi,useImperativeHandle:__name(function(a2,b2,c2){return c2=c2!=null?c2.concat([a2]):null,ki(4194308,4,pi2.bind(null,b2,a2),c2)},"useImperativeHandle"),useLayoutEffect:__name(function(a2,b2){return ki(4194308,4,a2,b2)},"useLayoutEffect"),useInsertionEffect:__name(function(a2,b2){return ki(4,2,a2,b2)},"useInsertionEffect"),useMemo:__name(function(a2,b2){var c2=Th();return b2=b2===void 0?null:b2,a2=a2(),c2.memoizedState=[a2,b2],a2},"useMemo"),useReducer:__name(function(a2,b2,c2){var d=Th();return b2=c2!==void 0?c2(b2):b2,d.memoizedState=d.baseState=b2,a2={pending:null,interleaved:null,lanes:0,dispatch:null,lastRenderedReducer:a2,lastRenderedState:b2},d.queue=a2,a2=a2.dispatch=xi.bind(null,M2,a2),[d.memoizedState,a2]},"useReducer"),useRef:__name(function(a2){var b2=Th();return a2={current:a2},b2.memoizedState=a2},"useRef"),useState:hi,useDebugValue:ri,useDeferredValue:__name(function(a2){return Th().memoizedState=a2},"useDeferredValue"),useTransition:__name(function(){var a2=hi(!1),b2=a2[0];return a2=vi.bind(null,a2[1]),Th().memoizedState=a2,[b2,a2]},"useTransition"),useMutableSource:__name(function(){},"useMutableSource"),useSyncExternalStore:__name(function(a2,b2,c2){var d=M2,e3=Th();if(I2){if(c2===void 0)throw Error(p2(407));c2=c2()}else{if(c2=b2(),Q2===null)throw Error(p2(349));(Hh&30)!==0||di(d,b2,c2)}e3.memoizedState=c2;var f2={value:c2,getSnapshot:b2};return e3.queue=f2,mi(ai.bind(null,d,f2,a2),[a2]),d.flags|=2048,bi(9,ci.bind(null,d,f2,c2,b2),void 0,null),c2},"useSyncExternalStore"),useId:__name(function(){var a2=Th(),b2=Q2.identifierPrefix;if(I2){var c2=sg,d=rg;c2=(d&~(1<<32-oc(d)-1)).toString(32)+c2,b2=":"+b2+"R"+c2,c2=Kh++,0Tf||(a2.current=Sf[Tf],Sf[Tf]=null,Tf--)}__name(E2,"E");function G(a2,b2){Tf++,Sf[Tf]=a2.current,a2.current=b2}__name(G,"G");var Vf={},H=Uf(Vf),Wf=Uf(!1),Xf=Vf;function Yf(a2,b2){var c2=a2.type.contextTypes;if(!c2)return Vf;var d=a2.stateNode;if(d&&d.__reactInternalMemoizedUnmaskedChildContext===b2)return d.__reactInternalMemoizedMaskedChildContext;var e3={},f2;for(f2 in c2)e3[f2]=b2[f2];return d&&(a2=a2.stateNode,a2.__reactInternalMemoizedUnmaskedChildContext=b2,a2.__reactInternalMemoizedMaskedChildContext=e3),e3}__name(Yf,"Yf");function Zf(a2){return a2=a2.childContextTypes,a2!=null}__name(Zf,"Zf");function $f(){E2(Wf),E2(H)}__name($f,"$f");function ag(a2,b2,c2){if(H.current!==Vf)throw Error(p2(168));G(H,b2),G(Wf,c2)}__name(ag,"ag");function bg(a2,b2,c2){var d=a2.stateNode;if(b2=b2.childContextTypes,typeof d.getChildContext!="function")return c2;d=d.getChildContext();for(var e3 in d)if(!(e3 in b2))throw Error(p2(108,Ra(a2)||"Unknown",e3));return A2({},c2,d)}__name(bg,"bg");function cg(a2){return a2=(a2=a2.stateNode)&&a2.__reactInternalMemoizedMergedChildContext||Vf,Xf=H.current,G(H,a2),G(Wf,Wf.current),!0}__name(cg,"cg");function dg(a2,b2,c2){var d=a2.stateNode;if(!d)throw Error(p2(169));c2?(a2=bg(a2,b2,Xf),d.__reactInternalMemoizedMergedChildContext=a2,E2(Wf),E2(H),G(H,a2)):E2(Wf),G(Wf,c2)}__name(dg,"dg");var eg=null,fg=!1,gg=!1;function hg(a2){eg===null?eg=[a2]:eg.push(a2)}__name(hg,"hg");function ig(a2){fg=!0,hg(a2)}__name(ig,"ig");function jg(){if(!gg&&eg!==null){gg=!0;var a2=0,b2=C2;try{var c2=eg;for(C2=1;a2>=g2,e3-=g2,rg=1<<32-oc(b2)+e3|c2<w2?(x2=u2,u2=null):x2=u2.sibling;var n3=r2(e4,u2,h3[w2],k3);if(n3===null){u2===null&&(u2=x2);break}a2&&u2&&n3.alternate===null&&b2(e4,u2),g3=f2(n3,g3,w2),m3===null?l3=n3:m3.sibling=n3,m3=n3,u2=x2}if(w2===h3.length)return c2(e4,u2),I2&&tg(e4,w2),l3;if(u2===null){for(;w2w2?(x2=m3,m3=null):x2=m3.sibling;var t3=r2(e4,m3,n3.value,k3);if(t3===null){m3===null&&(m3=x2);break}a2&&m3&&t3.alternate===null&&b2(e4,m3),g3=f2(t3,g3,w2),u2===null?l3=t3:u2.sibling=t3,u2=t3,m3=x2}if(n3.done)return c2(e4,m3),I2&&tg(e4,w2),l3;if(m3===null){for(;!n3.done;w2++,n3=h3.next())n3=q2(e4,n3.value,k3),n3!==null&&(g3=f2(n3,g3,w2),u2===null?l3=n3:u2.sibling=n3,u2=n3);return I2&&tg(e4,w2),l3}for(m3=d(e4,m3);!n3.done;w2++,n3=h3.next())n3=y2(m3,e4,w2,n3.value,k3),n3!==null&&(a2&&n3.alternate!==null&&m3.delete(n3.key===null?w2:n3.key),g3=f2(n3,g3,w2),u2===null?l3=n3:u2.sibling=n3,u2=n3);return a2&&m3.forEach(function(a3){return b2(e4,a3)}),I2&&tg(e4,w2),l3}__name(t2,"t");function J2(a3,d2,f3,h3){if(typeof f3=="object"&&f3!==null&&f3.type===ya&&f3.key===null&&(f3=f3.props.children),typeof f3=="object"&&f3!==null){switch(f3.$$typeof){case va:a:{for(var k3=f3.key,l3=d2;l3!==null;){if(l3.key===k3){if(k3=f3.type,k3===ya){if(l3.tag===7){c2(a3,l3.sibling),d2=e3(l3,f3.props.children),d2.return=a3,a3=d2;break a}}else if(l3.elementType===k3||typeof k3=="object"&&k3!==null&&k3.$$typeof===Ha&&Ng(k3)===l3.type){c2(a3,l3.sibling),d2=e3(l3,f3.props),d2.ref=Lg(a3,l3,f3),d2.return=a3,a3=d2;break a}c2(a3,l3);break}else b2(a3,l3);l3=l3.sibling}f3.type===ya?(d2=Tg(f3.props.children,a3.mode,h3,f3.key),d2.return=a3,a3=d2):(h3=Rg(f3.type,f3.key,f3.props,null,a3.mode,h3),h3.ref=Lg(a3,d2,f3),h3.return=a3,a3=h3)}return g2(a3);case wa:a:{for(l3=f3.key;d2!==null;){if(d2.key===l3)if(d2.tag===4&&d2.stateNode.containerInfo===f3.containerInfo&&d2.stateNode.implementation===f3.implementation){c2(a3,d2.sibling),d2=e3(d2,f3.children||[]),d2.return=a3,a3=d2;break a}else{c2(a3,d2);break}else b2(a3,d2);d2=d2.sibling}d2=Sg(f3,a3.mode,h3),d2.return=a3,a3=d2}return g2(a3);case Ha:return l3=f3._init,J2(a3,d2,l3(f3._payload),h3)}if(eb(f3))return n2(a3,d2,f3,h3);if(Ka(f3))return t2(a3,d2,f3,h3);Mg(a3,f3)}return typeof f3=="string"&&f3!==""||typeof f3=="number"?(f3=""+f3,d2!==null&&d2.tag===6?(c2(a3,d2.sibling),d2=e3(d2,f3),d2.return=a3,a3=d2):(c2(a3,d2),d2=Qg(f3,a3.mode,h3),d2.return=a3,a3=d2),g2(a3)):c2(a3,d2)}return __name(J2,"J"),J2}__name(Og,"Og");var Ug=Og(!0),Vg=Og(!1),Wg=Uf(null),Xg=null,Yg=null,Zg=null;function $g(){Zg=Yg=Xg=null}__name($g,"$g");function ah(a2){var b2=Wg.current;E2(Wg),a2._currentValue=b2}__name(ah,"ah");function bh(a2,b2,c2){for(;a2!==null;){var d=a2.alternate;if((a2.childLanes&b2)!==b2?(a2.childLanes|=b2,d!==null&&(d.childLanes|=b2)):d!==null&&(d.childLanes&b2)!==b2&&(d.childLanes|=b2),a2===c2)break;a2=a2.return}}__name(bh,"bh");function ch(a2,b2){Xg=a2,Zg=Yg=null,a2=a2.dependencies,a2!==null&&a2.firstContext!==null&&((a2.lanes&b2)!==0&&(dh=!0),a2.firstContext=null)}__name(ch,"ch");function eh(a2){var b2=a2._currentValue;if(Zg!==a2)if(a2={context:a2,memoizedValue:b2,next:null},Yg===null){if(Xg===null)throw Error(p2(308));Yg=a2,Xg.dependencies={lanes:0,firstContext:a2}}else Yg=Yg.next=a2;return b2}__name(eh,"eh");var fh=null;function gh(a2){fh===null?fh=[a2]:fh.push(a2)}__name(gh,"gh");function hh(a2,b2,c2,d){var e3=b2.interleaved;return e3===null?(c2.next=c2,gh(b2)):(c2.next=e3.next,e3.next=c2),b2.interleaved=c2,ih(a2,d)}__name(hh,"hh");function ih(a2,b2){a2.lanes|=b2;var c2=a2.alternate;for(c2!==null&&(c2.lanes|=b2),c2=a2,a2=a2.return;a2!==null;)a2.childLanes|=b2,c2=a2.alternate,c2!==null&&(c2.childLanes|=b2),c2=a2,a2=a2.return;return c2.tag===3?c2.stateNode:null}__name(ih,"ih");var jh=!1;function kh(a2){a2.updateQueue={baseState:a2.memoizedState,firstBaseUpdate:null,lastBaseUpdate:null,shared:{pending:null,interleaved:null,lanes:0},effects:null}}__name(kh,"kh");function lh(a2,b2){a2=a2.updateQueue,b2.updateQueue===a2&&(b2.updateQueue={baseState:a2.baseState,firstBaseUpdate:a2.firstBaseUpdate,lastBaseUpdate:a2.lastBaseUpdate,shared:a2.shared,effects:a2.effects})}__name(lh,"lh");function mh(a2,b2){return{eventTime:a2,lane:b2,tag:0,payload:null,callback:null,next:null}}__name(mh,"mh");function nh(a2,b2,c2){var d=a2.updateQueue;if(d===null)return null;if(d=d.shared,(K2&2)!==0){var e3=d.pending;return e3===null?b2.next=b2:(b2.next=e3.next,e3.next=b2),d.pending=b2,ih(a2,c2)}return e3=d.interleaved,e3===null?(b2.next=b2,gh(d)):(b2.next=e3.next,e3.next=b2),d.interleaved=b2,ih(a2,c2)}__name(nh,"nh");function oh(a2,b2,c2){if(b2=b2.updateQueue,b2!==null&&(b2=b2.shared,(c2&4194240)!==0)){var d=b2.lanes;d&=a2.pendingLanes,c2|=d,b2.lanes=c2,Cc(a2,c2)}}__name(oh,"oh");function ph(a2,b2){var c2=a2.updateQueue,d=a2.alternate;if(d!==null&&(d=d.updateQueue,c2===d)){var e3=null,f2=null;if(c2=c2.firstBaseUpdate,c2!==null){do{var g2={eventTime:c2.eventTime,lane:c2.lane,tag:c2.tag,payload:c2.payload,callback:c2.callback,next:null};f2===null?e3=f2=g2:f2=f2.next=g2,c2=c2.next}while(c2!==null);f2===null?e3=f2=b2:f2=f2.next=b2}else e3=f2=b2;c2={baseState:d.baseState,firstBaseUpdate:e3,lastBaseUpdate:f2,shared:d.shared,effects:d.effects},a2.updateQueue=c2;return}a2=c2.lastBaseUpdate,a2===null?c2.firstBaseUpdate=b2:a2.next=b2,c2.lastBaseUpdate=b2}__name(ph,"ph");function qh(a2,b2,c2,d){var e3=a2.updateQueue;jh=!1;var f2=e3.firstBaseUpdate,g2=e3.lastBaseUpdate,h2=e3.shared.pending;if(h2!==null){e3.shared.pending=null;var k2=h2,l2=k2.next;k2.next=null,g2===null?f2=l2:g2.next=l2,g2=k2;var m2=a2.alternate;m2!==null&&(m2=m2.updateQueue,h2=m2.lastBaseUpdate,h2!==g2&&(h2===null?m2.firstBaseUpdate=l2:h2.next=l2,m2.lastBaseUpdate=k2))}if(f2!==null){var q2=e3.baseState;g2=0,m2=l2=k2=null,h2=f2;do{var r2=h2.lane,y2=h2.eventTime;if((d&r2)===r2){m2!==null&&(m2=m2.next={eventTime:y2,lane:0,tag:h2.tag,payload:h2.payload,callback:h2.callback,next:null});a:{var n2=a2,t2=h2;switch(r2=b2,y2=c2,t2.tag){case 1:if(n2=t2.payload,typeof n2=="function"){q2=n2.call(y2,q2,r2);break a}q2=n2;break a;case 3:n2.flags=n2.flags&-65537|128;case 0:if(n2=t2.payload,r2=typeof n2=="function"?n2.call(y2,q2,r2):n2,r2==null)break a;q2=A2({},q2,r2);break a;case 2:jh=!0}}h2.callback!==null&&h2.lane!==0&&(a2.flags|=64,r2=e3.effects,r2===null?e3.effects=[h2]:r2.push(h2))}else y2={eventTime:y2,lane:r2,tag:h2.tag,payload:h2.payload,callback:h2.callback,next:null},m2===null?(l2=m2=y2,k2=q2):m2=m2.next=y2,g2|=r2;if(h2=h2.next,h2===null){if(h2=e3.shared.pending,h2===null)break;r2=h2,h2=r2.next,r2.next=null,e3.lastBaseUpdate=r2,e3.shared.pending=null}}while(!0);if(m2===null&&(k2=q2),e3.baseState=k2,e3.firstBaseUpdate=l2,e3.lastBaseUpdate=m2,b2=e3.shared.interleaved,b2!==null){e3=b2;do g2|=e3.lane,e3=e3.next;while(e3!==b2)}else f2===null&&(e3.shared.lanes=0);rh|=g2,a2.lanes=g2,a2.memoizedState=q2}}__name(qh,"qh");function sh(a2,b2,c2){if(a2=b2.effects,b2.effects=null,a2!==null)for(b2=0;b2c2?c2:4,a2(!0);var d=Gh.transition;Gh.transition={};try{a2(!1),b2()}finally{C2=c2,Gh.transition=d}}__name(vi,"vi");function wi(){return Uh().memoizedState}__name(wi,"wi");function xi(a2,b2,c2){var d=yi(a2);if(c2={lane:d,action:c2,hasEagerState:!1,eagerState:null,next:null},zi(a2))Ai(b2,c2);else if(c2=hh(a2,b2,c2,d),c2!==null){var e3=R2();gi(c2,a2,d,e3),Bi(c2,b2,d)}}__name(xi,"xi");function ii(a2,b2,c2){var d=yi(a2),e3={lane:d,action:c2,hasEagerState:!1,eagerState:null,next:null};if(zi(a2))Ai(b2,e3);else{var f2=a2.alternate;if(a2.lanes===0&&(f2===null||f2.lanes===0)&&(f2=b2.lastRenderedReducer,f2!==null))try{var g2=b2.lastRenderedState,h2=f2(g2,c2);if(e3.hasEagerState=!0,e3.eagerState=h2,He2(h2,g2)){var k2=b2.interleaved;k2===null?(e3.next=e3,gh(b2)):(e3.next=k2.next,k2.next=e3),b2.interleaved=e3;return}}catch{}c2=hh(a2,b2,e3,d),c2!==null&&(e3=R2(),gi(c2,a2,d,e3),Bi(c2,b2,d))}}__name(ii,"ii");function zi(a2){var b2=a2.alternate;return a2===M2||b2!==null&&b2===M2}__name(zi,"zi");function Ai(a2,b2){Jh=Ih=!0;var c2=a2.pending;c2===null?b2.next=b2:(b2.next=c2.next,c2.next=b2),a2.pending=b2}__name(Ai,"Ai");function Bi(a2,b2,c2){if((c2&4194240)!==0){var d=b2.lanes;d&=a2.pendingLanes,c2|=d,b2.lanes=c2,Cc(a2,c2)}}__name(Bi,"Bi");var Rh={readContext:eh,useCallback:P2,useContext:P2,useEffect:P2,useImperativeHandle:P2,useInsertionEffect:P2,useLayoutEffect:P2,useMemo:P2,useReducer:P2,useRef:P2,useState:P2,useDebugValue:P2,useDeferredValue:P2,useTransition:P2,useMutableSource:P2,useSyncExternalStore:P2,useId:P2,unstable_isNewReconciler:!1},Oh={readContext:eh,useCallback:__name(function(a2,b2){return Th().memoizedState=[a2,b2===void 0?null:b2],a2},"useCallback"),useContext:eh,useEffect:mi,useImperativeHandle:__name(function(a2,b2,c2){return c2=c2!=null?c2.concat([a2]):null,ki(4194308,4,pi2.bind(null,b2,a2),c2)},"useImperativeHandle"),useLayoutEffect:__name(function(a2,b2){return ki(4194308,4,a2,b2)},"useLayoutEffect"),useInsertionEffect:__name(function(a2,b2){return ki(4,2,a2,b2)},"useInsertionEffect"),useMemo:__name(function(a2,b2){var c2=Th();return b2=b2===void 0?null:b2,a2=a2(),c2.memoizedState=[a2,b2],a2},"useMemo"),useReducer:__name(function(a2,b2,c2){var d=Th();return b2=c2!==void 0?c2(b2):b2,d.memoizedState=d.baseState=b2,a2={pending:null,interleaved:null,lanes:0,dispatch:null,lastRenderedReducer:a2,lastRenderedState:b2},d.queue=a2,a2=a2.dispatch=xi.bind(null,M2,a2),[d.memoizedState,a2]},"useReducer"),useRef:__name(function(a2){var b2=Th();return a2={current:a2},b2.memoizedState=a2},"useRef"),useState:hi,useDebugValue:ri,useDeferredValue:__name(function(a2){return Th().memoizedState=a2},"useDeferredValue"),useTransition:__name(function(){var a2=hi(!1),b2=a2[0];return a2=vi.bind(null,a2[1]),Th().memoizedState=a2,[b2,a2]},"useTransition"),useMutableSource:__name(function(){},"useMutableSource"),useSyncExternalStore:__name(function(a2,b2,c2){var d=M2,e3=Th();if(I2){if(c2===void 0)throw Error(p2(407));c2=c2()}else{if(c2=b2(),Q2===null)throw Error(p2(349));(Hh&30)!==0||di(d,b2,c2)}e3.memoizedState=c2;var f2={value:c2,getSnapshot:b2};return e3.queue=f2,mi(ai.bind(null,d,f2,a2),[a2]),d.flags|=2048,bi(9,ci.bind(null,d,f2,c2,b2),void 0,null),c2},"useSyncExternalStore"),useId:__name(function(){var a2=Th(),b2=Q2.identifierPrefix;if(I2){var c2=sg,d=rg;c2=(d&~(1<<32-oc(d)-1)).toString(32)+c2,b2=":"+b2+"R"+c2,c2=Kh++,0<\/script>",a2=a2.removeChild(a2.firstChild)):typeof d.is=="string"?a2=g2.createElement(c2,{is:d.is}):(a2=g2.createElement(c2),c2==="select"&&(g2=a2,d.multiple?g2.multiple=!0:d.size&&(g2.size=d.size))):a2=g2.createElementNS(a2,c2),a2[Of]=b2,a2[Pf]=d,zj(a2,b2,!1,!1),b2.stateNode=a2;a:{switch(g2=vb(c2,d),c2){case"dialog":D2("cancel",a2),D2("close",a2),e3=d;break;case"iframe":case"object":case"embed":D2("load",a2),e3=d;break;case"video":case"audio":for(e3=0;e3Gj&&(b2.flags|=128,d=!0,Dj(f2,!1),b2.lanes=4194304)}else{if(!d)if(a2=Ch(g2),a2!==null){if(b2.flags|=128,d=!0,c2=a2.updateQueue,c2!==null&&(b2.updateQueue=c2,b2.flags|=4),Dj(f2,!0),f2.tail===null&&f2.tailMode==="hidden"&&!g2.alternate&&!I2)return S2(b2),null}else 2*B2()-f2.renderingStartTime>Gj&&c2!==1073741824&&(b2.flags|=128,d=!0,Dj(f2,!1),b2.lanes=4194304);f2.isBackwards?(g2.sibling=b2.child,b2.child=g2):(c2=f2.last,c2!==null?c2.sibling=g2:b2.child=g2,f2.last=g2)}return f2.tail!==null?(b2=f2.tail,f2.rendering=b2,f2.tail=b2.sibling,f2.renderingStartTime=B2(),b2.sibling=null,c2=L2.current,G(L2,d?c2&1|2:c2&1),b2):(S2(b2),null);case 22:case 23:return Hj(),d=b2.memoizedState!==null,a2!==null&&a2.memoizedState!==null!==d&&(b2.flags|=8192),d&&(b2.mode&1)!==0?(fj&1073741824)!==0&&(S2(b2),b2.subtreeFlags&6&&(b2.flags|=8192)):S2(b2),null;case 24:return null;case 25:return null}throw Error(p2(156,b2.tag))}__name(Ej,"Ej");function Ij(a2,b2){switch(wg(b2),b2.tag){case 1:return Zf(b2.type)&&$f(),a2=b2.flags,a2&65536?(b2.flags=a2&-65537|128,b2):null;case 3:return zh(),E2(Wf),E2(H),Eh(),a2=b2.flags,(a2&65536)!==0&&(a2&128)===0?(b2.flags=a2&-65537|128,b2):null;case 5:return Bh(b2),null;case 13:if(E2(L2),a2=b2.memoizedState,a2!==null&&a2.dehydrated!==null){if(b2.alternate===null)throw Error(p2(340));Ig()}return a2=b2.flags,a2&65536?(b2.flags=a2&-65537|128,b2):null;case 19:return E2(L2),null;case 4:return zh(),null;case 10:return ah(b2.type._context),null;case 22:case 23:return Hj(),null;case 24:return null;default:return null}}__name(Ij,"Ij");var Jj=!1,U2=!1,Kj=typeof WeakSet=="function"?WeakSet:Set,V2=null;function Lj(a2,b2){var c2=a2.ref;if(c2!==null)if(typeof c2=="function")try{c2(null)}catch(d){W2(a2,b2,d)}else c2.current=null}__name(Lj,"Lj");function Mj(a2,b2,c2){try{c2()}catch(d){W2(a2,b2,d)}}__name(Mj,"Mj");var Nj=!1;function Oj(a2,b2){if(Cf=dd,a2=Me2(),Ne(a2)){if("selectionStart"in a2)var c2={start:a2.selectionStart,end:a2.selectionEnd};else a:{c2=(c2=a2.ownerDocument)&&c2.defaultView||window;var d=c2.getSelection&&c2.getSelection();if(d&&d.rangeCount!==0){c2=d.anchorNode;var e3=d.anchorOffset,f2=d.focusNode;d=d.focusOffset;try{c2.nodeType,f2.nodeType}catch{c2=null;break a}var g2=0,h2=-1,k2=-1,l2=0,m2=0,q2=a2,r2=null;b:for(;;){for(var y2;q2!==c2||e3!==0&&q2.nodeType!==3||(h2=g2+e3),q2!==f2||d!==0&&q2.nodeType!==3||(k2=g2+d),q2.nodeType===3&&(g2+=q2.nodeValue.length),(y2=q2.firstChild)!==null;)r2=q2,q2=y2;for(;;){if(q2===a2)break b;if(r2===c2&&++l2===e3&&(h2=g2),r2===f2&&++m2===d&&(k2=g2),(y2=q2.nextSibling)!==null)break;q2=r2,r2=q2.parentNode}q2=y2}c2=h2===-1||k2===-1?null:{start:h2,end:k2}}else c2=null}c2=c2||{start:0,end:0}}else c2=null;for(Df={focusedElem:a2,selectionRange:c2},dd=!1,V2=b2;V2!==null;)if(b2=V2,a2=b2.child,(b2.subtreeFlags&1028)!==0&&a2!==null)a2.return=b2,V2=a2;else for(;V2!==null;){b2=V2;try{var n2=b2.alternate;if((b2.flags&1024)!==0)switch(b2.tag){case 0:case 11:case 15:break;case 1:if(n2!==null){var t2=n2.memoizedProps,J2=n2.memoizedState,x2=b2.stateNode,w2=x2.getSnapshotBeforeUpdate(b2.elementType===b2.type?t2:Ci(b2.type,t2),J2);x2.__reactInternalSnapshotBeforeUpdate=w2}break;case 3:var u2=b2.stateNode.containerInfo;u2.nodeType===1?u2.textContent="":u2.nodeType===9&&u2.documentElement&&u2.removeChild(u2.documentElement);break;case 5:case 6:case 4:case 17:break;default:throw Error(p2(163))}}catch(F2){W2(b2,b2.return,F2)}if(a2=b2.sibling,a2!==null){a2.return=b2.return,V2=a2;break}V2=b2.return}return n2=Nj,Nj=!1,n2}__name(Oj,"Oj");function Pj(a2,b2,c2){var d=b2.updateQueue;if(d=d!==null?d.lastEffect:null,d!==null){var e3=d=d.next;do{if((e3.tag&a2)===a2){var f2=e3.destroy;e3.destroy=void 0,f2!==void 0&&Mj(b2,c2,f2)}e3=e3.next}while(e3!==d)}}__name(Pj,"Pj");function Qj(a2,b2){if(b2=b2.updateQueue,b2=b2!==null?b2.lastEffect:null,b2!==null){var c2=b2=b2.next;do{if((c2.tag&a2)===a2){var d=c2.create;c2.destroy=d()}c2=c2.next}while(c2!==b2)}}__name(Qj,"Qj");function Rj(a2){var b2=a2.ref;if(b2!==null){var c2=a2.stateNode;switch(a2.tag){case 5:a2=c2;break;default:a2=c2}typeof b2=="function"?b2(a2):b2.current=a2}}__name(Rj,"Rj");function Sj(a2){var b2=a2.alternate;b2!==null&&(a2.alternate=null,Sj(b2)),a2.child=null,a2.deletions=null,a2.sibling=null,a2.tag===5&&(b2=a2.stateNode,b2!==null&&(delete b2[Of],delete b2[Pf],delete b2[of],delete b2[Qf],delete b2[Rf])),a2.stateNode=null,a2.return=null,a2.dependencies=null,a2.memoizedProps=null,a2.memoizedState=null,a2.pendingProps=null,a2.stateNode=null,a2.updateQueue=null}__name(Sj,"Sj");function Tj(a2){return a2.tag===5||a2.tag===3||a2.tag===4}__name(Tj,"Tj");function Uj(a2){a:for(;;){for(;a2.sibling===null;){if(a2.return===null||Tj(a2.return))return null;a2=a2.return}for(a2.sibling.return=a2.return,a2=a2.sibling;a2.tag!==5&&a2.tag!==6&&a2.tag!==18;){if(a2.flags&2||a2.child===null||a2.tag===4)continue a;a2.child.return=a2,a2=a2.child}if(!(a2.flags&2))return a2.stateNode}}__name(Uj,"Uj");function Vj(a2,b2,c2){var d=a2.tag;if(d===5||d===6)a2=a2.stateNode,b2?c2.nodeType===8?c2.parentNode.insertBefore(a2,b2):c2.insertBefore(a2,b2):(c2.nodeType===8?(b2=c2.parentNode,b2.insertBefore(a2,c2)):(b2=c2,b2.appendChild(a2)),c2=c2._reactRootContainer,c2!=null||b2.onclick!==null||(b2.onclick=Bf));else if(d!==4&&(a2=a2.child,a2!==null))for(Vj(a2,b2,c2),a2=a2.sibling;a2!==null;)Vj(a2,b2,c2),a2=a2.sibling}__name(Vj,"Vj");function Wj(a2,b2,c2){var d=a2.tag;if(d===5||d===6)a2=a2.stateNode,b2?c2.insertBefore(a2,b2):c2.appendChild(a2);else if(d!==4&&(a2=a2.child,a2!==null))for(Wj(a2,b2,c2),a2=a2.sibling;a2!==null;)Wj(a2,b2,c2),a2=a2.sibling}__name(Wj,"Wj");var X2=null,Xj=!1;function Yj(a2,b2,c2){for(c2=c2.child;c2!==null;)Zj(a2,b2,c2),c2=c2.sibling}__name(Yj,"Yj");function Zj(a2,b2,c2){if(lc&&typeof lc.onCommitFiberUnmount=="function")try{lc.onCommitFiberUnmount(kc,c2)}catch{}switch(c2.tag){case 5:U2||Lj(c2,b2);case 6:var d=X2,e3=Xj;X2=null,Yj(a2,b2,c2),X2=d,Xj=e3,X2!==null&&(Xj?(a2=X2,c2=c2.stateNode,a2.nodeType===8?a2.parentNode.removeChild(c2):a2.removeChild(c2)):X2.removeChild(c2.stateNode));break;case 18:X2!==null&&(Xj?(a2=X2,c2=c2.stateNode,a2.nodeType===8?Kf(a2.parentNode,c2):a2.nodeType===1&&Kf(a2,c2),bd(a2)):Kf(X2,c2.stateNode));break;case 4:d=X2,e3=Xj,X2=c2.stateNode.containerInfo,Xj=!0,Yj(a2,b2,c2),X2=d,Xj=e3;break;case 0:case 11:case 14:case 15:if(!U2&&(d=c2.updateQueue,d!==null&&(d=d.lastEffect,d!==null))){e3=d=d.next;do{var f2=e3,g2=f2.destroy;f2=f2.tag,g2!==void 0&&((f2&2)!==0||(f2&4)!==0)&&Mj(c2,b2,g2),e3=e3.next}while(e3!==d)}Yj(a2,b2,c2);break;case 1:if(!U2&&(Lj(c2,b2),d=c2.stateNode,typeof d.componentWillUnmount=="function"))try{d.props=c2.memoizedProps,d.state=c2.memoizedState,d.componentWillUnmount()}catch(h2){W2(c2,b2,h2)}Yj(a2,b2,c2);break;case 21:Yj(a2,b2,c2);break;case 22:c2.mode&1?(U2=(d=U2)||c2.memoizedState!==null,Yj(a2,b2,c2),U2=d):Yj(a2,b2,c2);break;default:Yj(a2,b2,c2)}}__name(Zj,"Zj");function ak(a2){var b2=a2.updateQueue;if(b2!==null){a2.updateQueue=null;var c2=a2.stateNode;c2===null&&(c2=a2.stateNode=new Kj),b2.forEach(function(b3){var d=bk.bind(null,a2,b3);c2.has(b3)||(c2.add(b3),b3.then(d,d))})}}__name(ak,"ak");function ck(a2,b2){var c2=b2.deletions;if(c2!==null)for(var d=0;de3&&(e3=g2),d&=~f2}if(d=e3,d=B2()-d,d=(120>d?120:480>d?480:1080>d?1080:1920>d?1920:3e3>d?3e3:4320>d?4320:1960*lk(d/1960))-d,10a2?16:a2,wk===null)var d=!1;else{if(a2=wk,wk=null,xk=0,(K2&6)!==0)throw Error(p2(331));var e3=K2;for(K2|=4,V2=a2.current;V2!==null;){var f2=V2,g2=f2.child;if((V2.flags&16)!==0){var h2=f2.deletions;if(h2!==null){for(var k2=0;k2B2()-fk?Kk(a2,0):rk|=c2),Dk(a2,b2)}__name(Ti,"Ti");function Yk(a2,b2){b2===0&&((a2.mode&1)===0?b2=1:(b2=sc,sc<<=1,(sc&130023424)===0&&(sc=4194304)));var c2=R2();a2=ih(a2,b2),a2!==null&&(Ac(a2,b2,c2),Dk(a2,c2))}__name(Yk,"Yk");function uj(a2){var b2=a2.memoizedState,c2=0;b2!==null&&(c2=b2.retryLane),Yk(a2,c2)}__name(uj,"uj");function bk(a2,b2){var c2=0;switch(a2.tag){case 13:var d=a2.stateNode,e3=a2.memoizedState;e3!==null&&(c2=e3.retryLane);break;case 19:d=a2.stateNode;break;default:throw Error(p2(314))}d!==null&&d.delete(b2),Yk(a2,c2)}__name(bk,"bk");var Vk;Vk=__name(function(a2,b2,c2){if(a2!==null)if(a2.memoizedProps!==b2.pendingProps||Wf.current)dh=!0;else{if((a2.lanes&c2)===0&&(b2.flags&128)===0)return dh=!1,yj(a2,b2,c2);dh=(a2.flags&131072)!==0}else dh=!1,I2&&(b2.flags&1048576)!==0&&ug(b2,ng,b2.index);switch(b2.lanes=0,b2.tag){case 2:var d=b2.type;ij(a2,b2),a2=b2.pendingProps;var e3=Yf(b2,H.current);ch(b2,c2),e3=Nh(null,b2,d,a2,e3,c2);var f2=Sh();return b2.flags|=1,typeof e3=="object"&&e3!==null&&typeof e3.render=="function"&&e3.$$typeof===void 0?(b2.tag=1,b2.memoizedState=null,b2.updateQueue=null,Zf(d)?(f2=!0,cg(b2)):f2=!1,b2.memoizedState=e3.state!==null&&e3.state!==void 0?e3.state:null,kh(b2),e3.updater=Ei,b2.stateNode=e3,e3._reactInternals=b2,Ii(b2,d,a2,c2),b2=jj(null,b2,d,!0,f2,c2)):(b2.tag=0,I2&&f2&&vg(b2),Xi(null,b2,e3,c2),b2=b2.child),b2;case 16:d=b2.elementType;a:{switch(ij(a2,b2),a2=b2.pendingProps,e3=d._init,d=e3(d._payload),b2.type=d,e3=b2.tag=Zk(d),a2=Ci(d,a2),e3){case 0:b2=cj(null,b2,d,a2,c2);break a;case 1:b2=hj(null,b2,d,a2,c2);break a;case 11:b2=Yi(null,b2,d,a2,c2);break a;case 14:b2=$i(null,b2,d,Ci(d.type,a2),c2);break a}throw Error(p2(306,d,""))}return b2;case 0:return d=b2.type,e3=b2.pendingProps,e3=b2.elementType===d?e3:Ci(d,e3),cj(a2,b2,d,e3,c2);case 1:return d=b2.type,e3=b2.pendingProps,e3=b2.elementType===d?e3:Ci(d,e3),hj(a2,b2,d,e3,c2);case 3:a:{if(kj(b2),a2===null)throw Error(p2(387));d=b2.pendingProps,f2=b2.memoizedState,e3=f2.element,lh(a2,b2),qh(b2,d,null,c2);var g2=b2.memoizedState;if(d=g2.element,f2.isDehydrated)if(f2={element:d,isDehydrated:!1,cache:g2.cache,pendingSuspenseBoundaries:g2.pendingSuspenseBoundaries,transitions:g2.transitions},b2.updateQueue.baseState=f2,b2.memoizedState=f2,b2.flags&256){e3=Ji(Error(p2(423)),b2),b2=lj(a2,b2,d,c2,e3);break a}else if(d!==e3){e3=Ji(Error(p2(424)),b2),b2=lj(a2,b2,d,c2,e3);break a}else for(yg=Lf(b2.stateNode.containerInfo.firstChild),xg=b2,I2=!0,zg=null,c2=Vg(b2,null,d,c2),b2.child=c2;c2;)c2.flags=c2.flags&-3|4096,c2=c2.sibling;else{if(Ig(),d===e3){b2=Zi(a2,b2,c2);break a}Xi(a2,b2,d,c2)}b2=b2.child}return b2;case 5:return Ah(b2),a2===null&&Eg(b2),d=b2.type,e3=b2.pendingProps,f2=a2!==null?a2.memoizedProps:null,g2=e3.children,Ef(d,e3)?g2=null:f2!==null&&Ef(d,f2)&&(b2.flags|=32),gj(a2,b2),Xi(a2,b2,g2,c2),b2.child;case 6:return a2===null&&Eg(b2),null;case 13:return oj(a2,b2,c2);case 4:return yh(b2,b2.stateNode.containerInfo),d=b2.pendingProps,a2===null?b2.child=Ug(b2,null,d,c2):Xi(a2,b2,d,c2),b2.child;case 11:return d=b2.type,e3=b2.pendingProps,e3=b2.elementType===d?e3:Ci(d,e3),Yi(a2,b2,d,e3,c2);case 7:return Xi(a2,b2,b2.pendingProps,c2),b2.child;case 8:return Xi(a2,b2,b2.pendingProps.children,c2),b2.child;case 12:return Xi(a2,b2,b2.pendingProps.children,c2),b2.child;case 10:a:{if(d=b2.type._context,e3=b2.pendingProps,f2=b2.memoizedProps,g2=e3.value,G(Wg,d._currentValue),d._currentValue=g2,f2!==null)if(He2(f2.value,g2)){if(f2.children===e3.children&&!Wf.current){b2=Zi(a2,b2,c2);break a}}else for(f2=b2.child,f2!==null&&(f2.return=b2);f2!==null;){var h2=f2.dependencies;if(h2!==null){g2=f2.child;for(var k2=h2.firstContext;k2!==null;){if(k2.context===d){if(f2.tag===1){k2=mh(-1,c2&-c2),k2.tag=2;var l2=f2.updateQueue;if(l2!==null){l2=l2.shared;var m2=l2.pending;m2===null?k2.next=k2:(k2.next=m2.next,m2.next=k2),l2.pending=k2}}f2.lanes|=c2,k2=f2.alternate,k2!==null&&(k2.lanes|=c2),bh(f2.return,c2,b2),h2.lanes|=c2;break}k2=k2.next}}else if(f2.tag===10)g2=f2.type===b2.type?null:f2.child;else if(f2.tag===18){if(g2=f2.return,g2===null)throw Error(p2(341));g2.lanes|=c2,h2=g2.alternate,h2!==null&&(h2.lanes|=c2),bh(g2,c2,b2),g2=f2.sibling}else g2=f2.child;if(g2!==null)g2.return=f2;else for(g2=f2;g2!==null;){if(g2===b2){g2=null;break}if(f2=g2.sibling,f2!==null){f2.return=g2.return,g2=f2;break}g2=g2.return}f2=g2}Xi(a2,b2,e3.children,c2),b2=b2.child}return b2;case 9:return e3=b2.type,d=b2.pendingProps.children,ch(b2,c2),e3=eh(e3),d=d(e3),b2.flags|=1,Xi(a2,b2,d,c2),b2.child;case 14:return d=b2.type,e3=Ci(d,b2.pendingProps),e3=Ci(d.type,e3),$i(a2,b2,d,e3,c2);case 15:return bj(a2,b2,b2.type,b2.pendingProps,c2);case 17:return d=b2.type,e3=b2.pendingProps,e3=b2.elementType===d?e3:Ci(d,e3),ij(a2,b2),b2.tag=1,Zf(d)?(a2=!0,cg(b2)):a2=!1,ch(b2,c2),Gi(b2,d,e3),Ii(b2,d,e3,c2),jj(null,b2,d,!0,a2,c2);case 19:return xj(a2,b2,c2);case 22:return dj(a2,b2,c2)}throw Error(p2(156,b2.tag))},"Vk");function Fk(a2,b2){return ac(a2,b2)}__name(Fk,"Fk");function $k(a2,b2,c2,d){this.tag=a2,this.key=c2,this.sibling=this.child=this.return=this.stateNode=this.type=this.elementType=null,this.index=0,this.ref=null,this.pendingProps=b2,this.dependencies=this.memoizedState=this.updateQueue=this.memoizedProps=null,this.mode=d,this.subtreeFlags=this.flags=0,this.deletions=null,this.childLanes=this.lanes=0,this.alternate=null}__name($k,"$k");function Bg(a2,b2,c2,d){return new $k(a2,b2,c2,d)}__name(Bg,"Bg");function aj(a2){return a2=a2.prototype,!(!a2||!a2.isReactComponent)}__name(aj,"aj");function Zk(a2){if(typeof a2=="function")return aj(a2)?1:0;if(a2!=null){if(a2=a2.$$typeof,a2===Da)return 11;if(a2===Ga)return 14}return 2}__name(Zk,"Zk");function Pg(a2,b2){var c2=a2.alternate;return c2===null?(c2=Bg(a2.tag,b2,a2.key,a2.mode),c2.elementType=a2.elementType,c2.type=a2.type,c2.stateNode=a2.stateNode,c2.alternate=a2,a2.alternate=c2):(c2.pendingProps=b2,c2.type=a2.type,c2.flags=0,c2.subtreeFlags=0,c2.deletions=null),c2.flags=a2.flags&14680064,c2.childLanes=a2.childLanes,c2.lanes=a2.lanes,c2.child=a2.child,c2.memoizedProps=a2.memoizedProps,c2.memoizedState=a2.memoizedState,c2.updateQueue=a2.updateQueue,b2=a2.dependencies,c2.dependencies=b2===null?null:{lanes:b2.lanes,firstContext:b2.firstContext},c2.sibling=a2.sibling,c2.index=a2.index,c2.ref=a2.ref,c2}__name(Pg,"Pg");function Rg(a2,b2,c2,d,e3,f2){var g2=2;if(d=a2,typeof a2=="function")aj(a2)&&(g2=1);else if(typeof a2=="string")g2=5;else a:switch(a2){case ya:return Tg(c2.children,e3,f2,b2);case za:g2=8,e3|=8;break;case Aa:return a2=Bg(12,c2,b2,e3|2),a2.elementType=Aa,a2.lanes=f2,a2;case Ea:return a2=Bg(13,c2,b2,e3),a2.elementType=Ea,a2.lanes=f2,a2;case Fa:return a2=Bg(19,c2,b2,e3),a2.elementType=Fa,a2.lanes=f2,a2;case Ia:return pj(c2,e3,f2,b2);default:if(typeof a2=="object"&&a2!==null)switch(a2.$$typeof){case Ba:g2=10;break a;case Ca:g2=9;break a;case Da:g2=11;break a;case Ga:g2=14;break a;case Ha:g2=16,d=null;break a}throw Error(p2(130,a2==null?a2:typeof a2,""))}return b2=Bg(g2,c2,b2,e3),b2.elementType=a2,b2.type=d,b2.lanes=f2,b2}__name(Rg,"Rg");function Tg(a2,b2,c2,d){return a2=Bg(7,a2,d,b2),a2.lanes=c2,a2}__name(Tg,"Tg");function pj(a2,b2,c2,d){return a2=Bg(22,a2,d,b2),a2.elementType=Ia,a2.lanes=c2,a2.stateNode={isHidden:!1},a2}__name(pj,"pj");function Qg(a2,b2,c2){return a2=Bg(6,a2,null,b2),a2.lanes=c2,a2}__name(Qg,"Qg");function Sg(a2,b2,c2){return b2=Bg(4,a2.children!==null?a2.children:[],a2.key,b2),b2.lanes=c2,b2.stateNode={containerInfo:a2.containerInfo,pendingChildren:null,implementation:a2.implementation},b2}__name(Sg,"Sg");function al(a2,b2,c2,d,e3){this.tag=b2,this.containerInfo=a2,this.finishedWork=this.pingCache=this.current=this.pendingChildren=null,this.timeoutHandle=-1,this.callbackNode=this.pendingContext=this.context=null,this.callbackPriority=0,this.eventTimes=zc(0),this.expirationTimes=zc(-1),this.entangledLanes=this.finishedLanes=this.mutableReadLanes=this.expiredLanes=this.pingedLanes=this.suspendedLanes=this.pendingLanes=0,this.entanglements=zc(0),this.identifierPrefix=d,this.onRecoverableError=e3,this.mutableSourceEagerHydrationData=null}__name(al,"al");function bl(a2,b2,c2,d,e3,f2,g2,h2,k2){return a2=new al(a2,b2,c2,h2,k2),b2===1?(b2=1,f2===!0&&(b2|=8)):b2=0,f2=Bg(3,null,null,b2),a2.current=f2,f2.stateNode=a2,f2.memoizedState={element:d,isDehydrated:c2,cache:null,transitions:null,pendingSuspenseBoundaries:null},kh(f2),a2}__name(bl,"bl");function cl(a2,b2,c2){var d=3"u"||typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.checkDCE!="function"))try{__REACT_DEVTOOLS_GLOBAL_HOOK__.checkDCE(checkDCE)}catch(err){console.error(err)}}return __name(checkDCE,"checkDCE"),checkDCE(),reactDom.exports=requireReactDom_production_min(),reactDom.exports}__name(requireReactDom,"requireReactDom");var hasRequiredClient;function requireClient(){if(hasRequiredClient)return client;hasRequiredClient=1;var m2=requireReactDom();return client.createRoot=m2.createRoot,client.hydrateRoot=m2.hydrateRoot,client}__name(requireClient,"requireClient");var clientExports=requireClient();const ReactDOM$2=getDefaultExportFromCjs(clientExports);var reactDomExports=requireReactDom();const ReactDOM=getDefaultExportFromCjs(reactDomExports),ReactDOM$1=_mergeNamespaces({__proto__:null,default:ReactDOM},[reactDomExports]);function _extends$x(){return _extends$x=Object.assign?Object.assign.bind():function(target){for(var i2=1;i2"u")throw new Error(message)}__name(invariant$1,"invariant$1");function warning(cond,message){if(!cond){typeof console<"u"&&console.warn(message);try{throw new Error(message)}catch{}}}__name(warning,"warning");function createKey(){return Math.random().toString(36).substr(2,8)}__name(createKey,"createKey");function getHistoryState(location2,index2){return{usr:location2.state,key:location2.key,idx:index2}}__name(getHistoryState,"getHistoryState");function createLocation$1(current,to2,state,key){return state===void 0&&(state=null),_extends$x({pathname:typeof current=="string"?current:current.pathname,search:"",hash:""},typeof to2=="string"?parsePath(to2):to2,{state,key:to2&&to2.key||key||createKey()})}__name(createLocation$1,"createLocation$1");function createPath(_ref){let{pathname="/",search:search2="",hash=""}=_ref;return search2&&search2!=="?"&&(pathname+=search2.charAt(0)==="?"?search2:"?"+search2),hash&&hash!=="#"&&(pathname+=hash.charAt(0)==="#"?hash:"#"+hash),pathname}__name(createPath,"createPath");function parsePath(path2){let parsedPath={};if(path2){let hashIndex=path2.indexOf("#");hashIndex>=0&&(parsedPath.hash=path2.substr(hashIndex),path2=path2.substr(0,hashIndex));let searchIndex=path2.indexOf("?");searchIndex>=0&&(parsedPath.search=path2.substr(searchIndex),path2=path2.substr(0,searchIndex)),path2&&(parsedPath.pathname=path2)}return parsedPath}__name(parsePath,"parsePath");function getUrlBasedHistory(getLocation,createHref,validateLocation,options){options===void 0&&(options={});let{window:window2=document.defaultView,v5Compat=!1}=options,globalHistory=window2.history,action=Action.Pop,listener=null,index2=getIndex();index2==null&&(index2=0,globalHistory.replaceState(_extends$x({},globalHistory.state,{idx:index2}),""));function getIndex(){return(globalHistory.state||{idx:null}).idx}__name(getIndex,"getIndex");function handlePop(){action=Action.Pop;let nextIndex=getIndex(),delta=nextIndex==null?null:nextIndex-index2;index2=nextIndex,listener&&listener({action,location:history.location,delta})}__name(handlePop,"handlePop");function push2(to2,state){action=Action.Push;let location2=createLocation$1(history.location,to2,state);validateLocation&&validateLocation(location2,to2),index2=getIndex()+1;let historyState=getHistoryState(location2,index2),url=history.createHref(location2);try{globalHistory.pushState(historyState,"",url)}catch(error){if(error instanceof DOMException&&error.name==="DataCloneError")throw error;window2.location.assign(url)}v5Compat&&listener&&listener({action,location:history.location,delta:1})}__name(push2,"push");function replace2(to2,state){action=Action.Replace;let location2=createLocation$1(history.location,to2,state);validateLocation&&validateLocation(location2,to2),index2=getIndex();let historyState=getHistoryState(location2,index2),url=history.createHref(location2);globalHistory.replaceState(historyState,"",url),v5Compat&&listener&&listener({action,location:history.location,delta:0})}__name(replace2,"replace2");function createURL(to2){let base=window2.location.origin!=="null"?window2.location.origin:window2.location.href,href=typeof to2=="string"?to2:createPath(to2);return href=href.replace(/ $/,"%20"),invariant$1(base,"No window.location.(origin|href) available to create URL for href: "+href),new URL(href,base)}__name(createURL,"createURL");let history={get action(){return action},get location(){return getLocation(window2,globalHistory)},listen(fn2){if(listener)throw new Error("A history only accepts one active listener");return window2.addEventListener(PopStateEventType,handlePop),listener=fn2,()=>{window2.removeEventListener(PopStateEventType,handlePop),listener=null}},createHref(to2){return createHref(window2,to2)},createURL,encodeLocation(to2){let url=createURL(to2);return{pathname:url.pathname,search:url.search,hash:url.hash}},push:push2,replace:replace2,go(n2){return globalHistory.go(n2)}};return history}__name(getUrlBasedHistory,"getUrlBasedHistory");var ResultType;(function(ResultType2){ResultType2.data="data",ResultType2.deferred="deferred",ResultType2.redirect="redirect",ResultType2.error="error"})(ResultType||(ResultType={}));const immutableRouteKeys=new Set(["lazy","caseSensitive","path","id","index","children"]);function isIndexRoute(route){return route.index===!0}__name(isIndexRoute,"isIndexRoute");function convertRoutesToDataRoutes(routes,mapRouteProperties2,parentPath,manifest){return parentPath===void 0&&(parentPath=[]),manifest===void 0&&(manifest={}),routes.map((route,index2)=>{let treePath=[...parentPath,String(index2)],id=typeof route.id=="string"?route.id:treePath.join("-");if(invariant$1(route.index!==!0||!route.children,"Cannot specify children on an index route"),invariant$1(!manifest[id],'Found a route id collision on id "'+id+`". Route id's must be globally unique within Data Router usages`),isIndexRoute(route)){let indexRoute=_extends$x({},route,mapRouteProperties2(route),{id});return manifest[id]=indexRoute,indexRoute}else{let pathOrLayoutRoute=_extends$x({},route,mapRouteProperties2(route),{id,children:void 0});return manifest[id]=pathOrLayoutRoute,route.children&&(pathOrLayoutRoute.children=convertRoutesToDataRoutes(route.children,mapRouteProperties2,treePath,manifest)),pathOrLayoutRoute}})}__name(convertRoutesToDataRoutes,"convertRoutesToDataRoutes");function matchRoutes(routes,locationArg,basename2){return basename2===void 0&&(basename2="/"),matchRoutesImpl(routes,locationArg,basename2,!1)}__name(matchRoutes,"matchRoutes");function matchRoutesImpl(routes,locationArg,basename2,allowPartial){let location2=typeof locationArg=="string"?parsePath(locationArg):locationArg,pathname=stripBasename(location2.pathname||"/",basename2);if(pathname==null)return null;let branches=flattenRoutes(routes);rankRouteBranches(branches);let matches=null;for(let i2=0;matches==null&&i2{let meta={relativePath:relativePath===void 0?route.path||"":relativePath,caseSensitive:route.caseSensitive===!0,childrenIndex:index2,route};meta.relativePath.startsWith("/")&&(invariant$1(meta.relativePath.startsWith(parentPath),'Absolute route path "'+meta.relativePath+'" nested under path '+('"'+parentPath+'" is not valid. An absolute child route path ')+"must start with the combined path of all its parent routes."),meta.relativePath=meta.relativePath.slice(parentPath.length));let path2=joinPaths([parentPath,meta.relativePath]),routesMeta=parentsMeta.concat(meta);route.children&&route.children.length>0&&(invariant$1(route.index!==!0,"Index routes must not have child routes. Please remove "+('all child routes from route path "'+path2+'".')),flattenRoutes(route.children,branches,routesMeta,path2)),!(route.path==null&&!route.index)&&branches.push({path:path2,score:computeScore(path2,route.index),routesMeta})},"flattenRoute");return routes.forEach((route,index2)=>{var _route$path;if(route.path===""||!((_route$path=route.path)!=null&&_route$path.includes("?")))flattenRoute(route,index2);else for(let exploded of explodeOptionalSegments(route.path))flattenRoute(route,index2,exploded)}),branches}__name(flattenRoutes,"flattenRoutes");function explodeOptionalSegments(path2){let segments=path2.split("/");if(segments.length===0)return[];let[first,...rest]=segments,isOptional=first.endsWith("?"),required=first.replace(/\?$/,"");if(rest.length===0)return isOptional?[required,""]:[required];let restExploded=explodeOptionalSegments(rest.join("/")),result=[];return result.push(...restExploded.map(subpath=>subpath===""?required:[required,subpath].join("/"))),isOptional&&result.push(...restExploded),result.map(exploded=>path2.startsWith("/")&&exploded===""?"/":exploded)}__name(explodeOptionalSegments,"explodeOptionalSegments");function rankRouteBranches(branches){branches.sort((a2,b2)=>a2.score!==b2.score?b2.score-a2.score:compareIndexes(a2.routesMeta.map(meta=>meta.childrenIndex),b2.routesMeta.map(meta=>meta.childrenIndex)))}__name(rankRouteBranches,"rankRouteBranches");const paramRe=/^:[\w-]+$/,dynamicSegmentValue=3,indexRouteValue=2,emptySegmentValue=1,staticSegmentValue=10,splatPenalty=-2,isSplat=__name(s2=>s2==="*","isSplat");function computeScore(path2,index2){let segments=path2.split("/"),initialScore=segments.length;return segments.some(isSplat)&&(initialScore+=splatPenalty),index2&&(initialScore+=indexRouteValue),segments.filter(s2=>!isSplat(s2)).reduce((score,segment)=>score+(paramRe.test(segment)?dynamicSegmentValue:segment===""?emptySegmentValue:staticSegmentValue),initialScore)}__name(computeScore,"computeScore");function compareIndexes(a2,b2){return a2.length===b2.length&&a2.slice(0,-1).every((n2,i2)=>n2===b2[i2])?a2[a2.length-1]-b2[b2.length-1]:0}__name(compareIndexes,"compareIndexes");function matchRouteBranch(branch,pathname,allowPartial){allowPartial===void 0&&(allowPartial=!1);let{routesMeta}=branch,matchedParams={},matchedPathname="/",matches=[];for(let i2=0;i2{let{paramName,isOptional}=_ref;if(paramName==="*"){let splatValue=captureGroups[index2]||"";pathnameBase=matchedPathname.slice(0,matchedPathname.length-splatValue.length).replace(/(.)\/+$/,"$1")}const value2=captureGroups[index2];return isOptional&&!value2?memo2[paramName]=void 0:memo2[paramName]=(value2||"").replace(/%2F/g,"/"),memo2},{}),pathname:matchedPathname,pathnameBase,pattern}}__name(matchPath,"matchPath");function compilePath(path2,caseSensitive,end){caseSensitive===void 0&&(caseSensitive=!1),end===void 0&&(end=!0),warning(path2==="*"||!path2.endsWith("*")||path2.endsWith("/*"),'Route path "'+path2+'" will be treated as if it were '+('"'+path2.replace(/\*$/,"/*")+'" because the `*` character must ')+"always follow a `/` in the pattern. To get rid of this warning, "+('please change the route path to "'+path2.replace(/\*$/,"/*")+'".'));let params=[],regexpSource="^"+path2.replace(/\/*\*?$/,"").replace(/^\/*/,"/").replace(/[\\.*+^${}|()[\]]/g,"\\$&").replace(/\/:([\w-]+)(\?)?/g,(_2,paramName,isOptional)=>(params.push({paramName,isOptional:isOptional!=null}),isOptional?"/?([^\\/]+)?":"/([^\\/]+)"));return path2.endsWith("*")?(params.push({paramName:"*"}),regexpSource+=path2==="*"||path2==="/*"?"(.*)$":"(?:\\/(.+)|\\/*)$"):end?regexpSource+="\\/*$":path2!==""&&path2!=="/"&&(regexpSource+="(?:(?=\\/|$))"),[new RegExp(regexpSource,caseSensitive?void 0:"i"),params]}__name(compilePath,"compilePath");function decodePath(value2){try{return value2.split("/").map(v2=>decodeURIComponent(v2).replace(/\//g,"%2F")).join("/")}catch(error){return warning(!1,'The URL path "'+value2+'" could not be decoded because it is is a malformed URL segment. This is probably due to a bad percent '+("encoding ("+error+").")),value2}}__name(decodePath,"decodePath");function stripBasename(pathname,basename2){if(basename2==="/")return pathname;if(!pathname.toLowerCase().startsWith(basename2.toLowerCase()))return null;let startIndex=basename2.endsWith("/")?basename2.length-1:basename2.length,nextChar=pathname.charAt(startIndex);return nextChar&&nextChar!=="/"?null:pathname.slice(startIndex)||"/"}__name(stripBasename,"stripBasename");const ABSOLUTE_URL_REGEX$1=/^(?:[a-z][a-z0-9+.-]*:|\/\/)/i,isAbsoluteUrl=__name(url=>ABSOLUTE_URL_REGEX$1.test(url),"isAbsoluteUrl");function resolvePath(to2,fromPathname){fromPathname===void 0&&(fromPathname="/");let{pathname:toPathname,search:search2="",hash=""}=typeof to2=="string"?parsePath(to2):to2,pathname;if(toPathname)if(isAbsoluteUrl(toPathname))pathname=toPathname;else{if(toPathname.includes("//")){let oldPathname=toPathname;toPathname=toPathname.replace(/\/\/+/g,"/"),warning(!1,"Pathnames cannot have embedded double slashes - normalizing "+(oldPathname+" -> "+toPathname))}toPathname.startsWith("/")?pathname=resolvePathname(toPathname.substring(1),"/"):pathname=resolvePathname(toPathname,fromPathname)}else pathname=fromPathname;return{pathname,search:normalizeSearch(search2),hash:normalizeHash(hash)}}__name(resolvePath,"resolvePath");function resolvePathname(relativePath,fromPathname){let segments=fromPathname.replace(/\/+$/,"").split("/");return relativePath.split("/").forEach(segment=>{segment===".."?segments.length>1&&segments.pop():segment!=="."&&segments.push(segment)}),segments.length>1?segments.join("/"):"/"}__name(resolvePathname,"resolvePathname");function getInvalidPathError(char,field,dest,path2){return"Cannot include a '"+char+"' character in a manually specified "+("`to."+field+"` field ["+JSON.stringify(path2)+"]. Please separate it out to the ")+("`to."+dest+"` field. Alternatively you may provide the full path as ")+'a string in and the router will parse it for you.'}__name(getInvalidPathError,"getInvalidPathError");function getPathContributingMatches(matches){return matches.filter((match,index2)=>index2===0||match.route.path&&match.route.path.length>0)}__name(getPathContributingMatches,"getPathContributingMatches");function getResolveToMatches(matches,v7_relativeSplatPath){let pathMatches=getPathContributingMatches(matches);return v7_relativeSplatPath?pathMatches.map((match,idx)=>idx===pathMatches.length-1?match.pathname:match.pathnameBase):pathMatches.map(match=>match.pathnameBase)}__name(getResolveToMatches,"getResolveToMatches");function resolveTo(toArg,routePathnames,locationPathname,isPathRelative){isPathRelative===void 0&&(isPathRelative=!1);let to2;typeof toArg=="string"?to2=parsePath(toArg):(to2=_extends$x({},toArg),invariant$1(!to2.pathname||!to2.pathname.includes("?"),getInvalidPathError("?","pathname","search",to2)),invariant$1(!to2.pathname||!to2.pathname.includes("#"),getInvalidPathError("#","pathname","hash",to2)),invariant$1(!to2.search||!to2.search.includes("#"),getInvalidPathError("#","search","hash",to2)));let isEmptyPath=toArg===""||to2.pathname==="",toPathname=isEmptyPath?"/":to2.pathname,from;if(toPathname==null)from=locationPathname;else{let routePathnameIndex=routePathnames.length-1;if(!isPathRelative&&toPathname.startsWith("..")){let toSegments=toPathname.split("/");for(;toSegments[0]==="..";)toSegments.shift(),routePathnameIndex-=1;to2.pathname=toSegments.join("/")}from=routePathnameIndex>=0?routePathnames[routePathnameIndex]:"/"}let path2=resolvePath(to2,from),hasExplicitTrailingSlash=toPathname&&toPathname!=="/"&&toPathname.endsWith("/"),hasCurrentTrailingSlash=(isEmptyPath||toPathname===".")&&locationPathname.endsWith("/");return!path2.pathname.endsWith("/")&&(hasExplicitTrailingSlash||hasCurrentTrailingSlash)&&(path2.pathname+="/"),path2}__name(resolveTo,"resolveTo");const joinPaths=__name(paths=>paths.join("/").replace(/\/\/+/g,"/"),"joinPaths"),normalizePathname=__name(pathname=>pathname.replace(/\/+$/,"").replace(/^\/*/,"/"),"normalizePathname"),normalizeSearch=__name(search2=>!search2||search2==="?"?"":search2.startsWith("?")?search2:"?"+search2,"normalizeSearch"),normalizeHash=__name(hash=>!hash||hash==="#"?"":hash.startsWith("#")?hash:"#"+hash,"normalizeHash"),_ErrorResponseImpl=class _ErrorResponseImpl{constructor(status,statusText,data2,internal){internal===void 0&&(internal=!1),this.status=status,this.statusText=statusText||"",this.internal=internal,data2 instanceof Error?(this.data=data2.toString(),this.error=data2):this.data=data2}};__name(_ErrorResponseImpl,"ErrorResponseImpl");let ErrorResponseImpl=_ErrorResponseImpl;function isRouteErrorResponse(error){return error!=null&&typeof error.status=="number"&&typeof error.statusText=="string"&&typeof error.internal=="boolean"&&"data"in error}__name(isRouteErrorResponse,"isRouteErrorResponse");const validMutationMethodsArr=["post","put","patch","delete"],validMutationMethods=new Set(validMutationMethodsArr),validRequestMethodsArr=["get",...validMutationMethodsArr],validRequestMethods=new Set(validRequestMethodsArr),redirectStatusCodes=new Set([301,302,303,307,308]),redirectPreserveMethodStatusCodes=new Set([307,308]),IDLE_NAVIGATION={state:"idle",location:void 0,formMethod:void 0,formAction:void 0,formEncType:void 0,formData:void 0,json:void 0,text:void 0},IDLE_FETCHER={state:"idle",data:void 0,formMethod:void 0,formAction:void 0,formEncType:void 0,formData:void 0,json:void 0,text:void 0},IDLE_BLOCKER={state:"unblocked",proceed:void 0,reset:void 0,location:void 0},ABSOLUTE_URL_REGEX$2=/^(?:[a-z][a-z0-9+.-]*:|\/\/)/i,defaultMapRouteProperties=__name(route=>({hasErrorBoundary:!!route.hasErrorBoundary}),"defaultMapRouteProperties"),TRANSITIONS_STORAGE_KEY="remix-router-transitions";function createRouter(init){const routerWindow=init.window?init.window:typeof window<"u"?window:void 0,isBrowser2=typeof routerWindow<"u"&&typeof routerWindow.document<"u"&&typeof routerWindow.document.createElement<"u",isServer=!isBrowser2;invariant$1(init.routes.length>0,"You must provide a non-empty routes array to createRouter");let mapRouteProperties2;if(init.mapRouteProperties)mapRouteProperties2=init.mapRouteProperties;else if(init.detectErrorBoundary){let detectErrorBoundary=init.detectErrorBoundary;mapRouteProperties2=__name(route=>({hasErrorBoundary:detectErrorBoundary(route)}),"mapRouteProperties")}else mapRouteProperties2=defaultMapRouteProperties;let manifest={},dataRoutes=convertRoutesToDataRoutes(init.routes,mapRouteProperties2,void 0,manifest),inFlightDataRoutes,basename2=init.basename||"/",dataStrategyImpl=init.dataStrategy||defaultDataStrategy,patchRoutesOnNavigationImpl=init.patchRoutesOnNavigation,future=_extends$x({v7_fetcherPersist:!1,v7_normalizeFormMethod:!1,v7_partialHydration:!1,v7_prependBasename:!1,v7_relativeSplatPath:!1,v7_skipActionErrorRevalidation:!1},init.future),unlistenHistory=null,subscribers=new Set,savedScrollPositions=null,getScrollRestorationKey=null,getScrollPosition=null,initialScrollRestored=init.hydrationData!=null,initialMatches=matchRoutes(dataRoutes,init.history.location,basename2),initialMatchesIsFOW=!1,initialErrors=null;if(initialMatches==null&&!patchRoutesOnNavigationImpl){let error=getInternalRouterError(404,{pathname:init.history.location.pathname}),{matches,route}=getShortCircuitMatches(dataRoutes);initialMatches=matches,initialErrors={[route.id]:error}}initialMatches&&!init.hydrationData&&checkFogOfWar(initialMatches,dataRoutes,init.history.location.pathname).active&&(initialMatches=null);let initialized;if(initialMatches)if(initialMatches.some(m2=>m2.route.lazy))initialized=!1;else if(!initialMatches.some(m2=>m2.route.loader))initialized=!0;else if(future.v7_partialHydration){let loaderData=init.hydrationData?init.hydrationData.loaderData:null,errors=init.hydrationData?init.hydrationData.errors:null;if(errors){let idx=initialMatches.findIndex(m2=>errors[m2.route.id]!==void 0);initialized=initialMatches.slice(0,idx+1).every(m2=>!shouldLoadRouteOnHydration(m2.route,loaderData,errors))}else initialized=initialMatches.every(m2=>!shouldLoadRouteOnHydration(m2.route,loaderData,errors))}else initialized=init.hydrationData!=null;else if(initialized=!1,initialMatches=[],future.v7_partialHydration){let fogOfWar=checkFogOfWar(null,dataRoutes,init.history.location.pathname);fogOfWar.active&&fogOfWar.matches&&(initialMatchesIsFOW=!0,initialMatches=fogOfWar.matches)}let router2,state={historyAction:init.history.action,location:init.history.location,matches:initialMatches,initialized,navigation:IDLE_NAVIGATION,restoreScrollPosition:init.hydrationData!=null?!1:null,preventScrollReset:!1,revalidation:"idle",loaderData:init.hydrationData&&init.hydrationData.loaderData||{},actionData:init.hydrationData&&init.hydrationData.actionData||null,errors:init.hydrationData&&init.hydrationData.errors||initialErrors,fetchers:new Map,blockers:new Map},pendingAction=Action.Pop,pendingPreventScrollReset=!1,pendingNavigationController,pendingViewTransitionEnabled=!1,appliedViewTransitions=new Map,removePageHideEventListener=null,isUninterruptedRevalidation=!1,isRevalidationRequired=!1,cancelledDeferredRoutes=[],cancelledFetcherLoads=new Set,fetchControllers=new Map,incrementingLoadId=0,pendingNavigationLoadId=-1,fetchReloadIds=new Map,fetchRedirectIds=new Set,fetchLoadMatches=new Map,activeFetchers=new Map,deletedFetchers=new Set,activeDeferreds=new Map,blockerFunctions=new Map,unblockBlockerHistoryUpdate;function initialize(){if(unlistenHistory=init.history.listen(_ref=>{let{action:historyAction,location:location2,delta}=_ref;if(unblockBlockerHistoryUpdate){unblockBlockerHistoryUpdate(),unblockBlockerHistoryUpdate=void 0;return}warning(blockerFunctions.size===0||delta!=null,"You are trying to use a blocker on a POP navigation to a location that was not created by @remix-run/router. This will fail silently in production. This can happen if you are navigating outside the router via `window.history.pushState`/`window.location.hash` instead of using router navigation APIs. This can also happen if you are using createHashRouter and the user manually changes the URL.");let blockerKey=shouldBlockNavigation({currentLocation:state.location,nextLocation:location2,historyAction});if(blockerKey&&delta!=null){let nextHistoryUpdatePromise=new Promise(resolve=>{unblockBlockerHistoryUpdate=resolve});init.history.go(delta*-1),updateBlocker(blockerKey,{state:"blocked",location:location2,proceed(){updateBlocker(blockerKey,{state:"proceeding",proceed:void 0,reset:void 0,location:location2}),nextHistoryUpdatePromise.then(()=>init.history.go(delta))},reset(){let blockers=new Map(state.blockers);blockers.set(blockerKey,IDLE_BLOCKER),updateState({blockers})}});return}return startNavigation(historyAction,location2)}),isBrowser2){restoreAppliedTransitions(routerWindow,appliedViewTransitions);let _saveAppliedTransitions=__name(()=>persistAppliedTransitions(routerWindow,appliedViewTransitions),"_saveAppliedTransitions");routerWindow.addEventListener("pagehide",_saveAppliedTransitions),removePageHideEventListener=__name(()=>routerWindow.removeEventListener("pagehide",_saveAppliedTransitions),"removePageHideEventListener")}return state.initialized||startNavigation(Action.Pop,state.location,{initialHydration:!0}),router2}__name(initialize,"initialize");function dispose(){unlistenHistory&&unlistenHistory(),removePageHideEventListener&&removePageHideEventListener(),subscribers.clear(),pendingNavigationController&&pendingNavigationController.abort(),state.fetchers.forEach((_2,key)=>deleteFetcher(key)),state.blockers.forEach((_2,key)=>deleteBlocker(key))}__name(dispose,"dispose");function subscribe2(fn2){return subscribers.add(fn2),()=>subscribers.delete(fn2)}__name(subscribe2,"subscribe");function updateState(newState,opts){opts===void 0&&(opts={}),state=_extends$x({},state,newState);let completedFetchers=[],deletedFetchersKeys=[];future.v7_fetcherPersist&&state.fetchers.forEach((fetcher,key)=>{fetcher.state==="idle"&&(deletedFetchers.has(key)?deletedFetchersKeys.push(key):completedFetchers.push(key))}),deletedFetchers.forEach(key=>{!state.fetchers.has(key)&&!fetchControllers.has(key)&&deletedFetchersKeys.push(key)}),[...subscribers].forEach(subscriber=>subscriber(state,{deletedFetchers:deletedFetchersKeys,viewTransitionOpts:opts.viewTransitionOpts,flushSync:opts.flushSync===!0})),future.v7_fetcherPersist?(completedFetchers.forEach(key=>state.fetchers.delete(key)),deletedFetchersKeys.forEach(key=>deleteFetcher(key))):deletedFetchersKeys.forEach(key=>deletedFetchers.delete(key))}__name(updateState,"updateState");function completeNavigation(location2,newState,_temp){var _location$state,_location$state2;let{flushSync}=_temp===void 0?{}:_temp,isActionReload=state.actionData!=null&&state.navigation.formMethod!=null&&isMutationMethod(state.navigation.formMethod)&&state.navigation.state==="loading"&&((_location$state=location2.state)==null?void 0:_location$state._isRedirect)!==!0,actionData;newState.actionData?Object.keys(newState.actionData).length>0?actionData=newState.actionData:actionData=null:isActionReload?actionData=state.actionData:actionData=null;let loaderData=newState.loaderData?mergeLoaderData(state.loaderData,newState.loaderData,newState.matches||[],newState.errors):state.loaderData,blockers=state.blockers;blockers.size>0&&(blockers=new Map(blockers),blockers.forEach((_2,k2)=>blockers.set(k2,IDLE_BLOCKER)));let preventScrollReset=pendingPreventScrollReset===!0||state.navigation.formMethod!=null&&isMutationMethod(state.navigation.formMethod)&&((_location$state2=location2.state)==null?void 0:_location$state2._isRedirect)!==!0;inFlightDataRoutes&&(dataRoutes=inFlightDataRoutes,inFlightDataRoutes=void 0),isUninterruptedRevalidation||pendingAction===Action.Pop||(pendingAction===Action.Push?init.history.push(location2,location2.state):pendingAction===Action.Replace&&init.history.replace(location2,location2.state));let viewTransitionOpts;if(pendingAction===Action.Pop){let priorPaths=appliedViewTransitions.get(state.location.pathname);priorPaths&&priorPaths.has(location2.pathname)?viewTransitionOpts={currentLocation:state.location,nextLocation:location2}:appliedViewTransitions.has(location2.pathname)&&(viewTransitionOpts={currentLocation:location2,nextLocation:state.location})}else if(pendingViewTransitionEnabled){let toPaths=appliedViewTransitions.get(state.location.pathname);toPaths?toPaths.add(location2.pathname):(toPaths=new Set([location2.pathname]),appliedViewTransitions.set(state.location.pathname,toPaths)),viewTransitionOpts={currentLocation:state.location,nextLocation:location2}}updateState(_extends$x({},newState,{actionData,loaderData,historyAction:pendingAction,location:location2,initialized:!0,navigation:IDLE_NAVIGATION,revalidation:"idle",restoreScrollPosition:getSavedScrollPosition(location2,newState.matches||state.matches),preventScrollReset,blockers}),{viewTransitionOpts,flushSync:flushSync===!0}),pendingAction=Action.Pop,pendingPreventScrollReset=!1,pendingViewTransitionEnabled=!1,isUninterruptedRevalidation=!1,isRevalidationRequired=!1,cancelledDeferredRoutes=[]}__name(completeNavigation,"completeNavigation");async function navigate(to2,opts){if(typeof to2=="number"){init.history.go(to2);return}let normalizedPath=normalizeTo(state.location,state.matches,basename2,future.v7_prependBasename,to2,future.v7_relativeSplatPath,opts?.fromRouteId,opts?.relative),{path:path2,submission,error}=normalizeNavigateOptions(future.v7_normalizeFormMethod,!1,normalizedPath,opts),currentLocation=state.location,nextLocation=createLocation$1(state.location,path2,opts&&opts.state);nextLocation=_extends$x({},nextLocation,init.history.encodeLocation(nextLocation));let userReplace=opts&&opts.replace!=null?opts.replace:void 0,historyAction=Action.Push;userReplace===!0?historyAction=Action.Replace:userReplace===!1||submission!=null&&isMutationMethod(submission.formMethod)&&submission.formAction===state.location.pathname+state.location.search&&(historyAction=Action.Replace);let preventScrollReset=opts&&"preventScrollReset"in opts?opts.preventScrollReset===!0:void 0,flushSync=(opts&&opts.flushSync)===!0,blockerKey=shouldBlockNavigation({currentLocation,nextLocation,historyAction});if(blockerKey){updateBlocker(blockerKey,{state:"blocked",location:nextLocation,proceed(){updateBlocker(blockerKey,{state:"proceeding",proceed:void 0,reset:void 0,location:nextLocation}),navigate(to2,opts)},reset(){let blockers=new Map(state.blockers);blockers.set(blockerKey,IDLE_BLOCKER),updateState({blockers})}});return}return await startNavigation(historyAction,nextLocation,{submission,pendingError:error,preventScrollReset,replace:opts&&opts.replace,enableViewTransition:opts&&opts.viewTransition,flushSync})}__name(navigate,"navigate");function revalidate(){if(interruptActiveLoads(),updateState({revalidation:"loading"}),state.navigation.state!=="submitting"){if(state.navigation.state==="idle"){startNavigation(state.historyAction,state.location,{startUninterruptedRevalidation:!0});return}startNavigation(pendingAction||state.historyAction,state.navigation.location,{overrideNavigation:state.navigation,enableViewTransition:pendingViewTransitionEnabled===!0})}}__name(revalidate,"revalidate");async function startNavigation(historyAction,location2,opts){pendingNavigationController&&pendingNavigationController.abort(),pendingNavigationController=null,pendingAction=historyAction,isUninterruptedRevalidation=(opts&&opts.startUninterruptedRevalidation)===!0,saveScrollPosition(state.location,state.matches),pendingPreventScrollReset=(opts&&opts.preventScrollReset)===!0,pendingViewTransitionEnabled=(opts&&opts.enableViewTransition)===!0;let routesToUse=inFlightDataRoutes||dataRoutes,loadingNavigation=opts&&opts.overrideNavigation,matches=opts!=null&&opts.initialHydration&&state.matches&&state.matches.length>0&&!initialMatchesIsFOW?state.matches:matchRoutes(routesToUse,location2,basename2),flushSync=(opts&&opts.flushSync)===!0;if(matches&&state.initialized&&!isRevalidationRequired&&isHashChangeOnly(state.location,location2)&&!(opts&&opts.submission&&isMutationMethod(opts.submission.formMethod))){completeNavigation(location2,{matches},{flushSync});return}let fogOfWar=checkFogOfWar(matches,routesToUse,location2.pathname);if(fogOfWar.active&&fogOfWar.matches&&(matches=fogOfWar.matches),!matches){let{error,notFoundMatches,route}=handleNavigational404(location2.pathname);completeNavigation(location2,{matches:notFoundMatches,loaderData:{},errors:{[route.id]:error}},{flushSync});return}pendingNavigationController=new AbortController;let request=createClientSideRequest(init.history,location2,pendingNavigationController.signal,opts&&opts.submission),pendingActionResult;if(opts&&opts.pendingError)pendingActionResult=[findNearestBoundary(matches).route.id,{type:ResultType.error,error:opts.pendingError}];else if(opts&&opts.submission&&isMutationMethod(opts.submission.formMethod)){let actionResult=await handleAction(request,location2,opts.submission,matches,fogOfWar.active,{replace:opts.replace,flushSync});if(actionResult.shortCircuited)return;if(actionResult.pendingActionResult){let[routeId,result]=actionResult.pendingActionResult;if(isErrorResult(result)&&isRouteErrorResponse(result.error)&&result.error.status===404){pendingNavigationController=null,completeNavigation(location2,{matches:actionResult.matches,loaderData:{},errors:{[routeId]:result.error}});return}}matches=actionResult.matches||matches,pendingActionResult=actionResult.pendingActionResult,loadingNavigation=getLoadingNavigation(location2,opts.submission),flushSync=!1,fogOfWar.active=!1,request=createClientSideRequest(init.history,request.url,request.signal)}let{shortCircuited,matches:updatedMatches,loaderData,errors}=await handleLoaders(request,location2,matches,fogOfWar.active,loadingNavigation,opts&&opts.submission,opts&&opts.fetcherSubmission,opts&&opts.replace,opts&&opts.initialHydration===!0,flushSync,pendingActionResult);shortCircuited||(pendingNavigationController=null,completeNavigation(location2,_extends$x({matches:updatedMatches||matches},getActionDataForCommit(pendingActionResult),{loaderData,errors})))}__name(startNavigation,"startNavigation");async function handleAction(request,location2,submission,matches,isFogOfWar,opts){opts===void 0&&(opts={}),interruptActiveLoads();let navigation=getSubmittingNavigation(location2,submission);if(updateState({navigation},{flushSync:opts.flushSync===!0}),isFogOfWar){let discoverResult=await discoverRoutes(matches,location2.pathname,request.signal);if(discoverResult.type==="aborted")return{shortCircuited:!0};if(discoverResult.type==="error"){let boundaryId=findNearestBoundary(discoverResult.partialMatches).route.id;return{matches:discoverResult.partialMatches,pendingActionResult:[boundaryId,{type:ResultType.error,error:discoverResult.error}]}}else if(discoverResult.matches)matches=discoverResult.matches;else{let{notFoundMatches,error,route}=handleNavigational404(location2.pathname);return{matches:notFoundMatches,pendingActionResult:[route.id,{type:ResultType.error,error}]}}}let result,actionMatch=getTargetMatch(matches,location2);if(!actionMatch.route.action&&!actionMatch.route.lazy)result={type:ResultType.error,error:getInternalRouterError(405,{method:request.method,pathname:location2.pathname,routeId:actionMatch.route.id})};else if(result=(await callDataStrategy("action",state,request,[actionMatch],matches,null))[actionMatch.route.id],request.signal.aborted)return{shortCircuited:!0};if(isRedirectResult(result)){let replace2;return opts&&opts.replace!=null?replace2=opts.replace:replace2=normalizeRedirectLocation(result.response.headers.get("Location"),new URL(request.url),basename2,init.history)===state.location.pathname+state.location.search,await startRedirectNavigation(request,result,!0,{submission,replace:replace2}),{shortCircuited:!0}}if(isDeferredResult(result))throw getInternalRouterError(400,{type:"defer-action"});if(isErrorResult(result)){let boundaryMatch=findNearestBoundary(matches,actionMatch.route.id);return(opts&&opts.replace)!==!0&&(pendingAction=Action.Push),{matches,pendingActionResult:[boundaryMatch.route.id,result]}}return{matches,pendingActionResult:[actionMatch.route.id,result]}}__name(handleAction,"handleAction");async function handleLoaders(request,location2,matches,isFogOfWar,overrideNavigation,submission,fetcherSubmission,replace2,initialHydration,flushSync,pendingActionResult){let loadingNavigation=overrideNavigation||getLoadingNavigation(location2,submission),activeSubmission=submission||fetcherSubmission||getSubmissionFromNavigation(loadingNavigation),shouldUpdateNavigationState=!isUninterruptedRevalidation&&(!future.v7_partialHydration||!initialHydration);if(isFogOfWar){if(shouldUpdateNavigationState){let actionData=getUpdatedActionData(pendingActionResult);updateState(_extends$x({navigation:loadingNavigation},actionData!==void 0?{actionData}:{}),{flushSync})}let discoverResult=await discoverRoutes(matches,location2.pathname,request.signal);if(discoverResult.type==="aborted")return{shortCircuited:!0};if(discoverResult.type==="error"){let boundaryId=findNearestBoundary(discoverResult.partialMatches).route.id;return{matches:discoverResult.partialMatches,loaderData:{},errors:{[boundaryId]:discoverResult.error}}}else if(discoverResult.matches)matches=discoverResult.matches;else{let{error,notFoundMatches,route}=handleNavigational404(location2.pathname);return{matches:notFoundMatches,loaderData:{},errors:{[route.id]:error}}}}let routesToUse=inFlightDataRoutes||dataRoutes,[matchesToLoad,revalidatingFetchers]=getMatchesToLoad(init.history,state,matches,activeSubmission,location2,future.v7_partialHydration&&initialHydration===!0,future.v7_skipActionErrorRevalidation,isRevalidationRequired,cancelledDeferredRoutes,cancelledFetcherLoads,deletedFetchers,fetchLoadMatches,fetchRedirectIds,routesToUse,basename2,pendingActionResult);if(cancelActiveDeferreds(routeId=>!(matches&&matches.some(m2=>m2.route.id===routeId))||matchesToLoad&&matchesToLoad.some(m2=>m2.route.id===routeId)),pendingNavigationLoadId=++incrementingLoadId,matchesToLoad.length===0&&revalidatingFetchers.length===0){let updatedFetchers2=markFetchRedirectsDone();return completeNavigation(location2,_extends$x({matches,loaderData:{},errors:pendingActionResult&&isErrorResult(pendingActionResult[1])?{[pendingActionResult[0]]:pendingActionResult[1].error}:null},getActionDataForCommit(pendingActionResult),updatedFetchers2?{fetchers:new Map(state.fetchers)}:{}),{flushSync}),{shortCircuited:!0}}if(shouldUpdateNavigationState){let updates={};if(!isFogOfWar){updates.navigation=loadingNavigation;let actionData=getUpdatedActionData(pendingActionResult);actionData!==void 0&&(updates.actionData=actionData)}revalidatingFetchers.length>0&&(updates.fetchers=getUpdatedRevalidatingFetchers(revalidatingFetchers)),updateState(updates,{flushSync})}revalidatingFetchers.forEach(rf=>{abortFetcher(rf.key),rf.controller&&fetchControllers.set(rf.key,rf.controller)});let abortPendingFetchRevalidations=__name(()=>revalidatingFetchers.forEach(f2=>abortFetcher(f2.key)),"abortPendingFetchRevalidations");pendingNavigationController&&pendingNavigationController.signal.addEventListener("abort",abortPendingFetchRevalidations);let{loaderResults,fetcherResults}=await callLoadersAndMaybeResolveData(state,matches,matchesToLoad,revalidatingFetchers,request);if(request.signal.aborted)return{shortCircuited:!0};pendingNavigationController&&pendingNavigationController.signal.removeEventListener("abort",abortPendingFetchRevalidations),revalidatingFetchers.forEach(rf=>fetchControllers.delete(rf.key));let redirect3=findRedirect(loaderResults);if(redirect3)return await startRedirectNavigation(request,redirect3.result,!0,{replace:replace2}),{shortCircuited:!0};if(redirect3=findRedirect(fetcherResults),redirect3)return fetchRedirectIds.add(redirect3.key),await startRedirectNavigation(request,redirect3.result,!0,{replace:replace2}),{shortCircuited:!0};let{loaderData,errors}=processLoaderData(state,matches,loaderResults,pendingActionResult,revalidatingFetchers,fetcherResults,activeDeferreds);activeDeferreds.forEach((deferredData,routeId)=>{deferredData.subscribe(aborted=>{(aborted||deferredData.done)&&activeDeferreds.delete(routeId)})}),future.v7_partialHydration&&initialHydration&&state.errors&&(errors=_extends$x({},state.errors,errors));let updatedFetchers=markFetchRedirectsDone(),didAbortFetchLoads=abortStaleFetchLoads(pendingNavigationLoadId),shouldUpdateFetchers=updatedFetchers||didAbortFetchLoads||revalidatingFetchers.length>0;return _extends$x({matches,loaderData,errors},shouldUpdateFetchers?{fetchers:new Map(state.fetchers)}:{})}__name(handleLoaders,"handleLoaders");function getUpdatedActionData(pendingActionResult){if(pendingActionResult&&!isErrorResult(pendingActionResult[1]))return{[pendingActionResult[0]]:pendingActionResult[1].data};if(state.actionData)return Object.keys(state.actionData).length===0?null:state.actionData}__name(getUpdatedActionData,"getUpdatedActionData");function getUpdatedRevalidatingFetchers(revalidatingFetchers){return revalidatingFetchers.forEach(rf=>{let fetcher=state.fetchers.get(rf.key),revalidatingFetcher=getLoadingFetcher(void 0,fetcher?fetcher.data:void 0);state.fetchers.set(rf.key,revalidatingFetcher)}),new Map(state.fetchers)}__name(getUpdatedRevalidatingFetchers,"getUpdatedRevalidatingFetchers");function fetch2(key,routeId,href,opts){if(isServer)throw new Error("router.fetch() was called during the server render, but it shouldn't be. You are likely calling a useFetcher() method in the body of your component. Try moving it to a useEffect or a callback.");abortFetcher(key);let flushSync=(opts&&opts.flushSync)===!0,routesToUse=inFlightDataRoutes||dataRoutes,normalizedPath=normalizeTo(state.location,state.matches,basename2,future.v7_prependBasename,href,future.v7_relativeSplatPath,routeId,opts?.relative),matches=matchRoutes(routesToUse,normalizedPath,basename2),fogOfWar=checkFogOfWar(matches,routesToUse,normalizedPath);if(fogOfWar.active&&fogOfWar.matches&&(matches=fogOfWar.matches),!matches){setFetcherError(key,routeId,getInternalRouterError(404,{pathname:normalizedPath}),{flushSync});return}let{path:path2,submission,error}=normalizeNavigateOptions(future.v7_normalizeFormMethod,!0,normalizedPath,opts);if(error){setFetcherError(key,routeId,error,{flushSync});return}let match=getTargetMatch(matches,path2),preventScrollReset=(opts&&opts.preventScrollReset)===!0;if(submission&&isMutationMethod(submission.formMethod)){handleFetcherAction(key,routeId,path2,match,matches,fogOfWar.active,flushSync,preventScrollReset,submission);return}fetchLoadMatches.set(key,{routeId,path:path2}),handleFetcherLoader(key,routeId,path2,match,matches,fogOfWar.active,flushSync,preventScrollReset,submission)}__name(fetch2,"fetch");async function handleFetcherAction(key,routeId,path2,match,requestMatches,isFogOfWar,flushSync,preventScrollReset,submission){interruptActiveLoads(),fetchLoadMatches.delete(key);function detectAndHandle405Error(m2){if(!m2.route.action&&!m2.route.lazy){let error=getInternalRouterError(405,{method:submission.formMethod,pathname:path2,routeId});return setFetcherError(key,routeId,error,{flushSync}),!0}return!1}if(__name(detectAndHandle405Error,"detectAndHandle405Error"),!isFogOfWar&&detectAndHandle405Error(match))return;let existingFetcher=state.fetchers.get(key);updateFetcherState(key,getSubmittingFetcher(submission,existingFetcher),{flushSync});let abortController=new AbortController,fetchRequest=createClientSideRequest(init.history,path2,abortController.signal,submission);if(isFogOfWar){let discoverResult=await discoverRoutes(requestMatches,new URL(fetchRequest.url).pathname,fetchRequest.signal,key);if(discoverResult.type==="aborted")return;if(discoverResult.type==="error"){setFetcherError(key,routeId,discoverResult.error,{flushSync});return}else if(discoverResult.matches){if(requestMatches=discoverResult.matches,match=getTargetMatch(requestMatches,path2),detectAndHandle405Error(match))return}else{setFetcherError(key,routeId,getInternalRouterError(404,{pathname:path2}),{flushSync});return}}fetchControllers.set(key,abortController);let originatingLoadId=incrementingLoadId,actionResult=(await callDataStrategy("action",state,fetchRequest,[match],requestMatches,key))[match.route.id];if(fetchRequest.signal.aborted){fetchControllers.get(key)===abortController&&fetchControllers.delete(key);return}if(future.v7_fetcherPersist&&deletedFetchers.has(key)){if(isRedirectResult(actionResult)||isErrorResult(actionResult)){updateFetcherState(key,getDoneFetcher(void 0));return}}else{if(isRedirectResult(actionResult))if(fetchControllers.delete(key),pendingNavigationLoadId>originatingLoadId){updateFetcherState(key,getDoneFetcher(void 0));return}else return fetchRedirectIds.add(key),updateFetcherState(key,getLoadingFetcher(submission)),startRedirectNavigation(fetchRequest,actionResult,!1,{fetcherSubmission:submission,preventScrollReset});if(isErrorResult(actionResult)){setFetcherError(key,routeId,actionResult.error);return}}if(isDeferredResult(actionResult))throw getInternalRouterError(400,{type:"defer-action"});let nextLocation=state.navigation.location||state.location,revalidationRequest=createClientSideRequest(init.history,nextLocation,abortController.signal),routesToUse=inFlightDataRoutes||dataRoutes,matches=state.navigation.state!=="idle"?matchRoutes(routesToUse,state.navigation.location,basename2):state.matches;invariant$1(matches,"Didn't find any matches after fetcher action");let loadId=++incrementingLoadId;fetchReloadIds.set(key,loadId);let loadFetcher=getLoadingFetcher(submission,actionResult.data);state.fetchers.set(key,loadFetcher);let[matchesToLoad,revalidatingFetchers]=getMatchesToLoad(init.history,state,matches,submission,nextLocation,!1,future.v7_skipActionErrorRevalidation,isRevalidationRequired,cancelledDeferredRoutes,cancelledFetcherLoads,deletedFetchers,fetchLoadMatches,fetchRedirectIds,routesToUse,basename2,[match.route.id,actionResult]);revalidatingFetchers.filter(rf=>rf.key!==key).forEach(rf=>{let staleKey=rf.key,existingFetcher2=state.fetchers.get(staleKey),revalidatingFetcher=getLoadingFetcher(void 0,existingFetcher2?existingFetcher2.data:void 0);state.fetchers.set(staleKey,revalidatingFetcher),abortFetcher(staleKey),rf.controller&&fetchControllers.set(staleKey,rf.controller)}),updateState({fetchers:new Map(state.fetchers)});let abortPendingFetchRevalidations=__name(()=>revalidatingFetchers.forEach(rf=>abortFetcher(rf.key)),"abortPendingFetchRevalidations");abortController.signal.addEventListener("abort",abortPendingFetchRevalidations);let{loaderResults,fetcherResults}=await callLoadersAndMaybeResolveData(state,matches,matchesToLoad,revalidatingFetchers,revalidationRequest);if(abortController.signal.aborted)return;abortController.signal.removeEventListener("abort",abortPendingFetchRevalidations),fetchReloadIds.delete(key),fetchControllers.delete(key),revalidatingFetchers.forEach(r2=>fetchControllers.delete(r2.key));let redirect3=findRedirect(loaderResults);if(redirect3)return startRedirectNavigation(revalidationRequest,redirect3.result,!1,{preventScrollReset});if(redirect3=findRedirect(fetcherResults),redirect3)return fetchRedirectIds.add(redirect3.key),startRedirectNavigation(revalidationRequest,redirect3.result,!1,{preventScrollReset});let{loaderData,errors}=processLoaderData(state,matches,loaderResults,void 0,revalidatingFetchers,fetcherResults,activeDeferreds);if(state.fetchers.has(key)){let doneFetcher=getDoneFetcher(actionResult.data);state.fetchers.set(key,doneFetcher)}abortStaleFetchLoads(loadId),state.navigation.state==="loading"&&loadId>pendingNavigationLoadId?(invariant$1(pendingAction,"Expected pending action"),pendingNavigationController&&pendingNavigationController.abort(),completeNavigation(state.navigation.location,{matches,loaderData,errors,fetchers:new Map(state.fetchers)})):(updateState({errors,loaderData:mergeLoaderData(state.loaderData,loaderData,matches,errors),fetchers:new Map(state.fetchers)}),isRevalidationRequired=!1)}__name(handleFetcherAction,"handleFetcherAction");async function handleFetcherLoader(key,routeId,path2,match,matches,isFogOfWar,flushSync,preventScrollReset,submission){let existingFetcher=state.fetchers.get(key);updateFetcherState(key,getLoadingFetcher(submission,existingFetcher?existingFetcher.data:void 0),{flushSync});let abortController=new AbortController,fetchRequest=createClientSideRequest(init.history,path2,abortController.signal);if(isFogOfWar){let discoverResult=await discoverRoutes(matches,new URL(fetchRequest.url).pathname,fetchRequest.signal,key);if(discoverResult.type==="aborted")return;if(discoverResult.type==="error"){setFetcherError(key,routeId,discoverResult.error,{flushSync});return}else if(discoverResult.matches)matches=discoverResult.matches,match=getTargetMatch(matches,path2);else{setFetcherError(key,routeId,getInternalRouterError(404,{pathname:path2}),{flushSync});return}}fetchControllers.set(key,abortController);let originatingLoadId=incrementingLoadId,result=(await callDataStrategy("loader",state,fetchRequest,[match],matches,key))[match.route.id];if(isDeferredResult(result)&&(result=await resolveDeferredData(result,fetchRequest.signal,!0)||result),fetchControllers.get(key)===abortController&&fetchControllers.delete(key),!fetchRequest.signal.aborted){if(deletedFetchers.has(key)){updateFetcherState(key,getDoneFetcher(void 0));return}if(isRedirectResult(result))if(pendingNavigationLoadId>originatingLoadId){updateFetcherState(key,getDoneFetcher(void 0));return}else{fetchRedirectIds.add(key),await startRedirectNavigation(fetchRequest,result,!1,{preventScrollReset});return}if(isErrorResult(result)){setFetcherError(key,routeId,result.error);return}invariant$1(!isDeferredResult(result),"Unhandled fetcher deferred data"),updateFetcherState(key,getDoneFetcher(result.data))}}__name(handleFetcherLoader,"handleFetcherLoader");async function startRedirectNavigation(request,redirect3,isNavigation,_temp2){let{submission,fetcherSubmission,preventScrollReset,replace:replace2}=_temp2===void 0?{}:_temp2;redirect3.response.headers.has("X-Remix-Revalidate")&&(isRevalidationRequired=!0);let location2=redirect3.response.headers.get("Location");invariant$1(location2,"Expected a Location header on the redirect Response"),location2=normalizeRedirectLocation(location2,new URL(request.url),basename2,init.history);let redirectLocation=createLocation$1(state.location,location2,{_isRedirect:!0});if(isBrowser2){let isDocumentReload=!1;if(redirect3.response.headers.has("X-Remix-Reload-Document"))isDocumentReload=!0;else if(ABSOLUTE_URL_REGEX$2.test(location2)){const url=init.history.createURL(location2);isDocumentReload=url.origin!==routerWindow.location.origin||stripBasename(url.pathname,basename2)==null}if(isDocumentReload){replace2?routerWindow.location.replace(location2):routerWindow.location.assign(location2);return}}pendingNavigationController=null;let redirectHistoryAction=replace2===!0||redirect3.response.headers.has("X-Remix-Replace")?Action.Replace:Action.Push,{formMethod,formAction,formEncType}=state.navigation;!submission&&!fetcherSubmission&&formMethod&&formAction&&formEncType&&(submission=getSubmissionFromNavigation(state.navigation));let activeSubmission=submission||fetcherSubmission;if(redirectPreserveMethodStatusCodes.has(redirect3.response.status)&&activeSubmission&&isMutationMethod(activeSubmission.formMethod))await startNavigation(redirectHistoryAction,redirectLocation,{submission:_extends$x({},activeSubmission,{formAction:location2}),preventScrollReset:preventScrollReset||pendingPreventScrollReset,enableViewTransition:isNavigation?pendingViewTransitionEnabled:void 0});else{let overrideNavigation=getLoadingNavigation(redirectLocation,submission);await startNavigation(redirectHistoryAction,redirectLocation,{overrideNavigation,fetcherSubmission,preventScrollReset:preventScrollReset||pendingPreventScrollReset,enableViewTransition:isNavigation?pendingViewTransitionEnabled:void 0})}}__name(startRedirectNavigation,"startRedirectNavigation");async function callDataStrategy(type,state2,request,matchesToLoad,matches,fetcherKey){let results,dataResults={};try{results=await callDataStrategyImpl(dataStrategyImpl,type,state2,request,matchesToLoad,matches,fetcherKey,manifest,mapRouteProperties2)}catch(e3){return matchesToLoad.forEach(m2=>{dataResults[m2.route.id]={type:ResultType.error,error:e3}}),dataResults}for(let[routeId,result]of Object.entries(results))if(isRedirectDataStrategyResultResult(result)){let response=result.result;dataResults[routeId]={type:ResultType.redirect,response:normalizeRelativeRoutingRedirectResponse(response,request,routeId,matches,basename2,future.v7_relativeSplatPath)}}else dataResults[routeId]=await convertDataStrategyResultToDataResult(result);return dataResults}__name(callDataStrategy,"callDataStrategy");async function callLoadersAndMaybeResolveData(state2,matches,matchesToLoad,fetchersToLoad,request){let currentMatches=state2.matches,loaderResultsPromise=callDataStrategy("loader",state2,request,matchesToLoad,matches,null),fetcherResultsPromise=Promise.all(fetchersToLoad.map(async f2=>{if(f2.matches&&f2.match&&f2.controller){let result=(await callDataStrategy("loader",state2,createClientSideRequest(init.history,f2.path,f2.controller.signal),[f2.match],f2.matches,f2.key))[f2.match.route.id];return{[f2.key]:result}}else return Promise.resolve({[f2.key]:{type:ResultType.error,error:getInternalRouterError(404,{pathname:f2.path})}})})),loaderResults=await loaderResultsPromise,fetcherResults=(await fetcherResultsPromise).reduce((acc,r2)=>Object.assign(acc,r2),{});return await Promise.all([resolveNavigationDeferredResults(matches,loaderResults,request.signal,currentMatches,state2.loaderData),resolveFetcherDeferredResults(matches,fetcherResults,fetchersToLoad)]),{loaderResults,fetcherResults}}__name(callLoadersAndMaybeResolveData,"callLoadersAndMaybeResolveData");function interruptActiveLoads(){isRevalidationRequired=!0,cancelledDeferredRoutes.push(...cancelActiveDeferreds()),fetchLoadMatches.forEach((_2,key)=>{fetchControllers.has(key)&&cancelledFetcherLoads.add(key),abortFetcher(key)})}__name(interruptActiveLoads,"interruptActiveLoads");function updateFetcherState(key,fetcher,opts){opts===void 0&&(opts={}),state.fetchers.set(key,fetcher),updateState({fetchers:new Map(state.fetchers)},{flushSync:(opts&&opts.flushSync)===!0})}__name(updateFetcherState,"updateFetcherState");function setFetcherError(key,routeId,error,opts){opts===void 0&&(opts={});let boundaryMatch=findNearestBoundary(state.matches,routeId);deleteFetcher(key),updateState({errors:{[boundaryMatch.route.id]:error},fetchers:new Map(state.fetchers)},{flushSync:(opts&&opts.flushSync)===!0})}__name(setFetcherError,"setFetcherError");function getFetcher(key){return activeFetchers.set(key,(activeFetchers.get(key)||0)+1),deletedFetchers.has(key)&&deletedFetchers.delete(key),state.fetchers.get(key)||IDLE_FETCHER}__name(getFetcher,"getFetcher");function deleteFetcher(key){let fetcher=state.fetchers.get(key);fetchControllers.has(key)&&!(fetcher&&fetcher.state==="loading"&&fetchReloadIds.has(key))&&abortFetcher(key),fetchLoadMatches.delete(key),fetchReloadIds.delete(key),fetchRedirectIds.delete(key),future.v7_fetcherPersist&&deletedFetchers.delete(key),cancelledFetcherLoads.delete(key),state.fetchers.delete(key)}__name(deleteFetcher,"deleteFetcher");function deleteFetcherAndUpdateState(key){let count2=(activeFetchers.get(key)||0)-1;count2<=0?(activeFetchers.delete(key),deletedFetchers.add(key),future.v7_fetcherPersist||deleteFetcher(key)):activeFetchers.set(key,count2),updateState({fetchers:new Map(state.fetchers)})}__name(deleteFetcherAndUpdateState,"deleteFetcherAndUpdateState");function abortFetcher(key){let controller=fetchControllers.get(key);controller&&(controller.abort(),fetchControllers.delete(key))}__name(abortFetcher,"abortFetcher");function markFetchersDone(keys2){for(let key of keys2){let fetcher=getFetcher(key),doneFetcher=getDoneFetcher(fetcher.data);state.fetchers.set(key,doneFetcher)}}__name(markFetchersDone,"markFetchersDone");function markFetchRedirectsDone(){let doneKeys=[],updatedFetchers=!1;for(let key of fetchRedirectIds){let fetcher=state.fetchers.get(key);invariant$1(fetcher,"Expected fetcher: "+key),fetcher.state==="loading"&&(fetchRedirectIds.delete(key),doneKeys.push(key),updatedFetchers=!0)}return markFetchersDone(doneKeys),updatedFetchers}__name(markFetchRedirectsDone,"markFetchRedirectsDone");function abortStaleFetchLoads(landedId){let yeetedKeys=[];for(let[key,id]of fetchReloadIds)if(id0}__name(abortStaleFetchLoads,"abortStaleFetchLoads");function getBlocker(key,fn2){let blocker=state.blockers.get(key)||IDLE_BLOCKER;return blockerFunctions.get(key)!==fn2&&blockerFunctions.set(key,fn2),blocker}__name(getBlocker,"getBlocker");function deleteBlocker(key){state.blockers.delete(key),blockerFunctions.delete(key)}__name(deleteBlocker,"deleteBlocker");function updateBlocker(key,newBlocker){let blocker=state.blockers.get(key)||IDLE_BLOCKER;invariant$1(blocker.state==="unblocked"&&newBlocker.state==="blocked"||blocker.state==="blocked"&&newBlocker.state==="blocked"||blocker.state==="blocked"&&newBlocker.state==="proceeding"||blocker.state==="blocked"&&newBlocker.state==="unblocked"||blocker.state==="proceeding"&&newBlocker.state==="unblocked","Invalid blocker state transition: "+blocker.state+" -> "+newBlocker.state);let blockers=new Map(state.blockers);blockers.set(key,newBlocker),updateState({blockers})}__name(updateBlocker,"updateBlocker");function shouldBlockNavigation(_ref2){let{currentLocation,nextLocation,historyAction}=_ref2;if(blockerFunctions.size===0)return;blockerFunctions.size>1&&warning(!1,"A router only supports one blocker at a time");let entries=Array.from(blockerFunctions.entries()),[blockerKey,blockerFunction]=entries[entries.length-1],blocker=state.blockers.get(blockerKey);if(!(blocker&&blocker.state==="proceeding")&&blockerFunction({currentLocation,nextLocation,historyAction}))return blockerKey}__name(shouldBlockNavigation,"shouldBlockNavigation");function handleNavigational404(pathname){let error=getInternalRouterError(404,{pathname}),routesToUse=inFlightDataRoutes||dataRoutes,{matches,route}=getShortCircuitMatches(routesToUse);return cancelActiveDeferreds(),{notFoundMatches:matches,route,error}}__name(handleNavigational404,"handleNavigational404");function cancelActiveDeferreds(predicate){let cancelledRouteIds=[];return activeDeferreds.forEach((dfd,routeId)=>{(!predicate||predicate(routeId))&&(dfd.cancel(),cancelledRouteIds.push(routeId),activeDeferreds.delete(routeId))}),cancelledRouteIds}__name(cancelActiveDeferreds,"cancelActiveDeferreds");function enableScrollRestoration(positions,getPosition,getKey){if(savedScrollPositions=positions,getScrollPosition=getPosition,getScrollRestorationKey=getKey||null,!initialScrollRestored&&state.navigation===IDLE_NAVIGATION){initialScrollRestored=!0;let y2=getSavedScrollPosition(state.location,state.matches);y2!=null&&updateState({restoreScrollPosition:y2})}return()=>{savedScrollPositions=null,getScrollPosition=null,getScrollRestorationKey=null}}__name(enableScrollRestoration,"enableScrollRestoration");function getScrollKey(location2,matches){return getScrollRestorationKey&&getScrollRestorationKey(location2,matches.map(m2=>convertRouteMatchToUiMatch(m2,state.loaderData)))||location2.key}__name(getScrollKey,"getScrollKey");function saveScrollPosition(location2,matches){if(savedScrollPositions&&getScrollPosition){let key=getScrollKey(location2,matches);savedScrollPositions[key]=getScrollPosition()}}__name(saveScrollPosition,"saveScrollPosition");function getSavedScrollPosition(location2,matches){if(savedScrollPositions){let key=getScrollKey(location2,matches),y2=savedScrollPositions[key];if(typeof y2=="number")return y2}return null}__name(getSavedScrollPosition,"getSavedScrollPosition");function checkFogOfWar(matches,routesToUse,pathname){if(patchRoutesOnNavigationImpl)if(matches){if(Object.keys(matches[0].params).length>0)return{active:!0,matches:matchRoutesImpl(routesToUse,pathname,basename2,!0)}}else return{active:!0,matches:matchRoutesImpl(routesToUse,pathname,basename2,!0)||[]};return{active:!1,matches:null}}__name(checkFogOfWar,"checkFogOfWar");async function discoverRoutes(matches,pathname,signal,fetcherKey){if(!patchRoutesOnNavigationImpl)return{type:"success",matches};let partialMatches=matches;for(;;){let isNonHMR=inFlightDataRoutes==null,routesToUse=inFlightDataRoutes||dataRoutes,localManifest=manifest;try{await patchRoutesOnNavigationImpl({signal,path:pathname,matches:partialMatches,fetcherKey,patch:__name((routeId,children2)=>{signal.aborted||patchRoutesImpl(routeId,children2,routesToUse,localManifest,mapRouteProperties2)},"patch")})}catch(e3){return{type:"error",error:e3,partialMatches}}finally{isNonHMR&&!signal.aborted&&(dataRoutes=[...dataRoutes])}if(signal.aborted)return{type:"aborted"};let newMatches=matchRoutes(routesToUse,pathname,basename2);if(newMatches)return{type:"success",matches:newMatches};let newPartialMatches=matchRoutesImpl(routesToUse,pathname,basename2,!0);if(!newPartialMatches||partialMatches.length===newPartialMatches.length&&partialMatches.every((m2,i2)=>m2.route.id===newPartialMatches[i2].route.id))return{type:"success",matches:null};partialMatches=newPartialMatches}}__name(discoverRoutes,"discoverRoutes");function _internalSetRoutes(newRoutes){manifest={},inFlightDataRoutes=convertRoutesToDataRoutes(newRoutes,mapRouteProperties2,void 0,manifest)}__name(_internalSetRoutes,"_internalSetRoutes");function patchRoutes(routeId,children2){let isNonHMR=inFlightDataRoutes==null;patchRoutesImpl(routeId,children2,inFlightDataRoutes||dataRoutes,manifest,mapRouteProperties2),isNonHMR&&(dataRoutes=[...dataRoutes],updateState({}))}return __name(patchRoutes,"patchRoutes"),router2={get basename(){return basename2},get future(){return future},get state(){return state},get routes(){return dataRoutes},get window(){return routerWindow},initialize,subscribe:subscribe2,enableScrollRestoration,navigate,fetch:fetch2,revalidate,createHref:__name(to2=>init.history.createHref(to2),"createHref"),encodeLocation:__name(to2=>init.history.encodeLocation(to2),"encodeLocation"),getFetcher,deleteFetcher:deleteFetcherAndUpdateState,dispose,getBlocker,deleteBlocker,patchRoutes,_internalFetchControllers:fetchControllers,_internalActiveDeferreds:activeDeferreds,_internalSetRoutes},router2}__name(createRouter,"createRouter");function isSubmissionNavigation(opts){return opts!=null&&("formData"in opts&&opts.formData!=null||"body"in opts&&opts.body!==void 0)}__name(isSubmissionNavigation,"isSubmissionNavigation");function normalizeTo(location2,matches,basename2,prependBasename,to2,v7_relativeSplatPath,fromRouteId,relative){let contextualMatches,activeRouteMatch;if(fromRouteId){contextualMatches=[];for(let match of matches)if(contextualMatches.push(match),match.route.id===fromRouteId){activeRouteMatch=match;break}}else contextualMatches=matches,activeRouteMatch=matches[matches.length-1];let path2=resolveTo(to2||".",getResolveToMatches(contextualMatches,v7_relativeSplatPath),stripBasename(location2.pathname,basename2)||location2.pathname,relative==="path");if(to2==null&&(path2.search=location2.search,path2.hash=location2.hash),(to2==null||to2===""||to2===".")&&activeRouteMatch){let nakedIndex=hasNakedIndexQuery(path2.search);if(activeRouteMatch.route.index&&!nakedIndex)path2.search=path2.search?path2.search.replace(/^\?/,"?index&"):"?index";else if(!activeRouteMatch.route.index&&nakedIndex){let params=new URLSearchParams(path2.search),indexValues=params.getAll("index");params.delete("index"),indexValues.filter(v2=>v2).forEach(v2=>params.append("index",v2));let qs=params.toString();path2.search=qs?"?"+qs:""}}return prependBasename&&basename2!=="/"&&(path2.pathname=path2.pathname==="/"?basename2:joinPaths([basename2,path2.pathname])),createPath(path2)}__name(normalizeTo,"normalizeTo");function normalizeNavigateOptions(normalizeFormMethod,isFetcher,path2,opts){if(!opts||!isSubmissionNavigation(opts))return{path:path2};if(opts.formMethod&&!isValidMethod(opts.formMethod))return{path:path2,error:getInternalRouterError(405,{method:opts.formMethod})};let getInvalidBodyError=__name(()=>({path:path2,error:getInternalRouterError(400,{type:"invalid-body"})}),"getInvalidBodyError"),rawFormMethod=opts.formMethod||"get",formMethod=normalizeFormMethod?rawFormMethod.toUpperCase():rawFormMethod.toLowerCase(),formAction=stripHashFromPath(path2);if(opts.body!==void 0){if(opts.formEncType==="text/plain"){if(!isMutationMethod(formMethod))return getInvalidBodyError();let text2=typeof opts.body=="string"?opts.body:opts.body instanceof FormData||opts.body instanceof URLSearchParams?Array.from(opts.body.entries()).reduce((acc,_ref3)=>{let[name2,value2]=_ref3;return""+acc+name2+"="+value2+` +`+f2.stack}return{value:a2,source:b2,stack:e3,digest:null}}__name(Ji,"Ji");function Ki(a2,b2,c2){return{value:a2,source:null,stack:c2??null,digest:b2??null}}__name(Ki,"Ki");function Li(a2,b2){try{console.error(b2.value)}catch(c2){setTimeout(function(){throw c2})}}__name(Li,"Li");var Mi=typeof WeakMap=="function"?WeakMap:Map;function Ni(a2,b2,c2){c2=mh(-1,c2),c2.tag=3,c2.payload={element:null};var d=b2.value;return c2.callback=function(){Oi||(Oi=!0,Pi=d),Li(a2,b2)},c2}__name(Ni,"Ni");function Qi(a2,b2,c2){c2=mh(-1,c2),c2.tag=3;var d=a2.type.getDerivedStateFromError;if(typeof d=="function"){var e3=b2.value;c2.payload=function(){return d(e3)},c2.callback=function(){Li(a2,b2)}}var f2=a2.stateNode;return f2!==null&&typeof f2.componentDidCatch=="function"&&(c2.callback=function(){Li(a2,b2),typeof d!="function"&&(Ri===null?Ri=new Set([this]):Ri.add(this));var c3=b2.stack;this.componentDidCatch(b2.value,{componentStack:c3!==null?c3:""})}),c2}__name(Qi,"Qi");function Si(a2,b2,c2){var d=a2.pingCache;if(d===null){d=a2.pingCache=new Mi;var e3=new Set;d.set(b2,e3)}else e3=d.get(b2),e3===void 0&&(e3=new Set,d.set(b2,e3));e3.has(c2)||(e3.add(c2),a2=Ti.bind(null,a2,b2,c2),b2.then(a2,a2))}__name(Si,"Si");function Ui(a2){do{var b2;if((b2=a2.tag===13)&&(b2=a2.memoizedState,b2=b2!==null?b2.dehydrated!==null:!0),b2)return a2;a2=a2.return}while(a2!==null);return null}__name(Ui,"Ui");function Vi(a2,b2,c2,d,e3){return(a2.mode&1)===0?(a2===b2?a2.flags|=65536:(a2.flags|=128,c2.flags|=131072,c2.flags&=-52805,c2.tag===1&&(c2.alternate===null?c2.tag=17:(b2=mh(-1,1),b2.tag=2,nh(c2,b2,1))),c2.lanes|=1),a2):(a2.flags|=65536,a2.lanes=e3,a2)}__name(Vi,"Vi");var Wi=ua.ReactCurrentOwner,dh=!1;function Xi(a2,b2,c2,d){b2.child=a2===null?Vg(b2,null,c2,d):Ug(b2,a2.child,c2,d)}__name(Xi,"Xi");function Yi(a2,b2,c2,d,e3){c2=c2.render;var f2=b2.ref;return ch(b2,e3),d=Nh(a2,b2,c2,d,f2,e3),c2=Sh(),a2!==null&&!dh?(b2.updateQueue=a2.updateQueue,b2.flags&=-2053,a2.lanes&=~e3,Zi(a2,b2,e3)):(I2&&c2&&vg(b2),b2.flags|=1,Xi(a2,b2,d,e3),b2.child)}__name(Yi,"Yi");function $i(a2,b2,c2,d,e3){if(a2===null){var f2=c2.type;return typeof f2=="function"&&!aj(f2)&&f2.defaultProps===void 0&&c2.compare===null&&c2.defaultProps===void 0?(b2.tag=15,b2.type=f2,bj(a2,b2,f2,d,e3)):(a2=Rg(c2.type,null,d,b2,b2.mode,e3),a2.ref=b2.ref,a2.return=b2,b2.child=a2)}if(f2=a2.child,(a2.lanes&e3)===0){var g2=f2.memoizedProps;if(c2=c2.compare,c2=c2!==null?c2:Ie,c2(g2,d)&&a2.ref===b2.ref)return Zi(a2,b2,e3)}return b2.flags|=1,a2=Pg(f2,d),a2.ref=b2.ref,a2.return=b2,b2.child=a2}__name($i,"$i");function bj(a2,b2,c2,d,e3){if(a2!==null){var f2=a2.memoizedProps;if(Ie(f2,d)&&a2.ref===b2.ref)if(dh=!1,b2.pendingProps=d=f2,(a2.lanes&e3)!==0)(a2.flags&131072)!==0&&(dh=!0);else return b2.lanes=a2.lanes,Zi(a2,b2,e3)}return cj(a2,b2,c2,d,e3)}__name(bj,"bj");function dj(a2,b2,c2){var d=b2.pendingProps,e3=d.children,f2=a2!==null?a2.memoizedState:null;if(d.mode==="hidden")if((b2.mode&1)===0)b2.memoizedState={baseLanes:0,cachePool:null,transitions:null},G(ej,fj),fj|=c2;else{if((c2&1073741824)===0)return a2=f2!==null?f2.baseLanes|c2:c2,b2.lanes=b2.childLanes=1073741824,b2.memoizedState={baseLanes:a2,cachePool:null,transitions:null},b2.updateQueue=null,G(ej,fj),fj|=a2,null;b2.memoizedState={baseLanes:0,cachePool:null,transitions:null},d=f2!==null?f2.baseLanes:c2,G(ej,fj),fj|=d}else f2!==null?(d=f2.baseLanes|c2,b2.memoizedState=null):d=c2,G(ej,fj),fj|=d;return Xi(a2,b2,e3,c2),b2.child}__name(dj,"dj");function gj(a2,b2){var c2=b2.ref;(a2===null&&c2!==null||a2!==null&&a2.ref!==c2)&&(b2.flags|=512,b2.flags|=2097152)}__name(gj,"gj");function cj(a2,b2,c2,d,e3){var f2=Zf(c2)?Xf:H.current;return f2=Yf(b2,f2),ch(b2,e3),c2=Nh(a2,b2,c2,d,f2,e3),d=Sh(),a2!==null&&!dh?(b2.updateQueue=a2.updateQueue,b2.flags&=-2053,a2.lanes&=~e3,Zi(a2,b2,e3)):(I2&&d&&vg(b2),b2.flags|=1,Xi(a2,b2,c2,e3),b2.child)}__name(cj,"cj");function hj(a2,b2,c2,d,e3){if(Zf(c2)){var f2=!0;cg(b2)}else f2=!1;if(ch(b2,e3),b2.stateNode===null)ij(a2,b2),Gi(b2,c2,d),Ii(b2,c2,d,e3),d=!0;else if(a2===null){var g2=b2.stateNode,h2=b2.memoizedProps;g2.props=h2;var k2=g2.context,l2=c2.contextType;typeof l2=="object"&&l2!==null?l2=eh(l2):(l2=Zf(c2)?Xf:H.current,l2=Yf(b2,l2));var m2=c2.getDerivedStateFromProps,q2=typeof m2=="function"||typeof g2.getSnapshotBeforeUpdate=="function";q2||typeof g2.UNSAFE_componentWillReceiveProps!="function"&&typeof g2.componentWillReceiveProps!="function"||(h2!==d||k2!==l2)&&Hi(b2,g2,d,l2),jh=!1;var r2=b2.memoizedState;g2.state=r2,qh(b2,d,g2,e3),k2=b2.memoizedState,h2!==d||r2!==k2||Wf.current||jh?(typeof m2=="function"&&(Di(b2,c2,m2,d),k2=b2.memoizedState),(h2=jh||Fi(b2,c2,h2,d,r2,k2,l2))?(q2||typeof g2.UNSAFE_componentWillMount!="function"&&typeof g2.componentWillMount!="function"||(typeof g2.componentWillMount=="function"&&g2.componentWillMount(),typeof g2.UNSAFE_componentWillMount=="function"&&g2.UNSAFE_componentWillMount()),typeof g2.componentDidMount=="function"&&(b2.flags|=4194308)):(typeof g2.componentDidMount=="function"&&(b2.flags|=4194308),b2.memoizedProps=d,b2.memoizedState=k2),g2.props=d,g2.state=k2,g2.context=l2,d=h2):(typeof g2.componentDidMount=="function"&&(b2.flags|=4194308),d=!1)}else{g2=b2.stateNode,lh(a2,b2),h2=b2.memoizedProps,l2=b2.type===b2.elementType?h2:Ci(b2.type,h2),g2.props=l2,q2=b2.pendingProps,r2=g2.context,k2=c2.contextType,typeof k2=="object"&&k2!==null?k2=eh(k2):(k2=Zf(c2)?Xf:H.current,k2=Yf(b2,k2));var y2=c2.getDerivedStateFromProps;(m2=typeof y2=="function"||typeof g2.getSnapshotBeforeUpdate=="function")||typeof g2.UNSAFE_componentWillReceiveProps!="function"&&typeof g2.componentWillReceiveProps!="function"||(h2!==q2||r2!==k2)&&Hi(b2,g2,d,k2),jh=!1,r2=b2.memoizedState,g2.state=r2,qh(b2,d,g2,e3);var n2=b2.memoizedState;h2!==q2||r2!==n2||Wf.current||jh?(typeof y2=="function"&&(Di(b2,c2,y2,d),n2=b2.memoizedState),(l2=jh||Fi(b2,c2,l2,d,r2,n2,k2)||!1)?(m2||typeof g2.UNSAFE_componentWillUpdate!="function"&&typeof g2.componentWillUpdate!="function"||(typeof g2.componentWillUpdate=="function"&&g2.componentWillUpdate(d,n2,k2),typeof g2.UNSAFE_componentWillUpdate=="function"&&g2.UNSAFE_componentWillUpdate(d,n2,k2)),typeof g2.componentDidUpdate=="function"&&(b2.flags|=4),typeof g2.getSnapshotBeforeUpdate=="function"&&(b2.flags|=1024)):(typeof g2.componentDidUpdate!="function"||h2===a2.memoizedProps&&r2===a2.memoizedState||(b2.flags|=4),typeof g2.getSnapshotBeforeUpdate!="function"||h2===a2.memoizedProps&&r2===a2.memoizedState||(b2.flags|=1024),b2.memoizedProps=d,b2.memoizedState=n2),g2.props=d,g2.state=n2,g2.context=k2,d=l2):(typeof g2.componentDidUpdate!="function"||h2===a2.memoizedProps&&r2===a2.memoizedState||(b2.flags|=4),typeof g2.getSnapshotBeforeUpdate!="function"||h2===a2.memoizedProps&&r2===a2.memoizedState||(b2.flags|=1024),d=!1)}return jj(a2,b2,c2,d,f2,e3)}__name(hj,"hj");function jj(a2,b2,c2,d,e3,f2){gj(a2,b2);var g2=(b2.flags&128)!==0;if(!d&&!g2)return e3&&dg(b2,c2,!1),Zi(a2,b2,f2);d=b2.stateNode,Wi.current=b2;var h2=g2&&typeof c2.getDerivedStateFromError!="function"?null:d.render();return b2.flags|=1,a2!==null&&g2?(b2.child=Ug(b2,a2.child,null,f2),b2.child=Ug(b2,null,h2,f2)):Xi(a2,b2,h2,f2),b2.memoizedState=d.state,e3&&dg(b2,c2,!0),b2.child}__name(jj,"jj");function kj(a2){var b2=a2.stateNode;b2.pendingContext?ag(a2,b2.pendingContext,b2.pendingContext!==b2.context):b2.context&&ag(a2,b2.context,!1),yh(a2,b2.containerInfo)}__name(kj,"kj");function lj(a2,b2,c2,d,e3){return Ig(),Jg(e3),b2.flags|=256,Xi(a2,b2,c2,d),b2.child}__name(lj,"lj");var mj={dehydrated:null,treeContext:null,retryLane:0};function nj(a2){return{baseLanes:a2,cachePool:null,transitions:null}}__name(nj,"nj");function oj(a2,b2,c2){var d=b2.pendingProps,e3=L2.current,f2=!1,g2=(b2.flags&128)!==0,h2;if((h2=g2)||(h2=a2!==null&&a2.memoizedState===null?!1:(e3&2)!==0),h2?(f2=!0,b2.flags&=-129):(a2===null||a2.memoizedState!==null)&&(e3|=1),G(L2,e3&1),a2===null)return Eg(b2),a2=b2.memoizedState,a2!==null&&(a2=a2.dehydrated,a2!==null)?((b2.mode&1)===0?b2.lanes=1:a2.data==="$!"?b2.lanes=8:b2.lanes=1073741824,null):(g2=d.children,a2=d.fallback,f2?(d=b2.mode,f2=b2.child,g2={mode:"hidden",children:g2},(d&1)===0&&f2!==null?(f2.childLanes=0,f2.pendingProps=g2):f2=pj(g2,d,0,null),a2=Tg(a2,d,c2,null),f2.return=b2,a2.return=b2,f2.sibling=a2,b2.child=f2,b2.child.memoizedState=nj(c2),b2.memoizedState=mj,a2):qj(b2,g2));if(e3=a2.memoizedState,e3!==null&&(h2=e3.dehydrated,h2!==null))return rj(a2,b2,g2,d,h2,e3,c2);if(f2){f2=d.fallback,g2=b2.mode,e3=a2.child,h2=e3.sibling;var k2={mode:"hidden",children:d.children};return(g2&1)===0&&b2.child!==e3?(d=b2.child,d.childLanes=0,d.pendingProps=k2,b2.deletions=null):(d=Pg(e3,k2),d.subtreeFlags=e3.subtreeFlags&14680064),h2!==null?f2=Pg(h2,f2):(f2=Tg(f2,g2,c2,null),f2.flags|=2),f2.return=b2,d.return=b2,d.sibling=f2,b2.child=d,d=f2,f2=b2.child,g2=a2.child.memoizedState,g2=g2===null?nj(c2):{baseLanes:g2.baseLanes|c2,cachePool:null,transitions:g2.transitions},f2.memoizedState=g2,f2.childLanes=a2.childLanes&~c2,b2.memoizedState=mj,d}return f2=a2.child,a2=f2.sibling,d=Pg(f2,{mode:"visible",children:d.children}),(b2.mode&1)===0&&(d.lanes=c2),d.return=b2,d.sibling=null,a2!==null&&(c2=b2.deletions,c2===null?(b2.deletions=[a2],b2.flags|=16):c2.push(a2)),b2.child=d,b2.memoizedState=null,d}__name(oj,"oj");function qj(a2,b2){return b2=pj({mode:"visible",children:b2},a2.mode,0,null),b2.return=a2,a2.child=b2}__name(qj,"qj");function sj(a2,b2,c2,d){return d!==null&&Jg(d),Ug(b2,a2.child,null,c2),a2=qj(b2,b2.pendingProps.children),a2.flags|=2,b2.memoizedState=null,a2}__name(sj,"sj");function rj(a2,b2,c2,d,e3,f2,g2){if(c2)return b2.flags&256?(b2.flags&=-257,d=Ki(Error(p2(422))),sj(a2,b2,g2,d)):b2.memoizedState!==null?(b2.child=a2.child,b2.flags|=128,null):(f2=d.fallback,e3=b2.mode,d=pj({mode:"visible",children:d.children},e3,0,null),f2=Tg(f2,e3,g2,null),f2.flags|=2,d.return=b2,f2.return=b2,d.sibling=f2,b2.child=d,(b2.mode&1)!==0&&Ug(b2,a2.child,null,g2),b2.child.memoizedState=nj(g2),b2.memoizedState=mj,f2);if((b2.mode&1)===0)return sj(a2,b2,g2,null);if(e3.data==="$!"){if(d=e3.nextSibling&&e3.nextSibling.dataset,d)var h2=d.dgst;return d=h2,f2=Error(p2(419)),d=Ki(f2,d,void 0),sj(a2,b2,g2,d)}if(h2=(g2&a2.childLanes)!==0,dh||h2){if(d=Q2,d!==null){switch(g2&-g2){case 4:e3=2;break;case 16:e3=8;break;case 64:case 128:case 256:case 512:case 1024:case 2048:case 4096:case 8192:case 16384:case 32768:case 65536:case 131072:case 262144:case 524288:case 1048576:case 2097152:case 4194304:case 8388608:case 16777216:case 33554432:case 67108864:e3=32;break;case 536870912:e3=268435456;break;default:e3=0}e3=(e3&(d.suspendedLanes|g2))!==0?0:e3,e3!==0&&e3!==f2.retryLane&&(f2.retryLane=e3,ih(a2,e3),gi(d,a2,e3,-1))}return tj(),d=Ki(Error(p2(421))),sj(a2,b2,g2,d)}return e3.data==="$?"?(b2.flags|=128,b2.child=a2.child,b2=uj.bind(null,a2),e3._reactRetry=b2,null):(a2=f2.treeContext,yg=Lf(e3.nextSibling),xg=b2,I2=!0,zg=null,a2!==null&&(og[pg++]=rg,og[pg++]=sg,og[pg++]=qg,rg=a2.id,sg=a2.overflow,qg=b2),b2=qj(b2,d.children),b2.flags|=4096,b2)}__name(rj,"rj");function vj(a2,b2,c2){a2.lanes|=b2;var d=a2.alternate;d!==null&&(d.lanes|=b2),bh(a2.return,b2,c2)}__name(vj,"vj");function wj(a2,b2,c2,d,e3){var f2=a2.memoizedState;f2===null?a2.memoizedState={isBackwards:b2,rendering:null,renderingStartTime:0,last:d,tail:c2,tailMode:e3}:(f2.isBackwards=b2,f2.rendering=null,f2.renderingStartTime=0,f2.last=d,f2.tail=c2,f2.tailMode=e3)}__name(wj,"wj");function xj(a2,b2,c2){var d=b2.pendingProps,e3=d.revealOrder,f2=d.tail;if(Xi(a2,b2,d.children,c2),d=L2.current,(d&2)!==0)d=d&1|2,b2.flags|=128;else{if(a2!==null&&(a2.flags&128)!==0)a:for(a2=b2.child;a2!==null;){if(a2.tag===13)a2.memoizedState!==null&&vj(a2,c2,b2);else if(a2.tag===19)vj(a2,c2,b2);else if(a2.child!==null){a2.child.return=a2,a2=a2.child;continue}if(a2===b2)break a;for(;a2.sibling===null;){if(a2.return===null||a2.return===b2)break a;a2=a2.return}a2.sibling.return=a2.return,a2=a2.sibling}d&=1}if(G(L2,d),(b2.mode&1)===0)b2.memoizedState=null;else switch(e3){case"forwards":for(c2=b2.child,e3=null;c2!==null;)a2=c2.alternate,a2!==null&&Ch(a2)===null&&(e3=c2),c2=c2.sibling;c2=e3,c2===null?(e3=b2.child,b2.child=null):(e3=c2.sibling,c2.sibling=null),wj(b2,!1,e3,c2,f2);break;case"backwards":for(c2=null,e3=b2.child,b2.child=null;e3!==null;){if(a2=e3.alternate,a2!==null&&Ch(a2)===null){b2.child=e3;break}a2=e3.sibling,e3.sibling=c2,c2=e3,e3=a2}wj(b2,!0,c2,null,f2);break;case"together":wj(b2,!1,null,null,void 0);break;default:b2.memoizedState=null}return b2.child}__name(xj,"xj");function ij(a2,b2){(b2.mode&1)===0&&a2!==null&&(a2.alternate=null,b2.alternate=null,b2.flags|=2)}__name(ij,"ij");function Zi(a2,b2,c2){if(a2!==null&&(b2.dependencies=a2.dependencies),rh|=b2.lanes,(c2&b2.childLanes)===0)return null;if(a2!==null&&b2.child!==a2.child)throw Error(p2(153));if(b2.child!==null){for(a2=b2.child,c2=Pg(a2,a2.pendingProps),b2.child=c2,c2.return=b2;a2.sibling!==null;)a2=a2.sibling,c2=c2.sibling=Pg(a2,a2.pendingProps),c2.return=b2;c2.sibling=null}return b2.child}__name(Zi,"Zi");function yj(a2,b2,c2){switch(b2.tag){case 3:kj(b2),Ig();break;case 5:Ah(b2);break;case 1:Zf(b2.type)&&cg(b2);break;case 4:yh(b2,b2.stateNode.containerInfo);break;case 10:var d=b2.type._context,e3=b2.memoizedProps.value;G(Wg,d._currentValue),d._currentValue=e3;break;case 13:if(d=b2.memoizedState,d!==null)return d.dehydrated!==null?(G(L2,L2.current&1),b2.flags|=128,null):(c2&b2.child.childLanes)!==0?oj(a2,b2,c2):(G(L2,L2.current&1),a2=Zi(a2,b2,c2),a2!==null?a2.sibling:null);G(L2,L2.current&1);break;case 19:if(d=(c2&b2.childLanes)!==0,(a2.flags&128)!==0){if(d)return xj(a2,b2,c2);b2.flags|=128}if(e3=b2.memoizedState,e3!==null&&(e3.rendering=null,e3.tail=null,e3.lastEffect=null),G(L2,L2.current),d)break;return null;case 22:case 23:return b2.lanes=0,dj(a2,b2,c2)}return Zi(a2,b2,c2)}__name(yj,"yj");var zj,Aj,Bj,Cj;zj=__name(function(a2,b2){for(var c2=b2.child;c2!==null;){if(c2.tag===5||c2.tag===6)a2.appendChild(c2.stateNode);else if(c2.tag!==4&&c2.child!==null){c2.child.return=c2,c2=c2.child;continue}if(c2===b2)break;for(;c2.sibling===null;){if(c2.return===null||c2.return===b2)return;c2=c2.return}c2.sibling.return=c2.return,c2=c2.sibling}},"zj"),Aj=__name(function(){},"Aj"),Bj=__name(function(a2,b2,c2,d){var e3=a2.memoizedProps;if(e3!==d){a2=b2.stateNode,xh(uh.current);var f2=null;switch(c2){case"input":e3=Ya(a2,e3),d=Ya(a2,d),f2=[];break;case"select":e3=A2({},e3,{value:void 0}),d=A2({},d,{value:void 0}),f2=[];break;case"textarea":e3=gb(a2,e3),d=gb(a2,d),f2=[];break;default:typeof e3.onClick!="function"&&typeof d.onClick=="function"&&(a2.onclick=Bf)}ub(c2,d);var g2;c2=null;for(l2 in e3)if(!d.hasOwnProperty(l2)&&e3.hasOwnProperty(l2)&&e3[l2]!=null)if(l2==="style"){var h2=e3[l2];for(g2 in h2)h2.hasOwnProperty(g2)&&(c2||(c2={}),c2[g2]="")}else l2!=="dangerouslySetInnerHTML"&&l2!=="children"&&l2!=="suppressContentEditableWarning"&&l2!=="suppressHydrationWarning"&&l2!=="autoFocus"&&(ea.hasOwnProperty(l2)?f2||(f2=[]):(f2=f2||[]).push(l2,null));for(l2 in d){var k2=d[l2];if(h2=e3?.[l2],d.hasOwnProperty(l2)&&k2!==h2&&(k2!=null||h2!=null))if(l2==="style")if(h2){for(g2 in h2)!h2.hasOwnProperty(g2)||k2&&k2.hasOwnProperty(g2)||(c2||(c2={}),c2[g2]="");for(g2 in k2)k2.hasOwnProperty(g2)&&h2[g2]!==k2[g2]&&(c2||(c2={}),c2[g2]=k2[g2])}else c2||(f2||(f2=[]),f2.push(l2,c2)),c2=k2;else l2==="dangerouslySetInnerHTML"?(k2=k2?k2.__html:void 0,h2=h2?h2.__html:void 0,k2!=null&&h2!==k2&&(f2=f2||[]).push(l2,k2)):l2==="children"?typeof k2!="string"&&typeof k2!="number"||(f2=f2||[]).push(l2,""+k2):l2!=="suppressContentEditableWarning"&&l2!=="suppressHydrationWarning"&&(ea.hasOwnProperty(l2)?(k2!=null&&l2==="onScroll"&&D2("scroll",a2),f2||h2===k2||(f2=[])):(f2=f2||[]).push(l2,k2))}c2&&(f2=f2||[]).push("style",c2);var l2=f2;(b2.updateQueue=l2)&&(b2.flags|=4)}},"Bj"),Cj=__name(function(a2,b2,c2,d){c2!==d&&(b2.flags|=4)},"Cj");function Dj(a2,b2){if(!I2)switch(a2.tailMode){case"hidden":b2=a2.tail;for(var c2=null;b2!==null;)b2.alternate!==null&&(c2=b2),b2=b2.sibling;c2===null?a2.tail=null:c2.sibling=null;break;case"collapsed":c2=a2.tail;for(var d=null;c2!==null;)c2.alternate!==null&&(d=c2),c2=c2.sibling;d===null?b2||a2.tail===null?a2.tail=null:a2.tail.sibling=null:d.sibling=null}}__name(Dj,"Dj");function S2(a2){var b2=a2.alternate!==null&&a2.alternate.child===a2.child,c2=0,d=0;if(b2)for(var e3=a2.child;e3!==null;)c2|=e3.lanes|e3.childLanes,d|=e3.subtreeFlags&14680064,d|=e3.flags&14680064,e3.return=a2,e3=e3.sibling;else for(e3=a2.child;e3!==null;)c2|=e3.lanes|e3.childLanes,d|=e3.subtreeFlags,d|=e3.flags,e3.return=a2,e3=e3.sibling;return a2.subtreeFlags|=d,a2.childLanes=c2,b2}__name(S2,"S");function Ej(a2,b2,c2){var d=b2.pendingProps;switch(wg(b2),b2.tag){case 2:case 16:case 15:case 0:case 11:case 7:case 8:case 12:case 9:case 14:return S2(b2),null;case 1:return Zf(b2.type)&&$f(),S2(b2),null;case 3:return d=b2.stateNode,zh(),E2(Wf),E2(H),Eh(),d.pendingContext&&(d.context=d.pendingContext,d.pendingContext=null),(a2===null||a2.child===null)&&(Gg(b2)?b2.flags|=4:a2===null||a2.memoizedState.isDehydrated&&(b2.flags&256)===0||(b2.flags|=1024,zg!==null&&(Fj(zg),zg=null))),Aj(a2,b2),S2(b2),null;case 5:Bh(b2);var e3=xh(wh.current);if(c2=b2.type,a2!==null&&b2.stateNode!=null)Bj(a2,b2,c2,d,e3),a2.ref!==b2.ref&&(b2.flags|=512,b2.flags|=2097152);else{if(!d){if(b2.stateNode===null)throw Error(p2(166));return S2(b2),null}if(a2=xh(uh.current),Gg(b2)){d=b2.stateNode,c2=b2.type;var f2=b2.memoizedProps;switch(d[Of]=b2,d[Pf]=f2,a2=(b2.mode&1)!==0,c2){case"dialog":D2("cancel",d),D2("close",d);break;case"iframe":case"object":case"embed":D2("load",d);break;case"video":case"audio":for(e3=0;e3<\/script>",a2=a2.removeChild(a2.firstChild)):typeof d.is=="string"?a2=g2.createElement(c2,{is:d.is}):(a2=g2.createElement(c2),c2==="select"&&(g2=a2,d.multiple?g2.multiple=!0:d.size&&(g2.size=d.size))):a2=g2.createElementNS(a2,c2),a2[Of]=b2,a2[Pf]=d,zj(a2,b2,!1,!1),b2.stateNode=a2;a:{switch(g2=vb(c2,d),c2){case"dialog":D2("cancel",a2),D2("close",a2),e3=d;break;case"iframe":case"object":case"embed":D2("load",a2),e3=d;break;case"video":case"audio":for(e3=0;e3Gj&&(b2.flags|=128,d=!0,Dj(f2,!1),b2.lanes=4194304)}else{if(!d)if(a2=Ch(g2),a2!==null){if(b2.flags|=128,d=!0,c2=a2.updateQueue,c2!==null&&(b2.updateQueue=c2,b2.flags|=4),Dj(f2,!0),f2.tail===null&&f2.tailMode==="hidden"&&!g2.alternate&&!I2)return S2(b2),null}else 2*B2()-f2.renderingStartTime>Gj&&c2!==1073741824&&(b2.flags|=128,d=!0,Dj(f2,!1),b2.lanes=4194304);f2.isBackwards?(g2.sibling=b2.child,b2.child=g2):(c2=f2.last,c2!==null?c2.sibling=g2:b2.child=g2,f2.last=g2)}return f2.tail!==null?(b2=f2.tail,f2.rendering=b2,f2.tail=b2.sibling,f2.renderingStartTime=B2(),b2.sibling=null,c2=L2.current,G(L2,d?c2&1|2:c2&1),b2):(S2(b2),null);case 22:case 23:return Hj(),d=b2.memoizedState!==null,a2!==null&&a2.memoizedState!==null!==d&&(b2.flags|=8192),d&&(b2.mode&1)!==0?(fj&1073741824)!==0&&(S2(b2),b2.subtreeFlags&6&&(b2.flags|=8192)):S2(b2),null;case 24:return null;case 25:return null}throw Error(p2(156,b2.tag))}__name(Ej,"Ej");function Ij(a2,b2){switch(wg(b2),b2.tag){case 1:return Zf(b2.type)&&$f(),a2=b2.flags,a2&65536?(b2.flags=a2&-65537|128,b2):null;case 3:return zh(),E2(Wf),E2(H),Eh(),a2=b2.flags,(a2&65536)!==0&&(a2&128)===0?(b2.flags=a2&-65537|128,b2):null;case 5:return Bh(b2),null;case 13:if(E2(L2),a2=b2.memoizedState,a2!==null&&a2.dehydrated!==null){if(b2.alternate===null)throw Error(p2(340));Ig()}return a2=b2.flags,a2&65536?(b2.flags=a2&-65537|128,b2):null;case 19:return E2(L2),null;case 4:return zh(),null;case 10:return ah(b2.type._context),null;case 22:case 23:return Hj(),null;case 24:return null;default:return null}}__name(Ij,"Ij");var Jj=!1,U2=!1,Kj=typeof WeakSet=="function"?WeakSet:Set,V2=null;function Lj(a2,b2){var c2=a2.ref;if(c2!==null)if(typeof c2=="function")try{c2(null)}catch(d){W2(a2,b2,d)}else c2.current=null}__name(Lj,"Lj");function Mj(a2,b2,c2){try{c2()}catch(d){W2(a2,b2,d)}}__name(Mj,"Mj");var Nj=!1;function Oj(a2,b2){if(Cf=dd,a2=Me2(),Ne(a2)){if("selectionStart"in a2)var c2={start:a2.selectionStart,end:a2.selectionEnd};else a:{c2=(c2=a2.ownerDocument)&&c2.defaultView||window;var d=c2.getSelection&&c2.getSelection();if(d&&d.rangeCount!==0){c2=d.anchorNode;var e3=d.anchorOffset,f2=d.focusNode;d=d.focusOffset;try{c2.nodeType,f2.nodeType}catch{c2=null;break a}var g2=0,h2=-1,k2=-1,l2=0,m2=0,q2=a2,r2=null;b:for(;;){for(var y2;q2!==c2||e3!==0&&q2.nodeType!==3||(h2=g2+e3),q2!==f2||d!==0&&q2.nodeType!==3||(k2=g2+d),q2.nodeType===3&&(g2+=q2.nodeValue.length),(y2=q2.firstChild)!==null;)r2=q2,q2=y2;for(;;){if(q2===a2)break b;if(r2===c2&&++l2===e3&&(h2=g2),r2===f2&&++m2===d&&(k2=g2),(y2=q2.nextSibling)!==null)break;q2=r2,r2=q2.parentNode}q2=y2}c2=h2===-1||k2===-1?null:{start:h2,end:k2}}else c2=null}c2=c2||{start:0,end:0}}else c2=null;for(Df={focusedElem:a2,selectionRange:c2},dd=!1,V2=b2;V2!==null;)if(b2=V2,a2=b2.child,(b2.subtreeFlags&1028)!==0&&a2!==null)a2.return=b2,V2=a2;else for(;V2!==null;){b2=V2;try{var n2=b2.alternate;if((b2.flags&1024)!==0)switch(b2.tag){case 0:case 11:case 15:break;case 1:if(n2!==null){var t2=n2.memoizedProps,J2=n2.memoizedState,x2=b2.stateNode,w2=x2.getSnapshotBeforeUpdate(b2.elementType===b2.type?t2:Ci(b2.type,t2),J2);x2.__reactInternalSnapshotBeforeUpdate=w2}break;case 3:var u2=b2.stateNode.containerInfo;u2.nodeType===1?u2.textContent="":u2.nodeType===9&&u2.documentElement&&u2.removeChild(u2.documentElement);break;case 5:case 6:case 4:case 17:break;default:throw Error(p2(163))}}catch(F2){W2(b2,b2.return,F2)}if(a2=b2.sibling,a2!==null){a2.return=b2.return,V2=a2;break}V2=b2.return}return n2=Nj,Nj=!1,n2}__name(Oj,"Oj");function Pj(a2,b2,c2){var d=b2.updateQueue;if(d=d!==null?d.lastEffect:null,d!==null){var e3=d=d.next;do{if((e3.tag&a2)===a2){var f2=e3.destroy;e3.destroy=void 0,f2!==void 0&&Mj(b2,c2,f2)}e3=e3.next}while(e3!==d)}}__name(Pj,"Pj");function Qj(a2,b2){if(b2=b2.updateQueue,b2=b2!==null?b2.lastEffect:null,b2!==null){var c2=b2=b2.next;do{if((c2.tag&a2)===a2){var d=c2.create;c2.destroy=d()}c2=c2.next}while(c2!==b2)}}__name(Qj,"Qj");function Rj(a2){var b2=a2.ref;if(b2!==null){var c2=a2.stateNode;a2.tag,a2=c2,typeof b2=="function"?b2(a2):b2.current=a2}}__name(Rj,"Rj");function Sj(a2){var b2=a2.alternate;b2!==null&&(a2.alternate=null,Sj(b2)),a2.child=null,a2.deletions=null,a2.sibling=null,a2.tag===5&&(b2=a2.stateNode,b2!==null&&(delete b2[Of],delete b2[Pf],delete b2[of],delete b2[Qf],delete b2[Rf])),a2.stateNode=null,a2.return=null,a2.dependencies=null,a2.memoizedProps=null,a2.memoizedState=null,a2.pendingProps=null,a2.stateNode=null,a2.updateQueue=null}__name(Sj,"Sj");function Tj(a2){return a2.tag===5||a2.tag===3||a2.tag===4}__name(Tj,"Tj");function Uj(a2){a:for(;;){for(;a2.sibling===null;){if(a2.return===null||Tj(a2.return))return null;a2=a2.return}for(a2.sibling.return=a2.return,a2=a2.sibling;a2.tag!==5&&a2.tag!==6&&a2.tag!==18;){if(a2.flags&2||a2.child===null||a2.tag===4)continue a;a2.child.return=a2,a2=a2.child}if(!(a2.flags&2))return a2.stateNode}}__name(Uj,"Uj");function Vj(a2,b2,c2){var d=a2.tag;if(d===5||d===6)a2=a2.stateNode,b2?c2.nodeType===8?c2.parentNode.insertBefore(a2,b2):c2.insertBefore(a2,b2):(c2.nodeType===8?(b2=c2.parentNode,b2.insertBefore(a2,c2)):(b2=c2,b2.appendChild(a2)),c2=c2._reactRootContainer,c2!=null||b2.onclick!==null||(b2.onclick=Bf));else if(d!==4&&(a2=a2.child,a2!==null))for(Vj(a2,b2,c2),a2=a2.sibling;a2!==null;)Vj(a2,b2,c2),a2=a2.sibling}__name(Vj,"Vj");function Wj(a2,b2,c2){var d=a2.tag;if(d===5||d===6)a2=a2.stateNode,b2?c2.insertBefore(a2,b2):c2.appendChild(a2);else if(d!==4&&(a2=a2.child,a2!==null))for(Wj(a2,b2,c2),a2=a2.sibling;a2!==null;)Wj(a2,b2,c2),a2=a2.sibling}__name(Wj,"Wj");var X2=null,Xj=!1;function Yj(a2,b2,c2){for(c2=c2.child;c2!==null;)Zj(a2,b2,c2),c2=c2.sibling}__name(Yj,"Yj");function Zj(a2,b2,c2){if(lc&&typeof lc.onCommitFiberUnmount=="function")try{lc.onCommitFiberUnmount(kc,c2)}catch{}switch(c2.tag){case 5:U2||Lj(c2,b2);case 6:var d=X2,e3=Xj;X2=null,Yj(a2,b2,c2),X2=d,Xj=e3,X2!==null&&(Xj?(a2=X2,c2=c2.stateNode,a2.nodeType===8?a2.parentNode.removeChild(c2):a2.removeChild(c2)):X2.removeChild(c2.stateNode));break;case 18:X2!==null&&(Xj?(a2=X2,c2=c2.stateNode,a2.nodeType===8?Kf(a2.parentNode,c2):a2.nodeType===1&&Kf(a2,c2),bd(a2)):Kf(X2,c2.stateNode));break;case 4:d=X2,e3=Xj,X2=c2.stateNode.containerInfo,Xj=!0,Yj(a2,b2,c2),X2=d,Xj=e3;break;case 0:case 11:case 14:case 15:if(!U2&&(d=c2.updateQueue,d!==null&&(d=d.lastEffect,d!==null))){e3=d=d.next;do{var f2=e3,g2=f2.destroy;f2=f2.tag,g2!==void 0&&((f2&2)!==0||(f2&4)!==0)&&Mj(c2,b2,g2),e3=e3.next}while(e3!==d)}Yj(a2,b2,c2);break;case 1:if(!U2&&(Lj(c2,b2),d=c2.stateNode,typeof d.componentWillUnmount=="function"))try{d.props=c2.memoizedProps,d.state=c2.memoizedState,d.componentWillUnmount()}catch(h2){W2(c2,b2,h2)}Yj(a2,b2,c2);break;case 21:Yj(a2,b2,c2);break;case 22:c2.mode&1?(U2=(d=U2)||c2.memoizedState!==null,Yj(a2,b2,c2),U2=d):Yj(a2,b2,c2);break;default:Yj(a2,b2,c2)}}__name(Zj,"Zj");function ak(a2){var b2=a2.updateQueue;if(b2!==null){a2.updateQueue=null;var c2=a2.stateNode;c2===null&&(c2=a2.stateNode=new Kj),b2.forEach(function(b3){var d=bk.bind(null,a2,b3);c2.has(b3)||(c2.add(b3),b3.then(d,d))})}}__name(ak,"ak");function ck(a2,b2){var c2=b2.deletions;if(c2!==null)for(var d=0;de3&&(e3=g2),d&=~f2}if(d=e3,d=B2()-d,d=(120>d?120:480>d?480:1080>d?1080:1920>d?1920:3e3>d?3e3:4320>d?4320:1960*lk(d/1960))-d,10a2?16:a2,wk===null)var d=!1;else{if(a2=wk,wk=null,xk=0,(K2&6)!==0)throw Error(p2(331));var e3=K2;for(K2|=4,V2=a2.current;V2!==null;){var f2=V2,g2=f2.child;if((V2.flags&16)!==0){var h2=f2.deletions;if(h2!==null){for(var k2=0;k2B2()-fk?Kk(a2,0):rk|=c2),Dk(a2,b2)}__name(Ti,"Ti");function Yk(a2,b2){b2===0&&((a2.mode&1)===0?b2=1:(b2=sc,sc<<=1,(sc&130023424)===0&&(sc=4194304)));var c2=R2();a2=ih(a2,b2),a2!==null&&(Ac(a2,b2,c2),Dk(a2,c2))}__name(Yk,"Yk");function uj(a2){var b2=a2.memoizedState,c2=0;b2!==null&&(c2=b2.retryLane),Yk(a2,c2)}__name(uj,"uj");function bk(a2,b2){var c2=0;switch(a2.tag){case 13:var d=a2.stateNode,e3=a2.memoizedState;e3!==null&&(c2=e3.retryLane);break;case 19:d=a2.stateNode;break;default:throw Error(p2(314))}d!==null&&d.delete(b2),Yk(a2,c2)}__name(bk,"bk");var Vk;Vk=__name(function(a2,b2,c2){if(a2!==null)if(a2.memoizedProps!==b2.pendingProps||Wf.current)dh=!0;else{if((a2.lanes&c2)===0&&(b2.flags&128)===0)return dh=!1,yj(a2,b2,c2);dh=(a2.flags&131072)!==0}else dh=!1,I2&&(b2.flags&1048576)!==0&&ug(b2,ng,b2.index);switch(b2.lanes=0,b2.tag){case 2:var d=b2.type;ij(a2,b2),a2=b2.pendingProps;var e3=Yf(b2,H.current);ch(b2,c2),e3=Nh(null,b2,d,a2,e3,c2);var f2=Sh();return b2.flags|=1,typeof e3=="object"&&e3!==null&&typeof e3.render=="function"&&e3.$$typeof===void 0?(b2.tag=1,b2.memoizedState=null,b2.updateQueue=null,Zf(d)?(f2=!0,cg(b2)):f2=!1,b2.memoizedState=e3.state!==null&&e3.state!==void 0?e3.state:null,kh(b2),e3.updater=Ei,b2.stateNode=e3,e3._reactInternals=b2,Ii(b2,d,a2,c2),b2=jj(null,b2,d,!0,f2,c2)):(b2.tag=0,I2&&f2&&vg(b2),Xi(null,b2,e3,c2),b2=b2.child),b2;case 16:d=b2.elementType;a:{switch(ij(a2,b2),a2=b2.pendingProps,e3=d._init,d=e3(d._payload),b2.type=d,e3=b2.tag=Zk(d),a2=Ci(d,a2),e3){case 0:b2=cj(null,b2,d,a2,c2);break a;case 1:b2=hj(null,b2,d,a2,c2);break a;case 11:b2=Yi(null,b2,d,a2,c2);break a;case 14:b2=$i(null,b2,d,Ci(d.type,a2),c2);break a}throw Error(p2(306,d,""))}return b2;case 0:return d=b2.type,e3=b2.pendingProps,e3=b2.elementType===d?e3:Ci(d,e3),cj(a2,b2,d,e3,c2);case 1:return d=b2.type,e3=b2.pendingProps,e3=b2.elementType===d?e3:Ci(d,e3),hj(a2,b2,d,e3,c2);case 3:a:{if(kj(b2),a2===null)throw Error(p2(387));d=b2.pendingProps,f2=b2.memoizedState,e3=f2.element,lh(a2,b2),qh(b2,d,null,c2);var g2=b2.memoizedState;if(d=g2.element,f2.isDehydrated)if(f2={element:d,isDehydrated:!1,cache:g2.cache,pendingSuspenseBoundaries:g2.pendingSuspenseBoundaries,transitions:g2.transitions},b2.updateQueue.baseState=f2,b2.memoizedState=f2,b2.flags&256){e3=Ji(Error(p2(423)),b2),b2=lj(a2,b2,d,c2,e3);break a}else if(d!==e3){e3=Ji(Error(p2(424)),b2),b2=lj(a2,b2,d,c2,e3);break a}else for(yg=Lf(b2.stateNode.containerInfo.firstChild),xg=b2,I2=!0,zg=null,c2=Vg(b2,null,d,c2),b2.child=c2;c2;)c2.flags=c2.flags&-3|4096,c2=c2.sibling;else{if(Ig(),d===e3){b2=Zi(a2,b2,c2);break a}Xi(a2,b2,d,c2)}b2=b2.child}return b2;case 5:return Ah(b2),a2===null&&Eg(b2),d=b2.type,e3=b2.pendingProps,f2=a2!==null?a2.memoizedProps:null,g2=e3.children,Ef(d,e3)?g2=null:f2!==null&&Ef(d,f2)&&(b2.flags|=32),gj(a2,b2),Xi(a2,b2,g2,c2),b2.child;case 6:return a2===null&&Eg(b2),null;case 13:return oj(a2,b2,c2);case 4:return yh(b2,b2.stateNode.containerInfo),d=b2.pendingProps,a2===null?b2.child=Ug(b2,null,d,c2):Xi(a2,b2,d,c2),b2.child;case 11:return d=b2.type,e3=b2.pendingProps,e3=b2.elementType===d?e3:Ci(d,e3),Yi(a2,b2,d,e3,c2);case 7:return Xi(a2,b2,b2.pendingProps,c2),b2.child;case 8:return Xi(a2,b2,b2.pendingProps.children,c2),b2.child;case 12:return Xi(a2,b2,b2.pendingProps.children,c2),b2.child;case 10:a:{if(d=b2.type._context,e3=b2.pendingProps,f2=b2.memoizedProps,g2=e3.value,G(Wg,d._currentValue),d._currentValue=g2,f2!==null)if(He2(f2.value,g2)){if(f2.children===e3.children&&!Wf.current){b2=Zi(a2,b2,c2);break a}}else for(f2=b2.child,f2!==null&&(f2.return=b2);f2!==null;){var h2=f2.dependencies;if(h2!==null){g2=f2.child;for(var k2=h2.firstContext;k2!==null;){if(k2.context===d){if(f2.tag===1){k2=mh(-1,c2&-c2),k2.tag=2;var l2=f2.updateQueue;if(l2!==null){l2=l2.shared;var m2=l2.pending;m2===null?k2.next=k2:(k2.next=m2.next,m2.next=k2),l2.pending=k2}}f2.lanes|=c2,k2=f2.alternate,k2!==null&&(k2.lanes|=c2),bh(f2.return,c2,b2),h2.lanes|=c2;break}k2=k2.next}}else if(f2.tag===10)g2=f2.type===b2.type?null:f2.child;else if(f2.tag===18){if(g2=f2.return,g2===null)throw Error(p2(341));g2.lanes|=c2,h2=g2.alternate,h2!==null&&(h2.lanes|=c2),bh(g2,c2,b2),g2=f2.sibling}else g2=f2.child;if(g2!==null)g2.return=f2;else for(g2=f2;g2!==null;){if(g2===b2){g2=null;break}if(f2=g2.sibling,f2!==null){f2.return=g2.return,g2=f2;break}g2=g2.return}f2=g2}Xi(a2,b2,e3.children,c2),b2=b2.child}return b2;case 9:return e3=b2.type,d=b2.pendingProps.children,ch(b2,c2),e3=eh(e3),d=d(e3),b2.flags|=1,Xi(a2,b2,d,c2),b2.child;case 14:return d=b2.type,e3=Ci(d,b2.pendingProps),e3=Ci(d.type,e3),$i(a2,b2,d,e3,c2);case 15:return bj(a2,b2,b2.type,b2.pendingProps,c2);case 17:return d=b2.type,e3=b2.pendingProps,e3=b2.elementType===d?e3:Ci(d,e3),ij(a2,b2),b2.tag=1,Zf(d)?(a2=!0,cg(b2)):a2=!1,ch(b2,c2),Gi(b2,d,e3),Ii(b2,d,e3,c2),jj(null,b2,d,!0,a2,c2);case 19:return xj(a2,b2,c2);case 22:return dj(a2,b2,c2)}throw Error(p2(156,b2.tag))},"Vk");function Fk(a2,b2){return ac(a2,b2)}__name(Fk,"Fk");function $k(a2,b2,c2,d){this.tag=a2,this.key=c2,this.sibling=this.child=this.return=this.stateNode=this.type=this.elementType=null,this.index=0,this.ref=null,this.pendingProps=b2,this.dependencies=this.memoizedState=this.updateQueue=this.memoizedProps=null,this.mode=d,this.subtreeFlags=this.flags=0,this.deletions=null,this.childLanes=this.lanes=0,this.alternate=null}__name($k,"$k");function Bg(a2,b2,c2,d){return new $k(a2,b2,c2,d)}__name(Bg,"Bg");function aj(a2){return a2=a2.prototype,!(!a2||!a2.isReactComponent)}__name(aj,"aj");function Zk(a2){if(typeof a2=="function")return aj(a2)?1:0;if(a2!=null){if(a2=a2.$$typeof,a2===Da)return 11;if(a2===Ga)return 14}return 2}__name(Zk,"Zk");function Pg(a2,b2){var c2=a2.alternate;return c2===null?(c2=Bg(a2.tag,b2,a2.key,a2.mode),c2.elementType=a2.elementType,c2.type=a2.type,c2.stateNode=a2.stateNode,c2.alternate=a2,a2.alternate=c2):(c2.pendingProps=b2,c2.type=a2.type,c2.flags=0,c2.subtreeFlags=0,c2.deletions=null),c2.flags=a2.flags&14680064,c2.childLanes=a2.childLanes,c2.lanes=a2.lanes,c2.child=a2.child,c2.memoizedProps=a2.memoizedProps,c2.memoizedState=a2.memoizedState,c2.updateQueue=a2.updateQueue,b2=a2.dependencies,c2.dependencies=b2===null?null:{lanes:b2.lanes,firstContext:b2.firstContext},c2.sibling=a2.sibling,c2.index=a2.index,c2.ref=a2.ref,c2}__name(Pg,"Pg");function Rg(a2,b2,c2,d,e3,f2){var g2=2;if(d=a2,typeof a2=="function")aj(a2)&&(g2=1);else if(typeof a2=="string")g2=5;else a:switch(a2){case ya:return Tg(c2.children,e3,f2,b2);case za:g2=8,e3|=8;break;case Aa:return a2=Bg(12,c2,b2,e3|2),a2.elementType=Aa,a2.lanes=f2,a2;case Ea:return a2=Bg(13,c2,b2,e3),a2.elementType=Ea,a2.lanes=f2,a2;case Fa:return a2=Bg(19,c2,b2,e3),a2.elementType=Fa,a2.lanes=f2,a2;case Ia:return pj(c2,e3,f2,b2);default:if(typeof a2=="object"&&a2!==null)switch(a2.$$typeof){case Ba:g2=10;break a;case Ca:g2=9;break a;case Da:g2=11;break a;case Ga:g2=14;break a;case Ha:g2=16,d=null;break a}throw Error(p2(130,a2==null?a2:typeof a2,""))}return b2=Bg(g2,c2,b2,e3),b2.elementType=a2,b2.type=d,b2.lanes=f2,b2}__name(Rg,"Rg");function Tg(a2,b2,c2,d){return a2=Bg(7,a2,d,b2),a2.lanes=c2,a2}__name(Tg,"Tg");function pj(a2,b2,c2,d){return a2=Bg(22,a2,d,b2),a2.elementType=Ia,a2.lanes=c2,a2.stateNode={isHidden:!1},a2}__name(pj,"pj");function Qg(a2,b2,c2){return a2=Bg(6,a2,null,b2),a2.lanes=c2,a2}__name(Qg,"Qg");function Sg(a2,b2,c2){return b2=Bg(4,a2.children!==null?a2.children:[],a2.key,b2),b2.lanes=c2,b2.stateNode={containerInfo:a2.containerInfo,pendingChildren:null,implementation:a2.implementation},b2}__name(Sg,"Sg");function al(a2,b2,c2,d,e3){this.tag=b2,this.containerInfo=a2,this.finishedWork=this.pingCache=this.current=this.pendingChildren=null,this.timeoutHandle=-1,this.callbackNode=this.pendingContext=this.context=null,this.callbackPriority=0,this.eventTimes=zc(0),this.expirationTimes=zc(-1),this.entangledLanes=this.finishedLanes=this.mutableReadLanes=this.expiredLanes=this.pingedLanes=this.suspendedLanes=this.pendingLanes=0,this.entanglements=zc(0),this.identifierPrefix=d,this.onRecoverableError=e3,this.mutableSourceEagerHydrationData=null}__name(al,"al");function bl(a2,b2,c2,d,e3,f2,g2,h2,k2){return a2=new al(a2,b2,c2,h2,k2),b2===1?(b2=1,f2===!0&&(b2|=8)):b2=0,f2=Bg(3,null,null,b2),a2.current=f2,f2.stateNode=a2,f2.memoizedState={element:d,isDehydrated:c2,cache:null,transitions:null,pendingSuspenseBoundaries:null},kh(f2),a2}__name(bl,"bl");function cl(a2,b2,c2){var d=3"u"||typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.checkDCE!="function"))try{__REACT_DEVTOOLS_GLOBAL_HOOK__.checkDCE(checkDCE)}catch(err){console.error(err)}}return __name(checkDCE,"checkDCE"),checkDCE(),reactDom.exports=requireReactDom_production_min(),reactDom.exports}__name(requireReactDom,"requireReactDom");var hasRequiredClient;function requireClient(){if(hasRequiredClient)return client;hasRequiredClient=1;var m2=requireReactDom();return client.createRoot=m2.createRoot,client.hydrateRoot=m2.hydrateRoot,client}__name(requireClient,"requireClient");var clientExports=requireClient();const ReactDOM$2=getDefaultExportFromCjs(clientExports);var reactDomExports=requireReactDom();const ReactDOM=getDefaultExportFromCjs(reactDomExports),ReactDOM$1=_mergeNamespaces({__proto__:null,default:ReactDOM},[reactDomExports]);function _extends$x(){return _extends$x=Object.assign?Object.assign.bind():function(target){for(var i2=1;i2"u")throw new Error(message)}__name(invariant$1,"invariant$1");function warning(cond,message){if(!cond){typeof console<"u"&&console.warn(message);try{throw new Error(message)}catch{}}}__name(warning,"warning");function createKey(){return Math.random().toString(36).substr(2,8)}__name(createKey,"createKey");function getHistoryState(location2,index2){return{usr:location2.state,key:location2.key,idx:index2}}__name(getHistoryState,"getHistoryState");function createLocation$1(current,to2,state,key){return state===void 0&&(state=null),_extends$x({pathname:typeof current=="string"?current:current.pathname,search:"",hash:""},typeof to2=="string"?parsePath(to2):to2,{state,key:to2&&to2.key||key||createKey()})}__name(createLocation$1,"createLocation$1");function createPath(_ref){let{pathname="/",search:search2="",hash=""}=_ref;return search2&&search2!=="?"&&(pathname+=search2.charAt(0)==="?"?search2:"?"+search2),hash&&hash!=="#"&&(pathname+=hash.charAt(0)==="#"?hash:"#"+hash),pathname}__name(createPath,"createPath");function parsePath(path2){let parsedPath={};if(path2){let hashIndex=path2.indexOf("#");hashIndex>=0&&(parsedPath.hash=path2.substr(hashIndex),path2=path2.substr(0,hashIndex));let searchIndex=path2.indexOf("?");searchIndex>=0&&(parsedPath.search=path2.substr(searchIndex),path2=path2.substr(0,searchIndex)),path2&&(parsedPath.pathname=path2)}return parsedPath}__name(parsePath,"parsePath");function getUrlBasedHistory(getLocation,createHref,validateLocation,options){options===void 0&&(options={});let{window:window2=document.defaultView,v5Compat=!1}=options,globalHistory=window2.history,action=Action.Pop,listener=null,index2=getIndex();index2==null&&(index2=0,globalHistory.replaceState(_extends$x({},globalHistory.state,{idx:index2}),""));function getIndex(){return(globalHistory.state||{idx:null}).idx}__name(getIndex,"getIndex");function handlePop(){action=Action.Pop;let nextIndex=getIndex(),delta=nextIndex==null?null:nextIndex-index2;index2=nextIndex,listener&&listener({action,location:history.location,delta})}__name(handlePop,"handlePop");function push2(to2,state){action=Action.Push;let location2=createLocation$1(history.location,to2,state);validateLocation&&validateLocation(location2,to2),index2=getIndex()+1;let historyState=getHistoryState(location2,index2),url=history.createHref(location2);try{globalHistory.pushState(historyState,"",url)}catch(error){if(error instanceof DOMException&&error.name==="DataCloneError")throw error;window2.location.assign(url)}v5Compat&&listener&&listener({action,location:history.location,delta:1})}__name(push2,"push");function replace2(to2,state){action=Action.Replace;let location2=createLocation$1(history.location,to2,state);validateLocation&&validateLocation(location2,to2),index2=getIndex();let historyState=getHistoryState(location2,index2),url=history.createHref(location2);globalHistory.replaceState(historyState,"",url),v5Compat&&listener&&listener({action,location:history.location,delta:0})}__name(replace2,"replace2");function createURL(to2){let base=window2.location.origin!=="null"?window2.location.origin:window2.location.href,href=typeof to2=="string"?to2:createPath(to2);return href=href.replace(/ $/,"%20"),invariant$1(base,"No window.location.(origin|href) available to create URL for href: "+href),new URL(href,base)}__name(createURL,"createURL");let history={get action(){return action},get location(){return getLocation(window2,globalHistory)},listen(fn2){if(listener)throw new Error("A history only accepts one active listener");return window2.addEventListener(PopStateEventType,handlePop),listener=fn2,()=>{window2.removeEventListener(PopStateEventType,handlePop),listener=null}},createHref(to2){return createHref(window2,to2)},createURL,encodeLocation(to2){let url=createURL(to2);return{pathname:url.pathname,search:url.search,hash:url.hash}},push:push2,replace:replace2,go(n2){return globalHistory.go(n2)}};return history}__name(getUrlBasedHistory,"getUrlBasedHistory");var ResultType;(function(ResultType2){ResultType2.data="data",ResultType2.deferred="deferred",ResultType2.redirect="redirect",ResultType2.error="error"})(ResultType||(ResultType={}));const immutableRouteKeys=new Set(["lazy","caseSensitive","path","id","index","children"]);function isIndexRoute(route){return route.index===!0}__name(isIndexRoute,"isIndexRoute");function convertRoutesToDataRoutes(routes,mapRouteProperties2,parentPath,manifest){return parentPath===void 0&&(parentPath=[]),manifest===void 0&&(manifest={}),routes.map((route,index2)=>{let treePath=[...parentPath,String(index2)],id=typeof route.id=="string"?route.id:treePath.join("-");if(invariant$1(route.index!==!0||!route.children,"Cannot specify children on an index route"),invariant$1(!manifest[id],'Found a route id collision on id "'+id+`". Route id's must be globally unique within Data Router usages`),isIndexRoute(route)){let indexRoute=_extends$x({},route,mapRouteProperties2(route),{id});return manifest[id]=indexRoute,indexRoute}else{let pathOrLayoutRoute=_extends$x({},route,mapRouteProperties2(route),{id,children:void 0});return manifest[id]=pathOrLayoutRoute,route.children&&(pathOrLayoutRoute.children=convertRoutesToDataRoutes(route.children,mapRouteProperties2,treePath,manifest)),pathOrLayoutRoute}})}__name(convertRoutesToDataRoutes,"convertRoutesToDataRoutes");function matchRoutes(routes,locationArg,basename2){return basename2===void 0&&(basename2="/"),matchRoutesImpl(routes,locationArg,basename2,!1)}__name(matchRoutes,"matchRoutes");function matchRoutesImpl(routes,locationArg,basename2,allowPartial){let location2=typeof locationArg=="string"?parsePath(locationArg):locationArg,pathname=stripBasename(location2.pathname||"/",basename2);if(pathname==null)return null;let branches=flattenRoutes(routes);rankRouteBranches(branches);let matches=null;for(let i2=0;matches==null&&i2{let meta={relativePath:relativePath===void 0?route.path||"":relativePath,caseSensitive:route.caseSensitive===!0,childrenIndex:index2,route};meta.relativePath.startsWith("/")&&(invariant$1(meta.relativePath.startsWith(parentPath),'Absolute route path "'+meta.relativePath+'" nested under path '+('"'+parentPath+'" is not valid. An absolute child route path ')+"must start with the combined path of all its parent routes."),meta.relativePath=meta.relativePath.slice(parentPath.length));let path2=joinPaths([parentPath,meta.relativePath]),routesMeta=parentsMeta.concat(meta);route.children&&route.children.length>0&&(invariant$1(route.index!==!0,"Index routes must not have child routes. Please remove "+('all child routes from route path "'+path2+'".')),flattenRoutes(route.children,branches,routesMeta,path2)),!(route.path==null&&!route.index)&&branches.push({path:path2,score:computeScore(path2,route.index),routesMeta})},"flattenRoute");return routes.forEach((route,index2)=>{var _route$path;if(route.path===""||!((_route$path=route.path)!=null&&_route$path.includes("?")))flattenRoute(route,index2);else for(let exploded of explodeOptionalSegments(route.path))flattenRoute(route,index2,exploded)}),branches}__name(flattenRoutes,"flattenRoutes");function explodeOptionalSegments(path2){let segments=path2.split("/");if(segments.length===0)return[];let[first,...rest]=segments,isOptional=first.endsWith("?"),required=first.replace(/\?$/,"");if(rest.length===0)return isOptional?[required,""]:[required];let restExploded=explodeOptionalSegments(rest.join("/")),result=[];return result.push(...restExploded.map(subpath=>subpath===""?required:[required,subpath].join("/"))),isOptional&&result.push(...restExploded),result.map(exploded=>path2.startsWith("/")&&exploded===""?"/":exploded)}__name(explodeOptionalSegments,"explodeOptionalSegments");function rankRouteBranches(branches){branches.sort((a2,b2)=>a2.score!==b2.score?b2.score-a2.score:compareIndexes(a2.routesMeta.map(meta=>meta.childrenIndex),b2.routesMeta.map(meta=>meta.childrenIndex)))}__name(rankRouteBranches,"rankRouteBranches");const paramRe=/^:[\w-]+$/,dynamicSegmentValue=3,indexRouteValue=2,emptySegmentValue=1,staticSegmentValue=10,splatPenalty=-2,isSplat=__name(s2=>s2==="*","isSplat");function computeScore(path2,index2){let segments=path2.split("/"),initialScore=segments.length;return segments.some(isSplat)&&(initialScore+=splatPenalty),index2&&(initialScore+=indexRouteValue),segments.filter(s2=>!isSplat(s2)).reduce((score,segment)=>score+(paramRe.test(segment)?dynamicSegmentValue:segment===""?emptySegmentValue:staticSegmentValue),initialScore)}__name(computeScore,"computeScore");function compareIndexes(a2,b2){return a2.length===b2.length&&a2.slice(0,-1).every((n2,i2)=>n2===b2[i2])?a2[a2.length-1]-b2[b2.length-1]:0}__name(compareIndexes,"compareIndexes");function matchRouteBranch(branch,pathname,allowPartial){allowPartial===void 0&&(allowPartial=!1);let{routesMeta}=branch,matchedParams={},matchedPathname="/",matches=[];for(let i2=0;i2{let{paramName,isOptional}=_ref;if(paramName==="*"){let splatValue=captureGroups[index2]||"";pathnameBase=matchedPathname.slice(0,matchedPathname.length-splatValue.length).replace(/(.)\/+$/,"$1")}const value2=captureGroups[index2];return isOptional&&!value2?memo2[paramName]=void 0:memo2[paramName]=(value2||"").replace(/%2F/g,"/"),memo2},{}),pathname:matchedPathname,pathnameBase,pattern}}__name(matchPath,"matchPath");function compilePath(path2,caseSensitive,end){caseSensitive===void 0&&(caseSensitive=!1),end===void 0&&(end=!0),warning(path2==="*"||!path2.endsWith("*")||path2.endsWith("/*"),'Route path "'+path2+'" will be treated as if it were '+('"'+path2.replace(/\*$/,"/*")+'" because the `*` character must ')+"always follow a `/` in the pattern. To get rid of this warning, "+('please change the route path to "'+path2.replace(/\*$/,"/*")+'".'));let params=[],regexpSource="^"+path2.replace(/\/*\*?$/,"").replace(/^\/*/,"/").replace(/[\\.*+^${}|()[\]]/g,"\\$&").replace(/\/:([\w-]+)(\?)?/g,(_2,paramName,isOptional)=>(params.push({paramName,isOptional:isOptional!=null}),isOptional?"/?([^\\/]+)?":"/([^\\/]+)"));return path2.endsWith("*")?(params.push({paramName:"*"}),regexpSource+=path2==="*"||path2==="/*"?"(.*)$":"(?:\\/(.+)|\\/*)$"):end?regexpSource+="\\/*$":path2!==""&&path2!=="/"&&(regexpSource+="(?:(?=\\/|$))"),[new RegExp(regexpSource,caseSensitive?void 0:"i"),params]}__name(compilePath,"compilePath");function decodePath(value2){try{return value2.split("/").map(v2=>decodeURIComponent(v2).replace(/\//g,"%2F")).join("/")}catch(error){return warning(!1,'The URL path "'+value2+'" could not be decoded because it is is a malformed URL segment. This is probably due to a bad percent '+("encoding ("+error+").")),value2}}__name(decodePath,"decodePath");function stripBasename(pathname,basename2){if(basename2==="/")return pathname;if(!pathname.toLowerCase().startsWith(basename2.toLowerCase()))return null;let startIndex=basename2.endsWith("/")?basename2.length-1:basename2.length,nextChar=pathname.charAt(startIndex);return nextChar&&nextChar!=="/"?null:pathname.slice(startIndex)||"/"}__name(stripBasename,"stripBasename");const ABSOLUTE_URL_REGEX$1=/^(?:[a-z][a-z0-9+.-]*:|\/\/)/i,isAbsoluteUrl=__name(url=>ABSOLUTE_URL_REGEX$1.test(url),"isAbsoluteUrl");function resolvePath(to2,fromPathname){fromPathname===void 0&&(fromPathname="/");let{pathname:toPathname,search:search2="",hash=""}=typeof to2=="string"?parsePath(to2):to2,pathname;if(toPathname)if(isAbsoluteUrl(toPathname))pathname=toPathname;else{if(toPathname.includes("//")){let oldPathname=toPathname;toPathname=toPathname.replace(/\/\/+/g,"/"),warning(!1,"Pathnames cannot have embedded double slashes - normalizing "+(oldPathname+" -> "+toPathname))}toPathname.startsWith("/")?pathname=resolvePathname(toPathname.substring(1),"/"):pathname=resolvePathname(toPathname,fromPathname)}else pathname=fromPathname;return{pathname,search:normalizeSearch(search2),hash:normalizeHash(hash)}}__name(resolvePath,"resolvePath");function resolvePathname(relativePath,fromPathname){let segments=fromPathname.replace(/\/+$/,"").split("/");return relativePath.split("/").forEach(segment=>{segment===".."?segments.length>1&&segments.pop():segment!=="."&&segments.push(segment)}),segments.length>1?segments.join("/"):"/"}__name(resolvePathname,"resolvePathname");function getInvalidPathError(char,field,dest,path2){return"Cannot include a '"+char+"' character in a manually specified "+("`to."+field+"` field ["+JSON.stringify(path2)+"]. Please separate it out to the ")+("`to."+dest+"` field. Alternatively you may provide the full path as ")+'a string in and the router will parse it for you.'}__name(getInvalidPathError,"getInvalidPathError");function getPathContributingMatches(matches){return matches.filter((match,index2)=>index2===0||match.route.path&&match.route.path.length>0)}__name(getPathContributingMatches,"getPathContributingMatches");function getResolveToMatches(matches,v7_relativeSplatPath){let pathMatches=getPathContributingMatches(matches);return v7_relativeSplatPath?pathMatches.map((match,idx)=>idx===pathMatches.length-1?match.pathname:match.pathnameBase):pathMatches.map(match=>match.pathnameBase)}__name(getResolveToMatches,"getResolveToMatches");function resolveTo(toArg,routePathnames,locationPathname,isPathRelative){isPathRelative===void 0&&(isPathRelative=!1);let to2;typeof toArg=="string"?to2=parsePath(toArg):(to2=_extends$x({},toArg),invariant$1(!to2.pathname||!to2.pathname.includes("?"),getInvalidPathError("?","pathname","search",to2)),invariant$1(!to2.pathname||!to2.pathname.includes("#"),getInvalidPathError("#","pathname","hash",to2)),invariant$1(!to2.search||!to2.search.includes("#"),getInvalidPathError("#","search","hash",to2)));let isEmptyPath=toArg===""||to2.pathname==="",toPathname=isEmptyPath?"/":to2.pathname,from;if(toPathname==null)from=locationPathname;else{let routePathnameIndex=routePathnames.length-1;if(!isPathRelative&&toPathname.startsWith("..")){let toSegments=toPathname.split("/");for(;toSegments[0]==="..";)toSegments.shift(),routePathnameIndex-=1;to2.pathname=toSegments.join("/")}from=routePathnameIndex>=0?routePathnames[routePathnameIndex]:"/"}let path2=resolvePath(to2,from),hasExplicitTrailingSlash=toPathname&&toPathname!=="/"&&toPathname.endsWith("/"),hasCurrentTrailingSlash=(isEmptyPath||toPathname===".")&&locationPathname.endsWith("/");return!path2.pathname.endsWith("/")&&(hasExplicitTrailingSlash||hasCurrentTrailingSlash)&&(path2.pathname+="/"),path2}__name(resolveTo,"resolveTo");const joinPaths=__name(paths=>paths.join("/").replace(/\/\/+/g,"/"),"joinPaths"),normalizePathname=__name(pathname=>pathname.replace(/\/+$/,"").replace(/^\/*/,"/"),"normalizePathname"),normalizeSearch=__name(search2=>!search2||search2==="?"?"":search2.startsWith("?")?search2:"?"+search2,"normalizeSearch"),normalizeHash=__name(hash=>!hash||hash==="#"?"":hash.startsWith("#")?hash:"#"+hash,"normalizeHash"),_ErrorResponseImpl=class _ErrorResponseImpl{constructor(status,statusText,data2,internal){internal===void 0&&(internal=!1),this.status=status,this.statusText=statusText||"",this.internal=internal,data2 instanceof Error?(this.data=data2.toString(),this.error=data2):this.data=data2}};__name(_ErrorResponseImpl,"ErrorResponseImpl");let ErrorResponseImpl=_ErrorResponseImpl;function isRouteErrorResponse(error){return error!=null&&typeof error.status=="number"&&typeof error.statusText=="string"&&typeof error.internal=="boolean"&&"data"in error}__name(isRouteErrorResponse,"isRouteErrorResponse");const validMutationMethodsArr=["post","put","patch","delete"],validMutationMethods=new Set(validMutationMethodsArr),validRequestMethodsArr=["get",...validMutationMethodsArr],validRequestMethods=new Set(validRequestMethodsArr),redirectStatusCodes=new Set([301,302,303,307,308]),redirectPreserveMethodStatusCodes=new Set([307,308]),IDLE_NAVIGATION={state:"idle",location:void 0,formMethod:void 0,formAction:void 0,formEncType:void 0,formData:void 0,json:void 0,text:void 0},IDLE_FETCHER={state:"idle",data:void 0,formMethod:void 0,formAction:void 0,formEncType:void 0,formData:void 0,json:void 0,text:void 0},IDLE_BLOCKER={state:"unblocked",proceed:void 0,reset:void 0,location:void 0},ABSOLUTE_URL_REGEX$2=/^(?:[a-z][a-z0-9+.-]*:|\/\/)/i,defaultMapRouteProperties=__name(route=>({hasErrorBoundary:!!route.hasErrorBoundary}),"defaultMapRouteProperties"),TRANSITIONS_STORAGE_KEY="remix-router-transitions";function createRouter(init){const routerWindow=init.window?init.window:typeof window<"u"?window:void 0,isBrowser2=typeof routerWindow<"u"&&typeof routerWindow.document<"u"&&typeof routerWindow.document.createElement<"u",isServer=!isBrowser2;invariant$1(init.routes.length>0,"You must provide a non-empty routes array to createRouter");let mapRouteProperties2;if(init.mapRouteProperties)mapRouteProperties2=init.mapRouteProperties;else if(init.detectErrorBoundary){let detectErrorBoundary=init.detectErrorBoundary;mapRouteProperties2=__name(route=>({hasErrorBoundary:detectErrorBoundary(route)}),"mapRouteProperties")}else mapRouteProperties2=defaultMapRouteProperties;let manifest={},dataRoutes=convertRoutesToDataRoutes(init.routes,mapRouteProperties2,void 0,manifest),inFlightDataRoutes,basename2=init.basename||"/",dataStrategyImpl=init.dataStrategy||defaultDataStrategy,patchRoutesOnNavigationImpl=init.patchRoutesOnNavigation,future=_extends$x({v7_fetcherPersist:!1,v7_normalizeFormMethod:!1,v7_partialHydration:!1,v7_prependBasename:!1,v7_relativeSplatPath:!1,v7_skipActionErrorRevalidation:!1},init.future),unlistenHistory=null,subscribers=new Set,savedScrollPositions=null,getScrollRestorationKey=null,getScrollPosition=null,initialScrollRestored=init.hydrationData!=null,initialMatches=matchRoutes(dataRoutes,init.history.location,basename2),initialMatchesIsFOW=!1,initialErrors=null;if(initialMatches==null&&!patchRoutesOnNavigationImpl){let error=getInternalRouterError(404,{pathname:init.history.location.pathname}),{matches,route}=getShortCircuitMatches(dataRoutes);initialMatches=matches,initialErrors={[route.id]:error}}initialMatches&&!init.hydrationData&&checkFogOfWar(initialMatches,dataRoutes,init.history.location.pathname).active&&(initialMatches=null);let initialized;if(initialMatches)if(initialMatches.some(m2=>m2.route.lazy))initialized=!1;else if(!initialMatches.some(m2=>m2.route.loader))initialized=!0;else if(future.v7_partialHydration){let loaderData=init.hydrationData?init.hydrationData.loaderData:null,errors=init.hydrationData?init.hydrationData.errors:null;if(errors){let idx=initialMatches.findIndex(m2=>errors[m2.route.id]!==void 0);initialized=initialMatches.slice(0,idx+1).every(m2=>!shouldLoadRouteOnHydration(m2.route,loaderData,errors))}else initialized=initialMatches.every(m2=>!shouldLoadRouteOnHydration(m2.route,loaderData,errors))}else initialized=init.hydrationData!=null;else if(initialized=!1,initialMatches=[],future.v7_partialHydration){let fogOfWar=checkFogOfWar(null,dataRoutes,init.history.location.pathname);fogOfWar.active&&fogOfWar.matches&&(initialMatchesIsFOW=!0,initialMatches=fogOfWar.matches)}let router2,state={historyAction:init.history.action,location:init.history.location,matches:initialMatches,initialized,navigation:IDLE_NAVIGATION,restoreScrollPosition:init.hydrationData!=null?!1:null,preventScrollReset:!1,revalidation:"idle",loaderData:init.hydrationData&&init.hydrationData.loaderData||{},actionData:init.hydrationData&&init.hydrationData.actionData||null,errors:init.hydrationData&&init.hydrationData.errors||initialErrors,fetchers:new Map,blockers:new Map},pendingAction=Action.Pop,pendingPreventScrollReset=!1,pendingNavigationController,pendingViewTransitionEnabled=!1,appliedViewTransitions=new Map,removePageHideEventListener=null,isUninterruptedRevalidation=!1,isRevalidationRequired=!1,cancelledDeferredRoutes=[],cancelledFetcherLoads=new Set,fetchControllers=new Map,incrementingLoadId=0,pendingNavigationLoadId=-1,fetchReloadIds=new Map,fetchRedirectIds=new Set,fetchLoadMatches=new Map,activeFetchers=new Map,deletedFetchers=new Set,activeDeferreds=new Map,blockerFunctions=new Map,unblockBlockerHistoryUpdate;function initialize(){if(unlistenHistory=init.history.listen(_ref=>{let{action:historyAction,location:location2,delta}=_ref;if(unblockBlockerHistoryUpdate){unblockBlockerHistoryUpdate(),unblockBlockerHistoryUpdate=void 0;return}warning(blockerFunctions.size===0||delta!=null,"You are trying to use a blocker on a POP navigation to a location that was not created by @remix-run/router. This will fail silently in production. This can happen if you are navigating outside the router via `window.history.pushState`/`window.location.hash` instead of using router navigation APIs. This can also happen if you are using createHashRouter and the user manually changes the URL.");let blockerKey=shouldBlockNavigation({currentLocation:state.location,nextLocation:location2,historyAction});if(blockerKey&&delta!=null){let nextHistoryUpdatePromise=new Promise(resolve=>{unblockBlockerHistoryUpdate=resolve});init.history.go(delta*-1),updateBlocker(blockerKey,{state:"blocked",location:location2,proceed(){updateBlocker(blockerKey,{state:"proceeding",proceed:void 0,reset:void 0,location:location2}),nextHistoryUpdatePromise.then(()=>init.history.go(delta))},reset(){let blockers=new Map(state.blockers);blockers.set(blockerKey,IDLE_BLOCKER),updateState({blockers})}});return}return startNavigation(historyAction,location2)}),isBrowser2){restoreAppliedTransitions(routerWindow,appliedViewTransitions);let _saveAppliedTransitions=__name(()=>persistAppliedTransitions(routerWindow,appliedViewTransitions),"_saveAppliedTransitions");routerWindow.addEventListener("pagehide",_saveAppliedTransitions),removePageHideEventListener=__name(()=>routerWindow.removeEventListener("pagehide",_saveAppliedTransitions),"removePageHideEventListener")}return state.initialized||startNavigation(Action.Pop,state.location,{initialHydration:!0}),router2}__name(initialize,"initialize");function dispose(){unlistenHistory&&unlistenHistory(),removePageHideEventListener&&removePageHideEventListener(),subscribers.clear(),pendingNavigationController&&pendingNavigationController.abort(),state.fetchers.forEach((_2,key)=>deleteFetcher(key)),state.blockers.forEach((_2,key)=>deleteBlocker(key))}__name(dispose,"dispose");function subscribe2(fn2){return subscribers.add(fn2),()=>subscribers.delete(fn2)}__name(subscribe2,"subscribe");function updateState(newState,opts){opts===void 0&&(opts={}),state=_extends$x({},state,newState);let completedFetchers=[],deletedFetchersKeys=[];future.v7_fetcherPersist&&state.fetchers.forEach((fetcher,key)=>{fetcher.state==="idle"&&(deletedFetchers.has(key)?deletedFetchersKeys.push(key):completedFetchers.push(key))}),deletedFetchers.forEach(key=>{!state.fetchers.has(key)&&!fetchControllers.has(key)&&deletedFetchersKeys.push(key)}),[...subscribers].forEach(subscriber=>subscriber(state,{deletedFetchers:deletedFetchersKeys,viewTransitionOpts:opts.viewTransitionOpts,flushSync:opts.flushSync===!0})),future.v7_fetcherPersist?(completedFetchers.forEach(key=>state.fetchers.delete(key)),deletedFetchersKeys.forEach(key=>deleteFetcher(key))):deletedFetchersKeys.forEach(key=>deletedFetchers.delete(key))}__name(updateState,"updateState");function completeNavigation(location2,newState,_temp){var _location$state,_location$state2;let{flushSync}=_temp===void 0?{}:_temp,isActionReload=state.actionData!=null&&state.navigation.formMethod!=null&&isMutationMethod(state.navigation.formMethod)&&state.navigation.state==="loading"&&((_location$state=location2.state)==null?void 0:_location$state._isRedirect)!==!0,actionData;newState.actionData?Object.keys(newState.actionData).length>0?actionData=newState.actionData:actionData=null:isActionReload?actionData=state.actionData:actionData=null;let loaderData=newState.loaderData?mergeLoaderData(state.loaderData,newState.loaderData,newState.matches||[],newState.errors):state.loaderData,blockers=state.blockers;blockers.size>0&&(blockers=new Map(blockers),blockers.forEach((_2,k2)=>blockers.set(k2,IDLE_BLOCKER)));let preventScrollReset=pendingPreventScrollReset===!0||state.navigation.formMethod!=null&&isMutationMethod(state.navigation.formMethod)&&((_location$state2=location2.state)==null?void 0:_location$state2._isRedirect)!==!0;inFlightDataRoutes&&(dataRoutes=inFlightDataRoutes,inFlightDataRoutes=void 0),isUninterruptedRevalidation||pendingAction===Action.Pop||(pendingAction===Action.Push?init.history.push(location2,location2.state):pendingAction===Action.Replace&&init.history.replace(location2,location2.state));let viewTransitionOpts;if(pendingAction===Action.Pop){let priorPaths=appliedViewTransitions.get(state.location.pathname);priorPaths&&priorPaths.has(location2.pathname)?viewTransitionOpts={currentLocation:state.location,nextLocation:location2}:appliedViewTransitions.has(location2.pathname)&&(viewTransitionOpts={currentLocation:location2,nextLocation:state.location})}else if(pendingViewTransitionEnabled){let toPaths=appliedViewTransitions.get(state.location.pathname);toPaths?toPaths.add(location2.pathname):(toPaths=new Set([location2.pathname]),appliedViewTransitions.set(state.location.pathname,toPaths)),viewTransitionOpts={currentLocation:state.location,nextLocation:location2}}updateState(_extends$x({},newState,{actionData,loaderData,historyAction:pendingAction,location:location2,initialized:!0,navigation:IDLE_NAVIGATION,revalidation:"idle",restoreScrollPosition:getSavedScrollPosition(location2,newState.matches||state.matches),preventScrollReset,blockers}),{viewTransitionOpts,flushSync:flushSync===!0}),pendingAction=Action.Pop,pendingPreventScrollReset=!1,pendingViewTransitionEnabled=!1,isUninterruptedRevalidation=!1,isRevalidationRequired=!1,cancelledDeferredRoutes=[]}__name(completeNavigation,"completeNavigation");async function navigate(to2,opts){if(typeof to2=="number"){init.history.go(to2);return}let normalizedPath=normalizeTo(state.location,state.matches,basename2,future.v7_prependBasename,to2,future.v7_relativeSplatPath,opts?.fromRouteId,opts?.relative),{path:path2,submission,error}=normalizeNavigateOptions(future.v7_normalizeFormMethod,!1,normalizedPath,opts),currentLocation=state.location,nextLocation=createLocation$1(state.location,path2,opts&&opts.state);nextLocation=_extends$x({},nextLocation,init.history.encodeLocation(nextLocation));let userReplace=opts&&opts.replace!=null?opts.replace:void 0,historyAction=Action.Push;userReplace===!0?historyAction=Action.Replace:userReplace===!1||submission!=null&&isMutationMethod(submission.formMethod)&&submission.formAction===state.location.pathname+state.location.search&&(historyAction=Action.Replace);let preventScrollReset=opts&&"preventScrollReset"in opts?opts.preventScrollReset===!0:void 0,flushSync=(opts&&opts.flushSync)===!0,blockerKey=shouldBlockNavigation({currentLocation,nextLocation,historyAction});if(blockerKey){updateBlocker(blockerKey,{state:"blocked",location:nextLocation,proceed(){updateBlocker(blockerKey,{state:"proceeding",proceed:void 0,reset:void 0,location:nextLocation}),navigate(to2,opts)},reset(){let blockers=new Map(state.blockers);blockers.set(blockerKey,IDLE_BLOCKER),updateState({blockers})}});return}return await startNavigation(historyAction,nextLocation,{submission,pendingError:error,preventScrollReset,replace:opts&&opts.replace,enableViewTransition:opts&&opts.viewTransition,flushSync})}__name(navigate,"navigate");function revalidate(){if(interruptActiveLoads(),updateState({revalidation:"loading"}),state.navigation.state!=="submitting"){if(state.navigation.state==="idle"){startNavigation(state.historyAction,state.location,{startUninterruptedRevalidation:!0});return}startNavigation(pendingAction||state.historyAction,state.navigation.location,{overrideNavigation:state.navigation,enableViewTransition:pendingViewTransitionEnabled===!0})}}__name(revalidate,"revalidate");async function startNavigation(historyAction,location2,opts){pendingNavigationController&&pendingNavigationController.abort(),pendingNavigationController=null,pendingAction=historyAction,isUninterruptedRevalidation=(opts&&opts.startUninterruptedRevalidation)===!0,saveScrollPosition(state.location,state.matches),pendingPreventScrollReset=(opts&&opts.preventScrollReset)===!0,pendingViewTransitionEnabled=(opts&&opts.enableViewTransition)===!0;let routesToUse=inFlightDataRoutes||dataRoutes,loadingNavigation=opts&&opts.overrideNavigation,matches=opts!=null&&opts.initialHydration&&state.matches&&state.matches.length>0&&!initialMatchesIsFOW?state.matches:matchRoutes(routesToUse,location2,basename2),flushSync=(opts&&opts.flushSync)===!0;if(matches&&state.initialized&&!isRevalidationRequired&&isHashChangeOnly(state.location,location2)&&!(opts&&opts.submission&&isMutationMethod(opts.submission.formMethod))){completeNavigation(location2,{matches},{flushSync});return}let fogOfWar=checkFogOfWar(matches,routesToUse,location2.pathname);if(fogOfWar.active&&fogOfWar.matches&&(matches=fogOfWar.matches),!matches){let{error,notFoundMatches,route}=handleNavigational404(location2.pathname);completeNavigation(location2,{matches:notFoundMatches,loaderData:{},errors:{[route.id]:error}},{flushSync});return}pendingNavigationController=new AbortController;let request=createClientSideRequest(init.history,location2,pendingNavigationController.signal,opts&&opts.submission),pendingActionResult;if(opts&&opts.pendingError)pendingActionResult=[findNearestBoundary(matches).route.id,{type:ResultType.error,error:opts.pendingError}];else if(opts&&opts.submission&&isMutationMethod(opts.submission.formMethod)){let actionResult=await handleAction(request,location2,opts.submission,matches,fogOfWar.active,{replace:opts.replace,flushSync});if(actionResult.shortCircuited)return;if(actionResult.pendingActionResult){let[routeId,result]=actionResult.pendingActionResult;if(isErrorResult(result)&&isRouteErrorResponse(result.error)&&result.error.status===404){pendingNavigationController=null,completeNavigation(location2,{matches:actionResult.matches,loaderData:{},errors:{[routeId]:result.error}});return}}matches=actionResult.matches||matches,pendingActionResult=actionResult.pendingActionResult,loadingNavigation=getLoadingNavigation(location2,opts.submission),flushSync=!1,fogOfWar.active=!1,request=createClientSideRequest(init.history,request.url,request.signal)}let{shortCircuited,matches:updatedMatches,loaderData,errors}=await handleLoaders(request,location2,matches,fogOfWar.active,loadingNavigation,opts&&opts.submission,opts&&opts.fetcherSubmission,opts&&opts.replace,opts&&opts.initialHydration===!0,flushSync,pendingActionResult);shortCircuited||(pendingNavigationController=null,completeNavigation(location2,_extends$x({matches:updatedMatches||matches},getActionDataForCommit(pendingActionResult),{loaderData,errors})))}__name(startNavigation,"startNavigation");async function handleAction(request,location2,submission,matches,isFogOfWar,opts){opts===void 0&&(opts={}),interruptActiveLoads();let navigation=getSubmittingNavigation(location2,submission);if(updateState({navigation},{flushSync:opts.flushSync===!0}),isFogOfWar){let discoverResult=await discoverRoutes(matches,location2.pathname,request.signal);if(discoverResult.type==="aborted")return{shortCircuited:!0};if(discoverResult.type==="error"){let boundaryId=findNearestBoundary(discoverResult.partialMatches).route.id;return{matches:discoverResult.partialMatches,pendingActionResult:[boundaryId,{type:ResultType.error,error:discoverResult.error}]}}else if(discoverResult.matches)matches=discoverResult.matches;else{let{notFoundMatches,error,route}=handleNavigational404(location2.pathname);return{matches:notFoundMatches,pendingActionResult:[route.id,{type:ResultType.error,error}]}}}let result,actionMatch=getTargetMatch(matches,location2);if(!actionMatch.route.action&&!actionMatch.route.lazy)result={type:ResultType.error,error:getInternalRouterError(405,{method:request.method,pathname:location2.pathname,routeId:actionMatch.route.id})};else if(result=(await callDataStrategy("action",state,request,[actionMatch],matches,null))[actionMatch.route.id],request.signal.aborted)return{shortCircuited:!0};if(isRedirectResult(result)){let replace2;return opts&&opts.replace!=null?replace2=opts.replace:replace2=normalizeRedirectLocation(result.response.headers.get("Location"),new URL(request.url),basename2,init.history)===state.location.pathname+state.location.search,await startRedirectNavigation(request,result,!0,{submission,replace:replace2}),{shortCircuited:!0}}if(isDeferredResult(result))throw getInternalRouterError(400,{type:"defer-action"});if(isErrorResult(result)){let boundaryMatch=findNearestBoundary(matches,actionMatch.route.id);return(opts&&opts.replace)!==!0&&(pendingAction=Action.Push),{matches,pendingActionResult:[boundaryMatch.route.id,result]}}return{matches,pendingActionResult:[actionMatch.route.id,result]}}__name(handleAction,"handleAction");async function handleLoaders(request,location2,matches,isFogOfWar,overrideNavigation,submission,fetcherSubmission,replace2,initialHydration,flushSync,pendingActionResult){let loadingNavigation=overrideNavigation||getLoadingNavigation(location2,submission),activeSubmission=submission||fetcherSubmission||getSubmissionFromNavigation(loadingNavigation),shouldUpdateNavigationState=!isUninterruptedRevalidation&&(!future.v7_partialHydration||!initialHydration);if(isFogOfWar){if(shouldUpdateNavigationState){let actionData=getUpdatedActionData(pendingActionResult);updateState(_extends$x({navigation:loadingNavigation},actionData!==void 0?{actionData}:{}),{flushSync})}let discoverResult=await discoverRoutes(matches,location2.pathname,request.signal);if(discoverResult.type==="aborted")return{shortCircuited:!0};if(discoverResult.type==="error"){let boundaryId=findNearestBoundary(discoverResult.partialMatches).route.id;return{matches:discoverResult.partialMatches,loaderData:{},errors:{[boundaryId]:discoverResult.error}}}else if(discoverResult.matches)matches=discoverResult.matches;else{let{error,notFoundMatches,route}=handleNavigational404(location2.pathname);return{matches:notFoundMatches,loaderData:{},errors:{[route.id]:error}}}}let routesToUse=inFlightDataRoutes||dataRoutes,[matchesToLoad,revalidatingFetchers]=getMatchesToLoad(init.history,state,matches,activeSubmission,location2,future.v7_partialHydration&&initialHydration===!0,future.v7_skipActionErrorRevalidation,isRevalidationRequired,cancelledDeferredRoutes,cancelledFetcherLoads,deletedFetchers,fetchLoadMatches,fetchRedirectIds,routesToUse,basename2,pendingActionResult);if(cancelActiveDeferreds(routeId=>!(matches&&matches.some(m2=>m2.route.id===routeId))||matchesToLoad&&matchesToLoad.some(m2=>m2.route.id===routeId)),pendingNavigationLoadId=++incrementingLoadId,matchesToLoad.length===0&&revalidatingFetchers.length===0){let updatedFetchers2=markFetchRedirectsDone();return completeNavigation(location2,_extends$x({matches,loaderData:{},errors:pendingActionResult&&isErrorResult(pendingActionResult[1])?{[pendingActionResult[0]]:pendingActionResult[1].error}:null},getActionDataForCommit(pendingActionResult),updatedFetchers2?{fetchers:new Map(state.fetchers)}:{}),{flushSync}),{shortCircuited:!0}}if(shouldUpdateNavigationState){let updates={};if(!isFogOfWar){updates.navigation=loadingNavigation;let actionData=getUpdatedActionData(pendingActionResult);actionData!==void 0&&(updates.actionData=actionData)}revalidatingFetchers.length>0&&(updates.fetchers=getUpdatedRevalidatingFetchers(revalidatingFetchers)),updateState(updates,{flushSync})}revalidatingFetchers.forEach(rf=>{abortFetcher(rf.key),rf.controller&&fetchControllers.set(rf.key,rf.controller)});let abortPendingFetchRevalidations=__name(()=>revalidatingFetchers.forEach(f2=>abortFetcher(f2.key)),"abortPendingFetchRevalidations");pendingNavigationController&&pendingNavigationController.signal.addEventListener("abort",abortPendingFetchRevalidations);let{loaderResults,fetcherResults}=await callLoadersAndMaybeResolveData(state,matches,matchesToLoad,revalidatingFetchers,request);if(request.signal.aborted)return{shortCircuited:!0};pendingNavigationController&&pendingNavigationController.signal.removeEventListener("abort",abortPendingFetchRevalidations),revalidatingFetchers.forEach(rf=>fetchControllers.delete(rf.key));let redirect3=findRedirect(loaderResults);if(redirect3)return await startRedirectNavigation(request,redirect3.result,!0,{replace:replace2}),{shortCircuited:!0};if(redirect3=findRedirect(fetcherResults),redirect3)return fetchRedirectIds.add(redirect3.key),await startRedirectNavigation(request,redirect3.result,!0,{replace:replace2}),{shortCircuited:!0};let{loaderData,errors}=processLoaderData(state,matches,loaderResults,pendingActionResult,revalidatingFetchers,fetcherResults,activeDeferreds);activeDeferreds.forEach((deferredData,routeId)=>{deferredData.subscribe(aborted=>{(aborted||deferredData.done)&&activeDeferreds.delete(routeId)})}),future.v7_partialHydration&&initialHydration&&state.errors&&(errors=_extends$x({},state.errors,errors));let updatedFetchers=markFetchRedirectsDone(),didAbortFetchLoads=abortStaleFetchLoads(pendingNavigationLoadId),shouldUpdateFetchers=updatedFetchers||didAbortFetchLoads||revalidatingFetchers.length>0;return _extends$x({matches,loaderData,errors},shouldUpdateFetchers?{fetchers:new Map(state.fetchers)}:{})}__name(handleLoaders,"handleLoaders");function getUpdatedActionData(pendingActionResult){if(pendingActionResult&&!isErrorResult(pendingActionResult[1]))return{[pendingActionResult[0]]:pendingActionResult[1].data};if(state.actionData)return Object.keys(state.actionData).length===0?null:state.actionData}__name(getUpdatedActionData,"getUpdatedActionData");function getUpdatedRevalidatingFetchers(revalidatingFetchers){return revalidatingFetchers.forEach(rf=>{let fetcher=state.fetchers.get(rf.key),revalidatingFetcher=getLoadingFetcher(void 0,fetcher?fetcher.data:void 0);state.fetchers.set(rf.key,revalidatingFetcher)}),new Map(state.fetchers)}__name(getUpdatedRevalidatingFetchers,"getUpdatedRevalidatingFetchers");function fetch2(key,routeId,href,opts){if(isServer)throw new Error("router.fetch() was called during the server render, but it shouldn't be. You are likely calling a useFetcher() method in the body of your component. Try moving it to a useEffect or a callback.");abortFetcher(key);let flushSync=(opts&&opts.flushSync)===!0,routesToUse=inFlightDataRoutes||dataRoutes,normalizedPath=normalizeTo(state.location,state.matches,basename2,future.v7_prependBasename,href,future.v7_relativeSplatPath,routeId,opts?.relative),matches=matchRoutes(routesToUse,normalizedPath,basename2),fogOfWar=checkFogOfWar(matches,routesToUse,normalizedPath);if(fogOfWar.active&&fogOfWar.matches&&(matches=fogOfWar.matches),!matches){setFetcherError(key,routeId,getInternalRouterError(404,{pathname:normalizedPath}),{flushSync});return}let{path:path2,submission,error}=normalizeNavigateOptions(future.v7_normalizeFormMethod,!0,normalizedPath,opts);if(error){setFetcherError(key,routeId,error,{flushSync});return}let match=getTargetMatch(matches,path2),preventScrollReset=(opts&&opts.preventScrollReset)===!0;if(submission&&isMutationMethod(submission.formMethod)){handleFetcherAction(key,routeId,path2,match,matches,fogOfWar.active,flushSync,preventScrollReset,submission);return}fetchLoadMatches.set(key,{routeId,path:path2}),handleFetcherLoader(key,routeId,path2,match,matches,fogOfWar.active,flushSync,preventScrollReset,submission)}__name(fetch2,"fetch");async function handleFetcherAction(key,routeId,path2,match,requestMatches,isFogOfWar,flushSync,preventScrollReset,submission){interruptActiveLoads(),fetchLoadMatches.delete(key);function detectAndHandle405Error(m2){if(!m2.route.action&&!m2.route.lazy){let error=getInternalRouterError(405,{method:submission.formMethod,pathname:path2,routeId});return setFetcherError(key,routeId,error,{flushSync}),!0}return!1}if(__name(detectAndHandle405Error,"detectAndHandle405Error"),!isFogOfWar&&detectAndHandle405Error(match))return;let existingFetcher=state.fetchers.get(key);updateFetcherState(key,getSubmittingFetcher(submission,existingFetcher),{flushSync});let abortController=new AbortController,fetchRequest=createClientSideRequest(init.history,path2,abortController.signal,submission);if(isFogOfWar){let discoverResult=await discoverRoutes(requestMatches,new URL(fetchRequest.url).pathname,fetchRequest.signal,key);if(discoverResult.type==="aborted")return;if(discoverResult.type==="error"){setFetcherError(key,routeId,discoverResult.error,{flushSync});return}else if(discoverResult.matches){if(requestMatches=discoverResult.matches,match=getTargetMatch(requestMatches,path2),detectAndHandle405Error(match))return}else{setFetcherError(key,routeId,getInternalRouterError(404,{pathname:path2}),{flushSync});return}}fetchControllers.set(key,abortController);let originatingLoadId=incrementingLoadId,actionResult=(await callDataStrategy("action",state,fetchRequest,[match],requestMatches,key))[match.route.id];if(fetchRequest.signal.aborted){fetchControllers.get(key)===abortController&&fetchControllers.delete(key);return}if(future.v7_fetcherPersist&&deletedFetchers.has(key)){if(isRedirectResult(actionResult)||isErrorResult(actionResult)){updateFetcherState(key,getDoneFetcher(void 0));return}}else{if(isRedirectResult(actionResult))if(fetchControllers.delete(key),pendingNavigationLoadId>originatingLoadId){updateFetcherState(key,getDoneFetcher(void 0));return}else return fetchRedirectIds.add(key),updateFetcherState(key,getLoadingFetcher(submission)),startRedirectNavigation(fetchRequest,actionResult,!1,{fetcherSubmission:submission,preventScrollReset});if(isErrorResult(actionResult)){setFetcherError(key,routeId,actionResult.error);return}}if(isDeferredResult(actionResult))throw getInternalRouterError(400,{type:"defer-action"});let nextLocation=state.navigation.location||state.location,revalidationRequest=createClientSideRequest(init.history,nextLocation,abortController.signal),routesToUse=inFlightDataRoutes||dataRoutes,matches=state.navigation.state!=="idle"?matchRoutes(routesToUse,state.navigation.location,basename2):state.matches;invariant$1(matches,"Didn't find any matches after fetcher action");let loadId=++incrementingLoadId;fetchReloadIds.set(key,loadId);let loadFetcher=getLoadingFetcher(submission,actionResult.data);state.fetchers.set(key,loadFetcher);let[matchesToLoad,revalidatingFetchers]=getMatchesToLoad(init.history,state,matches,submission,nextLocation,!1,future.v7_skipActionErrorRevalidation,isRevalidationRequired,cancelledDeferredRoutes,cancelledFetcherLoads,deletedFetchers,fetchLoadMatches,fetchRedirectIds,routesToUse,basename2,[match.route.id,actionResult]);revalidatingFetchers.filter(rf=>rf.key!==key).forEach(rf=>{let staleKey=rf.key,existingFetcher2=state.fetchers.get(staleKey),revalidatingFetcher=getLoadingFetcher(void 0,existingFetcher2?existingFetcher2.data:void 0);state.fetchers.set(staleKey,revalidatingFetcher),abortFetcher(staleKey),rf.controller&&fetchControllers.set(staleKey,rf.controller)}),updateState({fetchers:new Map(state.fetchers)});let abortPendingFetchRevalidations=__name(()=>revalidatingFetchers.forEach(rf=>abortFetcher(rf.key)),"abortPendingFetchRevalidations");abortController.signal.addEventListener("abort",abortPendingFetchRevalidations);let{loaderResults,fetcherResults}=await callLoadersAndMaybeResolveData(state,matches,matchesToLoad,revalidatingFetchers,revalidationRequest);if(abortController.signal.aborted)return;abortController.signal.removeEventListener("abort",abortPendingFetchRevalidations),fetchReloadIds.delete(key),fetchControllers.delete(key),revalidatingFetchers.forEach(r2=>fetchControllers.delete(r2.key));let redirect3=findRedirect(loaderResults);if(redirect3)return startRedirectNavigation(revalidationRequest,redirect3.result,!1,{preventScrollReset});if(redirect3=findRedirect(fetcherResults),redirect3)return fetchRedirectIds.add(redirect3.key),startRedirectNavigation(revalidationRequest,redirect3.result,!1,{preventScrollReset});let{loaderData,errors}=processLoaderData(state,matches,loaderResults,void 0,revalidatingFetchers,fetcherResults,activeDeferreds);if(state.fetchers.has(key)){let doneFetcher=getDoneFetcher(actionResult.data);state.fetchers.set(key,doneFetcher)}abortStaleFetchLoads(loadId),state.navigation.state==="loading"&&loadId>pendingNavigationLoadId?(invariant$1(pendingAction,"Expected pending action"),pendingNavigationController&&pendingNavigationController.abort(),completeNavigation(state.navigation.location,{matches,loaderData,errors,fetchers:new Map(state.fetchers)})):(updateState({errors,loaderData:mergeLoaderData(state.loaderData,loaderData,matches,errors),fetchers:new Map(state.fetchers)}),isRevalidationRequired=!1)}__name(handleFetcherAction,"handleFetcherAction");async function handleFetcherLoader(key,routeId,path2,match,matches,isFogOfWar,flushSync,preventScrollReset,submission){let existingFetcher=state.fetchers.get(key);updateFetcherState(key,getLoadingFetcher(submission,existingFetcher?existingFetcher.data:void 0),{flushSync});let abortController=new AbortController,fetchRequest=createClientSideRequest(init.history,path2,abortController.signal);if(isFogOfWar){let discoverResult=await discoverRoutes(matches,new URL(fetchRequest.url).pathname,fetchRequest.signal,key);if(discoverResult.type==="aborted")return;if(discoverResult.type==="error"){setFetcherError(key,routeId,discoverResult.error,{flushSync});return}else if(discoverResult.matches)matches=discoverResult.matches,match=getTargetMatch(matches,path2);else{setFetcherError(key,routeId,getInternalRouterError(404,{pathname:path2}),{flushSync});return}}fetchControllers.set(key,abortController);let originatingLoadId=incrementingLoadId,result=(await callDataStrategy("loader",state,fetchRequest,[match],matches,key))[match.route.id];if(isDeferredResult(result)&&(result=await resolveDeferredData(result,fetchRequest.signal,!0)||result),fetchControllers.get(key)===abortController&&fetchControllers.delete(key),!fetchRequest.signal.aborted){if(deletedFetchers.has(key)){updateFetcherState(key,getDoneFetcher(void 0));return}if(isRedirectResult(result))if(pendingNavigationLoadId>originatingLoadId){updateFetcherState(key,getDoneFetcher(void 0));return}else{fetchRedirectIds.add(key),await startRedirectNavigation(fetchRequest,result,!1,{preventScrollReset});return}if(isErrorResult(result)){setFetcherError(key,routeId,result.error);return}invariant$1(!isDeferredResult(result),"Unhandled fetcher deferred data"),updateFetcherState(key,getDoneFetcher(result.data))}}__name(handleFetcherLoader,"handleFetcherLoader");async function startRedirectNavigation(request,redirect3,isNavigation,_temp2){let{submission,fetcherSubmission,preventScrollReset,replace:replace2}=_temp2===void 0?{}:_temp2;redirect3.response.headers.has("X-Remix-Revalidate")&&(isRevalidationRequired=!0);let location2=redirect3.response.headers.get("Location");invariant$1(location2,"Expected a Location header on the redirect Response"),location2=normalizeRedirectLocation(location2,new URL(request.url),basename2,init.history);let redirectLocation=createLocation$1(state.location,location2,{_isRedirect:!0});if(isBrowser2){let isDocumentReload=!1;if(redirect3.response.headers.has("X-Remix-Reload-Document"))isDocumentReload=!0;else if(ABSOLUTE_URL_REGEX$2.test(location2)){const url=init.history.createURL(location2);isDocumentReload=url.origin!==routerWindow.location.origin||stripBasename(url.pathname,basename2)==null}if(isDocumentReload){replace2?routerWindow.location.replace(location2):routerWindow.location.assign(location2);return}}pendingNavigationController=null;let redirectHistoryAction=replace2===!0||redirect3.response.headers.has("X-Remix-Replace")?Action.Replace:Action.Push,{formMethod,formAction,formEncType}=state.navigation;!submission&&!fetcherSubmission&&formMethod&&formAction&&formEncType&&(submission=getSubmissionFromNavigation(state.navigation));let activeSubmission=submission||fetcherSubmission;if(redirectPreserveMethodStatusCodes.has(redirect3.response.status)&&activeSubmission&&isMutationMethod(activeSubmission.formMethod))await startNavigation(redirectHistoryAction,redirectLocation,{submission:_extends$x({},activeSubmission,{formAction:location2}),preventScrollReset:preventScrollReset||pendingPreventScrollReset,enableViewTransition:isNavigation?pendingViewTransitionEnabled:void 0});else{let overrideNavigation=getLoadingNavigation(redirectLocation,submission);await startNavigation(redirectHistoryAction,redirectLocation,{overrideNavigation,fetcherSubmission,preventScrollReset:preventScrollReset||pendingPreventScrollReset,enableViewTransition:isNavigation?pendingViewTransitionEnabled:void 0})}}__name(startRedirectNavigation,"startRedirectNavigation");async function callDataStrategy(type,state2,request,matchesToLoad,matches,fetcherKey){let results,dataResults={};try{results=await callDataStrategyImpl(dataStrategyImpl,type,state2,request,matchesToLoad,matches,fetcherKey,manifest,mapRouteProperties2)}catch(e3){return matchesToLoad.forEach(m2=>{dataResults[m2.route.id]={type:ResultType.error,error:e3}}),dataResults}for(let[routeId,result]of Object.entries(results))if(isRedirectDataStrategyResultResult(result)){let response=result.result;dataResults[routeId]={type:ResultType.redirect,response:normalizeRelativeRoutingRedirectResponse(response,request,routeId,matches,basename2,future.v7_relativeSplatPath)}}else dataResults[routeId]=await convertDataStrategyResultToDataResult(result);return dataResults}__name(callDataStrategy,"callDataStrategy");async function callLoadersAndMaybeResolveData(state2,matches,matchesToLoad,fetchersToLoad,request){let currentMatches=state2.matches,loaderResultsPromise=callDataStrategy("loader",state2,request,matchesToLoad,matches,null),fetcherResultsPromise=Promise.all(fetchersToLoad.map(async f2=>{if(f2.matches&&f2.match&&f2.controller){let result=(await callDataStrategy("loader",state2,createClientSideRequest(init.history,f2.path,f2.controller.signal),[f2.match],f2.matches,f2.key))[f2.match.route.id];return{[f2.key]:result}}else return Promise.resolve({[f2.key]:{type:ResultType.error,error:getInternalRouterError(404,{pathname:f2.path})}})})),loaderResults=await loaderResultsPromise,fetcherResults=(await fetcherResultsPromise).reduce((acc,r2)=>Object.assign(acc,r2),{});return await Promise.all([resolveNavigationDeferredResults(matches,loaderResults,request.signal,currentMatches,state2.loaderData),resolveFetcherDeferredResults(matches,fetcherResults,fetchersToLoad)]),{loaderResults,fetcherResults}}__name(callLoadersAndMaybeResolveData,"callLoadersAndMaybeResolveData");function interruptActiveLoads(){isRevalidationRequired=!0,cancelledDeferredRoutes.push(...cancelActiveDeferreds()),fetchLoadMatches.forEach((_2,key)=>{fetchControllers.has(key)&&cancelledFetcherLoads.add(key),abortFetcher(key)})}__name(interruptActiveLoads,"interruptActiveLoads");function updateFetcherState(key,fetcher,opts){opts===void 0&&(opts={}),state.fetchers.set(key,fetcher),updateState({fetchers:new Map(state.fetchers)},{flushSync:(opts&&opts.flushSync)===!0})}__name(updateFetcherState,"updateFetcherState");function setFetcherError(key,routeId,error,opts){opts===void 0&&(opts={});let boundaryMatch=findNearestBoundary(state.matches,routeId);deleteFetcher(key),updateState({errors:{[boundaryMatch.route.id]:error},fetchers:new Map(state.fetchers)},{flushSync:(opts&&opts.flushSync)===!0})}__name(setFetcherError,"setFetcherError");function getFetcher(key){return activeFetchers.set(key,(activeFetchers.get(key)||0)+1),deletedFetchers.has(key)&&deletedFetchers.delete(key),state.fetchers.get(key)||IDLE_FETCHER}__name(getFetcher,"getFetcher");function deleteFetcher(key){let fetcher=state.fetchers.get(key);fetchControllers.has(key)&&!(fetcher&&fetcher.state==="loading"&&fetchReloadIds.has(key))&&abortFetcher(key),fetchLoadMatches.delete(key),fetchReloadIds.delete(key),fetchRedirectIds.delete(key),future.v7_fetcherPersist&&deletedFetchers.delete(key),cancelledFetcherLoads.delete(key),state.fetchers.delete(key)}__name(deleteFetcher,"deleteFetcher");function deleteFetcherAndUpdateState(key){let count2=(activeFetchers.get(key)||0)-1;count2<=0?(activeFetchers.delete(key),deletedFetchers.add(key),future.v7_fetcherPersist||deleteFetcher(key)):activeFetchers.set(key,count2),updateState({fetchers:new Map(state.fetchers)})}__name(deleteFetcherAndUpdateState,"deleteFetcherAndUpdateState");function abortFetcher(key){let controller=fetchControllers.get(key);controller&&(controller.abort(),fetchControllers.delete(key))}__name(abortFetcher,"abortFetcher");function markFetchersDone(keys2){for(let key of keys2){let fetcher=getFetcher(key),doneFetcher=getDoneFetcher(fetcher.data);state.fetchers.set(key,doneFetcher)}}__name(markFetchersDone,"markFetchersDone");function markFetchRedirectsDone(){let doneKeys=[],updatedFetchers=!1;for(let key of fetchRedirectIds){let fetcher=state.fetchers.get(key);invariant$1(fetcher,"Expected fetcher: "+key),fetcher.state==="loading"&&(fetchRedirectIds.delete(key),doneKeys.push(key),updatedFetchers=!0)}return markFetchersDone(doneKeys),updatedFetchers}__name(markFetchRedirectsDone,"markFetchRedirectsDone");function abortStaleFetchLoads(landedId){let yeetedKeys=[];for(let[key,id]of fetchReloadIds)if(id0}__name(abortStaleFetchLoads,"abortStaleFetchLoads");function getBlocker(key,fn2){let blocker=state.blockers.get(key)||IDLE_BLOCKER;return blockerFunctions.get(key)!==fn2&&blockerFunctions.set(key,fn2),blocker}__name(getBlocker,"getBlocker");function deleteBlocker(key){state.blockers.delete(key),blockerFunctions.delete(key)}__name(deleteBlocker,"deleteBlocker");function updateBlocker(key,newBlocker){let blocker=state.blockers.get(key)||IDLE_BLOCKER;invariant$1(blocker.state==="unblocked"&&newBlocker.state==="blocked"||blocker.state==="blocked"&&newBlocker.state==="blocked"||blocker.state==="blocked"&&newBlocker.state==="proceeding"||blocker.state==="blocked"&&newBlocker.state==="unblocked"||blocker.state==="proceeding"&&newBlocker.state==="unblocked","Invalid blocker state transition: "+blocker.state+" -> "+newBlocker.state);let blockers=new Map(state.blockers);blockers.set(key,newBlocker),updateState({blockers})}__name(updateBlocker,"updateBlocker");function shouldBlockNavigation(_ref2){let{currentLocation,nextLocation,historyAction}=_ref2;if(blockerFunctions.size===0)return;blockerFunctions.size>1&&warning(!1,"A router only supports one blocker at a time");let entries=Array.from(blockerFunctions.entries()),[blockerKey,blockerFunction]=entries[entries.length-1],blocker=state.blockers.get(blockerKey);if(!(blocker&&blocker.state==="proceeding")&&blockerFunction({currentLocation,nextLocation,historyAction}))return blockerKey}__name(shouldBlockNavigation,"shouldBlockNavigation");function handleNavigational404(pathname){let error=getInternalRouterError(404,{pathname}),routesToUse=inFlightDataRoutes||dataRoutes,{matches,route}=getShortCircuitMatches(routesToUse);return cancelActiveDeferreds(),{notFoundMatches:matches,route,error}}__name(handleNavigational404,"handleNavigational404");function cancelActiveDeferreds(predicate){let cancelledRouteIds=[];return activeDeferreds.forEach((dfd,routeId)=>{(!predicate||predicate(routeId))&&(dfd.cancel(),cancelledRouteIds.push(routeId),activeDeferreds.delete(routeId))}),cancelledRouteIds}__name(cancelActiveDeferreds,"cancelActiveDeferreds");function enableScrollRestoration(positions,getPosition,getKey){if(savedScrollPositions=positions,getScrollPosition=getPosition,getScrollRestorationKey=getKey||null,!initialScrollRestored&&state.navigation===IDLE_NAVIGATION){initialScrollRestored=!0;let y2=getSavedScrollPosition(state.location,state.matches);y2!=null&&updateState({restoreScrollPosition:y2})}return()=>{savedScrollPositions=null,getScrollPosition=null,getScrollRestorationKey=null}}__name(enableScrollRestoration,"enableScrollRestoration");function getScrollKey(location2,matches){return getScrollRestorationKey&&getScrollRestorationKey(location2,matches.map(m2=>convertRouteMatchToUiMatch(m2,state.loaderData)))||location2.key}__name(getScrollKey,"getScrollKey");function saveScrollPosition(location2,matches){if(savedScrollPositions&&getScrollPosition){let key=getScrollKey(location2,matches);savedScrollPositions[key]=getScrollPosition()}}__name(saveScrollPosition,"saveScrollPosition");function getSavedScrollPosition(location2,matches){if(savedScrollPositions){let key=getScrollKey(location2,matches),y2=savedScrollPositions[key];if(typeof y2=="number")return y2}return null}__name(getSavedScrollPosition,"getSavedScrollPosition");function checkFogOfWar(matches,routesToUse,pathname){if(patchRoutesOnNavigationImpl)if(matches){if(Object.keys(matches[0].params).length>0)return{active:!0,matches:matchRoutesImpl(routesToUse,pathname,basename2,!0)}}else return{active:!0,matches:matchRoutesImpl(routesToUse,pathname,basename2,!0)||[]};return{active:!1,matches:null}}__name(checkFogOfWar,"checkFogOfWar");async function discoverRoutes(matches,pathname,signal,fetcherKey){if(!patchRoutesOnNavigationImpl)return{type:"success",matches};let partialMatches=matches;for(;;){let isNonHMR=inFlightDataRoutes==null,routesToUse=inFlightDataRoutes||dataRoutes,localManifest=manifest;try{await patchRoutesOnNavigationImpl({signal,path:pathname,matches:partialMatches,fetcherKey,patch:__name((routeId,children2)=>{signal.aborted||patchRoutesImpl(routeId,children2,routesToUse,localManifest,mapRouteProperties2)},"patch")})}catch(e3){return{type:"error",error:e3,partialMatches}}finally{isNonHMR&&!signal.aborted&&(dataRoutes=[...dataRoutes])}if(signal.aborted)return{type:"aborted"};let newMatches=matchRoutes(routesToUse,pathname,basename2);if(newMatches)return{type:"success",matches:newMatches};let newPartialMatches=matchRoutesImpl(routesToUse,pathname,basename2,!0);if(!newPartialMatches||partialMatches.length===newPartialMatches.length&&partialMatches.every((m2,i2)=>m2.route.id===newPartialMatches[i2].route.id))return{type:"success",matches:null};partialMatches=newPartialMatches}}__name(discoverRoutes,"discoverRoutes");function _internalSetRoutes(newRoutes){manifest={},inFlightDataRoutes=convertRoutesToDataRoutes(newRoutes,mapRouteProperties2,void 0,manifest)}__name(_internalSetRoutes,"_internalSetRoutes");function patchRoutes(routeId,children2){let isNonHMR=inFlightDataRoutes==null;patchRoutesImpl(routeId,children2,inFlightDataRoutes||dataRoutes,manifest,mapRouteProperties2),isNonHMR&&(dataRoutes=[...dataRoutes],updateState({}))}return __name(patchRoutes,"patchRoutes"),router2={get basename(){return basename2},get future(){return future},get state(){return state},get routes(){return dataRoutes},get window(){return routerWindow},initialize,subscribe:subscribe2,enableScrollRestoration,navigate,fetch:fetch2,revalidate,createHref:__name(to2=>init.history.createHref(to2),"createHref"),encodeLocation:__name(to2=>init.history.encodeLocation(to2),"encodeLocation"),getFetcher,deleteFetcher:deleteFetcherAndUpdateState,dispose,getBlocker,deleteBlocker,patchRoutes,_internalFetchControllers:fetchControllers,_internalActiveDeferreds:activeDeferreds,_internalSetRoutes},router2}__name(createRouter,"createRouter");function isSubmissionNavigation(opts){return opts!=null&&("formData"in opts&&opts.formData!=null||"body"in opts&&opts.body!==void 0)}__name(isSubmissionNavigation,"isSubmissionNavigation");function normalizeTo(location2,matches,basename2,prependBasename,to2,v7_relativeSplatPath,fromRouteId,relative){let contextualMatches,activeRouteMatch;if(fromRouteId){contextualMatches=[];for(let match of matches)if(contextualMatches.push(match),match.route.id===fromRouteId){activeRouteMatch=match;break}}else contextualMatches=matches,activeRouteMatch=matches[matches.length-1];let path2=resolveTo(to2||".",getResolveToMatches(contextualMatches,v7_relativeSplatPath),stripBasename(location2.pathname,basename2)||location2.pathname,relative==="path");if(to2==null&&(path2.search=location2.search,path2.hash=location2.hash),(to2==null||to2===""||to2===".")&&activeRouteMatch){let nakedIndex=hasNakedIndexQuery(path2.search);if(activeRouteMatch.route.index&&!nakedIndex)path2.search=path2.search?path2.search.replace(/^\?/,"?index&"):"?index";else if(!activeRouteMatch.route.index&&nakedIndex){let params=new URLSearchParams(path2.search),indexValues=params.getAll("index");params.delete("index"),indexValues.filter(v2=>v2).forEach(v2=>params.append("index",v2));let qs=params.toString();path2.search=qs?"?"+qs:""}}return prependBasename&&basename2!=="/"&&(path2.pathname=path2.pathname==="/"?basename2:joinPaths([basename2,path2.pathname])),createPath(path2)}__name(normalizeTo,"normalizeTo");function normalizeNavigateOptions(normalizeFormMethod,isFetcher,path2,opts){if(!opts||!isSubmissionNavigation(opts))return{path:path2};if(opts.formMethod&&!isValidMethod(opts.formMethod))return{path:path2,error:getInternalRouterError(405,{method:opts.formMethod})};let getInvalidBodyError=__name(()=>({path:path2,error:getInternalRouterError(400,{type:"invalid-body"})}),"getInvalidBodyError"),rawFormMethod=opts.formMethod||"get",formMethod=normalizeFormMethod?rawFormMethod.toUpperCase():rawFormMethod.toLowerCase(),formAction=stripHashFromPath(path2);if(opts.body!==void 0){if(opts.formEncType==="text/plain"){if(!isMutationMethod(formMethod))return getInvalidBodyError();let text2=typeof opts.body=="string"?opts.body:opts.body instanceof FormData||opts.body instanceof URLSearchParams?Array.from(opts.body.entries()).reduce((acc,_ref3)=>{let[name2,value2]=_ref3;return""+acc+name2+"="+value2+` `},""):String(opts.body);return{path:path2,submission:{formMethod,formAction,formEncType:opts.formEncType,formData:void 0,json:void 0,text:text2}}}else if(opts.formEncType==="application/json"){if(!isMutationMethod(formMethod))return getInvalidBodyError();try{let json3=typeof opts.body=="string"?JSON.parse(opts.body):opts.body;return{path:path2,submission:{formMethod,formAction,formEncType:opts.formEncType,formData:void 0,json:json3,text:void 0}}}catch{return getInvalidBodyError()}}}invariant$1(typeof FormData=="function","FormData is not available in this environment");let searchParams,formData;if(opts.formData)searchParams=convertFormDataToSearchParams(opts.formData),formData=opts.formData;else if(opts.body instanceof FormData)searchParams=convertFormDataToSearchParams(opts.body),formData=opts.body;else if(opts.body instanceof URLSearchParams)searchParams=opts.body,formData=convertSearchParamsToFormData(searchParams);else if(opts.body==null)searchParams=new URLSearchParams,formData=new FormData;else try{searchParams=new URLSearchParams(opts.body),formData=convertSearchParamsToFormData(searchParams)}catch{return getInvalidBodyError()}let submission={formMethod,formAction,formEncType:opts&&opts.formEncType||"application/x-www-form-urlencoded",formData,json:void 0,text:void 0};if(isMutationMethod(submission.formMethod))return{path:path2,submission};let parsedPath=parsePath(path2);return isFetcher&&parsedPath.search&&hasNakedIndexQuery(parsedPath.search)&&searchParams.append("index",""),parsedPath.search="?"+searchParams,{path:createPath(parsedPath),submission}}__name(normalizeNavigateOptions,"normalizeNavigateOptions");function getLoaderMatchesUntilBoundary(matches,boundaryId,includeBoundary){includeBoundary===void 0&&(includeBoundary=!1);let index2=matches.findIndex(m2=>m2.route.id===boundaryId);return index2>=0?matches.slice(0,includeBoundary?index2+1:index2):matches}__name(getLoaderMatchesUntilBoundary,"getLoaderMatchesUntilBoundary");function getMatchesToLoad(history,state,matches,submission,location2,initialHydration,skipActionErrorRevalidation,isRevalidationRequired,cancelledDeferredRoutes,cancelledFetcherLoads,deletedFetchers,fetchLoadMatches,fetchRedirectIds,routesToUse,basename2,pendingActionResult){let actionResult=pendingActionResult?isErrorResult(pendingActionResult[1])?pendingActionResult[1].error:pendingActionResult[1].data:void 0,currentUrl=history.createURL(state.location),nextUrl=history.createURL(location2),boundaryMatches=matches;initialHydration&&state.errors?boundaryMatches=getLoaderMatchesUntilBoundary(matches,Object.keys(state.errors)[0],!0):pendingActionResult&&isErrorResult(pendingActionResult[1])&&(boundaryMatches=getLoaderMatchesUntilBoundary(matches,pendingActionResult[0]));let actionStatus=pendingActionResult?pendingActionResult[1].statusCode:void 0,shouldSkipRevalidation=skipActionErrorRevalidation&&actionStatus&&actionStatus>=400,navigationMatches=boundaryMatches.filter((match,index2)=>{let{route}=match;if(route.lazy)return!0;if(route.loader==null)return!1;if(initialHydration)return shouldLoadRouteOnHydration(route,state.loaderData,state.errors);if(isNewLoader(state.loaderData,state.matches[index2],match)||cancelledDeferredRoutes.some(id=>id===match.route.id))return!0;let currentRouteMatch=state.matches[index2],nextRouteMatch=match;return shouldRevalidateLoader(match,_extends$x({currentUrl,currentParams:currentRouteMatch.params,nextUrl,nextParams:nextRouteMatch.params},submission,{actionResult,actionStatus,defaultShouldRevalidate:shouldSkipRevalidation?!1:isRevalidationRequired||currentUrl.pathname+currentUrl.search===nextUrl.pathname+nextUrl.search||currentUrl.search!==nextUrl.search||isNewRouteInstance(currentRouteMatch,nextRouteMatch)}))}),revalidatingFetchers=[];return fetchLoadMatches.forEach((f2,key)=>{if(initialHydration||!matches.some(m2=>m2.route.id===f2.routeId)||deletedFetchers.has(key))return;let fetcherMatches=matchRoutes(routesToUse,f2.path,basename2);if(!fetcherMatches){revalidatingFetchers.push({key,routeId:f2.routeId,path:f2.path,matches:null,match:null,controller:null});return}let fetcher=state.fetchers.get(key),fetcherMatch=getTargetMatch(fetcherMatches,f2.path),shouldRevalidate=!1;fetchRedirectIds.has(key)?shouldRevalidate=!1:cancelledFetcherLoads.has(key)?(cancelledFetcherLoads.delete(key),shouldRevalidate=!0):fetcher&&fetcher.state!=="idle"&&fetcher.data===void 0?shouldRevalidate=isRevalidationRequired:shouldRevalidate=shouldRevalidateLoader(fetcherMatch,_extends$x({currentUrl,currentParams:state.matches[state.matches.length-1].params,nextUrl,nextParams:matches[matches.length-1].params},submission,{actionResult,actionStatus,defaultShouldRevalidate:shouldSkipRevalidation?!1:isRevalidationRequired})),shouldRevalidate&&revalidatingFetchers.push({key,routeId:f2.routeId,path:f2.path,matches:fetcherMatches,match:fetcherMatch,controller:new AbortController})}),[navigationMatches,revalidatingFetchers]}__name(getMatchesToLoad,"getMatchesToLoad");function shouldLoadRouteOnHydration(route,loaderData,errors){if(route.lazy)return!0;if(!route.loader)return!1;let hasData=loaderData!=null&&loaderData[route.id]!==void 0,hasError=errors!=null&&errors[route.id]!==void 0;return!hasData&&hasError?!1:typeof route.loader=="function"&&route.loader.hydrate===!0?!0:!hasData&&!hasError}__name(shouldLoadRouteOnHydration,"shouldLoadRouteOnHydration");function isNewLoader(currentLoaderData,currentMatch,match){let isNew=!currentMatch||match.route.id!==currentMatch.route.id,isMissingData=currentLoaderData[match.route.id]===void 0;return isNew||isMissingData}__name(isNewLoader,"isNewLoader");function isNewRouteInstance(currentMatch,match){let currentPath=currentMatch.route.path;return currentMatch.pathname!==match.pathname||currentPath!=null&¤tPath.endsWith("*")&¤tMatch.params["*"]!==match.params["*"]}__name(isNewRouteInstance,"isNewRouteInstance");function shouldRevalidateLoader(loaderMatch,arg){if(loaderMatch.route.shouldRevalidate){let routeChoice=loaderMatch.route.shouldRevalidate(arg);if(typeof routeChoice=="boolean")return routeChoice}return arg.defaultShouldRevalidate}__name(shouldRevalidateLoader,"shouldRevalidateLoader");function patchRoutesImpl(routeId,children2,routesToUse,manifest,mapRouteProperties2){var _childrenToPatch;let childrenToPatch;if(routeId){let route=manifest[routeId];invariant$1(route,"No route found to patch children into: routeId = "+routeId),route.children||(route.children=[]),childrenToPatch=route.children}else childrenToPatch=routesToUse;let uniqueChildren=children2.filter(newRoute=>!childrenToPatch.some(existingRoute=>isSameRoute(newRoute,existingRoute))),newRoutes=convertRoutesToDataRoutes(uniqueChildren,mapRouteProperties2,[routeId||"_","patch",String(((_childrenToPatch=childrenToPatch)==null?void 0:_childrenToPatch.length)||"0")],manifest);childrenToPatch.push(...newRoutes)}__name(patchRoutesImpl,"patchRoutesImpl");function isSameRoute(newRoute,existingRoute){return"id"in newRoute&&"id"in existingRoute&&newRoute.id===existingRoute.id?!0:newRoute.index===existingRoute.index&&newRoute.path===existingRoute.path&&newRoute.caseSensitive===existingRoute.caseSensitive?(!newRoute.children||newRoute.children.length===0)&&(!existingRoute.children||existingRoute.children.length===0)?!0:newRoute.children.every((aChild,i2)=>{var _existingRoute$childr;return(_existingRoute$childr=existingRoute.children)==null?void 0:_existingRoute$childr.some(bChild=>isSameRoute(aChild,bChild))}):!1}__name(isSameRoute,"isSameRoute");async function loadLazyRouteModule(route,mapRouteProperties2,manifest){if(!route.lazy)return;let lazyRoute=await route.lazy();if(!route.lazy)return;let routeToUpdate=manifest[route.id];invariant$1(routeToUpdate,"No route found in manifest");let routeUpdates={};for(let lazyRouteProperty in lazyRoute){let isPropertyStaticallyDefined=routeToUpdate[lazyRouteProperty]!==void 0&&lazyRouteProperty!=="hasErrorBoundary";warning(!isPropertyStaticallyDefined,'Route "'+routeToUpdate.id+'" has a static property "'+lazyRouteProperty+'" defined but its lazy function is also returning a value for this property. '+('The lazy route property "'+lazyRouteProperty+'" will be ignored.')),!isPropertyStaticallyDefined&&!immutableRouteKeys.has(lazyRouteProperty)&&(routeUpdates[lazyRouteProperty]=lazyRoute[lazyRouteProperty])}Object.assign(routeToUpdate,routeUpdates),Object.assign(routeToUpdate,_extends$x({},mapRouteProperties2(routeToUpdate),{lazy:void 0}))}__name(loadLazyRouteModule,"loadLazyRouteModule");async function defaultDataStrategy(_ref4){let{matches}=_ref4,matchesToLoad=matches.filter(m2=>m2.shouldLoad);return(await Promise.all(matchesToLoad.map(m2=>m2.resolve()))).reduce((acc,result,i2)=>Object.assign(acc,{[matchesToLoad[i2].route.id]:result}),{})}__name(defaultDataStrategy,"defaultDataStrategy");async function callDataStrategyImpl(dataStrategyImpl,type,state,request,matchesToLoad,matches,fetcherKey,manifest,mapRouteProperties2,requestContext){let loadRouteDefinitionsPromises=matches.map(m2=>m2.route.lazy?loadLazyRouteModule(m2.route,mapRouteProperties2,manifest):void 0),dsMatches=matches.map((match,i2)=>{let loadRoutePromise=loadRouteDefinitionsPromises[i2],shouldLoad=matchesToLoad.some(m2=>m2.route.id===match.route.id);return _extends$x({},match,{shouldLoad,resolve:__name(async handlerOverride=>(handlerOverride&&request.method==="GET"&&(match.route.lazy||match.route.loader)&&(shouldLoad=!0),shouldLoad?callLoaderOrAction(type,request,match,loadRoutePromise,handlerOverride,requestContext):Promise.resolve({type:ResultType.data,result:void 0})),"resolve")})}),results=await dataStrategyImpl({matches:dsMatches,request,params:matches[0].params,fetcherKey,context:requestContext});try{await Promise.all(loadRouteDefinitionsPromises)}catch{}return results}__name(callDataStrategyImpl,"callDataStrategyImpl");async function callLoaderOrAction(type,request,match,loadRoutePromise,handlerOverride,staticContext){let result,onReject,runHandler=__name(handler=>{let reject,abortPromise=new Promise((_2,r2)=>reject=r2);onReject=__name(()=>reject(),"onReject"),request.signal.addEventListener("abort",onReject);let actualHandler=__name(ctx2=>typeof handler!="function"?Promise.reject(new Error("You cannot call the handler for a route which defines a boolean "+('"'+type+'" [routeId: '+match.route.id+"]"))):handler({request,params:match.params,context:staticContext},...ctx2!==void 0?[ctx2]:[]),"actualHandler"),handlerPromise=(async()=>{try{return{type:"data",result:await(handlerOverride?handlerOverride(ctx2=>actualHandler(ctx2)):actualHandler())}}catch(e3){return{type:"error",result:e3}}})();return Promise.race([handlerPromise,abortPromise])},"runHandler");try{let handler=match.route[type];if(loadRoutePromise)if(handler){let handlerError,[value2]=await Promise.all([runHandler(handler).catch(e3=>{handlerError=e3}),loadRoutePromise]);if(handlerError!==void 0)throw handlerError;result=value2}else if(await loadRoutePromise,handler=match.route[type],handler)result=await runHandler(handler);else if(type==="action"){let url=new URL(request.url),pathname=url.pathname+url.search;throw getInternalRouterError(405,{method:request.method,pathname,routeId:match.route.id})}else return{type:ResultType.data,result:void 0};else if(handler)result=await runHandler(handler);else{let url=new URL(request.url),pathname=url.pathname+url.search;throw getInternalRouterError(404,{pathname})}invariant$1(result.result!==void 0,"You defined "+(type==="action"?"an action":"a loader")+" for route "+('"'+match.route.id+"\" but didn't return anything from your `"+type+"` ")+"function. Please return a value or `null`.")}catch(e3){return{type:ResultType.error,result:e3}}finally{onReject&&request.signal.removeEventListener("abort",onReject)}return result}__name(callLoaderOrAction,"callLoaderOrAction");async function convertDataStrategyResultToDataResult(dataStrategyResult){let{result,type}=dataStrategyResult;if(isResponse(result)){let data2;try{let contentType=result.headers.get("Content-Type");contentType&&/\bapplication\/json\b/.test(contentType)?result.body==null?data2=null:data2=await result.json():data2=await result.text()}catch(e3){return{type:ResultType.error,error:e3}}return type===ResultType.error?{type:ResultType.error,error:new ErrorResponseImpl(result.status,result.statusText,data2),statusCode:result.status,headers:result.headers}:{type:ResultType.data,data:data2,statusCode:result.status,headers:result.headers}}if(type===ResultType.error){if(isDataWithResponseInit(result)){var _result$init3,_result$init4;if(result.data instanceof Error){var _result$init,_result$init2;return{type:ResultType.error,error:result.data,statusCode:(_result$init=result.init)==null?void 0:_result$init.status,headers:(_result$init2=result.init)!=null&&_result$init2.headers?new Headers(result.init.headers):void 0}}return{type:ResultType.error,error:new ErrorResponseImpl(((_result$init3=result.init)==null?void 0:_result$init3.status)||500,void 0,result.data),statusCode:isRouteErrorResponse(result)?result.status:void 0,headers:(_result$init4=result.init)!=null&&_result$init4.headers?new Headers(result.init.headers):void 0}}return{type:ResultType.error,error:result,statusCode:isRouteErrorResponse(result)?result.status:void 0}}if(isDeferredData(result)){var _result$init5,_result$init6;return{type:ResultType.deferred,deferredData:result,statusCode:(_result$init5=result.init)==null?void 0:_result$init5.status,headers:((_result$init6=result.init)==null?void 0:_result$init6.headers)&&new Headers(result.init.headers)}}if(isDataWithResponseInit(result)){var _result$init7,_result$init8;return{type:ResultType.data,data:result.data,statusCode:(_result$init7=result.init)==null?void 0:_result$init7.status,headers:(_result$init8=result.init)!=null&&_result$init8.headers?new Headers(result.init.headers):void 0}}return{type:ResultType.data,data:result}}__name(convertDataStrategyResultToDataResult,"convertDataStrategyResultToDataResult");function normalizeRelativeRoutingRedirectResponse(response,request,routeId,matches,basename2,v7_relativeSplatPath){let location2=response.headers.get("Location");if(invariant$1(location2,"Redirects returned/thrown from loaders/actions must have a Location header"),!ABSOLUTE_URL_REGEX$2.test(location2)){let trimmedMatches=matches.slice(0,matches.findIndex(m2=>m2.route.id===routeId)+1);location2=normalizeTo(new URL(request.url),trimmedMatches,basename2,!0,location2,v7_relativeSplatPath),response.headers.set("Location",location2)}return response}__name(normalizeRelativeRoutingRedirectResponse,"normalizeRelativeRoutingRedirectResponse");function normalizeRedirectLocation(location2,currentUrl,basename2,historyInstance){let invalidProtocols=["about:","blob:","chrome:","chrome-untrusted:","content:","data:","devtools:","file:","filesystem:","javascript:"];if(ABSOLUTE_URL_REGEX$2.test(location2)){let normalizedLocation=location2,url=normalizedLocation.startsWith("//")?new URL(currentUrl.protocol+normalizedLocation):new URL(normalizedLocation);if(invalidProtocols.includes(url.protocol))throw new Error("Invalid redirect location");let isSameBasename=stripBasename(url.pathname,basename2)!=null;if(url.origin===currentUrl.origin&&isSameBasename)return url.pathname+url.search+url.hash}try{let url=historyInstance.createURL(location2);if(invalidProtocols.includes(url.protocol))throw new Error("Invalid redirect location")}catch{}return location2}__name(normalizeRedirectLocation,"normalizeRedirectLocation");function createClientSideRequest(history,location2,signal,submission){let url=history.createURL(stripHashFromPath(location2)).toString(),init={signal};if(submission&&isMutationMethod(submission.formMethod)){let{formMethod,formEncType}=submission;init.method=formMethod.toUpperCase(),formEncType==="application/json"?(init.headers=new Headers({"Content-Type":formEncType}),init.body=JSON.stringify(submission.json)):formEncType==="text/plain"?init.body=submission.text:formEncType==="application/x-www-form-urlencoded"&&submission.formData?init.body=convertFormDataToSearchParams(submission.formData):init.body=submission.formData}return new Request(url,init)}__name(createClientSideRequest,"createClientSideRequest");function convertFormDataToSearchParams(formData){let searchParams=new URLSearchParams;for(let[key,value2]of formData.entries())searchParams.append(key,typeof value2=="string"?value2:value2.name);return searchParams}__name(convertFormDataToSearchParams,"convertFormDataToSearchParams");function convertSearchParamsToFormData(searchParams){let formData=new FormData;for(let[key,value2]of searchParams.entries())formData.append(key,value2);return formData}__name(convertSearchParamsToFormData,"convertSearchParamsToFormData");function processRouteLoaderData(matches,results,pendingActionResult,activeDeferreds,skipLoaderErrorBubbling){let loaderData={},errors=null,statusCode,foundError=!1,loaderHeaders={},pendingError=pendingActionResult&&isErrorResult(pendingActionResult[1])?pendingActionResult[1].error:void 0;return matches.forEach(match=>{if(!(match.route.id in results))return;let id=match.route.id,result=results[id];if(invariant$1(!isRedirectResult(result),"Cannot handle redirect results in processLoaderData"),isErrorResult(result)){let error=result.error;pendingError!==void 0&&(error=pendingError,pendingError=void 0),errors=errors||{};{let boundaryMatch=findNearestBoundary(matches,id);errors[boundaryMatch.route.id]==null&&(errors[boundaryMatch.route.id]=error)}loaderData[id]=void 0,foundError||(foundError=!0,statusCode=isRouteErrorResponse(result.error)?result.error.status:500),result.headers&&(loaderHeaders[id]=result.headers)}else isDeferredResult(result)?(activeDeferreds.set(id,result.deferredData),loaderData[id]=result.deferredData.data,result.statusCode!=null&&result.statusCode!==200&&!foundError&&(statusCode=result.statusCode),result.headers&&(loaderHeaders[id]=result.headers)):(loaderData[id]=result.data,result.statusCode&&result.statusCode!==200&&!foundError&&(statusCode=result.statusCode),result.headers&&(loaderHeaders[id]=result.headers))}),pendingError!==void 0&&pendingActionResult&&(errors={[pendingActionResult[0]]:pendingError},loaderData[pendingActionResult[0]]=void 0),{loaderData,errors,statusCode:statusCode||200,loaderHeaders}}__name(processRouteLoaderData,"processRouteLoaderData");function processLoaderData(state,matches,results,pendingActionResult,revalidatingFetchers,fetcherResults,activeDeferreds){let{loaderData,errors}=processRouteLoaderData(matches,results,pendingActionResult,activeDeferreds);return revalidatingFetchers.forEach(rf=>{let{key,match,controller}=rf,result=fetcherResults[key];if(invariant$1(result,"Did not find corresponding fetcher result"),!(controller&&controller.signal.aborted))if(isErrorResult(result)){let boundaryMatch=findNearestBoundary(state.matches,match?.route.id);errors&&errors[boundaryMatch.route.id]||(errors=_extends$x({},errors,{[boundaryMatch.route.id]:result.error})),state.fetchers.delete(key)}else if(isRedirectResult(result))invariant$1(!1,"Unhandled fetcher revalidation redirect");else if(isDeferredResult(result))invariant$1(!1,"Unhandled fetcher deferred data");else{let doneFetcher=getDoneFetcher(result.data);state.fetchers.set(key,doneFetcher)}}),{loaderData,errors}}__name(processLoaderData,"processLoaderData");function mergeLoaderData(loaderData,newLoaderData,matches,errors){let mergedLoaderData=_extends$x({},newLoaderData);for(let match of matches){let id=match.route.id;if(newLoaderData.hasOwnProperty(id)?newLoaderData[id]!==void 0&&(mergedLoaderData[id]=newLoaderData[id]):loaderData[id]!==void 0&&match.route.loader&&(mergedLoaderData[id]=loaderData[id]),errors&&errors.hasOwnProperty(id))break}return mergedLoaderData}__name(mergeLoaderData,"mergeLoaderData");function getActionDataForCommit(pendingActionResult){return pendingActionResult?isErrorResult(pendingActionResult[1])?{actionData:{}}:{actionData:{[pendingActionResult[0]]:pendingActionResult[1].data}}:{}}__name(getActionDataForCommit,"getActionDataForCommit");function findNearestBoundary(matches,routeId){return(routeId?matches.slice(0,matches.findIndex(m2=>m2.route.id===routeId)+1):[...matches]).reverse().find(m2=>m2.route.hasErrorBoundary===!0)||matches[0]}__name(findNearestBoundary,"findNearestBoundary");function getShortCircuitMatches(routes){let route=routes.length===1?routes[0]:routes.find(r2=>r2.index||!r2.path||r2.path==="/")||{id:"__shim-error-route__"};return{matches:[{params:{},pathname:"",pathnameBase:"",route}],route}}__name(getShortCircuitMatches,"getShortCircuitMatches");function getInternalRouterError(status,_temp5){let{pathname,routeId,method,type,message}=_temp5===void 0?{}:_temp5,statusText="Unknown Server Error",errorMessage="Unknown @remix-run/router error";return status===400?(statusText="Bad Request",method&&pathname&&routeId?errorMessage="You made a "+method+' request to "'+pathname+'" but '+('did not provide a `loader` for route "'+routeId+'", ')+"so there is no way to handle the request.":type==="defer-action"?errorMessage="defer() is not supported in actions":type==="invalid-body"&&(errorMessage="Unable to encode submission body")):status===403?(statusText="Forbidden",errorMessage='Route "'+routeId+'" does not match URL "'+pathname+'"'):status===404?(statusText="Not Found",errorMessage='No route matches URL "'+pathname+'"'):status===405&&(statusText="Method Not Allowed",method&&pathname&&routeId?errorMessage="You made a "+method.toUpperCase()+' request to "'+pathname+'" but '+('did not provide an `action` for route "'+routeId+'", ')+"so there is no way to handle the request.":method&&(errorMessage='Invalid request method "'+method.toUpperCase()+'"')),new ErrorResponseImpl(status||500,statusText,new Error(errorMessage),!0)}__name(getInternalRouterError,"getInternalRouterError");function findRedirect(results){let entries=Object.entries(results);for(let i2=entries.length-1;i2>=0;i2--){let[key,result]=entries[i2];if(isRedirectResult(result))return{key,result}}}__name(findRedirect,"findRedirect");function stripHashFromPath(path2){let parsedPath=typeof path2=="string"?parsePath(path2):path2;return createPath(_extends$x({},parsedPath,{hash:""}))}__name(stripHashFromPath,"stripHashFromPath");function isHashChangeOnly(a2,b2){return a2.pathname!==b2.pathname||a2.search!==b2.search?!1:a2.hash===""?b2.hash!=="":a2.hash===b2.hash?!0:b2.hash!==""}__name(isHashChangeOnly,"isHashChangeOnly");function isRedirectDataStrategyResultResult(result){return isResponse(result.result)&&redirectStatusCodes.has(result.result.status)}__name(isRedirectDataStrategyResultResult,"isRedirectDataStrategyResultResult");function isDeferredResult(result){return result.type===ResultType.deferred}__name(isDeferredResult,"isDeferredResult");function isErrorResult(result){return result.type===ResultType.error}__name(isErrorResult,"isErrorResult");function isRedirectResult(result){return(result&&result.type)===ResultType.redirect}__name(isRedirectResult,"isRedirectResult");function isDataWithResponseInit(value2){return typeof value2=="object"&&value2!=null&&"type"in value2&&"data"in value2&&"init"in value2&&value2.type==="DataWithResponseInit"}__name(isDataWithResponseInit,"isDataWithResponseInit");function isDeferredData(value2){let deferred=value2;return deferred&&typeof deferred=="object"&&typeof deferred.data=="object"&&typeof deferred.subscribe=="function"&&typeof deferred.cancel=="function"&&typeof deferred.resolveData=="function"}__name(isDeferredData,"isDeferredData");function isResponse(value2){return value2!=null&&typeof value2.status=="number"&&typeof value2.statusText=="string"&&typeof value2.headers=="object"&&typeof value2.body<"u"}__name(isResponse,"isResponse");function isValidMethod(method){return validRequestMethods.has(method.toLowerCase())}__name(isValidMethod,"isValidMethod");function isMutationMethod(method){return validMutationMethods.has(method.toLowerCase())}__name(isMutationMethod,"isMutationMethod");async function resolveNavigationDeferredResults(matches,results,signal,currentMatches,currentLoaderData){let entries=Object.entries(results);for(let index2=0;index2m2?.route.id===routeId);if(!match)continue;let currentMatch=currentMatches.find(m2=>m2.route.id===match.route.id),isRevalidatingLoader=currentMatch!=null&&!isNewRouteInstance(currentMatch,match)&&(currentLoaderData&¤tLoaderData[match.route.id])!==void 0;isDeferredResult(result)&&isRevalidatingLoader&&await resolveDeferredData(result,signal,!1).then(result2=>{result2&&(results[routeId]=result2)})}}__name(resolveNavigationDeferredResults,"resolveNavigationDeferredResults");async function resolveFetcherDeferredResults(matches,results,revalidatingFetchers){for(let index2=0;index2m2?.route.id===routeId)&&isDeferredResult(result)&&(invariant$1(controller,"Expected an AbortController for revalidating fetcher deferred result"),await resolveDeferredData(result,controller.signal,!0).then(result2=>{result2&&(results[key]=result2)}))}}__name(resolveFetcherDeferredResults,"resolveFetcherDeferredResults");async function resolveDeferredData(result,signal,unwrap){if(unwrap===void 0&&(unwrap=!1),!await result.deferredData.resolveData(signal)){if(unwrap)try{return{type:ResultType.data,data:result.deferredData.unwrappedData}}catch(e3){return{type:ResultType.error,error:e3}}return{type:ResultType.data,data:result.deferredData.data}}}__name(resolveDeferredData,"resolveDeferredData");function hasNakedIndexQuery(search2){return new URLSearchParams(search2).getAll("index").some(v2=>v2==="")}__name(hasNakedIndexQuery,"hasNakedIndexQuery");function getTargetMatch(matches,location2){let search2=typeof location2=="string"?parsePath(location2).search:location2.search;if(matches[matches.length-1].route.index&&hasNakedIndexQuery(search2||""))return matches[matches.length-1];let pathMatches=getPathContributingMatches(matches);return pathMatches[pathMatches.length-1]}__name(getTargetMatch,"getTargetMatch");function getSubmissionFromNavigation(navigation){let{formMethod,formAction,formEncType,text:text2,formData,json:json3}=navigation;if(!(!formMethod||!formAction||!formEncType)){if(text2!=null)return{formMethod,formAction,formEncType,formData:void 0,json:void 0,text:text2};if(formData!=null)return{formMethod,formAction,formEncType,formData,json:void 0,text:void 0};if(json3!==void 0)return{formMethod,formAction,formEncType,formData:void 0,json:json3,text:void 0}}}__name(getSubmissionFromNavigation,"getSubmissionFromNavigation");function getLoadingNavigation(location2,submission){return submission?{state:"loading",location:location2,formMethod:submission.formMethod,formAction:submission.formAction,formEncType:submission.formEncType,formData:submission.formData,json:submission.json,text:submission.text}:{state:"loading",location:location2,formMethod:void 0,formAction:void 0,formEncType:void 0,formData:void 0,json:void 0,text:void 0}}__name(getLoadingNavigation,"getLoadingNavigation");function getSubmittingNavigation(location2,submission){return{state:"submitting",location:location2,formMethod:submission.formMethod,formAction:submission.formAction,formEncType:submission.formEncType,formData:submission.formData,json:submission.json,text:submission.text}}__name(getSubmittingNavigation,"getSubmittingNavigation");function getLoadingFetcher(submission,data2){return submission?{state:"loading",formMethod:submission.formMethod,formAction:submission.formAction,formEncType:submission.formEncType,formData:submission.formData,json:submission.json,text:submission.text,data:data2}:{state:"loading",formMethod:void 0,formAction:void 0,formEncType:void 0,formData:void 0,json:void 0,text:void 0,data:data2}}__name(getLoadingFetcher,"getLoadingFetcher");function getSubmittingFetcher(submission,existingFetcher){return{state:"submitting",formMethod:submission.formMethod,formAction:submission.formAction,formEncType:submission.formEncType,formData:submission.formData,json:submission.json,text:submission.text,data:existingFetcher?existingFetcher.data:void 0}}__name(getSubmittingFetcher,"getSubmittingFetcher");function getDoneFetcher(data2){return{state:"idle",formMethod:void 0,formAction:void 0,formEncType:void 0,formData:void 0,json:void 0,text:void 0,data:data2}}__name(getDoneFetcher,"getDoneFetcher");function restoreAppliedTransitions(_window,transitions){try{let sessionPositions=_window.sessionStorage.getItem(TRANSITIONS_STORAGE_KEY);if(sessionPositions){let json3=JSON.parse(sessionPositions);for(let[k2,v2]of Object.entries(json3||{}))v2&&Array.isArray(v2)&&transitions.set(k2,new Set(v2||[]))}}catch{}}__name(restoreAppliedTransitions,"restoreAppliedTransitions");function persistAppliedTransitions(_window,transitions){if(transitions.size>0){let json3={};for(let[k2,v2]of transitions)json3[k2]=[...v2];try{_window.sessionStorage.setItem(TRANSITIONS_STORAGE_KEY,JSON.stringify(json3))}catch(error){warning(!1,"Failed to save applied view transitions in sessionStorage ("+error+").")}}}__name(persistAppliedTransitions,"persistAppliedTransitions");function _extends$w(){return _extends$w=Object.assign?Object.assign.bind():function(target){for(var i2=1;i2{activeRef.current=!0}),reactExports.useCallback(function(to2,options){if(options===void 0&&(options={}),!activeRef.current)return;if(typeof to2=="number"){navigator2.go(to2);return}let path2=resolveTo(to2,JSON.parse(routePathnamesJson),locationPathname,options.relative==="path");dataRouterContext==null&&basename2!=="/"&&(path2.pathname=path2.pathname==="/"?basename2:joinPaths([basename2,path2.pathname])),(options.replace?navigator2.replace:navigator2.push)(path2,options.state,options)},[basename2,navigator2,routePathnamesJson,locationPathname,dataRouterContext])}__name(useNavigateUnstable,"useNavigateUnstable");const OutletContext=reactExports.createContext(null);function useOutlet(context){let outlet=reactExports.useContext(RouteContext).outlet;return outlet&&reactExports.createElement(OutletContext.Provider,{value:context},outlet)}__name(useOutlet,"useOutlet");function useResolvedPath(to2,_temp2){let{relative}=_temp2===void 0?{}:_temp2,{future}=reactExports.useContext(NavigationContext),{matches}=reactExports.useContext(RouteContext),{pathname:locationPathname}=useLocation(),routePathnamesJson=JSON.stringify(getResolveToMatches(matches,future.v7_relativeSplatPath));return reactExports.useMemo(()=>resolveTo(to2,JSON.parse(routePathnamesJson),locationPathname,relative==="path"),[to2,routePathnamesJson,locationPathname,relative])}__name(useResolvedPath,"useResolvedPath");function useRoutesImpl(routes,locationArg,dataRouterState,future){useInRouterContext()||invariant$1(!1);let{navigator:navigator2}=reactExports.useContext(NavigationContext),{matches:parentMatches}=reactExports.useContext(RouteContext),routeMatch=parentMatches[parentMatches.length-1],parentParams=routeMatch?routeMatch.params:{};routeMatch&&routeMatch.pathname;let parentPathnameBase=routeMatch?routeMatch.pathnameBase:"/";routeMatch&&routeMatch.route;let locationFromContext=useLocation(),location2;location2=locationFromContext;let pathname=location2.pathname||"/",remainingPathname=pathname;if(parentPathnameBase!=="/"){let parentSegments=parentPathnameBase.replace(/^\//,"").split("/");remainingPathname="/"+pathname.replace(/^\//,"").split("/").slice(parentSegments.length).join("/")}let matches=matchRoutes(routes,{pathname:remainingPathname});return _renderMatches(matches&&matches.map(match=>Object.assign({},match,{params:Object.assign({},parentParams,match.params),pathname:joinPaths([parentPathnameBase,navigator2.encodeLocation?navigator2.encodeLocation(match.pathname).pathname:match.pathname]),pathnameBase:match.pathnameBase==="/"?parentPathnameBase:joinPaths([parentPathnameBase,navigator2.encodeLocation?navigator2.encodeLocation(match.pathnameBase).pathname:match.pathnameBase])})),parentMatches,dataRouterState,future)}__name(useRoutesImpl,"useRoutesImpl");function DefaultErrorComponent(){let error=useRouteError(),message=isRouteErrorResponse(error)?error.status+" "+error.statusText:error instanceof Error?error.message:JSON.stringify(error),stack=error instanceof Error?error.stack:null,preStyles={padding:"0.5rem",backgroundColor:"rgba(200,200,200, 0.5)"};return reactExports.createElement(reactExports.Fragment,null,reactExports.createElement("h2",null,"Unexpected Application Error!"),reactExports.createElement("h3",{style:{fontStyle:"italic"}},message),stack?reactExports.createElement("pre",{style:preStyles},stack):null,null)}__name(DefaultErrorComponent,"DefaultErrorComponent");const defaultErrorElement=reactExports.createElement(DefaultErrorComponent,null),_RenderErrorBoundary=class _RenderErrorBoundary extends reactExports.Component{constructor(props){super(props),this.state={location:props.location,revalidation:props.revalidation,error:props.error}}static getDerivedStateFromError(error){return{error}}static getDerivedStateFromProps(props,state){return state.location!==props.location||state.revalidation!=="idle"&&props.revalidation==="idle"?{error:props.error,location:props.location,revalidation:props.revalidation}:{error:props.error!==void 0?props.error:state.error,location:state.location,revalidation:props.revalidation||state.revalidation}}componentDidCatch(error,errorInfo){console.error("React Router caught the following error during render",error,errorInfo)}render(){return this.state.error!==void 0?reactExports.createElement(RouteContext.Provider,{value:this.props.routeContext},reactExports.createElement(RouteErrorContext.Provider,{value:this.state.error,children:this.props.component})):this.props.children}};__name(_RenderErrorBoundary,"RenderErrorBoundary");let RenderErrorBoundary=_RenderErrorBoundary;function RenderedRoute(_ref){let{routeContext,match,children:children2}=_ref,dataRouterContext=reactExports.useContext(DataRouterContext);return dataRouterContext&&dataRouterContext.static&&dataRouterContext.staticContext&&(match.route.errorElement||match.route.ErrorBoundary)&&(dataRouterContext.staticContext._deepestRenderedBoundaryId=match.route.id),reactExports.createElement(RouteContext.Provider,{value:routeContext},children2)}__name(RenderedRoute,"RenderedRoute");function _renderMatches(matches,parentMatches,dataRouterState,future){var _dataRouterState;if(parentMatches===void 0&&(parentMatches=[]),dataRouterState===void 0&&(dataRouterState=null),future===void 0&&(future=null),matches==null){var _future;if(!dataRouterState)return null;if(dataRouterState.errors)matches=dataRouterState.matches;else if((_future=future)!=null&&_future.v7_partialHydration&&parentMatches.length===0&&!dataRouterState.initialized&&dataRouterState.matches.length>0)matches=dataRouterState.matches;else return null}let renderedMatches=matches,errors=(_dataRouterState=dataRouterState)==null?void 0:_dataRouterState.errors;if(errors!=null){let errorIndex=renderedMatches.findIndex(m2=>m2.route.id&&errors?.[m2.route.id]!==void 0);errorIndex>=0||invariant$1(!1),renderedMatches=renderedMatches.slice(0,Math.min(renderedMatches.length,errorIndex+1))}let renderFallback=!1,fallbackIndex=-1;if(dataRouterState&&future&&future.v7_partialHydration)for(let i2=0;i2=0?renderedMatches=renderedMatches.slice(0,fallbackIndex+1):renderedMatches=[renderedMatches[0]];break}}}return renderedMatches.reduceRight((outlet,match,index2)=>{let error,shouldRenderHydrateFallback=!1,errorElement=null,hydrateFallbackElement=null;dataRouterState&&(error=errors&&match.route.id?errors[match.route.id]:void 0,errorElement=match.route.errorElement||defaultErrorElement,renderFallback&&(fallbackIndex<0&&index2===0?(warningOnce("route-fallback"),shouldRenderHydrateFallback=!0,hydrateFallbackElement=null):fallbackIndex===index2&&(shouldRenderHydrateFallback=!0,hydrateFallbackElement=match.route.hydrateFallbackElement||null)));let matches2=parentMatches.concat(renderedMatches.slice(0,index2+1)),getChildren=__name(()=>{let children2;return error?children2=errorElement:shouldRenderHydrateFallback?children2=hydrateFallbackElement:match.route.Component?children2=reactExports.createElement(match.route.Component,null):match.route.element?children2=match.route.element:children2=outlet,reactExports.createElement(RenderedRoute,{match,routeContext:{outlet,matches:matches2,isDataRoute:dataRouterState!=null},children:children2})},"getChildren");return dataRouterState&&(match.route.ErrorBoundary||match.route.errorElement||index2===0)?reactExports.createElement(RenderErrorBoundary,{location:dataRouterState.location,revalidation:dataRouterState.revalidation,component:errorElement,error,children:getChildren(),routeContext:{outlet:null,matches:matches2,isDataRoute:!0}}):getChildren()},null)}__name(_renderMatches,"_renderMatches");var DataRouterHook$1=(function(DataRouterHook2){return DataRouterHook2.UseBlocker="useBlocker",DataRouterHook2.UseRevalidator="useRevalidator",DataRouterHook2.UseNavigateStable="useNavigate",DataRouterHook2})(DataRouterHook$1||{}),DataRouterStateHook$1=(function(DataRouterStateHook2){return DataRouterStateHook2.UseBlocker="useBlocker",DataRouterStateHook2.UseLoaderData="useLoaderData",DataRouterStateHook2.UseActionData="useActionData",DataRouterStateHook2.UseRouteError="useRouteError",DataRouterStateHook2.UseNavigation="useNavigation",DataRouterStateHook2.UseRouteLoaderData="useRouteLoaderData",DataRouterStateHook2.UseMatches="useMatches",DataRouterStateHook2.UseRevalidator="useRevalidator",DataRouterStateHook2.UseNavigateStable="useNavigate",DataRouterStateHook2.UseRouteId="useRouteId",DataRouterStateHook2})(DataRouterStateHook$1||{});function useDataRouterContext$1(hookName){let ctx2=reactExports.useContext(DataRouterContext);return ctx2||invariant$1(!1),ctx2}__name(useDataRouterContext$1,"useDataRouterContext$1");function useDataRouterState(hookName){let state=reactExports.useContext(DataRouterStateContext);return state||invariant$1(!1),state}__name(useDataRouterState,"useDataRouterState");function useRouteContext(hookName){let route=reactExports.useContext(RouteContext);return route||invariant$1(!1),route}__name(useRouteContext,"useRouteContext");function useCurrentRouteId(hookName){let route=useRouteContext(),thisRoute=route.matches[route.matches.length-1];return thisRoute.route.id||invariant$1(!1),thisRoute.route.id}__name(useCurrentRouteId,"useCurrentRouteId");function useRouteError(){var _state$errors;let error=reactExports.useContext(RouteErrorContext),state=useDataRouterState(),routeId=useCurrentRouteId();return error!==void 0?error:(_state$errors=state.errors)==null?void 0:_state$errors[routeId]}__name(useRouteError,"useRouteError");function useNavigateStable(){let{router:router2}=useDataRouterContext$1(DataRouterHook$1.UseNavigateStable),id=useCurrentRouteId(DataRouterStateHook$1.UseNavigateStable),activeRef=reactExports.useRef(!1);return useIsomorphicLayoutEffect$2(()=>{activeRef.current=!0}),reactExports.useCallback(function(to2,options){options===void 0&&(options={}),activeRef.current&&(typeof to2=="number"?router2.navigate(to2):router2.navigate(to2,_extends$w({fromRouteId:id},options)))},[router2,id])}__name(useNavigateStable,"useNavigateStable");const alreadyWarned$1={};function warningOnce(key,cond,message){alreadyWarned$1[key]||(alreadyWarned$1[key]=!0)}__name(warningOnce,"warningOnce");function logV6DeprecationWarnings(renderFuture,routerFuture){renderFuture?.v7_startTransition,renderFuture?.v7_relativeSplatPath===void 0&&(!routerFuture||routerFuture.v7_relativeSplatPath),routerFuture&&(routerFuture.v7_fetcherPersist,routerFuture.v7_normalizeFormMethod,routerFuture.v7_partialHydration,routerFuture.v7_skipActionErrorRevalidation)}__name(logV6DeprecationWarnings,"logV6DeprecationWarnings");function Outlet(props){return useOutlet(props.context)}__name(Outlet,"Outlet");function Router(_ref5){let{basename:basenameProp="/",children:children2=null,location:locationProp,navigationType=Action.Pop,navigator:navigator2,static:staticProp=!1,future}=_ref5;useInRouterContext()&&invariant$1(!1);let basename2=basenameProp.replace(/^\/*/,"/"),navigationContext=reactExports.useMemo(()=>({basename:basename2,navigator:navigator2,static:staticProp,future:_extends$w({v7_relativeSplatPath:!1},future)}),[basename2,future,navigator2,staticProp]);typeof locationProp=="string"&&(locationProp=parsePath(locationProp));let{pathname="/",search:search2="",hash="",state=null,key="default"}=locationProp,locationContext=reactExports.useMemo(()=>{let trailingPathname=stripBasename(pathname,basename2);return trailingPathname==null?null:{location:{pathname:trailingPathname,search:search2,hash,state,key},navigationType}},[basename2,pathname,search2,hash,state,key,navigationType]);return locationContext==null?null:reactExports.createElement(NavigationContext.Provider,{value:navigationContext},reactExports.createElement(LocationContext.Provider,{children:children2,value:locationContext}))}__name(Router,"Router");new Promise(()=>{});function mapRouteProperties(route){let updates={hasErrorBoundary:route.ErrorBoundary!=null||route.errorElement!=null};return route.Component&&Object.assign(updates,{element:reactExports.createElement(route.Component),Component:void 0}),route.HydrateFallback&&Object.assign(updates,{hydrateFallbackElement:reactExports.createElement(route.HydrateFallback),HydrateFallback:void 0}),route.ErrorBoundary&&Object.assign(updates,{errorElement:reactExports.createElement(route.ErrorBoundary),ErrorBoundary:void 0}),updates}__name(mapRouteProperties,"mapRouteProperties");function _extends$v(){return _extends$v=Object.assign?Object.assign.bind():function(target){for(var i2=1;i2=0)&&(target[key]=source[key]);return target}__name(_objectWithoutPropertiesLoose$k,"_objectWithoutPropertiesLoose$k");function isModifiedEvent(event){return!!(event.metaKey||event.altKey||event.ctrlKey||event.shiftKey)}__name(isModifiedEvent,"isModifiedEvent");function shouldProcessLinkClick(event,target){return event.button===0&&(!target||target==="_self")&&!isModifiedEvent(event)}__name(shouldProcessLinkClick,"shouldProcessLinkClick");const _excluded$k=["onClick","relative","reloadDocument","replace","state","target","to","preventScrollReset","viewTransition"],_excluded2$7=["aria-current","caseSensitive","className","end","style","to","viewTransition","children"],REACT_ROUTER_VERSION="6";try{window.__reactRouterVersion=REACT_ROUTER_VERSION}catch{}function createHashRouter(routes,opts){return createRouter({basename:opts?.basename,future:_extends$v({},opts?.future,{v7_prependBasename:!0}),history:createHashHistory({window:opts?.window}),hydrationData:opts?.hydrationData||parseHydrationData(),routes,mapRouteProperties,dataStrategy:opts?.dataStrategy,patchRoutesOnNavigation:opts?.patchRoutesOnNavigation,window:opts?.window}).initialize()}__name(createHashRouter,"createHashRouter");function parseHydrationData(){var _window;let state=(_window=window)==null?void 0:_window.__staticRouterHydrationData;return state&&state.errors&&(state=_extends$v({},state,{errors:deserializeErrors(state.errors)})),state}__name(parseHydrationData,"parseHydrationData");function deserializeErrors(errors){if(!errors)return null;let entries=Object.entries(errors),serialized={};for(let[key,val]of entries)if(val&&val.__type==="RouteErrorResponse")serialized[key]=new ErrorResponseImpl(val.status,val.statusText,val.data,val.internal===!0);else if(val&&val.__type==="Error"){if(val.__subType){let ErrorConstructor=window[val.__subType];if(typeof ErrorConstructor=="function")try{let error=new ErrorConstructor(val.message);error.stack="",serialized[key]=error}catch{}}if(serialized[key]==null){let error=new Error(val.message);error.stack="",serialized[key]=error}}else serialized[key]=val;return serialized}__name(deserializeErrors,"deserializeErrors");const ViewTransitionContext=reactExports.createContext({isTransitioning:!1}),FetchersContext=reactExports.createContext(new Map),START_TRANSITION="startTransition",startTransitionImpl=React$1[START_TRANSITION],FLUSH_SYNC="flushSync",flushSyncImpl=ReactDOM$1[FLUSH_SYNC];function startTransitionSafe(cb){startTransitionImpl?startTransitionImpl(cb):cb()}__name(startTransitionSafe,"startTransitionSafe");function flushSyncSafe(cb){flushSyncImpl?flushSyncImpl(cb):cb()}__name(flushSyncSafe,"flushSyncSafe");const _Deferred=class _Deferred{constructor(){this.status="pending",this.promise=new Promise((resolve,reject)=>{this.resolve=value2=>{this.status==="pending"&&(this.status="resolved",resolve(value2))},this.reject=reason=>{this.status==="pending"&&(this.status="rejected",reject(reason))}})}};__name(_Deferred,"Deferred");let Deferred=_Deferred;function RouterProvider(_ref){let{fallbackElement,router:router2,future}=_ref,[state,setStateImpl]=reactExports.useState(router2.state),[pendingState,setPendingState]=reactExports.useState(),[vtContext,setVtContext]=reactExports.useState({isTransitioning:!1}),[renderDfd,setRenderDfd]=reactExports.useState(),[transition,setTransition]=reactExports.useState(),[interruption,setInterruption]=reactExports.useState(),fetcherData=reactExports.useRef(new Map),{v7_startTransition}=future||{},optInStartTransition=reactExports.useCallback(cb=>{v7_startTransition?startTransitionSafe(cb):cb()},[v7_startTransition]),setState=reactExports.useCallback((newState,_ref2)=>{let{deletedFetchers,flushSync,viewTransitionOpts}=_ref2;newState.fetchers.forEach((fetcher,key)=>{fetcher.data!==void 0&&fetcherData.current.set(key,fetcher.data)}),deletedFetchers.forEach(key=>fetcherData.current.delete(key));let isViewTransitionUnavailable=router2.window==null||router2.window.document==null||typeof router2.window.document.startViewTransition!="function";if(!viewTransitionOpts||isViewTransitionUnavailable){flushSync?flushSyncSafe(()=>setStateImpl(newState)):optInStartTransition(()=>setStateImpl(newState));return}if(flushSync){flushSyncSafe(()=>{transition&&(renderDfd&&renderDfd.resolve(),transition.skipTransition()),setVtContext({isTransitioning:!0,flushSync:!0,currentLocation:viewTransitionOpts.currentLocation,nextLocation:viewTransitionOpts.nextLocation})});let t2=router2.window.document.startViewTransition(()=>{flushSyncSafe(()=>setStateImpl(newState))});t2.finished.finally(()=>{flushSyncSafe(()=>{setRenderDfd(void 0),setTransition(void 0),setPendingState(void 0),setVtContext({isTransitioning:!1})})}),flushSyncSafe(()=>setTransition(t2));return}transition?(renderDfd&&renderDfd.resolve(),transition.skipTransition(),setInterruption({state:newState,currentLocation:viewTransitionOpts.currentLocation,nextLocation:viewTransitionOpts.nextLocation})):(setPendingState(newState),setVtContext({isTransitioning:!0,flushSync:!1,currentLocation:viewTransitionOpts.currentLocation,nextLocation:viewTransitionOpts.nextLocation}))},[router2.window,transition,renderDfd,fetcherData,optInStartTransition]);reactExports.useLayoutEffect(()=>router2.subscribe(setState),[router2,setState]),reactExports.useEffect(()=>{vtContext.isTransitioning&&!vtContext.flushSync&&setRenderDfd(new Deferred)},[vtContext]),reactExports.useEffect(()=>{if(renderDfd&&pendingState&&router2.window){let newState=pendingState,renderPromise=renderDfd.promise,transition2=router2.window.document.startViewTransition(async()=>{optInStartTransition(()=>setStateImpl(newState)),await renderPromise});transition2.finished.finally(()=>{setRenderDfd(void 0),setTransition(void 0),setPendingState(void 0),setVtContext({isTransitioning:!1})}),setTransition(transition2)}},[optInStartTransition,pendingState,renderDfd,router2.window]),reactExports.useEffect(()=>{renderDfd&&pendingState&&state.location.key===pendingState.location.key&&renderDfd.resolve()},[renderDfd,transition,state.location,pendingState]),reactExports.useEffect(()=>{!vtContext.isTransitioning&&interruption&&(setPendingState(interruption.state),setVtContext({isTransitioning:!0,flushSync:!1,currentLocation:interruption.currentLocation,nextLocation:interruption.nextLocation}),setInterruption(void 0))},[vtContext.isTransitioning,interruption]),reactExports.useEffect(()=>{},[]);let navigator2=reactExports.useMemo(()=>({createHref:router2.createHref,encodeLocation:router2.encodeLocation,go:__name(n2=>router2.navigate(n2),"go"),push:__name((to2,state2,opts)=>router2.navigate(to2,{state:state2,preventScrollReset:opts?.preventScrollReset}),"push"),replace:__name((to2,state2,opts)=>router2.navigate(to2,{replace:!0,state:state2,preventScrollReset:opts?.preventScrollReset}),"replace")}),[router2]),basename2=router2.basename||"/",dataRouterContext=reactExports.useMemo(()=>({router:router2,navigator:navigator2,static:!1,basename:basename2}),[router2,navigator2,basename2]),routerFuture=reactExports.useMemo(()=>({v7_relativeSplatPath:router2.future.v7_relativeSplatPath}),[router2.future.v7_relativeSplatPath]);return reactExports.useEffect(()=>logV6DeprecationWarnings(future,router2.future),[future,router2.future]),reactExports.createElement(reactExports.Fragment,null,reactExports.createElement(DataRouterContext.Provider,{value:dataRouterContext},reactExports.createElement(DataRouterStateContext.Provider,{value:state},reactExports.createElement(FetchersContext.Provider,{value:fetcherData.current},reactExports.createElement(ViewTransitionContext.Provider,{value:vtContext},reactExports.createElement(Router,{basename:basename2,location:state.location,navigationType:state.historyAction,navigator:navigator2,future:routerFuture},state.initialized||router2.future.v7_partialHydration?reactExports.createElement(MemoizedDataRoutes,{routes:router2.routes,future:router2.future,state}):fallbackElement))))),null)}__name(RouterProvider,"RouterProvider");const MemoizedDataRoutes=reactExports.memo(DataRoutes);function DataRoutes(_ref3){let{routes,future,state}=_ref3;return useRoutesImpl(routes,void 0,state,future)}__name(DataRoutes,"DataRoutes");const isBrowser=typeof window<"u"&&typeof window.document<"u"&&typeof window.document.createElement<"u",ABSOLUTE_URL_REGEX=/^(?:[a-z][a-z0-9+.-]*:|\/\/)/i,Link=reactExports.forwardRef(__name(function(_ref7,ref){let{onClick,relative,reloadDocument,replace:replace2,state,target,to:to2,preventScrollReset,viewTransition}=_ref7,rest=_objectWithoutPropertiesLoose$k(_ref7,_excluded$k),{basename:basename2}=reactExports.useContext(NavigationContext),absoluteHref,isExternal=!1;if(typeof to2=="string"&&ABSOLUTE_URL_REGEX.test(to2)&&(absoluteHref=to2,isBrowser))try{let currentUrl=new URL(window.location.href),targetUrl=to2.startsWith("//")?new URL(currentUrl.protocol+to2):new URL(to2),path2=stripBasename(targetUrl.pathname,basename2);targetUrl.origin===currentUrl.origin&&path2!=null?to2=path2+targetUrl.search+targetUrl.hash:isExternal=!0}catch{}let href=useHref(to2,{relative}),internalOnClick=useLinkClickHandler(to2,{replace:replace2,state,target,preventScrollReset,relative,viewTransition});function handleClick(event){onClick&&onClick(event),event.defaultPrevented||internalOnClick(event)}return __name(handleClick,"handleClick"),reactExports.createElement("a",_extends$v({},rest,{href:absoluteHref||href,onClick:isExternal||reloadDocument?onClick:handleClick,ref,target}))},"LinkWithRef")),NavLink=reactExports.forwardRef(__name(function(_ref8,ref){let{"aria-current":ariaCurrentProp="page",caseSensitive=!1,className:classNameProp="",end=!1,style:styleProp,to:to2,viewTransition,children:children2}=_ref8,rest=_objectWithoutPropertiesLoose$k(_ref8,_excluded2$7),path2=useResolvedPath(to2,{relative:rest.relative}),location2=useLocation(),routerState=reactExports.useContext(DataRouterStateContext),{navigator:navigator2,basename:basename2}=reactExports.useContext(NavigationContext),isTransitioning=routerState!=null&&useViewTransitionState(path2)&&viewTransition===!0,toPathname=navigator2.encodeLocation?navigator2.encodeLocation(path2).pathname:path2.pathname,locationPathname=location2.pathname,nextLocationPathname=routerState&&routerState.navigation&&routerState.navigation.location?routerState.navigation.location.pathname:null;caseSensitive||(locationPathname=locationPathname.toLowerCase(),nextLocationPathname=nextLocationPathname?nextLocationPathname.toLowerCase():null,toPathname=toPathname.toLowerCase()),nextLocationPathname&&basename2&&(nextLocationPathname=stripBasename(nextLocationPathname,basename2)||nextLocationPathname);const endSlashPosition=toPathname!=="/"&&toPathname.endsWith("/")?toPathname.length-1:toPathname.length;let isActive=locationPathname===toPathname||!end&&locationPathname.startsWith(toPathname)&&locationPathname.charAt(endSlashPosition)==="/",isPending=nextLocationPathname!=null&&(nextLocationPathname===toPathname||!end&&nextLocationPathname.startsWith(toPathname)&&nextLocationPathname.charAt(toPathname.length)==="/"),renderProps={isActive,isPending,isTransitioning},ariaCurrent=isActive?ariaCurrentProp:void 0,className;typeof classNameProp=="function"?className=classNameProp(renderProps):className=[classNameProp,isActive?"active":null,isPending?"pending":null,isTransitioning?"transitioning":null].filter(Boolean).join(" ");let style2=typeof styleProp=="function"?styleProp(renderProps):styleProp;return reactExports.createElement(Link,_extends$v({},rest,{"aria-current":ariaCurrent,className,ref,style:style2,to:to2,viewTransition}),typeof children2=="function"?children2(renderProps):children2)},"NavLinkWithRef"));var DataRouterHook;(function(DataRouterHook2){DataRouterHook2.UseScrollRestoration="useScrollRestoration",DataRouterHook2.UseSubmit="useSubmit",DataRouterHook2.UseSubmitFetcher="useSubmitFetcher",DataRouterHook2.UseFetcher="useFetcher",DataRouterHook2.useViewTransitionState="useViewTransitionState"})(DataRouterHook||(DataRouterHook={}));var DataRouterStateHook;(function(DataRouterStateHook2){DataRouterStateHook2.UseFetcher="useFetcher",DataRouterStateHook2.UseFetchers="useFetchers",DataRouterStateHook2.UseScrollRestoration="useScrollRestoration"})(DataRouterStateHook||(DataRouterStateHook={}));function useDataRouterContext(hookName){let ctx2=reactExports.useContext(DataRouterContext);return ctx2||invariant$1(!1),ctx2}__name(useDataRouterContext,"useDataRouterContext");function useLinkClickHandler(to2,_temp){let{target,replace:replaceProp,state,preventScrollReset,relative,viewTransition}=_temp===void 0?{}:_temp,navigate=useNavigate(),location2=useLocation(),path2=useResolvedPath(to2,{relative});return reactExports.useCallback(event=>{if(shouldProcessLinkClick(event,target)){event.preventDefault();let replace2=replaceProp!==void 0?replaceProp:createPath(location2)===createPath(path2);navigate(to2,{replace:replace2,state,preventScrollReset,relative,viewTransition})}},[location2,navigate,path2,replaceProp,state,target,to2,preventScrollReset,relative,viewTransition])}__name(useLinkClickHandler,"useLinkClickHandler");function useViewTransitionState(to2,opts){opts===void 0&&(opts={});let vtContext=reactExports.useContext(ViewTransitionContext);vtContext==null&&invariant$1(!1);let{basename:basename2}=useDataRouterContext(DataRouterHook.useViewTransitionState),path2=useResolvedPath(to2,{relative:opts.relative});if(!vtContext.isTransitioning)return!1;let currentPath=stripBasename(vtContext.currentLocation.pathname,basename2)||vtContext.currentLocation.pathname,nextPath=stripBasename(vtContext.nextLocation.pathname,basename2)||vtContext.nextLocation.pathname;return matchPath(path2.pathname,nextPath)!=null||matchPath(path2.pathname,currentPath)!=null}__name(useViewTransitionState,"useViewTransitionState");const initialState={theme:"system",setTheme:__name(()=>null,"setTheme")},ThemeProviderContext=reactExports.createContext(initialState);function ThemeProvider({children:children2,defaultTheme="system",storageKey="shadcn-ui-theme",...props}){const[theme,setTheme]=reactExports.useState(()=>localStorage.getItem(storageKey)??defaultTheme);return reactExports.useEffect(()=>{const root2=window.document.documentElement;if(root2.classList.remove("light","dark"),theme==="system"){const systemTheme=window.matchMedia("(prefers-color-scheme: dark)").matches?"dark":"light";root2.classList.add(systemTheme);return}root2.classList.add(theme)},[theme]),reactExports.useEffect(()=>{const mediaQuery=window.matchMedia("(prefers-color-scheme: dark)"),handleChange=__name(()=>{if(theme==="system"){const root2=window.document.documentElement;root2.classList.remove("light","dark");const systemTheme=mediaQuery.matches?"dark":"light";root2.classList.add(systemTheme)}},"handleChange");return mediaQuery.addEventListener("change",handleChange),()=>mediaQuery.removeEventListener("change",handleChange)},[theme]),jsxRuntimeExports.jsx(ThemeProviderContext.Provider,{...props,value:{theme,setTheme:__name(theme2=>{localStorage.setItem(storageKey,theme2),setTheme(theme2)},"setTheme")},children:children2})}__name(ThemeProvider,"ThemeProvider");function r$2(e3){var t2,f2,n2="";if(typeof e3=="string"||typeof e3=="number")n2+=e3;else if(typeof e3=="object")if(Array.isArray(e3)){var o2=e3.length;for(t2=0;t2{const classMap=createClassMap(config2),{conflictingClassGroups,conflictingClassGroupModifiers}=config2;return{getClassGroupId:__name(className=>{const classParts=className.split(CLASS_PART_SEPARATOR);return classParts[0]===""&&classParts.length!==1&&classParts.shift(),getGroupRecursive(classParts,classMap)||getGroupIdForArbitraryProperty(className)},"getClassGroupId"),getConflictingClassGroupIds:__name((classGroupId,hasPostfixModifier)=>{const conflicts=conflictingClassGroups[classGroupId]||[];return hasPostfixModifier&&conflictingClassGroupModifiers[classGroupId]?[...conflicts,...conflictingClassGroupModifiers[classGroupId]]:conflicts},"getConflictingClassGroupIds")}},"createClassGroupUtils"),getGroupRecursive=__name((classParts,classPartObject)=>{if(classParts.length===0)return classPartObject.classGroupId;const currentClassPart=classParts[0],nextClassPartObject=classPartObject.nextPart.get(currentClassPart),classGroupFromNextClassPart=nextClassPartObject?getGroupRecursive(classParts.slice(1),nextClassPartObject):void 0;if(classGroupFromNextClassPart)return classGroupFromNextClassPart;if(classPartObject.validators.length===0)return;const classRest=classParts.join(CLASS_PART_SEPARATOR);return classPartObject.validators.find(({validator})=>validator(classRest))?.classGroupId},"getGroupRecursive"),arbitraryPropertyRegex=/^\[(.+)\]$/,getGroupIdForArbitraryProperty=__name(className=>{if(arbitraryPropertyRegex.test(className)){const arbitraryPropertyClassName=arbitraryPropertyRegex.exec(className)[1],property=arbitraryPropertyClassName?.substring(0,arbitraryPropertyClassName.indexOf(":"));if(property)return"arbitrary.."+property}},"getGroupIdForArbitraryProperty"),createClassMap=__name(config2=>{const{theme,prefix:prefix2}=config2,classMap={nextPart:new Map,validators:[]};return getPrefixedClassGroupEntries(Object.entries(config2.classGroups),prefix2).forEach(([classGroupId,classGroup])=>{processClassesRecursively(classGroup,classMap,classGroupId,theme)}),classMap},"createClassMap"),processClassesRecursively=__name((classGroup,classPartObject,classGroupId,theme)=>{classGroup.forEach(classDefinition=>{if(typeof classDefinition=="string"){const classPartObjectToEdit=classDefinition===""?classPartObject:getPart(classPartObject,classDefinition);classPartObjectToEdit.classGroupId=classGroupId;return}if(typeof classDefinition=="function"){if(isThemeGetter(classDefinition)){processClassesRecursively(classDefinition(theme),classPartObject,classGroupId,theme);return}classPartObject.validators.push({validator:classDefinition,classGroupId});return}Object.entries(classDefinition).forEach(([key,classGroup2])=>{processClassesRecursively(classGroup2,getPart(classPartObject,key),classGroupId,theme)})})},"processClassesRecursively"),getPart=__name((classPartObject,path2)=>{let currentClassPartObject=classPartObject;return path2.split(CLASS_PART_SEPARATOR).forEach(pathPart=>{currentClassPartObject.nextPart.has(pathPart)||currentClassPartObject.nextPart.set(pathPart,{nextPart:new Map,validators:[]}),currentClassPartObject=currentClassPartObject.nextPart.get(pathPart)}),currentClassPartObject},"getPart"),isThemeGetter=__name(func=>func.isThemeGetter,"isThemeGetter"),getPrefixedClassGroupEntries=__name((classGroupEntries,prefix2)=>prefix2?classGroupEntries.map(([classGroupId,classGroup])=>{const prefixedClassGroup=classGroup.map(classDefinition=>typeof classDefinition=="string"?prefix2+classDefinition:typeof classDefinition=="object"?Object.fromEntries(Object.entries(classDefinition).map(([key,value2])=>[prefix2+key,value2])):classDefinition);return[classGroupId,prefixedClassGroup]}):classGroupEntries,"getPrefixedClassGroupEntries"),createLruCache=__name(maxCacheSize=>{if(maxCacheSize<1)return{get:__name(()=>{},"get"),set:__name(()=>{},"set")};let cacheSize=0,cache=new Map,previousCache=new Map;const update2=__name((key,value2)=>{cache.set(key,value2),cacheSize++,cacheSize>maxCacheSize&&(cacheSize=0,previousCache=cache,cache=new Map)},"update");return{get(key){let value2=cache.get(key);if(value2!==void 0)return value2;if((value2=previousCache.get(key))!==void 0)return update2(key,value2),value2},set(key,value2){cache.has(key)?cache.set(key,value2):update2(key,value2)}}},"createLruCache"),IMPORTANT_MODIFIER="!",createParseClassName=__name(config2=>{const{separator,experimentalParseClassName}=config2,isSeparatorSingleCharacter=separator.length===1,firstSeparatorCharacter=separator[0],separatorLength=separator.length,parseClassName=__name(className=>{const modifiers=[];let bracketDepth=0,modifierStart=0,postfixModifierPosition;for(let index2=0;index2modifierStart?postfixModifierPosition-modifierStart:void 0;return{modifiers,hasImportantModifier,baseClassName,maybePostfixModifierPosition}},"parseClassName");return experimentalParseClassName?className=>experimentalParseClassName({className,parseClassName}):parseClassName},"createParseClassName"),sortModifiers=__name(modifiers=>{if(modifiers.length<=1)return modifiers;const sortedModifiers=[];let unsortedModifiers=[];return modifiers.forEach(modifier=>{modifier[0]==="["?(sortedModifiers.push(...unsortedModifiers.sort(),modifier),unsortedModifiers=[]):unsortedModifiers.push(modifier)}),sortedModifiers.push(...unsortedModifiers.sort()),sortedModifiers},"sortModifiers"),createConfigUtils=__name(config2=>({cache:createLruCache(config2.cacheSize),parseClassName:createParseClassName(config2),...createClassGroupUtils(config2)}),"createConfigUtils"),SPLIT_CLASSES_REGEX=/\s+/,mergeClassList=__name((classList,configUtils)=>{const{parseClassName,getClassGroupId,getConflictingClassGroupIds}=configUtils,classGroupsInConflict=[],classNames=classList.trim().split(SPLIT_CLASSES_REGEX);let result="";for(let index2=classNames.length-1;index2>=0;index2-=1){const originalClassName=classNames[index2],{modifiers,hasImportantModifier,baseClassName,maybePostfixModifierPosition}=parseClassName(originalClassName);let hasPostfixModifier=!!maybePostfixModifierPosition,classGroupId=getClassGroupId(hasPostfixModifier?baseClassName.substring(0,maybePostfixModifierPosition):baseClassName);if(!classGroupId){if(!hasPostfixModifier){result=originalClassName+(result.length>0?" "+result:result);continue}if(classGroupId=getClassGroupId(baseClassName),!classGroupId){result=originalClassName+(result.length>0?" "+result:result);continue}hasPostfixModifier=!1}const variantModifier=sortModifiers(modifiers).join(":"),modifierId=hasImportantModifier?variantModifier+IMPORTANT_MODIFIER:variantModifier,classId=modifierId+classGroupId;if(classGroupsInConflict.includes(classId))continue;classGroupsInConflict.push(classId);const conflictGroups=getConflictingClassGroupIds(classGroupId,hasPostfixModifier);for(let i2=0;i20?" "+result:result)}return result},"mergeClassList");function twJoin(){let index2=0,argument,resolvedValue,string2="";for(;index2{if(typeof mix=="string")return mix;let resolvedValue,string2="";for(let k2=0;k2createConfigCurrent(previousConfig),createConfigFirst());return configUtils=createConfigUtils(config2),cacheGet=configUtils.cache.get,cacheSet=configUtils.cache.set,functionToCall=tailwindMerge,tailwindMerge(classList)}__name(initTailwindMerge,"initTailwindMerge");function tailwindMerge(classList){const cachedResult=cacheGet(classList);if(cachedResult)return cachedResult;const result=mergeClassList(classList,configUtils);return cacheSet(classList,result),result}return __name(tailwindMerge,"tailwindMerge"),__name(function(){return functionToCall(twJoin.apply(null,arguments))},"callTailwindMerge")}__name(createTailwindMerge,"createTailwindMerge");const fromTheme=__name(key=>{const themeGetter=__name(theme=>theme[key]||[],"themeGetter");return themeGetter.isThemeGetter=!0,themeGetter},"fromTheme"),arbitraryValueRegex=/^\[(?:([a-z-]+):)?(.+)\]$/i,fractionRegex=/^\d+\/\d+$/,stringLengths=new Set(["px","full","screen"]),tshirtUnitRegex=/^(\d+(\.\d+)?)?(xs|sm|md|lg|xl)$/,lengthUnitRegex=/\d+(%|px|r?em|[sdl]?v([hwib]|min|max)|pt|pc|in|cm|mm|cap|ch|ex|r?lh|cq(w|h|i|b|min|max))|\b(calc|min|max|clamp)\(.+\)|^0$/,colorFunctionRegex=/^(rgba?|hsla?|hwb|(ok)?(lab|lch))\(.+\)$/,shadowRegex=/^(inset_)?-?((\d+)?\.?(\d+)[a-z]+|0)_-?((\d+)?\.?(\d+)[a-z]+|0)/,imageRegex=/^(url|image|image-set|cross-fade|element|(repeating-)?(linear|radial|conic)-gradient)\(.+\)$/,isLength=__name(value2=>isNumber$3(value2)||stringLengths.has(value2)||fractionRegex.test(value2),"isLength"),isArbitraryLength=__name(value2=>getIsArbitraryValue(value2,"length",isLengthOnly),"isArbitraryLength"),isNumber$3=__name(value2=>!!value2&&!Number.isNaN(Number(value2)),"isNumber$3"),isArbitraryNumber=__name(value2=>getIsArbitraryValue(value2,"number",isNumber$3),"isArbitraryNumber"),isInteger=__name(value2=>!!value2&&Number.isInteger(Number(value2)),"isInteger"),isPercent$1=__name(value2=>value2.endsWith("%")&&isNumber$3(value2.slice(0,-1)),"isPercent$1"),isArbitraryValue=__name(value2=>arbitraryValueRegex.test(value2),"isArbitraryValue"),isTshirtSize=__name(value2=>tshirtUnitRegex.test(value2),"isTshirtSize"),sizeLabels=new Set(["length","size","percentage"]),isArbitrarySize=__name(value2=>getIsArbitraryValue(value2,sizeLabels,isNever),"isArbitrarySize"),isArbitraryPosition=__name(value2=>getIsArbitraryValue(value2,"position",isNever),"isArbitraryPosition"),imageLabels=new Set(["image","url"]),isArbitraryImage=__name(value2=>getIsArbitraryValue(value2,imageLabels,isImage),"isArbitraryImage"),isArbitraryShadow=__name(value2=>getIsArbitraryValue(value2,"",isShadow),"isArbitraryShadow"),isAny=__name(()=>!0,"isAny"),getIsArbitraryValue=__name((value2,label,testValue)=>{const result=arbitraryValueRegex.exec(value2);return result?result[1]?typeof label=="string"?result[1]===label:label.has(result[1]):testValue(result[2]):!1},"getIsArbitraryValue"),isLengthOnly=__name(value2=>lengthUnitRegex.test(value2)&&!colorFunctionRegex.test(value2),"isLengthOnly"),isNever=__name(()=>!1,"isNever"),isShadow=__name(value2=>shadowRegex.test(value2),"isShadow"),isImage=__name(value2=>imageRegex.test(value2),"isImage"),getDefaultConfig=__name(()=>{const colors3=fromTheme("colors"),spacing=fromTheme("spacing"),blur=fromTheme("blur"),brightness=fromTheme("brightness"),borderColor=fromTheme("borderColor"),borderRadius=fromTheme("borderRadius"),borderSpacing=fromTheme("borderSpacing"),borderWidth=fromTheme("borderWidth"),contrast=fromTheme("contrast"),grayscale=fromTheme("grayscale"),hueRotate=fromTheme("hueRotate"),invert=fromTheme("invert"),gap=fromTheme("gap"),gradientColorStops=fromTheme("gradientColorStops"),gradientColorStopPositions=fromTheme("gradientColorStopPositions"),inset=fromTheme("inset"),margin=fromTheme("margin"),opacity=fromTheme("opacity"),padding=fromTheme("padding"),saturate=fromTheme("saturate"),scale=fromTheme("scale"),sepia=fromTheme("sepia"),skew=fromTheme("skew"),space2=fromTheme("space"),translate=fromTheme("translate"),getOverscroll=__name(()=>["auto","contain","none"],"getOverscroll"),getOverflow=__name(()=>["auto","hidden","clip","visible","scroll"],"getOverflow"),getSpacingWithAutoAndArbitrary=__name(()=>["auto",isArbitraryValue,spacing],"getSpacingWithAutoAndArbitrary"),getSpacingWithArbitrary=__name(()=>[isArbitraryValue,spacing],"getSpacingWithArbitrary"),getLengthWithEmptyAndArbitrary=__name(()=>["",isLength,isArbitraryLength],"getLengthWithEmptyAndArbitrary"),getNumberWithAutoAndArbitrary=__name(()=>["auto",isNumber$3,isArbitraryValue],"getNumberWithAutoAndArbitrary"),getPositions=__name(()=>["bottom","center","left","left-bottom","left-top","right","right-bottom","right-top","top"],"getPositions"),getLineStyles=__name(()=>["solid","dashed","dotted","double","none"],"getLineStyles"),getBlendModes=__name(()=>["normal","multiply","screen","overlay","darken","lighten","color-dodge","color-burn","hard-light","soft-light","difference","exclusion","hue","saturation","color","luminosity"],"getBlendModes"),getAlign=__name(()=>["start","end","center","between","around","evenly","stretch"],"getAlign"),getZeroAndEmpty=__name(()=>["","0",isArbitraryValue],"getZeroAndEmpty"),getBreaks=__name(()=>["auto","avoid","all","avoid-page","page","left","right","column"],"getBreaks"),getNumberAndArbitrary=__name(()=>[isNumber$3,isArbitraryValue],"getNumberAndArbitrary");return{cacheSize:500,separator:":",theme:{colors:[isAny],spacing:[isLength,isArbitraryLength],blur:["none","",isTshirtSize,isArbitraryValue],brightness:getNumberAndArbitrary(),borderColor:[colors3],borderRadius:["none","","full",isTshirtSize,isArbitraryValue],borderSpacing:getSpacingWithArbitrary(),borderWidth:getLengthWithEmptyAndArbitrary(),contrast:getNumberAndArbitrary(),grayscale:getZeroAndEmpty(),hueRotate:getNumberAndArbitrary(),invert:getZeroAndEmpty(),gap:getSpacingWithArbitrary(),gradientColorStops:[colors3],gradientColorStopPositions:[isPercent$1,isArbitraryLength],inset:getSpacingWithAutoAndArbitrary(),margin:getSpacingWithAutoAndArbitrary(),opacity:getNumberAndArbitrary(),padding:getSpacingWithArbitrary(),saturate:getNumberAndArbitrary(),scale:getNumberAndArbitrary(),sepia:getZeroAndEmpty(),skew:getNumberAndArbitrary(),space:getSpacingWithArbitrary(),translate:getSpacingWithArbitrary()},classGroups:{aspect:[{aspect:["auto","square","video",isArbitraryValue]}],container:["container"],columns:[{columns:[isTshirtSize]}],"break-after":[{"break-after":getBreaks()}],"break-before":[{"break-before":getBreaks()}],"break-inside":[{"break-inside":["auto","avoid","avoid-page","avoid-column"]}],"box-decoration":[{"box-decoration":["slice","clone"]}],box:[{box:["border","content"]}],display:["block","inline-block","inline","flex","inline-flex","table","inline-table","table-caption","table-cell","table-column","table-column-group","table-footer-group","table-header-group","table-row-group","table-row","flow-root","grid","inline-grid","contents","list-item","hidden"],float:[{float:["right","left","none","start","end"]}],clear:[{clear:["left","right","both","none","start","end"]}],isolation:["isolate","isolation-auto"],"object-fit":[{object:["contain","cover","fill","none","scale-down"]}],"object-position":[{object:[...getPositions(),isArbitraryValue]}],overflow:[{overflow:getOverflow()}],"overflow-x":[{"overflow-x":getOverflow()}],"overflow-y":[{"overflow-y":getOverflow()}],overscroll:[{overscroll:getOverscroll()}],"overscroll-x":[{"overscroll-x":getOverscroll()}],"overscroll-y":[{"overscroll-y":getOverscroll()}],position:["static","fixed","absolute","relative","sticky"],inset:[{inset:[inset]}],"inset-x":[{"inset-x":[inset]}],"inset-y":[{"inset-y":[inset]}],start:[{start:[inset]}],end:[{end:[inset]}],top:[{top:[inset]}],right:[{right:[inset]}],bottom:[{bottom:[inset]}],left:[{left:[inset]}],visibility:["visible","invisible","collapse"],z:[{z:["auto",isInteger,isArbitraryValue]}],basis:[{basis:getSpacingWithAutoAndArbitrary()}],"flex-direction":[{flex:["row","row-reverse","col","col-reverse"]}],"flex-wrap":[{flex:["wrap","wrap-reverse","nowrap"]}],flex:[{flex:["1","auto","initial","none",isArbitraryValue]}],grow:[{grow:getZeroAndEmpty()}],shrink:[{shrink:getZeroAndEmpty()}],order:[{order:["first","last","none",isInteger,isArbitraryValue]}],"grid-cols":[{"grid-cols":[isAny]}],"col-start-end":[{col:["auto",{span:["full",isInteger,isArbitraryValue]},isArbitraryValue]}],"col-start":[{"col-start":getNumberWithAutoAndArbitrary()}],"col-end":[{"col-end":getNumberWithAutoAndArbitrary()}],"grid-rows":[{"grid-rows":[isAny]}],"row-start-end":[{row:["auto",{span:[isInteger,isArbitraryValue]},isArbitraryValue]}],"row-start":[{"row-start":getNumberWithAutoAndArbitrary()}],"row-end":[{"row-end":getNumberWithAutoAndArbitrary()}],"grid-flow":[{"grid-flow":["row","col","dense","row-dense","col-dense"]}],"auto-cols":[{"auto-cols":["auto","min","max","fr",isArbitraryValue]}],"auto-rows":[{"auto-rows":["auto","min","max","fr",isArbitraryValue]}],gap:[{gap:[gap]}],"gap-x":[{"gap-x":[gap]}],"gap-y":[{"gap-y":[gap]}],"justify-content":[{justify:["normal",...getAlign()]}],"justify-items":[{"justify-items":["start","end","center","stretch"]}],"justify-self":[{"justify-self":["auto","start","end","center","stretch"]}],"align-content":[{content:["normal",...getAlign(),"baseline"]}],"align-items":[{items:["start","end","center","baseline","stretch"]}],"align-self":[{self:["auto","start","end","center","stretch","baseline"]}],"place-content":[{"place-content":[...getAlign(),"baseline"]}],"place-items":[{"place-items":["start","end","center","baseline","stretch"]}],"place-self":[{"place-self":["auto","start","end","center","stretch"]}],p:[{p:[padding]}],px:[{px:[padding]}],py:[{py:[padding]}],ps:[{ps:[padding]}],pe:[{pe:[padding]}],pt:[{pt:[padding]}],pr:[{pr:[padding]}],pb:[{pb:[padding]}],pl:[{pl:[padding]}],m:[{m:[margin]}],mx:[{mx:[margin]}],my:[{my:[margin]}],ms:[{ms:[margin]}],me:[{me:[margin]}],mt:[{mt:[margin]}],mr:[{mr:[margin]}],mb:[{mb:[margin]}],ml:[{ml:[margin]}],"space-x":[{"space-x":[space2]}],"space-x-reverse":["space-x-reverse"],"space-y":[{"space-y":[space2]}],"space-y-reverse":["space-y-reverse"],w:[{w:["auto","min","max","fit","svw","lvw","dvw",isArbitraryValue,spacing]}],"min-w":[{"min-w":[isArbitraryValue,spacing,"min","max","fit"]}],"max-w":[{"max-w":[isArbitraryValue,spacing,"none","full","min","max","fit","prose",{screen:[isTshirtSize]},isTshirtSize]}],h:[{h:[isArbitraryValue,spacing,"auto","min","max","fit","svh","lvh","dvh"]}],"min-h":[{"min-h":[isArbitraryValue,spacing,"min","max","fit","svh","lvh","dvh"]}],"max-h":[{"max-h":[isArbitraryValue,spacing,"min","max","fit","svh","lvh","dvh"]}],size:[{size:[isArbitraryValue,spacing,"auto","min","max","fit"]}],"font-size":[{text:["base",isTshirtSize,isArbitraryLength]}],"font-smoothing":["antialiased","subpixel-antialiased"],"font-style":["italic","not-italic"],"font-weight":[{font:["thin","extralight","light","normal","medium","semibold","bold","extrabold","black",isArbitraryNumber]}],"font-family":[{font:[isAny]}],"fvn-normal":["normal-nums"],"fvn-ordinal":["ordinal"],"fvn-slashed-zero":["slashed-zero"],"fvn-figure":["lining-nums","oldstyle-nums"],"fvn-spacing":["proportional-nums","tabular-nums"],"fvn-fraction":["diagonal-fractions","stacked-fractions"],tracking:[{tracking:["tighter","tight","normal","wide","wider","widest",isArbitraryValue]}],"line-clamp":[{"line-clamp":["none",isNumber$3,isArbitraryNumber]}],leading:[{leading:["none","tight","snug","normal","relaxed","loose",isLength,isArbitraryValue]}],"list-image":[{"list-image":["none",isArbitraryValue]}],"list-style-type":[{list:["none","disc","decimal",isArbitraryValue]}],"list-style-position":[{list:["inside","outside"]}],"placeholder-color":[{placeholder:[colors3]}],"placeholder-opacity":[{"placeholder-opacity":[opacity]}],"text-alignment":[{text:["left","center","right","justify","start","end"]}],"text-color":[{text:[colors3]}],"text-opacity":[{"text-opacity":[opacity]}],"text-decoration":["underline","overline","line-through","no-underline"],"text-decoration-style":[{decoration:[...getLineStyles(),"wavy"]}],"text-decoration-thickness":[{decoration:["auto","from-font",isLength,isArbitraryLength]}],"underline-offset":[{"underline-offset":["auto",isLength,isArbitraryValue]}],"text-decoration-color":[{decoration:[colors3]}],"text-transform":["uppercase","lowercase","capitalize","normal-case"],"text-overflow":["truncate","text-ellipsis","text-clip"],"text-wrap":[{text:["wrap","nowrap","balance","pretty"]}],indent:[{indent:getSpacingWithArbitrary()}],"vertical-align":[{align:["baseline","top","middle","bottom","text-top","text-bottom","sub","super",isArbitraryValue]}],whitespace:[{whitespace:["normal","nowrap","pre","pre-line","pre-wrap","break-spaces"]}],break:[{break:["normal","words","all","keep"]}],hyphens:[{hyphens:["none","manual","auto"]}],content:[{content:["none",isArbitraryValue]}],"bg-attachment":[{bg:["fixed","local","scroll"]}],"bg-clip":[{"bg-clip":["border","padding","content","text"]}],"bg-opacity":[{"bg-opacity":[opacity]}],"bg-origin":[{"bg-origin":["border","padding","content"]}],"bg-position":[{bg:[...getPositions(),isArbitraryPosition]}],"bg-repeat":[{bg:["no-repeat",{repeat:["","x","y","round","space"]}]}],"bg-size":[{bg:["auto","cover","contain",isArbitrarySize]}],"bg-image":[{bg:["none",{"gradient-to":["t","tr","r","br","b","bl","l","tl"]},isArbitraryImage]}],"bg-color":[{bg:[colors3]}],"gradient-from-pos":[{from:[gradientColorStopPositions]}],"gradient-via-pos":[{via:[gradientColorStopPositions]}],"gradient-to-pos":[{to:[gradientColorStopPositions]}],"gradient-from":[{from:[gradientColorStops]}],"gradient-via":[{via:[gradientColorStops]}],"gradient-to":[{to:[gradientColorStops]}],rounded:[{rounded:[borderRadius]}],"rounded-s":[{"rounded-s":[borderRadius]}],"rounded-e":[{"rounded-e":[borderRadius]}],"rounded-t":[{"rounded-t":[borderRadius]}],"rounded-r":[{"rounded-r":[borderRadius]}],"rounded-b":[{"rounded-b":[borderRadius]}],"rounded-l":[{"rounded-l":[borderRadius]}],"rounded-ss":[{"rounded-ss":[borderRadius]}],"rounded-se":[{"rounded-se":[borderRadius]}],"rounded-ee":[{"rounded-ee":[borderRadius]}],"rounded-es":[{"rounded-es":[borderRadius]}],"rounded-tl":[{"rounded-tl":[borderRadius]}],"rounded-tr":[{"rounded-tr":[borderRadius]}],"rounded-br":[{"rounded-br":[borderRadius]}],"rounded-bl":[{"rounded-bl":[borderRadius]}],"border-w":[{border:[borderWidth]}],"border-w-x":[{"border-x":[borderWidth]}],"border-w-y":[{"border-y":[borderWidth]}],"border-w-s":[{"border-s":[borderWidth]}],"border-w-e":[{"border-e":[borderWidth]}],"border-w-t":[{"border-t":[borderWidth]}],"border-w-r":[{"border-r":[borderWidth]}],"border-w-b":[{"border-b":[borderWidth]}],"border-w-l":[{"border-l":[borderWidth]}],"border-opacity":[{"border-opacity":[opacity]}],"border-style":[{border:[...getLineStyles(),"hidden"]}],"divide-x":[{"divide-x":[borderWidth]}],"divide-x-reverse":["divide-x-reverse"],"divide-y":[{"divide-y":[borderWidth]}],"divide-y-reverse":["divide-y-reverse"],"divide-opacity":[{"divide-opacity":[opacity]}],"divide-style":[{divide:getLineStyles()}],"border-color":[{border:[borderColor]}],"border-color-x":[{"border-x":[borderColor]}],"border-color-y":[{"border-y":[borderColor]}],"border-color-s":[{"border-s":[borderColor]}],"border-color-e":[{"border-e":[borderColor]}],"border-color-t":[{"border-t":[borderColor]}],"border-color-r":[{"border-r":[borderColor]}],"border-color-b":[{"border-b":[borderColor]}],"border-color-l":[{"border-l":[borderColor]}],"divide-color":[{divide:[borderColor]}],"outline-style":[{outline:["",...getLineStyles()]}],"outline-offset":[{"outline-offset":[isLength,isArbitraryValue]}],"outline-w":[{outline:[isLength,isArbitraryLength]}],"outline-color":[{outline:[colors3]}],"ring-w":[{ring:getLengthWithEmptyAndArbitrary()}],"ring-w-inset":["ring-inset"],"ring-color":[{ring:[colors3]}],"ring-opacity":[{"ring-opacity":[opacity]}],"ring-offset-w":[{"ring-offset":[isLength,isArbitraryLength]}],"ring-offset-color":[{"ring-offset":[colors3]}],shadow:[{shadow:["","inner","none",isTshirtSize,isArbitraryShadow]}],"shadow-color":[{shadow:[isAny]}],opacity:[{opacity:[opacity]}],"mix-blend":[{"mix-blend":[...getBlendModes(),"plus-lighter","plus-darker"]}],"bg-blend":[{"bg-blend":getBlendModes()}],filter:[{filter:["","none"]}],blur:[{blur:[blur]}],brightness:[{brightness:[brightness]}],contrast:[{contrast:[contrast]}],"drop-shadow":[{"drop-shadow":["","none",isTshirtSize,isArbitraryValue]}],grayscale:[{grayscale:[grayscale]}],"hue-rotate":[{"hue-rotate":[hueRotate]}],invert:[{invert:[invert]}],saturate:[{saturate:[saturate]}],sepia:[{sepia:[sepia]}],"backdrop-filter":[{"backdrop-filter":["","none"]}],"backdrop-blur":[{"backdrop-blur":[blur]}],"backdrop-brightness":[{"backdrop-brightness":[brightness]}],"backdrop-contrast":[{"backdrop-contrast":[contrast]}],"backdrop-grayscale":[{"backdrop-grayscale":[grayscale]}],"backdrop-hue-rotate":[{"backdrop-hue-rotate":[hueRotate]}],"backdrop-invert":[{"backdrop-invert":[invert]}],"backdrop-opacity":[{"backdrop-opacity":[opacity]}],"backdrop-saturate":[{"backdrop-saturate":[saturate]}],"backdrop-sepia":[{"backdrop-sepia":[sepia]}],"border-collapse":[{border:["collapse","separate"]}],"border-spacing":[{"border-spacing":[borderSpacing]}],"border-spacing-x":[{"border-spacing-x":[borderSpacing]}],"border-spacing-y":[{"border-spacing-y":[borderSpacing]}],"table-layout":[{table:["auto","fixed"]}],caption:[{caption:["top","bottom"]}],transition:[{transition:["none","all","","colors","opacity","shadow","transform",isArbitraryValue]}],duration:[{duration:getNumberAndArbitrary()}],ease:[{ease:["linear","in","out","in-out",isArbitraryValue]}],delay:[{delay:getNumberAndArbitrary()}],animate:[{animate:["none","spin","ping","pulse","bounce",isArbitraryValue]}],transform:[{transform:["","gpu","none"]}],scale:[{scale:[scale]}],"scale-x":[{"scale-x":[scale]}],"scale-y":[{"scale-y":[scale]}],rotate:[{rotate:[isInteger,isArbitraryValue]}],"translate-x":[{"translate-x":[translate]}],"translate-y":[{"translate-y":[translate]}],"skew-x":[{"skew-x":[skew]}],"skew-y":[{"skew-y":[skew]}],"transform-origin":[{origin:["center","top","top-right","right","bottom-right","bottom","bottom-left","left","top-left",isArbitraryValue]}],accent:[{accent:["auto",colors3]}],appearance:[{appearance:["none","auto"]}],cursor:[{cursor:["auto","default","pointer","wait","text","move","help","not-allowed","none","context-menu","progress","cell","crosshair","vertical-text","alias","copy","no-drop","grab","grabbing","all-scroll","col-resize","row-resize","n-resize","e-resize","s-resize","w-resize","ne-resize","nw-resize","se-resize","sw-resize","ew-resize","ns-resize","nesw-resize","nwse-resize","zoom-in","zoom-out",isArbitraryValue]}],"caret-color":[{caret:[colors3]}],"pointer-events":[{"pointer-events":["none","auto"]}],resize:[{resize:["none","y","x",""]}],"scroll-behavior":[{scroll:["auto","smooth"]}],"scroll-m":[{"scroll-m":getSpacingWithArbitrary()}],"scroll-mx":[{"scroll-mx":getSpacingWithArbitrary()}],"scroll-my":[{"scroll-my":getSpacingWithArbitrary()}],"scroll-ms":[{"scroll-ms":getSpacingWithArbitrary()}],"scroll-me":[{"scroll-me":getSpacingWithArbitrary()}],"scroll-mt":[{"scroll-mt":getSpacingWithArbitrary()}],"scroll-mr":[{"scroll-mr":getSpacingWithArbitrary()}],"scroll-mb":[{"scroll-mb":getSpacingWithArbitrary()}],"scroll-ml":[{"scroll-ml":getSpacingWithArbitrary()}],"scroll-p":[{"scroll-p":getSpacingWithArbitrary()}],"scroll-px":[{"scroll-px":getSpacingWithArbitrary()}],"scroll-py":[{"scroll-py":getSpacingWithArbitrary()}],"scroll-ps":[{"scroll-ps":getSpacingWithArbitrary()}],"scroll-pe":[{"scroll-pe":getSpacingWithArbitrary()}],"scroll-pt":[{"scroll-pt":getSpacingWithArbitrary()}],"scroll-pr":[{"scroll-pr":getSpacingWithArbitrary()}],"scroll-pb":[{"scroll-pb":getSpacingWithArbitrary()}],"scroll-pl":[{"scroll-pl":getSpacingWithArbitrary()}],"snap-align":[{snap:["start","end","center","align-none"]}],"snap-stop":[{snap:["normal","always"]}],"snap-type":[{snap:["none","x","y","both"]}],"snap-strictness":[{snap:["mandatory","proximity"]}],touch:[{touch:["auto","none","manipulation"]}],"touch-x":[{"touch-pan":["x","left","right"]}],"touch-y":[{"touch-pan":["y","up","down"]}],"touch-pz":["touch-pinch-zoom"],select:[{select:["none","text","all","auto"]}],"will-change":[{"will-change":["auto","scroll","contents","transform",isArbitraryValue]}],fill:[{fill:[colors3,"none"]}],"stroke-w":[{stroke:[isLength,isArbitraryLength,isArbitraryNumber]}],stroke:[{stroke:[colors3,"none"]}],sr:["sr-only","not-sr-only"],"forced-color-adjust":[{"forced-color-adjust":["auto","none"]}]},conflictingClassGroups:{overflow:["overflow-x","overflow-y"],overscroll:["overscroll-x","overscroll-y"],inset:["inset-x","inset-y","start","end","top","right","bottom","left"],"inset-x":["right","left"],"inset-y":["top","bottom"],flex:["basis","grow","shrink"],gap:["gap-x","gap-y"],p:["px","py","ps","pe","pt","pr","pb","pl"],px:["pr","pl"],py:["pt","pb"],m:["mx","my","ms","me","mt","mr","mb","ml"],mx:["mr","ml"],my:["mt","mb"],size:["w","h"],"font-size":["leading"],"fvn-normal":["fvn-ordinal","fvn-slashed-zero","fvn-figure","fvn-spacing","fvn-fraction"],"fvn-ordinal":["fvn-normal"],"fvn-slashed-zero":["fvn-normal"],"fvn-figure":["fvn-normal"],"fvn-spacing":["fvn-normal"],"fvn-fraction":["fvn-normal"],"line-clamp":["display","overflow"],rounded:["rounded-s","rounded-e","rounded-t","rounded-r","rounded-b","rounded-l","rounded-ss","rounded-se","rounded-ee","rounded-es","rounded-tl","rounded-tr","rounded-br","rounded-bl"],"rounded-s":["rounded-ss","rounded-es"],"rounded-e":["rounded-se","rounded-ee"],"rounded-t":["rounded-tl","rounded-tr"],"rounded-r":["rounded-tr","rounded-br"],"rounded-b":["rounded-br","rounded-bl"],"rounded-l":["rounded-tl","rounded-bl"],"border-spacing":["border-spacing-x","border-spacing-y"],"border-w":["border-w-s","border-w-e","border-w-t","border-w-r","border-w-b","border-w-l"],"border-w-x":["border-w-r","border-w-l"],"border-w-y":["border-w-t","border-w-b"],"border-color":["border-color-s","border-color-e","border-color-t","border-color-r","border-color-b","border-color-l"],"border-color-x":["border-color-r","border-color-l"],"border-color-y":["border-color-t","border-color-b"],"scroll-m":["scroll-mx","scroll-my","scroll-ms","scroll-me","scroll-mt","scroll-mr","scroll-mb","scroll-ml"],"scroll-mx":["scroll-mr","scroll-ml"],"scroll-my":["scroll-mt","scroll-mb"],"scroll-p":["scroll-px","scroll-py","scroll-ps","scroll-pe","scroll-pt","scroll-pr","scroll-pb","scroll-pl"],"scroll-px":["scroll-pr","scroll-pl"],"scroll-py":["scroll-pt","scroll-pb"],touch:["touch-x","touch-y","touch-pz"],"touch-x":["touch"],"touch-y":["touch"],"touch-pz":["touch"]},conflictingClassGroupModifiers:{"font-size":["leading"]}}},"getDefaultConfig"),twMerge=createTailwindMerge(getDefaultConfig);function cn$2(...inputs){return twMerge(clsx(inputs))}__name(cn$2,"cn$2");function composeEventHandlers(originalEventHandler,ourEventHandler,{checkForDefaultPrevented=!0}={}){return __name(function(event){if(originalEventHandler?.(event),checkForDefaultPrevented===!1||!event.defaultPrevented)return ourEventHandler?.(event)},"handleEvent")}__name(composeEventHandlers,"composeEventHandlers");function setRef(ref,value2){if(typeof ref=="function")return ref(value2);ref!=null&&(ref.current=value2)}__name(setRef,"setRef");function composeRefs(...refs){return node2=>{let hasCleanup=!1;const cleanups=refs.map(ref=>{const cleanup=setRef(ref,node2);return!hasCleanup&&typeof cleanup=="function"&&(hasCleanup=!0),cleanup});if(hasCleanup)return()=>{for(let i2=0;i2{const{children:children2,...context}=props,value2=reactExports.useMemo(()=>context,Object.values(context));return jsxRuntimeExports.jsx(Context.Provider,{value:value2,children:children2})},"Provider");Provider2.displayName=rootComponentName+"Provider";function useContext2(consumerName){const context=reactExports.useContext(Context);if(context)return context;if(defaultContext!==void 0)return defaultContext;throw new Error(`\`${consumerName}\` must be used within \`${rootComponentName}\``)}return __name(useContext2,"useContext2"),[Provider2,useContext2]}__name(createContext2,"createContext2");function createContextScope$1(scopeName,createContextScopeDeps=[]){let defaultContexts=[];function createContext3(rootComponentName,defaultContext){const BaseContext=reactExports.createContext(defaultContext),index2=defaultContexts.length;defaultContexts=[...defaultContexts,defaultContext];const Provider2=__name(props=>{const{scope,children:children2,...context}=props,Context=scope?.[scopeName]?.[index2]||BaseContext,value2=reactExports.useMemo(()=>context,Object.values(context));return jsxRuntimeExports.jsx(Context.Provider,{value:value2,children:children2})},"Provider");Provider2.displayName=rootComponentName+"Provider";function useContext2(consumerName,scope){const Context=scope?.[scopeName]?.[index2]||BaseContext,context=reactExports.useContext(Context);if(context)return context;if(defaultContext!==void 0)return defaultContext;throw new Error(`\`${consumerName}\` must be used within \`${rootComponentName}\``)}return __name(useContext2,"useContext2"),[Provider2,useContext2]}__name(createContext3,"createContext3");const createScope=__name(()=>{const scopeContexts=defaultContexts.map(defaultContext=>reactExports.createContext(defaultContext));return __name(function(scope){const contexts=scope?.[scopeName]||scopeContexts;return reactExports.useMemo(()=>({[`__scope${scopeName}`]:{...scope,[scopeName]:contexts}}),[scope,contexts])},"useScope")},"createScope");return createScope.scopeName=scopeName,[createContext3,composeContextScopes$1(createScope,...createContextScopeDeps)]}__name(createContextScope$1,"createContextScope$1");function composeContextScopes$1(...scopes){const baseScope=scopes[0];if(scopes.length===1)return baseScope;const createScope=__name(()=>{const scopeHooks=scopes.map(createScope2=>({useScope:createScope2(),scopeName:createScope2.scopeName}));return __name(function(overrideScopes){const nextScopes=scopeHooks.reduce((nextScopes2,{useScope,scopeName})=>{const currentScope=useScope(overrideScopes)[`__scope${scopeName}`];return{...nextScopes2,...currentScope}},{});return reactExports.useMemo(()=>({[`__scope${baseScope.scopeName}`]:nextScopes}),[nextScopes])},"useComposedScopes")},"createScope");return createScope.scopeName=baseScope.scopeName,createScope}__name(composeContextScopes$1,"composeContextScopes$1");var useLayoutEffect2=globalThis?.document?reactExports.useLayoutEffect:()=>{},useReactId=React$1[" useId ".trim().toString()]||(()=>{}),count$2=0;function useId(deterministicId){const[id,setId]=reactExports.useState(useReactId());return useLayoutEffect2(()=>{setId(reactId=>reactId??String(count$2++))},[deterministicId]),id?`radix-${id}`:""}__name(useId,"useId");var useInsertionEffect=React$1[" useInsertionEffect ".trim().toString()]||useLayoutEffect2;function useControllableState({prop,defaultProp,onChange=__name(()=>{},"onChange"),caller}){const[uncontrolledProp,setUncontrolledProp,onChangeRef]=useUncontrolledState({defaultProp,onChange}),isControlled=prop!==void 0,value2=isControlled?prop:uncontrolledProp;{const isControlledRef=reactExports.useRef(prop!==void 0);reactExports.useEffect(()=>{const wasControlled=isControlledRef.current;wasControlled!==isControlled&&console.warn(`${caller} is changing from ${wasControlled?"controlled":"uncontrolled"} to ${isControlled?"controlled":"uncontrolled"}. Components should not switch from controlled to uncontrolled (or vice versa). Decide between using a controlled or uncontrolled value for the lifetime of the component.`),isControlledRef.current=isControlled},[isControlled,caller])}const setValue=reactExports.useCallback(nextValue=>{if(isControlled){const value22=isFunction$1(nextValue)?nextValue(prop):nextValue;value22!==prop&&onChangeRef.current?.(value22)}else setUncontrolledProp(nextValue)},[isControlled,prop,setUncontrolledProp,onChangeRef]);return[value2,setValue]}__name(useControllableState,"useControllableState");function useUncontrolledState({defaultProp,onChange}){const[value2,setValue]=reactExports.useState(defaultProp),prevValueRef=reactExports.useRef(value2),onChangeRef=reactExports.useRef(onChange);return useInsertionEffect(()=>{onChangeRef.current=onChange},[onChange]),reactExports.useEffect(()=>{prevValueRef.current!==value2&&(onChangeRef.current?.(value2),prevValueRef.current=value2)},[value2,prevValueRef]),[value2,setValue,onChangeRef]}__name(useUncontrolledState,"useUncontrolledState");function isFunction$1(value2){return typeof value2=="function"}__name(isFunction$1,"isFunction$1");function createSlot$4(ownerName){const SlotClone=createSlotClone$4(ownerName),Slot2=reactExports.forwardRef((props,forwardedRef)=>{const{children:children2,...slotProps}=props,childrenArray=reactExports.Children.toArray(children2),slottable=childrenArray.find(isSlottable$4);if(slottable){const newElement=slottable.props.children,newChildren=childrenArray.map(child=>child===slottable?reactExports.Children.count(newElement)>1?reactExports.Children.only(null):reactExports.isValidElement(newElement)?newElement.props.children:null:child);return jsxRuntimeExports.jsx(SlotClone,{...slotProps,ref:forwardedRef,children:reactExports.isValidElement(newElement)?reactExports.cloneElement(newElement,void 0,newChildren):null})}return jsxRuntimeExports.jsx(SlotClone,{...slotProps,ref:forwardedRef,children:children2})});return Slot2.displayName=`${ownerName}.Slot`,Slot2}__name(createSlot$4,"createSlot$4");function createSlotClone$4(ownerName){const SlotClone=reactExports.forwardRef((props,forwardedRef)=>{const{children:children2,...slotProps}=props;if(reactExports.isValidElement(children2)){const childrenRef=getElementRef$5(children2),props2=mergeProps$4(slotProps,children2.props);return children2.type!==reactExports.Fragment&&(props2.ref=forwardedRef?composeRefs(forwardedRef,childrenRef):childrenRef),reactExports.cloneElement(children2,props2)}return reactExports.Children.count(children2)>1?reactExports.Children.only(null):null});return SlotClone.displayName=`${ownerName}.SlotClone`,SlotClone}__name(createSlotClone$4,"createSlotClone$4");var SLOTTABLE_IDENTIFIER$5=Symbol("radix.slottable");function isSlottable$4(child){return reactExports.isValidElement(child)&&typeof child.type=="function"&&"__radixId"in child.type&&child.type.__radixId===SLOTTABLE_IDENTIFIER$5}__name(isSlottable$4,"isSlottable$4");function mergeProps$4(slotProps,childProps){const overrideProps={...childProps};for(const propName in childProps){const slotPropValue=slotProps[propName],childPropValue=childProps[propName];/^on[A-Z]/.test(propName)?slotPropValue&&childPropValue?overrideProps[propName]=(...args)=>{const result=childPropValue(...args);return slotPropValue(...args),result}:slotPropValue&&(overrideProps[propName]=slotPropValue):propName==="style"?overrideProps[propName]={...slotPropValue,...childPropValue}:propName==="className"&&(overrideProps[propName]=[slotPropValue,childPropValue].filter(Boolean).join(" "))}return{...slotProps,...overrideProps}}__name(mergeProps$4,"mergeProps$4");function getElementRef$5(element2){let getter=Object.getOwnPropertyDescriptor(element2.props,"ref")?.get,mayWarn=getter&&"isReactWarning"in getter&&getter.isReactWarning;return mayWarn?element2.ref:(getter=Object.getOwnPropertyDescriptor(element2,"ref")?.get,mayWarn=getter&&"isReactWarning"in getter&&getter.isReactWarning,mayWarn?element2.props.ref:element2.props.ref||element2.ref)}__name(getElementRef$5,"getElementRef$5");var NODES$2=["a","button","div","form","h2","h3","img","input","label","li","nav","ol","p","select","span","svg","ul"],Primitive$2=NODES$2.reduce((primitive,node2)=>{const Slot2=createSlot$4(`Primitive.${node2}`),Node2=reactExports.forwardRef((props,forwardedRef)=>{const{asChild,...primitiveProps}=props,Comp=asChild?Slot2:node2;return typeof window<"u"&&(window[Symbol.for("radix-ui")]=!0),jsxRuntimeExports.jsx(Comp,{...primitiveProps,ref:forwardedRef})});return Node2.displayName=`Primitive.${node2}`,{...primitive,[node2]:Node2}},{});function dispatchDiscreteCustomEvent(target,event){target&&reactDomExports.flushSync(()=>target.dispatchEvent(event))}__name(dispatchDiscreteCustomEvent,"dispatchDiscreteCustomEvent");function useCallbackRef$1(callback){const callbackRef=reactExports.useRef(callback);return reactExports.useEffect(()=>{callbackRef.current=callback}),reactExports.useMemo(()=>(...args)=>callbackRef.current?.(...args),[])}__name(useCallbackRef$1,"useCallbackRef$1");function useEscapeKeydown(onEscapeKeyDownProp,ownerDocument=globalThis?.document){const onEscapeKeyDown=useCallbackRef$1(onEscapeKeyDownProp);reactExports.useEffect(()=>{const handleKeyDown=__name(event=>{event.key==="Escape"&&onEscapeKeyDown(event)},"handleKeyDown");return ownerDocument.addEventListener("keydown",handleKeyDown,{capture:!0}),()=>ownerDocument.removeEventListener("keydown",handleKeyDown,{capture:!0})},[onEscapeKeyDown,ownerDocument])}__name(useEscapeKeydown,"useEscapeKeydown");var DISMISSABLE_LAYER_NAME="DismissableLayer",CONTEXT_UPDATE="dismissableLayer.update",POINTER_DOWN_OUTSIDE="dismissableLayer.pointerDownOutside",FOCUS_OUTSIDE="dismissableLayer.focusOutside",originalBodyPointerEvents,DismissableLayerContext=reactExports.createContext({layers:new Set,layersWithOutsidePointerEventsDisabled:new Set,branches:new Set}),DismissableLayer=reactExports.forwardRef((props,forwardedRef)=>{const{disableOutsidePointerEvents=!1,onEscapeKeyDown,onPointerDownOutside,onFocusOutside,onInteractOutside,onDismiss,...layerProps}=props,context=reactExports.useContext(DismissableLayerContext),[node2,setNode]=reactExports.useState(null),ownerDocument=node2?.ownerDocument??globalThis?.document,[,force]=reactExports.useState({}),composedRefs=useComposedRefs(forwardedRef,node22=>setNode(node22)),layers=Array.from(context.layers),[highestLayerWithOutsidePointerEventsDisabled]=[...context.layersWithOutsidePointerEventsDisabled].slice(-1),highestLayerWithOutsidePointerEventsDisabledIndex=layers.indexOf(highestLayerWithOutsidePointerEventsDisabled),index2=node2?layers.indexOf(node2):-1,isBodyPointerEventsDisabled=context.layersWithOutsidePointerEventsDisabled.size>0,isPointerEventsEnabled=index2>=highestLayerWithOutsidePointerEventsDisabledIndex,pointerDownOutside=usePointerDownOutside(event=>{const target=event.target,isPointerDownOnBranch=[...context.branches].some(branch=>branch.contains(target));!isPointerEventsEnabled||isPointerDownOnBranch||(onPointerDownOutside?.(event),onInteractOutside?.(event),event.defaultPrevented||onDismiss?.())},ownerDocument),focusOutside=useFocusOutside(event=>{const target=event.target;[...context.branches].some(branch=>branch.contains(target))||(onFocusOutside?.(event),onInteractOutside?.(event),event.defaultPrevented||onDismiss?.())},ownerDocument);return useEscapeKeydown(event=>{index2===context.layers.size-1&&(onEscapeKeyDown?.(event),!event.defaultPrevented&&onDismiss&&(event.preventDefault(),onDismiss()))},ownerDocument),reactExports.useEffect(()=>{if(node2)return disableOutsidePointerEvents&&(context.layersWithOutsidePointerEventsDisabled.size===0&&(originalBodyPointerEvents=ownerDocument.body.style.pointerEvents,ownerDocument.body.style.pointerEvents="none"),context.layersWithOutsidePointerEventsDisabled.add(node2)),context.layers.add(node2),dispatchUpdate(),()=>{disableOutsidePointerEvents&&context.layersWithOutsidePointerEventsDisabled.size===1&&(ownerDocument.body.style.pointerEvents=originalBodyPointerEvents)}},[node2,ownerDocument,disableOutsidePointerEvents,context]),reactExports.useEffect(()=>()=>{node2&&(context.layers.delete(node2),context.layersWithOutsidePointerEventsDisabled.delete(node2),dispatchUpdate())},[node2,context]),reactExports.useEffect(()=>{const handleUpdate=__name(()=>force({}),"handleUpdate");return document.addEventListener(CONTEXT_UPDATE,handleUpdate),()=>document.removeEventListener(CONTEXT_UPDATE,handleUpdate)},[]),jsxRuntimeExports.jsx(Primitive$2.div,{...layerProps,ref:composedRefs,style:{pointerEvents:isBodyPointerEventsDisabled?isPointerEventsEnabled?"auto":"none":void 0,...props.style},onFocusCapture:composeEventHandlers(props.onFocusCapture,focusOutside.onFocusCapture),onBlurCapture:composeEventHandlers(props.onBlurCapture,focusOutside.onBlurCapture),onPointerDownCapture:composeEventHandlers(props.onPointerDownCapture,pointerDownOutside.onPointerDownCapture)})});DismissableLayer.displayName=DISMISSABLE_LAYER_NAME;var BRANCH_NAME="DismissableLayerBranch",DismissableLayerBranch=reactExports.forwardRef((props,forwardedRef)=>{const context=reactExports.useContext(DismissableLayerContext),ref=reactExports.useRef(null),composedRefs=useComposedRefs(forwardedRef,ref);return reactExports.useEffect(()=>{const node2=ref.current;if(node2)return context.branches.add(node2),()=>{context.branches.delete(node2)}},[context.branches]),jsxRuntimeExports.jsx(Primitive$2.div,{...props,ref:composedRefs})});DismissableLayerBranch.displayName=BRANCH_NAME;function usePointerDownOutside(onPointerDownOutside,ownerDocument=globalThis?.document){const handlePointerDownOutside=useCallbackRef$1(onPointerDownOutside),isPointerInsideReactTreeRef=reactExports.useRef(!1),handleClickRef=reactExports.useRef(()=>{});return reactExports.useEffect(()=>{const handlePointerDown=__name(event=>{if(event.target&&!isPointerInsideReactTreeRef.current){let handleAndDispatchPointerDownOutsideEvent2=__name(function(){handleAndDispatchCustomEvent(POINTER_DOWN_OUTSIDE,handlePointerDownOutside,eventDetail,{discrete:!0})},"handleAndDispatchPointerDownOutsideEvent2");const eventDetail={originalEvent:event};event.pointerType==="touch"?(ownerDocument.removeEventListener("click",handleClickRef.current),handleClickRef.current=handleAndDispatchPointerDownOutsideEvent2,ownerDocument.addEventListener("click",handleClickRef.current,{once:!0})):handleAndDispatchPointerDownOutsideEvent2()}else ownerDocument.removeEventListener("click",handleClickRef.current);isPointerInsideReactTreeRef.current=!1},"handlePointerDown"),timerId=window.setTimeout(()=>{ownerDocument.addEventListener("pointerdown",handlePointerDown)},0);return()=>{window.clearTimeout(timerId),ownerDocument.removeEventListener("pointerdown",handlePointerDown),ownerDocument.removeEventListener("click",handleClickRef.current)}},[ownerDocument,handlePointerDownOutside]),{onPointerDownCapture:__name(()=>isPointerInsideReactTreeRef.current=!0,"onPointerDownCapture")}}__name(usePointerDownOutside,"usePointerDownOutside");function useFocusOutside(onFocusOutside,ownerDocument=globalThis?.document){const handleFocusOutside=useCallbackRef$1(onFocusOutside),isFocusInsideReactTreeRef=reactExports.useRef(!1);return reactExports.useEffect(()=>{const handleFocus=__name(event=>{event.target&&!isFocusInsideReactTreeRef.current&&handleAndDispatchCustomEvent(FOCUS_OUTSIDE,handleFocusOutside,{originalEvent:event},{discrete:!1})},"handleFocus");return ownerDocument.addEventListener("focusin",handleFocus),()=>ownerDocument.removeEventListener("focusin",handleFocus)},[ownerDocument,handleFocusOutside]),{onFocusCapture:__name(()=>isFocusInsideReactTreeRef.current=!0,"onFocusCapture"),onBlurCapture:__name(()=>isFocusInsideReactTreeRef.current=!1,"onBlurCapture")}}__name(useFocusOutside,"useFocusOutside");function dispatchUpdate(){const event=new CustomEvent(CONTEXT_UPDATE);document.dispatchEvent(event)}__name(dispatchUpdate,"dispatchUpdate");function handleAndDispatchCustomEvent(name2,handler,detail,{discrete}){const target=detail.originalEvent.target,event=new CustomEvent(name2,{bubbles:!1,cancelable:!0,detail});handler&&target.addEventListener(name2,handler,{once:!0}),discrete?dispatchDiscreteCustomEvent(target,event):target.dispatchEvent(event)}__name(handleAndDispatchCustomEvent,"handleAndDispatchCustomEvent");var AUTOFOCUS_ON_MOUNT="focusScope.autoFocusOnMount",AUTOFOCUS_ON_UNMOUNT="focusScope.autoFocusOnUnmount",EVENT_OPTIONS$1={bubbles:!1,cancelable:!0},FOCUS_SCOPE_NAME="FocusScope",FocusScope=reactExports.forwardRef((props,forwardedRef)=>{const{loop:loop2=!1,trapped=!1,onMountAutoFocus:onMountAutoFocusProp,onUnmountAutoFocus:onUnmountAutoFocusProp,...scopeProps}=props,[container,setContainer]=reactExports.useState(null),onMountAutoFocus=useCallbackRef$1(onMountAutoFocusProp),onUnmountAutoFocus=useCallbackRef$1(onUnmountAutoFocusProp),lastFocusedElementRef=reactExports.useRef(null),composedRefs=useComposedRefs(forwardedRef,node2=>setContainer(node2)),focusScope=reactExports.useRef({paused:!1,pause(){this.paused=!0},resume(){this.paused=!1}}).current;reactExports.useEffect(()=>{if(trapped){let handleFocusIn2=__name(function(event){if(focusScope.paused||!container)return;const target=event.target;container.contains(target)?lastFocusedElementRef.current=target:focus(lastFocusedElementRef.current,{select:!0})},"handleFocusIn2"),handleFocusOut2=__name(function(event){if(focusScope.paused||!container)return;const relatedTarget=event.relatedTarget;relatedTarget!==null&&(container.contains(relatedTarget)||focus(lastFocusedElementRef.current,{select:!0}))},"handleFocusOut2"),handleMutations2=__name(function(mutations){if(document.activeElement===document.body)for(const mutation of mutations)mutation.removedNodes.length>0&&focus(container)},"handleMutations2");document.addEventListener("focusin",handleFocusIn2),document.addEventListener("focusout",handleFocusOut2);const mutationObserver=new MutationObserver(handleMutations2);return container&&mutationObserver.observe(container,{childList:!0,subtree:!0}),()=>{document.removeEventListener("focusin",handleFocusIn2),document.removeEventListener("focusout",handleFocusOut2),mutationObserver.disconnect()}}},[trapped,container,focusScope.paused]),reactExports.useEffect(()=>{if(container){focusScopesStack.add(focusScope);const previouslyFocusedElement=document.activeElement;if(!container.contains(previouslyFocusedElement)){const mountEvent=new CustomEvent(AUTOFOCUS_ON_MOUNT,EVENT_OPTIONS$1);container.addEventListener(AUTOFOCUS_ON_MOUNT,onMountAutoFocus),container.dispatchEvent(mountEvent),mountEvent.defaultPrevented||(focusFirst$2(removeLinks(getTabbableCandidates(container)),{select:!0}),document.activeElement===previouslyFocusedElement&&focus(container))}return()=>{container.removeEventListener(AUTOFOCUS_ON_MOUNT,onMountAutoFocus),setTimeout(()=>{const unmountEvent=new CustomEvent(AUTOFOCUS_ON_UNMOUNT,EVENT_OPTIONS$1);container.addEventListener(AUTOFOCUS_ON_UNMOUNT,onUnmountAutoFocus),container.dispatchEvent(unmountEvent),unmountEvent.defaultPrevented||focus(previouslyFocusedElement??document.body,{select:!0}),container.removeEventListener(AUTOFOCUS_ON_UNMOUNT,onUnmountAutoFocus),focusScopesStack.remove(focusScope)},0)}}},[container,onMountAutoFocus,onUnmountAutoFocus,focusScope]);const handleKeyDown=reactExports.useCallback(event=>{if(!loop2&&!trapped||focusScope.paused)return;const isTabKey=event.key==="Tab"&&!event.altKey&&!event.ctrlKey&&!event.metaKey,focusedElement=document.activeElement;if(isTabKey&&focusedElement){const container2=event.currentTarget,[first,last]=getTabbableEdges(container2);first&&last?!event.shiftKey&&focusedElement===last?(event.preventDefault(),loop2&&focus(first,{select:!0})):event.shiftKey&&focusedElement===first&&(event.preventDefault(),loop2&&focus(last,{select:!0})):focusedElement===container2&&event.preventDefault()}},[loop2,trapped,focusScope.paused]);return jsxRuntimeExports.jsx(Primitive$2.div,{tabIndex:-1,...scopeProps,ref:composedRefs,onKeyDown:handleKeyDown})});FocusScope.displayName=FOCUS_SCOPE_NAME;function focusFirst$2(candidates,{select=!1}={}){const previouslyFocusedElement=document.activeElement;for(const candidate of candidates)if(focus(candidate,{select}),document.activeElement!==previouslyFocusedElement)return}__name(focusFirst$2,"focusFirst$2");function getTabbableEdges(container){const candidates=getTabbableCandidates(container),first=findVisible(candidates,container),last=findVisible(candidates.reverse(),container);return[first,last]}__name(getTabbableEdges,"getTabbableEdges");function getTabbableCandidates(container){const nodes=[],walker=document.createTreeWalker(container,NodeFilter.SHOW_ELEMENT,{acceptNode:__name(node2=>{const isHiddenInput2=node2.tagName==="INPUT"&&node2.type==="hidden";return node2.disabled||node2.hidden||isHiddenInput2?NodeFilter.FILTER_SKIP:node2.tabIndex>=0?NodeFilter.FILTER_ACCEPT:NodeFilter.FILTER_SKIP},"acceptNode")});for(;walker.nextNode();)nodes.push(walker.currentNode);return nodes}__name(getTabbableCandidates,"getTabbableCandidates");function findVisible(elements,container){for(const element2 of elements)if(!isHidden(element2,{upTo:container}))return element2}__name(findVisible,"findVisible");function isHidden(node2,{upTo}){if(getComputedStyle(node2).visibility==="hidden")return!0;for(;node2;){if(upTo!==void 0&&node2===upTo)return!1;if(getComputedStyle(node2).display==="none")return!0;node2=node2.parentElement}return!1}__name(isHidden,"isHidden");function isSelectableInput(element2){return element2 instanceof HTMLInputElement&&"select"in element2}__name(isSelectableInput,"isSelectableInput");function focus(element2,{select=!1}={}){if(element2&&element2.focus){const previouslyFocusedElement=document.activeElement;element2.focus({preventScroll:!0}),element2!==previouslyFocusedElement&&isSelectableInput(element2)&&select&&element2.select()}}__name(focus,"focus");var focusScopesStack=createFocusScopesStack();function createFocusScopesStack(){let stack=[];return{add(focusScope){const activeFocusScope=stack[0];focusScope!==activeFocusScope&&activeFocusScope?.pause(),stack=arrayRemove(stack,focusScope),stack.unshift(focusScope)},remove(focusScope){stack=arrayRemove(stack,focusScope),stack[0]?.resume()}}}__name(createFocusScopesStack,"createFocusScopesStack");function arrayRemove(array2,item){const updatedArray=[...array2],index2=updatedArray.indexOf(item);return index2!==-1&&updatedArray.splice(index2,1),updatedArray}__name(arrayRemove,"arrayRemove");function removeLinks(items){return items.filter(item=>item.tagName!=="A")}__name(removeLinks,"removeLinks");var PORTAL_NAME$4="Portal",Portal$2=reactExports.forwardRef((props,forwardedRef)=>{const{container:containerProp,...portalProps}=props,[mounted,setMounted]=reactExports.useState(!1);useLayoutEffect2(()=>setMounted(!0),[]);const container=containerProp||mounted&&globalThis?.document?.body;return container?ReactDOM.createPortal(jsxRuntimeExports.jsx(Primitive$2.div,{...portalProps,ref:forwardedRef}),container):null});Portal$2.displayName=PORTAL_NAME$4;function useStateMachine$1(initialState2,machine){return reactExports.useReducer((state,event)=>machine[state][event]??state,initialState2)}__name(useStateMachine$1,"useStateMachine$1");var Presence=__name(props=>{const{present,children:children2}=props,presence=usePresence(present),child=typeof children2=="function"?children2({present:presence.isPresent}):reactExports.Children.only(children2),ref=useComposedRefs(presence.ref,getElementRef$4(child));return typeof children2=="function"||presence.isPresent?reactExports.cloneElement(child,{ref}):null},"Presence");Presence.displayName="Presence";function usePresence(present){const[node2,setNode]=reactExports.useState(),stylesRef=reactExports.useRef(null),prevPresentRef=reactExports.useRef(present),prevAnimationNameRef=reactExports.useRef("none"),initialState2=present?"mounted":"unmounted",[state,send]=useStateMachine$1(initialState2,{mounted:{UNMOUNT:"unmounted",ANIMATION_OUT:"unmountSuspended"},unmountSuspended:{MOUNT:"mounted",ANIMATION_END:"unmounted"},unmounted:{MOUNT:"mounted"}});return reactExports.useEffect(()=>{const currentAnimationName=getAnimationName(stylesRef.current);prevAnimationNameRef.current=state==="mounted"?currentAnimationName:"none"},[state]),useLayoutEffect2(()=>{const styles=stylesRef.current,wasPresent=prevPresentRef.current;if(wasPresent!==present){const prevAnimationName=prevAnimationNameRef.current,currentAnimationName=getAnimationName(styles);present?send("MOUNT"):currentAnimationName==="none"||styles?.display==="none"?send("UNMOUNT"):send(wasPresent&&prevAnimationName!==currentAnimationName?"ANIMATION_OUT":"UNMOUNT"),prevPresentRef.current=present}},[present,send]),useLayoutEffect2(()=>{if(node2){let timeoutId;const ownerWindow=node2.ownerDocument.defaultView??window,handleAnimationEnd=__name(event=>{const isCurrentAnimation=getAnimationName(stylesRef.current).includes(CSS.escape(event.animationName));if(event.target===node2&&isCurrentAnimation&&(send("ANIMATION_END"),!prevPresentRef.current)){const currentFillMode=node2.style.animationFillMode;node2.style.animationFillMode="forwards",timeoutId=ownerWindow.setTimeout(()=>{node2.style.animationFillMode==="forwards"&&(node2.style.animationFillMode=currentFillMode)})}},"handleAnimationEnd"),handleAnimationStart=__name(event=>{event.target===node2&&(prevAnimationNameRef.current=getAnimationName(stylesRef.current))},"handleAnimationStart");return node2.addEventListener("animationstart",handleAnimationStart),node2.addEventListener("animationcancel",handleAnimationEnd),node2.addEventListener("animationend",handleAnimationEnd),()=>{ownerWindow.clearTimeout(timeoutId),node2.removeEventListener("animationstart",handleAnimationStart),node2.removeEventListener("animationcancel",handleAnimationEnd),node2.removeEventListener("animationend",handleAnimationEnd)}}else send("ANIMATION_END")},[node2,send]),{isPresent:["mounted","unmountSuspended"].includes(state),ref:reactExports.useCallback(node22=>{stylesRef.current=node22?getComputedStyle(node22):null,setNode(node22)},[])}}__name(usePresence,"usePresence");function getAnimationName(styles){return styles?.animationName||"none"}__name(getAnimationName,"getAnimationName");function getElementRef$4(element2){let getter=Object.getOwnPropertyDescriptor(element2.props,"ref")?.get,mayWarn=getter&&"isReactWarning"in getter&&getter.isReactWarning;return mayWarn?element2.ref:(getter=Object.getOwnPropertyDescriptor(element2,"ref")?.get,mayWarn=getter&&"isReactWarning"in getter&&getter.isReactWarning,mayWarn?element2.props.ref:element2.props.ref||element2.ref)}__name(getElementRef$4,"getElementRef$4");var count$1=0;function useFocusGuards(){reactExports.useEffect(()=>{const edgeGuards=document.querySelectorAll("[data-radix-focus-guard]");return document.body.insertAdjacentElement("afterbegin",edgeGuards[0]??createFocusGuard()),document.body.insertAdjacentElement("beforeend",edgeGuards[1]??createFocusGuard()),count$1++,()=>{count$1===1&&document.querySelectorAll("[data-radix-focus-guard]").forEach(node2=>node2.remove()),count$1--}},[])}__name(useFocusGuards,"useFocusGuards");function createFocusGuard(){const element2=document.createElement("span");return element2.setAttribute("data-radix-focus-guard",""),element2.tabIndex=0,element2.style.outline="none",element2.style.opacity="0",element2.style.position="fixed",element2.style.pointerEvents="none",element2}__name(createFocusGuard,"createFocusGuard");var __assign=__name(function(){return __assign=Object.assign||__name(function(t2){for(var s2,i2=1,n2=arguments.length;i2"u")return zeroGap;var offsets=getOffset$1(gapMode),documentWidth=document.documentElement.clientWidth,windowWidth=window.innerWidth;return{left:offsets[0],top:offsets[1],right:offsets[2],gap:Math.max(0,windowWidth-documentWidth+offsets[2]-offsets[0])}},"getGapWidth"),Style=styleSingleton(),lockAttribute="data-scroll-locked",getStyles=__name(function(_a18,allowRelative,gapMode,important){var left2=_a18.left,top=_a18.top,right2=_a18.right,gap=_a18.gap;return gapMode===void 0&&(gapMode="margin"),` .`.concat(noScrollbarsClassName,` { overflow: hidden `).concat(important,`; @@ -63,7 +63,7 @@ If you want to hide the \`${titleWarningContext.titleName}\`, you can wrap it with our VisuallyHidden component. -For more information, see https://radix-ui.com/primitives/docs/components/${titleWarningContext.docsSlug}`;return reactExports.useEffect(()=>{titleId&&(document.getElementById(titleId)||console.error(MESSAGE))},[MESSAGE,titleId]),null},"TitleWarning"),DESCRIPTION_WARNING_NAME="DialogDescriptionWarning",DescriptionWarning=__name(({contentRef,descriptionId})=>{const MESSAGE=`Warning: Missing \`Description\` or \`aria-describedby={undefined}\` for {${useWarningContext(DESCRIPTION_WARNING_NAME).contentName}}.`;return reactExports.useEffect(()=>{const describedById=contentRef.current?.getAttribute("aria-describedby");descriptionId&&describedById&&(document.getElementById(descriptionId)||console.warn(MESSAGE))},[MESSAGE,contentRef,descriptionId]),null},"DescriptionWarning"),Root$6=Dialog,Trigger$4=DialogTrigger,Portal$1=DialogPortal,Overlay=DialogOverlay,Content$3=DialogContent,Title=DialogTitle,Description=DialogDescription,Close=DialogClose;const falsyToString=__name(value2=>typeof value2=="boolean"?`${value2}`:value2===0?"0":value2,"falsyToString"),cx=clsx,cva=__name((base,config2)=>props=>{var _config_compoundVariants;if(config2?.variants==null)return cx(base,props?.class,props?.className);const{variants,defaultVariants}=config2,getVariantClassNames=Object.keys(variants).map(variant=>{const variantProp=props?.[variant],defaultVariantProp=defaultVariants?.[variant];if(variantProp===null)return null;const variantKey=falsyToString(variantProp)||falsyToString(defaultVariantProp);return variants[variant][variantKey]}),propsWithoutUndefined=props&&Object.entries(props).reduce((acc,param)=>{let[key,value2]=param;return value2===void 0||(acc[key]=value2),acc},{}),getCompoundVariantClassNames=config2==null||(_config_compoundVariants=config2.compoundVariants)===null||_config_compoundVariants===void 0?void 0:_config_compoundVariants.reduce((acc,param)=>{let{class:cvClass,className:cvClassName,...compoundVariantOptions}=param;return Object.entries(compoundVariantOptions).every(param2=>{let[key,value2]=param2;return Array.isArray(value2)?value2.includes({...defaultVariants,...propsWithoutUndefined}[key]):{...defaultVariants,...propsWithoutUndefined}[key]===value2})?[...acc,cvClass,cvClassName]:acc},[]);return cx(base,getVariantClassNames,getCompoundVariantClassNames,props?.class,props?.className)},"cva");const toKebabCase=__name(string2=>string2.replace(/([a-z0-9])([A-Z])/g,"$1-$2").toLowerCase(),"toKebabCase"),mergeClasses=__name((...classes)=>classes.filter((className,index2,array2)=>!!className&&array2.indexOf(className)===index2).join(" "),"mergeClasses");var defaultAttributes={xmlns:"http://www.w3.org/2000/svg",width:24,height:24,viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:2,strokeLinecap:"round",strokeLinejoin:"round"};const Icon=reactExports.forwardRef(({color="currentColor",size:size2=24,strokeWidth=2,absoluteStrokeWidth,className="",children:children2,iconNode,...rest},ref)=>reactExports.createElement("svg",{ref,...defaultAttributes,width:size2,height:size2,stroke:color,strokeWidth:absoluteStrokeWidth?Number(strokeWidth)*24/Number(size2):strokeWidth,className:mergeClasses("lucide",className),...rest},[...iconNode.map(([tag,attrs])=>reactExports.createElement(tag,attrs)),...Array.isArray(children2)?children2:[children2]]));const createLucideIcon=__name((iconName,iconNode)=>{const Component=reactExports.forwardRef(({className,...props},ref)=>reactExports.createElement(Icon,{ref,iconNode,className:mergeClasses(`lucide-${toKebabCase(iconName)}`,className),...props}));return Component.displayName=`${iconName}`,Component},"createLucideIcon");const ArrowUpDown=createLucideIcon("ArrowUpDown",[["path",{d:"m21 16-4 4-4-4",key:"f6ql7i"}],["path",{d:"M17 20V4",key:"1ejh1v"}],["path",{d:"m3 8 4-4 4 4",key:"11wl7u"}],["path",{d:"M7 4v16",key:"1glfcx"}]]);const BadgeCheck=createLucideIcon("BadgeCheck",[["path",{d:"M3.85 8.62a4 4 0 0 1 4.78-4.77 4 4 0 0 1 6.74 0 4 4 0 0 1 4.78 4.78 4 4 0 0 1 0 6.74 4 4 0 0 1-4.77 4.78 4 4 0 0 1-6.75 0 4 4 0 0 1-4.78-4.77 4 4 0 0 1 0-6.76Z",key:"3c2336"}],["path",{d:"m9 12 2 2 4-4",key:"dzmm74"}]]);const Briefcase=createLucideIcon("Briefcase",[["path",{d:"M16 20V4a2 2 0 0 0-2-2h-4a2 2 0 0 0-2 2v16",key:"jecpp"}],["rect",{width:"20",height:"14",x:"2",y:"6",rx:"2",key:"i6l2r4"}]]);const Building2=createLucideIcon("Building2",[["path",{d:"M6 22V4a2 2 0 0 1 2-2h8a2 2 0 0 1 2 2v18Z",key:"1b4qmf"}],["path",{d:"M6 12H4a2 2 0 0 0-2 2v6a2 2 0 0 0 2 2h2",key:"i71pzd"}],["path",{d:"M18 9h2a2 2 0 0 1 2 2v9a2 2 0 0 1-2 2h-2",key:"10jefs"}],["path",{d:"M10 6h4",key:"1itunk"}],["path",{d:"M10 10h4",key:"tcdvrf"}],["path",{d:"M10 14h4",key:"kelpxr"}],["path",{d:"M10 18h4",key:"1ulq68"}]]);const Building=createLucideIcon("Building",[["rect",{width:"16",height:"20",x:"4",y:"2",rx:"2",ry:"2",key:"76otgf"}],["path",{d:"M9 22v-4h6v4",key:"r93iot"}],["path",{d:"M8 6h.01",key:"1dz90k"}],["path",{d:"M16 6h.01",key:"1x0f13"}],["path",{d:"M12 6h.01",key:"1vi96p"}],["path",{d:"M12 10h.01",key:"1nrarc"}],["path",{d:"M12 14h.01",key:"1etili"}],["path",{d:"M16 10h.01",key:"1m94wz"}],["path",{d:"M16 14h.01",key:"1gbofw"}],["path",{d:"M8 10h.01",key:"19clt8"}],["path",{d:"M8 14h.01",key:"6423bh"}]]);const ChartColumn=createLucideIcon("ChartColumn",[["path",{d:"M3 3v16a2 2 0 0 0 2 2h16",key:"c24i48"}],["path",{d:"M18 17V9",key:"2bz60n"}],["path",{d:"M13 17V5",key:"1frdt8"}],["path",{d:"M8 17v-3",key:"17ska0"}]]);const Check=createLucideIcon("Check",[["path",{d:"M20 6 9 17l-5-5",key:"1gmf2c"}]]);const ChevronDown=createLucideIcon("ChevronDown",[["path",{d:"m6 9 6 6 6-6",key:"qrunsl"}]]);const ChevronRight=createLucideIcon("ChevronRight",[["path",{d:"m9 18 6-6-6-6",key:"mthhwq"}]]);const CircleCheckBig=createLucideIcon("CircleCheckBig",[["path",{d:"M22 11.08V12a10 10 0 1 1-5.93-9.14",key:"g774vq"}],["path",{d:"m9 11 3 3L22 4",key:"1pflzl"}]]);const CircleCheck=createLucideIcon("CircleCheck",[["circle",{cx:"12",cy:"12",r:"10",key:"1mglay"}],["path",{d:"m9 12 2 2 4-4",key:"dzmm74"}]]);const Circle=createLucideIcon("Circle",[["circle",{cx:"12",cy:"12",r:"10",key:"1mglay"}]]);const Columns2=createLucideIcon("Columns2",[["rect",{width:"18",height:"18",x:"3",y:"3",rx:"2",key:"afitv7"}],["path",{d:"M12 3v18",key:"108xh3"}]]);const Eye=createLucideIcon("Eye",[["path",{d:"M2.062 12.348a1 1 0 0 1 0-.696 10.75 10.75 0 0 1 19.876 0 1 1 0 0 1 0 .696 10.75 10.75 0 0 1-19.876 0",key:"1nclc0"}],["circle",{cx:"12",cy:"12",r:"3",key:"1v7zrd"}]]);const Hash=createLucideIcon("Hash",[["line",{x1:"4",x2:"20",y1:"9",y2:"9",key:"4lhtct"}],["line",{x1:"4",x2:"20",y1:"15",y2:"15",key:"vyu0kd"}],["line",{x1:"10",x2:"8",y1:"3",y2:"21",key:"1ggp8o"}],["line",{x1:"16",x2:"14",y1:"3",y2:"21",key:"weycgp"}]]);const Info$1=createLucideIcon("Info",[["circle",{cx:"12",cy:"12",r:"10",key:"1mglay"}],["path",{d:"M12 16v-4",key:"1dtifu"}],["path",{d:"M12 8h.01",key:"e9boi3"}]]);const Layers3=createLucideIcon("Layers3",[["path",{d:"m12.83 2.18a2 2 0 0 0-1.66 0L2.6 6.08a1 1 0 0 0 0 1.83l8.58 3.91a2 2 0 0 0 1.66 0l8.58-3.9a1 1 0 0 0 0-1.83Z",key:"8b97xw"}],["path",{d:"m6.08 9.5-3.5 1.6a1 1 0 0 0 0 1.81l8.6 3.91a2 2 0 0 0 1.65 0l8.58-3.9a1 1 0 0 0 0-1.83l-3.5-1.59",key:"1e5n1m"}],["path",{d:"m6.08 14.5-3.5 1.6a1 1 0 0 0 0 1.81l8.6 3.91a2 2 0 0 0 1.65 0l8.58-3.9a1 1 0 0 0 0-1.83l-3.5-1.59",key:"1iwflc"}]]);const LoaderCircle=createLucideIcon("LoaderCircle",[["path",{d:"M21 12a9 9 0 1 1-6.219-8.56",key:"13zald"}]]);const Lock=createLucideIcon("Lock",[["rect",{width:"18",height:"11",x:"3",y:"11",rx:"2",ry:"2",key:"1w4ew1"}],["path",{d:"M7 11V7a5 5 0 0 1 10 0v4",key:"fwvmzm"}]]);const Luggage=createLucideIcon("Luggage",[["path",{d:"M6 20a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h12a2 2 0 0 1 2 2v10a2 2 0 0 1-2 2",key:"1m57jg"}],["path",{d:"M8 18V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v14",key:"1l99gc"}],["path",{d:"M10 20h4",key:"ni2waw"}],["circle",{cx:"16",cy:"20",r:"2",key:"1vifvg"}],["circle",{cx:"8",cy:"20",r:"2",key:"ckkr5m"}]]);const Maximize2=createLucideIcon("Maximize2",[["polyline",{points:"15 3 21 3 21 9",key:"mznyad"}],["polyline",{points:"9 21 3 21 3 15",key:"1avn1i"}],["line",{x1:"21",x2:"14",y1:"3",y2:"10",key:"ota7mn"}],["line",{x1:"3",x2:"10",y1:"21",y2:"14",key:"1atl0r"}]]);const Minimize2=createLucideIcon("Minimize2",[["polyline",{points:"4 14 10 14 10 20",key:"11kfnr"}],["polyline",{points:"20 10 14 10 14 4",key:"rlmsce"}],["line",{x1:"14",x2:"21",y1:"10",y2:"3",key:"o5lafz"}],["line",{x1:"3",x2:"10",y1:"21",y2:"14",key:"1atl0r"}]]);const MonitorSmartphone=createLucideIcon("MonitorSmartphone",[["path",{d:"M18 8V6a2 2 0 0 0-2-2H4a2 2 0 0 0-2 2v7a2 2 0 0 0 2 2h8",key:"10dyio"}],["path",{d:"M10 19v-3.96 3.15",key:"1irgej"}],["path",{d:"M7 19h5",key:"qswx4l"}],["rect",{width:"6",height:"10",x:"16",y:"12",rx:"2",key:"1egngj"}]]);const Monitor=createLucideIcon("Monitor",[["rect",{width:"20",height:"14",x:"2",y:"3",rx:"2",key:"48i651"}],["line",{x1:"8",x2:"16",y1:"21",y2:"21",key:"1svkeh"}],["line",{x1:"12",x2:"12",y1:"17",y2:"21",key:"vw1qmm"}]]);const OctagonX=createLucideIcon("OctagonX",[["path",{d:"m15 9-6 6",key:"1uzhvr"}],["path",{d:"M2.586 16.726A2 2 0 0 1 2 15.312V8.688a2 2 0 0 1 .586-1.414l4.688-4.688A2 2 0 0 1 8.688 2h6.624a2 2 0 0 1 1.414.586l4.688 4.688A2 2 0 0 1 22 8.688v6.624a2 2 0 0 1-.586 1.414l-4.688 4.688a2 2 0 0 1-1.414.586H8.688a2 2 0 0 1-1.414-.586z",key:"2d38gg"}],["path",{d:"m9 9 6 6",key:"z0biqf"}]]);const Settings=createLucideIcon("Settings",[["path",{d:"M12.22 2h-.44a2 2 0 0 0-2 2v.18a2 2 0 0 1-1 1.73l-.43.25a2 2 0 0 1-2 0l-.15-.08a2 2 0 0 0-2.73.73l-.22.38a2 2 0 0 0 .73 2.73l.15.1a2 2 0 0 1 1 1.72v.51a2 2 0 0 1-1 1.74l-.15.09a2 2 0 0 0-.73 2.73l.22.38a2 2 0 0 0 2.73.73l.15-.08a2 2 0 0 1 2 0l.43.25a2 2 0 0 1 1 1.73V20a2 2 0 0 0 2 2h.44a2 2 0 0 0 2-2v-.18a2 2 0 0 1 1-1.73l.43-.25a2 2 0 0 1 2 0l.15.08a2 2 0 0 0 2.73-.73l.22-.39a2 2 0 0 0-.73-2.73l-.15-.08a2 2 0 0 1-1-1.74v-.5a2 2 0 0 1 1-1.74l.15-.09a2 2 0 0 0 .73-2.73l-.22-.38a2 2 0 0 0-2.73-.73l-.15.08a2 2 0 0 1-2 0l-.43-.25a2 2 0 0 1-1-1.73V4a2 2 0 0 0-2-2z",key:"1qme2f"}],["circle",{cx:"12",cy:"12",r:"3",key:"1v7zrd"}]]);const ShieldCheck=createLucideIcon("ShieldCheck",[["path",{d:"M20 13c0 5-3.5 7.5-7.66 8.95a1 1 0 0 1-.67-.01C7.5 20.5 4 18 4 13V6a1 1 0 0 1 1-1c2 0 4.5-1.2 6.24-2.72a1.17 1.17 0 0 1 1.52 0C14.51 3.81 17 5 19 5a1 1 0 0 1 1 1z",key:"oel41y"}],["path",{d:"m9 12 2 2 4-4",key:"dzmm74"}]]);const Shield=createLucideIcon("Shield",[["path",{d:"M20 13c0 5-3.5 7.5-7.66 8.95a1 1 0 0 1-.67-.01C7.5 20.5 4 18 4 13V6a1 1 0 0 1 1-1c2 0 4.5-1.2 6.24-2.72a1.17 1.17 0 0 1 1.52 0C14.51 3.81 17 5 19 5a1 1 0 0 1 1 1z",key:"oel41y"}]]);const TriangleAlert=createLucideIcon("TriangleAlert",[["path",{d:"m21.73 18-8-14a2 2 0 0 0-3.48 0l-8 14A2 2 0 0 0 4 21h16a2 2 0 0 0 1.73-3",key:"wmoenq"}],["path",{d:"M12 9v4",key:"juzpu7"}],["path",{d:"M12 17h.01",key:"p32p05"}]]);const UserCog=createLucideIcon("UserCog",[["circle",{cx:"18",cy:"15",r:"3",key:"gjjjvw"}],["circle",{cx:"9",cy:"7",r:"4",key:"nufk8"}],["path",{d:"M10 15H6a4 4 0 0 0-4 4v2",key:"1nfge6"}],["path",{d:"m21.7 16.4-.9-.3",key:"12j9ji"}],["path",{d:"m15.2 13.9-.9-.3",key:"1fdjdi"}],["path",{d:"m16.6 18.7.3-.9",key:"heedtr"}],["path",{d:"m19.1 12.2.3-.9",key:"1af3ki"}],["path",{d:"m19.6 18.7-.4-1",key:"1x9vze"}],["path",{d:"m16.8 12.3-.4-1",key:"vqeiwj"}],["path",{d:"m14.3 16.6 1-.4",key:"1qlj63"}],["path",{d:"m20.7 13.8 1-.4",key:"1v5t8k"}]]);const User=createLucideIcon("User",[["path",{d:"M19 21v-2a4 4 0 0 0-4-4H9a4 4 0 0 0-4 4v2",key:"975kel"}],["circle",{cx:"12",cy:"7",r:"4",key:"17ys0d"}]]);const Users=createLucideIcon("Users",[["path",{d:"M16 21v-2a4 4 0 0 0-4-4H6a4 4 0 0 0-4 4v2",key:"1yyitq"}],["circle",{cx:"9",cy:"7",r:"4",key:"nufk8"}],["path",{d:"M22 21v-2a4 4 0 0 0-3-3.87",key:"kshegd"}],["path",{d:"M16 3.13a4 4 0 0 1 0 7.75",key:"1da9ce"}]]);const Wrench=createLucideIcon("Wrench",[["path",{d:"M14.7 6.3a1 1 0 0 0 0 1.4l1.6 1.6a1 1 0 0 0 1.4 0l3.77-3.77a6 6 0 0 1-7.94 7.94l-6.91 6.91a2.12 2.12 0 0 1-3-3l6.91-6.91a6 6 0 0 1 7.94-7.94l-3.76 3.76z",key:"cbrjhi"}]]);const X$3=createLucideIcon("X",[["path",{d:"M18 6 6 18",key:"1bl5f8"}],["path",{d:"m6 6 12 12",key:"d8bk6v"}]]);const Zap=createLucideIcon("Zap",[["path",{d:"M4 14a1 1 0 0 1-.78-1.63l9.9-10.2a.5.5 0 0 1 .86.46l-1.92 6.02A1 1 0 0 0 13 10h7a1 1 0 0 1 .78 1.63l-9.9 10.2a.5.5 0 0 1-.86-.46l1.92-6.02A1 1 0 0 0 11 14z",key:"1xq2db"}]]),Sheet=Root$6,SheetTrigger=Trigger$4,SheetPortal=Portal$1,SheetOverlay=reactExports.forwardRef(({className,...props},ref)=>jsxRuntimeExports.jsx(Overlay,{className:cn$2("fixed inset-0 z-50 bg-black/80 data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0",className),...props,ref}));SheetOverlay.displayName=Overlay.displayName;const sheetVariants=cva("fixed z-50 gap-4 bg-background p-6 shadow-lg transition ease-in-out data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:duration-300 data-[state=open]:duration-500",{variants:{side:{top:"inset-x-0 top-0 border-b data-[state=closed]:slide-out-to-top data-[state=open]:slide-in-from-top",bottom:"inset-x-0 bottom-0 border-t data-[state=closed]:slide-out-to-bottom data-[state=open]:slide-in-from-bottom",left:"inset-y-0 left-0 h-full w-3/4 border-r data-[state=closed]:slide-out-to-left data-[state=open]:slide-in-from-left sm:max-w-sm",right:"inset-y-0 right-0 h-full w-3/4 border-l data-[state=closed]:slide-out-to-right data-[state=open]:slide-in-from-right sm:max-w-sm"}},defaultVariants:{side:"right"}}),SheetContent=reactExports.forwardRef(({side="right",className,children:children2,allowMaximize=!1,...props},ref)=>{const[isMaximized,setIsMaximized]=reactExports.useState(!1),toggleMaximize=__name(()=>setIsMaximized(!isMaximized),"toggleMaximize");return jsxRuntimeExports.jsxs(SheetPortal,{children:[jsxRuntimeExports.jsx(SheetOverlay,{}),jsxRuntimeExports.jsxs(Content$3,{ref,className:cn$2(sheetVariants({side}),isMaximized&&side==="right"||isMaximized&&side==="left"?"!w-full !max-w-full":"",className),...props,children:[children2,jsxRuntimeExports.jsxs("div",{className:"absolute right-4 top-4 flex gap-2",children:[allowMaximize&&jsxRuntimeExports.jsxs("button",{onClick:toggleMaximize,className:"rounded-sm opacity-70 ring-offset-background transition-opacity hover:opacity-100 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 disabled:pointer-events-none data-[state=open]:bg-secondary",children:[isMaximized?jsxRuntimeExports.jsx(Minimize2,{className:"h-4 w-4"}):jsxRuntimeExports.jsx(Maximize2,{className:"h-4 w-4"}),jsxRuntimeExports.jsx("span",{className:"sr-only",children:isMaximized?"Minimize":"Maximize"})]}),jsxRuntimeExports.jsxs(Close,{className:"rounded-sm opacity-70 ring-offset-background transition-opacity hover:opacity-100 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 disabled:pointer-events-none data-[state=open]:bg-secondary",children:[jsxRuntimeExports.jsx(X$3,{className:"h-4 w-4"}),jsxRuntimeExports.jsx("span",{className:"sr-only",children:"Close"})]})]})]})]})});SheetContent.displayName=Content$3.displayName;const SheetHeader=__name(({className,...props})=>jsxRuntimeExports.jsx("div",{className:cn$2("flex flex-col space-y-2 text-center sm:text-left",className),...props}),"SheetHeader");SheetHeader.displayName="SheetHeader";const SheetTitle=reactExports.forwardRef(({className,...props},ref)=>jsxRuntimeExports.jsx(Title,{ref,className:cn$2("text-lg font-semibold text-foreground",className),...props}));SheetTitle.displayName=Title.displayName;const SheetDescription=reactExports.forwardRef(({className,...props},ref)=>jsxRuntimeExports.jsx(Description,{ref,className:cn$2("text-sm text-muted-foreground",className),...props}));SheetDescription.displayName=Description.displayName;const Icons={logo:__name(props=>jsxRuntimeExports.jsxs("svg",{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 18 18",...props,children:[jsxRuntimeExports.jsx("path",{"fill-rule":"evenodd","clip-rule":"evenodd",fill:"#F35123",d:"M0 0h7v7h-7z"}),jsxRuntimeExports.jsx("path",{"fill-rule":"evenodd","clip-rule":"evenodd",fill:"#01A4EF",d:"M0 9h7v7h-7z"}),jsxRuntimeExports.jsx("path",{"fill-rule":"evenodd","clip-rule":"evenodd",fill:"#7FBA00",d:"M9 0h7v7h-7z"}),jsxRuntimeExports.jsx("path",{"fill-rule":"evenodd","clip-rule":"evenodd",fill:"#FFB901",d:"M9 9h7v7h-7z"})]}),"logo"),gitHub:__name(props=>jsxRuntimeExports.jsx("svg",{viewBox:"0 0 438.549 438.549",...props,children:jsxRuntimeExports.jsx("path",{fill:"currentColor",d:"M409.132 114.573c-19.608-33.596-46.205-60.194-79.798-79.8-33.598-19.607-70.277-29.408-110.063-29.408-39.781 0-76.472 9.804-110.063 29.408-33.596 19.605-60.192 46.204-79.8 79.8C9.803 148.168 0 184.854 0 224.63c0 47.78 13.94 90.745 41.827 128.906 27.884 38.164 63.906 64.572 108.063 79.227 5.14.954 8.945.283 11.419-1.996 2.475-2.282 3.711-5.14 3.711-8.562 0-.571-.049-5.708-.144-15.417a2549.81 2549.81 0 01-.144-25.406l-6.567 1.136c-4.187.767-9.469 1.092-15.846 1-6.374-.089-12.991-.757-19.842-1.999-6.854-1.231-13.229-4.086-19.13-8.559-5.898-4.473-10.085-10.328-12.56-17.556l-2.855-6.57c-1.903-4.374-4.899-9.233-8.992-14.559-4.093-5.331-8.232-8.945-12.419-10.848l-1.999-1.431c-1.332-.951-2.568-2.098-3.711-3.429-1.142-1.331-1.997-2.663-2.568-3.997-.572-1.335-.098-2.43 1.427-3.289 1.525-.859 4.281-1.276 8.28-1.276l5.708.853c3.807.763 8.516 3.042 14.133 6.851 5.614 3.806 10.229 8.754 13.846 14.842 4.38 7.806 9.657 13.754 15.846 17.847 6.184 4.093 12.419 6.136 18.699 6.136 6.28 0 11.704-.476 16.274-1.423 4.565-.952 8.848-2.383 12.847-4.285 1.713-12.758 6.377-22.559 13.988-29.41-10.848-1.14-20.601-2.857-29.264-5.14-8.658-2.286-17.605-5.996-26.835-11.14-9.235-5.137-16.896-11.516-22.985-19.126-6.09-7.614-11.088-17.61-14.987-29.979-3.901-12.374-5.852-26.648-5.852-42.826 0-23.035 7.52-42.637 22.557-58.817-7.044-17.318-6.379-36.732 1.997-58.24 5.52-1.715 13.706-.428 24.554 3.853 10.85 4.283 18.794 7.952 23.84 10.994 5.046 3.041 9.089 5.618 12.135 7.708 17.705-4.947 35.976-7.421 54.818-7.421s37.117 2.474 54.823 7.421l10.849-6.849c7.419-4.57 16.18-8.758 26.262-12.565 10.088-3.805 17.802-4.853 23.134-3.138 8.562 21.509 9.325 40.922 2.279 58.24 15.036 16.18 22.559 35.787 22.559 58.817 0 16.178-1.958 30.497-5.853 42.966-3.9 12.471-8.941 22.457-15.125 29.979-6.191 7.521-13.901 13.85-23.131 18.986-9.232 5.14-18.182 8.85-26.84 11.136-8.662 2.286-18.415 4.004-29.263 5.146 9.894 8.562 14.842 22.077 14.842 40.539v60.237c0 3.422 1.19 6.279 3.572 8.562 2.379 2.279 6.136 2.95 11.276 1.995 44.163-14.653 80.185-41.062 108.068-79.226 27.88-38.161 41.825-81.126 41.825-128.906-.01-39.771-9.818-76.454-29.414-110.049z"})}),"gitHub")},ztAppConfig={name:"Zero Trust Assessment",github:{title:"GitHub",url:"https://github.com/microsoft/zerotrustassessment"}},reportData= {"ExecutedAt":"2026-05-19T08:21:38.163451+10:00","TenantId":"aaaabbbb-0000-cccc-1111-dddd2222eeee","TenantName":"Contoso","Domain":"contoso.com","Account":"admin@contoso.com","CurrentVersion":"2.1.8","LatestVersion":"2.2.0","TestResultSummary":{"IdentityPassed":85,"IdentityTotal":100,"DevicesPassed":25,"DevicesTotal":36,"NetworkPassed":1,"NetworkTotal":9,"DataPassed":24,"DataTotal":34,"InfrastructurePassed":7,"InfrastructureTotal":13,"SecOpsPassed":0,"SecOpsTotal":0,"AIPassed":0,"AITotal":0},"Tests":[{"TestImpact":"Low","TestRisk":"Medium","TestSkipped":"","TestAppliesTo":null,"TestPillar":"Data","TestCategory":"Information Protection","TestDescription":"Autolabeling policies only classify new and modified content. Existing files and emails remain unclassified and invisible to DLP policies that depend on label detection. On-demand scans let you manually trigger sensitive information type detection across specified locations to discover and retroactively classify historical content, giving you a complete view of your information protection posture rather than forward-looking coverage.\n\n**Remediation action**\n\n- [On-demand classification in Microsoft Purview](https://learn.microsoft.com/purview/on-demand-classification?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci)\n","TestTitle":"On-Demand scans configured for sensitive information discovery","SkippedReason":null,"TestId":"35022","TestImplementationCost":"Medium","TestMinimumLicense":["EXCHANGE_S_ENTERPRISE"],"TestSfiPillar":"Protect tenants and production systems","TestResult":"\n✅ At least one on-demand scan is configured in the organization, enabling discovery and classification of historical sensitive information.\n\n### On-Demand scan configuration summary\n\n**Scan details:**\n\n| Name | Sensitive information scan status | Workload | Sensitive information types detected | When created UTC | Last scan start time|\n|------|--------|----------|--------------|---------------|-----------------|\n| Test exchange | ImpactAssessmentCancelled | Exchange, SharePoint, OneDriveForBusiness, EndpointDevices | None | 2026-09-01 | |\n| Purview_35022_test | ClassificationComplete | Exchange, SharePoint, OneDriveForBusiness | None | 2026-04-02 | 2026-04-02 |\n| Item search | ClassificationInProgress | Exchange, SharePoint, OneDriveForBusiness | None | 2026-04-02 | 2026-04-02 |\n| Purview_35022 | ImpactAssessmentComplete | Exchange, SharePoint, OneDriveForBusiness | None | 01/27/2026 06:40:53 | |\n\n**Summary:**\n\n* **Total on-demand scans configured:** 4\n* **Scans by status:**\n * ClassificationComplete: 1\n * ClassificationInProgress: 1\n * ImpactAssessmentCancelled: 1\n * ImpactAssessmentComplete: 1\n* **Locations scanned:**\n * SharePoint: Yes\n * OneDrive: Yes\n * Exchange: Yes\n* **Most recent scan completion:** 02/04/2026 14:13:01\n\n[Microsoft Purview Portal > Information Protection > Classifiers > On-demand classification](https://purview.microsoft.com/informationprotection/dataclassification/colddatascans)\nor\n[Microsoft Purview Portal > Data Loss Prevention > Classifiers > On-demand classification](https://purview.microsoft.com/datalossprevention/dataclassification/colddatascans)\n\n\n","TestStatus":"Passed","TestTags":null},{"TestImpact":"Low","TestRisk":"Medium","TestSkipped":"NotConnectedToService","TestAppliesTo":null,"TestPillar":"Data","TestCategory":"SharePoint Online","TestDescription":"When you configure SharePoint with a default label for document libraries, any new files uploaded to that library, or existing files edited in the library will have that label applied if they don't already have a sensitivity label, or they have a sensitivity label but with lower priority. This location-based labeling offers a baseline level of protection and a form of automatic labeling without content inspection. When files aren't labeled, important files can bypass protection and remain vulnerable.\n\nThis configuration is most suitable for document libraries that contain files with the same level of sensitivity. It can be supplemented with auto-labeling policies that uses content inspection, and manual labeling with a higher priority sensitivity label if needed.\n\n**Remediation action**\n\n- [Configure a default sensitivity label for a SharePoint document library](https://learn.microsoft.com/purview/sensitivity-labels-sharepoint-default-label?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci)\n","TestTitle":"Default sensitivity labels are configured for SharePoint document libraries","SkippedReason":"This test requires connection to the service(s) \"SharePointOnline\" currently disconnected. Please use _Connect-ZtAssessment_ to connect.","TestId":"35008","TestImplementationCost":"Low","TestMinimumLicense":["RMS_S_PREMIUM2"],"TestSfiPillar":"Protect tenants and production systems","TestResult":"\nSkipped. This test requires connection to the service(s) \"SharePointOnline\" currently disconnected. Please use _Connect-ZtAssessment_ to connect.\n\n","TestStatus":"Skipped","TestTags":null},{"TestImplementationCost":"","TestPillar":"Infrastructure","TestCategory":"Manage access and permissions","SkippedReason":null,"TestImpact":"","TestAppliesTo":null,"TestSfiPillar":"Protect tenants and isolate production systems","TestSkipped":"","TestMinimumLicense":"N/A","TestTags":null,"TestTitle":"Disabled accounts with owner permissions on Azure resources should be removed","TestRisk":"High","TestResult":"Disabled accounts with owner permissions on Azure resources should be removed\n\n| Subscription | Affected resource | Status | Azure portal |\n| :----------- | :---------------- | :----- | :----------- |\n| [Visual Studio Enterprise Subscription](https://portal.azure.com/#resource/subscriptions/54d3ea01-5a07-45d0-8d69-e5f5b0b20098) | [54d3ea01-5a07-45d0-8d69-e5f5b0b20098](https://portal.azure.com/#resource/subscriptions/54d3ea01-5a07-45d0-8d69-e5f5b0b20098) | ✅ | [View recommendation](https://portal.azure.com/#blade/Microsoft_Azure_Security/RecommendationsBlade/assessmentKey/050ac097-3dda-4d24-ab6d-82568e7a50cf/resourceId/%2fsubscriptions%2f54d3ea01-5a07-45d0-8d69-e5f5b0b20098) |\n","TestStatus":"Passed","TestDescription":"It's important to remove accounts that have been disabled from signing in on Active Directory from your Azure resources.
These disabled accounts, especially those with owner permissions, can become targets for attackers.
If these accounts are compromised, attackers could gain unnoticed access to your data.
Therefore, to maintain a secure environment, we recommend removing these accounts from Azure resources..
\n\n**Remediation action**\n\nReview the list of accounts that are disabled from signing in on the Accounts section. Select an account to view its role definitions and locate the source scope. If you accept the risk for specific account, use the exempt capability to exclude it from evaluation.
  1. Go to the Azure portal.
  2. Open Access control (IAM) at a scope, such as management group, subscription, resource group, or resource, where the guest user has a role assignment.
  3. Click the Role assignments tab to view all the role assignments.
  4. In the list of role assignments, add a checkmark next to the disabled user with the role assignment you want to remove.
  5. Click Remove. In the remove role assignment message that appears, click Yes.
","TestId":"050ac097-3dda-4d24-ab6d-82568e7a50cf"},{"TestImplementationCost":"Low","TestPillar":"Identity","TestCategory":"Application management","SkippedReason":null,"TestImpact":"Low","TestAppliesTo":["Identity"],"TestSfiPillar":"Protect engineering systems","TestSkipped":"","TestMinimumLicense":"P1","TestTags":["Identity"],"TestTitle":"App registrations must not have dangling or abandoned domain redirect URIs","TestRisk":"High","TestResult":"\nUnsafe redirect URIs found\n\n1️⃣ → Use of http(s) instead of https, 2️⃣ → Use of *.azurewebsites.net, 3️⃣ → Invalid URL, 4️⃣ → Domain not resolved\n\n| | Name | Unsafe redirect URIs |\n| :--- | :--- | :--- |\n| | [21869testapp](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/SignOn/objectId/e69e29be-ba40-445a-9824-a3a45e0ae57a/appId/dd63d132-18fb-4f2e-aec4-82b97f30301f/preferredSingleSignOnMode/saml/servicePrincipalType/Application/fromNav/) | `4️⃣ https://testapp.local/callback` | |\n| | [Contoso Access Verifier](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/SignOn/objectId/41d3b041-9859-4830-8feb-72ffd7afad65/appId/a6af3433-bc44-4d27-9b35-81d10fd51315/preferredSingleSignOnMode/saml/servicePrincipalType/Application/fromNav/) | `4️⃣ https://demoeam2025.blob.core.windows.net/data/index.html` | |\n| | [My nice app](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/SignOn/objectId/d41cfc13-11d1-4f93-835a-88e729725564/appId/2946f286-2b59-4f29-876c-0ed8bbe1c482/preferredSingleSignOnMode/saml/servicePrincipalType/Application/fromNav/) | `4️⃣ https://mysalmon.azurewebsites.net/login.saml` | |\n| | [ServiceNow](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/SignOn/objectId/9a8af246-0d94-42eb-aaaf-836a9f9a4974/appId/ecbbb1c8-ef06-48c4-9211-9ffbfbc24b94/preferredSingleSignOnMode/saml/servicePrincipalType/Application/fromNav/) | `4️⃣ https://dev92989.service-now.com/navpage.do` | |\n| | [aad-extensions-app. Do not modify. Used by AAD for storing user data.](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/SignOn/objectId/b5277031-31cb-4a88-b5a1-316878166f55/appId/d211b2a1-0c5e-4be8-a40a-46033a0b6df2/preferredSingleSignOnMode/saml/servicePrincipalType/Application/fromNav/) | `4️⃣ https://contoso.onmicrosoft.com/cpimextensions` | |\n| | [saml test app](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/SignOn/objectId/daa6074c-db6f-4bdc-a41b-bc0052c536a5/appId/c266d677-a5f8-47bc-9f0a-1b6fbe0bddad/preferredSingleSignOnMode/saml/servicePrincipalType/Application/fromNav/) | `4️⃣ https://appclaims.azurewebsites.net/signin-saml`, `4️⃣ https://appclaims.azurewebsites.net/signin-oidc` | |\n\n\n","TestStatus":"Failed","TestDescription":"Unmaintained or orphaned redirect URIs in app registrations create significant security vulnerabilities when they reference domains that no longer point to active resources. Threat actors can exploit these \"dangling\" DNS entries by provisioning resources at abandoned domains, effectively taking control of redirect endpoints. This vulnerability enables attackers to intercept authentication tokens and credentials during OAuth 2.0 flows, which can lead to unauthorized access, session hijacking, and potential broader organizational compromise.\n\n**Remediation action**\n\n- [Redirect URI (reply URL) outline and restrictions](https://learn.microsoft.com/entra/identity-platform/reply-url?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci)\n","TestId":"21888"},{"TestImplementationCost":"Low","TestPillar":"Identity","TestCategory":"Application management","SkippedReason":null,"TestImpact":"Low","TestAppliesTo":["Identity"],"TestSfiPillar":"Protect tenants and isolate production systems","TestSkipped":"","TestMinimumLicense":"Free","TestTags":["Identity"],"TestTitle":"Guests are not assigned high privileged directory roles","TestRisk":"High","TestResult":"\nGuests with privileged roles were detected.\n\n\n## Guests with privileged roles\n\n\n| Role Name | User Name | User Principal Name | User Type | Assignment Type |\n| :-------- | :-------- | :------------------ | :-------- | :-------------- |\n| Application Administrator | [Riley Martinez](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/overview/userId/653c7fdd-1b41-4229-992a-69cc35aad4f7/hidePreviewBanner~/true) | riley@contoso.onmicrosoft.com | Guest | Eligible |\n| Global Administrator | [Dakota Lee](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/overview/userId/210d3e96-015f-462d-b6d6-81e6023263df/hidePreviewBanner~/true) | guest-user_external.com#EXT#@contoso.com | Guest | Permanent |\n\n\n\n","TestStatus":"Failed","TestDescription":"When guest users are assigned highly privileged directory roles such as Global Administrator or Privileged Role Administrator, organizations create significant security vulnerabilities that threat actors can exploit for initial access through compromised external accounts or business partner environments. Since guest users originate from external organizations without direct control of security policies, threat actors who compromise these external identities can gain privileged access to the target organization's Microsoft Entra tenant.\n\nWhen threat actors obtain access through compromised guest accounts with elevated privileges, they can escalate their own privilege to create other backdoor accounts, modify security policies, or assign themselves permanent roles within the organization. The compromised privileged guest accounts enable threat actors to establish persistence and then make all the changes they need to remain undetected. For example they could create cloud-only accounts, bypass Conditional Access policies applied to internal users, and maintain access even after the guest's home organization detects the compromise. Threat actors can then conduct lateral movement using administrative privileges to access sensitive resources, modify audit settings, or disable security monitoring across the entire tenant. Threat actors can reach complete compromise of the organization's identity infrastructure while maintaining plausible deniability through the external guest account origin. \n\n**Remediation action**\n\n- [Remove Guest users from privileged roles](https://learn.microsoft.com/entra/identity/role-based-access-control/best-practices?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci)\n","TestId":"22128"},{"TestImplementationCost":"High","TestPillar":"Identity","TestCategory":"Application management","SkippedReason":null,"TestImpact":"Low","TestAppliesTo":["Identity"],"TestSfiPillar":"Protect engineering systems","TestSkipped":"","TestMinimumLicense":"P1","TestTags":["Identity"],"TestTitle":"Service principals use safe redirect URIs","TestRisk":"High","TestResult":"\nUnsafe redirect URIs found\n\n1️⃣ → Use of http(s) instead of https, 2️⃣ → Use of *.azurewebsites.net, 3️⃣ → Invalid URL, 4️⃣ → Domain not resolved\n\n| | Name | Unsafe redirect URIs |App owner tenant |\n| :--- | :--- | :--- | :--- |\n| | [EAM Demo](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/Overview/objectId/24b12ae7-4648-4aae-b00c-6349a565d24c/appId/e6e0be31-7040-4084-ac44-600b67661f2c) | `2️⃣ https://eamdemo.azurewebsites.net` | 1852b10f-a011-428b-98f9-d09c37d477cf |\n| | [FIDO2-passkeys-MFA](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/Overview/objectId/1aa7e155-cbf8-4970-8458-05a0c7a2d1a5/appId/4fabcfc0-5c44-45a1-8c80-8537f0625949) | `2️⃣ https://fidomfaserver.azurewebsites.net/connect/authorize` | 1852b10f-a011-428b-98f9-d09c37d477cf |\n| | [Graph Explorer](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/Overview/objectId/8f8f300a-870a-46ff-bdab-934e1436920d/appId/d3ce4cf8-6810-442d-b42e-375e14710095) | `2️⃣ https://graphexplorer.azurewebsites.net/` | 5508eaf2-e7b4-4510-a4fb-9f5970550d80 |\n| | [Graph explorer (official site)](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/Overview/objectId/cd2e9b58-eb21-4a50-a338-33f9daa1599c/appId/de8bc8b5-d9f9-48b1-a8ad-b748da725064) | `2️⃣ https://graphtryit.azurewebsites.net`, `2️⃣ https://graphtryit.azurewebsites.net/` | 72f988bf-86f1-41af-91ab-2d7cd011db47 |\n| | [Internal_AccessScope](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/Overview/objectId/180a3ccb-3f2f-486f-8b56-025fc225166d/appId/3f9bd1ee-5a72-4ad3-b67d-cb016f935bcf) | `1️⃣ http://featureconfiguration.onmicrosoft.com/Internal_AccessScope` | 0d2db716-b331-4d7b-aa37-7f1ac9d35dae |\n| | [Modern Workplace Concierge](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/Overview/objectId/ad1c51e8-f8a8-4bf2-ac09-a3a20cba5fa5/appId/c65c4011-1b90-4ec9-b5e9-1ee17786ad84) | `2️⃣ https://mwconcierge.azurewebsites.net/` | 7955e1b3-cbad-49eb-9a84-e14aed7f3400 |\n| | [entraChatAppMultiTenant](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/Overview/objectId/855a57ff-88a6-4ad0-85d7-4f46d742730e/appId/5e00b345-a805-42a0-9caa-7d6cb761c668) | `2️⃣ https://entrachatapp.azurewebsites.net`, `2️⃣ https://entrachatapp.azurewebsites.net/redirect` | 8b047ec6-6d2e-481d-acfa-5d562c09f49a |\n\n\n","TestStatus":"Failed","TestDescription":"Non-Microsoft and multitenant applications configured with URLs that include wildcards, localhost, or URL shorteners increase the attack surface for threat actors. These insecure redirect URIs (reply URLs) might allow adversaries to manipulate authentication requests, hijack authorization codes, and intercept tokens by directing users to attacker-controlled endpoints. Wildcard entries expand the risk by permitting unintended domains to process authentication responses, while localhost and shortener URLs might facilitate phishing and token theft in uncontrolled environments.\n\nWithout strict validation of redirect URIs, attackers can bypass security controls, impersonate legitimate applications, and escalate their privileges. This misconfiguration enables persistence, unauthorized access, and lateral movement, as adversaries exploit weak OAuth enforcement to infiltrate protected resources undetected.\n\n**Remediation action**\n\n- [Check the redirect URIs for your application registrations.](https://learn.microsoft.com/entra/identity-platform/reply-url?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci) Make sure the redirect URIs don't have localhost, *.azurewebsites.net, wildcards, or URL shorteners.\n","TestId":"23183"},{"TestImplementationCost":"High","TestPillar":"Identity","TestCategory":"Application management","SkippedReason":null,"TestImpact":"Low","TestAppliesTo":null,"TestSfiPillar":"Protect identities and secrets","TestSkipped":"","TestMinimumLicense":"Free","TestTags":null,"TestTitle":"No usage of ADAL in the tenant","TestRisk":"Medium","TestResult":"\nNo ADAL applications found in the tenant.\n\n","TestStatus":"Passed","TestDescription":"Microsoft ended support and security fixes for ADAL on June 30, 2023. Continued ADAL usage bypasses modern security protections available only in MSAL, including Conditional Access enforcement, Continuous Access Evaluation (CAE), and advanced token protection. ADAL applications create security vulnerabilities by using weaker legacy authentication patterns, often calling deprecated Azure AD Graph endpoints, and preventing adoption of hardened authentication flows that could mitigate future security advisories. \n\n**Remediation action**\n\n- [Migrate applications to the Microsoft Authentication Library (MSAL)](https://learn.microsoft.com/entra/identity-platform/msal-migration?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci)\n","TestId":"21780"},{"TestImplementationCost":"Medium","TestPillar":"Identity","TestCategory":"Access control","SkippedReason":"UnderConstruction","TestImpact":"Low","TestAppliesTo":["Identity"],"TestSfiPillar":"Protect identities and secrets","TestSkipped":"UnderConstruction","TestMinimumLicense":null,"TestTags":["Identity"],"TestTitle":"All registered redirect URIs must have proper DNS records and ownerships","TestRisk":"Medium","TestResult":"\nPlanned for future release.\n","TestStatus":"Planned","TestDescription":"...\n\n**Remediation action**\n\n","TestId":"21887"},{"TestImplementationCost":"Low","TestPillar":"Identity","TestCategory":"Access control","SkippedReason":"UnderConstruction","TestImpact":"Low","TestAppliesTo":["Identity"],"TestSfiPillar":"Protect identities and secrets","TestSkipped":"UnderConstruction","TestMinimumLicense":"P1","TestTags":["Identity"],"TestTitle":"All groups in Conditional Access policies belong to a restricted management administrative unit","TestRisk":"Medium","TestResult":"\nPlanned for future release.\n","TestStatus":"Planned","TestDescription":"...\n\n**Remediation action**\n\n","TestId":"21832"},{"TestImpact":"Low","TestRisk":"High","TestSkipped":"","TestAppliesTo":null,"TestPillar":"Data","TestCategory":"Information Protection","TestDescription":"Auto-labeling greatly extends your labeling reach, by automatically labeling items based on content inspection. When you rely on just manual labeling, users might not always recognize what counts as sensitive data or might forget to label information during their daily tasks. Default labels offer a baseline of protection but don't take into consideration content that requires a higher level of protection. This leads to gaps in classification, allowing sensitive content to move through Microsoft 365 applications without proper labels or protection.\n\nYou can configure auto-labeling settings for labels that trigger when users open files in their Office apps, and auto-labeling policies that require no user interactions. Setting up at least one auto-labeling policy to detect sensitive content automatically labels this content, no matter what actions people take. In turn, this labeled content can be used with other Microsoft Purview solutions to increase your security, such as data loss prevention (DLP) rules and access restrictions.\n\n**Remediation action**\n\n- [Automatically apply a sensitivity label to Microsoft 365 data](https://learn.microsoft.com/purview/apply-sensitivity-label-automatically?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci)\n","TestTitle":"Auto-Labeling Policies Configured (All Workloads)","SkippedReason":null,"TestId":"35019","TestImplementationCost":"Medium","TestMinimumLicense":["EXCHANGE_S_ENTERPRISE"],"TestSfiPillar":"Protect tenants and production systems","TestResult":"\n✅ 2 auto-labeling policies exist in the organization, enabling automatic content classification.\n\n### [Auto-Labeling Policies](https://purview.microsoft.com/informationprotection/autolabeling)\n\n| Policy Name | Description | Enabled | Mode | Workload | Created | Last Modified |\n| :--- | :--- | :---: | :--- | :--- | :--- | :--- |\n| Japan Financial Data | | ✅ | TestWithoutNotifications | Exchange, SharePoint, OneDriveForBusiness, Applications, Azure, AWS | 2026-02-05 | 2026-02-05 |\n| U.S. Patriot Act Enhanced | | ✅ | TestWithoutNotifications | Exchange, SharePoint, OneDriveForBusiness, Applications, Azure, AWS | 2026-02-05 | 2026-02-06 |\n\n### Summary\n\n* **Total Auto-Labeling Policies:** 2\n\n**Workloads with Auto-Labeling Policies:**\n* Exchange/Outlook: [Yes]\n* SharePoint: [Yes]\n* OneDrive: [Yes]\n* Teams: [No]\n* Power BI: [No]\n\n* **Policy Creation Date Range:** 2026-02-05 to 2026-02-05\n\n💡 **Note:** This test validates policy existence only. Test 35020 validates that at least one policy is in enforcement mode.\n\n\n","TestStatus":"Passed","TestTags":null},{"TestImplementationCost":"Low","TestPillar":"Identity","TestCategory":"Access control","SkippedReason":null,"TestImpact":"Medium","TestAppliesTo":["Identity"],"TestSfiPillar":"Protect identities and secrets","TestSkipped":"","TestMinimumLicense":"P1","TestTags":["ConditionalAccess"],"TestTitle":"Restrict device code flow","TestRisk":"High","TestResult":"\nDevice code flow is properly restricted in the tenant.\n## Conditional Access Policies targeting Device Code Flow\n\n| Policy Name | Status | Target Users | Target Resources | Grant Controls |\n| :---------- | :----- | :----------- | :--------------- | :------------ |\n| [Block Device Code](https://entra.microsoft.com/#view/Microsoft_AAD_ConditionalAccess/PolicyBlade/policyId/db2153a1-40a2-457f-917c-c280b204b5cd) | Enabled | All Users, Excluded: 8 users/groups | All Applications | Block (ANY) |\n\n## Inactive Conditional Access Policies targeting Device Code Flow\nThese policies are not contributing to your security posture because they are not enabled:\n\n| Policy Name | Status | Target Users | Target Resources | Grant Controls |\n| :---------- | :----- | :----------- | :--------------- | :------------ |\n| [Block DCF](https://entra.microsoft.com/#view/Microsoft_AAD_ConditionalAccess/PolicyBlade/policyId/b5ff217b-3d84-4581-bd92-5d8f8b8bab6a) | Disabled | All Users, Excluded: 1 users/groups | All Applications | Block (ANY) |\n\n\n","TestStatus":"Passed","TestDescription":"Device code flow is a cross-device authentication flow designed for input-constrained devices. It can be exploited in phishing attacks, where an attacker initiates the flow and tricks a user into completing it on their device, thereby sending the user's tokens to the attacker. Given the security risks and the infrequent legitimate use of device code flow, you should enable a Conditional Access policy to block this flow by default.\n\n**Remediation action**\n\n- [Deploy a Conditional Access policy to block device code flow](https://learn.microsoft.com/entra/identity/conditional-access/policy-block-authentication-flows?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci#device-code-flow-policies).\n","TestId":"21808"},{"TestImplementationCost":"Medium","TestPillar":"Identity","TestCategory":"Credential management","SkippedReason":null,"TestImpact":"Low","TestAppliesTo":null,"TestSfiPillar":"Protect identities and secrets","TestSkipped":"","TestMinimumLicense":"Free","TestTags":null,"TestTitle":"Passkey authentication method enabled","TestRisk":"High","TestResult":"\nPasskey authentication method is enabled and configured for users in your tenant.\n## [Passkey authentication method details](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ConfigureAuthMethodsBlade/authMethod~/%7B%22%40odata.type%22%3A%22%23microsoft.graph.fido2AuthenticationMethodConfiguration%22%2C%22id%22%3A%22Fido2%22%2C%22state%22%3A%22enabled%22%2C%22isSelfServiceRegistrationAllowed%22%3Atrue%2C%22isAttestationEnforced%22%3Afalse%2C%22excludeTargets%22%3A%5B%7B%22id%22%3A%2243b7bc87-77eb-4263-abad-e3c2478f0a35%22%2C%22targetType%22%3A%22group%22%2C%22displayName%22%3A%22eam-block-user%22%7D%5D%2C%22keyRestrictions%22%3A%7B%22isEnforced%22%3Afalse%2C%22enforcementType%22%3A%22allow%22%2C%22aaGuids%22%3A%5B%22de1e552d-db1d-4423-a619-566b625cdc84%22%2C%2290a3ccdf-635c-4729-a248-9b709135078f%22%2C%2277010bd7-212a-4fc9-b236-d2ca5e9d4084%22%2C%22b6ede29c-3772-412c-8a78-539c1f4c62d2%22%2C%22ee041bce-25e5-4cdb-8f86-897fd6418464%22%2C%2273bb0cd4-e502-49b8-9c6f-b59445bf720b%22%5D%7D%2C%22includeTargets%40odata.context%22%3A%22https%3A%2F%2Fgraph.microsoft.com%2Fbeta%2F%24metadata%23policies%2FauthenticationMethodsPolicy%2FauthenticationMethodConfigurations('Fido2')%2Fmicrosoft.graph.fido2AuthenticationMethodConfiguration%2FincludeTargets%22%2C%22includeTargets%22%3A%5B%7B%22targetType%22%3A%22group%22%2C%22id%22%3A%22all_users%22%2C%22isRegistrationRequired%22%3Afalse%7D%5D%2C%22enabled%22%3Atrue%2C%22target%22%3A%22All%20users%2C%20excluding%201%20group%22%2C%22isAllUsers%22%3Atrue%2C%22voiceDisabled%22%3Afalse%7D/canModify~/true/voiceDisabled~/false/userMemberIds~/%5B%5D/userId/1ce4078f-f795-4baf-aa55-1fdfcc2ebfe6/isCiamTenant~/false/isCiamTrialTenant~/false)\n- **Status** : Enabled ✅\n- **Include targets** : All users\n- **Enforce attestation** : False\n- **Key restriction policy** :\n - **Enforce key restrictions** : False\n - **Restrict specific keys** : Allow\n\n\n","TestStatus":"Passed","TestDescription":"When passkey authentication isn't enabled in Microsoft Entra ID, organizations rely on password-based authentication methods that are vulnerable to phishing, credential theft, and replay attacks. Attackers can use stolen passwords to gain initial access, bypass traditional multifactor authentication through Adversary-in-the-Middle (AiTM) attacks, and establish persistent access through token theft.\n\nPasskeys provide phishing-resistant authentication using cryptographic proof that attackers can't phish, intercept, or replay. Enabling passkeys eliminates the foundational vulnerability that enables credential-based attack chains.\n\n**Remediation action**\n\n- Learn how to [enable the passkey authentication method](https://learn.microsoft.com/entra/identity/authentication/how-to-enable-passkey-fido2?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci#enable-passkey-fido2-authentication-method).\n- Learn how to [plan a phishing-resistant passwordless authentication deployment](https://learn.microsoft.com/entra/identity/authentication/how-to-plan-prerequisites-phishing-resistant-passwordless-authentication?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci).\n","TestId":"21839"},{"TestImplementationCost":"Medium","TestPillar":"Identity","TestCategory":"Credential management","SkippedReason":null,"TestImpact":"Medium","TestAppliesTo":["Identity"],"TestSfiPillar":"Protect identities and secrets","TestSkipped":"","TestMinimumLicense":"P1","TestTags":["Identity"],"TestTitle":"Weak authentication methods are disabled","TestRisk":"High","TestResult":"\nFound weak authentication methods that are still enabled.\n\n## Weak authentication methods\n| Method ID | Is method weak? | State |\n| :-------- | :-------------- | :---- |\n| Sms | Yes | enabled |\n| Voice | Yes | disabled |\n\n\n","TestStatus":"Failed","TestDescription":"When weak authentication methods like SMS and voice calls remain enabled in Microsoft Entra ID, threat actors can exploit these vulnerabilities through multiple attack vectors. Initially, attackers often conduct reconnaissance to identify organizations using these weaker authentication methods through social engineering or technical scanning. Then they can execute initial access through credential stuffing attacks, password spraying, or phishing campaigns targeting user credentials.\n\nOnce basic credentials are compromised, threat actors use these weaknesses in SMS and voice-based authentication. SMS messages can be intercepted through SIM swapping attacks, SS7 network vulnerabilities, or malware on mobile devices, while voice calls are susceptible to voice phishing (vishing) and call forwarding manipulation. With these weak second factors bypassed, attackers achieve persistence by registering their own authentication methods. Compromised accounts can be used to target higher-privileged users through internal phishing or social engineering, allowing attackers to escalate privileges within the organization. Finally, threat actors achieve their objectives through data exfiltration, lateral movement to critical systems, or deployment of other malicious tools, all while maintaining stealth by using legitimate authentication pathways that appear normal in security logs. \n\n**Remediation action**\n\n- [Deploy authentication method registration campaigns to encourage stronger methods](https://learn.microsoft.com/graph/api/authenticationmethodspolicy-update?view=graph-rest-beta&preserve-view=true&wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci)\n- [Disable authentication methods](https://learn.microsoft.com/entra/identity/authentication/concept-authentication-methods-manage?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci)\n- [Disable phone-based methods in legacy MFA settings](https://learn.microsoft.com/entra/identity/authentication/howto-mfa-mfasettings?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci)\n- [Deploy Conditional Access policies using authentication strength](https://learn.microsoft.com/entra/identity/authentication/concept-authentication-strength-how-it-works?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci)\n","TestId":"21804"},{"TestImplementationCost":"","TestPillar":"Infrastructure","TestCategory":"Manage access and permissions","SkippedReason":null,"TestImpact":"","TestAppliesTo":null,"TestSfiPillar":"Protect tenants and isolate production systems","TestSkipped":"","TestMinimumLicense":"N/A","TestTags":null,"TestTitle":"Guest accounts with owner permissions on Azure resources should be removed","TestRisk":"High","TestResult":"Guest accounts with owner permissions on Azure resources should be removed\n\n| Subscription | Affected resource | Status | Azure portal |\n| :----------- | :---------------- | :----- | :----------- |\n| [Visual Studio Enterprise Subscription](https://portal.azure.com/#resource/subscriptions/54d3ea01-5a07-45d0-8d69-e5f5b0b20098) | [54d3ea01-5a07-45d0-8d69-e5f5b0b20098](https://portal.azure.com/#resource/subscriptions/54d3ea01-5a07-45d0-8d69-e5f5b0b20098) | ❌ | [View recommendation](https://portal.azure.com/#blade/Microsoft_Azure_Security/RecommendationsBlade/assessmentKey/20606e75-05c4-48c0-9d97-add6daa2109a/resourceId/%2fsubscriptions%2f54d3ea01-5a07-45d0-8d69-e5f5b0b20098) |\n","TestStatus":"Failed","TestDescription":"Accounts with owner permissions that have been provisioned outside of the Azure Active Directory tenant (different domain names), should be removed from your Azure resources.
These guest accounts are not managed to the same standards as enterprise tenant identities.
This makes them potential targets for threat actors looking to find ways to access your data without being noticed.
By removing these accounts, you can reduce the risk of unauthorized data access and potential breaches.
\n\n**Remediation action**\n\nReview the list of guest accounts that require access removal on the Accounts section. Select an account to view its role definitions and locate source scope. If you accept the risk for a specific account, use the exempt capability to exclude it from evaluation.
  1. Go to the Azure portal.
  2. Open Access control (IAM) at a scope, such as management group, subscription, resource group, or resource, where the guest user has a role assignment.
  3. Click the Role assignments tab to view all the role assignments.
  4. In the list of role assignments, add a checkmark next to the guest user with the role assignment you want to remove.
  5. Click Remove. In the remove role assignment message that appears, click Yes.
","TestId":"20606e75-05c4-48c0-9d97-add6daa2109a"},{"TestImplementationCost":"Low","TestPillar":"Devices","TestCategory":"Tenant","SkippedReason":null,"TestImpact":"Medium","TestAppliesTo":null,"TestSfiPillar":"Protect tenants and isolate production systems","TestSkipped":"","TestMinimumLicense":"Intune","TestTags":null,"TestTitle":"Device enrollment notification is configured and assigned","TestRisk":"Medium","TestResult":"\nNo device enrollment notification is configured or assigned in Intune.\n\n\n\n","TestStatus":"Failed","TestDescription":"Without device enrollment notifications, users might be unaware that their device has been enrolled in Intune—particularly in cases of unauthorized or unexpected enrollment. This lack of visibility can delay user reporting of suspicious activity and increase the risk of unmanaged or compromised devices gaining access to corporate resources. Attackers who obtain user credentials or exploit self-enrollment flows can silently onboard devices, bypassing user scrutiny and enabling data exposure or lateral movement.\n\nEnrollment notifications provide users with improved visibility into device onboarding activity. They help detect unauthorized enrollment, reinforce secure provisioning practices, and support Zero Trust principles of visibility, verification, and user engagement.\n\n**Remediation action**\n\nConfigure Intune enrollment notifications to alert users when their device is enrolled and reinforce secure onboarding practices: \n- [Set up enrollment notifications in Intune](https://learn.microsoft.com/intune/intune-service/enrollment/enrollment-notifications?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci)\n","TestId":"24572"},{"TestImpact":"Medium","TestRisk":"High","TestSkipped":"NoCompatibleLicenseFound","TestAppliesTo":null,"TestPillar":"Network","TestCategory":"Global Secure Access","TestDescription":"When the Internet Access forwarding profile isn't enabled, users can access internet resources without routing traffic through the Secure Web Gateway. This gap allows threat actors to bypass security controls that block threats, malicious content, and unsafe destinations.\n\nWithout this protection:\n\n- Organizations lose visibility into traffic patterns. They can't detect data exfiltration, connections to malicious domains, or unauthorized external access.\n- Threat actors can deliver malware, establish command and control connections, or exfiltrate data through unmonitored channels.\n- Threat actors can use compromised credentials or social engineering to gain initial access, download tools, establish persistence, or communicate with external infrastructure.\n- Threat actors can use compromised accounts to blend with typical user behavior and access external resources without triggering security alerts based on user context, device compliance, or location.\n\n**Remediation action**\n- Enable the Internet Access forwarding profile to route traffic through the Secure Web Gateway. For more information, see [How to manage the Internet Access traffic forwarding profile](https://learn.microsoft.com/entra/global-secure-access/how-to-manage-internet-access-profile?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci).\n- Assign users and groups to the Internet Access profile to limit traffic forwarding to specific users. For more information, see [Global Secure Access traffic forwarding profiles](https://learn.microsoft.com/entra/global-secure-access/concept-traffic-forwarding?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci).\n","TestTitle":"Internet access forwarding profile is enabled","SkippedReason":"This test requires one of the following licenses: (\"Entra_Premium_Internet_Access\"). Please ensure your tenant has the appropriate licenses to run this test. See [Licensing & Service Plans](https://learn.microsoft.com/entra/identity/users/licensing-service-plan-reference)","TestId":"25406","TestImplementationCost":"Low","TestMinimumLicense":["Entra_Premium_Internet_Access"],"TestSfiPillar":"Protect networks","TestResult":"\nSkipped. This test requires one of the following licenses: (\"Entra_Premium_Internet_Access\"). Please ensure your tenant has the appropriate licenses to run this test. See [Licensing & Service Plans](https://learn.microsoft.com/entra/identity/users/licensing-service-plan-reference)\n\n","TestStatus":"Skipped","TestTags":null},{"TestImplementationCost":"","TestPillar":"Infrastructure","TestCategory":"Implement security best practices","SkippedReason":null,"TestImpact":"","TestAppliesTo":null,"TestSfiPillar":"Protect tenants and isolate production systems","TestSkipped":"","TestMinimumLicense":"N/A","TestTags":null,"TestTitle":"Guest accounts with read permissions on Azure resources should be removed","TestRisk":"High","TestResult":"Guest accounts with read permissions on Azure resources should be removed\n\n| Subscription | Affected resource | Status | Azure portal |\n| :----------- | :---------------- | :----- | :----------- |\n| [Visual Studio Enterprise Subscription](https://portal.azure.com/#resource/subscriptions/54d3ea01-5a07-45d0-8d69-e5f5b0b20098) | [54d3ea01-5a07-45d0-8d69-e5f5b0b20098](https://portal.azure.com/#resource/subscriptions/54d3ea01-5a07-45d0-8d69-e5f5b0b20098) | ✅ | [View recommendation](https://portal.azure.com/#blade/Microsoft_Azure_Security/RecommendationsBlade/assessmentKey/fde1c0c9-0fd2-4ecc-87b5-98956cbc1095/resourceId/%2fsubscriptions%2f54d3ea01-5a07-45d0-8d69-e5f5b0b20098) |\n","TestStatus":"Passed","TestDescription":"Accounts with read permissions that have been provisioned outside of the Azure Active Directory tenant (different domain names), should be removed from your Azure resources.
These guest accounts are not managed to the same standards as enterprise tenant identities.
This makes them potential targets for threat actors looking to find ways to access your data without being noticed.
By removing these accounts, you can reduce the risk of unauthorized data access and potential breaches.
\n\n**Remediation action**\n\nReview the list of guest accounts that require access removal on the Accounts section. Select an account to view its role definitions and locate source scope. If you accept the risk for a specific account, use the exempt capability to exclude it from evaluation.
  1. Go to the Azure portal.
  2. Open Access control (IAM) at a scope, such as management group, subscription, resource group, or resource, where the guest user has a role assignment.
  3. Click the Role assignments tab to view all the role assignments.
  4. In the list of role assignments, add a checkmark next to the guest user with the role assignment you want to remove.
  5. Click Remove. In the remove role assignment message that appears, click Yes.
","TestId":"fde1c0c9-0fd2-4ecc-87b5-98956cbc1095"},{"TestImpact":"Medium","TestRisk":"High","TestSkipped":"","TestAppliesTo":null,"TestPillar":"Data","TestCategory":"Data Security Posture Management","TestDescription":"Collection Policies provide the data ingestion layer that supports monitoring of enterprise AI app activity. When these policies are in place, Communication Compliance can collect signals from AI app interactions and help organizations understand where data protection risks may exist across AI‑enabled workflows. This visibility helps teams apply data protection controls more consistently as AI use expands beyond Microsoft Copilot.\n\t\t\nIn practice, users may accidentally share sensitive data with custom AI applications, Power Automate flows, AI Builder automations, or non‑Microsoft AI services that aren’t approved to handle confidential information. However, Communication Compliance policies that cover enterprise AI app interactions can help surface potential data exposure to these services and extend data protection practices to custom and third‑party AI solutions.\n\n**Remediation action**\n\n- [Create and Deploy collection policies](https://learn.microsoft.com/purview/collection-policies-create-deploy-policy?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci)\n- [Create and manage Communication Compliance policies](https://learn.microsoft.com/purview/communication-compliance-policies?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci)\n","TestTitle":"Communication compliance monitoring is configured for enterprise AI tools","SkippedReason":null,"TestId":"35040","TestImplementationCost":"Medium","TestMinimumLicense":["EXCHANGE_S_ENTERPRISE"],"TestSfiPillar":"Protect tenants and production systems","TestResult":"\n✅ Collection Policies are configured for data ingestion, Communication Compliance rules are configured to target enterprise AI apps (ConnectedAIApp and/or UnifiedGenAIWorkloads identified in RuleXml), AND at least one Communication Compliance policy is ENABLED with a ReviewMailbox configured, enabling the organization to detect and investigate unauthorized data sharing and policy violations through enterprise AI interactions.\n\n\n### [Data ingestion layer (Collection policies)](https://purview.microsoft.com/cc/dataclassification/dataandactivitydiscovery?tid=0817c655-a853-4d8f-9723-3a333b5b9235)\n\n| Policy name | Enabled | Mode | Workload | Activities | Enforcement planes | Created by | Last modified | Policy category |\n| :---------- | :------ | :--- | :------- | :--------- | :----------------- | :--------- | :------------ | :-------------- |\n| 35040-Test | ❌ False | ❌ Disable | Exchange, EndpointDevices, Applications | UploadText, DownloadText | Entra | Cameron Anderson | 2026-02-13 | ApplicableToAI |\n| 35040-test2 | ✅ True | ✅ Enable | Exchange, EndpointDevices | filecreated | Devices | Cameron Anderson | 2026-02-20 | ApplicableToAI |\n| DSPM for AI - Capture interactions for Copilot experiences | ✅ True | ✅ Enable | Exchange, Applications | UploadText, DownloadText | CopilotExperiences | Dakota Lee Test | 2026-05-11 | ApplicableToAI |\n| DSPM for AI - Capture interactions for enterprise AI apps | ✅ True | ✅ Enable | Exchange, Applications | UploadText, DownloadText | Entra | Dakota Lee Test | 2026-05-11 | ApplicableToAI |\n| DSPM for AI - Detect sensitive info shared with AI via network | ✅ True | ✅ Enable | Exchange, Applications | UploadText, UploadFile, DownloadText, DownloadFile | Network | Dakota Lee Test | 2026-05-11 | ApplicableToAI |\n\n### [Communication Compliance rules targeting Enterprise AI Apps](https://purview.microsoft.com/cc/policies?tid=0817c655-a853-4d8f-9723-3a333b5b9235)\n\n| Rule name | Associated policy | Workloads | UnifiedGenAIWorkloads |\n| :-------- | :---------------- | :-------- | :-------------------- |\n| Enterprise AI CC Test_Exchange_Content, Enterprise AI CC Test_Exchange_InPurview | Enterprise AI CC Test | ConnectedAIApp | ChatGPT.Enterprise, EntraApp, AzureAI |\n\n### [Enabled policies with review mailbox](https://purview.microsoft.com/cc/policies?tid=0817c655-a853-4d8f-9723-3a333b5b9235)\n\n| Policy name | Enabled | Review mailbox |\n| :---------- | :------ | :------------- |\n| Copilot Data Protection | ✅ True | ✅ SupervisoryReview{3bbbbd4f-cc0a-45ff-b0f5-c6023124c881}@contoso.onmicrosoft.com |\n| Custom Policy 35040 | ✅ True | ✅ SupervisoryReview{8fb152db-0f94-45f9-b29c-8764f3a5ccef}@contoso.onmicrosoft.com |\n| Enterprise AI CC Test | ✅ True | ✅ SupervisoryReview{efe29507-f54b-430a-8a92-f67bd2385dec}@contoso.onmicrosoft.com |\n| Microsoft 365 Copilot interactions | ✅ True | ✅ SupervisoryReview{8ce4a232-c7cf-4712-aee9-f02c9a9cd3e8}@contoso.onmicrosoft.com |\n| test1 | ✅ True | ✅ SupervisoryReview{7a05811d-28e7-4163-a013-d57c554fca5f}@contoso.onmicrosoft.com |\n\n\n**Summary:**\n- Collection Policies Configured: 5\n- Enterprise AI Rules Detected (with ConnectedAIApp or UnifiedGenAIWorkloads): 1\n- Policies Enabled with ReviewMailbox: 5\n\n","TestStatus":"Passed","TestTags":null},{"TestImpact":"Low","TestRisk":"High","TestSkipped":"NoCompatibleLicenseFound","TestAppliesTo":null,"TestPillar":"Network","TestCategory":"Global Secure Access","TestDescription":"Traffic forwarding profiles are the foundational mechanism through which Global Secure Access captures and routes network traffic to Microsoft's Security Service Edge infrastructure. If you don't enable the appropriate traffic forwarding profiles, network traffic bypasses the Global Secure Access service entirely, and users don't get these network access protections.\n\nThere are three distinct profiles:\n\n- **Microsoft traffic profile**: Captures Microsoft Entra ID, Microsoft Graph, SharePoint Online, Exchange Online, and other Microsoft 365 workloads.\n- **Private access profile**: Captures traffic destined for internal corporate resources.\n- **Internet access profile**: Captures traffic to the public internet including non-Microsoft SaaS applications.\n\nIf you don't enable these profiles:\n\n- You can't enforce security policies, web content filtering, threat protection, or Universal Continuous Access Evaluation.\n- Threat actors who compromise user credentials can access corporate resources without the security controls that Global Secure Access would otherwise apply.\n\n**Remediation action**\n\n- Enable the Microsoft traffic forwarding profile. For more information, see [Manage the Microsoft traffic profile](https://learn.microsoft.com/entra/global-secure-access/how-to-manage-microsoft-profile?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci).\n- Enable the Private Access traffic forwarding profile. For more information, see [Manage the Private Access traffic forwarding profile](https://learn.microsoft.com/entra/global-secure-access/how-to-manage-private-access-profile?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci).\n- Enable the Internet Access traffic forwarding profile. For more information, see [Manage the Internet Access traffic forwarding profile](https://learn.microsoft.com/entra/global-secure-access/how-to-manage-internet-access-profile?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci).\n","TestTitle":"Network traffic is routed through Global Secure Access for security policy enforcement","SkippedReason":"This test requires one of the following licenses: (\"Entra_Premium_Private_Access\") OR (\"Entra_Premium_Internet_Access\"). Please ensure your tenant has the appropriate licenses to run this test. See [Licensing & Service Plans](https://learn.microsoft.com/entra/identity/users/licensing-service-plan-reference)","TestId":"25381","TestImplementationCost":"Medium","TestMinimumLicense":["Entra_Premium_Private_Access","Entra_Premium_Internet_Access"],"TestSfiPillar":"Protect networks","TestResult":"\nSkipped. This test requires one of the following licenses: (\"Entra_Premium_Private_Access\") OR (\"Entra_Premium_Internet_Access\"). Please ensure your tenant has the appropriate licenses to run this test. See [Licensing & Service Plans](https://learn.microsoft.com/entra/identity/users/licensing-service-plan-reference)\n\n","TestStatus":"Skipped","TestTags":null},{"TestImplementationCost":"","TestPillar":"Infrastructure","TestCategory":"Remediate security configurations","SkippedReason":"This test is not applicable to the current environment.","TestImpact":"","TestAppliesTo":null,"TestSfiPillar":"Protect tenants and isolate production systems","TestSkipped":"NotApplicable","TestMinimumLicense":"N/A","TestTags":null,"TestTitle":"Vulnerabilities in security configuration on your Windows machines should be remediated (powered by Guest Configuration)","TestRisk":"Low","TestResult":"UnsupportedPricingPlan\n\n| Subscription | Resource group | Resource type | Affected resource | Status | Azure portal |\n| :----------- | :------------- | :------------ | :---------------- | :----- | :----------- |\n| [Visual Studio Enterprise Subscription](https://portal.azure.com/#resource/subscriptions/54d3ea01-5a07-45d0-8d69-e5f5b0b20098) | indiavm_group | virtualmachines | [india-2](https://portal.azure.com/#resource/subscriptions/54d3ea01-5a07-45d0-8d69-e5f5b0b20098/resourceGroups/indiavm_group/providers/Microsoft.Compute/virtualMachines/india-2) | N/A | [View recommendation](https://portal.azure.com/#blade/Microsoft_Azure_Security/RecommendationsBlade/assessmentKey/8c3d9ad0-3639-4686-9cd2-2b2ab2609bda/resourceId/%2fsubscriptions%2f54d3ea01-5a07-45d0-8d69-e5f5b0b20098%2fresourceGroups%2findiavm_group%2fproviders%2fMicrosoft.Compute%2fvirtualMachines%2findia-2) |\n| [Visual Studio Enterprise Subscription](https://portal.azure.com/#resource/subscriptions/54d3ea01-5a07-45d0-8d69-e5f5b0b20098) | indiavm_group | virtualmachines | [indiavm](https://portal.azure.com/#resource/subscriptions/54d3ea01-5a07-45d0-8d69-e5f5b0b20098/resourceGroups/indiavm_group/providers/Microsoft.Compute/virtualMachines/indiavm) | N/A | [View recommendation](https://portal.azure.com/#blade/Microsoft_Azure_Security/RecommendationsBlade/assessmentKey/8c3d9ad0-3639-4686-9cd2-2b2ab2609bda/resourceId/%2fsubscriptions%2f54d3ea01-5a07-45d0-8d69-e5f5b0b20098%2fresourceGroups%2findiavm_group%2fproviders%2fMicrosoft.Compute%2fvirtualMachines%2findiavm) |\n","TestStatus":"Skipped","TestDescription":"Addressing vulnerabilities in the security configuration of Windows machines is important to safeguard them from potential attacks.
These vulnerabilities, if left unattended, could be exploited by attackers to gain unauthorized access or disrupt system operations.
Remediation, powered by Guest Configuration, helps to ensure the security and integrity of the system, thereby reducing the risk of compromise.
\n\n**Remediation action**\n\n1. Select any of the findings below.
2. On the right pane opened, follow the instructions under 'Remediation' if exist.","TestId":"8c3d9ad0-3639-4686-9cd2-2b2ab2609bda"},{"TestImplementationCost":"Low","TestPillar":"Network","TestCategory":"Private Access","SkippedReason":null,"TestImpact":"Medium","TestAppliesTo":null,"TestSfiPillar":"Protect networks","TestSkipped":"","TestMinimumLicense":"Entra_Premium_Private_Access","TestTags":null,"TestTitle":"At least two Private Access connectors are active and healthy per connector group","TestRisk":"High","TestResult":"\n❌ One or more Private Access connector groups have fewer than two active connectors, exposing private application access to a single point of failure.\n\n\n#### [Private Access Connector Groups](https://entra.microsoft.com/#view/Microsoft_Entra_GSA_Connect/Connectors.ReactView)\n\n| Connector group name | Region | Active connectors | Total connectors | Status |\n| :------------------- | :----- | ----------------: | ---------------: | :----- |\n| Default | aus | 0 | 0 | ❌ Fail |\n\n\n#### Connector Details for Failing Groups\n\n**Connector Group: Default** (Region: aus)\n\n_No connectors found in this group._\n\n\n","TestStatus":"Failed","TestDescription":"Microsoft Entra Private Access relies on private network connectors—lightweight Windows Server agents that broker outbound connections from on-premises or cloud-hosted networks to the Global Secure Access service. Each connector group acts as the sole access path for the private applications assigned to it. If only one connector is deployed in a group serving a region, any failure of that host—whether due to a hardware fault, OS crash, scheduled patch reboot, or a threat actor deliberately disrupting connector host connectivity—immediately eliminates all private application access for users in that region. A threat actor who achieves enough access to terminate the connector Windows service or block its outbound TLS communication on ports 443/80 can silently deny access to private applications without triggering identity-layer alerts. The service marks a connector `inactive` after it stops heartbeating and removes it after 10 days; during that window, no automated failover occurs if it was the sole connector in the group. Because Private Access enforces Conditional Access policies at the point of connection—requiring the connector to be reachable to validate session tokens and enforce per-app policies—a downed single connector means Zero Trust controls cannot be applied, and users are denied access rather than routed through an alternative enforcement point. Microsoft documentation explicitly states: \"maintain a minimum of two healthy connectors to ensure resiliency and consistent availability,\" and \"you might experience downtime during an update if you have only one connector.\" Deploying at least two active connectors per connector group ensures load balancing, seamless automatic updates (which target one connector at a time), and continuity of Zero Trust enforcement if one connector fails.\n\n**Remediation action**\n\nInstall and register an additional private network connector on a Windows Server in the affected region\n- [How to configure private network connectors for Microsoft Entra Private Access](https://learn.microsoft.com/en-us/entra/global-secure-access/how-to-configure-connectors)\n\nUnderstand connector group high-availability requirements and best practices\n- [Microsoft Entra private network connectors — Connector groups](https://learn.microsoft.com/en-us/entra/global-secure-access/concept-connectors#connector-groups)\n\nReview sizing and resiliency guidance including the minimum two-connector recommendation\n- [Microsoft Entra private network connectors — Specifications and sizing requirements](https://learn.microsoft.com/en-us/entra/global-secure-access/concept-connectors#specifications-and-sizing-requirements)\n\nApplication Proxy high-availability load balancing best practices applicable to Private Access connector groups\n- [Best practices for high availability of connectors](https://learn.microsoft.com/en-us/entra/identity/app-proxy/application-proxy-high-availability-load-balancing#best-practices-for-high-availability-of-connectors)\n\nTroubleshoot inactive or malfunctioning connectors\n- [Troubleshoot connectors](https://learn.microsoft.com/en-us/entra/global-secure-access/troubleshoot-connectors)\n\n\n","TestId":"25466"},{"TestImplementationCost":"Low","TestPillar":"Identity","TestCategory":"Access control","SkippedReason":"UnderConstruction","TestImpact":"Low","TestAppliesTo":["Identity"],"TestSfiPillar":"Protect identities and secrets","TestSkipped":"UnderConstruction","TestMinimumLicense":null,"TestTags":["Identity"],"TestTitle":"No Active Medium priority Entra recommendations found","TestRisk":"Medium","TestResult":"\nPlanned for future release.\n","TestStatus":"Planned","TestDescription":"...\n\n**Remediation action**\n\n","TestId":"21983"},{"TestImpact":"Low","TestRisk":"High","TestSkipped":"","TestAppliesTo":null,"TestPillar":"Data","TestCategory":"Data Security Posture Management","TestDescription":"Purview audit logging logs who accessed sensitive data, when policy violations occurred, and what administrative actions were taken across Microsoft 365. When audit logs are available, security teams can investigate incidents, perform eDiscovery, detect insider threats, and demonstrate controls to auditors and regulators.\n\nWithout audit logging enabled, threat actors can often operate undetected, and incident response becomes impossible due to lack of evidence. Organizations that fail to enable audit logging also risk noncompliance with regulatory requirements that mandate activity logging for sensitive operations.\n\n**Remediation action**\n\n- [Turn auditing on or off](https://learn.microsoft.com/purview/audit-log-enable-disable?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci)\n","TestTitle":"Purview audit logging enabled","SkippedReason":null,"TestId":"35037","TestImplementationCost":"Low","TestMinimumLicense":["RMS_S_PREMIUM"],"TestSfiPillar":"Protect tenants and production systems","TestResult":"\n❌ Purview Audit Logging is DISABLED, creating a critical visibility gap where unauthorized access, policy violations, and security incidents cannot be detected or investigated.\n\n\n\n### [Audit logging status](https://purview.microsoft.com/audit)\n| Configuration property | Value |\n| :--- | :--- |\n| Unified audit log ingestion enabled | False |\n| Audit log age limit | 90.00:00:00 |\n| Organization ID | FFO.extest.microsoft.com/Microsoft Exchange Hosted Organizations/contoso.onmicrosoft.com - FFO.extest.microsoft.com/Microsoft Exchange Hosted Organizations/contoso.onmicrosoft.com/Configuration |\n\n","TestStatus":"Failed","TestTags":null},{"TestImpact":"High","TestRisk":"High","TestSkipped":"","TestAppliesTo":null,"TestPillar":"Data","TestCategory":"Rights Management Service","TestDescription":"The Azure Rights Management service provides the foundational encryption and access control technology for Microsoft Purview Information Protection. It's used with sensitivity labels that apply encryption, protects emails with Microsoft Purview Message Encryption, and even used with the older protection technologies such as SharePoint IRM and mail flow rules that apply encryption. This service should be activated for the tenant before you configure any other information protection features.\n\n**Remediation action**\n\n- [Activate the Azure Rights Management service](https://learn.microsoft.com/purview/activate-rights-management-service?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci)\n","TestTitle":"Azure RMS Licensing Enabled","SkippedReason":null,"TestId":"35024","TestImplementationCost":"Low","TestMinimumLicense":["RMS_S_PREMIUM"],"TestSfiPillar":"Protect tenants and production systems","TestResult":"\n✅ Azure RMS is enabled at the tenant level, enabling all downstream encryption and rights management capabilities.\n\n\n### Azure RMS Status\n\n| Setting | Value |\n| :------ | :---- |\n| AzureRMSLicensingEnabled | True |\n| SimplifiedClientAccessEnabled | True |\n| InternalLicensingEnabled | True |\n| ExternalLicensingEnabled | True |\n| Configuration Created | 07/07/2020 05:00:17 |\n\n\n**Summary:**\n\n Azure RMS Service: ✅ Enabled\n\n\n","TestStatus":"Passed","TestTags":null},{"TestImplementationCost":"Medium","TestPillar":"Identity","TestCategory":"Privileged access","SkippedReason":"UnderConstruction","TestImpact":"Low","TestAppliesTo":["Identity"],"TestSfiPillar":"Monitor and detect cyberthreats","TestSkipped":"UnderConstruction","TestMinimumLicense":"P1","TestTags":["Authentication"],"TestTitle":"Privileged users sign in with phishing-resistant methods","TestRisk":"High","TestResult":"\nFound Accounts have not registered phishing resistant methods\n\n\n\n","TestStatus":"Planned","TestDescription":"Without phishing-resistant authentication methods, privileged users are more vulnerable to phishing attacks. These types of attacks trick users into revealing their credentials to grant unauthorized access to attackers. If non-phishing-resistant authentication methods are used, attackers might intercept credentials and tokens, through methods like adversary-in-the-middle attacks, undermining the security of the privileged account.\n\nOnce a privileged account or session is compromised due to weak authentication methods, attackers might manipulate the account to maintain long-term access, create other backdoors, or modify user permissions. Attackers can also use the compromised privileged account to escalate their access even further, potentially gaining control over more sensitive systems.\n\n**Remediation action**\n\n- [Get started with a phishing-resistant passwordless authentication deployment](https://learn.microsoft.com/entra/identity/authentication/how-to-plan-prerequisites-phishing-resistant-passwordless-authentication?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci)\n- [Ensure that privileged accounts register and use phishing resistant methods](https://learn.microsoft.com/entra/identity/authentication/concept-authentication-strengths?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci#authentication-strengths)\n- [Deploy a Conditional Access policy to target privileged accounts and require phishing resistant credentials](https://learn.microsoft.com/entra/identity/conditional-access/policy-admin-phish-resistant-mfa?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci)\n- [Monitor authentication method activity](https://learn.microsoft.com/entra/identity/monitoring-health/concept-usage-insights-report?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci#authentication-methods-activity)\n","TestId":"21781"},{"TestImplementationCost":"Low","TestPillar":"Network","TestCategory":"Azure Network Security","SkippedReason":"This test is not applicable to the current environment.","TestImpact":"Low","TestAppliesTo":null,"TestSfiPillar":"Protect networks","TestSkipped":"NotApplicable","TestMinimumLicense":"Azure_Firewall_Premium","TestTags":null,"TestTitle":"IDPS Inspection is Enabled in Deny Mode on Azure Firewall","TestRisk":"High","TestResult":"\nSkipped. This test is not applicable to the current environment.\n\n","TestStatus":"Skipped","TestDescription":"Azure Firewall Premium provides signature-based intrusion detection and prevention (IDPS) that identifies attacks by detecting specific patterns in network traffic, such as byte sequences and known malicious instruction sequences used by malware. IDPS applies to inbound, east-west (spoke-to-spoke), and outbound traffic across Layers 3-7. When IDPS isn't configured in `Alert and deny` mode, Azure Firewall only logs detected threats without blocking them.\n\nWithout IDPS enabled in `Alert and deny` mode:\n\n- Threat actors can send traffic that matches known attack signatures without being blocked.\n- Organizations running IDPS in `Alert only` mode gain visibility into threats but can't prevent intrusion attempts from reaching their workloads.\n- Lateral movement and exfiltration traffic that matches known attack signatures passes through the firewall without active intervention.\n\n**Remediation action**\n\n- [Enable IDPS in Alert and Deny mode in Azure Firewall Premium](https://learn.microsoft.com/azure/firewall/premium-features?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci) by configuring the intrusion detection mode to `Alert and deny` in the firewall policy.\n","TestId":25539},{"TestImplementationCost":"High","TestPillar":"Identity","TestCategory":"Privileged access","SkippedReason":null,"TestImpact":"Low","TestAppliesTo":["Identity"],"TestSfiPillar":"Protect identities and secrets","TestSkipped":"","TestMinimumLicense":"P2","TestTags":["Identity"],"TestTitle":"All privileged role assignments are activated just in time and not permanently active","TestRisk":"High","TestResult":"\nPrivileged users with permanent role assignments were found.\n\n\n## Privileged users with permanent role assignments\n\n\n| User | UPN | Role Name | Assignment Type |\n| :--- | :-- | :-------- | :-------------- |\n| [Reese Harris](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/AdministrativeRole/userId/babe04c9-8340-4329-a727-a8cee0cd2b1a/hidePreviewBanner~/true) | reese@contoso.com | Global Administrator | Permanent |\n| [Jordan Smith](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/AdministrativeRole/userId/bfaeba1e-1357-47de-9557-529caa103d5d/hidePreviewBanner~/true) | jordan@contoso.com | Application Administrator | Permanent |\n| [Jordan Smith](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/AdministrativeRole/userId/bfaeba1e-1357-47de-9557-529caa103d5d/hidePreviewBanner~/true) | jordan@contoso.com | AI Administrator | Permanent |\n| [Dakota Lee](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/AdministrativeRole/userId/e4bc6f4a-124f-469b-8951-3d5c34fb9741/hidePreviewBanner~/true) | dakota@contoso.com | User Administrator | Permanent |\n| [Avery Brooks](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/AdministrativeRole/userId/a85798bd-652b-4eb9-ba90-3ee882df0179/hidePreviewBanner~/true) | avery.brooks@contoso.com | Global Administrator | Permanent |\n| [Finley Robinson](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/AdministrativeRole/userId/990fd38a-c516-4e3f-82e4-d458a1ab0f91/hidePreviewBanner~/true) | finley.robinson@contoso.com | Global Administrator | Permanent |\n| [Finley Robinson](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/AdministrativeRole/userId/990fd38a-c516-4e3f-82e4-d458a1ab0f91/hidePreviewBanner~/true) | finley.robinson@contoso.com | Global Reader | Permanent |\n| [Taylor Brown](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/AdministrativeRole/userId/2072badc-3cf0-4e84-b4c2-f9c065c46165/hidePreviewBanner~/true) | taylor@contoso.com | Global Administrator | Permanent |\n| [Jamie Rodriguez](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/AdministrativeRole/userId/0b37813c-ae19-4399-982f-16587f17f9c0/hidePreviewBanner~/true) | jamie@contoso.com | Global Administrator | Permanent |\n| [Cameron Anderson](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/AdministrativeRole/userId/1ce4078f-f795-4baf-aa55-1fdfcc2ebfe6/hidePreviewBanner~/true) | cameron@contoso.com | Global Reader | Permanent |\n| [Drew Mitchell](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/AdministrativeRole/userId/df02402a-e291-42cc-b449-79366daa2a40/hidePreviewBanner~/true) | drew@contoso.com | Application Administrator | Permanent |\n| [Cameron Anderson](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/AdministrativeRole/userId/1ce4078f-f795-4baf-aa55-1fdfcc2ebfe6/hidePreviewBanner~/true) | cameron@contoso.com | Security Administrator | Permanent |\n| [Sage Bennett](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/AdministrativeRole/userId/518ce209-faf4-4717-add9-7129a669fa11/hidePreviewBanner~/true) | sage@contoso.com | Agent ID Administrator | Permanent |\n| [Sage Bennett](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/AdministrativeRole/userId/518ce209-faf4-4717-add9-7129a669fa11/hidePreviewBanner~/true) | sage@contoso.com | Global Administrator | Permanent |\n| [PimLevel](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/AdministrativeRole/userId/e8971185-8150-402e-b90f-5c1eb0d30dfe/hidePreviewBanner~/true) | | Application Administrator | Permanent |\n| [Ellis Cooper](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/AdministrativeRole/userId/1433571b-3d7c-4a56-a9cc-67580848bc73/hidePreviewBanner~/true) | ellis@contoso.com | Global Administrator | Permanent |\n| [Dakota Lee Test](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/AdministrativeRole/userId/43482f27-d1af-420f-84ba-e9148a700f45/hidePreviewBanner~/true) | dakota-test@contoso.com | Global Administrator | Permanent |\n| [Mailbox Migration Account](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/AdministrativeRole/userId/d22f071d-e8d3-41fc-a516-b29753cdd1f6/hidePreviewBanner~/true) | | Application Administrator | Permanent |\n| [Cameron Anderson](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/AdministrativeRole/userId/1ce4078f-f795-4baf-aa55-1fdfcc2ebfe6/hidePreviewBanner~/true) | cameron@contoso.com | Global Administrator | Permanent |\n| [Custom-App-Test](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/AdministrativeRole/userId/38415a71-b77b-44d5-a276-539faabe0de7/hidePreviewBanner~/true) | | Global Administrator | Permanent |\n| [Quinn Garcia](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/AdministrativeRole/userId/ceef37b7-c865-48fb-80c9-4def11201854/hidePreviewBanner~/true) | quinn@contoso.com | Global Administrator | Permanent |\n| [Peyton Clark](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/AdministrativeRole/userId/7e92f268-bb12-469a-a869-210d596d4c1f/hidePreviewBanner~/true) | peyton@contoso.com | Global Administrator | Permanent |\n| [Drew Mitchell](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/AdministrativeRole/userId/df02402a-e291-42cc-b449-79366daa2a40/hidePreviewBanner~/true) | drew@contoso.com | Global Administrator | Permanent |\n| [Mailbox Migration Account](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/AdministrativeRole/userId/d22f071d-e8d3-41fc-a516-b29753cdd1f6/hidePreviewBanner~/true) | | Global Administrator | Permanent |\n| [Hayden Scott Test](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/AdministrativeRole/userId/6f467d0a-25ec-435c-8fb9-9d53eb21e02f/hidePreviewBanner~/true) | hayden-test@contoso.com | Global Reader | Permanent |\n| [peyton-test](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/AdministrativeRole/userId/e0952dcb-8d63-496d-8661-05c86c1a51f0/hidePreviewBanner~/true) | peyton-test@contoso.com | Global Reader | Permanent |\n| [Jordan Smith](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/AdministrativeRole/userId/bfaeba1e-1357-47de-9557-529caa103d5d/hidePreviewBanner~/true) | jordan@contoso.com | Global Administrator | Permanent |\n| [contoso-tenant-devops-7576c63d-bc90-4ae4-9f1c-0d959fb520db](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/AdministrativeRole/userId/c5632968-35cd-445d-926e-16e0afc9160e/hidePreviewBanner~/true) | | Global Administrator | Permanent |\n| [Ash Williams](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/AdministrativeRole/userId/513f3db2-044c-41be-af14-431bf88a2b3e/hidePreviewBanner~/true) | ash@contoso.com | Global Administrator | Permanent |\n| [parker-test](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/AdministrativeRole/userId/c1bdb03c-0079-40b1-96a8-3595de3b94a2/hidePreviewBanner~/true) | parker-test@contoso.com | Global Reader | Permanent |\n| [Drew Mitchell](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/AdministrativeRole/userId/df02402a-e291-42cc-b449-79366daa2a40/hidePreviewBanner~/true) | drew@contoso.com | Global Reader | Permanent |\n| [Sage Bennett](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/AdministrativeRole/userId/518ce209-faf4-4717-add9-7129a669fa11/hidePreviewBanner~/true) | sage@contoso.com | Global Reader | Permanent |\n| [ash-williams-test](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/AdministrativeRole/userId/c5c8ba63-4620-4e91-ac40-b66bebe07a0d/hidePreviewBanner~/true) | ash.test@contoso.com | Global Reader | Permanent |\n| [Phoenix Gray](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/AdministrativeRole/userId/7094fb23-003a-4f81-9796-5daeaa603003/hidePreviewBanner~/true) | phoenix@contoso.com | Global Administrator | Permanent |\n| [Hayden Scott](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/AdministrativeRole/userId/c0b65b13-37b1-4081-bcfc-14844159b4a5/hidePreviewBanner~/true) | hayden@contoso.com | Global Administrator | Permanent |\n| [Hayden Scott](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/AdministrativeRole/userId/0d6cfd05-fc46-440b-b605-66dd26dcd7d2/hidePreviewBanner~/true) | hayden.p@contoso.com | Global Reader | Permanent |\n| [Peyton Clark](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/AdministrativeRole/userId/7e92f268-bb12-469a-a869-210d596d4c1f/hidePreviewBanner~/true) | peyton@contoso.com | Global Reader | Permanent |\n| [finley-test](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/AdministrativeRole/userId/d71ccc09-c0a3-4604-9d02-49f7a3715f49/hidePreviewBanner~/true) | finley-test@contoso.com | Global Reader | Permanent |\n| [Jules Bailey](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/AdministrativeRole/userId/0145d508-50fd-4f86-a47a-bf1c043c8358/hidePreviewBanner~/true) | jules@contoso.com | Global Administrator | Permanent |\n| [Dakota Lee](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/AdministrativeRole/userId/210d3e96-015f-462d-b6d6-81e6023263df/hidePreviewBanner~/true) | guest-user_external.com#EXT#@contoso.com | Global Administrator | Permanent |\n| [Charlie Lewis](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/AdministrativeRole/userId/5b0ec3ff-cea1-4eb9-8530-f2a66e5bec0a/hidePreviewBanner~/true) | charlie@contoso.com | Global Administrator | Permanent |\n| [Avery Thomas](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/AdministrativeRole/userId/f431700c-6d81-45b8-8f8d-581a8aa7cda6/hidePreviewBanner~/true) | avery@contoso.com | Global Administrator | Permanent |\n\n\n\n","TestStatus":"Failed","TestDescription":"Threat actors target privileged accounts because they have access to the data and resources they want. This might include more access to your Microsoft Entra tenant, data in Microsoft SharePoint, or the ability to establish long-term persistence. Without a just-in-time (JIT) activation model, administrative privileges remain continuously exposed, providing attackers with an extended window to operate undetected. Just-in-time access mitigates risk by enforcing time-limited privilege activation with extra controls such as approvals, justification, and Conditional Access policy, ensuring that high-risk permissions are granted only when needed and for a limited duration. This restriction minimizes the attack surface, disrupts lateral movement, and forces adversaries to trigger actions that can be specially monitored and denied when not expected. Without just-in-time access, compromised admin accounts grant indefinite control, letting attackers disable security controls, erase logs, and maintain stealth, amplifying the impact of a compromise.\n\nUse Microsoft Entra Privileged Identity Management (PIM) to provide time-bound just-in-time access to privileged role assignments. Use access reviews in Microsoft Entra ID Governance to regularly review privileged access to ensure continued need.\n\n**Remediation action**\n\n- [Start using Privileged Identity Management](https://learn.microsoft.com/entra/id-governance/privileged-identity-management/pim-getting-started?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci)\n- [Create an access review of Azure resource and Microsoft Entra roles in PIM](https://learn.microsoft.com/entra/id-governance/privileged-identity-management/pim-create-roles-and-resource-roles-review?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci)\n","TestId":"21815"},{"TestImplementationCost":"Low","TestPillar":"Devices","TestCategory":"Data","SkippedReason":null,"TestImpact":"Low","TestAppliesTo":null,"TestSfiPillar":"Protect networks","TestSkipped":"","TestMinimumLicense":"Intune","TestTags":null,"TestTitle":"Secure Wi-Fi profiles protect Android devices from unauthorized network access","TestRisk":"High","TestResult":"\nNo Enterprise Wi-Fi profile for android exists or none are assigned.\n\n\n\n","TestStatus":"Failed","TestDescription":"If Wi-Fi profiles aren't properly configured and assigned, Android devices can fail to connect to secure networks or connect insecurely, exposing corporate data to interception or unauthorized access. Without centralized management, devices rely on manual configuration, increasing the risk of misconfiguration, weak authentication, and connection to rogue networks.\n\nCentrally managing Wi-Fi profiles for Android devices in Intune ensures secure and consistent connectivity to enterprise networks. This enforces authentication and encryption standards, simplifies onboarding, and supports Zero Trust by reducing exposure to untrusted networks.\n\n\n\nUse Intune to configure secure Wi-Fi profiles that enforce authentication and encryption standards.\n\n**Remediation action**\n\nUse Intune to configure and assign secure Wi-Fi profiles for Android devices to enforce authentication and encryption standards: \n- [Deploy Wi-Fi profiles to devices in Microsoft Intune](https://learn.microsoft.com/intune/intune-service/configuration/wi-fi-settings-configure?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci#create-the-profile)\n\nFor more information, see: \n- [Review the available Wi-Fi settings for Android devices in Microsoft Intune](https://learn.microsoft.com/intune/intune-service/configuration/wi-fi-settings-android-enterprise?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci)\n","TestId":"24840"},{"TestImpact":"Medium","TestRisk":"Medium","TestSkipped":"","TestAppliesTo":null,"TestPillar":"Data","TestCategory":"Advanced Classification","TestDescription":"Trainable classifiers are machine learning-based classifiers that recognize content by meaning and context rather than fixed patterns. Unlike sensitive information types that match predefined formats, trainable classifiers can identify unstructured content like strategic plans, financial reports, or HR documents. Using trainable classifiers in auto-labeling policies, and data loss prevention (DLP) rules, extends protection to sensitive business content that pattern-based rules can't reliably capture.\n\n**Remediation action**\n\n- [Learn about trainable classifiers](https://learn.microsoft.com/purview/classifier-learn-about?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci)\n- [Get started with trainable classifiers](https://learn.microsoft.com/purview/trainable-classifiers-get-started-with?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci)\n","TestTitle":"Trainable Classifiers Usage in Policies","SkippedReason":null,"TestId":"35036","TestImplementationCost":"High","TestMinimumLicense":["EXCHANGE_S_ENTERPRISE"],"TestSfiPillar":"Protect tenants and production systems","TestResult":"\n✅ Trainable classifiers are integrated into auto-labeling and/or DLP policies, enabling AI-powered content classification for complex business documents.\n\n\n## [Trainable Classifier Usage in Policies](https://purview.microsoft.com/informationprotection/dataclassification/trainableclassifiers)\n\n**Trainable Classifiers in Auto-Labeling Rules:**\n\n| Rule name | Parent policy | Created date | Classifiers in rule |\n| :-------- | :------------ | :----------- | :------------------ |\n| U.S. Patriot Act Enhanced-ODB | U.S. Patriot Act Enhanced | 2026-02-05 | Targeted Harassment, Profanity |\n\n**Trainable Classifiers in DLP Rules:**\n\n| Rule name | Parent policy | Created date | Classifiers in rule |\n| :-------- | :------------ | :----------- | :------------------ |\n| test036 | Endpoint DLP - Financial Data | 2026-02-06 | Source code, Targeted Harassment, Profanity, Threat, Resume, ... |\n\n\n\n**Summary:**\n* Total Auto-Labeling Rules Using Classifiers: 1\n* Total DLP Rules Using Classifiers: 1\n\n\n","TestStatus":"Passed","TestTags":null},{"TestImpact":"Medium","TestRisk":"High","TestSkipped":"NoCompatibleLicenseFound","TestAppliesTo":null,"TestPillar":"Network","TestCategory":"Global Secure Access","TestDescription":"TLS inspection decrypts and inspects HTTPS traffic, enabling visibility into encrypted sessions. Without it, many Microsoft Entra Internet Access features can't function, including URL filtering and advanced threat detection. Most internet traffic is encrypted, so TLS inspection is essential for applying security policies to most user activity.\n\n**Remediation action**\n\n- [Configure Transport Layer Security Inspection Policies](https://learn.microsoft.com/entra/global-secure-access/how-to-transport-layer-security?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci)\n","TestTitle":"TLS inspection is enabled and correctly configured for outbound traffic","SkippedReason":"This test requires one of the following licenses: (\"Entra_Premium_Internet_Access\"). Please ensure your tenant has the appropriate licenses to run this test. See [Licensing & Service Plans](https://learn.microsoft.com/entra/identity/users/licensing-service-plan-reference)","TestId":"25411","TestImplementationCost":"High","TestMinimumLicense":["Entra_Premium_Internet_Access"],"TestSfiPillar":"Protect networks","TestResult":"\nSkipped. This test requires one of the following licenses: (\"Entra_Premium_Internet_Access\"). Please ensure your tenant has the appropriate licenses to run this test. See [Licensing & Service Plans](https://learn.microsoft.com/entra/identity/users/licensing-service-plan-reference)\n\n","TestStatus":"Skipped","TestTags":null},{"TestImpact":"Medium","TestRisk":"High","TestSkipped":"NoCompatibleLicenseFound","TestAppliesTo":null,"TestPillar":"Network","TestCategory":"Global Secure Access","TestDescription":"When organizations configure Microsoft Entra Private Access with broad application segments—such as wide IP ranges or multiple protocols—they effectively replicate the over-permissive access model of traditional VPNs. This approach contradicts the Zero Trust principle of least-privilege access, where users should only reach the specific resources required for their role. Threat actors who compromise a user's credentials or device can leverage these broad network permissions to perform reconnaissance, identifying additional systems and services within the permitted range. \n\nWith visibility into the network topology, they can escalate privileges by targeting vulnerable systems, move laterally to access sensitive data stores or administrative interfaces, and establish persistence by deploying backdoors across multiple accessible systems. The lack of granular segmentation also complicates incident response, as security teams cannot quickly determine which specific resources a compromised identity could access. By contrast, per-application segmentation with tightly scoped destination hosts, specific ports, and Custom Security Attributes enables dynamic, attribute-driven Conditional Access enforcement—requiring stronger authentication or device compliance for high-risk applications while streamlining access to lower-risk resources. \n\nThis approach aligns with the Zero Trust \"verify explicitly\" principle by ensuring each access request is evaluated against the specific security requirements of the target application rather than applying uniform policies to broad network segments.\n\n**Investigate**: Private Access applications are missing Custom Security Attributes, have CA policies using applicationFilter that require manual review, or no per-app Private Access applications are configured.\n\n**Remediation action**\n- [Transition from Quick Access](https://learn.microsoft.com/en-us/entra/global-secure-access/how-to-configure-per-app-access) to per-app Private Access by creating individual Global Secure Access enterprise applications with specific FQDNs, IP addresses, and ports for each private resource.\n- [Use Application Discovery](https://learn.microsoft.com/en-us/entra/global-secure-access/how-to-application-discovery) to identify which resources users access through Quick Access, then create targeted Private Access apps for those resources.\n- [Create Custom Security Attribute sets](https://learn.microsoft.com/en-us/entra/fundamentals/custom-security-attributes-add) and definitions to categorize Private Access applications by risk level, department, or compliance requirements.\n- [Assign Custom Security Attributes](https://learn.microsoft.com/en-us/entra/identity/enterprise-apps/custom-security-attributes-apps) to Private Access application service principals to enable attribute-based access control.\n- [Create Conditional Access policies using application filters](https://learn.microsoft.com/en-us/entra/identity/conditional-access/concept-filter-for-applications) to target Private Access apps based on their Custom Security Attributes, enforcing granular controls like MFA or device compliance.\n- [Apply Conditional Access policies to Private Access](https://learn.microsoft.com/en-us/entra/global-secure-access/how-to-target-resource-private-access-apps) apps from within Global Secure Access for streamlined configuration.\n\n**Review**\n- [Zero Trust network segmentation guidance for software-defined perimeters](https://learn.microsoft.com/en-us/security/zero-trust/deploy/networks#1-network-segmentation-and-software-defined-perimeters)\n\n\n","TestTitle":"Entra Private Access Application segments are defined to enforce least-privilege access","SkippedReason":"This test requires one of the following licenses: (\"Entra_Premium_Private_Access\"). Please ensure your tenant has the appropriate licenses to run this test. See [Licensing & Service Plans](https://learn.microsoft.com/entra/identity/users/licensing-service-plan-reference)","TestId":"25395","TestImplementationCost":"High","TestMinimumLicense":["Entra_Premium_Private_Access"],"TestSfiPillar":"Protect networks","TestResult":"\nSkipped. This test requires one of the following licenses: (\"Entra_Premium_Private_Access\"). Please ensure your tenant has the appropriate licenses to run this test. See [Licensing & Service Plans](https://learn.microsoft.com/entra/identity/users/licensing-service-plan-reference)\n","TestStatus":"Skipped","TestTags":null},{"TestImpact":"Low","TestRisk":"High","TestSkipped":"NoCompatibleLicenseFound","TestAppliesTo":null,"TestPillar":"Network","TestCategory":"Global Secure Access","TestDescription":"If organizations don't use Prompt Shield protection, threat actors can exploit prompt injection vulnerabilities to compromise AI-powered workflows. Malicious users can craft adversarial inputs that manipulate large language models into ignoring system instructions, disclosing confidential data, or executing unintended actions like generating phishing content.\n\nWithout network-level prompt filtering:\n\n- Direct prompt injection attacks can bypass application-layer safety mechanisms through sophisticated jailbreak techniques.\n- Indirect prompt injection occurs when threat actors embed malicious instructions in external content that the AI processes.\n- Each AI application must independently implement protection, creating inconsistent security postures and inadequate safeguards against new or custom AI deployments.\n\n**Remediation action**\n\n- [Enable the Internet Access traffic forwarding profile to route internet traffic through Global Secure Access](https://learn.microsoft.com/entra/global-secure-access/how-to-manage-internet-access-profile?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci).\n- [Configure TLS inspection settings and deploy the CA certificate to allow inspection of encrypted AI application traffic](https://learn.microsoft.com/entra/global-secure-access/how-to-transport-layer-security-settings?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci).\n- Follow the steps in [Protect enterprise generative AI applications with Prompt Shield](https://learn.microsoft.com/entra/global-secure-access/how-to-ai-prompt-shield?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci) to:\n - Create prompt policies to scan and block malicious prompts targeting generative AI applications.\n - Link prompt policies to security profiles to organize them for Conditional Access targeting.\n - Create Conditional Access policies to apply security profiles with prompt policies to users accessing internet resources.\n- [Install the Global Secure Access client on user devices to enable traffic acquisition](https://learn.microsoft.com/entra/global-secure-access/how-to-install-windows-client?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci).\n","TestTitle":"AI Gateway protects enterprise generative AI applications from prompt injection attacks","SkippedReason":"This test requires one of the following licenses: (\"Entra_Premium_Internet_Access\"). Please ensure your tenant has the appropriate licenses to run this test. See [Licensing & Service Plans](https://learn.microsoft.com/entra/identity/users/licensing-service-plan-reference)","TestId":"25415","TestImplementationCost":"Medium","TestMinimumLicense":["Entra_Premium_Internet_Access"],"TestSfiPillar":"Protect networks","TestResult":"\nSkipped. This test requires one of the following licenses: (\"Entra_Premium_Internet_Access\"). Please ensure your tenant has the appropriate licenses to run this test. See [Licensing & Service Plans](https://learn.microsoft.com/entra/identity/users/licensing-service-plan-reference)\n\n","TestStatus":"Skipped","TestTags":null},{"TestImplementationCost":"Medium","TestPillar":"Identity","TestCategory":"Hybrid infrastructure","SkippedReason":null,"TestImpact":"Low","TestAppliesTo":null,"TestSfiPillar":"Protect identities and secrets","TestSkipped":"","TestMinimumLicense":"Free","TestTags":null,"TestTitle":"Entra Connect Sync is configured with Service Principal Credentials","TestRisk":"High","TestResult":"\nFound enabled user accounts with Microsoft Entra Connect connector permissions.\n\n**Hybrid Identity Status**: True\n\n\n## Identities for Entra Connect Sync\n\n| Directory Synchronization Accounts Role Member | User Principal Name | Enabled | User Type |\n| :--------------------------------------------- | :------------------ | :------ | :-------- |\n| [On-Premises Directory Synchronization Service Account](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/overview/userId/33956e9a-cb54-42e9-94e8-d8f6ba05a55f) | Sync_DC1_demouser-d8475d81663f@contoso.onmicrosoft.com | ❌ Yes | Member |\n\n\n\n","TestStatus":"Failed","TestDescription":"Microsoft Entra Connect Sync using user accounts instead of service principals creates security vulnerabilities. Legacy user account authentication with passwords is more susceptible to credential theft and password attacks than service principal authentication with certificates. Compromised connector accounts allow threat actors to manipulate identity synchronization, create backdoor accounts, escalate privileges, or disrupt hybrid identity infrastructure. \n\n**Remediation action**\n\n- [Configure service principal authentication for Entra Connect](https://learn.microsoft.com/entra/identity/hybrid/connect/authenticate-application-id?tabs=default&wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci#onboard-to-application-based-authentication)\n- [Remove legacy Directory Synchronization Accounts](https://learn.microsoft.com/entra/identity/hybrid/connect/authenticate-application-id?tabs=default&wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci#remove-a-legacy-service-account)\n","TestId":"24570"},{"TestImplementationCost":"Low","TestPillar":"Devices","TestCategory":"Data","SkippedReason":null,"TestImpact":"High","TestAppliesTo":null,"TestSfiPillar":"Protect identities and secrets","TestSkipped":"","TestMinimumLicense":"Intune","TestTags":null,"TestTitle":"An app protection policy for iOS devices exists","TestRisk":"High","TestResult":"\nAt least one App protection policy for iOS exists and is assigned.\n\n\n## OS App Protection policies configured for iOS\n\n| Policy Name | Status | Assignment |\n| :---------- | :----- | :--------- |\n| [iOS Policy](https://intune.microsoft.com/#view/Microsoft_Intune_DeviceSettings/AppsMenu/~/protection) | ✅ Assigned | **Included:** WFgroup, **Excluded:** graph test |\n\n\n\n","TestStatus":"Passed","TestDescription":"Without app protection policies, corporate data accessed on iOS/iPadOS devices is vulnerable to leakage through unmanaged or personal apps. Users can unintentionally copy sensitive information into unsecured apps, store data outside corporate boundaries, or bypass authentication controls. This risk is especially high on BYOD devices, where personal and work contexts coexist, increasing the likelihood of data exfiltration or unauthorized access.\n\nApp protection policies ensure corporate data remains secure within approved apps, even on personal devices. These policies enforce encryption, restrict data sharing, and require authentication, reducing the risk of data leakage and aligning with Zero Trust principles of data protection and Conditional Access.\n \n**Remediation action**\n\nDeploy Intune app protection policies that encrypt corporate data, restrict sharing, and require authentication in approved iOS/iPadOS apps: \n- [Deploy Intune app protection policies](https://learn.microsoft.com/intune/intune-service/apps/app-protection-policies?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci#create-an-iosipados-or-android-app-protection-policy)\n- [Review the iOS app protection settings reference](https://learn.microsoft.com/intune/intune-service/apps/app-protection-policy-settings-ios?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci)\n\nFor more information, see: \n- [Learn about using app protection policies](https://learn.microsoft.com/intune/intune-service/apps/app-protection-policy?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci)\n","TestId":"24548"},{"TestImplementationCost":"Low","TestPillar":"Devices","TestCategory":"Data","SkippedReason":null,"TestImpact":"Medium","TestAppliesTo":null,"TestSfiPillar":"Protect tenants and isolate production systems","TestSkipped":"","TestMinimumLicense":"Intune","TestTags":null,"TestTitle":"Unmanaged and unprotected Apps are restricted from Accessing Corporate Data","TestRisk":"High","TestResult":"\nAt least one enabled conditional access policy with Application Protection exists for iOS and Android. The platforms could be part of same or different policy with the required grant control.\n\n\n## iOS & Android Conditional Access Policies\n\n| Policy Name | Platforms |\n| :---------- | :-------- |\n| [\\[ellis\\] - Require app protection policy](https://intune.microsoft.com/#view/Microsoft_AAD_ConditionalAccess/ConditionalAccessBlade/~/Policies) | android, iOS |\n\n\n","TestStatus":"Passed","TestDescription":"If Microsoft Entra Conditional Access policies aren't combined with app protection controls, users can connect to corporate resources through unmanaged or unsecured applications. This exposes sensitive data to risks such as data leakage, unauthorized access, and regulatory noncompliance. Without safeguards like app-level data protection, access restrictions, and data loss prevention, threat actors can exploit unprotected apps to bypass security controls and compromise organizational data.\n\nEnforcing Intune app protection policies within Conditional Access ensures only trusted apps can access corporate data. This supports Zero Trust by enforcing access decisions based on app trust, data containment, and usage restrictions.\n\n**Remediation action**\n\nConfigure app-based Conditional Access policies in Microsoft Entra and Intune to require app protection for access to corporate resources: \n- [Set up app-based Conditional Access policies with Intune](https://learn.microsoft.com/intune/intune-service/protect/app-based-conditional-access-intune-create?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci)\n\nFor more information, see: \n- [What is Conditional Access?](https://learn.microsoft.com/entra/identity/conditional-access/overview?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci)\n- [Learn about app-based Conditional Access policies with Intune](https://learn.microsoft.com/intune/intune-service/protect/app-based-conditional-access-intune?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci)\n","TestId":"24827"},{"TestImplementationCost":"High","TestPillar":"Identity","TestCategory":"Application management","SkippedReason":null,"TestImpact":"Low","TestAppliesTo":["Identity"],"TestSfiPillar":"Protect identities and secrets","TestSkipped":"","TestMinimumLicense":"Free","TestTags":["Identity"],"TestTitle":"Application Certificates need to be rotated on a regular basis","TestRisk":"High","TestResult":"\nFound 4 applications and 15 service principals in your tenant with certificates that have not been rotated within 180 days.\n\n\n## Applications with certificates that have not been rotated within 180 days\n\n| Application | Certificate Start Date |\n| :--- | :--- |\n| [Automation](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/ApplicationMenuBlade/~/Credentials/appId/dc7d83b5-d38b-4488-8952-7abf02e71590) | 2025-03-03 |\n| [InfinityDemo - Sample](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/ApplicationMenuBlade/~/Credentials/appId/20f152d5-856c-449d-aa07-81f5e510dfa7) | 2021-05-03 |\n| [M365PronounKit](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/ApplicationMenuBlade/~/Credentials/appId/eea28244-3eec-4820-beae-d4a2c0bcc235) | 2021-02-28 |\n| [test public client](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/ApplicationMenuBlade/~/Credentials/appId/79a0c604-f215-4c52-8fbe-641d08aa7937) | 2021-10-22 |\n\n\n## Service principals with certificates that have not been rotated within 180 days\n\n| Service principal | App owner tenant | Certificate Start Date |\n| :--- | :--- | :--- |\n| [21869testapp](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/SignOn/objectId/e69e29be-ba40-445a-9824-a3a45e0ae57a/appId/dd63d132-18fb-4f2e-aec4-82b97f30301f/preferredSingleSignOnMode/saml/servicePrincipalType/Application/fromNav/) | | 2025-10-27 |\n| [APP-2732_Genesys Cloud TCCC-G-TFS-Prod](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/SignOn/objectId/ba63bb52-182c-4ec6-9cc8-ad2287cf51ed/appId/76249b01-8747-4db4-843f-6478d5b32b14/preferredSingleSignOnMode/saml/servicePrincipalType/Application/fromNav/) | | 2025-07-30 |\n| [AWS Single-Account Access](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/SignOn/objectId/dc89bf5d-83e8-4419-9162-3b9280a85755/appId/091edd89-b342-4bb5-9144-82fe6c913987/preferredSingleSignOnMode/saml/servicePrincipalType/Application/fromNav/) | | 2022-10-26 |\n| [Azure AD SAML Toolkit](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/SignOn/objectId/4317fd0a-dcee-45bf-8e94-9a66638b11e0/appId/6f5ed68c-9fad-4d78-bf88-2b16bbe16338/preferredSingleSignOnMode/saml/servicePrincipalType/Application/fromNav/) | | 2025-10-11 |\n| [Dropbox Business](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/SignOn/objectId/5eec0e98-b81a-422a-ab61-f8de2729330d/appId/f76d7d98-02ee-4e62-9345-36016a72e664/preferredSingleSignOnMode/saml/servicePrincipalType/Application/fromNav/) | | 2021-02-17 |\n| [charlie AWS Account](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/SignOn/objectId/39861745-eda1-4e3c-8358-d0ba931f12bb/appId/d3a04f85-a969-436b-bf4d-eae0a91efb4c/preferredSingleSignOnMode/saml/servicePrincipalType/Application/fromNav/) | | 2025-01-07 |\n| [charlie- Genesys Cloud for Azure](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/SignOn/objectId/84dc13ec-5754-4745-90f9-5cc92a5ded28/appId/9c599cd2-9fb0-4815-b65c-83be33f5df1b/preferredSingleSignOnMode/saml/servicePrincipalType/Application/fromNav/) | | 2025-07-30 |\n| [P2P Server](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/SignOn/objectId/05c98ca9-d208-4d3e-ad24-911bfc3d028c/appId/2af9f5c5-0ffc-4d1c-ba2e-72cf6382df06/preferredSingleSignOnMode/saml/servicePrincipalType/Application/fromNav/) | | 2023-06-11 |\n| [SPO Version](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/SignOn/objectId/4c780b09-998f-4b35-b41f-b125dc9f729a/appId/2d6d9bf1-1f6e-48cf-bb02-31beec2f442e/preferredSingleSignOnMode/saml/servicePrincipalType/Application/fromNav/) | | 2023-11-17 |\n| [Salesforce](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/SignOn/objectId/13720002-03b6-462f-ac2f-765f0f9b3f58/appId/1a2a1d4c-1d76-44ec-95f4-3ed5345423a9/preferredSingleSignOnMode/saml/servicePrincipalType/Application/fromNav/) | | 2022-10-02 |\n| [Saml test entity id](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/SignOn/objectId/d589a2e6-4a78-4cdd-901b-f574dc7880db/appId/6590313e-1c00-4c07-be28-72858e837a52/preferredSingleSignOnMode/saml/servicePrincipalType/Application/fromNav/) | | 2022-11-17 |\n| [ServiceNow](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/SignOn/objectId/9a8af246-0d94-42eb-aaaf-836a9f9a4974/appId/ecbbb1c8-ef06-48c4-9211-9ffbfbc24b94/preferredSingleSignOnMode/saml/servicePrincipalType/Application/fromNav/) | | 2021-02-15 |\n| [SumoLogic](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/SignOn/objectId/144df581-a0c9-4280-9739-0c3612ab9ccf/appId/1b6c36b2-f2b1-43d3-b74f-8d52c44fc9c1/preferredSingleSignOnMode/saml/servicePrincipalType/Application/fromNav/) | | 2024-02-15 |\n| [claimtest](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/SignOn/objectId/f7b07e81-79a0-4e51-b93a-169b8f2f6c4e/appId/f816d68b-aec7-4eab-9ebc-bd23b0d04e35/preferredSingleSignOnMode/saml/servicePrincipalType/Application/fromNav/) | | 2025-02-26 |\n| [test](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/SignOn/objectId/31e80a1b-3faa-4ce9-9794-2b77f61f20f7/appId/8ae2b566-71f5-467e-8960-cfe8da3a2cfa/preferredSingleSignOnMode/saml/servicePrincipalType/Application/fromNav/) | | 2022-10-10 |\n\n\n","TestStatus":"Failed","TestDescription":"If certificates aren't rotated regularly, they can give threat actors an extended window to extract and exploit them, leading to unauthorized access. When credentials like these are exposed, attackers can blend their malicious activities with legitimate operations, making it easier to bypass security controls. If an attacker compromises an application’s certificate, they can escalate their privileges within the system, leading to broader access and control, depending on the application's privileges.\n\nQuery all of your service principals and application registrations that have certificate credentials. Make sure the certificate start date is less than 180 days.\n\n**Remediation action**\n\n- [Define an application management policy to manage certificate lifetimes](https://learn.microsoft.com/graph/api/resources/applicationauthenticationmethodpolicy?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci)\n- [Define a trusted certificate chain of trust](https://learn.microsoft.com/graph/api/resources/certificatebasedapplicationconfiguration?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci)\n- [Create a least privileged custom role to rotate application credentials](https://learn.microsoft.com/entra/identity/role-based-access-control/custom-create?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci) \n- [Learn more about app management policies to manage certificate based credentials](https://devblogs.microsoft.com/identity/app-management-policy/)\n","TestId":"21992"},{"TestImplementationCost":"Low","TestPillar":"Identity","TestCategory":"Access control","SkippedReason":null,"TestImpact":"Low","TestAppliesTo":["Identity"],"TestSfiPillar":"Protect identities and secrets","TestSkipped":"","TestMinimumLicense":"P1","TestTags":["Identity"],"TestTitle":"User sign-in activity uses token protection","TestRisk":"High","TestResult":"\nThe tenant is missing properly configured Token Protection policies.\n\n","TestStatus":"Failed","TestDescription":"A threat actor can intercept or extract authentication tokens from memory, local storage on a legitimate device, or by inspecting network traffic. The attacker might replay those tokens to bypass authentication controls on users and devices, get unauthorized access to sensitive data, or run further attacks. Because these tokens are valid and time bound, traditional anomaly detection often fails to flag the activity, which might allow sustained access until the token expires or is revoked.\n\nToken protection, also called token binding, helps prevent token theft by making sure a token is usable only from the intended device. Token protection uses cryptography so that without the client device key, no one can use the token.\n\n**Remediation action**\n\n- [Deploy a Conditional Access policy to require token protection](https://learn.microsoft.com/entra/identity/conditional-access/concept-token-protection?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci)\n","TestId":"21786"},{"TestImplementationCost":"High","TestPillar":"Identity","TestCategory":"Monitoring","SkippedReason":"This test is for tenants that are licensed for Entra Workload ID. See [Entra Workload ID licensing](https://learn.microsoft.com/entra/workload-id/workload-identities-faqs)","TestImpact":"Low","TestAppliesTo":null,"TestSfiPillar":"Protect identities and secrets","TestSkipped":"NotLicensedEntraWorkloadID","TestMinimumLicense":"P2","TestTags":null,"TestTitle":"All risky workload identity sign-ins are triaged","TestRisk":"High","TestResult":"\nSkipped. This test is for tenants that are licensed for Entra Workload ID. See [Entra Workload ID licensing](https://learn.microsoft.com/entra/workload-id/workload-identities-faqs)\n\n","TestStatus":"Skipped","TestDescription":"Threat actors increasingly target workload identities (applications, service principals, and managed identities) because they lack human factors and often use long-lived credentials. A compromise often looks like the following path:\n\n1. Credential abuse or key theft.\n1. Non-interactive sign-ins to cloud resources.\n1. Lateral movement via app permissions.\n1. Persistence through new secrets or role assignments.\n\nMicrosoft Entra ID Protection continuously generates risky workload identity detections and flags sign-in events with risk state and detail. Risky workload identity sign-ins that aren’t triaged (confirmed compromised, dismissed, or marked safe), detection fatigue, and a large alert backlog can be challenging for IT admins to manage. This heavy workload can let repeated malicious access, privilege escalation, and token replay to continue to go unnoticed. To make the workload manageable, address risky workload identity sign-ins in two parts:\n\n- Close the loop: Triage sign-ins and record an authoritative decision on each risky event.\n- Drive containment: Disable the service principal, rotate credentials, or revoke sessions.\n\n**Remediation action**\n\n- [Investigate risky workload identities and perform appropriate remediation ](https://learn.microsoft.com/entra/id-protection/concept-workload-identity-risk?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci)\n- [Dismiss workload identity risks when determined to be false positives](https://learn.microsoft.com/graph/api/riskyserviceprincipal-dismiss?view=graph-rest-1.0&preserve-view=true&wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci)\n- [Confirm compromised workload identities when risks are validated](https://learn.microsoft.com/graph/api/riskyserviceprincipal-confirmcompromised?view=graph-rest-1.0&preserve-view=true&wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci)\n","TestId":22659},{"TestImpact":"Low","TestRisk":"High","TestSkipped":"NoCompatibleLicenseFound","TestAppliesTo":null,"TestPillar":"Network","TestCategory":"Role management","TestDescription":"An Application Administrator role scoped at the tenant level can manage every app registration and enterprise application. If a threat actor compromises an Application Administrator with tenant-wide scope, they can add credentials to any service principal, consent to malicious APIs, modify or create applications that enable data exfiltration, and disable or tamper with Private Access apps. Scoping the role to only required Private Access enterprise apps enforces least privilege and limits the blast radius.\n\nIf you don't scope Application Administrator assignments to specific apps:\n\n- A compromised Application Administrator can manage every app registration and enterprise application in your tenant.\n- Threat actors can add credentials to any service principal, enabling persistence and lateral movement.\n- There's no blast radius containment; a single compromised identity can affect all applications.\n\n**Remediation action**\n\n- [Assign Application Administrator roles scoped to specific app registrations](https://learn.microsoft.com/entra/identity/role-based-access-control/custom-enterprise-app-permissions?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci) instead of tenant-wide.\n- [Assign Microsoft Entra roles](https://learn.microsoft.com/entra/identity/role-based-access-control/manage-roles-portal?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci) with the least privilege necessary to perform required tasks.\n- [Use Privileged Identity Management to manage just-in-time role activation](https://learn.microsoft.com/entra/id-governance/privileged-identity-management/pim-configure?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci).\n- [Manage Microsoft Entra role assignments in the admin center](https://learn.microsoft.com/entra/identity/role-based-access-control/manage-roles-portal?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci).\n","TestTitle":"Application admin rights are constrained to specific Private Access apps","SkippedReason":"This test requires one of the following licenses: (\"Entra_Premium_Private_Access\") OR (\"Entra_Premium_Internet_Access\"). Please ensure your tenant has the appropriate licenses to run this test. See [Licensing & Service Plans](https://learn.microsoft.com/entra/identity/users/licensing-service-plan-reference)","TestId":"25384","TestImplementationCost":"Low","TestMinimumLicense":["Entra_Premium_Private_Access","Entra_Premium_Internet_Access"],"TestSfiPillar":"Protect identities and secrets","TestResult":"\nSkipped. This test requires one of the following licenses: (\"Entra_Premium_Private_Access\") OR (\"Entra_Premium_Internet_Access\"). Please ensure your tenant has the appropriate licenses to run this test. See [Licensing & Service Plans](https://learn.microsoft.com/entra/identity/users/licensing-service-plan-reference)\n\n","TestStatus":"Skipped","TestTags":null},{"TestImplementationCost":"Medium","TestPillar":"Identity","TestCategory":"Privileged access","SkippedReason":null,"TestImpact":"Low","TestAppliesTo":null,"TestSfiPillar":"Protect identities and secrets","TestSkipped":"","TestMinimumLicense":"Free","TestTags":null,"TestTitle":"High Global Administrator to privileged user ratio","TestRisk":"High","TestResult":"\nMore than 50% of privileged role assignments in the tenant are Global Administrator.\n## Privileged role assignment summary\n\n**Global administrator role count:** 22 (55%) - ❌ Failed\n\n**Other privileged role count:** 18 (45%)\n\n## User privileged role assignments\n\n| User | Global administrator | Other Privileged Role(s) |\n| :--- | :------------------- | :------ |\n| [Alex Johnson](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/AdministrativeRole/userId/e436ca15-3a39-4dcc-819e-7dbb246cd46b/hidePreviewBanner~/true) | Yes | Application Administrator |\n| [Hayden Scott](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/AdministrativeRole/userId/c0b65b13-37b1-4081-bcfc-14844159b4a5/hidePreviewBanner~/true) | Yes | - |\n| [Jordan Smith](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/AdministrativeRole/userId/bfaeba1e-1357-47de-9557-529caa103d5d/hidePreviewBanner~/true) | Yes | AI Administrator, Application Administrator |\n| [Taylor Brown](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/AdministrativeRole/userId/2072badc-3cf0-4e84-b4c2-f9c065c46165/hidePreviewBanner~/true) | Yes | - |\n| [Morgan Wilson](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/AdministrativeRole/userId/5655cf54-34bc-4f36-bb74-44da35547975/hidePreviewBanner~/true) | Yes | - |\n| [Cameron Anderson](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/AdministrativeRole/userId/1ce4078f-f795-4baf-aa55-1fdfcc2ebfe6/hidePreviewBanner~/true) | Yes | Global Reader, Security Administrator |\n| [Avery Thomas](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/AdministrativeRole/userId/f431700c-6d81-45b8-8f8d-581a8aa7cda6/hidePreviewBanner~/true) | Yes | - |\n| [Quinn Garcia](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/AdministrativeRole/userId/ceef37b7-c865-48fb-80c9-4def11201854/hidePreviewBanner~/true) | Yes | - |\n| [Jamie Rodriguez](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/AdministrativeRole/userId/0b37813c-ae19-4399-982f-16587f17f9c0/hidePreviewBanner~/true) | Yes | - |\n| [Jules Bailey](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/AdministrativeRole/userId/0145d508-50fd-4f86-a47a-bf1c043c8358/hidePreviewBanner~/true) | Yes | - |\n| [Reese Harris](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/AdministrativeRole/userId/babe04c9-8340-4329-a727-a8cee0cd2b1a/hidePreviewBanner~/true) | Yes | - |\n| [Peyton Clark](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/AdministrativeRole/userId/7e92f268-bb12-469a-a869-210d596d4c1f/hidePreviewBanner~/true) | Yes | Global Reader |\n| [Charlie Lewis](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/AdministrativeRole/userId/5b0ec3ff-cea1-4eb9-8530-f2a66e5bec0a/hidePreviewBanner~/true) | Yes | - |\n| [Finley Robinson](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/AdministrativeRole/userId/990fd38a-c516-4e3f-82e4-d458a1ab0f91/hidePreviewBanner~/true) | Yes | Global Reader |\n| [Ash Williams](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/AdministrativeRole/userId/513f3db2-044c-41be-af14-431bf88a2b3e/hidePreviewBanner~/true) | Yes | - |\n| [Drew Mitchell](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/AdministrativeRole/userId/df02402a-e291-42cc-b449-79366daa2a40/hidePreviewBanner~/true) | Yes | Application Administrator, Global Reader |\n| [Ellis Cooper](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/AdministrativeRole/userId/1433571b-3d7c-4a56-a9cc-67580848bc73/hidePreviewBanner~/true) | Yes | - |\n| [Sage Bennett](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/AdministrativeRole/userId/518ce209-faf4-4717-add9-7129a669fa11/hidePreviewBanner~/true) | Yes | Agent ID Administrator, Global Reader, Privileged Role Administrator |\n| [Dakota Lee](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/AdministrativeRole/userId/210d3e96-015f-462d-b6d6-81e6023263df/hidePreviewBanner~/true) | Yes | - |\n| [Dakota Lee Test](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/AdministrativeRole/userId/43482f27-d1af-420f-84ba-e9148a700f45/hidePreviewBanner~/true) | Yes | - |\n| [Phoenix Gray](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/AdministrativeRole/userId/7094fb23-003a-4f81-9796-5daeaa603003/hidePreviewBanner~/true) | Yes | - |\n| [Avery Brooks](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/AdministrativeRole/userId/a85798bd-652b-4eb9-ba90-3ee882df0179/hidePreviewBanner~/true) | Yes | - |\n| [Hayden Scott Test](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/AdministrativeRole/userId/6f467d0a-25ec-435c-8fb9-9d53eb21e02f/hidePreviewBanner~/true) | No | Global Reader |\n| [Hayden Scott](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/AdministrativeRole/userId/0d6cfd05-fc46-440b-b605-66dd26dcd7d2/hidePreviewBanner~/true) | No | Global Reader |\n| [Casey Davis](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/AdministrativeRole/userId/58d9ed99-93ca-4674-8c5f-ec770f5ba17d/hidePreviewBanner~/true) | No | Global Reader |\n| [ash-williams-test](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/AdministrativeRole/userId/c5c8ba63-4620-4e91-ac40-b66bebe07a0d/hidePreviewBanner~/true) | No | Global Reader |\n| [Riley Martinez](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/AdministrativeRole/userId/653c7fdd-1b41-4229-992a-69cc35aad4f7/hidePreviewBanner~/true) | No | Application Administrator |\n| [Dakota Lee](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/AdministrativeRole/userId/e4bc6f4a-124f-469b-8951-3d5c34fb9741/hidePreviewBanner~/true) | No | User Administrator |\n| [Skylar White](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/AdministrativeRole/userId/2a054082-8f05-4e05-8fce-4e35c3bb40cc/hidePreviewBanner~/true) | No | Application Administrator |\n| [peyton-test](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/AdministrativeRole/userId/e0952dcb-8d63-496d-8661-05c86c1a51f0/hidePreviewBanner~/true) | No | Global Reader |\n| [finley-test](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/AdministrativeRole/userId/d71ccc09-c0a3-4604-9d02-49f7a3715f49/hidePreviewBanner~/true) | No | Global Reader |\n| [Sam Parker](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/AdministrativeRole/userId/96d29f01-873c-46a3-b542-f7ee192cc675/hidePreviewBanner~/true) | No | Application Administrator |\n| [parker-test](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/AdministrativeRole/userId/c1bdb03c-0079-40b1-96a8-3595de3b94a2/hidePreviewBanner~/true) | No | Global Reader |\n\n\n","TestStatus":"Failed","TestDescription":"When organizations maintain a disproportionately high ratio of Global Administrators relative to their total privileged user population, they expose themselves to significant security risks that threat actors might exploit through various attack vectors. Excessive Global Administrator assignments create multiple high-value targets for threat actors who might leverage initial access through credential compromise, phishing attacks, or insider threats to gain unrestricted access to the entire Microsoft Entra ID tenant and connected Microsoft 365 services. \n\n**Remediation action**\n\n- [Minimize the number of Global Administrator role assignments](https://learn.microsoft.com/entra/identity/role-based-access-control/best-practices?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci#5-limit-the-number-of-global-administrators-to-less-than-5)\n","TestId":"21813"},{"TestImplementationCost":"Low","TestPillar":"Devices","TestCategory":"Tenant","SkippedReason":null,"TestImpact":"Medium","TestAppliesTo":null,"TestSfiPillar":"Protect tenants and isolate production systems","TestSkipped":"","TestMinimumLicense":"Intune","TestTags":null,"TestTitle":"Compliance Policy for Android Enterprise Personally-Owned Work Profile is configured and assigned","TestRisk":"High","TestResult":"\nAt least one compliance policy for Android Enterprise Personally-Owned Work Profile exists and is assigned.\n\n\n## Compliance policy assignment for Android Enterprise Fully managed device is configured and assigned\n\n| Policy Name | Status | Assignment |\n| :---------- | :----- | :--------- |\n| [My android personally-owned](https://intune.microsoft.com/#view/Microsoft_Intune_DeviceSettings/DevicesComplianceMenu/~/policies) | ✅ Assigned | **Included:** aad-conditional-access-allow-legacy-auth, **Excluded:** Executive Management, HR |\n\n\n","TestStatus":"Passed","TestDescription":"If compliance policies aren't assigned to Android Enterprise personally owned devices in Intune, threat actors can exploit noncompliant endpoints to gain unauthorized access to corporate resources, bypass security controls, and introduce vulnerabilities. Without enforced compliance, devices can lack critical security configurations like passcode requirements, data storage encryption, and OS version controls. These gaps increase the risk of data leakage and unauthorized access. Inconsistent device compliance weakens the organization’s security posture and makes it harder to detect and remediate threats before significant damage occurs.\n\nEnforcing compliance policies ensures that personally owned Android devices meet core security requirements and supports Zero Trust by validating device health and reducing exposure to misconfigured or unmanaged endpoints.\n\n**Remediation action**\n\nCreate and assign Intune compliance policies to Android Enterprise personally owned devices to enforce organizational standards for secure access and management: \n- [Create a compliance policy in Microsoft Intune](https://learn.microsoft.com/intune/intune-service/protect/create-compliance-policy?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci#create-the-policy)\n- [Review the Android Enterprise compliance settings you can manage with Intune](https://learn.microsoft.com/intune/intune-service/protect/compliance-policy-create-android-for-work?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci)\n","TestId":"24547"},{"TestImplementationCost":"Low","TestPillar":"Identity","TestCategory":"Access control","SkippedReason":null,"TestImpact":"Low","TestAppliesTo":null,"TestSfiPillar":"Protect tenants and isolate production systems","TestSkipped":"","TestMinimumLicense":"P1","TestTags":null,"TestTitle":"Enable protected actions to secure Conditional Access policy creation and changes","TestRisk":"High","TestResult":"\n\n### Conditional Access Policies by Protected Action\n\n#### Update basic properties for Conditional Access policies - ✅ Pass\n\n**Auth Context:** Require FIDO2 key (ID: c1)\n\n| Display Name | State | Authentication Context | Authentication Strength | Device Filters | SignIn Frequency |\n| :--- | :--- | :--- | :--- | :--- | :--- |\n| [AuthContext: Require FIDO2 ](https://entra.microsoft.com/#view/Microsoft_AAD_ConditionalAccess/PolicyBlade/policyId/) | Enabled | Require FIDO2 key | ✅ | ❌ | ✅ |\n| [Test-PA](https://entra.microsoft.com/#view/Microsoft_AAD_ConditionalAccess/PolicyBlade/policyId/) | Disabled | Require FIDO2 key,MFA,Strong auth | ✅ | ❌ | ✅ |\n\n#### Create Conditional Access policies - ✅ Pass\n\n**Auth Context:** Require FIDO2 key (ID: c1)\n\n| Display Name | State | Authentication Context | Authentication Strength | Device Filters | SignIn Frequency |\n| :--- | :--- | :--- | :--- | :--- | :--- |\n| [AuthContext: Require FIDO2 ](https://entra.microsoft.com/#view/Microsoft_AAD_ConditionalAccess/PolicyBlade/policyId/) | Enabled | Require FIDO2 key | ✅ | ❌ | ✅ |\n| [Test-PA](https://entra.microsoft.com/#view/Microsoft_AAD_ConditionalAccess/PolicyBlade/policyId/) | Disabled | Require FIDO2 key,MFA,Strong auth | ✅ | ❌ | ✅ |\n\n#### Delete Conditional Access policies - ✅ Pass\n\n**Auth Context:** Require FIDO2 key (ID: c1)\n\n| Display Name | State | Authentication Context | Authentication Strength | Device Filters | SignIn Frequency |\n| :--- | :--- | :--- | :--- | :--- | :--- |\n| [AuthContext: Require FIDO2 ](https://entra.microsoft.com/#view/Microsoft_AAD_ConditionalAccess/PolicyBlade/policyId/) | Enabled | Require FIDO2 key | ✅ | ❌ | ✅ |\n| [Test-PA](https://entra.microsoft.com/#view/Microsoft_AAD_ConditionalAccess/PolicyBlade/policyId/) | Disabled | Require FIDO2 key,MFA,Strong auth | ✅ | ❌ | ✅ |\n\n#### Update Conditional Access authentication context of Microsoft 365 role-based access control (RBAC) resource actions - ✅ Pass\n\n**Auth Context:** Require FIDO2 key (ID: c1)\n\n| Display Name | State | Authentication Context | Authentication Strength | Device Filters | SignIn Frequency |\n| :--- | :--- | :--- | :--- | :--- | :--- |\n| [AuthContext: Require FIDO2 ](https://entra.microsoft.com/#view/Microsoft_AAD_ConditionalAccess/PolicyBlade/policyId/) | Enabled | Require FIDO2 key | ✅ | ❌ | ✅ |\n| [Test-PA](https://entra.microsoft.com/#view/Microsoft_AAD_ConditionalAccess/PolicyBlade/policyId/) | Disabled | Require FIDO2 key,MFA,Strong auth | ✅ | ❌ | ✅ |\n\n\n\n","TestStatus":"Passed","TestDescription":"Threat actors who gain privileged access to a tenant can manipulate Conditional Access policies, potentially disabling critical security controls and enabling persistent access or lateral movement. This type of attack can result in environment-wide compromise by bypassing authentication and authorization barriers.\n\nProtected actions let administrators secure Conditional Access policy creation and modification with extra security controls, such as stronger authentication methods (passwordless MFA or phishing-resistant MFA), the use of Privileged Access Workstation (PAW) devices, or shorter session timeouts.\n\n**Remediation action**\n\n- [Add, test, or remove protected actions in Microsoft Entra ID](https://learn.microsoft.com/entra/identity/role-based-access-control/protected-actions-add?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci)\n","TestId":21964},{"TestImplementationCost":"Medium","TestPillar":"Identity","TestCategory":"Access control","SkippedReason":"UnderConstruction","TestImpact":"Low","TestAppliesTo":["Identity"],"TestSfiPillar":"Protect identities and secrets","TestSkipped":"UnderConstruction","TestMinimumLicense":null,"TestTags":["Identity"],"TestTitle":"GDAP admin least privilege","TestRisk":"Medium","TestResult":"\nPlanned for future release.\n","TestStatus":"Planned","TestDescription":"...\n\n**Remediation action**\n\n","TestId":"21859"},{"TestImplementationCost":"Low","TestPillar":"Devices","TestCategory":"Tenant","SkippedReason":null,"TestImpact":"Low","TestAppliesTo":null,"TestSfiPillar":"Protect tenants and isolate production systems","TestSkipped":"","TestMinimumLicense":"Intune","TestTags":null,"TestTitle":"Company Portal branding and support settings enhance user experience and trust","TestRisk":"Medium","TestResult":"\nNo Company Portal branding profile with support settings exists or none are assigned.\n\n\n## Company Portal Branding Profiles\n\n| Profile Name | Branding Properties | Status | Assignment Target |\n| :----------- | :------------------ | :----- | :---------------- |\n| [Default Branding profile.](https://intune.microsoft.com/#view/Microsoft_Intune_DeviceSettings/TenantAdminMenu/~/companyPortalBranding) | **Display Name**: Pora Labs Inc., **Contact Phone**: Not configured, **Contact Email**: ash@contoso.com | N/A | N/A |\n\n\n\n","TestStatus":"Failed","TestDescription":"If the Intune Company Portal branding isn't configured to represent your organization’s details, users can encounter a generic interface and lack direct support information. This reduces user trust, increases support overhead, and can lead to confusion or delays in resolving issues.\n\nCustomizing the Company Portal with your organization’s branding and support contact details improves user trust, streamlines support, and reinforces the legitimacy of device management communications.\n\n\n**Remediation action**\n\nConfigure the Intune Company Portal with your organization’s branding and support contact information to enhance user experience and reduce support overhead: \n- [Configure the Intune Company Portal](https://learn.microsoft.com/intune/intune-service/apps/company-portal-app?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci)\n","TestId":"24823"},{"TestImplementationCost":"Medium","TestPillar":null,"TestCategory":"Application management","SkippedReason":"UnderConstruction","TestImpact":"Low","TestAppliesTo":["Identity"],"TestSfiPillar":"","TestSkipped":"UnderConstruction","TestMinimumLicense":null,"TestTags":["Identity"],"TestTitle":"Use recent versions of Microsoft Applications","TestRisk":"Medium","TestResult":"\nPlanned for future release.\n","TestStatus":"Planned","TestDescription":"...\n\n**Remediation action**\n\n","TestId":"21779"},{"TestImplementationCost":"Medium","TestPillar":"Identity","TestCategory":"Access control","SkippedReason":null,"TestImpact":"Low","TestAppliesTo":null,"TestSfiPillar":"Protect identities and secrets","TestSkipped":"","TestMinimumLicense":"P1","TestTags":null,"TestTitle":"Token protection policies are configured","TestRisk":"Medium","TestResult":"\nToken protection policies are configured.\n\n### Token protection policy summary\n\nThe table below lists all the token protection Conditional Access policies found in the tenant.\n\n| Name | Policy state | Users | Applications | Token protection | Status |\n| :--- | :---: | :---: | :---: | :---: | :---: |\n| [Token protection](https://entra.microsoft.com/#view/Microsoft_AAD_ConditionalAccess/PolicyBlade/policyId/ff7b71d1-fa63-4073-a959-4790f299de0f) | 🟡 Report-only | All | Selected | 🟢 | ❌ Fail |\n| [token protection with 1 apps](https://entra.microsoft.com/#view/Microsoft_AAD_ConditionalAccess/PolicyBlade/policyId/c51217bf-4044-4001-bfe6-ed8ef2624beb) | 🟢 Enabled | Selected | Selected | 🟢 | ✅ Pass |\n\n","TestStatus":"Passed","TestDescription":"Token protection policies in Entra ID tenants are crucial for safeguarding authentication tokens from misuse and unauthorized access. Without these policies, threat actors can intercept and manipulate tokens, leading to unauthorized access to sensitive resources. This can result in data exfiltration, lateral movement within the network, and potential compromise of privileged accounts.\n\nWhen token protection is not properly configured, threat actors can exploit several attack vectors:\n\n1. **Token theft and replay attacks** - Attackers can steal authentication tokens from compromised devices and replay them from different locations\n2. **Session hijacking** - Without secure sign-in session controls, attackers can hijack legitimate user sessions\n3. **Cross-platform token abuse** - Tokens issued for one platform (like mobile) can be misused on other platforms (like web browsers)\n4. **Persistent access** - Compromised tokens can provide long-term unauthorized access without triggering security alerts\n\nThe attack chain typically involves initial access through token theft, followed by privilege escalation and persistence, ultimately leading to data exfiltration and impact across the organization's Microsoft 365 environment.\n\n**Remediation action**\n- [Configure Conditional Access policies as per the best practices](https://learn.microsoft.com/en-us/entra/identity/conditional-access/concept-token-protection#create-a-conditional-access-policy)\n- [Microsoft Entra Conditional Access token protection explained](https://learn.microsoft.com/en-us/entra/identity/conditional-access/concept-token-protection)\n- [Configure session controls in Conditional Access](https://learn.microsoft.com/en-us/entra/identity/conditional-access/concept-conditional-access-session)\n\n","TestId":21941},{"TestImpact":"Medium","TestRisk":"High","TestSkipped":"NoCompatibleLicenseFound","TestAppliesTo":null,"TestPillar":"Network","TestCategory":"Global Secure Access","TestDescription":"When Conditional Access policies don't protect Private Access applications by requiring strong authentication, threat actors can use phishing attacks, credential stuffing, or password spraying to get user credentials and sign in to private applications with just a compromised password.\n\nWithout strong authentication:\n\n- Threat actors gain initial access to internal resources that should be protected by stronger controls.\n- If multifactor authentication is missing or phishable methods like SMS or voice are used, adversary-in-the-middle attacks can happen where threat actors intercept authentication tokens and session cookies.\n- Threat actors can move laterally from the initially compromised private application to other internal resources.\n\nMicrosoft recommends enforcing phishing-resistant authentication methods such as FIDO2 security keys, Windows Hello for Business, or certificate-based authentication for access to private applications, with multifactor authentication as the minimum acceptable baseline.\n\n**Remediation action**\n\n- [Configure Conditional Access policies to require phishing-resistant authentication](https://learn.microsoft.com/entra/identity/conditional-access/policy-all-users-mfa-strength?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci).\n","TestTitle":"Conditional Access policies enforce strong authentication for private apps","SkippedReason":"This test requires one of the following licenses: (\"Entra_Premium_Private_Access\"). Please ensure your tenant has the appropriate licenses to run this test. See [Licensing & Service Plans](https://learn.microsoft.com/entra/identity/users/licensing-service-plan-reference)","TestId":"25396","TestImplementationCost":"Medium","TestMinimumLicense":["Entra_Premium_Private_Access"],"TestSfiPillar":"Protect identities and secrets","TestResult":"\nSkipped. This test requires one of the following licenses: (\"Entra_Premium_Private_Access\"). Please ensure your tenant has the appropriate licenses to run this test. See [Licensing & Service Plans](https://learn.microsoft.com/entra/identity/users/licensing-service-plan-reference)\n\n","TestStatus":"Skipped","TestTags":null},{"TestImplementationCost":"High","TestPillar":"Identity","TestCategory":"Access control","SkippedReason":"UnderConstruction","TestImpact":"Low","TestAppliesTo":["Identity"],"TestSfiPillar":"Protect identities and secrets","TestSkipped":"UnderConstruction","TestMinimumLicense":null,"TestTags":["Identity"],"TestTitle":"Application Certificate Credentials are managed using HSM","TestRisk":"Low","TestResult":"\nPlanned for future release.\n","TestStatus":"Planned","TestDescription":"...\n\n**Remediation action**\n\n","TestId":"21895"},{"TestImpact":"High","TestRisk":"Low","TestSkipped":"","TestAppliesTo":null,"TestPillar":"Data","TestCategory":"Encryption","TestDescription":"Double Key Encryption (DKE) provides an extra layer of protection for highly sensitive data by requiring two keys to decrypt content: one managed by Microsoft and one by the customer. This \"hold your own key\" approach ensures Microsoft can't decrypt content even with legal compulsion, meeting stringent regulatory requirements for data sovereignty.\n\nHowever, DKE introduces significant operational complexity including dedicated key service infrastructure, reduced feature compatibility, and increased support burden. Organizations should maintain 1-3 labels reserved for truly mission-critical or heavily regulated data, with documented business justification for each DKE label. Use standard encryption for general business content. Excessive DKE labels (4 or more) create management overhead, user confusion, and reduce collaboration. DKE should never be broadly deployed, as key service unavailability prevents access to business-critical documents.\n\n**Remediation action**\n\n- [Double Key Encryption](https://learn.microsoft.com/purview/double-key-encryption?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci)\n- [Set up Double Key Encryption](https://learn.microsoft.com/purview/double-key-encryption-setup?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci)\n","TestTitle":"Double Key Encryption (DKE) Labels","SkippedReason":null,"TestId":"35010","TestImplementationCost":"Medium","TestMinimumLicense":["RMS_S_PREMIUM2"],"TestSfiPillar":"Protect tenants and production systems","TestResult":"\n✅ DKE labels appropriately deployed (1-3 labels for mission-critical and regulated data).\n\n\n### Summary\n\n- Total Sensitivity Labels: 9\n- DKE Enabled Labels: 1\n\n### [Sensitivity Label Details](https://purview.microsoft.com/informationprotection/informationprotectionlabels/sensitivitylabels)\n\n| Label name | Disabled | DKE enabled | DKE endpoint url |\n|:-----------|:---------|:------------|:-----------------|\n| test-dke | False | True | https://entra.microsoft.com/#view/Microsoft_AAD_IAM/DirectoryRolesBlade |\n| alex-test-label-1 | False | False | N/A |\n| parker | False | False | N/A |\n| Confidential – RMS | False | False | N/A |\n| peyton | False | False | N/A |\n| test-35012-1 | False | False | N/A |\n| test-35012 | False | False | N/A |\n| test35036 | False | False | N/A |\n| 35014-parker | False | False | N/A |\n\n\n","TestStatus":"Passed","TestTags":null},{"TestImpact":"Medium","TestRisk":"High","TestSkipped":"","TestAppliesTo":null,"TestPillar":"Data","TestCategory":"Advanced Classification","TestDescription":"Custom sensitive information types (SITs) extend Microsoft Purview's built-in detection to cover organization-specific data patterns, proprietary identifiers, internal classification schemes, specialized industry codes, or other formats that built-in SITs don't match. Without custom SITs, auto-labeling policies and data loss prevention (DLP) rules rely exclusively on generic patterns and might miss sensitive data unique to your organization.\n\n**Remediation action**\n\n- [Create custom sensitive information types](https://learn.microsoft.com/purview/create-a-custom-sensitive-information-type?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci)\n","TestTitle":"Custom Sensitive Information Types (SITs) Configured","SkippedReason":null,"TestId":"35033","TestImplementationCost":"High","TestMinimumLicense":["EXCHANGE_S_ENTERPRISE"],"TestSfiPillar":"Protect tenants and production systems","TestResult":"\n✅ Custom Sensitive Information Types are configured, enabling detection of organization-specific sensitive data patterns.\n\n## [Custom Sensitive Information Types](https://purview.microsoft.com/informationprotection/dataclassification/sensinfoTypes)\n\n| Name | Description | Publisher |\n| :--- | :--- | :--- |\n| test-1 | testing | Pora Inc. |\n| test-35033 | custom SIT | Pora Inc. |\n\n**Summary:**\n* Total Custom SITs: 2\n\n\n","TestStatus":"Passed","TestTags":null},{"TestImplementationCost":"Low","TestPillar":"Devices","TestCategory":"Data","SkippedReason":null,"TestImpact":"Medium","TestAppliesTo":null,"TestSfiPillar":"Protect tenants and isolate production systems","TestSkipped":"","TestMinimumLicense":"Intune","TestTags":null,"TestTitle":"Non-compliant Devices are Restricted from Accessing Corporate Data ","TestRisk":"High","TestResult":"\nNo conditional access policy with device compliance exists for one or more platforms, and no policy applies to all platforms.\n\n\n## Conditional Access Policies with Device Compliance\n\n| Policy Name | Platforms |\n| :---------- | :-------- |\n| [\\[ellis\\] - Require app protection policy](https://intune.microsoft.com/#view/Microsoft_AAD_ConditionalAccess/ConditionalAccessBlade/~/Policies) | android, iOS |\n\n\n","TestStatus":"Failed","TestDescription":"If Microsoft Entra Conditional Access policies don't enforce device compliance, users can connect to corporate resources from devices that don't meet security standards. This exposes sensitive data to risks like malware, unauthorized access, and regulatory noncompliance. Without controls like encryption enforcement, device health checks, and access restrictions, threat actors can exploit noncompliant devices to bypass security measures and maintain persistence.\n\n\nRequiring device compliance in Conditional Access policies ensures only trusted and secure devices can access corporate resources. This supports Zero Trust by enforcing access decisions based on device health and compliance posture.\n\n**Remediation action**\n\nConfigure Conditional Access policies in Microsoft Entra to require device compliance before granting access to corporate resources: \n- [Create a device compliance-based Conditional Access policy](https://learn.microsoft.com/intune/intune-service/protect/create-conditional-access-intune?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci)\n\nFor more information, see:\n- [What is Conditional Access?](https://learn.microsoft.com/entra/identity/conditional-access/overview?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci)\n- [Integrate device compliance results with Conditional Access](https://learn.microsoft.com/intune/intune-service/protect/device-compliance-get-started?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci#integrate-with-conditional-access)\n","TestId":"24824"},{"TestImplementationCost":"Medium","TestPillar":"Identity","TestCategory":"Application management","SkippedReason":null,"TestImpact":"Low","TestAppliesTo":null,"TestSfiPillar":"Protect identities and secrets","TestSkipped":"","TestMinimumLicense":"Free","TestTags":null,"TestTitle":"Enforce standards for app secrets and certificates","TestRisk":"Medium","TestResult":"\n❌ Tenant app management policy is enabled but lacks active credential restrictions.`n`n\n\n## Policy configuration assessment\n\n| Property | Status | Value |\n| :------- | :----- | :---- |\n| Policy enabled | ✅ Yes | True |\n\n### Configuration details\n\n**Application restrictions**: ✅ Configured\n\n| Credential type | Restriction type | State | Status |\n| :-------------- | :--------------- | :---- | :----- |\n| Password credentials | passwordAddition | disabled | ⚠️ Configured but inactive |\n| Password credentials | symmetricKeyAddition | disabled | ⚠️ Configured but inactive |\n\n**Service principal restrictions**: ✅ Configured\n\n| Credential type | Restriction type | State | Status |\n| :-------------- | :--------------- | :---- | :----- |\n| Password credentials | passwordAddition | disabled | ⚠️ Configured but inactive |\n| Password credentials | symmetricKeyAddition | disabled | ⚠️ Configured but inactive |\n\n\n\n","TestStatus":"Failed","TestDescription":"Without proper application management policies, threat actors can exploit weak or misconfigured application credentials to get unauthorized access to organizational resources. Applications using long-lived password secrets or certificates create extended attack windows where compromised credentials stay valid for extended periods. If an application uses client secrets that are hardcoded in configuration files or have weak password requirements, threat actors can extract these credentials through different means, including source code repositories, configuration dumps, or memory analysis. If threat actors get these credentials, they can perform lateral movement within the environment, escalate privileges if the application has elevated permissions, establish persistence by creating more backdoor credentials, modify application configuration, or exfiltrate data. The lack of credential lifecycle management lets compromised credentials remain active indefinitely, giving threat actors sustained access to organizational assets and the ability to conduct data exfiltration, system manipulation, or deploy more malicious tools without detection. \n\nConfiguring appropriate app management policies helps organizations stay ahead of these threats.\n\n**Remediation action**\n\n- [Learn how to enforce secret and certificate standards using application management policies](https://learn.microsoft.com/entra/identity/enterprise-apps/tutorial-enforce-secret-standards?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci)\n","TestId":"21775"},{"TestImpact":"Low","TestRisk":"High","TestSkipped":"NoCompatibleLicenseFound","TestAppliesTo":null,"TestPillar":"Network","TestCategory":"Global Secure Access","TestDescription":"Without proper scoping of traffic forwarding profiles, organizations risk either exposing all users to security controls before infrastructure readiness is validated or inadvertently excluding users who should be protected.\n\nRisks of improper scoping:\n\n- **Too broad**: When profiles are assigned to \"all users\" without deliberate planning, a misconfiguration could disrupt network connectivity for the entire organization simultaneously.\n- **Too narrow**: If profiles are scoped too narrowly or assignments are incomplete, a subset of users operates outside the security perimeter, creating gaps that threat actors can exploit.\n- **Unmonitored access**: Attackers who compromise devices belonging to unassigned users can access resources without traffic being inspected, logged, or subject to security policies.\n\nProper scoping ensures controlled rollout—starting with pilot groups to validate functionality, then expanding to broader populations—while maintaining visibility into which users are protected.\n\n**Remediation action**\n\n- Assign users and groups to traffic forwarding profiles. For more information, see [Manage users and groups assignment](https://learn.microsoft.com/entra/global-secure-access/how-to-manage-users-groups-assignment?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci).\n","TestTitle":"Traffic forwarding profiles are scoped to appropriate users and groups for controlled deployment","SkippedReason":"This test requires one of the following licenses: (\"Entra_Premium_Internet_Access\") OR (\"Entra_Premium_Private_Access\"). Please ensure your tenant has the appropriate licenses to run this test. See [Licensing & Service Plans](https://learn.microsoft.com/entra/identity/users/licensing-service-plan-reference)","TestId":"25382","TestImplementationCost":"Low","TestMinimumLicense":["Entra_Premium_Internet_Access","Entra_Premium_Private_Access"],"TestSfiPillar":"Protect networks","TestResult":"\nSkipped. This test requires one of the following licenses: (\"Entra_Premium_Internet_Access\") OR (\"Entra_Premium_Private_Access\"). Please ensure your tenant has the appropriate licenses to run this test. See [Licensing & Service Plans](https://learn.microsoft.com/entra/identity/users/licensing-service-plan-reference)\n\n","TestStatus":"Skipped","TestTags":null},{"TestImplementationCost":"Low","TestPillar":"Network","TestCategory":"Global Secure Access","SkippedReason":"This test is not applicable to the current environment.","TestImpact":"High","TestAppliesTo":null,"TestSfiPillar":"Protect networks","TestSkipped":"NotApplicable","TestMinimumLicense":"Entra_Premium_Internet_Access","TestTags":null,"TestTitle":"TLS inspection certificates have sufficient validity period to prevent service disruption","TestRisk":"High","TestResult":"\nSkipped. This test is not applicable to the current environment.\n","TestStatus":"Skipped","TestDescription":"TLS inspection in Global Secure Access relies on an intermediate certificate authority certificate to dynamically generate leaf certificates for decrypting and inspecting encrypted traffic. When this certificate expires, the service can no longer perform TLS termination, which immediately disables all TLS inspection capabilities including URL filtering, threat detection, and data loss prevention on HTTPS traffic. Threat actors are aware that security controls often lapse during certificate expiration windows and may time attacks accordingly, knowing that encrypted malware delivery, command-and-control communications, and data exfiltration will bypass inspection. Organizations that do not proactively monitor certificate expiration risk sudden loss of visibility into encrypted traffic, potentially during a critical security incident. Microsoft documentation recommends that signed certificates remain valid for at least 6 months. Maintaining a 90-day buffer before expiration provides adequate time to complete the certificate renewal process.\n\n**Remediation action**\n\n1. Generate a new Certificate Signing Request (CSR) and upload a renewed certificate in the Microsoft Entra admin center under Global Secure Access > Secure > TLS inspection policies > TLS inspection settings tab\n2. Sign the CSR using your organization's PKI infrastructure with a validity period of at least 6 months (Microsoft recommendation)\n3. Use Active Directory Certificate Services (AD CS) or OpenSSL to sign the CSR\n\n","TestId":"27002"},{"TestImplementationCost":"Low","TestPillar":"Identity","TestCategory":"Privileged access","SkippedReason":null,"TestImpact":"Low","TestAppliesTo":null,"TestSfiPillar":"Protect engineering systems","TestSkipped":"","TestMinimumLicense":"Free","TestTags":null,"TestTitle":"Global Administrators don't have standing elevated access to all Azure subscriptions in the tenant","TestRisk":"High","TestResult":"\nStanding access to Root Management group was found.\n\n\n## Entra ID objects with standing access to Root Management group\n\n\n| Entra ID Object | Object ID | Principal type |\n| :-------------- | :-------- | :------------- |\n| ash@contoso.com | 513f3db2-044c-41be-af14-431bf88a2b3e | User |\n| charlie@contoso.com | 5b0ec3ff-cea1-4eb9-8530-f2a66e5bec0a | User |\n| peyton@contoso.com | 7e92f268-bb12-469a-a869-210d596d4c1f | User |\n| finley.robinson@contoso.com | 990fd38a-c516-4e3f-82e4-d458a1ab0f91 | User |\n| cameron@contoso.com | 1ce4078f-f795-4baf-aa55-1fdfcc2ebfe6 | User |\n| hayden@contoso.com | c0b65b13-37b1-4081-bcfc-14844159b4a5 | User |\n\n\n\n","TestStatus":"Failed","TestDescription":"Global Administrators with persistent access to Azure subscriptions expand the attack surface for threat actors. If a Global Administrator account is compromised, attackers can immediately enumerate resources, modify configurations, assign roles, and exfiltrate sensitive data across all subscriptions. Requiring just-in-time elevation for subscription access introduces detectable signals, slows attacker velocity, and routes high-impact operations through observable control points.\n\n**Remediation action**\n\n- [Get started with a phishing-resistant passwordless authentication deployment](https://learn.microsoft.com/entra/identity/authentication/how-to-plan-prerequisites-phishing-resistant-passwordless-authentication?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci)\n\n- [Ensure that privileged accounts register and use phishing resistant methods](https://learn.microsoft.com/entra/identity/authentication/concept-authentication-strengths?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci#authentication-strengths.md)\n\n- [Deploy Conditional Access policy to target privileged accounts and require phishing resistant credentials using authentication strengths](https://learn.microsoft.com/entra/identity/conditional-access/policy-admin-phish-resistant-mfa?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci)\n\n- [Monitor authentication method activity](https://learn.microsoft.com/entra/identity/monitoring-health/concept-usage-insights-report?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci#authentication-methods-activity.md)\n","TestId":"21788"},{"TestImplementationCost":"High","TestPillar":"Identity","TestCategory":"Monitoring","SkippedReason":null,"TestImpact":"Low","TestAppliesTo":["Identity"],"TestSfiPillar":"Monitor and detect cyberthreats","TestSkipped":"","TestMinimumLicense":"P2","TestTags":["Identity"],"TestTitle":"All risky users are triaged","TestRisk":"High","TestResult":"\nFound **1** untriaged high-risk users in Entra ID Protection.\n## Untriaged High-Risk Users\n\n| User | Risk level | Last updated | Risk detail |\n| :----------------- | :--------- | :-------------------- | :---------- |\n| finley.robinson@contoso.com | High | 05/05/2026 06:06:46 | none |\n\n\n","TestStatus":"Failed","TestDescription":"Users considered at high risk by Microsoft Entra ID Protection have a high probability of compromise by threat actors. Threat actors can gain initial access via compromised valid accounts, where their suspicious activities continue despite triggering risk indicators. This oversight can enable persistence as threat actors perform activities that normally warrant investigation, such as unusual login patterns or suspicious inbox manipulation. \n\nA lack of triage of these risky users allows for expanded reconnaissance activities and lateral movement, with anomalous behavior patterns continuing to generate uninvestigated alerts. Threat actors become emboldened as security teams show they aren't actively responding to risk indicators.\n\n**Remediation action**\n\n- [Investigate high risk users](https://learn.microsoft.com/entra/id-protection/howto-identity-protection-investigate-risk?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci) in Microsoft Entra ID Protection\n- [Remediate high risk users and unblock](https://learn.microsoft.com/entra/id-protection/howto-identity-protection-remediate-unblock?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci) in Microsoft Entra ID Protection\n","TestId":"21861"},{"TestImplementationCost":"Medium","TestPillar":"Identity","TestCategory":"Application management","SkippedReason":null,"TestImpact":"Medium","TestAppliesTo":["Identity"],"TestSfiPillar":"Protect identities and secrets","TestSkipped":"","TestMinimumLicense":"Free","TestTags":["Application"],"TestTitle":"Applications don't have secrets configured","TestRisk":"High","TestResult":"\nFound 46 applications and 16 service principals with client secrets configured.\n\n\n## Applications with client secrets\n\n| Application | Secret expiry |\n| :--- | :--- |\n| [AWS Account](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/ApplicationMenuBlade/~/Credentials/appId/2e311a1d-f5c0-41c6-b866-77af3289871e) | 2024-02-11 |\n| [Agent Identity Blueprint Example 12612901](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/ApplicationMenuBlade/~/Credentials/appId/ef1e370e-626b-4839-9340-83e62875489a) | 2026-05-25 |\n| [Agent Identity Blueprint Example 3792929](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/ApplicationMenuBlade/~/Credentials/appId/60253969-9e44-4e0b-85c0-abda1041272c) | 2026-11-02 |\n| [Agent Identity Blueprint Example 4208296](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/ApplicationMenuBlade/~/Credentials/appId/d0e3212f-58a2-4511-8b56-bd57b023106d) | 2026-02-16 |\n| [Agent Identity Blueprint Example 4208710](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/ApplicationMenuBlade/~/Credentials/appId/e79effd2-67cf-4caa-8879-b87389f47819) | 2026-02-16 |\n| [Agent Identity Blueprint Example 4209295](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/ApplicationMenuBlade/~/Credentials/appId/f522f080-5192-4665-87a4-e1211b7adca6) | 2026-02-16 |\n| [Agent0 API](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/ApplicationMenuBlade/~/Credentials/appId/a8a4a52c-9f15-4e2a-a8fe-c267cc3a6101) | 2026-05-28 |\n| [Atlassian - Jira](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/ApplicationMenuBlade/~/Credentials/appId/b0e53e94-b4b0-4632-98ae-e230af1f511c) | 2026-03-16 |\n| [Automation](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/ApplicationMenuBlade/~/Credentials/appId/dc7d83b5-d38b-4488-8952-7abf02e71590) | 2325-01-01 |\n| [Chopin Agent](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/ApplicationMenuBlade/~/Credentials/appId/7dcdc7c5-09a6-435f-9460-9382d32b7bc6) | 2026-02-18 |\n| [Entry Kiosk](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/ApplicationMenuBlade/~/Credentials/appId/b903f17a-87b0-460b-9978-962c812e4f98) | 2021-11-25 |\n| [Graph Filter](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/ApplicationMenuBlade/~/Credentials/appId/c94b2f6c-f4c2-4ab3-8d1a-6971b2c7e975) | 2024-09-16 |\n| [Graph PowerShell - Privileged Perms](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/ApplicationMenuBlade/~/Credentials/appId/c5338ce0-3e9e-4895-8f49-5e176836a348) | 2024-05-15 |\n| [GraphPermissionApp](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/ApplicationMenuBlade/~/Credentials/appId/d36fe320-bc28-40c8-a141-a512d65d112c) | 2027-10-26 |\n| [InfinityDemo](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/ApplicationMenuBlade/~/Credentials/appId/fef811e1-2354-43b0-961b-248fe15e737d) | 2022-11-02 |\n| [Lokka](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/ApplicationMenuBlade/~/Credentials/appId/f581405a-9e57-4e81-91f1-40cd62f7595e) | 2026-10-01 |\n| [M365PronounKit](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/ApplicationMenuBlade/~/Credentials/appId/eea28244-3eec-4820-beae-d4a2c0bcc235) | 2022-03-29 |\n| [Maester DevOps Account - GitHub - Secret (demo)](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/ApplicationMenuBlade/~/Credentials/appId/d0dc5f0a-bf75-41a4-9272-d5ec2345c963) | 2026-02-20 |\n| [Mailbox Migration Account](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/ApplicationMenuBlade/~/Credentials/appId/b650c3c1-3395-40bb-8471-2a6a8b76d8a9) | 2022-08-19 |\n| [Manson Nov 13 Test](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/ApplicationMenuBlade/~/Credentials/appId/d65bd82c-b625-48cd-b485-f61939b48727) | 2026-11-02 |\n| [Manson Test Agent](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/ApplicationMenuBlade/~/Credentials/appId/e6e0e568-682d-4640-a038-2f2489b1d2aa) | 2026-02-16 |\n| [Manson-Test-Nov13](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/ApplicationMenuBlade/~/Credentials/appId/516489b4-b179-4230-b149-440b5c78a7cc) | 2026-11-02 |\n| [MansonTestNov24](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/ApplicationMenuBlade/~/Credentials/appId/d4407e7a-9644-4e25-8df5-6e6da95a9013) | 2026-02-16 |\n| [Message Center](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/ApplicationMenuBlade/~/Credentials/appId/83f76a08-fa60-48e6-9cb5-fd8ced5ae314) | 2026-02-17 |\n| [MessageCenterAccount github.com/manson/mc DO NOT DELETE](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/ApplicationMenuBlade/~/Credentials/appId/778fad36-e4c1-4d40-a58e-9b5b64179d41) | 2124-02-21 |\n| [MyTestForBlock](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/ApplicationMenuBlade/~/Credentials/appId/14a3ba45-3246-4fbe-8c3b-c3922e68232b) | 2025-07-06 |\n| [PnPPowerShell](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/ApplicationMenuBlade/~/Credentials/appId/1d93462e-0f39-4e4c-898a-b6b1df5fa997) | 2022-03-29 |\n| [Postman](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/ApplicationMenuBlade/~/Credentials/appId/7fb37b38-ce4f-4675-9263-0cd3404b4925) | 2023-10-16 |\n| [RemixTest](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/ApplicationMenuBlade/~/Credentials/appId/d4588485-154e-4b32-935f-31ceaf993cdc) | 2024-06-24 |\n| [SharePoint On-Prem App Proxy](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/ApplicationMenuBlade/~/Credentials/appId/19a70df3-cddf-48c7-be44-97b25b9857f1) | 2025-12-12 |\n| [SharePoint Version App](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/ApplicationMenuBlade/~/Credentials/appId/2bb68591-782c-4c64-9415-bdf9414ae400) | 2024-05-15 |\n| [Trello](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/ApplicationMenuBlade/~/Credentials/appId/d77611ee-5051-4383-9af3-5ba3627306a7) | 2022-08-16 |\n| [WPNinja1](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/ApplicationMenuBlade/~/Credentials/appId/eee88dc1-4aab-42b3-b089-4a2cbb19b048) | 2026-05-24 |\n| [WebApplication3](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/ApplicationMenuBlade/~/Credentials/appId/bcdb1ed5-9470-41e6-821b-1fc42ae94cfb) | 2022-11-02 |\n| [WebApplication3_20210211261232](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/ApplicationMenuBlade/~/Credentials/appId/ac49e193-bd5f-40fe-b4ff-e62136419388) | 2022-11-02 |\n| [WebApplication4](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/ApplicationMenuBlade/~/Credentials/appId/b2d1f868-27ee-4ecd-ae81-0ee96b028605) | 2022-04-03 |\n| [WingtipToys App](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/ApplicationMenuBlade/~/Credentials/appId/56a89db1-6ed2-4171-88f6-b4f7597dbce3) | 2025-11-27 |\n| [aadgraphmggraph](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/ApplicationMenuBlade/~/Credentials/appId/24b66505-1142-452f-9472-2ecbb37deac1) | 2022-11-26 |\n| [agent0-blueprint](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/ApplicationMenuBlade/~/Credentials/appId/00b6bee4-a638-4260-9382-09301b3a1db9) | 2026-02-27 |\n| [da-typespec-todo-aad](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/ApplicationMenuBlade/~/Credentials/appId/9358444a-41ec-4a93-915a-4970b3f33738) | 2026-06-04 |\n| [entra-docs-email github DO NOT DELETE](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/ApplicationMenuBlade/~/Credentials/appId/ae06b71a-a0aa-4211-b846-fd74f25ccd45) | 2027-07-14 |\n| [sptest1](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/ApplicationMenuBlade/~/Credentials/appId/022dac2c-8763-4a45-bc41-34cf58e8e35d) | 2026-08-02 |\n| [test](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/ApplicationMenuBlade/~/Credentials/appId/99fbef85-8df4-44c5-ac4e-ec93a88a9b5b) | 2026-08-15 |\n| [test](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/ApplicationMenuBlade/~/Credentials/appId/4f50c653-dae4-44e7-ae2e-a081cce1f830) | 2023-02-25 |\n| [testSP](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/ApplicationMenuBlade/~/Credentials/appId/e47d8f25-5327-40f8-99fe-d832b99d938d) | 2026-05-26 |\n| [testuserread](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/ApplicationMenuBlade/~/Credentials/appId/9fe2675c-7fc5-4895-8470-eed989ea0d63) | 2025-09-03 |\n\n\n## Service Principals with client secrets\n\n| Service principal | App owner tenant | Secret expiry |\n| :--- | :--- | :--- |\n| [21869testapp](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/SignOn/objectId//appId/dd63d132-18fb-4f2e-aec4-82b97f30301f/preferredSingleSignOnMode/saml/servicePrincipalType/Application/fromNav/) | | 2028-10-27 |\n| [APP-2732_Genesys Cloud TCCC-G-TFS-Prod](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/SignOn/objectId//appId/76249b01-8747-4db4-843f-6478d5b32b14/preferredSingleSignOnMode/saml/servicePrincipalType/Application/fromNav/) | | 2028-07-30 |\n| [AWS Single-Account Access](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/SignOn/objectId//appId/091edd89-b342-4bb5-9144-82fe6c913987/preferredSingleSignOnMode/saml/servicePrincipalType/Application/fromNav/) | | 2025-10-26 |\n| [Automation](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/SignOn/objectId//appId/dc7d83b5-d38b-4488-8952-7abf02e71590/preferredSingleSignOnMode/saml/servicePrincipalType/Application/fromNav/) | | 2027-03-03 |\n| [Azure AD SAML Toolkit](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/SignOn/objectId//appId/6f5ed68c-9fad-4d78-bf88-2b16bbe16338/preferredSingleSignOnMode/saml/servicePrincipalType/Application/fromNav/) | | 2028-10-11 |\n| [Dropbox Business](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/SignOn/objectId//appId/f76d7d98-02ee-4e62-9345-36016a72e664/preferredSingleSignOnMode/saml/servicePrincipalType/Application/fromNav/) | | 2024-02-17 |\n| [charlie AWS Account](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/SignOn/objectId//appId/d3a04f85-a969-436b-bf4d-eae0a91efb4c/preferredSingleSignOnMode/saml/servicePrincipalType/Application/fromNav/) | | 2028-01-07 |\n| [charlie- Genesys Cloud for Azure](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/SignOn/objectId//appId/9c599cd2-9fb0-4815-b65c-83be33f5df1b/preferredSingleSignOnMode/saml/servicePrincipalType/Application/fromNav/) | | 2028-07-30 |\n| [P2P Server](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/SignOn/objectId//appId/2af9f5c5-0ffc-4d1c-ba2e-72cf6382df06/preferredSingleSignOnMode/saml/servicePrincipalType/Application/fromNav/) | | 2024-06-11 |\n| [SPO Version](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/SignOn/objectId//appId/2d6d9bf1-1f6e-48cf-bb02-31beec2f442e/preferredSingleSignOnMode/saml/servicePrincipalType/Application/fromNav/) | | 2024-11-17 |\n| [Salesforce](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/SignOn/objectId//appId/1a2a1d4c-1d76-44ec-95f4-3ed5345423a9/preferredSingleSignOnMode/saml/servicePrincipalType/Application/fromNav/) | | 2025-10-02 |\n| [Saml test entity id](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/SignOn/objectId//appId/6590313e-1c00-4c07-be28-72858e837a52/preferredSingleSignOnMode/saml/servicePrincipalType/Application/fromNav/) | | 2025-11-17 |\n| [ServiceNow](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/SignOn/objectId//appId/ecbbb1c8-ef06-48c4-9211-9ffbfbc24b94/preferredSingleSignOnMode/saml/servicePrincipalType/Application/fromNav/) | | 2024-02-15 |\n| [SumoLogic](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/SignOn/objectId//appId/1b6c36b2-f2b1-43d3-b74f-8d52c44fc9c1/preferredSingleSignOnMode/saml/servicePrincipalType/Application/fromNav/) | | 2027-02-15 |\n| [claimtest](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/SignOn/objectId//appId/f816d68b-aec7-4eab-9ebc-bd23b0d04e35/preferredSingleSignOnMode/saml/servicePrincipalType/Application/fromNav/) | | 2028-02-26 |\n| [test](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/SignOn/objectId//appId/8ae2b566-71f5-467e-8960-cfe8da3a2cfa/preferredSingleSignOnMode/saml/servicePrincipalType/Application/fromNav/) | | 2025-10-10 |\n\n\n","TestStatus":"Failed","TestDescription":"Applications that use client secrets might store them in configuration files, hardcode them in scripts, or risk their exposure in other ways. The complexities of secret management make client secrets susceptible to leaks and attractive to attackers. Client secrets, when exposed, provide attackers with the ability to blend their activities with legitimate operations, making it easier to bypass security controls. If an attacker compromises an application's client secret, they can escalate their privileges within the system, leading to broader access and control, depending on the permissions of the application.\n\nApplications and service principals that have permissions for Microsoft Graph APIs or other APIs have a higher risk because an attacker can potentially exploit these additional permissions.\n\n**Remediation action**\n\n- [Move applications away from shared secrets to managed identities and adopt more secure practices](https://learn.microsoft.com/entra/identity/enterprise-apps/migrate-applications-from-secrets?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci).\n - Use managed identities for Azure resources\n - Deploy Conditional Access policies for workload identities\n - Implement secret scanning\n - Deploy application authentication policies to enforce secure authentication practices\n - Create a least-privileged custom role to rotate application credentials\n - Ensure you have a process to triage and monitor applications\n","TestId":"21772"},{"TestImpact":"Medium","TestRisk":"Medium","TestSkipped":"NoCompatibleLicenseFound","TestAppliesTo":null,"TestPillar":"Network","TestCategory":"Global Secure Access","TestDescription":"When Microsoft Entra private network connectors are inactive or unhealthy, organizations might resort to using less secure access methods. This condition creates opportunities where threat actors can target externally exposed services or use compromised credentials.\n\nWithout functional connectors:\n\n- Token-based authentication and authorization for all Microsoft Entra Private Access scenarios is eliminated.\n- Threat actors can bypass intended security boundaries to access resources beyond their authorization scope.\n- The service can't route requests properly, directly disrupting network access controls.\n\n**Remediation action**\n\n- [Configure connectors for high availability](https://learn.microsoft.com/entra/global-secure-access/how-to-configure-connectors?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci).\n- Monitor connector health in the Microsoft Entra admin center under Global Secure Access > Connect > Connectors.\n- [Troubleshoot connector installation and connectivity issues](https://learn.microsoft.com/entra/global-secure-access/troubleshoot-connectors?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci).\n","TestTitle":"Private network connectors are active and healthy to maintain Zero Trust access to internal resources","SkippedReason":"This test requires one of the following licenses: (\"Entra_Premium_Private_Access\"). Please ensure your tenant has the appropriate licenses to run this test. See [Licensing & Service Plans](https://learn.microsoft.com/entra/identity/users/licensing-service-plan-reference)","TestId":"25391","TestImplementationCost":"Low","TestMinimumLicense":["Entra_Premium_Private_Access"],"TestSfiPillar":"Protect networks","TestResult":"\nSkipped. This test requires one of the following licenses: (\"Entra_Premium_Private_Access\"). Please ensure your tenant has the appropriate licenses to run this test. See [Licensing & Service Plans](https://learn.microsoft.com/entra/identity/users/licensing-service-plan-reference)\n\n","TestStatus":"Skipped","TestTags":null},{"TestImpact":"High","TestRisk":"Medium","TestSkipped":"","TestAppliesTo":null,"TestPillar":"Data","TestCategory":"Sensitivity Labels Configuration","TestDescription":"Container labels extend sensitivity labels beyond individual items to entire collaboration workspaces like Microsoft Teams, Microsoft 365 Groups, and SharePoint sites. These labels control workspace-level settings such as external sharing, guest access, device restrictions, and privacy.\n\nWithout container labels, users might be able to create Teams with external guest access even when handling confidential information. This action creates data exfiltration risks where properly labeled documents exist in improperly secured workspaces. Container labels can help to ensure that workspace security matches the sensitivity of stored content, for example, prevent documents labeled as \"Highly Confidential\" from residing in Teams sites that permit external sharing.\n\n**Remediation action**\n\n- [Use sensitivity labels to protect content in Microsoft Teams, Microsoft 365 groups, and SharePoint sites](https://learn.microsoft.com/purview/sensitivity-labels-teams-groups-sites?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci)\n","TestTitle":"Container labels are configured for Teams, Groups, and Sites","SkippedReason":null,"TestId":"35012","TestImplementationCost":"Medium","TestMinimumLicense":["RMS_S_PREMIUM2"],"TestSfiPillar":"Protect tenants and production systems","TestResult":"\n❌ No container labels are configured (acceptable if Teams/Groups not used; may be a gap if collaboration workspaces exist).\n\n\n## Summary\n\n| Metric | Value |\n|:---|:---|\n| Total sensitivity labels | 9 |\n| Container-protected labels | 0 |\n\n\n\n","TestStatus":"Failed","TestTags":null},{"TestImpact":"Low","TestRisk":"High","TestSkipped":"","TestAppliesTo":null,"TestPillar":"Data","TestCategory":"Entra","TestDescription":"Microsoft Rights Management Service (RMS) is the protection technology that enforces encryption for sensitivity labels and information protection policies. When users access encrypted content, their applications must authenticate to the RMS service (App ID: `00000012-0000-0000-c000-000000000000`) to decrypt the content. If Conditional Access policies incorrectly block or restrict this authentication - for example, by requiring multi-factor authentication (MFA), device compliance, or specific network locations - users will be unable to open encrypted emails, documents, or files protected by sensitivity labels.\nThis is most notable when trying to collaborate on MIP protected content from an external tenant to the source tenant.\nThe RMS service should be explicitly excluded from Conditional Access policies that enforce authentication controls, as the application itself is handling the decryption and the user has already authenticated through their primary client application. Blocking RMS authentication prevents the decryption process and breaks information protection workflows across Microsoft 365 services including Outlook, Word, Excel, PowerPoint, Teams, and SharePoint.\n\n**Remediation action**\n\nTo exclude RMS from Conditional Access policies:\n1. Navigate to [Microsoft Entra admin center > Entra ID > Conditional Access > Policies](https://entra.microsoft.com/#view/Microsoft_AAD_ConditionalAccess/ConditionalAccessBlade/~/Policies)\n2. Select the policy that is blocking RMS\n3. Under Target resources > All resources (formerly 'All cloud apps')\n4. Under Exclude, select 'Select resources' and add \"Microsoft Rights Management Services\" (App ID: `00000012-0000-0000-c000-000000000000`)\n5. Save the policy\n\n- [Microsoft Entra configuration for Azure Information Protection](https://learn.microsoft.com/purview/encryption-azure-ad-configuration)\n- [Conditional Access policies and encrypted documents](https://learn.microsoft.com/purview/encryption-azure-ad-configuration#conditional-access-policies-and-encrypted-documents)\n- [Conditional Access: Cloud apps, actions, and authentication context](https://learn.microsoft.com/entra/identity/conditional-access/concept-conditional-access-cloud-apps)\n\n","TestTitle":"Conditional Access RMS Exclusions","SkippedReason":null,"TestId":"35001","TestImplementationCost":"Low","TestMinimumLicense":["RMS_S_PREMIUM2"],"TestSfiPillar":"","TestResult":"\n❌ Microsoft Rights Management Service (RMS) is blocked or restricted by one or more Conditional Access policies.\n\n**Policies Affecting RMS:**\n\n| Policy Name | State | RMS Targeted | RMS Excluded | Grant Controls | Session Controls |\n| :--- | :--- | :--- | :--- | :--- | :--- |\n| [MFA - All users](https://entra.microsoft.com/#view/Microsoft_AAD_ConditionalAccess/PolicyBlade/policyId/474ddef4-5620-4e7a-8976-6e9b095b2675) | enabled | Yes | No | mfa | None |\n| [Guest-Meferna-Woodgrove-PhishingResistantAuthStrength](https://entra.microsoft.com/#view/Microsoft_AAD_ConditionalAccess/PolicyBlade/policyId/0f0a0c1c-41b0-4c18-ae20-d02492d03737) | enabled | Yes | No | None | None |\n| [Block Device Code](https://entra.microsoft.com/#view/Microsoft_AAD_ConditionalAccess/PolicyBlade/policyId/db2153a1-40a2-457f-917c-c280b204b5cd) | enabled | Yes | No | block | None |\n| [Block access except Compliant Network](https://entra.microsoft.com/#view/Microsoft_AAD_ConditionalAccess/PolicyBlade/policyId/9ee6df4b-165d-4f86-a176-0ddcc4ad886c) | enabled | Yes | No | block | None |\n| [ZTA Test - Block AI Agents with High Risk](https://entra.microsoft.com/#view/Microsoft_AAD_ConditionalAccess/PolicyBlade/policyId/a2eb4554-6a7e-4b08-8212-ca8fa3e67e32) | enabled | Yes | No | block | None |\n| [ZT-Test Agent Users](https://entra.microsoft.com/#view/Microsoft_AAD_ConditionalAccess/PolicyBlade/policyId/38498fd7-41cb-4fc3-8c88-513d4b13f0f1) | enabled | Yes | No | block | None |\n\n","TestStatus":"Failed","TestTags":null},{"TestImplementationCost":"Medium","TestPillar":"Identity","TestCategory":"Access control","SkippedReason":"UnderConstruction","TestImpact":"Low","TestAppliesTo":["Identity"],"TestSfiPillar":"Protect identities and secrets","TestSkipped":"UnderConstruction","TestMinimumLicense":null,"TestTags":["Identity"],"TestTitle":"All certificates Microsoft Entra Application Registrations and Service Principals must be issued by an approved certification authority","TestRisk":"Low","TestResult":"\nPlanned for future release.\n","TestStatus":"Planned","TestDescription":"...\n\n**Remediation action**\n\n","TestId":"21894"},{"TestImplementationCost":"Low","TestPillar":"Identity","TestCategory":"Credential management, Privileged access","SkippedReason":null,"TestImpact":"Low","TestAppliesTo":null,"TestSfiPillar":"Protect identities and secrets","TestSkipped":"","TestMinimumLicense":"P1","TestTags":null,"TestTitle":"Block administrators from using SSPR","TestRisk":"High","TestResult":"\n✅ Administrators are properly blocked from using Self-Service Password Reset, ensuring password changes go through controlled processes.\n\n","TestStatus":"Passed","TestDescription":"Self-Service Password Reset (SSPR) for administrators allows password changes to happen without strong secondary authentication factors or administrative oversight. Threat actors who compromise administrative credentials can use this capability to bypass other security controls and maintain persistent access to the environment.\n\nOnce compromised, attackers can immediately reset the password to lock out legitimate administrators. They can then establish persistence, escalate privileges, and deploy malicious payloads undetected.\n\n**Remediation action**\n\n- [Disable SSPR for administrators by updating the authorization policy](https://learn.microsoft.com/entra/identity/authentication/concept-sspr-policy?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci#administrator-reset-policy-differences)\n","TestId":"21842"},{"TestImplementationCost":"Low","TestPillar":"Identity","TestCategory":"External collaboration","SkippedReason":null,"TestImpact":"Low","TestAppliesTo":null,"TestSfiPillar":"Protect tenants and isolate production systems","TestSkipped":"","TestMinimumLicense":"Free","TestTags":null,"TestTitle":"Guest self-service sign-up via user flow is disabled","TestRisk":"Medium","TestResult":"\n[Guest self-service sign up via user flow](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/CompanyRelationshipsMenuBlade/~/Settings/menuId/ExternalIdentitiesGettingStarted) is disabled.\n\n\n","TestStatus":"Passed","TestDescription":"When guest self-service sign-up is enabled, threat actors can exploit it to establish unauthorized access by creating legitimate guest accounts without requiring approval from authorized personnel. These accounts can be scoped to specific services to reduce detection and effectively bypass invitation-based controls that validate external user legitimacy.\n\nOnce created, self-provisioned guest accounts provide persistent access to organizational resources and applications. Threat actors can use them to conduct reconnaissance activities to map internal systems, identify sensitive data repositories, and plan further attack vectors. This persistence allows adversaries to maintain access across restarts, credential changes, and other interruptions, while the guest account itself offers a seemingly legitimate identity that might evade security monitoring focused on external threats.\n\nAdditionally, compromised guest identities can be used to establish credential persistence and potentially escalate privileges. Attackers can exploit trust relationships between guest accounts and internal resources, or use the guest account as a staging ground for lateral movement toward more privileged organizational assets.\n\n**Remediation action**\n- [Configure guest self-service sign-up With Microsoft Entra External ID](https://learn.microsoft.com/entra/external-id/external-collaboration-settings-configure?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci#to-configure-guest-self-service-sign-up)\n","TestId":"21823"},{"TestImpact":"Medium","TestRisk":"Medium","TestSkipped":"","TestAppliesTo":null,"TestPillar":"Data","TestCategory":"Information Protection","TestDescription":"Without retention policies, emails persist indefinitely in user mailboxes, creating liability for regulatory violations (GDPR, HIPAA, SOX), increased eDiscovery costs, and uncontrolled storage expenses.\n\nRetention policies automatically manage email lifecycle by deleting or preserving messages based on compliance requirements, reducing legal risk, and ensuring regulatory record-keeping obligations are met.\n\n**Remediation action**\n\n- [Create and manage retention policies](https://learn.microsoft.com/purview/create-retention-policies?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci)\n","TestTitle":"Email retention policies are configured","SkippedReason":null,"TestId":"35028","TestImplementationCost":"Medium","TestMinimumLicense":["RMS_S_PREMIUM"],"TestSfiPillar":"Protect tenants and production systems","TestResult":"\n❌ No email retention policies are configured for Exchange Online, creating a compliance and legal risk where emails are retained indefinitely and eDiscovery scope is uncontrolled.\n\n\n### [Retention policies with Exchange scope](https://purview.microsoft.com/datalifecyclemanagement/retention)\n\n| Policy name | Enabled | Exchange scope | Mode |\n| :--- | :--- | :--- | :--- |\n| Email Retention - Standard | ❌ No | All | Enforce |\n| Email Retention - Tergeted | ❌ No | Finley Robinson | Enforce |\n\n\n### Retention rules for Exchange policies\n\n| Rule name | Parent policy | Enabled | Retention action | Retention period |\n| :--- | :--- | :--- | :--- | :--- |\n| Email Retention - Standard | Email Retention - Standard | ✅ Yes | KeepAndDelete | 2555 (Days) |\n| Email Retention - Tergeted | Email Retention - Tergeted | ✅ Yes | Keep | Unlimited (Days) |\n\n### Summary\n\n| Metric | Value |\n| :--- | :--- |\n| Total retention policies | 4 |\n| Enabled Exchange policies | 0 |\n| Active retention rules (Exchange) | 2 |\n\n","TestStatus":"Failed","TestTags":null},{"TestImplementationCost":"Low","TestPillar":"Identity","TestCategory":"Credential management","SkippedReason":null,"TestImpact":"Low","TestAppliesTo":null,"TestSfiPillar":"Protect identities and secrets","TestSkipped":"","TestMinimumLicense":"P1","TestTags":null,"TestTitle":"Temporary access pass is enabled","TestRisk":"Medium","TestResult":"\nTemporary Access Pass is enabled, targeting all users, and enforced with conditional access policies.\n\n**Configuration summary**\n\n[Temporary Access Pass](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/AuthenticationMethodsMenuBlade/~/AdminAuthMethods/fromNav/Identity): Enabled ✅\n\n[Conditional Access policy for Security info registration](https://entra.microsoft.com/#view/Microsoft_AAD_ConditionalAccess/ConditionalAccessBlade/~/Policies/fromNav/Identity): Enabled ✅\n\n[Authentication strength policy for Temporary Access Pass](https://entra.microsoft.com/#view/Microsoft_AAD_ConditionalAccess/AuthenticationStrength.ReactView/fromNav/Identity): Enabled ✅\n\n\n","TestStatus":"Passed","TestDescription":"Without Temporary Access Pass (TAP) enabled, organizations face significant challenges in securely bootstrapping user credentials, creating a vulnerability where users rely on weaker authentication mechanisms during their initial setup. When users cannot register phishing-resistant credentials like FIDO2 security keys or Windows Hello for Business due to lack of existing strong authentication methods, they remain exposed to credential-based attacks including phishing, password spray, or similar attacks. Threat actors can exploit this registration gap by targeting users during their most vulnerable state, when they have limited authentication options available and must rely on traditional username + password combinations. This exposure enables threat actors to compromise user accounts during the critical bootstrapping phase, allowing them to intercept or manipulate the registration process for stronger authentication methods, ultimately gaining persistent access to organizational resources and potentially escalating privileges before security controls are fully established. \n\nEnable TAP and use it with security info registration to secure this potential gap in your defenses.\n\n**Remediation action**\n\n- [Learn how to enable Temporary Access Pass in the Authentication methods policy](https://learn.microsoft.com/entra/identity/authentication/howto-authentication-temporary-access-pass?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci#enable-the-temporary-access-pass-policy)\n- [Learn how to update authentication strength policies to include Temporary Access Pass](https://learn.microsoft.com/entra/identity/authentication/concept-authentication-strength-advanced-options?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci)\n- [Learn how to create a Conditional Access policy for security info registration with authentication strength enforcement](https://learn.microsoft.com/entra/identity/conditional-access/policy-all-users-security-info-registration?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci)\n","TestId":"21845"},{"TestImpact":"Low","TestRisk":"High","TestSkipped":"NoCompatibleLicenseFound","TestAppliesTo":null,"TestPillar":"Network","TestCategory":"Global Secure Access","TestDescription":"Without universal tenant restrictions configured, users on corporate devices and networks can authenticate to unauthorized external Microsoft Entra tenants and access cloud applications by using external identities. This vulnerability makes it possible for a threat actor to use compromised user credentials or established persistence on a corporate device to authenticate to a tenant they control. They can bypass traditional network security controls that can't inspect encrypted authentication traffic to Microsoft identity endpoints.\n\nOnce authenticated to an external tenant, a threat actor can access Microsoft Graph APIs and cloud services. This access enables data exfiltration through OneDrive, SharePoint, Teams, or any Microsoft Entra-integrated application in the external tenant. This attack path exploits the inherent trust that corporate networks and devices have with Microsoft identity services. Universal tenant restrictions address this vulnerability by injecting tenant identity headers into authentication plane traffic through Global Secure Access. Microsoft Entra ID uses these headers to enforce tenant restrictions v2 policies that block authentication attempts to unauthorized external tenants.\n\n**Remediation action**\n- [Set up tenant restrictions v2](https://learn.microsoft.com/entra/external-id/tenant-restrictions-v2?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci) policies to block all external tenants by default.\n- [Turn on universal tenant restrictions](https://learn.microsoft.com/entra/global-secure-access/how-to-universal-tenant-restrictions?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci) signaling in Global Secure Access.\n- [Deploy Global Secure Access client](https://learn.microsoft.com/entra/global-secure-access/concept-clients?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci) on devices.\n- [Enable the Microsoft traffic profile](https://learn.microsoft.com/entra/global-secure-access/how-to-manage-microsoft-profile?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci).\n","TestTitle":"Universal tenant restrictions block unauthorized external tenant access","SkippedReason":"This test requires one of the following licenses: (\"Entra_Premium_Internet_Access\"). Please ensure your tenant has the appropriate licenses to run this test. See [Licensing & Service Plans](https://learn.microsoft.com/entra/identity/users/licensing-service-plan-reference)","TestId":"25377","TestImplementationCost":"Medium","TestMinimumLicense":["Entra_Premium_Internet_Access"],"TestSfiPillar":"Protect networks","TestResult":"\nSkipped. This test requires one of the following licenses: (\"Entra_Premium_Internet_Access\"). Please ensure your tenant has the appropriate licenses to run this test. See [Licensing & Service Plans](https://learn.microsoft.com/entra/identity/users/licensing-service-plan-reference)\n\n","TestStatus":"Skipped","TestTags":null},{"TestImplementationCost":"Low","TestPillar":"Devices","TestCategory":"Tenant","SkippedReason":null,"TestImpact":"Low","TestAppliesTo":null,"TestSfiPillar":"Protect tenants and isolate production systems","TestSkipped":"","TestMinimumLicense":"Intune","TestTags":null,"TestTitle":"Automatic Enrollment to Defender is enabled for Android Devices","TestRisk":"High","TestResult":"\nNo Microsoft Defender for Endpoint Connector found in the tenant.\n\n\n\n","TestStatus":"Failed","TestDescription":"If automatic enrollment into Microsoft Defender for Endpoint isn't configured for Android devices in Intune, managed endpoints might remain unprotected against mobile threats. Without Defender onboarding, devices lack advanced threat detection and response capabilities, increasing the risk of malware, phishing, and other mobile-based attacks. Unprotected devices can bypass security policies, access corporate resources, and expose sensitive data to compromise. This gap in mobile threat defense weakens the organization's Zero Trust posture and reduces visibility into endpoint health.\n\nEnabling automatic Defender enrollment ensures Android devices are protected by advanced threat detection and response capabilities. This supports Zero Trust by enforcing mobile threat protection, improving visibility, and reducing exposure to unmanaged or compromised endpoints.\n\n**Remediation action**\n\nUse Intune to configure automatic enrollment into Microsoft Defender for Endpoint for Android devices to enforce mobile threat protection:\n\n- [Integrate Microsoft Defender for Endpoint with Intune and Onboard Devices](https://learn.microsoft.com/intune/intune-service/protect/advanced-threat-protection-configure?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci)\n","TestId":"24871"},{"TestImplementationCost":"Low","TestPillar":"Identity","TestCategory":"Access control","SkippedReason":"UnderConstruction","TestImpact":"Low","TestAppliesTo":["Identity"],"TestSfiPillar":"Monitor and detect cyberthreats","TestSkipped":"UnderConstruction","TestMinimumLicense":"P2","TestTags":["Identity"],"TestTitle":"ID Protection notifications enabled","TestRisk":"High","TestResult":"\nPlanned for future release.\n\n","TestStatus":"Planned","TestDescription":"If you don't enable ID Protection notifications, your organization loses critical real-time alerts when threat actors compromise user accounts or conduct reconnaissance activities. When Microsoft Entra ID Protection detects accounts at risk, it sends email alerts with **Users at risk detected** as the subject and links to the **Users flagged for risk** report. Without these notifications, security teams remain unaware of active threats, allowing threat actors to maintain persistence in compromised accounts without being detected. You can feed these risks into tools like Conditional Access to make access decisions or send them to a security information and event management (SIEM) tool for investigation and correlation. Threat actors can use this detection gap to conduct lateral movement activities, privilege escalation attempts, or data exfiltration operations while administrators remain unaware of the ongoing compromise. The delayed response enables threat actors to establish more persistence mechanisms, change user permissions, or access sensitive resources before you can fix the issue. Without proactive notification of risk detections, organizations must rely solely on manual monitoring of risk reports, which significantly increases the time it takes to detect and respond to identity-based attacks. \n\n**Remediation action**\n\n- [Configure users at risk detected alerts](https://learn.microsoft.com/entra/id-protection/howto-identity-protection-configure-notifications?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci#configure-users-at-risk-detected-alerts)\n","TestId":"21798"},{"TestImplementationCost":"Medium","TestPillar":"Identity","TestCategory":"Application management","SkippedReason":null,"TestImpact":"High","TestAppliesTo":["Identity"],"TestSfiPillar":"Protect identities and secrets","TestSkipped":"","TestMinimumLicense":"Free","TestTags":["Identity"],"TestTitle":"User consent settings are restricted","TestRisk":"High","TestResult":"\n✅ **Pass**: User consent settings are properly restricted to prevent illicit consent grant attacks.\n\n\n## Authorization Policy Configuration\n\n\n**Current [user consent settings](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ConsentPoliciesMenuBlade/~/UserSettings)**\n\n- Allow user consent for apps from verified publishers, for selected permissions (Recommended).\nAll users can consent for permissions classified as \"low impact\", for apps from verified publishers or apps registered in this organization.\n\n\n","TestStatus":"Passed","TestDescription":"Without restricted user consent settings, threat actors can exploit permissive application consent configurations to gain unauthorized access to sensitive organizational data. When user consent is unrestricted, attackers can:\n\n- Use social engineering and illicit consent grant attacks to trick users into approving malicious applications.\n- Impersonate legitimate services to request broad permissions, such as access to email, files, calendars, and other critical business data.\n- Obtain legitimate OAuth tokens that bypass perimeter security controls, making access appear normal to security monitoring systems.\n- Establish persistent access to organizational resources, conduct reconnaissance across Microsoft 365 services, move laterally through connected systems, and potentially escalate privileges.\n\nUnrestricted user consent also limits an organization's ability to enforce centralized governance over application access, making it difficult to maintain visibility into which non-Microsoft applications have access to sensitive data. This gap creates compliance risks where unauthorized applications might violate data protection regulations or organizational security policies.\n\n**Remediation action**\n\n- [Configure restricted user consent settings](https://learn.microsoft.com/entra/identity/enterprise-apps/configure-user-consent?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci) to prevent illicit consent grants by disabling user consent or limiting it to verified publishers with low-risk permissions only.\n","TestId":"21776"},{"TestImplementationCost":"Low","TestPillar":"Identity","TestCategory":"Access control","SkippedReason":"UnderConstruction","TestImpact":"Low","TestAppliesTo":["Identity"],"TestSfiPillar":"Protect identities and secrets","TestSkipped":"UnderConstruction","TestMinimumLicense":null,"TestTags":["Identity"],"TestTitle":"All privileged role assignments have a recipient that can receive notifications","TestRisk":"Medium","TestResult":"\nPlanned for future release.\n","TestStatus":"Planned","TestDescription":"...\n\n**Remediation action**\n\n","TestId":"21899"},{"TestImpact":"Medium","TestRisk":"Medium","TestSkipped":"","TestAppliesTo":null,"TestPillar":"Network","TestCategory":"Global Secure Access","TestDescription":"Without compliant network controls in Conditional Access policies, organizations can't enforce that users connect to corporate resources through the Global Secure Access service. This limitation leaves authentication traffic vulnerable to interception and replay attacks from arbitrary network locations. \n\nA threat actor who obtains valid user credentials through phishing or credential theft can authenticate from any internet location, bypassing Global Secure Access network controls. Once authenticated, the threat actor can access Microsoft Entra ID-integrated applications and services, exfiltrate data, or establish persistence by creating additional credentials or modifying user permissions. \n\nThe compliant network check reduces this risk by requiring that authentication traffic originates from the Global Secure Access service, which tags authentication requests with tenant-specific network identity signals. This requirement enables Microsoft Entra ID Conditional Access to verify that users connect through the organization's secured network path before granting access.\n\n**Remediation action**\n- Enable Global Secure Access signaling for Conditional Access. For more information, see [Enable compliant network check with Conditional Access](https://learn.microsoft.com/entra/global-secure-access/how-to-compliant-network?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci#enable-global-secure-access-signaling-for-conditional-access).\n- Create a Conditional Access policy that requires compliant network for access. For more information, see [Protect your resources behind the compliant network](https://learn.microsoft.com/entra/global-secure-access/how-to-compliant-network?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci#protect-your-resources-behind-the-compliant-network).\n- Deploy Global Secure Access clients on devices. For more information, see [Global Secure Access clients overview](https://learn.microsoft.com/entra/global-secure-access/concept-clients?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci).\n- Understand compliant network enforcement. For more information, see [Compliant network check enforcement](https://learn.microsoft.com/entra/global-secure-access/how-to-compliant-network?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci#compliant-network-check-enforcement).\n","TestTitle":"Conditional Access policies use compliant network controls","SkippedReason":null,"TestId":"25379","TestImplementationCost":"Medium","TestMinimumLicense":["AAD_PREMIUM","AAD_PREMIUM_P2"],"TestSfiPillar":"Protect networks","TestResult":"\n❌ **Fail**: Global Secure Access signaling is disabled. Compliant network controls cannot function without this prerequisite.\n\n\n### [Global Secure Access Signaling Status](https://entra.microsoft.com/#view/Microsoft_Azure_Network_Access/Security.ReactView)\n\n| Setting | Value |\n| :------ | :---- |\n| Signaling status | ❌ Disabled |\n### [Compliant Network Named Location](https://entra.microsoft.com/#view/Microsoft_AAD_ConditionalAccess/ConditionalAccessBlade/~/NamedLocations)\n\n| Property | Value |\n| :------- | :---- |\n| Display name | All Compliant Network locations |\n| Network type | allTenantCompliantNetworks |\n| Is trusted | ✅ True |\n| Location ID | 3d46dbda-8382-466a-856d-eb00cbc6b910 |\n### [Conditional Access Policies Using Compliant Network](https://entra.microsoft.com/#view/Microsoft_AAD_ConditionalAccess/ConditionalAccessBlade/~/Policies)\n\n❌ No enabled Conditional Access policies reference the compliant network location.\n\n**Summary:**\n\n- Global Secure Access signaling enabled: False\n- Compliant network location exists: True\n- Policies using standard pattern (block all except compliant): 0\n- Policies using alternative patterns: 0\n\n","TestStatus":"Failed","TestTags":null},{"TestImplementationCost":"High","TestPillar":"Identity","TestCategory":"Access control","SkippedReason":null,"TestImpact":"High","TestAppliesTo":["Identity"],"TestSfiPillar":"Protect identities and secrets","TestSkipped":"","TestMinimumLicense":"P1","TestTags":["Identity"],"TestTitle":"Use cloud authentication","TestRisk":"High","TestResult":"\nAll domains are using cloud authentication.\n\n\n\n","TestStatus":"Passed","TestDescription":"An on-premises federation server introduces a critical attack surface by serving as a central authentication point for cloud applications. Threat actors often gain a foothold by compromising a privileged user such as a help desk representative or an operations engineer through attacks like phishing, credential stuffing, or exploiting weak passwords. They might also target unpatched vulnerabilities in infrastructure, use remote code execution exploits, attack the Kerberos protocol, or use pass-the-hash attacks to escalate privileges. Misconfigured remote access tools like remote desktop protocol (RDP), virtual private network (VPN), or jump servers provide other entry points, while supply chain compromises or malicious insiders further increase exposure. Once inside, threat actors can manipulate authentication flows, forge security tokens to impersonate any user, and pivot into cloud environments. Establishing persistence, they can disable security logs, evade detection, and exfiltrate sensitive data.\n\n**Remediation action**\n\n- [Migrate from federation to cloud authentication like Microsoft Entra Password hash synchronization (PHS)](https://learn.microsoft.com/entra/identity/hybrid/connect/migrate-from-federation-to-cloud-authentication?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci).\n","TestId":"21829"},{"TestImplementationCost":"Medium","TestPillar":"Identity","TestCategory":"Devices","SkippedReason":null,"TestImpact":"Low","TestAppliesTo":null,"TestSfiPillar":"Protect identities and secrets","TestSkipped":"","TestMinimumLicense":"P1","TestTags":null,"TestTitle":"Local Admin Password Solution is deployed","TestRisk":"High","TestResult":"\nLocal Admin Password Solution is deployed.\n## Local Admin Password Solution (LAPS) settings\n\n| Setting | Status |\n| :---- | :---- |\n|[Enable Microsoft Entra Local Administrator Password Solution (LAPS)](https://entra.microsoft.com/#view/Microsoft_AAD_Devices/DevicesMenuBlade/~/DeviceSettings/menuId/Overview) | Enabled\n\n\n","TestStatus":"Passed","TestDescription":"Without Local Admin Password Solution (LAPS) deployed, threat actors exploit static local administrator passwords to establish initial access. After threat actors compromise a single device with a shared local administrator credential, they can move laterally across the environment and authenticate to other systems sharing the same password. Compromised local administrator access gives threat actors system-level privileges, letting them disable security controls, install persistent backdoors, exfiltrate sensitive data, and establish command and control channels. \n\nThe automated password rotation and centralized management of LAPS closes this security gap and adds controls to help manage who has access to these critical accounts. Without solutions like LAPS, you can't detect or respond to unauthorized use of local administrator accounts, giving threat actors extended dwell time to achieve their objectives while remaining undetected.\n\n**Remediation action**\n\n- [Configure Windows Local Administrator Password Solution](https://learn.microsoft.com/entra/identity/devices/howto-manage-local-admin-passwords?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci).\n","TestId":"21953"},{"TestImplementationCost":"Low","TestPillar":"Identity","TestCategory":"Access control","SkippedReason":"UnderConstruction","TestImpact":"Low","TestAppliesTo":["Identity"],"TestSfiPillar":"Protect identities and secrets","TestSkipped":"UnderConstruction","TestMinimumLicense":null,"TestTags":["Identity"],"TestTitle":"Use PIM for Microsoft Entra privileged roles","TestRisk":"Medium","TestResult":"\nPlanned for future release.\n","TestStatus":"Planned","TestDescription":"...\n\n**Remediation action**\n\n","TestId":"21876"},{"TestImplementationCost":"Medium","TestPillar":"Identity","TestCategory":"External collaboration","SkippedReason":null,"TestImpact":"Low","TestAppliesTo":["Identity"],"TestSfiPillar":"Protect tenants and isolate production systems","TestSkipped":"","TestMinimumLicense":"Free","TestTags":["Identity"],"TestTitle":"Guests don't own apps in the tenant","TestRisk":"Medium","TestResult":"\nNo guest users own any applications or service principals in the tenant.\n\n","TestStatus":"Passed","TestDescription":"Without restrictions preventing guest users from registering and owning applications, threat actors can exploit external user accounts to establish persistent backdoor access to organizational resources through application registrations that might evade traditional security monitoring. When guest users own applications, compromised guest accounts can be used to exploit guest-owned applications that might have broad permissions. This vulnerability enables threat actors to request access to sensitive organizational data such as emails, files, and user information without the same level of scrutiny for internal user-owned applications.\n\nThis attack vector is dangerous because guest-owned applications can be configured to request high-privilege permissions and, once granted consent, provide threat actors with legitimate OAuth tokens. Furthermore, guest-owned applications can serve as command and control infrastructure, so threat actors can maintain access even after the compromised guest account is detected and remediated. Application credentials and permissions might persist independently of the original guest user account, so threat actors can retain access. Guest-owned applications also complicate security auditing and governance efforts, as organizations might have limited visibility into the purpose and security posture of applications registered by external users. These hidden weaknesses in the application lifecycle management make it difficult to assess the true scope of data access granted to non-Microsoft entities through seemingly legitimate application registrations.\n\n**Remediation action**\n- Remove guest users as owners from applications and service principals, and implement controls to prevent future guest user application ownership.\n- [Restrict guest user access permissions](https://learn.microsoft.com/entra/identity/users/users-restrict-guest-permissions?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci)\n","TestId":"21868"},{"TestImplementationCost":"Low","TestPillar":"Network","TestCategory":"Azure Network Security","SkippedReason":"This test is not applicable to the current environment.","TestImpact":"Low","TestAppliesTo":null,"TestSfiPillar":"Protect networks","TestSkipped":"NotApplicable","TestMinimumLicense":"Azure WAF","TestTags":null,"TestTitle":"Bot protection ruleset is enabled and assigned in Application Gateway WAF","TestRisk":"High","TestResult":"\nNo Application Gateway WAF policies found attached to Application Gateways.\n","TestStatus":"Skipped","TestDescription":"Azure Application Gateway Web Application Firewall (WAF) provides bot protection through the Microsoft Bot Manager ruleset, which identifies and categorizes automated traffic based on behavioral patterns, known bot signatures, and IP reputation. Without bot protection enabled, threat actors leverage automated tools to perform large-scale attacks that would be impractical manually: credential stuffing attacks that test stolen username and password combinations across login endpoints at thousands of attempts per minute, content scraping that extracts proprietary data and pricing information for competitive exploitation, inventory hoarding bots that deplete product availability for legitimate customers, and application-layer denial of service attacks that overwhelm backend resources. These automated attacks often originate from distributed botnets that rotate IP addresses to evade simple rate limiting, making signature-based bot detection essential. The Bot Manager ruleset classifies bots into categories including known good bots (search engines), known bad bots (scrapers, spammers), and unknown bots, allowing granular policy enforcement. Without this classification, malicious bot traffic blends with legitimate requests, consuming application resources and enabling fraud that damages revenue and customer trust.\n\n**Remediation action**\n\n- [What is Azure Web Application Firewall on Azure Application Gateway?](https://learn.microsoft.com/en-us/azure/web-application-firewall/ag/ag-overview) - Overview of WAF capabilities on Application Gateway including bot protection\n- [Configure bot protection for Web Application Firewall on Azure Application Gateway](https://learn.microsoft.com/en-us/azure/web-application-firewall/ag/bot-protection) - Step-by-step guidance on enabling and configuring bot protection\n- [Web Application Firewall bot protection overview](https://learn.microsoft.com/en-us/azure/web-application-firewall/ag/bot-protection-overview) - Detailed documentation of bot categories and detection capabilities\n\n","TestId":26882},{"TestImplementationCost":"Low","TestPillar":"Network","TestCategory":"Azure Network Security","SkippedReason":"This test is not applicable to the current environment.","TestImpact":"Low","TestAppliesTo":null,"TestSfiPillar":"Protect networks","TestSkipped":"NotApplicable","TestMinimumLicense":"Azure WAF","TestTags":null,"TestTitle":"Default rule set is assigned in Azure Front Door WAF","TestRisk":"High","TestResult":"\nNo Azure Front Door WAF policies attached to Azure Front Door found across subscriptions.\n","TestStatus":"Skipped","TestDescription":"Azure Front Door Web Application Firewall (WAF) provides centralized, edge-based protection for globally distributed web applications through managed rulesets that contain pre-configured detection signatures for known attack patterns. The Microsoft Default Ruleset is a continuously updated managed ruleset that protects against the most common and dangerous web vulnerabilities without requiring security expertise to configure. When no managed ruleset is enabled, the WAF policy provides no protection against known attack patterns, effectively operating as a pass-through despite being deployed at the edge. Threat actors routinely scan for unprotected web applications and exploit well-documented vulnerabilities using automated toolkits; without managed rules, attackers can execute SQL injection to extract or modify database contents, perform cross-site scripting to hijack user sessions and steal credentials, exploit local file inclusion to read sensitive configuration files, and leverage command injection to gain shell access on backend servers. These attack techniques have known signatures that managed rulesets detect and block at the edge before malicious traffic reaches origin servers, but an empty or disabled ruleset configuration means the WAF cannot recognize these patterns and will allow malicious requests to pass through to the application.\n\n**Remediation action**\n\nOverview of WAF capabilities on Azure Front Door including managed rulesets\n- [Azure Web Application Firewall on Azure Front Door](https://learn.microsoft.com/en-us/azure/web-application-firewall/afds/afds-overview)\n\nDetailed documentation of Default Rule Set groups and rules for Azure Front Door\n- [Web Application Firewall DRS rule groups and rules](https://learn.microsoft.com/en-us/azure/web-application-firewall/afds/waf-front-door-drs)\n\nStep-by-step guidance on creating and configuring WAF policies with managed rulesets\n- [Tutorial: Create a Web Application Firewall policy on Azure Front Door](https://learn.microsoft.com/en-us/azure/web-application-firewall/afds/waf-front-door-create-portal)\n\n","TestId":26883},{"TestImplementationCost":"Low","TestPillar":"Devices","TestCategory":"Tenant","SkippedReason":null,"TestImpact":"Low","TestAppliesTo":null,"TestSfiPillar":"Protect tenants and isolate production systems","TestSkipped":"","TestMinimumLicense":"Intune","TestTags":null,"TestTitle":"Intune Scope Tags are Configured for Delegated Administration","TestRisk":"Medium","TestResult":"\nDelegated administration is enforced with custom Intune Scope Tags assignments.\n\n\n## Scope Tags\n\n| Scope Tag Name | Status | Assignment Target |\n| :------------- | :----- | :---------------- |\n| [Biscope](https://intune.microsoft.com/#view/Microsoft_Intune_DeviceSettings/RolesLandingMenuBlade/~/scopeTags) | ✅ Assigned | **Included:** aad-conditional-access-excluded |\n\n\n\n","TestStatus":"Passed","TestDescription":"If Intune scope tags aren't properly configured for delegated administration, attackers who gain privileged access to Intune or Microsoft Entra ID can escalate privileges and access sensitive device configurations across the tenant. Without granular scope tags, administrative boundaries are unclear, allowing attackers to move laterally, manipulate device policies, exfiltrate configuration data, or deploy malicious settings to all users and devices. A single compromised admin account can impact the entire environment. The absence of delegated administration also undermines least-privileged access, making it difficult to contain breaches and enforce accountability. Attackers might exploit global administrator roles or misconfigured role-based access control (RBAC) assignments to bypass compliance policies and gain broad control over device management.\n\nEnforcing scope tags segments administrative access and aligns it with organizational boundaries. This limits the blast radius of compromised accounts, supports least-privilege access, and aligns with Zero Trust principles of segmentation, role-based control, and containment.\n\n**Remediation action**\n\nUse Intune scope tags and RBAC roles to limit admin access based on role, geography, or business unit: \n- [Learn how to create and deploy scope tags for distributed IT](https://learn.microsoft.com/intune/intune-service/fundamentals/scope-tags?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci)\n- [Implement role-based access control with Microsoft Intune](https://learn.microsoft.com/intune/intune-service/fundamentals/role-based-access-control?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci)\n","TestId":"24555"},{"TestImpact":"Low","TestRisk":"Medium","TestSkipped":"","TestAppliesTo":null,"TestPillar":"Data","TestCategory":"Information Protection","TestDescription":"OCR (optical character recognition) extends sensitive information type and trainable classifier detection to images across Exchange, SharePoint, OneDrive, Teams, and endpoint devices. Without OCR, DLP policies, and auto-labeling policies can't scan image-based content, scanned documents, screenshots, and invoices, leaving sensitive data in images unprotected. OCR requires Azure pay-as-you-go billing for Microsoft Syntex, and is configured at the tenant level.\n\n**Remediation action**\n\n- [Learn about and configure optical character recognition in Microsoft Purview](https://learn.microsoft.com/purview/ocr-learn-about?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci)\n","TestTitle":"OCR is enabled for sensitive information detection","SkippedReason":null,"TestId":"35023","TestImplementationCost":"Medium","TestMinimumLicense":["EXCHANGE_S_ENTERPRISE"],"TestSfiPillar":"Protect tenants and production systems","TestResult":"\n❌ OCR is configured but disabled at the tenant level.\n\n\n### OCR configuration status\n\n| Setting | Value |\n| :------ | :---- |\n| Configuration object exists | Yes |\n| OCR enabled (Tenant-level) | False |\n| Exchange location enabled | True |\n| SharePoint location enabled | True |\n| OneDrive location enabled | True |\n| Teams location enabled | True |\n| Endpoint location enabled | True |\n| OCR usage blocked | False |\n| Blockage reason | None |\n| Azure billing status | Configured |\n\n\n**Summary:**\n\n- OCR configuration: Configured\n- Active locations: 5\n\n[Microsoft Purview portal > Settings > Optical character recognition (OCR)](https://purview.microsoft.com/)\n\n\n","TestStatus":"Failed","TestTags":null},{"TestImplementationCost":"Medium","TestPillar":"Identity","TestCategory":"Access control","SkippedReason":null,"TestImpact":"High","TestAppliesTo":["Identity"],"TestSfiPillar":"Accelerate response and remediation","TestSkipped":"","TestMinimumLicense":"P2","TestTags":["Identity"],"TestTitle":"Restrict access to high risk users","TestRisk":"High","TestResult":"\nPasswordless authentication is enabled, but no policies to block high risk users are configured.\n## Passwordless Authentication Methods allowed in tenant\n\n| Authentication Method Name | State | Additional Info |\n| :------------------------ | :---- | :-------------- |\n| Fido2 | enabled | |\n\n## Conditional Access Policies targeting high risk users\n\nNo conditional access policies targeting high risk users found.\n\n### Inactive policies targeting high risk users (not contributing to security posture):\n\n| Conditional Access Policy Name | Status | Conditions |\n| :--------------------- | :----- | :--------- |\n| [Require password change for high-risk users](https://entra.microsoft.com/#view/Microsoft_AAD_ConditionalAccess/PolicyBlade/policyId/ddbc3bb1-3749-474f-b8c3-0d997118b24b) | Report-only | User Risk Level: High, Control: Block |\n| [Force Password Change](https://entra.microsoft.com/#view/Microsoft_AAD_ConditionalAccess/PolicyBlade/policyId/5848211d-96f2-40ae-92a4-af1aa8f48572) | Disabled | User Risk Level: High, Control: Password Change |\n| [CISA SCuBA.MS.AAD.2.3: Users detected as high risk SHALL be blocked.](https://entra.microsoft.com/#view/Microsoft_AAD_ConditionalAccess/PolicyBlade/policyId/94c7d8d0-5c8c-460d-8ace-364374250893) | Report-only | User Risk Level: High, Control: Block |\n\n\n","TestStatus":"Failed","TestDescription":"Assume high risk users are compromised by threat actors. Without investigation and remediation, threat actors can execute scripts, deploy malicious applications, or manipulate API calls to establish persistence, based on the potentially compromised user's permissions. Threat actors can then exploit misconfigurations or abuse OAuth tokens to move laterally across workloads like documents, SaaS applications, or Azure resources. Threat actors can gain access to sensitive files, customer records, or proprietary code and exfiltrate it to external repositories while maintaining stealth through legitimate cloud services. Finally, threat actors might disrupt operations by modifying configurations, encrypting data for ransom, or using the stolen information for further attacks, resulting in financial, reputational, and regulatory consequences.\n\nOrganizations using passwords can rely on password reset to automatically remediate risky users.\n\nOrganizations using passwordless credentials already mitigate most risk events that accrue to user risk levels, thus the volume of risky users should be considerably lower. Risky users in an organization that uses passwordless credentials must be blocked from access until the user risk is investigated and remediated.\n\n**Remediation action**\n\n- [Deploy a Conditional Access policy to require a secure password change for elevated user risk](https://learn.microsoft.com/entra/identity/conditional-access/policy-risk-based-user?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci).\n- Use Microsoft Entra ID Protection to [investigate risk further](https://learn.microsoft.com/entra/id-protection/howto-identity-protection-investigate-risk?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci).\n","TestId":"21797"},{"TestImplementationCost":"","TestPillar":"Infrastructure","TestCategory":"Secure management ports","SkippedReason":null,"TestImpact":"","TestAppliesTo":null,"TestSfiPillar":"Protect tenants and isolate production systems","TestSkipped":"","TestMinimumLicense":"N/A","TestTags":null,"TestTitle":"Management ports should be closed on your virtual machines","TestRisk":"Medium","TestResult":"Management ports should be closed on your virtual machines\n\n| Subscription | Resource group | Resource type | Affected resource | Status | Azure portal |\n| :----------- | :------------- | :------------ | :---------------- | :----- | :----------- |\n| [Visual Studio Enterprise Subscription](https://portal.azure.com/#resource/subscriptions/54d3ea01-5a07-45d0-8d69-e5f5b0b20098) | indiavm_group | virtualmachines | [india-2](https://portal.azure.com/#resource/subscriptions/54d3ea01-5a07-45d0-8d69-e5f5b0b20098/resourceGroups/INDIAVM_GROUP/providers/Microsoft.Compute/virtualMachines/india-2) | ❌ | [View recommendation](https://portal.azure.com/#blade/Microsoft_Azure_Security/RecommendationsBlade/assessmentKey/bc303248-3d14-44c2-96a0-55f5c326b5fe/resourceId/%2fsubscriptions%2f54d3ea01-5a07-45d0-8d69-e5f5b0b20098%2fresourceGroups%2fINDIAVM_GROUP%2fproviders%2fMicrosoft.Compute%2fvirtualMachines%2findia-2) |\n| [Visual Studio Enterprise Subscription](https://portal.azure.com/#resource/subscriptions/54d3ea01-5a07-45d0-8d69-e5f5b0b20098) | indiavm_group | virtualmachines | [indiavm](https://portal.azure.com/#resource/subscriptions/54d3ea01-5a07-45d0-8d69-e5f5b0b20098/resourceGroups/INDIAVM_GROUP/providers/Microsoft.Compute/virtualMachines/indiavm) | ✅ | [View recommendation](https://portal.azure.com/#blade/Microsoft_Azure_Security/RecommendationsBlade/assessmentKey/bc303248-3d14-44c2-96a0-55f5c326b5fe/resourceId/%2fsubscriptions%2f54d3ea01-5a07-45d0-8d69-e5f5b0b20098%2fresourceGroups%2fINDIAVM_GROUP%2fproviders%2fMicrosoft.Compute%2fvirtualMachines%2findiavm) |\n","TestStatus":"Failed","TestDescription":"Open remote management ports are exposing your VM to a high level of risk from Internet-based attacks. These attacks attempt to brute force credentials to gain admin access to the machine.\n\n**Remediation action**\n\nWe recommend that you edit the inbound rules of some of your virtual machines, to restrict access to specific source ranges.
To restrict access to your virtual machines:
1. Select a VM to restrict access to.
2. In the 'Networking' blade, click on each of the rules that allow management ports (for example, RDP-3389, WINRM-5985, SSH-22).
3. Either change the 'Action' property to 'Deny', or, improve the rule by applying a less permissive range of source IP ranges.
4. Click 'Save'.
Use Defender for Cloud's Just-in-time (JIT) virtual machine (VM) access to lock down inbound traffic to your Azure VMs by demand. Learn more in Understanding just-in-time (JIT) VM access.","TestId":"bc303248-3d14-44c2-96a0-55f5c326b5fe"},{"TestImplementationCost":"Medium","TestPillar":"Identity","TestCategory":"Identity governance","SkippedReason":null,"TestImpact":"Medium","TestAppliesTo":null,"TestSfiPillar":"Protect tenants and isolate production systems","TestSkipped":"","TestMinimumLicense":["P2","Governance"],"TestTags":null,"TestTitle":"All entitlement management policies have an expiration date","TestRisk":"Medium","TestResult":"\n❌ Not all entitlement management policies have expiration dates configured.\n### Entitlement Management Assignment Policies with Expiration Dates\n| Name | Expiration Type | Duration / End DateTime |\n| :--- | :--- | ---: |\n| [test Policy](https://entra.microsoft.com/#view/Microsoft_Azure_ELMAdmin/EntitlementMenuBlade/~/policies/entitlementId//catalogId//catalogName//entitlementName/test%20Policy) | afterDuration | P365D |\n| [All users](https://entra.microsoft.com/#view/Microsoft_Azure_ELMAdmin/EntitlementMenuBlade/~/policies/entitlementId//catalogId//catalogName//entitlementName/All%20users) | afterDateTime | 11/15/2027 12:59:59 |\n| [Initial Policy](https://entra.microsoft.com/#view/Microsoft_Azure_ELMAdmin/EntitlementMenuBlade/~/policies/entitlementId//catalogId//catalogName//entitlementName/Initial%20Policy) | afterDuration | P365D |\n| [Initial Policy](https://entra.microsoft.com/#view/Microsoft_Azure_ELMAdmin/EntitlementMenuBlade/~/policies/entitlementId//catalogId//catalogName//entitlementName/Initial%20Policy) | afterDuration | P365D |\n\n#### Policies missing expiration:\n| Name | Expiration Type | Duration / End DateTime |\n| :--- | :--- | ---: |\n| [21929Test](https://entra.microsoft.com/#view/Microsoft_Azure_ELMAdmin/EntitlementMenuBlade/~/policies/entitlementId//catalogId//catalogName//entitlementName/21929Test) | noExpiration | | |\n| [External](https://entra.microsoft.com/#view/Microsoft_Azure_ELMAdmin/EntitlementMenuBlade/~/policies/entitlementId//catalogId//catalogName//entitlementName/External) | noExpiration | | |\n| [All users](https://entra.microsoft.com/#view/Microsoft_Azure_ELMAdmin/EntitlementMenuBlade/~/policies/entitlementId//catalogId//catalogName//entitlementName/All%20users) | noExpiration | | |\n| [All users](https://entra.microsoft.com/#view/Microsoft_Azure_ELMAdmin/EntitlementMenuBlade/~/policies/entitlementId//catalogId//catalogName//entitlementName/All%20users) | noExpiration | | |\n\n\n","TestStatus":"Failed","TestDescription":"Entitlement management policies without expiration dates create persistent access that threat actors can exploit. When user assignments lack time bounds, compromised credentials maintain indefinite access, enabling attackers to establish persistence, escalate privileges through additional access packages, and conduct long-term malicious activities while remaining undetected. \n\n**Remediation action**\n\n- [Configure expiration settings for access packages](https://learn.microsoft.com/entra/id-governance/entitlement-management-access-package-lifecycle-policy?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci#specify-a-lifecycle)\n","TestId":"21878"},{"TestImplementationCost":"Low","TestPillar":"Identity","TestCategory":"Privileged access","SkippedReason":null,"TestImpact":"Low","TestAppliesTo":null,"TestSfiPillar":"Protect identities and secrets","TestSkipped":"","TestMinimumLicense":"P2","TestTags":null,"TestTitle":"Activation alert for Global Administrator role assignments","TestRisk":"Medium","TestResult":"\nActivation alerts are configured for Global Administrator role.\n\n| Role display name | Default recipients | Additional recipients |\n| :---------------- | :----------------- | :------------------- |\n| [Global Administrator](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/RolesManagementMenuBlade/~/AllRoles) | ✅ Enabled | peyton@contoso.com |\n\n\n","TestStatus":"Passed","TestDescription":"Without activation alerts for Global Administrator role assignments, threat actors can escalate privileges undetected. This lack of visibility creates a blind spot where attackers can activate the most privileged role and perform malicious actions such as creating backdoor accounts, modifying security policies, or accessing sensitive data.\n\nMonitoring these activation alerts can help security teams distinguish between authorized and unauthorized privilege escalation activities. \n\n**Remediation action**\n\n- [Configure notifications for privileged roles](https://learn.microsoft.com/entra/id-governance/privileged-identity-management/pim-how-to-change-default-settings?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci#require-justification-on-active-assignment)\n","TestId":"21819"},{"TestImpact":"Medium","TestRisk":"High","TestSkipped":"","TestAppliesTo":null,"TestPillar":"Data","TestCategory":"Data Loss Prevention (DLP)","TestDescription":"Without Data Loss Prevention (DLP) policies, employees can freely share sensitive information through email, file uploads, or Microsoft Teams communications, increasing the risk of data breaches and regulatory violations.\n\nDLP policies automatically monitor, detect, and prevent the disclosure of sensitive information across Microsoft 365 workloads, providing automated protection against unauthorized data exfiltration.\n\n**Remediation action**\n\n- [Create and configure DLP policies](https://learn.microsoft.com/purview/dlp-create-deploy-policy?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci)\n","TestTitle":"Data loss prevention policies are enabled","SkippedReason":null,"TestId":"35030","TestImplementationCost":"Medium","TestMinimumLicense":["EXCHANGE_S_ENTERPRISE"],"TestSfiPillar":"Protect tenants and production systems","TestResult":"\n✅ One or more DLP policies are enabled and configured, providing automated protection against sensitive data disclosure.\n\n## Data Loss Prevention Policy Summary\n\n**Total DLP Policies:** 7\n\n**Enabled Policies:** 7\n\n### DLP Policies Configuration\n\n| Policy Name | Enabled Status | Created Date | Last Modified Date |\n| :--- | :--- | :--- | :--- |\n| Custom policy | ✅ Yes | 2026-01-09 | 2026-05-13 |\n| Endpoint DLP - Financial Data | ✅ Yes | 2026-01-15 | 2026-02-06 |\n| Adaptive Protection - Elevated Risk | ✅ Yes | 2026-01-30 | 2026-02-06 |\n| Custom policy-2 | ✅ Yes | 2026-02-06 | 2026-02-06 |\n| Browser DLP Test | ✅ Yes | 2026-02-13 | 2026-02-13 |\n| Test - 61001 | ✅ Yes | 2026-05-12 | 2026-05-13 |\n| copilot-61001 | ✅ Yes | 2026-05-13 | 2026-05-13 |\n\n[View DLP Policies in Microsoft Purview Portal](https://purview.microsoft.com/datalossprevention/policies)\n\n\n","TestStatus":"Passed","TestTags":null},{"TestImplementationCost":"Low","TestPillar":"Identity","TestCategory":"Credential management","SkippedReason":null,"TestImpact":"Low","TestAppliesTo":null,"TestSfiPillar":"Protect identities and secrets","TestSkipped":"","TestMinimumLicense":"P1","TestTags":null,"TestTitle":"Smart lockout duration is set to a minimum of 60","TestRisk":"Medium","TestResult":"\nSmart Lockout duration is configured to 60 seconds or higher.\n## Smart Lockout Settings\n\n| Setting | Value |\n| :---- | :---- |\n| [Lockout Duration (seconds)](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/AuthenticationMethodsMenuBlade/~/PasswordProtection/fromNav/) | 60 |\n\n\n","TestStatus":"Passed","TestDescription":"When Smart Lockout duration is configured below the default 60 seconds, threat actors can exploit shortened lockout periods to conduct password spray and credential stuffing attacks more effectively. Reduced lockout windows allow attackers to resume authentication attempts more rapidly, increasing their success probability while potentially evading detection systems that rely on longer observation periods. \n\n**Remediation action**\n\n- [Set Smart Lockout duration to 60 seconds or higher](https://learn.microsoft.com/entra/identity/authentication/howto-password-smart-lockout?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci#manage-microsoft-entra-smart-lockout-values)\n","TestId":"21849"},{"TestImplementationCost":"Low","TestPillar":"Network","TestCategory":"Azure Network Security","SkippedReason":"This test is not applicable to the current environment.","TestImpact":"Low","TestAppliesTo":null,"TestSfiPillar":"Protect networks","TestSkipped":"NotApplicable","TestMinimumLicense":"Azure WAF","TestTags":null,"TestTitle":"JavaScript Challenge is Enabled in Application Gateway WAF","TestRisk":"Medium","TestResult":"\nNo Application Gateway WAF policies found attached to Application Gateways.\n","TestStatus":"Skipped","TestDescription":"Azure Application Gateway Web Application Firewall (WAF) supports JavaScript challenge as a defense mechanism against automated bots and headless browsers. JavaScript challenge works by serving a small JavaScript snippet that must be executed by the client browser to prove that the request originates from a real browser capable of running JavaScript, rather than a simple HTTP client or bot.\n\nWhen a request triggers a JavaScript challenge, the WAF responds with a challenge page containing JavaScript code that the browser must execute to obtain a valid challenge cookie. If the client successfully executes the JavaScript and returns with a valid cookie, subsequent requests proceed normally until the cookie expires. Bots and automated tools that cannot execute JavaScript fail this challenge and are blocked from accessing protected resources. This mechanism is particularly effective against credential stuffing bots, web scrapers, and distributed denial of service bots that use simple HTTP libraries without JavaScript engines.\n\nThe `jsChallengeCookieExpirationInMins` setting controls how long the challenge cookie remains valid before the client must complete another challenge. JavaScript challenge provides a middle ground between allowing all traffic and blocking suspected bots outright—it verifies browser capability without requiring user interaction like CAPTCHA. By configuring custom rules with JavaScript challenge action, organizations can protect sensitive endpoints like login pages, API endpoints, and high-value resources from automated abuse while maintaining a seamless experience for legitimate users.\n\n\n**Remediation action**\n\n- [What is Azure Web Application Firewall on Azure Application Gateway?](https://learn.microsoft.com/en-us/azure/web-application-firewall/ag/ag-overview) - Overview of WAF capabilities on Application Gateway including custom rules and actions\n- [Create and use Web Application Firewall v2 custom rules on Application Gateway](https://learn.microsoft.com/en-us/azure/web-application-firewall/ag/create-custom-waf-rules) - Step-by-step guidance on creating custom rules with different actions including JavaScript challenge\n- [Web Application Firewall custom rules](https://learn.microsoft.com/en-us/azure/web-application-firewall/ag/custom-waf-rules-overview) - Detailed documentation of custom rule types and available actions\n- [Bot protection overview for Application Gateway WAF](https://learn.microsoft.com/en-us/azure/web-application-firewall/ag/bot-protection-overview) - Overview of bot protection capabilities including challenge actions\n\n\n","TestId":27017},{"TestImpact":"Low","TestRisk":"High","TestSkipped":"NoCompatibleLicenseFound","TestAppliesTo":null,"TestPillar":"Network","TestCategory":"Global Secure Access","TestDescription":"The baseline profile applies the same filtering rules to all users and sessions. Conditional Access integration enables identity-aware filtering that adapts based on user risk, device compliance, location, or group membership. Apply stricter filtering to risky sessions while allowing standard access for verified users on compliant devices, preventing compromised accounts from bypassing security controls.\n\n**Remediation action**\n\n- [Link security profiles to Conditional Access policies](https://learn.microsoft.com/entra/global-secure-access/how-to-configure-web-content-filtering?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci#create-and-link-conditional-access-policy)\n","TestTitle":"Web content filtering integrates with Conditional Access","SkippedReason":"This test requires one of the following licenses: (\"Entra_Premium_Internet_Access\"). Please ensure your tenant has the appropriate licenses to run this test. See [Licensing & Service Plans](https://learn.microsoft.com/entra/identity/users/licensing-service-plan-reference)","TestId":"25407","TestImplementationCost":"Medium","TestMinimumLicense":["Entra_Premium_Internet_Access"],"TestSfiPillar":"Protect networks","TestResult":"\nSkipped. This test requires one of the following licenses: (\"Entra_Premium_Internet_Access\"). Please ensure your tenant has the appropriate licenses to run this test. See [Licensing & Service Plans](https://learn.microsoft.com/entra/identity/users/licensing-service-plan-reference)\n\n","TestStatus":"Skipped","TestTags":null},{"TestImplementationCost":"Low","TestPillar":"Devices","TestCategory":"Tenant","SkippedReason":null,"TestImpact":"Low","TestAppliesTo":null,"TestSfiPillar":"Protect tenants and isolate production systems","TestSkipped":"","TestMinimumLicense":"P1","TestTags":null,"TestTitle":"Windows Automatic Enrollment is enabled","TestRisk":"High","TestResult":"\nWindows Automatic Enrollment is enabled.\n\n\n## Windows Automatic Enrollment\n\n| Policy Name | User Scope |\n| :---------- | :--------- |\n| [Microsoft Intune](https://intune.microsoft.com/#view/Microsoft_AAD_IAM/MdmConfiguration.ReactView/appId/0000000a-0000-0000-c000-000000000000/appName/Microsoft%20Intune) | ✅ Specific Groups |\n\n\n\n","TestStatus":"Passed","TestDescription":"If Windows automatic enrollment isn't enabled, unmanaged devices can become an entry point for attackers. Threat actors might use these devices to access corporate data, bypass compliance policies, and introduce vulnerabilities into the environment. Devices joined to Microsoft Entra without Intune enrollment create gaps in visibility and control. These unmanaged endpoints can expose weaknesses in the operating system or misconfigured applications that attackers can exploit.\n\nEnforcing automatic enrollment ensures Windows devices are managed from the start, enabling consistent policy enforcement and visibility into compliance. This supports Zero Trust by ensuring all devices are verified, monitored, and governed by security controls.\n\n**Remediation action**\n\nEnable automatic enrollment for Windows devices using Intune and Microsoft Entra to ensure all domain-joined or Entra-joined devices are managed: \n- [Enable Windows automatic enrollment](https://learn.microsoft.com/intune/intune-service/enrollment/windows-enroll?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci#enable-windows-automatic-enrollment)\n\nFor more information, see: \n- [Deployment guide - Enrollment for Windows](https://learn.microsoft.com/intune/intune-service/fundamentals/deployment-guide-enroll?tabs=work-profile%2Ccorporate-owned-apple%2Cautomatic-enrollment&wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci#enrollment-for-windows)\n","TestId":"24546"},{"TestImplementationCost":"Low","TestPillar":"Identity","TestCategory":"Application management","SkippedReason":null,"TestImpact":"Medium","TestAppliesTo":["Identity"],"TestSfiPillar":"Protect engineering systems","TestSkipped":"","TestMinimumLicense":"P1","TestTags":["Application"],"TestTitle":"Creating new applications and service principles is restricted to privileged users","TestRisk":"Medium","TestResult":"\nTenant is configured to prevent users from registering applications.\n\n**[Users can register applications](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserManagementMenuBlade/~/UserSettings/menuId/UserSettings)** → **No** ✅\n\n","TestStatus":"Passed","TestDescription":"If nonprivileged users can create applications and service principals, these accounts might be misconfigured or be granted more permissions than necessary, creating new vectors for attackers to gain initial access. Attackers can exploit these accounts to establish valid credentials in the environment and bypass some security controls.\n\nIf these nonprivileged accounts are mistakenly granted elevated application owner permissions, attackers can use them to move from a lower level of access to a more privileged level of access. Attackers who compromise nonprivileged accounts might add their own credentials or change the permissions associated with the applications created by the nonprivileged users to ensure they can continue to access the environment undetected.\n\nAttackers can use service principals to blend in with legitimate system processes and activities. Because service principals often perform automated tasks, malicious activities carried out under these accounts might not be flagged as suspicious.\n\n**Remediation action**\n\n- [Block nonprivileged users from creating apps](https://learn.microsoft.com/entra/identity/role-based-access-control/delegate-app-roles?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci)\n","TestId":"21807"},{"TestImplementationCost":"Low","TestPillar":"Network","TestCategory":"Azure Network Security","SkippedReason":"This test is not applicable to the current environment.","TestImpact":"Low","TestAppliesTo":null,"TestSfiPillar":"Protect networks","TestSkipped":"NotApplicable","TestMinimumLicense":"Azure WAF","TestTags":null,"TestTitle":"JavaScript Challenge is Enabled in Azure Front Door WAF","TestRisk":"Medium","TestResult":"\nNo Azure Front Door WAF policies attached to Azure Front Door found.\n","TestStatus":"Skipped","TestDescription":"Azure Front Door Web Application Firewall (WAF) supports JavaScript challenge as a defense mechanism against automated bots and headless browsers across the global edge network. JavaScript challenge works by serving a small JavaScript snippet that must be executed by the client browser to prove that the request originates from a real browser capable of running JavaScript, rather than a simple HTTP client or bot.\n\nWhen a request triggers a JavaScript challenge, the WAF responds with a challenge page containing JavaScript code that the browser must execute to obtain a valid challenge cookie. Bots and automated tools that cannot execute JavaScript fail this challenge and are blocked from accessing protected resources.\n\nThe `javascriptChallengeExpirationInMinutes` setting controls how long the challenge cookie remains valid before the client must complete another challenge. JavaScript challenge provides a middle ground between allowing all traffic and blocking suspected bots outright.\n\nThis check identifies Azure Front Door WAF policies that are attached to an Azure Front Door and verifies that at least one custom rule with JavaScript challenge action is configured and enabled.\n\n**Remediation action**\n\n- [Azure Web Application Firewall on Azure Front Door](https://learn.microsoft.com/en-us/azure/web-application-firewall/afds/afds-overview)\n- [Web Application Firewall custom rules for Azure Front Door](https://learn.microsoft.com/en-us/azure/web-application-firewall/afds/waf-front-door-custom-rules)\n- [Configure JavaScript challenge for Azure Front Door WAF](https://learn.microsoft.com/en-us/azure/web-application-firewall/afds/waf-front-door-tuning#javascript-challenge)\n- [Tutorial: Create a Web Application Firewall policy on Azure Front Door](https://learn.microsoft.com/en-us/azure/web-application-firewall/afds/waf-front-door-create-portal)\n\n","TestId":27019},{"TestImplementationCost":"","TestPillar":"Infrastructure","TestCategory":"Protect applications against DDoS attacks","SkippedReason":"This test is not applicable to the current environment.","TestImpact":"","TestAppliesTo":null,"TestSfiPillar":"Protect tenants and isolate production systems","TestSkipped":"NotApplicable","TestMinimumLicense":"N/A","TestTags":null,"TestTitle":"Azure DDoS Protection Standard should be enabled","TestRisk":"Medium","TestResult":"VnetHasNoAppGateways\n\n| Subscription | Resource group | Resource type | Affected resource | Status | Azure portal |\n| :----------- | :------------- | :------------ | :---------------- | :----- | :----------- |\n| [Visual Studio Enterprise Subscription](https://portal.azure.com/#resource/subscriptions/54d3ea01-5a07-45d0-8d69-e5f5b0b20098) | indiavm_group | virtualnetworks | [indiavm-vnet](https://portal.azure.com/#resource/subscriptions/54d3ea01-5a07-45d0-8d69-e5f5b0b20098/resourceGroups/indiavm_group/providers/Microsoft.Network/virtualNetworks/indiavm-vnet) | N/A | [View recommendation](https://portal.azure.com/#blade/Microsoft_Azure_Security/RecommendationsBlade/assessmentKey/e3de1cc0-f4dd-3b34-e496-8b5381ba2d70/resourceId/%2fsubscriptions%2f54d3ea01-5a07-45d0-8d69-e5f5b0b20098%2fresourceGroups%2findiavm_group%2fproviders%2fMicrosoft.Network%2fvirtualNetworks%2findiavm-vnet) |\n| [Visual Studio Enterprise Subscription](https://portal.azure.com/#resource/subscriptions/54d3ea01-5a07-45d0-8d69-e5f5b0b20098) | charlie | virtualnetworks | [charlie-vnet](https://portal.azure.com/#resource/subscriptions/54d3ea01-5a07-45d0-8d69-e5f5b0b20098/resourceGroups/charlie/providers/Microsoft.Network/virtualNetworks/charlie-vnet) | N/A | [View recommendation](https://portal.azure.com/#blade/Microsoft_Azure_Security/RecommendationsBlade/assessmentKey/e3de1cc0-f4dd-3b34-e496-8b5381ba2d70/resourceId/%2fsubscriptions%2f54d3ea01-5a07-45d0-8d69-e5f5b0b20098%2fresourceGroups%2fcharlie%2fproviders%2fMicrosoft.Network%2fvirtualNetworks%2fcharlie-vnet) |\n","TestStatus":"Skipped","TestDescription":"Defender for Cloud has discovered virtual networks with Application Gateway or Azure Firewall resources that are unprotected by the DDoS protection service. These resources contain public IPs. Enable mitigation of network volumetric and protocol attacks.\n\n**Remediation action**\n\n
1. Select a virtual network to enable the DDoS protection service standard on.
2. Select the Standard option.
3. Click 'Save'.","TestId":"e3de1cc0-f4dd-3b34-e496-8b5381ba2d70"},{"TestImpact":"Low","TestRisk":"Medium","TestSkipped":"NoCompatibleLicenseFound","TestAppliesTo":null,"TestPillar":"Network","TestCategory":"Private Access","TestDescription":"The private network connector is a key component of Microsoft Entra Private Access and Application Proxy. To maintain security, stability, and performance, all connector machines must run the latest software version.\n\nIf your connectors don't run the latest version:\n\n- They might be missing critical security patches, which leaves connectors vulnerable to known exploits.\n- You don't get the latest performance improvements and bug fixes, which can affect reliability.\n- Compatibility problems might arise with the Global Secure Access service as it evolves.\n\n**Remediation action**\n\n- [Configure private network connectors for Microsoft Entra Private Access and Microsoft Entra application proxy](https://learn.microsoft.com/entra/global-secure-access/how-to-configure-connectors?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci).\n- Verify that all your connectors are up to date and install the latest [connector updates](https://learn.microsoft.com/entra/global-secure-access/concept-connectors?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci#connector-updates).\n","TestTitle":"Private network connectors are running the latest version","SkippedReason":"This test requires one of the following licenses: (\"Entra_Premium_Private_Access\"). Please ensure your tenant has the appropriate licenses to run this test. See [Licensing & Service Plans](https://learn.microsoft.com/entra/identity/users/licensing-service-plan-reference)","TestId":"25392","TestImplementationCost":"Low","TestMinimumLicense":["Entra_Premium_Private_Access"],"TestSfiPillar":"Protect networks","TestResult":"\nSkipped. This test requires one of the following licenses: (\"Entra_Premium_Private_Access\"). Please ensure your tenant has the appropriate licenses to run this test. See [Licensing & Service Plans](https://learn.microsoft.com/entra/identity/users/licensing-service-plan-reference)\n\n","TestStatus":"Skipped","TestTags":null},{"TestImplementationCost":"Medium","TestPillar":"Identity","TestCategory":"Application management","SkippedReason":null,"TestImpact":"Low","TestAppliesTo":null,"TestSfiPillar":"Protect engineering systems","TestSkipped":"","TestMinimumLicense":"Free","TestTags":null,"TestTitle":"Enterprise applications have owners","TestRisk":"Medium","TestResult":"\nNot all enterprise applications have at least two owners.\n\n## Enterprise Application Ownership\n\n| App name | Multi-tenant | Permission | Classification | Owner count |\n| :-------- | :------------ | :---------- | :------------- | :----------- |\n| [Microsoft Assessment React](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/Overview/objectId/0a8b4459-b0c2-4cb8-baeb-c4c5a6a8f14b/appId/c4b110d7-6f1d-473d-aa9e-6e74b8b8bd4b) | False | offline_access, openid, profile, User.Read | Low | 0 |\n| [idPowerToys - CI](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/Overview/objectId/043dd83b-94ce-4d12-b54b-45d77979f05a/appId/0b75bb7b-d365-4c29-92ea-e2799d2a3fce) | False | offline_access, openid, profile, User.Read | Low | 0 |\n| [idPowerToys](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/Overview/objectId/30aa6cd2-1aab-42fd-a235-0521713f4532/appId/afe793df-19e0-455a-8403-2e863379bfaa) | False | offline_access, openid, profile, User.Read | Low | 0 |\n| [Canva](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/Overview/objectId/37ae3acb-5850-49e8-a0f8-cb06f5a77417/appId/2c0bebe0-bdb3-4909-8955-7ef311f0db22) | False | email, openid, profile, User.Read | Low | 0 |\n| [EAM Demo](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/Overview/objectId/24b12ae7-4648-4aae-b00c-6349a565d24c/appId/e6e0be31-7040-4084-ac44-600b67661f2c) | True | openid, profile | Low | 0 |\n| [Azure Static Web Apps](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/Overview/objectId/6b1f4a00-db4e-43ae-b62b-2286d4fcc4ea/appId/d414ee2d-73e5-4e5b-bb16-03ef55fea597) | False | email, openid, profile | Low | 0 |\n| [FIDO2-passkeys-MFA](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/Overview/objectId/1aa7e155-cbf8-4970-8458-05a0c7a2d1a5/appId/4fabcfc0-5c44-45a1-8c80-8537f0625949) | True | openid, profile | Low | 0 |\n| [Opticom](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/Overview/objectId/3f142d86-14ba-4173-9458-be7fb36b37f7/appId/dd939d5a-d248-4f58-a25f-26a6b3f5183e) | False | email, openid, profile, User.Read | Low | 0 |\n| [AWS Account](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/Overview/objectId/77198970-f1eb-4574-9a1a-6af175a283af/appId/2e311a1d-f5c0-41c6-b866-77af3289871e) | True | offline_access, openid, profile, User.Read | Low | 0 |\n| [graph-developer-proxy-samples](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/Overview/objectId/e6570bb8-fdea-4329-82e2-2809d8fb67a7/appId/3658d9e9-dc87-4345-b59b-184febcf6781) | True | Presence.Read.All, User.Read.All | Low | 0 |\n| [idpowerelectron](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/Overview/objectId/cb64f850-a076-42d5-8dd8-cfd67d9e67f1/appId/909fff82-5b0a-4ce5-b66d-db58ee1a925d) | True | offline_access, openid, profile | Low | 0 |\n| [Atlassian - Jira](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/Overview/objectId/2425e515-5720-4071-9fae-fd50f153c0aa/appId/b0e53e94-b4b0-4632-98ae-e230af1f511c) | False | User.Read | Low | 0 |\n| [Entry Kiosk](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/Overview/objectId/83adcc80-3a35-4fdc-9c5b-1f6b9061508e/appId/b903f17a-87b0-460b-9978-962c812e4f98) | False | User.Read | Low | 0 |\n| [SharePoint On-Prem App Proxy](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/Overview/objectId/53c7bdb1-cae2-43b0-9e2e-d8605395ceec/appId/19a70df3-cddf-48c7-be44-97b25b9857f1) | False | User.Read | Low | 0 |\n| [WebApplication4](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/Overview/objectId/5bc56e47-7a8a-4e71-b25f-8c4e373f40a6/appId/b2d1f868-27ee-4ecd-ae81-0ee96b028605) | False | User.Read | Low | 0 |\n| [MyTokenTestApp](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/Overview/objectId/60923f18-748f-42bb-a0b2-ee60d44e17fc/appId/6a846cb7-35ad-41b2-b10a-0c5decde9855) | False | openid, profile | Low | 1 |\n| [Microsoft Graph PowerShell - Used by Team Incredibles](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/Overview/objectId/e67821d9-a20b-43ef-9c34-76a321643b4f/appId/2935f660-810c-41ff-b9ad-168cc649e36f) | False | offline_access, openid, profile, User.Read | Low | 0 |\n| [CachingSampleApp](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/Overview/objectId/59187561-8df5-4792-b3a4-f6ca8b54bfc7/appId/3d6835ff-f7f4-4a83-adb5-67ccdd934717) | False | offline_access, openid, profile, User.Read | Low | 0 |\n| [Demo](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/Overview/objectId/552daa69-8057-4684-8c93-2c41963aff01/appId/f864cc86-0f4f-4861-9583-2580817e4f88) | False | openid, profile | Low | 0 |\n| [Lokka-2-interactive](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/Overview/objectId/794b2542-39aa-433c-90c6-6ab5df851ffc/appId/e6ea9510-0e81-465a-ae7b-efaff41bd719) | False | User.Read, User.Read.All | Low | 0 |\n| [Contoso Access Verifier](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/Overview/objectId/41d3b041-9859-4830-8feb-72ffd7afad65/appId/a6af3433-bc44-4d27-9b35-81d10fd51315) | False | openid, profile, User.Read | Low | 0 |\n| [ASPNET-Tutorial](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/Overview/objectId/6e2f1852-1b3c-4516-a078-551846b5cf49/appId/059da61d-d02e-40ee-8140-6842d5819f18) | False | User.Read | Low | 0 |\n| [PowerShell Gallery ](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/Overview/objectId/a07b4145-250d-4a58-98eb-ab57e7e77d53/appId/d53deec6-b5c5-4953-8d80-73d001fd31e5) | False | email, openid, profile | Low | 0 |\n| [Manson Nov 13 Test](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/Overview/objectId/e515f788-f41c-4c34-aeaa-fded2cc006ed/appId/d65bd82c-b625-48cd-b485-f61939b48727) | False | AgentIdUser.ReadWrite.IdentityParentedBy, User.Read | Low | 0 |\n| [Manson-Test-Nov13](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/Overview/objectId/4499f84e-928d-44c7-a288-51fc4c4374e0/appId/516489b4-b179-4230-b149-440b5c78a7cc) | False | AgentIdUser.ReadWrite.IdentityParentedBy, User.Read | Low | 0 |\n| [Agent Identity Blueprint Example 3792929](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/Overview/objectId/a746a0f2-205f-49fb-ab32-b17b7ccf8cb8/appId/60253969-9e44-4e0b-85c0-abda1041272c) | False | AgentIdUser.ReadWrite.IdentityParentedBy, User.Read | Low | 0 |\n| [MyVscode](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/Overview/objectId/dfc83a5d-36e5-4506-ae9d-6ad5bb403377/appId/92abdce1-3952-4a8b-8720-e59257edd421) | False | MCP.AccessReview.Read.All, MCP.AdministrativeUnit.Read.All, MCP.Application.Read.All, MCP.AuditLog.Read.All, MCP.AuthenticationContext.Read.All, MCP.Device.Read.All, MCP.DirectoryRecommendations.Read.All, MCP.Domain.Read.All, MCP.EntitlementManagement.Read.All, MCP.GroupMember.Read.All, MCP.HealthMonitoringAlert.Read.All, MCP.IdentityRiskEvent.Read.All, MCP.IdentityRiskyServicePrincipal.Read.All, MCP.IdentityRiskyUser.Read.All, MCP.LicenseAssignment.Read.All, MCP.LifecycleWorkflows-CustomExt.Read.All, MCP.LifecycleWorkflows-Reports.Read.All, MCP.LifecycleWorkflows-Workflow.Read.All, MCP.LifecycleWorkflows-Workflow.ReadBasic.All, MCP.LifecycleWorkflows.Read.All, MCP.NetworkAccess-Reports.Read.All, MCP.NetworkAccess.Read.All, MCP.Organization.Read.All, MCP.Policy.Read.All, MCP.Policy.Read.ConditionalAccess, MCP.ProvisioningLog.Read.All, MCP.Reports.Read.All, MCP.RoleAssignmentSchedule.Read.Directory, MCP.RoleEligibilitySchedule.Read.Directory, MCP.RoleManagement.Read.Directory, MCP.Synchronization.Read.All, MCP.User.Read.All, MCP.UserAuthenticationMethod.Read.All | Unranked | 0 |\n| [MansonTestNov24](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/Overview/objectId/8eb7566e-6766-407d-b02e-562bce27c389/appId/d4407e7a-9644-4e25-8df5-6e6da95a9013) | False | AgentIdUser.ReadWrite.IdentityParentedBy, User.Read | Low | 0 |\n| [Manson Test Agent](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/Overview/objectId/4a371380-42bf-44df-9aab-0485be48bbef/appId/e6e0e568-682d-4640-a038-2f2489b1d2aa) | False | AgentIdUser.ReadWrite.IdentityParentedBy, User.Read | Low | 0 |\n| [Agent Identity Blueprint Example 4208710](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/Overview/objectId/7c8d289b-aa63-497f-a4bf-6f98d2323e7c/appId/e79effd2-67cf-4caa-8879-b87389f47819) | False | AgentIdUser.ReadWrite.IdentityParentedBy, User.Read | Low | 0 |\n| [Chopin Agent](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/Overview/objectId/09ac3973-23bc-4ea8-abbb-ce4ed641f39e/appId/7dcdc7c5-09a6-435f-9460-9382d32b7bc6) | False | AgentIdUser.ReadWrite.IdentityParentedBy, User.Read | Low | 0 |\n| [AADInternals OSINT](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/Overview/objectId/8aa2d89a-65ce-4b30-87a6-7c0aae6a55da/appId/08449b24-4aa6-4049-93ef-0c17b87c8d98) | True | openid, profile | Low | 0 |\n| [Agent0 API](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/Overview/objectId/8b627fed-f28e-4749-b5ca-05fa9be291a0/appId/a8a4a52c-9f15-4e2a-a8fe-c267cc3a6101) | False | User.Read | Low | 0 |\n| [agent0-blueprint](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/Overview/objectId/6d92662d-d10d-4a03-8c77-4f904ce22c44/appId/00b6bee4-a638-4260-9382-09301b3a1db9) | False | AgentIdentity.CreateAsManager, User.Read | Low | 0 |\n| [Agent Identity Blueprint Example 12612901](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/Overview/objectId/fe22156d-6b3b-45e4-867a-646e08707dcf/appId/ef1e370e-626b-4839-9340-83e62875489a) | False | AgentIdentity.CreateAsManager, User.Read | Low | 0 |\n| [Message Center](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/Overview/objectId/158f6ef9-a65d-45f2-bdf0-b0a1db70ebd4/appId/83f76a08-fa60-48e6-9cb5-fd8ced5ae314) | False | ServiceMessage.Read.All, User.Read | Low | 0 |\n| [MessageCenterAccount github.com/manson/mc DO NOT DELETE](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/Overview/objectId/427b14ca-13b3-4911-b67e-9ff626614781/appId/778fad36-e4c1-4d40-a58e-9b5b64179d41) | False | ServiceMessage.Read.All | Unranked | 0 |\n| [MyTestMcPClient](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/Overview/objectId/84fbf039-0d23-41d0-b58b-f7a7b76a0486/appId/b6e43d0e-e33f-4223-bae4-144e5974ec3b) | False | MCP.AccessReview.Read.All, MCP.AdministrativeUnit.Read.All, MCP.Application.Read.All, MCP.AuditLog.Read.All, MCP.AuthenticationContext.Read.All, MCP.Device.Read.All, MCP.DirectoryRecommendations.Read.All, MCP.Domain.Read.All, MCP.EntitlementManagement.Read.All, MCP.GroupMember.Read.All, MCP.HealthMonitoringAlert.Read.All, MCP.IdentityRiskEvent.Read.All, MCP.IdentityRiskyServicePrincipal.Read.All, MCP.IdentityRiskyUser.Read.All, MCP.LicenseAssignment.Read.All, MCP.LifecycleWorkflows-CustomExt.Read.All, MCP.LifecycleWorkflows-Reports.Read.All, MCP.LifecycleWorkflows-Workflow.Read.All, MCP.LifecycleWorkflows-Workflow.ReadBasic.All, MCP.LifecycleWorkflows.Read.All, MCP.NetworkAccess-Reports.Read.All, MCP.NetworkAccess.Read.All, MCP.Organization.Read.All, MCP.Policy.Read.All, MCP.Policy.Read.ConditionalAccess, MCP.ProvisioningLog.Read.All, MCP.Reports.Read.All, MCP.RoleAssignmentSchedule.Read.Directory, MCP.RoleEligibilitySchedule.Read.Directory, MCP.RoleManagement.Read.Directory, MCP.Synchronization.Read.All, MCP.User.Read.All, MCP.UserAuthenticationMethod.Read.All | Unranked | 0 |\n| [TestMcPClient](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/Overview/objectId/cf30c6da-890f-4e66-b353-06adbae9933f/appId/55c372a3-9a33-42bb-ac50-7f49224fee47) | False | MCP.AccessReview.Read.All, MCP.AdministrativeUnit.Read.All, MCP.Application.Read.All, MCP.AuditLog.Read.All, MCP.AuthenticationContext.Read.All, MCP.Device.Read.All, MCP.DirectoryRecommendations.Read.All, MCP.Domain.Read.All, MCP.EntitlementManagement.Read.All, MCP.GroupMember.Read.All, MCP.HealthMonitoringAlert.Read.All, MCP.IdentityRiskEvent.Read.All, MCP.IdentityRiskyServicePrincipal.Read.All, MCP.IdentityRiskyUser.Read.All, MCP.LicenseAssignment.Read.All, MCP.LifecycleWorkflows-CustomExt.Read.All, MCP.LifecycleWorkflows-Reports.Read.All, MCP.LifecycleWorkflows-Workflow.Read.All, MCP.LifecycleWorkflows-Workflow.ReadBasic.All, MCP.LifecycleWorkflows.Read.All, MCP.NetworkAccess-Reports.Read.All, MCP.NetworkAccess.Read.All, MCP.Organization.Read.All, MCP.Policy.Read.All, MCP.Policy.Read.ConditionalAccess, MCP.ProvisioningLog.Read.All, MCP.Reports.Read.All, MCP.RoleAssignmentSchedule.Read.Directory, MCP.RoleEligibilitySchedule.Read.Directory, MCP.RoleManagement.Read.Directory, MCP.Synchronization.Read.All, MCP.User.Read.All, MCP.UserAuthenticationMethod.Read.All | Unranked | 0 |\n| [Calendar Pro](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/Overview/objectId/36e156e4-4566-44a0-b05c-a112017086b5/appId/fb507a6d-2eaa-4f1f-b43a-140f388c4445) | False | email, offline_access, openid, profile, User.Read, User.ReadBasic.All | Low | 0 |\n| [MyVisualStudioMcpClient](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/Overview/objectId/cae606b7-4a44-4d07-a7a5-a6fb285e41f1/appId/84ad8697-445d-4b26-affd-1b1459e97aae) | False | MCP.AccessReview.Read.All, MCP.AdministrativeUnit.Read.All, MCP.Application.Read.All, MCP.AuditLog.Read.All, MCP.AuthenticationContext.Read.All, MCP.Device.Read.All, MCP.DirectoryRecommendations.Read.All, MCP.Domain.Read.All, MCP.EntitlementManagement.Read.All, MCP.GroupMember.Read.All, MCP.HealthMonitoringAlert.Read.All, MCP.IdentityRiskEvent.Read.All, MCP.IdentityRiskyServicePrincipal.Read.All, MCP.IdentityRiskyUser.Read.All, MCP.LicenseAssignment.Read.All, MCP.LifecycleWorkflows-CustomExt.Read.All, MCP.LifecycleWorkflows-Reports.Read.All, MCP.LifecycleWorkflows-Workflow.Read.All, MCP.LifecycleWorkflows-Workflow.ReadBasic.All, MCP.LifecycleWorkflows.Read.All, MCP.NetworkAccess-Reports.Read.All, MCP.NetworkAccess.Read.All, MCP.Organization.Read.All, MCP.Policy.Read.All, MCP.Policy.Read.ConditionalAccess, MCP.ProvisioningLog.Read.All, MCP.Reports.Read.All, MCP.RoleAssignmentSchedule.Read.Directory, MCP.RoleEligibilitySchedule.Read.Directory, MCP.RoleManagement.Read.Directory, MCP.Synchronization.Read.All, MCP.User.Read.All, MCP.UserAuthenticationMethod.Read.All | Unranked | 0 |\n| [Thunderbird](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/Overview/objectId/f0b3210a-52eb-4beb-a386-01a0a28aadff/appId/9e5f94bc-e8a4-4e73-b8be-63364c29d753) | False | IMAP.AccessAsUser.All, offline_access, POP.AccessAsUser.All, SMTP.Send | Low | 0 |\n| [WPNinja1](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/Overview/objectId/8b75d9d0-1b26-4143-98d0-e87df8b835b1/appId/eee88dc1-4aab-42b3-b089-4a2cbb19b048) | False | AgentIdentity.CreateAsManager, User.Read | Low | 0 |\n| [custommcp](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/Overview/objectId/fba0c411-7019-4c32-bec4-2f281824b698/appId/aca7e359-22cf-4d86-9338-6d6051245755) | False | MCP.AccessReview.Read.All, MCP.AdministrativeUnit.Read.All, MCP.Application.Read.All, MCP.AuditLog.Read.All, MCP.AuthenticationContext.Read.All, MCP.Device.Read.All, MCP.DirectoryRecommendations.Read.All, MCP.Domain.Read.All, MCP.EntitlementManagement.Read.All, MCP.GroupMember.Read.All, MCP.HealthMonitoringAlert.Read.All, MCP.IdentityRiskEvent.Read.All, MCP.IdentityRiskyServicePrincipal.Read.All, MCP.IdentityRiskyUser.Read.All, MCP.LicenseAssignment.Read.All, MCP.LifecycleWorkflows-CustomExt.Read.All, MCP.LifecycleWorkflows-Reports.Read.All, MCP.LifecycleWorkflows-Workflow.Read.All, MCP.LifecycleWorkflows-Workflow.ReadBasic.All, MCP.LifecycleWorkflows.Read.All, MCP.NetworkAccess-Reports.Read.All, MCP.NetworkAccess.Read.All, MCP.Organization.Read.All, MCP.Policy.Read.All, MCP.Policy.Read.ConditionalAccess, MCP.ProvisioningLog.Read.All, MCP.Reports.Read.All, MCP.RoleAssignmentSchedule.Read.Directory, MCP.RoleEligibilitySchedule.Read.Directory, MCP.RoleManagement.Read.Directory, MCP.Synchronization.Read.All, MCP.UserAuthenticationMethod.Read.All | Unranked | 0 |\n| [M365 MCP Client for Claude](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/Overview/objectId/73f345ba-56fb-4d92-b2f6-2fe168131092/appId/08ad6f98-a4f8-4635-bb8d-f1a3044760f0) | True | MCP.AdministrativeUnit.Read.All, MCP.Application.Read.All, MCP.AuditLog.Read.All, MCP.AuthenticationContext.Read.All, MCP.Device.Read.All, MCP.DirectoryRecommendations.Read.All, MCP.Domain.Read.All, MCP.EntitlementManagement.Read.All, MCP.GroupMember.Read.All, MCP.HealthMonitoringAlert.Read.All, MCP.IdentityRiskEvent.Read.All, MCP.IdentityRiskyServicePrincipal.Read.All, MCP.IdentityRiskyUser.Read.All, MCP.LicenseAssignment.Read.All, MCP.LifecycleWorkflows-CustomExt.Read.All, MCP.LifecycleWorkflows-Reports.Read.All, MCP.LifecycleWorkflows-Workflow.Read.All, MCP.LifecycleWorkflows-Workflow.ReadBasic.All, MCP.LifecycleWorkflows.Read.All, MCP.NetworkAccess-Reports.Read.All, MCP.NetworkAccess.Read.All, MCP.Organization.Read.All, MCP.Policy.Read.All, MCP.Policy.Read.ConditionalAccess, MCP.ProvisioningLog.Read.All, MCP.Reports.Read.All, MCP.RoleAssignmentSchedule.Read.Directory, MCP.RoleEligibilitySchedule.Read.Directory, MCP.RoleManagement.Read.Directory, MCP.Synchronization.Read.All, MCP.User.Read.All, MCP.UserAuthenticationMethod.Read.All | Unranked | 0 |\n| [ChatGPT](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/Overview/objectId/ede526ec-83dd-4e66-8ed0-98e05dca5454/appId/e0476654-c1d5-430b-ab80-70cbd947616a) | False | MCP.AccessReview.Read.All, MCP.AdministrativeUnit.Read.All, MCP.Application.Read.All, MCP.AuditLog.Read.All, MCP.AuthenticationContext.Read.All, MCP.Device.Read.All, MCP.DirectoryRecommendations.Read.All, MCP.Domain.Read.All, MCP.EntitlementManagement.Read.All, MCP.GroupMember.Read.All, MCP.HealthMonitoringAlert.Read.All, MCP.IdentityRiskEvent.Read.All, MCP.IdentityRiskyServicePrincipal.Read.All, MCP.IdentityRiskyUser.Read.All, MCP.LicenseAssignment.Read.All, MCP.LifecycleWorkflows-CustomExt.Read.All, MCP.LifecycleWorkflows-Reports.Read.All, MCP.LifecycleWorkflows-Workflow.Read.All, MCP.LifecycleWorkflows-Workflow.ReadBasic.All, MCP.LifecycleWorkflows.Read.All, MCP.NetworkAccess-Reports.Read.All, MCP.NetworkAccess.Read.All, MCP.Organization.Read.All, MCP.Policy.Read.All, MCP.Policy.Read.ConditionalAccess, MCP.ProvisioningLog.Read.All, MCP.Reports.Read.All, MCP.RoleAssignmentSchedule.Read.Directory, MCP.RoleEligibilitySchedule.Read.Directory, MCP.RoleManagement.Read.Directory, MCP.Synchronization.Read.All, MCP.User.Read.All, MCP.UserAuthenticationMethod.Read.All | Unranked | 0 |\n\n\n","TestStatus":"Failed","TestDescription":"Enterprise applications without owners become orphaned assets that threat actors can exploit. These applications often retain elevated permissions and access to sensitive resources while lacking proper oversight and security governance.\n\nApplications without owners create blind spots in security monitoring where attackers can establish persistence by leveraging existing application permissions to access data or create backdoor accounts. The absence of ownership also prevents proper access reviews and permission audits, allowing applications with excessive permissions or outdated configurations to remain unmanaged.\n\nAssigning owners enables effective application lifecycle management and ensures proper security oversight. \n\n**Remediation action**\n\n- [Assign enterprise application owners](https://learn.microsoft.com/entra/identity/enterprise-apps/assign-app-owners?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci)\n","TestId":"24518"},{"TestImpact":"Low","TestRisk":"High","TestSkipped":"","TestAppliesTo":null,"TestPillar":"Data","TestCategory":"sensitivity-labels","TestDescription":"Sensitivity labels are the foundation of Microsoft Purview Information Protection. They enable organizations to classify and protect sensitive data across Microsoft 365, on-premises locations, and non-Microsoft applications.\n\nWithout sensitivity labels, organizations lack a standardized way to protect their data, leaving it vulnerable to unauthorized access and sharing. A well-designed label taxonomy typically includes 3-7 top-level labels—too many labels overwhelm users and reduce effectiveness.\n\n**Remediation action**\n\n- [Get started with sensitivity labels](https://learn.microsoft.com/purview/get-started-with-sensitivity-labels?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci)\n- [Create and configure sensitivity labels and their policies](https://learn.microsoft.com/purview/create-sensitivity-labels?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci)\n","TestTitle":"Total Sensitivity Labels Configured","SkippedReason":null,"TestId":"35003","TestImplementationCost":"Medium","TestMinimumLicense":["RMS_S_PREMIUM"],"TestSfiPillar":"Protect tenants and production systems","TestResult":"\n✅ At least one sensitivity label is configured in the tenant.\n\n### Sensitivity Label Configuration Summary\n\n**Label Statistics:**\n* Total Label Count: 9\n* Top-Level Labels Count: 9\n* Sub-Labels Count: 0\n\n**Sample Labels** (up to 5):\n| Label Name | Priority | Parent Label |\n|:---|:---|:---|\n| alex-test-label-1-display | 0 | None |\n| 35010Test | 1 | None |\n| Confidential – RMS | 2 | None |\n| peyton | 3 | None |\n| test-35012-1 | 4 | None |\n\n[Manage Sensitivity Labels in Microsoft Purview](https://purview.microsoft.com/informationprotection/informationprotectionlabels/sensitivitylabels)\n\n\n","TestStatus":"Passed","TestTags":null},{"TestImplementationCost":"Medium","TestPillar":"Identity","TestCategory":"Application management","SkippedReason":null,"TestImpact":"Medium","TestAppliesTo":["Identity"],"TestSfiPillar":"Protect tenants and isolate production systems","TestSkipped":"","TestMinimumLicense":"Free","TestTags":["Identity"],"TestTitle":"All guests have a sponsor","TestRisk":"Medium","TestResult":"\n✅ All guest accounts in the tenant have an assigned sponsor.\n\n","TestStatus":"Passed","TestDescription":"Inviting external guests is beneficial for organizational collaboration. However, in the absence of an assigned internal sponsor for each guest, these accounts might persist within the directory without clear accountability. This oversight creates a risk: threat actors could potentially compromise an unused or unmonitored guest account, and then establish an initial foothold within the tenant. Once granted access as an apparent \"legitimate\" user, an attacker might explore accessible resources and attempt privilege escalation, which could ultimately expose sensitive information or critical systems. An unmonitored guest account might therefore become the vector for unauthorized data access or a significant security breach. A typical attack sequence might use the following pattern, all achieved under the guise of a standard external collaborator:\n\n1. Initial access gained through compromised guest credentials\n1. Persistence due to a lack of oversight.\n1. Further escalation or lateral movement if the guest account possesses group memberships or elevated permissions.\n1. Execution of malicious objectives. \n\nMandating that every guest account is assigned to a sponsor directly mitigates this risk. Such a requirement ensures that each external user is linked to a responsible internal party who is expected to regularly monitor and attest to the guest's ongoing need for access. The sponsor feature within Microsoft Entra ID supports accountability by tracking the inviter and preventing the proliferation of \"orphaned\" guest accounts. When a sponsor manages the guest account lifecycle, such as removing access when collaboration concludes, the opportunity for threat actors to exploit neglected accounts is substantially reduced. This best practice is consistent with Microsoft’s guidance to require sponsorship for business guests as part of an effective guest access governance strategy. It strikes a balance between enabling collaboration and enforcing security, as it guarantees that each guest user's presence and permissions remain under ongoing internal oversight.\n\n**Remediation action**\n- For each guest user that has no sponsor, assign a sponsor in Microsoft Entra ID.\n - [Add a sponsor to a guest user in the Microsoft Entra admin center](https://learn.microsoft.com/entra/external-id/b2b-sponsors?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci)\n - [Add a sponsor to a guest user using Microsoft Graph](https://learn.microsoft.com/graph/api/user-post-sponsors?view=graph-rest-1.0&preserve-view=true&wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci)\n","TestId":"21877"},{"TestImplementationCost":"Low","TestPillar":"Identity","TestCategory":"Access control","SkippedReason":"UnderConstruction","TestImpact":"Medium","TestAppliesTo":["Identity"],"TestSfiPillar":"Protect identities and secrets","TestSkipped":"UnderConstruction","TestMinimumLicense":null,"TestTags":["Identity"],"TestTitle":"Require password reset notifications for user roles","TestRisk":"Medium","TestResult":"\nPlanned for future release.\n","TestStatus":"Planned","TestDescription":"...\n\n**Remediation action**\n\n","TestId":"21890"},{"TestImplementationCost":"Low","TestPillar":"Identity","TestCategory":"Access control","SkippedReason":"UnderConstruction","TestImpact":"Low","TestAppliesTo":["Identity"],"TestSfiPillar":"Protect identities and secrets","TestSkipped":"UnderConstruction","TestMinimumLicense":null,"TestTags":["Identity"],"TestTitle":"Azure resources used by Microsoft Entra only allow access from privileged roles","TestRisk":"High","TestResult":"\nPlanned for future release.\n","TestStatus":"Planned","TestDescription":"...\n\n**Remediation action**\n\n","TestId":"21912"},{"TestImplementationCost":"Low","TestPillar":"Identity","TestCategory":"Access control","SkippedReason":null,"TestImpact":"Medium","TestAppliesTo":["Identity"],"TestSfiPillar":"Protect identities and secrets","TestSkipped":"","TestMinimumLicense":"P1","TestTags":["Identity"],"TestTitle":"Require multifactor authentication for device join and device registration using user action","TestRisk":"High","TestResult":"\n**Properly configured Conditional Access policies found** that require MFA for device registration/join actions.\n## Device Settings Configuration\n\n| Setting | Value | Recommended Value | Status |\n| :------ | :---- | :---------------- | :----- |\n| Require Multi-Factor Authentication to register or join devices | No | No | ✅ Correctly configured |\n\n## Device Registration/Join Conditional Access Policies\n\n| Policy Name | State | Requires MFA | Status |\n| :---------- | :---- | :----------- | :----- |\n| [testdevicereg21872](https://entra.microsoft.com/#view/Microsoft_AAD_ConditionalAccess/PolicyBlade/policyId/620a9c5c-09c4-4558-a0fe-7fc8b3540992) | enabled | Yes | ✅ Properly configured |\n\n\n","TestStatus":"Passed","TestDescription":"Threat actors can exploit the lack of multifactor authentication during new device registration. Once authenticated, they can register rogue devices, establish persistence, and circumvent security controls tied to trusted endpoints. This foothold enables attackers to exfiltrate sensitive data, deploy malicious applications, or move laterally, depending on the permissions of the accounts being used by the attacker. Without MFA enforcement, risk escalates as adversaries can continuously reauthenticate, evade detection, and execute objectives.\n\n**Remediation action**\n\n- [Deploy a Conditional Access policy to require multifactor authentication for device registration](https://learn.microsoft.com/entra/identity/conditional-access/policy-all-users-device-registration?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci).\n","TestId":"21872"},{"TestImplementationCost":"Low","TestPillar":"Identity","TestCategory":"External collaboration","SkippedReason":null,"TestImpact":"Medium","TestAppliesTo":["Identity"],"TestSfiPillar":"Protect tenants and isolate production systems","TestSkipped":"","TestMinimumLicense":"Free","TestTags":["Application"],"TestTitle":"Guests have restricted access to directory objects","TestRisk":"Medium","TestResult":"\n✅ Validated guest user access is restricted.\n\n","TestStatus":"Passed","TestDescription":"External user accounts are often used to provide access to business partners who belong to organizations that have a business relationship with your enterprise. If these accounts are compromised in their organization, attackers can use the valid credentials to gain initial access to your environment, often bypassing traditional defenses due to their legitimacy. \n\nExternal accounts with permissions to read directory object permissions provide attackers with broader initial access if compromised. These accounts allow attackers to gather additional information from the directory for reconnaissance.\n\n**Remediation action**\n\n- [Restrict guest access to their own directory objects](https://learn.microsoft.com/entra/external-id/external-collaboration-settings-configure?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci#to-configure-guest-user-access)\n","TestId":"21792"},{"TestImplementationCost":"Low","TestPillar":"Identity","TestCategory":"Application management","SkippedReason":null,"TestImpact":"Low","TestAppliesTo":["Identity"],"TestSfiPillar":"Protect identities and secrets","TestSkipped":"","TestMinimumLicense":"Free","TestTags":["Identity"],"TestTitle":"Admin consent workflow is enabled","TestRisk":"High","TestResult":"\nAdmin consent workflow is disabled.\n\nThe adminConsentRequestPolicy.isEnabled property is set to false.\n\n","TestStatus":"Failed","TestDescription":"Enabling the Admin consent workflow in a Microsoft Entra tenant is a vital security measure that mitigates risks associated with unauthorized application access and privilege escalation. This check is important because it ensures that any application requesting elevated permission undergoes a review process by designated administrators before consent is granted. The admin consent workflow in Microsoft Entra ID notifies reviewers who evaluate and approve or deny consent requests based on the application's legitimacy and necessity. If this check doesn't pass, meaning the workflow is disabled, any application can request and potentially receive elevated permissions without administrative review. This poses a substantial security risk, as malicious actors could exploit this lack of oversight to gain unauthorized access to sensitive data, perform privilege escalation, or execute other malicious activities.\n\n**Remediation action**\n\nFor admin consent requests, set the **Users can request admin consent to apps they are unable to consent to** setting to **Yes**. Specify other settings, such as who can review requests.\n\n- [Enable the admin consent workflow](https://learn.microsoft.com/entra/identity/enterprise-apps/configure-admin-consent-workflow?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci#enable-the-admin-consent-workflow)\n- Or use the [Update adminConsentRequestPolicy](https://learn.microsoft.com/graph/api/adminconsentrequestpolicy-update?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci) API to set the `isEnabled` property to true and other settings\n","TestId":"21809"},{"TestImplementationCost":"","TestPillar":"Infrastructure","TestCategory":"Restrict unauthorized network access","SkippedReason":null,"TestImpact":"","TestAppliesTo":null,"TestSfiPillar":"Protect tenants and isolate production systems","TestSkipped":"","TestMinimumLicense":"N/A","TestTags":null,"TestTitle":"All network ports should be restricted on network security groups associated to your virtual machine","TestRisk":"High","TestResult":"All network ports should be restricted on network security groups associated to your virtual machine\n\n| Subscription | Resource group | Resource type | Affected resource | Status | Azure portal |\n| :----------- | :------------- | :------------ | :---------------- | :----- | :----------- |\n| [Visual Studio Enterprise Subscription](https://portal.azure.com/#resource/subscriptions/54d3ea01-5a07-45d0-8d69-e5f5b0b20098) | indiavm_group | virtualmachines | [india-2](https://portal.azure.com/#resource/subscriptions/54d3ea01-5a07-45d0-8d69-e5f5b0b20098/resourceGroups/INDIAVM_GROUP/providers/Microsoft.Compute/virtualMachines/india-2) | ❌ | [View recommendation](https://portal.azure.com/#blade/Microsoft_Azure_Security/RecommendationsBlade/assessmentKey/3b20e985-f71f-483b-b078-f30d73936d43/resourceId/%2fsubscriptions%2f54d3ea01-5a07-45d0-8d69-e5f5b0b20098%2fresourceGroups%2fINDIAVM_GROUP%2fproviders%2fMicrosoft.Compute%2fvirtualMachines%2findia-2) |\n| [Visual Studio Enterprise Subscription](https://portal.azure.com/#resource/subscriptions/54d3ea01-5a07-45d0-8d69-e5f5b0b20098) | indiavm_group | virtualmachines | [indiavm](https://portal.azure.com/#resource/subscriptions/54d3ea01-5a07-45d0-8d69-e5f5b0b20098/resourceGroups/INDIAVM_GROUP/providers/Microsoft.Compute/virtualMachines/indiavm) | ✅ | [View recommendation](https://portal.azure.com/#blade/Microsoft_Azure_Security/RecommendationsBlade/assessmentKey/3b20e985-f71f-483b-b078-f30d73936d43/resourceId/%2fsubscriptions%2f54d3ea01-5a07-45d0-8d69-e5f5b0b20098%2fresourceGroups%2fINDIAVM_GROUP%2fproviders%2fMicrosoft.Compute%2fvirtualMachines%2findiavm) |\n","TestStatus":"Failed","TestDescription":"Defender for Cloud has identified some of your network security groups' inbound rules to be too permissive. Inbound rules should not allow access from 'Any' or 'Internet' ranges. This can potentially enable attackers to target your resources.\n\n**Remediation action**\n\nWe recommend that you edit the inbound rules of some of your virtual machines, to restrict access to specific source ranges.
To restrict access to your virtual machines:
1. Select a VM to restrict access to.
2. In the 'Networking' blade, click the Network Security Group with overly permissive rules.
3. In the 'Network security group' blade, click on each of the rules that are overly permissive.
4. Improve the rule by applying less permissive source IP ranges.
5. Apply the suggested changes and click 'Save'.
If some or all of these virtual machines do not need to be accessed directly from the Internet, then you can also consider removing the public IP associated to them.","TestId":"3b20e985-f71f-483b-b078-f30d73936d43"},{"TestImplementationCost":"Low","TestPillar":"Identity","TestCategory":"Application management","SkippedReason":null,"TestImpact":"Low","TestAppliesTo":["Identity"],"TestSfiPillar":"Protect identities and secrets","TestSkipped":"","TestMinimumLicense":"Free","TestTags":["Identity"],"TestTitle":"Microsoft services applications don't have credentials configured","TestRisk":"High","TestResult":"\nNo Microsoft services applications have credentials configured in the tenant.\n\n","TestStatus":"Passed","TestDescription":"Microsoft services applications that operate in your tenant are identified as service principals with the owner organization ID \"f8cdef31-a31e-4b4a-93e4-5f571e91255a.\" When these service principals have credentials configured in your tenant, they might create potential attack vectors that threat actors can exploit. If an administrator added the credentials and they're no longer needed, they can become a target for attackers. Although less likely when proper preventive and detective controls are in place on privileged activities, threat actors can also maliciously add credentials. In either case, threat actors can use these credentials to authenticate as the service principal, gaining the same permissions and access rights as the Microsoft service application. This initial access can lead to privilege escalation if the application has high-level permissions, allowing lateral movement across the tenant. Attackers can then proceed to data exfiltration or persistence establishment through creating other backdoor credentials.\n\nWhen credentials (like client secrets or certificates) are configured for these service principals in your tenant, it means someone - either an administrator or a malicious actor - enabled them to authenticate independently within your environment. These credentials should be investigated to determine their legitimacy and necessity. If they're no longer needed, they should be removed to reduce the risk. \n\nIf this check doesn't pass, the recommendation is to \"investigate\" because you need to identify and review any applications with unused credentials configured.\n\n**Remediation action**\n\n- Confirm if the credentials added are still valid use cases. If not, remove credentials from Microsoft service applications to reduce security risk. \n - In the Microsoft Entra admin center, browse to **Entra ID** > **App registrations** and select the affected application.\n - Go to the **Certificates & secrets** section and remove any credentials that are no longer needed.\n","TestId":"21774"},{"TestImplementationCost":"Low","TestPillar":"Network","TestCategory":"Azure Network Security","SkippedReason":"This test is not applicable to the current environment.","TestImpact":"Low","TestAppliesTo":null,"TestSfiPillar":"Protect networks","TestSkipped":"NotApplicable","TestMinimumLicense":["Azure WAF on Azure Front Door Premium SKU","Azure Standard SKU"],"TestTags":null,"TestTitle":"Azure Front Door WAF is Enabled in Prevention Mode","TestRisk":"High","TestResult":"\nSkipped. This test is not applicable to the current environment.\n\n","TestStatus":"Skipped","TestDescription":"Azure Front Door Web Application Firewall (WAF) protects web applications from common exploits and vulnerabilities, including SQL injection, cross-site scripting, and other OWASP Top 10 threats. WAF operates in two modes: Detection and Prevention. Detection mode evaluates and logs requests that match WAF rules but doesn't block traffic, while Prevention mode actively blocks malicious requests before they reach the backend application. When WAF is in Detection mode, web applications remain exposed to exploitation even though threats are being identified.\n\nWithout WAF in Prevention mode:\n\n- Threat actors can exploit web application vulnerabilities because matched requests are only logged, not blocked.\n- Organizations lose active protection at the global edge that managed and custom WAF rules provide, which reduces WAF to an observation tool rather than a security control.\n\n**Remediation action**\n\n- [Configure WAF for Azure Front Door](https://learn.microsoft.com/azure/web-application-firewall/afds/afds-overview?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci) to switch the WAF policy from **Detection mode** to **Prevention mode**.\n- [Configure WAF policy settings for Azure Front Door](https://learn.microsoft.com/azure/web-application-firewall/afds/waf-front-door-policy-settings?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci#waf-mode) to enable **Prevention mode** in the policy settings.\n","TestId":25543},{"TestImplementationCost":"Low","TestPillar":"Network","TestCategory":"Azure Network Security","SkippedReason":"This test is not applicable to the current environment.","TestImpact":"Low","TestAppliesTo":null,"TestSfiPillar":"Monitor and detect cyberthreats","TestSkipped":"NotApplicable","TestMinimumLicense":"Azure_Application_Gateway_WAF","TestTags":null,"TestTitle":"Diagnostic logging is enabled in Application Gateway WAF","TestRisk":"High","TestResult":"\nSkipped. This test is not applicable to the current environment.\n","TestStatus":"Skipped","TestDescription":"Azure Application Gateway Web Application Firewall (WAF) protects web applications from common exploits and vulnerabilities such as SQL injection, cross-site scripting, and other OWASP Top 10 threats. When diagnostic logging is not enabled, security operations teams lose visibility into blocked attacks, rule matches, access patterns, and firewall events. A threat actor attempting to exploit web application vulnerabilities would go undetected because no WAF logs are being captured or analyzed. The absence of logging prevents correlation of WAF events with other security telemetry, eliminating the ability to construct attack timelines during incident investigations. Furthermore, compliance frameworks such as PCI-DSS, HIPAA, and SOC 2 require organizations to maintain audit logs of web application security events, and the lack of WAF diagnostic logging creates audit failures. Azure Application Gateway WAF provides multiple log categories including Application Gateway Access Logs, Performance Logs, and Firewall Logs, all of which must be routed to a destination such as Log Analytics, Storage Account, or Event Hub to enable security monitoring and forensic analysis.\n\n**Remediation action**\n\nCreate a Log Analytics workspace for storing Application Gateway WAF logs\n- [Create a Log Analytics workspace](https://learn.microsoft.com/en-us/azure/azure-monitor/logs/quick-create-workspace)\n\nConfigure diagnostic settings for Application Gateway to enable log collection\n- [Create diagnostic settings in Azure Monitor](https://learn.microsoft.com/en-us/azure/azure-monitor/essentials/create-diagnostic-settings)\n\nEnable WAF logging to capture firewall events and rule matches\n- [Application Gateway WAF logs and metrics](https://learn.microsoft.com/en-us/azure/web-application-firewall/ag/application-gateway-waf-metrics)\n\nMonitor Application Gateway using diagnostic logs and metrics\n- [Monitor Azure Application Gateway](https://learn.microsoft.com/en-us/azure/application-gateway/application-gateway-diagnostics)\n\nUse Azure Monitor Workbooks for visualizing and analyzing WAF logs\n- [Azure Monitor Workbooks](https://learn.microsoft.com/en-us/azure/azure-monitor/visualize/workbooks-overview)\n\n","TestId":26888},{"TestImplementationCost":"Low","TestPillar":"Identity","TestCategory":"Credential management","SkippedReason":null,"TestImpact":"Low","TestAppliesTo":null,"TestSfiPillar":"Protect identities and secrets","TestSkipped":"","TestMinimumLicense":"P1","TestTags":null,"TestTitle":"Password protection for on-premises is enabled","TestRisk":"High","TestResult":"\n\n❌ **Fail**: Password protection for on-premises is not set to 'Enforce' mode.\n\n## Password Protection Settings\n\n| Setting | Value |\n| :---- | :---- |\n| Password Protection for Active Directory Domain Services | ✅ Enabled |\n| Enabled Mode (Audit/Enforce) | ❌ Audit |\n\n\n","TestStatus":"Failed","TestDescription":"When on-premises password protection isn’t enabled or enforced, threat actors can use low-and-slow password spray with common variants, such as season+year+symbol or local terms, to gain initial access to Active Directory Domain Services accounts. Domain Controllers (DCs) can accept weak passwords when either of the following statements are true:\n\n- Microsoft Entra Password Protection DC agent isn't installed\n- The password protection tenant setting is disabled or in audit-only mode\n\nWith valid on-premises credentials, attackers laterally move by reusing passwords across endpoints, escalate to domain admin through local admin reuse or service accounts, and persist by adding backdoors, while weak or disabled enforcement produces fewer blocking events and predictable signals. Microsoft’s design requires a proxy that brokers policy from Microsoft Entra ID and a DC agent that enforces the combined global and tenant custom banned lists on password change/reset; consistent enforcement requires DC agent coverage on all DCs in a domain and using Enforced mode after audit evaluation.\n\n**Remediation action**\n\n- [Deploy Microsoft Entra password protection](https://learn.microsoft.com/entra/identity/authentication/howto-password-ban-bad-on-premises-deploy?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci)\n","TestId":"21847"},{"TestImplementationCost":"Low","TestPillar":"Devices","TestCategory":"Device","SkippedReason":null,"TestImpact":"Low","TestAppliesTo":null,"TestSfiPillar":"Protect identities and secrets","TestSkipped":"","TestMinimumLicense":"Intune","TestTags":null,"TestTitle":"Windows Cloud LAPS policy is created and assigned","TestRisk":"High","TestResult":"\nCloud LAPS policy is assigned and enforced.\n\n\n## Windows Cloud LAPS policy is created and assigned\n\n| Policy Name | Status | Assignment | Backup Directory | Automatic Account Management |\n| :---------- | :----- | :--------- | :--------------- | :--------------------------- |\n| [relaps](https://intune.microsoft.com/#view/Microsoft_Intune_Workflows/SecurityManagementMenu/~/accountprotection) | ✅ Assigned | **Included:** All Devices | ✅ Entra ID (AAD) | ❌ Not Configured |\n| [test](https://intune.microsoft.com/#view/Microsoft_Intune_Workflows/SecurityManagementMenu/~/accountprotection) | ✅ Assigned | **Included:** All Users | ✅ Active Directory | ✅ Enabled |\n\n\n\n","TestStatus":"Passed","TestDescription":"Without enforcing Local Administrator Password Solution (LAPS) policies, threat actors who gain access to endpoints can exploit static or weak local administrator passwords to escalate privileges, move laterally, and establish persistence. The attack chain typically begins with device compromise—via phishing, malware, or physical access—followed by attempts to harvest local admin credentials. Without LAPS, attackers can reuse compromised credentials across multiple devices, increasing the risk of privilege escalation and domain-wide compromise.\n\nEnforcing Windows LAPS on all corporate Windows devices ensures unique, regularly rotated local administrator passwords. This disrupts the attack chain at the credential access and lateral movement stages, significantly reducing the risk of widespread compromise.\n\n**Remediation action**\n\nUse Intune to enforce Windows LAPS policies that rotate strong and unique local admin passwords, and that back them up securely: \n- [Deploy Windows LAPS policy with Microsoft Intune](https://learn.microsoft.com/intune/intune-service/protect/windows-laps-policy?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci#create-a-laps-policy)\n\nFor more information, see: \n- [Windows LAPS policy settings reference](https://learn.microsoft.com/windows-server/identity/laps/laps-management-policy-settings?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci)\n- [Learn about Intune support for Windows LAPS](https://learn.microsoft.com/intune/intune-service/protect/windows-laps-overview?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci)\n","TestId":"24560"},{"TestImplementationCost":"High","TestPillar":"Identity","TestCategory":"Monitoring","SkippedReason":null,"TestImpact":"Low","TestAppliesTo":["Identity"],"TestSfiPillar":"Monitor and detect cyberthreats","TestSkipped":"","TestMinimumLicense":"P1","TestTags":["Identity"],"TestTitle":"All Microsoft Entra recommendations are addressed","TestRisk":"Medium","TestResult":"\nFound 11 unaddressed Entra recommendations.\n\n\n## Unaddressed Entra recommendations\n\n| Display Name | Status | Insights | Priority |\n| :--- | :--- | :--- | :--- |\n| Protect your tenant with Insider Risk condition in Conditional Access policy | active | You have 86 of 88 users that aren’t covered by the Insider Risk condition in a Conditional Access policy. | medium |\n| Protect all users with a user risk policy | active | You have 86 of 88 users that don’t have a user risk policy enabled. | high |\n| Protect all users with a sign-in risk policy | active | You have 86 of 88 users that don't have a sign-in risk policy turned on. | high |\n| Enable password hash sync if hybrid | active | You have disabled password hash sync. | medium |\n| Ensure all users can complete multifactor authentication | active | You have 59 of 88 users that aren’t registered with MFA. | high |\n| Enable policy to block legacy authentication | active | You have 3 of 88 users that don’t have legacy authentication blocked. | high |\n| Require multifactor authentication for administrative roles | active | You have 8 of 26 users with administrative roles that aren’t registered and protected with MFA. | high |\n| Renew expiring application credentials | active | Your tenant has applications with credentials that will expire soon. | high |\n| Remove unused credentials from applications | active | Your tenant has applications with credentials which have not been used in more than 30 days. | medium |\n| Remove unused applications | active | This recommendation will surface if your tenant has applications that have not been used for over 90 days. Applications that were created but never used, client applications which have not been issued a token or resource apps that have not been a target of a token request, will show under this recommendation. | medium |\n| Start your Defender for Identity deployment, installing Sensors on Domain Controllers and other eligible servers. | active | Installing Microsoft Defender for Identity sensors provides you with the ability to detect advanced threats in your entire identity infrastructure. Actionable security alerts are generated through the analysis of network traffic and security events. | low |\n\n\n","TestStatus":"Failed","TestDescription":"Microsoft Entra recommendations give organizations opportunities to implement best practices and optimize their security posture. Not acting on these items might result in an increased attack surface area, suboptimal operations, or poor user experience.\n\n**Remediation action**\n\n- [Address all active or postponed recommendations in the Microsoft Entra admin center](https://learn.microsoft.com/entra/identity/monitoring-health/overview-recommendations?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci#how-does-it-work)\n","TestId":"21866"},{"TestImpact":"Medium","TestRisk":"Low","TestSkipped":"","TestAppliesTo":null,"TestPillar":"Data","TestCategory":"Sensitivity Labels","TestDescription":"Labels must be published by using label policies before users can apply them to items, such as files, emails, and meetings. Label policies define which users receive which labels, set default labeling behavior, and other labeling requirements. Without published policies, sensitivity labels remain unavailable to users.\n\n**Remediation action**\n\n- [Create and configure sensitivity labels and their policies](https://learn.microsoft.com/purview/create-sensitivity-labels?tabs=classic-label-scheme&wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci#publish-sensitivity-labels-by-creating-a-label-policy)\n","TestTitle":"Published Label Policies","SkippedReason":null,"TestId":"35004","TestImplementationCost":"Low","TestMinimumLicense":["RMS_S_PREMIUM"],"TestSfiPillar":"Protect tenants and production systems","TestResult":"\n✅ At least one enabled label policy is published to users.\n\n### Label Policy Summary\n\n* Total Policies Configured: 6\n* Enabled Policies: 6\n* Disabled Policies: 0\n* Total Users/Groups with Label Access: All Users\n\n**Policies:**\n| Policy name | Enabled | Labels included | Published to |\n|:---|:---|:---|:---|\n| 35035-Test-Policy | True | 1 | Specific Users/Groups |\n| Test Policy | True | 1 | Specific Users/Groups |\n| true event | True | 1 | All Users/Groups |\n| userpolicy | True | 1 | Specific Users/Groups |\n| peyton | True | 1 | All Users/Groups |\n| test-policy-35012 | True | 1 | All Users/Groups |\n\n[Manage Label Policies in Microsoft Purview](https://purview.microsoft.com/informationprotection/labelpolicies)\n\n\n","TestStatus":"Passed","TestTags":null},{"TestImpact":"Low","TestRisk":"High","TestSkipped":"NoCompatibleLicenseFound","TestAppliesTo":null,"TestPillar":"Network","TestCategory":"Global Secure Access","TestDescription":"When administrators use Microsoft Entra Private Access to reach domain controllers through Remote Desktop Protocol (RDP), they authenticate through Microsoft Entra ID before the Global Secure Access client tunnels their connection to the on-premises network. Domain controllers hold the cryptographic keys to the entire Active Directory forest. Compromising one domain controller offers a way to compromise every identity and resource in the organization.\n\nWithout phishing-resistant authentication:\n\n- Threat actors can intercept credentials during phishing campaigns or adversary-in-the-middle attacks.\n- Stolen session tokens can be replayed to establish RDP connections to domain controllers.\n- Once connected, threat actors can execute DCSync attacks to harvest all password hashes in the domain.\n- Attackers can create golden tickets for indefinite domain persistence.\n- Group Policy Objects can be modified to deploy ransomware or backdoors across all domain-joined machines.\n\nBy requiring phishing-resistant authentication, organizations ensure that even if users are successfully phished, threat actors can't replay credentials because these methods require cryptographic proof of possession.\n\n**Remediation action**\n\n- [Deploy phishing-resistant authentication methods to domain controller administrators](https://learn.microsoft.com/entra/identity/authentication/how-to-deploy-phishing-resistant-passwordless-authentication?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci).\n- [Require phishing-resistant authentication for administrators accessing domain controllers via RDP](https://learn.microsoft.com/entra/global-secure-access/how-to-configure-domain-controllers?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci).\n","TestTitle":"Domain controller RDP access is protected by phishing-resistant authentication through Global Secure Access","SkippedReason":"This test requires one of the following licenses: (\"Entra_Premium_Private_Access\"). Please ensure your tenant has the appropriate licenses to run this test. See [Licensing & Service Plans](https://learn.microsoft.com/entra/identity/users/licensing-service-plan-reference)","TestId":"25398","TestImplementationCost":"Medium","TestMinimumLicense":["Entra_Premium_Private_Access"],"TestSfiPillar":"Protect networks","TestResult":"\nSkipped. This test requires one of the following licenses: (\"Entra_Premium_Private_Access\"). Please ensure your tenant has the appropriate licenses to run this test. See [Licensing & Service Plans](https://learn.microsoft.com/entra/identity/users/licensing-service-plan-reference)\n\n","TestStatus":"Skipped","TestTags":null},{"TestImplementationCost":"Medium","TestPillar":"Identity","TestCategory":"Applications management","SkippedReason":null,"TestImpact":"Low","TestAppliesTo":["Identity"],"TestSfiPillar":"Protect identities and secrets","TestSkipped":"","TestMinimumLicense":"P1","TestTags":["Identity"],"TestTitle":"Applications that use Microsoft Entra for authentication and support provisioning are configured","TestRisk":"Medium","TestResult":"\nApplications that are configured for SSO and support provisioning are NOT configured for provisioning.\n\n\n## Applications that are NOT configured for provisioning\n\n\n| Application Name | Object ID | Application ID |\n| :--------------- | :-------- | :------------- |\n| [21869testapp](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/Overview/objectId/e69e29be-ba40-445a-9824-a3a45e0ae57a/appId/dd63d132-18fb-4f2e-aec4-82b97f30301f/preferredSingleSignOnMode/saml/servicePrincipalType/Application/fromNav/) | e69e29be-ba40-445a-9824-a3a45e0ae57a | dd63d132-18fb-4f2e-aec4-82b97f30301f |\n| [APP-2732_Genesys Cloud TCCC-G-TFS-Prod](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/Overview/objectId/ba63bb52-182c-4ec6-9cc8-ad2287cf51ed/appId/76249b01-8747-4db4-843f-6478d5b32b14/preferredSingleSignOnMode/saml/servicePrincipalType/Application/fromNav/) | ba63bb52-182c-4ec6-9cc8-ad2287cf51ed | 76249b01-8747-4db4-843f-6478d5b32b14 |\n| [AWS Single-Account Access](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/Overview/objectId/dc89bf5d-83e8-4419-9162-3b9280a85755/appId/091edd89-b342-4bb5-9144-82fe6c913987/preferredSingleSignOnMode/saml/servicePrincipalType/Application/fromNav/) | dc89bf5d-83e8-4419-9162-3b9280a85755 | 091edd89-b342-4bb5-9144-82fe6c913987 |\n| [claimtest](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/Overview/objectId/f7b07e81-79a0-4e51-b93a-169b8f2f6c4e/appId/f816d68b-aec7-4eab-9ebc-bd23b0d04e35/preferredSingleSignOnMode/saml/servicePrincipalType/Application/fromNav/) | f7b07e81-79a0-4e51-b93a-169b8f2f6c4e | f816d68b-aec7-4eab-9ebc-bd23b0d04e35 |\n| [Docusign](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/Overview/objectId/c6c64515-9c2c-4458-830d-fda30f7f55b5/appId/bc582926-d3ef-48e0-9a43-e813b898afb0/preferredSingleSignOnMode/saml/servicePrincipalType/Application/fromNav/) | c6c64515-9c2c-4458-830d-fda30f7f55b5 | bc582926-d3ef-48e0-9a43-e813b898afb0 |\n| [Dropbox Business](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/Overview/objectId/5eec0e98-b81a-422a-ab61-f8de2729330d/appId/f76d7d98-02ee-4e62-9345-36016a72e664/preferredSingleSignOnMode/saml/servicePrincipalType/Application/fromNav/) | 5eec0e98-b81a-422a-ab61-f8de2729330d | f76d7d98-02ee-4e62-9345-36016a72e664 |\n| [charlie AWS Account](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/Overview/objectId/39861745-eda1-4e3c-8358-d0ba931f12bb/appId/d3a04f85-a969-436b-bf4d-eae0a91efb4c/preferredSingleSignOnMode/saml/servicePrincipalType/Application/fromNav/) | 39861745-eda1-4e3c-8358-d0ba931f12bb | d3a04f85-a969-436b-bf4d-eae0a91efb4c |\n| [charlie- Genesys Cloud for Azure](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/Overview/objectId/84dc13ec-5754-4745-90f9-5cc92a5ded28/appId/9c599cd2-9fb0-4815-b65c-83be33f5df1b/preferredSingleSignOnMode/saml/servicePrincipalType/Application/fromNav/) | 84dc13ec-5754-4745-90f9-5cc92a5ded28 | 9c599cd2-9fb0-4815-b65c-83be33f5df1b |\n| [Salesforce](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/Overview/objectId/13720002-03b6-462f-ac2f-765f0f9b3f58/appId/1a2a1d4c-1d76-44ec-95f4-3ed5345423a9/preferredSingleSignOnMode/saml/servicePrincipalType/Application/fromNav/) | 13720002-03b6-462f-ac2f-765f0f9b3f58 | 1a2a1d4c-1d76-44ec-95f4-3ed5345423a9 |\n| [Saml test entity id](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/Overview/objectId/d589a2e6-4a78-4cdd-901b-f574dc7880db/appId/6590313e-1c00-4c07-be28-72858e837a52/preferredSingleSignOnMode/saml/servicePrincipalType/Application/fromNav/) | d589a2e6-4a78-4cdd-901b-f574dc7880db | 6590313e-1c00-4c07-be28-72858e837a52 |\n| [ServiceNow](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/Overview/objectId/9a8af246-0d94-42eb-aaaf-836a9f9a4974/appId/ecbbb1c8-ef06-48c4-9211-9ffbfbc24b94/preferredSingleSignOnMode/saml/servicePrincipalType/Application/fromNav/) | 9a8af246-0d94-42eb-aaaf-836a9f9a4974 | ecbbb1c8-ef06-48c4-9211-9ffbfbc24b94 |\n| [test](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/Overview/objectId/31e80a1b-3faa-4ce9-9794-2b77f61f20f7/appId/8ae2b566-71f5-467e-8960-cfe8da3a2cfa/preferredSingleSignOnMode/saml/servicePrincipalType/Application/fromNav/) | 31e80a1b-3faa-4ce9-9794-2b77f61f20f7 | 8ae2b566-71f5-467e-8960-cfe8da3a2cfa |\n\n\n\n","TestStatus":"Failed","TestDescription":"When applications that support both authentication and provisioning through Microsoft Entra aren't configured for automatic provisioning, organizations become vulnerable to identity lifecycle gaps that threat actors can exploit. Without automated provisioning, user accounts might persist in applications after employees leave the organization. This vulnerability creates dormant accounts that threat actors can discover through reconnaissance activities. These orphaned accounts often retain their original access permissions but lack active monitoring, making them attractive targets for initial access.\n\nThreat actors who gain access to these dormant accounts can use them to establish persistence in the target application, as the accounts appear legitimate and might not trigger security alerts. From these compromised application accounts, attackers can:\n\n- Attempt to escalate their privileges by exploring application-specific permissions\n- Access sensitive data stored within the application\n- Use the application as a pivot point to access other connected systems\n\nThe lack of centralized identity lifecycle management also makes it difficult for security teams to detect when an attacker is using these orphaned accounts, as the accounts might not be properly correlated with the organization's active user directory. \n\n**Remediation action**\n\n- [Configure application provisioning for missing applications](https://learn.microsoft.com/entra/identity/app-provisioning/configure-automatic-user-provisioning-portal?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci)\n","TestId":"21886"},{"TestImplementationCost":"","TestPillar":"Infrastructure","TestCategory":"Manage access and permissions","SkippedReason":null,"TestImpact":"","TestAppliesTo":null,"TestSfiPillar":"Protect tenants and isolate production systems","TestSkipped":"","TestMinimumLicense":"N/A","TestTags":null,"TestTitle":"Disabled accounts with read and write permissions on Azure resources should be removed","TestRisk":"High","TestResult":"Disabled accounts with read and write permissions on Azure resources should be removed\n\n| Subscription | Affected resource | Status | Azure portal |\n| :----------- | :---------------- | :----- | :----------- |\n| [Visual Studio Enterprise Subscription](https://portal.azure.com/#resource/subscriptions/54d3ea01-5a07-45d0-8d69-e5f5b0b20098) | [54d3ea01-5a07-45d0-8d69-e5f5b0b20098](https://portal.azure.com/#resource/subscriptions/54d3ea01-5a07-45d0-8d69-e5f5b0b20098) | ✅ | [View recommendation](https://portal.azure.com/#blade/Microsoft_Azure_Security/RecommendationsBlade/assessmentKey/1ff0b4c9-ed56-4de6-be9c-d7ab39645926/resourceId/%2fsubscriptions%2f54d3ea01-5a07-45d0-8d69-e5f5b0b20098) |\n","TestStatus":"Passed","TestDescription":"It's important to remove disabled accounts that have read and write permissions on Azure resources.
These accounts, although disabled from signing in on Active Directory, can still be targeted by attackers.
If exploited, these accounts could provide unauthorized access to your data, potentially leading to data breaches.
Therefore, to maintain a secure environment, we recommend removing these accounts from Azure resources.
\n\n**Remediation action**\n\nReview the list of accounts that are disabled from signing in on the Accounts section. Select an account to view its role definitions and locate the source scope. If you accept the risk for specific account, use the exempt capability to exclude it from evaluation.
  1. Go to the Azure portal.
  2. Open Access control (IAM) at a scope, such as management group, subscription, resource group, or resource, where the guest user has a role assignment.
  3. Click the Role assignments tab to view all the role assignments.
  4. In the list of role assignments, add a checkmark next to the disabled user with the role assignment you want to remove.
  5. Click Remove. In the remove role assignment message that appears, click Yes.
","TestId":"1ff0b4c9-ed56-4de6-be9c-d7ab39645926"},{"TestImpact":"Low","TestRisk":"Medium","TestSkipped":"NoCompatibleLicenseFound","TestAppliesTo":null,"TestPillar":"Network","TestCategory":"Global Secure Access","TestDescription":"Without private DNS configuration, remote users can't resolve internal domain names through Microsoft Entra Private Access and must rely on public DNS servers. Threat actors can exploit this gap through DNS spoofing attacks that redirect users to malicious sites, enabling credential harvesting and data exfiltration. Organizations also lose visibility into DNS queries and can't enforce consistent security policies.\n\n**Remediation action**\n\n- [Configure private DNS for internal name resolution](https://learn.microsoft.com/entra/global-secure-access/how-to-configure-quick-access?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci#add-private-dns-suffixes)\n","TestTitle":"Private DNS is configured for internal name resolution","SkippedReason":"This test requires one of the following licenses: (\"Entra_Premium_Private_Access\"). Please ensure your tenant has the appropriate licenses to run this test. See [Licensing & Service Plans](https://learn.microsoft.com/entra/identity/users/licensing-service-plan-reference)","TestId":"25399","TestImplementationCost":"Medium","TestMinimumLicense":["Entra_Premium_Private_Access"],"TestSfiPillar":"Protect networks","TestResult":"\nSkipped. This test requires one of the following licenses: (\"Entra_Premium_Private_Access\"). Please ensure your tenant has the appropriate licenses to run this test. See [Licensing & Service Plans](https://learn.microsoft.com/entra/identity/users/licensing-service-plan-reference)\n\n","TestStatus":"Skipped","TestTags":null},{"TestImplementationCost":"Low","TestPillar":"Identity","TestCategory":"Credential management","SkippedReason":null,"TestImpact":"Low","TestAppliesTo":["Identity"],"TestSfiPillar":"Protect identities and secrets","TestSkipped":"","TestMinimumLicense":"P1","TestTags":["Identity"],"TestTitle":"Password expiration is disabled","TestRisk":"Medium","TestResult":"\nPassword expiration is properly disabled across all domains and users.\n\n","TestStatus":"Passed","TestDescription":"When password expiration policies remain enabled, threat actors can exploit the predictable password rotation patterns that users typically follow when forced to change passwords regularly. Users frequently create weaker passwords by making minimal modifications to existing ones, such as incrementing numbers or adding sequential characters. Threat actors can easily anticipate and exploit these types of changes through credential stuffing attacks or targeted password spraying campaigns. These predictable patterns enable threat actors to establish persistence through:\n\n- Compromised credentials\n- Escalated privileges by targeting administrative accounts with weak rotated passwords\n- Maintaining long-term access by predicting future password variations\n\nResearch shows that users create weaker, more predictable passwords when they are forced to expire. These predictable passwords are easier for experienced attackers to crack, as they often make simple modifications to existing passwords rather than creating entirely new, strong passwords. Additionally, when users are required to frequently change passwords, they might resort to insecure practices such as writing down passwords or storing them in easily accessible locations, creating more attack vectors for threat actors to exploit during physical reconnaissance or social engineering campaigns. \n\n**Remediation action**\n\n- [Set the password expiration policy for your organization](https://learn.microsoft.com/microsoft-365/admin/manage/set-password-expiration-policy?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci).\n - Sign in to the [Microsoft 365 admin center](https://admin.microsoft.com/). Go to **Settings** > **Org Settings** >** Security & Privacy** > **Password expiration policy**. Ensure the **Set passwords to never expire** setting is checked.\n- [Disable password expiration using Microsoft Graph](https://learn.microsoft.com/graph/api/domain-update?view=graph-rest-1.0&preserve-view=true&wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci).\n- [Set individual user passwords to never expire using Microsoft Graph PowerShell](https://learn.microsoft.com/microsoft-365/admin/add-users/set-password-to-never-expire?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci)\n - `Update-MgUser -UserId -PasswordPolicies DisablePasswordExpiration`\n","TestId":"21811"},{"TestImplementationCost":"Low","TestPillar":"Identity","TestCategory":"Monitoring","SkippedReason":"UnderConstruction","TestImpact":"Low","TestAppliesTo":["Identity"],"TestSfiPillar":"Monitor and detect cyberthreats","TestSkipped":"UnderConstruction","TestMinimumLicense":null,"TestTags":["Identity"],"TestTitle":"Tenant creation events are triaged","TestRisk":"Medium","TestResult":"\nPlanned for future release.\n\n","TestStatus":"Planned","TestDescription":"Tenant creation events should be monitored and triaged to detect unauthorized tenant creation. Users with sufficient permissions can create new tenants, which could be used to establish shadow environments outside your organization's security monitoring. Routing audit logs to a SIEM and configuring alerts for tenant creation events enables security teams to quickly investigate and respond to potentially malicious activity.\n\n**Remediation action**\n\n- [Review and restrict permissions to create tenants](https://learn.microsoft.com/entra/identity/role-based-access-control/permissions-reference?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci)\n- [Stream audit logs to an event hub for SIEM integration](https://learn.microsoft.com/entra/identity/monitoring-health/howto-stream-logs-to-event-hub?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci)\n- [Configure monitoring and alerting for audit events](https://learn.microsoft.com/entra/identity/monitoring-health/overview-monitoring-health?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci)\n","TestId":"21789"},{"TestImpact":"Medium","TestRisk":"Medium","TestSkipped":"","TestAppliesTo":null,"TestPillar":"Data","TestCategory":"Information Protection","TestDescription":"When users aren't required to provide a justification for changing a label, they can silently replace a label with one that has a lower sensitivity. For example, replace the \"Confidential\" label that applies additional protection settings, with \"General\". This action creates security and compliance risk. Requiring a justification reason makes this risk more obvious to users, and forces them to provide a reason as a visible audit trail.\n\nCompromised accounts or departing employees could downgrade labels to enable data exfiltration. Requiring justification is a lightweight control that increases accountability with low impact on user workflows.\n\n**Remediation action**\n\n- [Publish sensitivity labels by creating a label policy](https://learn.microsoft.com/purview/create-sensitivity-labels?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci#publish-sensitivity-labels-by-creating-a-label-policy)\n- [What label policies can do](https://learn.microsoft.com/purview/sensitivity-labels?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci#what-label-policies-can-do)\n- [Review labeling activities in activity explorer](https://learn.microsoft.com/purview/data-classification-activity-explorer-available-events?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci#protection-removed)\n","TestTitle":"Downgrade Justification Required for Sensitivity Labels","SkippedReason":null,"TestId":"35018","TestImplementationCost":"Low","TestMinimumLicense":["RMS_S_PREMIUM"],"TestSfiPillar":"Protect tenants and production systems","TestResult":"\n✅ Downgrade justification is enforced in at least one enabled sensitivity label policy.\n\n\n\n### Downgrade Justification Configuration\n| Policy name | Downgrade justification | Scope | Labels | Workloads |\n| :--- | :--- | :--- | :--- | :--- |\n| [35035-Test-Policy](https://purview.microsoft.com/informationprotection/labelpolicies) | ✅ | Scoped | 1 | M365 Groups |\n| [Test Policy](https://purview.microsoft.com/informationprotection/labelpolicies) | ✅ | Scoped | 1 | Exchange |\n| [true event](https://purview.microsoft.com/informationprotection/labelpolicies) | ✅ | Global | 1 | Exchange |\n| [userpolicy](https://purview.microsoft.com/informationprotection/labelpolicies) | ✅ | Scoped | 1 | Exchange |\n| [peyton](https://purview.microsoft.com/informationprotection/labelpolicies) | ✅ | Global | 1 | Exchange |\n| [test-policy-35012](https://purview.microsoft.com/informationprotection/labelpolicies) | ❌ | Global | 1 | Exchange |\n\n### Summary\n| Metric | Count |\n| :--- | :--- |\n| Total enabled label policies | 6 |\n| Policies requiring downgrade justification | 5 |\n| Policies NOT requiring downgrade justification | 1 |\n| Percentage with downgrade justification | 83.33% |\n\n","TestStatus":"Passed","TestTags":null},{"TestImplementationCost":"Medium","TestPillar":"Identity","TestCategory":"Application management","SkippedReason":null,"TestImpact":"Low","TestAppliesTo":["Identity"],"TestSfiPillar":"Protect engineering systems","TestSkipped":"","TestMinimumLicense":"P2","TestTags":["Identity"],"TestTitle":"Global Administrator role activation triggers an approval workflow","TestRisk":"High","TestResult":"\n✅ **Pass**: Approval required with 2 primary approver(s) configured.\n\n\n## Global Administrator role activation and approval workflow\n\n\n| Approval Required | Primary Approvers | Escalation Approvers |\n| :---------------- | :---------------- | :------------------- |\n| Yes | Jordan Smith, Ash Williams | |\n\n\n\n","TestStatus":"Passed","TestDescription":"Without approval workflows, threat actors who compromise Global Administrator credentials through phishing, credential stuffing, or other authentication bypass techniques can immediately activate the most privileged role in a tenant without any other verification or oversight. Privileged Identity Management (PIM) allows eligible role activations to become active within seconds, so compromised credentials can allow near-instant privilege escalation. Once activated, threat actors can use the Global Administrator role to use the following attack paths to gain persistent access to the tenant:\n- Create new privileged accounts\n- Modify Conditional Access policies to exclude those new accounts\n- Establish alternate authentication methods such as certificate-based authentication or application registrations with high privileges\n\nThe Global Administrator role provides access to administrative features in Microsoft Entra ID and services that use Microsoft Entra identities, including Microsoft Defender XDR, Microsoft Purview, Exchange Online, and SharePoint Online. Without approval gates, threat actors can rapidly escalate to complete tenant takeover, exfiltrating sensitive data, compromising all user accounts, and establishing long-term backdoors through service principals or federation modifications that persist even after the initial compromise is detected. \n\n**Remediation action**\n\n- [Configure role settings to require approval for Global Administrator activation](https://learn.microsoft.com/entra/id-governance/privileged-identity-management/pim-how-to-change-default-settings?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci)\n- [Set up approval workflow for privileged roles](https://learn.microsoft.com/entra/id-governance/privileged-identity-management/pim-approval-workflow?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci)\n","TestId":"21817"},{"TestImpact":"Low","TestRisk":"Medium","TestSkipped":"NoCompatibleLicenseFound","TestAppliesTo":null,"TestPillar":"Network","TestCategory":"Network","TestDescription":"\nWhen organizations deploy Global Secure Access as their cloud-based network proxy, Microsoft's Secure Service Edge infrastructure routes user traffic. If you don't enable source IP restoration, all authentication requests come from the proxy's IP address instead of the user's actual public egress IP.\n\nWithout this protection:\n\n- Threat actors who compromise user credentials can authenticate from any location while bypassing IP-based Conditional Access controls and named location policies.\n- Microsoft Entra ID Protection risk detections lose visibility into the original user IP address, which degrades the accuracy of risk scoring algorithms.\n- Sign-in logs and audit trails no longer show the true source of authentication attempts, which makes incident investigation and forensic analysis more difficult.\n\n**Remediation action**\n\n- Enable Global Secure Access signaling in Conditional Access. For more information, see [Source IP restoration](https://learn.microsoft.com/entra/global-secure-access/how-to-source-ip-restoration?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci).\n","TestTitle":"Source IP restoration is enabled","SkippedReason":"This test requires one of the following licenses: (\"Entra_Premium_Private_Access\") OR (\"Entra_Premium_Internet_Access\"). Please ensure your tenant has the appropriate licenses to run this test. See [Licensing & Service Plans](https://learn.microsoft.com/entra/identity/users/licensing-service-plan-reference)","TestId":"25370","TestImplementationCost":"Low","TestMinimumLicense":["Entra_Premium_Private_Access","Entra_Premium_Internet_Access"],"TestSfiPillar":"Protect networks","TestResult":"\nSkipped. This test requires one of the following licenses: (\"Entra_Premium_Private_Access\") OR (\"Entra_Premium_Internet_Access\"). Please ensure your tenant has the appropriate licenses to run this test. See [Licensing & Service Plans](https://learn.microsoft.com/entra/identity/users/licensing-service-plan-reference)\n\n","TestStatus":"Skipped","TestTags":null},{"TestImplementationCost":"Medium","TestPillar":"Identity","TestCategory":"Access control","SkippedReason":null,"TestImpact":"Low","TestAppliesTo":null,"TestSfiPillar":"Protect identities and secrets","TestSkipped":"","TestMinimumLicense":"Free","TestTags":null,"TestTitle":"Block legacy Azure AD PowerShell module","TestRisk":"Medium","TestResult":"\nSummary\n\n- [Azure AD PowerShell](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/Overview/objectId/39921e28-0140-4bfc-ad89-26a3294f6ca9/appId/1b730954-1685-4b74-9bfd-dac224a7b894)\n- Sign in disabled: Yes\n\nAzure AD PowerShell is blocked in the tenant by turning off user sign in to the Azure Active Directory PowerShell Enterprise Application.\n\n","TestStatus":"Passed","TestDescription":"Threat actors frequently target legacy management interfaces such as the Azure AD PowerShell module (AzureAD and AzureADPreview), which don't support modern authentication, Conditional Access enforcement, or advanced audit logging. Continued use of these modules exposes the environment to risks including weak authentication, bypass of security controls, and incomplete visibility into administrative actions. Attackers can exploit these weaknesses to gain unauthorized access, escalate privileges, and perform malicious changes. \n\nBlock the Azure AD PowerShell module and enforce the use of Microsoft Graph PowerShell or Microsoft Entra PowerShell to ensure that only secure, supported, and auditable management channels are available, which closes critical gaps in the attack chain. \n\n**Remediation action**\n\n- [Disable user sign-in for application](https://learn.microsoft.com/entra/identity/enterprise-apps/disable-user-sign-in-portal?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci)\n","TestId":"21844"},{"TestImplementationCost":"Medium","TestPillar":"Identity","TestCategory":"Access control","SkippedReason":null,"TestImpact":"Low","TestAppliesTo":["Identity"],"TestSfiPillar":"Protect identities and secrets","TestSkipped":"","TestMinimumLicense":"P1","TestTags":["Identity"],"TestTitle":"Secure the MFA registration (My Security Info) page","TestRisk":"High","TestResult":"\nSecurity information registration is protected by Conditional Access policies.\n## Conditional Access Policies targeting security information registration\n\n\n| Policy Name | User Actions Targeted | Grant Controls Applied |\n| :---------- | :-------------------- | :--------------------- |\n| [Security regisrtation info](https://entra.microsoft.com/#view/Microsoft_AAD_ConditionalAccess/PolicyBlade/policyId/508ae024-d4c4-42bf-a8c9-40257c214c10) | urn:user:registersecurityinfo | |\n\n\n\n","TestStatus":"Passed","TestDescription":"Without Conditional Access policies protecting security information registration, threat actors can exploit unprotected registration flows to compromise authentication methods. When users register multifactor authentication and self-service password reset methods without proper controls, threat actors can intercept these registration sessions through adversary-in-the-middle attacks or exploit unmanaged devices accessing registration from untrusted locations. Once threat actors gain access to an unprotected registration flow, they can register their own authentication methods, effectively hijacking the target's authentication profile. The threat actors can bypass security controls and potentially escalate privileges throughout the environment because they can maintain persistent access by controlling the MFA methods. The compromised authentication methods then become the foundation for lateral movement as threat actors can authenticate as the legitimate user across multiple services and applications.\n\n**Remediation action**\n\n- [Deploy a Conditional Access policy for security info registration](https://learn.microsoft.com/entra/identity/conditional-access/policy-all-users-security-info-registration?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci)\n- [Configure known network locations](https://learn.microsoft.com/entra/identity/conditional-access/concept-assignment-network?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci)\n- [Enable combined security info registration](https://learn.microsoft.com/entra/identity/authentication/howto-registration-mfa-sspr-combined?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci)\n","TestId":"21806"},{"TestImplementationCost":"Low","TestPillar":"Identity","TestCategory":"Devices","SkippedReason":"This test is not applicable to the current environment.","TestImpact":"Low","TestAppliesTo":null,"TestSfiPillar":"Protect tenants and isolate production systems","TestSkipped":"NotApplicable","TestMinimumLicense":"P1","TestTags":null,"TestTitle":"Manage the local administrators on Microsoft Entra joined devices","TestRisk":"High","TestResult":"\nSkipped. This test is not applicable to the current environment.\n\n","TestStatus":"Skipped","TestDescription":"When local administrators on Microsoft Entra joined devices aren't properly managed, threat actors with compromised credentials can execute device takeover attacks by removing organizational administrators and disabling the device's connection to Microsoft Entra. This lack of control results in complete loss of organizational control, creating orphaned assets that can't be managed or recovered.\n\n**Remediation action**\n\n- [Manage the local administrators on Microsoft Entra joined devices](https://learn.microsoft.com/entra/identity/devices/assign-local-admin?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci#manage-the-microsoft-entra-joined-device-local-administrator-role)\n","TestId":21955},{"TestImplementationCost":"","TestPillar":"Infrastructure","TestCategory":"Apply system updates","SkippedReason":"This test is not applicable to the current environment.","TestImpact":"","TestAppliesTo":null,"TestSfiPillar":"Protect tenants and isolate production systems","TestSkipped":"NotApplicable","TestMinimumLicense":"N/A","TestTags":null,"TestTitle":"System updates should be installed on your machines (powered by Azure Update Manager)","TestRisk":"High","TestResult":"NotSupported, AssessmentModeNotSetToAuto\n\n| Subscription | Resource group | Resource type | Affected resource | Status | Azure portal |\n| :----------- | :------------- | :------------ | :---------------- | :----- | :----------- |\n| [Visual Studio Enterprise Subscription](https://portal.azure.com/#resource/subscriptions/54d3ea01-5a07-45d0-8d69-e5f5b0b20098) | indiavm_group | virtualmachines | [india-2](https://portal.azure.com/#resource/subscriptions/54d3ea01-5a07-45d0-8d69-e5f5b0b20098/resourcegroups/indiavm_group/providers/microsoft.compute/virtualmachines/india-2) | N/A | [View recommendation](https://portal.azure.com/#blade/Microsoft_Azure_Security/RecommendationsBlade/assessmentKey/e1145ab1-eb4f-43d8-911b-36ddf771d13f/resourceId/%2fsubscriptions%2f54d3ea01-5a07-45d0-8d69-e5f5b0b20098%2fresourcegroups%2findiavm_group%2fproviders%2fmicrosoft.compute%2fvirtualmachines%2findia-2) |\n| [Visual Studio Enterprise Subscription](https://portal.azure.com/#resource/subscriptions/54d3ea01-5a07-45d0-8d69-e5f5b0b20098) | indiavm_group | virtualmachines | [indiavm](https://portal.azure.com/#resource/subscriptions/54d3ea01-5a07-45d0-8d69-e5f5b0b20098/resourcegroups/indiavm_group/providers/microsoft.compute/virtualmachines/indiavm) | N/A | [View recommendation](https://portal.azure.com/#blade/Microsoft_Azure_Security/RecommendationsBlade/assessmentKey/e1145ab1-eb4f-43d8-911b-36ddf771d13f/resourceId/%2fsubscriptions%2f54d3ea01-5a07-45d0-8d69-e5f5b0b20098%2fresourcegroups%2findiavm_group%2fproviders%2fmicrosoft.compute%2fvirtualmachines%2findiavm) |\n","TestStatus":"Skipped","TestDescription":"It's important to keep your machines updated by installing any missing security and critical OS updates.
These updates often contain crucial patches for security vulnerabilities, which, if left unpatched, can be exploited by threat actors.
Therefore, to secure your machines and prevent potential breaches,follow the remediation steps and install all outstanding patches provided by Azure Update Manager.
\n\n**Remediation action**\n\nTo install missing system updates on a selected machine: 1. From \"Affected resources\", select a virtual machine. 2. Select the \"Fix\" button. This will redirect you to Azure Update Manager. 3. Follow the instructions on Azure Update Manager portal to complete the process.","TestId":"e1145ab1-eb4f-43d8-911b-36ddf771d13f"},{"TestImpact":"High","TestRisk":"Low","TestSkipped":"","TestAppliesTo":null,"TestPillar":"Data","TestCategory":"Sensitivity Labels","TestDescription":"When co-authoring isn't enabled for documents protected by sensitivity labels that apply encryption, only one person can edit the file at a time when they use Office desktop apps. As a result, this can slow down teams, which makes collaboration difficult and can delay project completion. This limitation is especially challenging for groups working on sensitive projects that require encryption for privacy but also need to work together efficiently.\n\nTurning on co-authoring for files encrypted with sensitivity labels lets several authorized users edit the file at the same time in Office desktop apps. Unless you can ensure that all users edit these files by using Office for the web, this change removes the slowdown of requiring checkout and allows teams to efficiently collaborate without sacrificing security. The co-authoring setting might also be a requirement for other labeling features.\n\n**Remediation action**\n\n- [Enable co-authoring for files encrypted with sensitivity labels](https://learn.microsoft.com/purview/sensitivity-labels-coauthoring?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci)\n","TestTitle":"Co-Authoring Enabled for Encrypted Documents","SkippedReason":null,"TestId":"35009","TestImplementationCost":"Low","TestMinimumLicense":["RMS_S_PREMIUM2"],"TestSfiPillar":"Protect tenants and production systems","TestResult":"\n✅ Co-authoring is enabled for encrypted documents with sensitivity labels.\n\n\n\n## Configuration Details\n\n| Setting | Status |\n| :------ | :----- |\n| EnableLabelCoauth | ✅ Enabled |\n\n\n","TestStatus":"Passed","TestTags":null},{"TestImplementationCost":"Low","TestPillar":"Network","TestCategory":"Private Access","SkippedReason":"This test is not applicable to the current environment.","TestImpact":"Low","TestAppliesTo":null,"TestSfiPillar":"Protect networks","TestSkipped":"NotApplicable","TestMinimumLicense":["AAD_PREMIUM","Entra_Premium_Private_Access"],"TestTags":null,"TestTitle":"Is port 53 published or private DNS configured for Private Access applications","TestRisk":"Low","TestResult":"\nPrivate Access is not enabled in this tenant. This check is not applicable until Private Access is configured and enabled.\n","TestStatus":"Skipped","TestDescription":"When the Private Access profile is enabled in Global Secure Access but neither port 53 (UDP/TCP) is published in application segments nor private DNS suffixes are configured, the Global Secure Access client on remote devices cannot route DNS queries for internal domain names through the tunnel. DNS queries for internal FQDNs then go to the local resolver on the device, which has no knowledge of internal zones. This causes FQDN-based application segments to fail to match traffic because the client cannot resolve internal host names to IP addresses. A threat actor operating on the same local network as the remote user can observe these unencrypted DNS queries (T1040 - Network Sniffing), map internal resource names, and use that information to identify targets for later stages of an attack. The client may also fall back to direct connections that bypass Conditional Access and security profile enforcement applied through Global Secure Access, reducing the organization's control over access to private resources. Configuring private DNS suffixes or publishing port 53 to an internal DNS server through an application segment ensures that DNS resolution for internal domains occurs within the tunnel, preventing DNS leakage and maintaining traffic acquisition for FQDN-based segments.\n\n**Remediation action**\n\n- [Configure private DNS suffixes for Quick Access or per-app access to route DNS queries for internal domains through Global Secure Access](https://learn.microsoft.com/entra/global-secure-access/how-to-configure-quick-access)\n- [Configure per-app access with application segments that include port 53 to an internal DNS server](https://learn.microsoft.com/entra/global-secure-access/how-to-configure-per-app-access)\n- [Understand Private Access and application segment configuration in Global Secure Access](https://learn.microsoft.com/entra/global-secure-access/concept-private-access)\n\n","TestId":25400},{"TestImplementationCost":"Low","TestPillar":"Network","TestCategory":"Azure Network Security","SkippedReason":"This test is not applicable to the current environment.","TestImpact":"Low","TestAppliesTo":null,"TestSfiPillar":"Monitor and detect cyberthreats","TestSkipped":"NotApplicable","TestMinimumLicense":["Azure_FrontDoor_Standard","Azure_FrontDoor_Premium"],"TestTags":null,"TestTitle":"Diagnostic logging is enabled in Azure Front Door WAF","TestRisk":"High","TestResult":"\nSkipped. This test is not applicable to the current environment.\n","TestStatus":"Skipped","TestDescription":"Without diagnostic logging enabled for Azure Front Door WAF, security teams lose visibility into blocked attacks, rule matches, access patterns, and WAF events occurring at the network edge. Threat actors attempting to exploit web application vulnerabilities through SQL injection, cross-site scripting, or other OWASP Top 10 attacks would go undetected because no WAF logs are being captured or analyzed. The absence of logging prevents correlation of WAF events with other security telemetry, eliminating the ability to construct attack timelines during incident investigations. Furthermore, compliance frameworks such as PCI-DSS, HIPAA, and SOC 2 require organizations to maintain audit logs of web application security events, and the lack of WAF diagnostic logging creates audit failures. Azure Front Door WAF provides multiple log categories including Access Logs and WAF Logs, which must be routed to a destination such as Log Analytics, Storage Account, or Event Hub to enable security monitoring and forensic analysis.\n\n**Remediation action**\n\nConfigure diagnostic settings for Azure Front Door to enable WAF log collection\n- [Create diagnostic settings in Azure Monitor](https://learn.microsoft.com/en-us/azure/azure-monitor/essentials/create-diagnostic-settings)\n\nEnable WAF logging to capture firewall events and rule matches\n- [Azure Front Door WAF monitoring and logging](https://learn.microsoft.com/en-us/azure/web-application-firewall/afds/waf-front-door-monitor)\n\nCreate a Log Analytics workspace for storing and analyzing WAF logs\n- [Create a Log Analytics workspace](https://learn.microsoft.com/en-us/azure/azure-monitor/logs/quick-create-workspace)\n\nMonitor Azure Front Door using diagnostic logs and metrics\n- [Monitor metrics and logs in Azure Front Door](https://learn.microsoft.com/en-us/azure/frontdoor/front-door-diagnostics)\n\n","TestId":26889},{"TestImplementationCost":"","TestPillar":"Infrastructure","TestCategory":"Implement security best practices","SkippedReason":"This test is not applicable to the current environment.","TestImpact":"","TestAppliesTo":null,"TestSfiPillar":"Protect tenants and isolate production systems","TestSkipped":"NotApplicable","TestMinimumLicense":"N/A","TestTags":null,"TestTitle":"Non-internet-facing virtual machines should be protected with network security groups","TestRisk":"Low","TestResult":"InternetFacingVms\n\n| Subscription | Resource group | Resource type | Affected resource | Status | Azure portal |\n| :----------- | :------------- | :------------ | :---------------- | :----- | :----------- |\n| [Visual Studio Enterprise Subscription](https://portal.azure.com/#resource/subscriptions/54d3ea01-5a07-45d0-8d69-e5f5b0b20098) | indiavm_group | virtualmachines | [india-2](https://portal.azure.com/#resource/subscriptions/54d3ea01-5a07-45d0-8d69-e5f5b0b20098/resourceGroups/indiavm_group/providers/Microsoft.Compute/virtualMachines/india-2) | N/A | [View recommendation](https://portal.azure.com/#blade/Microsoft_Azure_Security/RecommendationsBlade/assessmentKey/a9341235-9389-42f0-a0bf-9bfb57960d44/resourceId/%2fsubscriptions%2f54d3ea01-5a07-45d0-8d69-e5f5b0b20098%2fresourceGroups%2findiavm_group%2fproviders%2fMicrosoft.Compute%2fvirtualMachines%2findia-2) |\n| [Visual Studio Enterprise Subscription](https://portal.azure.com/#resource/subscriptions/54d3ea01-5a07-45d0-8d69-e5f5b0b20098) | indiavm_group | virtualmachines | [indiavm](https://portal.azure.com/#resource/subscriptions/54d3ea01-5a07-45d0-8d69-e5f5b0b20098/resourceGroups/indiavm_group/providers/Microsoft.Compute/virtualMachines/indiavm) | N/A | [View recommendation](https://portal.azure.com/#blade/Microsoft_Azure_Security/RecommendationsBlade/assessmentKey/a9341235-9389-42f0-a0bf-9bfb57960d44/resourceId/%2fsubscriptions%2f54d3ea01-5a07-45d0-8d69-e5f5b0b20098%2fresourceGroups%2findiavm_group%2fproviders%2fMicrosoft.Compute%2fvirtualMachines%2findiavm) |\n","TestStatus":"Skipped","TestDescription":"Protect your non-internet-facing virtual machine from potential threats by restricting access to it with a network security group (NSG). NSGs contain a list of Access Control List (ACL) rules that allow or deny network traffic to your VM from other instances, whether or not they're on the same subnet.
Note that to keep your machine as secure as possible, the VM's access to the internet must be restricted and an NSG should be enabled on the subnet.\n\n**Remediation action**\n\nTo protect a virtual machine with a network security group:
1. Select a VM from the list below, or select \"Take action\" if you've arrived from a recommendation for a specific VM.
2. Assign the relevant NSG to the NIC or subnet for the VM you're protecting:
  a. To assign the NSG to the VM's subnet (recommended):
    i. In the Networking page, select the 'Virtual network/subnet'.
    ii. Open the \"Subnets\" menu.
    iii. Select the subnet where your VM is deployed.
    iv. Select the network security group to assign to the subnet and select \"Save\".
  b. To assign the NSG to the NIC:
    i. In the Networking page, select the network interface that's associated with the selected VM.
    ii. In the Network interfaces page, select the 'Network security group' menu item.
    iii. Select 'Edit' at the top of the page.
    iv. Follow the on-screen instructions and select the network security group to assign to this NIC.
Learn more.","TestId":"a9341235-9389-42f0-a0bf-9bfb57960d44"},{"TestImpact":"High","TestRisk":"High","TestSkipped":"","TestAppliesTo":null,"TestPillar":"Data","TestCategory":"Sensitivity Labels Configuration","TestDescription":"Without encryption, sensitivity labels denote an item's sensitivity level without preventing unauthorized access, unless supplemented by another protection mechanism. Sensitivity labels that are configured to apply encryption from the Azure Rights Management service enforce access control and usage rights. This protection persists regardless of where the content is stored or shared. For example, users can still share a document labeled as \"Confidential\", but if that label applies encryption, unauthorized people won't be able to open it.\n\nOrganizations using labels without encryption gain visibility of the sensitivity level but the labels themselves lack technical enforcement. Labels that apply encryption ensure only authorized users can decrypt content and use it with any restrictions that are specified for that user. For example, read-only, or prevent copying. This protection helps prevent data exfiltration even if files are leaked or improperly shared. At least one sensitivity label should be configured to apply encryption for high-value data that requires protection beyond identifying the sensitivity level.\n\n**Remediation action**\n\n- [Restrict access to content by using encryption in sensitivity labels](https://learn.microsoft.com/purview/encryption-sensitivity-labels?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci)\n","TestTitle":"Encryption-Enabled Labels","SkippedReason":null,"TestId":"35013","TestImplementationCost":"Medium","TestMinimumLicense":["RMS_S_PREMIUM"],"TestSfiPillar":"Protect tenants and production systems","TestResult":"\n✅ At least one encryption-enabled sensitivity label is configured.\n\n\n## [Encryption Label Details](https://purview.microsoft.com/informationprotection/informationprotectionlabels/sensitivitylabels)\n\n| Label name | Encryption type | Default permissions identities | Co-Authoring blocked |\n| :--------- | :-------------- | :----------------------------- | :------------------: |\n| Confidential – RMS | User-Defined | Not specified | No |\n| test35036 | Standard RMS | demouser3791943@contoso.com, demouser3792567@contoso.com, demouser3792993@contoso.com | No |\n| test-dke | Double Key Encryption (DKE) | demouser3792993@contoso.com, demouser4181693@contoso.com, demouser4208366@contoso.com, demouser4208785@contoso.com, sessionenforced@contoso.com, ... | Yes |\n\n**Summary:**\n* Total Encryption-Enabled Labels: 3\n* Standard RMS: 1\n* User-Defined: 1\n* Double Key Encryption (DKE): 1\n\n\n","TestStatus":"Passed","TestTags":null},{"TestImpact":"Low","TestRisk":"High","TestSkipped":"","TestAppliesTo":null,"TestPillar":"Data","TestCategory":"Information Protection","TestDescription":"When auto-labeling policies are left in simulation mode, you're not realizing the protection from labeling that data. As a result, users and services can't take additional protective measures to safeguard the identified sensitive data. For example, users won't see in their Office apps that a file is labeled Highly Confidential. Data loss prevention rules might use sensitivity labels to prevent sharing with external users, and other risky actions. Labeled data also provides an additional layer of protection when you use Microsoft 365 Copilot.\n\nTo ensure sensitive information is automatically labeled, turn on at least one auto-labeling policy. Turning on auto-labeling policies after simulation testing puts protective measures into effect and starts reducing risk.\n\n**Remediation action**\n\n- [How to configure auto-labeling policies for SharePoint, OneDrive, and Exchange](https://learn.microsoft.com/purview/apply-sensitivity-label-automatically?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci#how-to-configure-auto-labeling-policies-for-sharepoint-onedrive-and-exchange)\n","TestTitle":"Auto-labeling enforcement mode enabled","SkippedReason":null,"TestId":"35020","TestImplementationCost":"Low","TestMinimumLicense":["EXCHANGE_S_ENTERPRISE"],"TestSfiPillar":"Protect tenants and production systems","TestResult":"\n❌ No auto-labeling policies are in enforcement mode. All policies are either disabled or in simulation mode.\n\n\n\n### Summary:\n\n- **Total Policies in Enforcement Mode:** 0\n- **Total Policies in Simulation Mode:** 2\n- **Total Policies Disabled:** 0\n- **Workloads Covered by Enforcement Policies:**\n - **Exchange/Outlook:** No\n - **SharePoint:** No\n - **OneDrive:** No\n - **Teams:** No\n - **Power BI:** No\n\n\n","TestStatus":"Failed","TestTags":null},{"TestImplementationCost":"High","TestPillar":"Identity","TestCategory":"Application management","SkippedReason":null,"TestImpact":"Medium","TestAppliesTo":["Identity"],"TestSfiPillar":"Protect tenants and isolate production systems","TestSkipped":"","TestMinimumLicense":"Free","TestTags":["Identity"],"TestTitle":"Outbound cross-tenant access settings are configured","TestRisk":"High","TestResult":"\nTenant has a default cross-tenant access setting outbound policy with unrestricted access.\n## [Outbound access settings - Default settings](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/OutboundAccessSettings.ReactView/isDefault~/true/name//id/)\n### B2B Collaboration\nUsers and groups\n- Access status: allowed\n- Applies to: All users\n\nExternal applications\n- Access status: allowed\n- Applies to: Selected external applications (1 applications)\n\n### B2B Direct Connect\nUsers and groups\n- Access status: allowed\n- Applies to: All users\n\nExternal applications\n- Access status: allowed\n- Applies to: All external applications\n\n\n","TestStatus":"Failed","TestDescription":"Allowing unrestricted external collaboration with unverified organizations can increase the risk surface area of the tenant because it allows guest accounts that might not have proper security controls. Threat actors can attempt to gain access by compromising identities in these loosely governed external tenants. Once granted guest access, they can then use legitimate collaboration pathways to infiltrate resources in your tenant and attempt to gain sensitive information. Threat actors can also exploit misconfigured permissions to escalate privileges and try different types of attacks.\n\nWithout vetting the security of organizations you collaborate with, malicious external accounts can persist undetected, exfiltrate confidential data, and inject malicious payloads. This type of exposure can weaken organizational control and enable cross-tenant attacks that bypass traditional perimeter defenses and undermine both data integrity and operational resilience. Cross-tenant settings for outbound access in Microsoft Entra provide the ability to block collaboration with unknown organizations by default, reducing the attack surface.\n\n**Remediation action**\n\n- [Cross-tenant access overview](https://learn.microsoft.com/entra/external-id/cross-tenant-access-overview?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci)\n- [Configure cross-tenant access settings](https://learn.microsoft.com/entra/external-id/cross-tenant-access-settings-b2b-collaboration?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci#configure-default-settings)\n- [Modify outbound access settings](https://learn.microsoft.com/entra/external-id/cross-tenant-access-settings-b2b-collaboration?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci)\n","TestId":"21790"},{"TestImplementationCost":"Low","TestPillar":"Identity","TestCategory":"Privileged access","SkippedReason":null,"TestImpact":"Low","TestAppliesTo":null,"TestSfiPillar":"Protect engineering systems","TestSkipped":"","TestMinimumLicense":"P1","TestTags":null,"TestTitle":"Maximum number of Global Administrators doesn't exceed eight users","TestRisk":"Low","TestResult":"\nMaximum number of Global Administrators exceeds eight users/service principals.\n\n\n## Global Administrators\n\n### Total number of Global Administrators: 25\n\n| Display Name | Object Type | User Principal Name |\n| :----------- | :---------- | :------------------ |\n| [Jules Bailey](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/AdministrativeRole/userId/0145d508-50fd-4f86-a47a-bf1c043c8358) | User | jules@contoso.com |\n| [Jamie Rodriguez](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/AdministrativeRole/userId/0b37813c-ae19-4399-982f-16587f17f9c0) | User | jamie@contoso.com |\n| [Ellis Cooper](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/AdministrativeRole/userId/1433571b-3d7c-4a56-a9cc-67580848bc73) | User | ellis@contoso.com |\n| [Cameron Anderson](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/AdministrativeRole/userId/1ce4078f-f795-4baf-aa55-1fdfcc2ebfe6) | User | cameron@contoso.com |\n| [Taylor Brown](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/AdministrativeRole/userId/2072badc-3cf0-4e84-b4c2-f9c065c46165) | User | taylor@contoso.com |\n| [Dakota Lee](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/AdministrativeRole/userId/210d3e96-015f-462d-b6d6-81e6023263df) | User | guest-user_external.com#EXT#@contoso.com |\n| [Custom-App-Test](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/ApplicationMenuBlade/~/Overview/appId/ddb4f0e6-8018-4359-96c1-7473704bde43) | Service Principal | N/A |\n| [Dakota Lee Test](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/AdministrativeRole/userId/43482f27-d1af-420f-84ba-e9148a700f45) | User | dakota-test@contoso.com |\n| [Ash Williams](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/AdministrativeRole/userId/513f3db2-044c-41be-af14-431bf88a2b3e) | User | ash@contoso.com |\n| [Sage Bennett](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/AdministrativeRole/userId/518ce209-faf4-4717-add9-7129a669fa11) | User | sage@contoso.com |\n| [Morgan Wilson](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/AdministrativeRole/userId/5655cf54-34bc-4f36-bb74-44da35547975) | User | morgan@contoso.com |\n| [Charlie Lewis](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/AdministrativeRole/userId/5b0ec3ff-cea1-4eb9-8530-f2a66e5bec0a) | User | charlie@contoso.com |\n| [Phoenix Gray](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/AdministrativeRole/userId/7094fb23-003a-4f81-9796-5daeaa603003) | User | phoenix@contoso.com |\n| [Peyton Clark](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/AdministrativeRole/userId/7e92f268-bb12-469a-a869-210d596d4c1f) | User | peyton@contoso.com |\n| [Finley Robinson](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/AdministrativeRole/userId/990fd38a-c516-4e3f-82e4-d458a1ab0f91) | User | finley.robinson@contoso.com |\n| [Avery Brooks](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/AdministrativeRole/userId/a85798bd-652b-4eb9-ba90-3ee882df0179) | User | avery.brooks@contoso.com |\n| [Reese Harris](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/AdministrativeRole/userId/babe04c9-8340-4329-a727-a8cee0cd2b1a) | User | reese@contoso.com |\n| [Jordan Smith](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/AdministrativeRole/userId/bfaeba1e-1357-47de-9557-529caa103d5d) | User | jordan@contoso.com |\n| [Hayden Scott](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/AdministrativeRole/userId/c0b65b13-37b1-4081-bcfc-14844159b4a5) | User | hayden@contoso.com |\n| [contoso-tenant-devops-7576c63d-bc90-4ae4-9f1c-0d959fb520db](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/ApplicationMenuBlade/~/Overview/appId/e876f7cb-13f3-48a4-8329-66d7b1fa33fb) | Service Principal | N/A |\n| [Quinn Garcia](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/AdministrativeRole/userId/ceef37b7-c865-48fb-80c9-4def11201854) | User | quinn@contoso.com |\n| [Mailbox Migration Account](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/ApplicationMenuBlade/~/Overview/appId/b650c3c1-3395-40bb-8471-2a6a8b76d8a9) | Service Principal | N/A |\n| [Drew Mitchell](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/AdministrativeRole/userId/df02402a-e291-42cc-b449-79366daa2a40) | User | drew@contoso.com |\n| [Alex Johnson](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/AdministrativeRole/userId/e436ca15-3a39-4dcc-819e-7dbb246cd46b) | User | alex@contoso.onmicrosoft.com |\n| [Avery Thomas](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/AdministrativeRole/userId/f431700c-6d81-45b8-8f8d-581a8aa7cda6) | User | avery@contoso.com |\n\n\n\n","TestStatus":"Failed","TestDescription":"An excessive number of Global Administrator accounts creates an expanded attack surface that threat actors can exploit through various initial access vectors. Each extra privileged account represents a potential entry point for threat actors. An excess of Global Administrator accounts undermines the principle of least privilege. Microsoft recommends that organizations have no more than eight Global Administrators.\n\n**Remediation action**\n\n- [Follow best practices for Microsoft Entra roles](https://learn.microsoft.com/entra/identity/role-based-access-control/best-practices?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci)\n","TestId":"21812"},{"TestImplementationCost":"Low","TestPillar":"Devices","TestCategory":"Tenant","SkippedReason":null,"TestImpact":"Medium","TestAppliesTo":null,"TestSfiPillar":"Protect tenants and isolate production systems","TestSkipped":"","TestMinimumLicense":"Intune","TestTags":null,"TestTitle":"Compliance policy assignment for Android Enterprise Fully managed device is configured and assigned","TestRisk":"High","TestResult":"\nAt least one compliance policy for Android Enterprise Fully managed devices exists and is assigned.\n\n\n## Compliance policy assignment for Android Enterprise Fully managed device is configured and assigned\n\n| Policy Name | Status | Assignment |\n| :---------- | :----- | :--------- |\n| [My android enterprise policy](https://intune.microsoft.com/#view/Microsoft_Intune_DeviceSettings/DevicesComplianceMenu/~/policies) | ✅ Assigned | **Included:** All Users, **Excluded:** testPIM |\n\n\n","TestStatus":"Passed","TestDescription":"If compliance policies aren't assigned to fully managed Android Enterprise devices in Intune, threat actors can exploit noncompliant endpoints to gain unauthorized access to corporate resources, bypass security controls, and persist in the environment. Without enforced compliance, devices can lack critical security configurations such as passcode requirements, data storage encryption, and OS version controls. These gaps increase the risk of data leakage, privilege escalation, and lateral movement. Inconsistent device compliance weakens the organization’s security posture and makes it harder to detect and remediate threats before significant damage occurs.\n\nEnforcing compliance policies ensures Android Enterprise devices meet core security requirements and supports Zero Trust by validating device health and reducing exposure to misconfigured or unmanaged endpoints.\n\n**Remediation action**\n\nCreate and assign Intune compliance policies to fully managed and corporate-owned Android Enterprise devices to enforce organizational standards for secure access and management: \n- [Create a compliance policy in Microsoft Intune](https://learn.microsoft.com/intune/intune-service/protect/create-compliance-policy?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci#create-the-policy)\n- [Review the Android Enterprise compliance settings you can manage with Intune](https://learn.microsoft.com/intune/intune-service/protect/compliance-policy-create-android-for-work?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci)\n","TestId":"24545"},{"TestImpact":"High","TestRisk":"High","TestSkipped":"","TestAppliesTo":null,"TestPillar":"Data","TestCategory":"Information Protection","TestDescription":"The policy setting **Require users to apply a label** ensures a sensitivity label must be applied before users can save files and send emails or meeting invites, create new groups or sites, and use Power BI content. This setting also prevents users from completely removing a sensitivity label. Unlabeled items create security and compliance risks. For example, threat actors can exfiltrate sensitive data that could be prevented by protection solutions that trigger based on label detection.\n\n**Remediation action**\n\n- [Publish sensitivity labels by creating a label policy](https://learn.microsoft.com/purview/create-sensitivity-labels?tabs=modern-label-scheme&wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci#publish-sensitivity-labels-by-creating-a-label-policy)\n- [Require users to apply a label to their email and documents](https://learn.microsoft.com/purview/sensitivity-labels-office-apps?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci#require-users-to-apply-a-label-to-their-email-and-documents)\n","TestTitle":"Mandatory labeling enabled for sensitivity labels","SkippedReason":null,"TestId":"35016","TestImplementationCost":"Medium","TestMinimumLicense":["RMS_S_PREMIUM"],"TestSfiPillar":"Protect tenants and production systems","TestResult":"\n✅ Mandatory labeling is configured and enforced through at least one active sensitivity label policy across one or more workloads (Outlook, Teams/OneDrive, SharePoint/Microsoft 365 Groups, or Power BI).\n\n\n\n### [Enabled label policies](https://purview.microsoft.com/informationprotection/labelpolicies)\n| Policy name | Email | Files/Collab | Sites/Groups | Power BI | Email override | Scope | Labels |\n| :--- | :--- | :--- | :--- | :--- | :--- | :--- | :--- |\n| 35035-Test-Policy | ✅ | ❌ | ❌ | ❌ | No | User/Group-scoped | 1 |\n| Test Policy | ❌ | ✅ | ❌ | ✅ | Yes | User/Group-scoped | 1 |\n| true event | ❌ | ❌ | ❌ | ❌ | Yes | Global | 1 |\n| userpolicy | ❌ | ❌ | ❌ | ❌ | Yes | User/Group-scoped | 1 |\n| peyton | ✅ | ✅ | ❌ | ✅ | No | Global | 1 |\n| test-policy-35012 | ❌ | ❌ | ❌ | ❌ | Yes | Global | 1 |\n\n\n### Summary\n| Metric | Count |\n| :--- | :--- |\n| Total enabled label policies | 6 |\n| Total enabled label policies with mandatory labeling | 3 |\n| Email mandatory labeling | 2 |\n| File/collaboration mandatory labeling | 2 |\n| Site/group mandatory labeling | 0 |\n| Power BI mandatory labeling | 2 |\n\n","TestStatus":"Passed","TestTags":null},{"TestImpact":"High","TestRisk":"High","TestSkipped":"","TestAppliesTo":null,"TestPillar":"Data","TestCategory":"Rights Management Service (RMS)","TestDescription":"Internal RMS licensing allows users and services in the organization to license protected content for internal distribution and sharing. It's enabled automatically when Azure RMS is activated. If disabled, users can't collaborate on encrypted emails and files internally, and legal holds, eDiscovery, and data recovery operations can't access encrypted content.\n\n**Remediation action**\n\n- [Set up Message Encryption](https://learn.microsoft.com/purview/set-up-new-message-encryption-capabilities?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci)\n","TestTitle":"Internal RMS Licensing Enabled","SkippedReason":null,"TestId":"35025","TestImplementationCost":"Low","TestMinimumLicense":["RMS_S_PREMIUM"],"TestSfiPillar":"Protect tenants and production systems","TestResult":"\n✅ Internal RMS licensing is enabled, allowing internal users to license and share protected content within the organization.\n\n**[Internal RMS Licensing Status](https://purview.microsoft.com/settings/encryption)**\n| Setting | Status |\n| :--- | :--- |\n| InternalLicensingEnabled | True |\n| ExternalLicensingEnabled | True |\n| AzureRMSLicensingEnabled | True |\n| LicensingLocation | https://f34ade14-8c5d-483e-b19e-d6ae7663a26f.rms.ap.aadrm.com/_wmcs/licensing |\n\n**Summary:**\n* Internal Licensing Configuration: ✅ Enabled\n* Licensing Endpoints: ✅ Configured\n\n\n","TestStatus":"Passed","TestTags":null},{"TestImplementationCost":"Low","TestPillar":"Identity","TestCategory":"Access control","SkippedReason":null,"TestImpact":"Low","TestAppliesTo":["Identity"],"TestSfiPillar":"Protect tenants and isolate production systems","TestSkipped":"","TestMinimumLicense":"Free","TestTags":["Identity"],"TestTitle":"App Instance Property Lock is configured for all multitenant applications","TestRisk":"High","TestResult":"\nFound multi-tenant apps without app instance property lock configured.\n\n\n## Multi-tenant applications and their App Instance Property Lock setting\n\n\n| Application | Application ID | App Instance Property Lock configured |\n| :---------- | :------------- | :------------------------------------ |\n| [AWS Account](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/ApplicationMenuBlade/~/Authentication/appId/2e311a1d-f5c0-41c6-b866-77af3289871e/isMSAApp~/false) | 2e311a1d-f5c0-41c6-b866-77af3289871e | False |\n| [Adatum Demo App](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/ApplicationMenuBlade/~/Authentication/appId/d2934d2a-3fbc-44a1-bda0-13e8d8a73b15/isMSAApp~/false) | d2934d2a-3fbc-44a1-bda0-13e8d8a73b15 | False |\n| [EAM Provider](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/ApplicationMenuBlade/~/Authentication/appId/f8642471-b7d7-4432-9527-776071e69b8b/isMSAApp~/false) | f8642471-b7d7-4432-9527-776071e69b8b | True |\n| [ExtProperties](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/ApplicationMenuBlade/~/Authentication/appId/61a54643-d4b6-471d-bd7c-a55586155dfc/isMSAApp~/false) | 61a54643-d4b6-471d-bd7c-a55586155dfc | False |\n| [Graph Filter](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/ApplicationMenuBlade/~/Authentication/appId/c94b2f6c-f4c2-4ab3-8d1a-6971b2c7e975/isMSAApp~/false) | c94b2f6c-f4c2-4ab3-8d1a-6971b2c7e975 | False |\n| [My Properties Bag](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/ApplicationMenuBlade/~/Authentication/appId/303b4699-5b62-451c-b951-7e10b01d9b6d/isMSAApp~/false) | 303b4699-5b62-451c-b951-7e10b01d9b6d | False |\n| [Tenant Extension Properties App](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/ApplicationMenuBlade/~/Authentication/appId/7db77c2b-30c1-4379-838f-8767c1e0d619/isMSAApp~/false) | 7db77c2b-30c1-4379-838f-8767c1e0d619 | False |\n| [Tenant Extension Properties App](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/ApplicationMenuBlade/~/Authentication/appId/271b9db4-6e96-430c-808f-973a776adeaf/isMSAApp~/false) | 271b9db4-6e96-430c-808f-973a776adeaf | False |\n| [Zero Trust Assessment](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/ApplicationMenuBlade/~/Authentication/appId/e7dfcbb6-fe86-44a2-b512-8d361dcc3d30/isMSAApp~/false) | e7dfcbb6-fe86-44a2-b512-8d361dcc3d30 | True |\n| [da-typespec-todo-aad](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/ApplicationMenuBlade/~/Authentication/appId/9358444a-41ec-4a93-915a-4970b3f33738/isMSAApp~/false) | 9358444a-41ec-4a93-915a-4970b3f33738 | False |\n| [graph-developer-proxy-samples](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/ApplicationMenuBlade/~/Authentication/appId/3658d9e9-dc87-4345-b59b-184febcf6781/isMSAApp~/false) | 3658d9e9-dc87-4345-b59b-184febcf6781 | False |\n| [idpowerelectron](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/ApplicationMenuBlade/~/Authentication/appId/909fff82-5b0a-4ce5-b66d-db58ee1a925d/isMSAApp~/false) | 909fff82-5b0a-4ce5-b66d-db58ee1a925d | True |\n| [test-mta](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/ApplicationMenuBlade/~/Authentication/appId/5ebc726d-e583-4822-b111-95ee05503c7e/isMSAApp~/false) | 5ebc726d-e583-4822-b111-95ee05503c7e | True |\n| [test1](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/ApplicationMenuBlade/~/Authentication/appId/8d0c8cec-8d54-414b-abfd-7418b8d0bfa0/isMSAApp~/false) | 8d0c8cec-8d54-414b-abfd-7418b8d0bfa0 | True |\n\n\n\n","TestStatus":"Failed","TestDescription":"App instance property lock prevents changes to sensitive properties of a multitenant application after the application is provisioned in another tenant. Without a lock, critical properties such as application credentials can be maliciously or unintentionally modified, causing disruptions, increased risk, unauthorized access, or privilege escalations.\n\n**Remediation action**\nEnable the app instance property lock for all multitenant applications and specify the properties to lock.\n- [Configure an app instance lock](https://learn.microsoft.com/entra/identity-platform/howto-configure-app-instance-property-locks?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci#configure-an-app-instance-lock)\n","TestId":"21777"},{"TestImplementationCost":"Medium","TestPillar":"Identity","TestCategory":"Application management","SkippedReason":null,"TestImpact":"Low","TestAppliesTo":null,"TestSfiPillar":"Protect engineering systems","TestSkipped":"","TestMinimumLicense":"P1","TestTags":null,"TestTitle":"Workload Identities are not assigned privileged roles","TestRisk":"High","TestResult":"\n**Found workload identities assigned to privileged roles.**\n| Service Principal Name | Privileged Role | Assignment Type |\n| :--- | :--- | :--- |\n| [Custom-App-Test](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/Overview/objectId/38415a71-b77b-44d5-a276-539faabe0de7/appId/ddb4f0e6-8018-4359-96c1-7473704bde43/preferredSingleSignOnMode~/null/servicePrincipalType/Application/fromNav/) | Global Administrator | Permanent |\n| [contoso-tenant-devops-7576c63d-bc90-4ae4-9f1c-0d959fb520db](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/Overview/objectId/c5632968-35cd-445d-926e-16e0afc9160e/appId/e876f7cb-13f3-48a4-8329-66d7b1fa33fb/preferredSingleSignOnMode~/null/servicePrincipalType/Application/fromNav/) | Global Administrator | Permanent |\n| [Mailbox Migration Account](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/Overview/objectId/d22f071d-e8d3-41fc-a516-b29753cdd1f6/appId/b650c3c1-3395-40bb-8471-2a6a8b76d8a9/preferredSingleSignOnMode~/null/servicePrincipalType/Application/fromNav/) | Application Administrator | Permanent |\n| [Mailbox Migration Account](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/Overview/objectId/d22f071d-e8d3-41fc-a516-b29753cdd1f6/appId/b650c3c1-3395-40bb-8471-2a6a8b76d8a9/preferredSingleSignOnMode~/null/servicePrincipalType/Application/fromNav/) | Global Administrator | Permanent |\n\n\n**Recommendation:** Review and remove privileged role assignments from workload identities unless absolutely necessary. Use least-privilege principles and consider alternative approaches like managed identities with specific API permissions instead of directory roles.\n\n\n","TestStatus":"Failed","TestDescription":"If administrators assign privileged roles to workload identities, such as service principals or managed identities, the tenant can be exposed to significant risk if those identities are compromised. Threat actors who gain access to a privileged workload identity can perform reconnaissance to enumerate resources, escalate privileges, and manipulate or exfiltrate sensitive data. The attack chain typically begins with credential theft or abuse of a vulnerable application. Next step is privilege escalation through the assigned role, lateral movement across cloud resources, and finally persistence via other role assignments or credential updates. Workload identities are often used in automation and might not be monitored as closely as user accounts. Compromise can then go undetected, allowing threat actors to maintain access and control over critical resources. Workload identities aren't subject to user-centric protections like MFA, making least-privilege assignment and regular review essential. \n\n**Remediation action**\n- [Review and remove privileged roles assignments](https://learn.microsoft.com/entra/id-governance/privileged-identity-management/pim-resource-roles-assign-roles?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci#update-or-remove-an-existing-role-assignment).\n- [Follow the best practices for workload identities](https://learn.microsoft.com/entra/workload-id/workload-identities-overview?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci#key-scenarios).\n- [Learn about privileged roles and permissions in Microsoft Entra ID](https://learn.microsoft.com/entra/identity/role-based-access-control/privileged-roles-permissions?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci)\n","TestId":21836},{"TestImplementationCost":"","TestPillar":"Infrastructure","TestCategory":"Implement security best practices","SkippedReason":null,"TestImpact":"","TestAppliesTo":null,"TestSfiPillar":"Protect tenants and isolate production systems","TestSkipped":"","TestMinimumLicense":"N/A","TestTags":null,"TestTitle":"A maximum of 3 owners should be designated for subscriptions","TestRisk":"High","TestResult":"A maximum of 3 owners should be designated for subscriptions\n\n| Subscription | Affected resource | Status | Azure portal |\n| :----------- | :---------------- | :----- | :----------- |\n| [Visual Studio Enterprise Subscription](https://portal.azure.com/#resource/subscriptions/54d3ea01-5a07-45d0-8d69-e5f5b0b20098) | [54d3ea01-5a07-45d0-8d69-e5f5b0b20098](https://portal.azure.com/#resource/subscriptions/54d3ea01-5a07-45d0-8d69-e5f5b0b20098) | ❌ | [View recommendation](https://portal.azure.com/#blade/Microsoft_Azure_Security/RecommendationsBlade/assessmentKey/6f90a6d6-d4d6-0794-0ec1-98fa77878c2e/resourceId/%2fsubscriptions%2f54d3ea01-5a07-45d0-8d69-e5f5b0b20098) |\n","TestStatus":"Failed","TestDescription":"To reduce the potential for breaches by compromised owner accounts, we recommend limiting the number of owner accounts to a maximum of 3\n\n**Remediation action**\n\nTo remove owner permissions from user accounts on your subscription:
Click a subscription from the list of subscriptions below or click 'Take action' if you are coming from a specific subscription.
The Access control (IAM) page opens.
1. Click the Role assignments tab and set the 'Role' filter to 'Owner'.
2. Select the owners you want to remove.
3. Click Remove.","TestId":"6f90a6d6-d4d6-0794-0ec1-98fa77878c2e"},{"TestImplementationCost":"Medium","TestPillar":"Identity","TestCategory":"Monitoring","SkippedReason":null,"TestImpact":"Low","TestAppliesTo":null,"TestSfiPillar":"Monitor and detect cyberthreats","TestSkipped":"","TestMinimumLicense":null,"TestTags":null,"TestTitle":"Diagnostic settings are configured for all Microsoft Entra logs","TestRisk":"High","TestResult":"\n❌ Some Entra Logs are not configured with Diagnostic settings.\n\n\n\n## [Microsoft Entra Log Archiving](https://portal.azure.com/#view/Microsoft_AAD_IAM/DiagnosticSettingsMenuBlade)\n\n| Log name | Diagnostic settings |\n| :--- | :--- |\n| ADFSSignInLogs | none |\n| AuditLogs | none |\n| EnrichedOffice365AuditLogs | none |\n| ManagedIdentitySignInLogs | none |\n| MicrosoftGraphActivityLogs | none |\n| NetworkAccessTrafficLogs | none |\n| NonInteractiveUserSignInLogs | none |\n| ProvisioningLogs | none |\n| RemoteNetworkHealthLogs | none |\n| RiskyServicePrincipals | none |\n| RiskyUsers | none |\n| ServicePrincipalRiskEvents | none |\n| ServicePrincipalSignInLogs | none |\n| SignInLogs | none |\n| UserRiskEvents | none |\n\n\n\n","TestStatus":"Failed","TestDescription":"The activity logs and reports in Microsoft Entra can help detect unauthorized access attempts or identify when tenant configuration changes. When logs are archived or integrated with Security Information and Event Management (SIEM) tools, security teams can implement powerful monitoring and detection security controls, proactive threat hunting, and incident response processes. The logs and monitoring features can be used to assess tenant health and provide evidence for compliance and audits.\n\nIf logs aren't regularly archived or sent to a SIEM tool for querying, it's challenging to investigate sign-in issues. The absence of historical logs means that security teams might miss patterns of failed sign-in attempts, unusual activity, and other indicators of compromise. This lack of visibility can prevent the timely detection of breaches, allowing attackers to maintain undetected access for extended periods.\n\n**Remediation action**\n\n- [Configure Microsoft Entra diagnostic settings](https://learn.microsoft.com/entra/identity/monitoring-health/howto-configure-diagnostic-settings?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci)\n- [Integrate Microsoft Entra logs with Azure Monitor logs](https://learn.microsoft.com/entra/identity/monitoring-health/howto-integrate-activity-logs-with-azure-monitor-logs?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci)\n- [Stream Microsoft Entra logs to an event hub](https://learn.microsoft.com/entra/identity/monitoring-health/howto-stream-logs-to-event-hub?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci)\n","TestId":"21860"},{"TestImplementationCost":"High","TestPillar":"Identity","TestCategory":"Application management","SkippedReason":null,"TestImpact":"Low","TestAppliesTo":["Identity"],"TestSfiPillar":"Protect engineering systems","TestSkipped":"","TestMinimumLicense":"P1","TestTags":["Identity"],"TestTitle":"Highly privileged roles are only activated in a PAW/SAW device","TestRisk":"High","TestResult":"\nNo Conditional Access policies found that restrict privileged roles to PAW device.\n\n**❌ Found 0 policy(s) with compliant device control targeting all privileged roles**\n\n\n**❌ Found 0 policy(s) with PAW/SAW device filter targeting all privileged roles**\n\n\n","TestStatus":"Failed","TestDescription":"If privileged role activations aren't restricted to dedicated Privileged Access Workstations (PAWs), threat actors can exploit compromised endpoint devices to perform privileged escalation attacks from unmanaged or noncompliant workstations. Standard productivity workstations often contain attack vectors such as unrestricted web browsing, email clients vulnerable to phishing, and locally installed applications with potential vulnerabilities. When administrators activated privileged roles from these workstations, threat actors who gain initial access through malware, browser exploits, or social engineering can then use the locally cached privileged credentials or hijack existing authenticated sessions to escalate their privileges. Privileged role activations grant extensive administrative rights across Microsoft Entra ID and connected services, so attackers can create new administrative accounts, modify security policies, access sensitive data across all organizational resources, and deploy malware or backdoors throughout the environment to establish persistent access. This lateral movement from a compromised endpoint to privileged cloud resources represents a critical attack path that bypasses many traditional security controls. The privileged access appears legitimate when originating from an authenticated administrator's session.\n\nIf this check passes, your tenant has a Conditional Access policy that restricts privileged role access to PAW devices, but it isn't the only control required to fully enable a PAW solution. You also need to configure an Intune device configuration and compliance policy and a device filter.\n\n**Remediation action**\n\n- [Deploy a privileged access workstation solution](https://learn.microsoft.com/security/privileged-access-workstations/privileged-access-deployment?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci)\n - Provides guidance for configuring the Conditional Access and Intune device configuration and compliance policies.\n- [Configure device filters in Conditional Access to restrict privileged access](https://learn.microsoft.com/entra/identity/conditional-access/concept-condition-filters-for-devices?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci)\n","TestId":"21830"},{"TestImplementationCost":"Low","TestPillar":"Devices","TestCategory":"Tenant","SkippedReason":null,"TestImpact":"Low","TestAppliesTo":null,"TestSfiPillar":"Protect tenants and isolate production systems","TestSkipped":"","TestMinimumLicense":"Intune","TestTags":null,"TestTitle":"Device Clean-up Rule is Created","TestRisk":"Low","TestResult":"\nNo device clean-up rule exists.\n\n\n\n","TestStatus":"Failed","TestDescription":"If device cleanup rules aren't configured in Intune, stale or inactive devices can remain visible in the tenant indefinitely. This leads to cluttered device lists, inaccurate reporting, and reduced visibility into the active device landscape. Unused devices might retain access credentials or tokens, increasing the risk of unauthorized access or misinformed policy decisions. \n\nDevice cleanup rules automatically hide inactive devices from admin views and reports, improving tenant hygiene and reducing administrative burden. This supports Zero Trust by maintaining an accurate and trustworthy device inventory while preserving historical data for audit or investigation.\n\n**Remediation action**\n\nConfigure Intune device cleanup rules to automatically hide inactive devices from the tenant: \n- [Create a device cleanup rule](https://learn.microsoft.com/intune/intune-service/fundamentals/device-cleanup-rules?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci#how-to-create-a-device-cleanup-rule)\n\nFor more information, see: \n- [Using Intune device cleanup rules](https://techcommunity.microsoft.com/blog/devicemanagementmicrosoft/using-intune-device-cleanup-rules-updated-version/3760854) *on the Microsoft Tech Community blog*\n","TestId":"24802"},{"TestImpact":"Low","TestRisk":"High","TestSkipped":"","TestAppliesTo":null,"TestPillar":"Data","TestCategory":"Information Protection","TestDescription":"When auto-labeling for SharePoint and OneDrive isn't set up, files uploaded without sensitivity labels might not be visible to Data Loss Protection (DLP) policies that rely on labels. As a result, those files can move through the environment with fewer safeguards, which can raise the risk of inappropriate sharing or access.\n \nFor example, enabling at least one auto-labeling policy in enforcement mode for SharePoint and OneDrive helps classify sensitive files when users create or edit them. Auto-labeling classification supports downstream protections, such as DLP policies, so they can respond based on the file’s sensitivity and help reduce data exposure risk.\n\n**Remediation action**\n\n- [Apply sensitivity labels automatically for SharePoint and OneDrive](https://learn.microsoft.com/purview/apply-sensitivity-label-automatically?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci)\n","TestTitle":"Auto-Labeling Policies Enabled for SharePoint and OneDrive","SkippedReason":null,"TestId":"35021","TestImplementationCost":"Medium","TestMinimumLicense":["EXCHANGE_S_ENTERPRISE"],"TestSfiPillar":"Protect tenants and production systems","TestResult":"\n❌ 2 auto-labeling policies target SharePoint/OneDrive, but none are enabled and in enforcement mode.\n\n### [Auto-Labeling Policies for SharePoint/OneDrive](https://purview.microsoft.com/informationprotection/autolabeling)\n\n| Policy Name | Description | Enabled | Mode | Workload | Created | Last Modified |\n| :--- | :--- | :---: | :--- | :--- | :--- | :--- |\n| Japan Financial Data | | ✅ | TestWithoutNotifications | Exchange, SharePoint, OneDriveForBusiness, Applications, Azure, AWS | 2026-02-05 | 2026-02-05 |\n| U.S. Patriot Act Enhanced | | ✅ | TestWithoutNotifications | Exchange, SharePoint, OneDriveForBusiness, Applications, Azure, AWS | 2026-02-05 | 2026-02-06 |\n\n### Summary\n\n* **Total Policies Targeting SharePoint/OneDrive:** 2\n* **Policies in Enforcement Mode:** 0\n* **Policies in Simulation Mode:** 2\n* **Policies Disabled:** 0\n* **SharePoint Coverage:** [No]\n* **OneDrive Coverage:** [No]\n\n### Recommendation\n\nEnable at least one auto-labeling policy in enforcement mode for SharePoint and/or OneDrive to automatically classify sensitive files. Visit the [Auto-labeling policies portal](https://purview.microsoft.com/informationprotection/autolabeling) to create or configure policies.\n\n\n","TestStatus":"Failed","TestTags":null},{"TestImplementationCost":"Low","TestPillar":"Devices","TestCategory":"Tenant","SkippedReason":null,"TestImpact":"Medium","TestAppliesTo":null,"TestSfiPillar":"Protect tenants and isolate production systems","TestSkipped":"","TestMinimumLicense":"Intune","TestTags":null,"TestTitle":"Compliance policies protect Windows devices","TestRisk":"High","TestResult":"\n❌ Test 24541 failed due to an unexpected error.\r\n - **Error Message**: Response status code does not indicate success: NotFound (Not Found)..\r\n```\r\n\nException : \n Type : Microsoft.Graph.PowerShell.Authentication.Helpers.HttpResponseException\n Response : StatusCode: 404, ReasonPhrase: 'Not Found', Version: 2.0, Content: System.Net.Http.DecompressionHandler+GZipDecompressedContent, Headers:\n {\n Cache-Control: no-cache\n Vary: Accept-Encoding\n Strict-Transport-Security: max-age=31536000\n request-id: f632d1e1-0368-48a8-8809-88eea06e56f8\n client-request-id: b25c394e-fc7e-4f7b-90f7-88dc2444fd83\n x-ms-ags-diagnostic: {\"ServerInfo\":{\"DataCenter\":\"Australia East\",\"Slice\":\"E\",\"Ring\":\"5\",\"ScaleUnit\":\"001\",\"RoleInstance\":\"SY1PEPF000060EA\"}}\n x-ms-resource-unit: 1\n Date: Mon, 18 May 2026 22:16:57 GMT\n Content-Type: application/json\n }\n TargetSite : \n Name : ThrowTerminatingError\n DeclaringType : [System.Management.Automation.MshCommandRuntime]\n MemberType : Method\n Module : System.Management.Automation.dll\n Message : Response status code does not indicate success: NotFound (Not Found).\n Source : System.Management.Automation\n HResult : -2146233088\n StackTrace : \n at System.Management.Automation.MshCommandRuntime.ThrowTerminatingError(ErrorRecord errorRecord)\nTargetObject : Method: GET, RequestUri: 'https://graph.microsoft.com/v1.0/groups/91732cd1-062d-41ab-991a-8e37e1ac1937?$select=displayName', Version: 2.0, Content: , Headers:\n {\n ConsistencyLevel: eventual\n User-Agent: Mozilla/5.0\n User-Agent: (Macintosh; Darwin 25.5.0 Darwin Kernel Version 25.5.0: Mon Apr 27 20:41:06 PDT 2026; root:xnu-12377.121.6~2/RELEASE_ARM64_T6030; en-AU)\n User-Agent: PowerShell/7.5.2\n User-Agent: Invoke-MgGraphRequest\n FeatureFlag: 00000003\n Cache-Control: no-store, no-cache\n Authorization: Bearer [REDACTED]\n SdkVersion: graph-powershell/2.35.1\n client-request-id: b25c394e-fc7e-4f7b-90f7-88dc2444fd83\n Accept-Encoding: gzip\n Accept-Encoding: deflate\n Accept-Encoding: br\n }\nCategoryInfo : InvalidOperation: (Method: GET, Reques…cept-Encoding: br\n }:HttpRequestMessage) [Invoke-ZtRetry], HttpResponseException\nFullyQualifiedErrorId : InvokeGraphHttpResponseException,Invoke-ZtRetry\nErrorDetails : GET https://graph.microsoft.com/v1.0/groups/91732cd1-062d-41ab-991a-8e37e1ac1937?$select=displayName\n HTTP/2.0 404 Not Found\n Cache-Control: no-cache\n Vary: Accept-Encoding\n Strict-Transport-Security: max-age=31536000\n request-id: f632d1e1-0368-48a8-8809-88eea06e56f8\n client-request-id: b25c394e-fc7e-4f7b-90f7-88dc2444fd83\n x-ms-ags-diagnostic: {\"ServerInfo\":{\"DataCenter\":\"Australia East\",\"Slice\":\"E\",\"Ring\":\"5\",\"ScaleUnit\":\"001\",\"RoleInstance\":\"SY1PEPF000060EA\"}}\n x-ms-resource-unit: 1\n Date: Mon, 18 May 2026 22:16:57 GMT\n Content-Type: application/json\n \n {\"error\":{\"code\":\"Request_ResourceNotFound\",\"message\":\"Resource '91732cd1-062d-41ab-991a-8e37e1ac1937' does not exist or one of its queried reference-property objects are not present.\",\"innerError\":{\"date\":\"2026-05-18T22:16:58\",\"request-id\":\"f632d1e1-0368-48a8-8809-88eea06e56f8\",\"client-request-id\":\"b25c394e-fc7e-4f7b-90f7-88dc2444fd83\"}}}\nInvocationInfo : \n MyCommand : Invoke-ZtRetry\n ScriptLineNumber : 118\n OffsetInLine : 13\n HistoryId : 1\n ScriptName : /Users/manson/GitHub/zerotrustassessment/src/powershell/private/core/Invoke-ZtGraphRequestCache.ps1\n Line : $results = Invoke-ZtRetry -ScriptBlock { Invoke-MgGraphRequest -Method $Method -Uri $Uri -Headers $Headers -OutputType $OutputType } # -Body $Body # Cannot use Body with GET in PS 5.1\n \n Statement : Invoke-ZtRetry -ScriptBlock { Invoke-MgGraphRequest -Method $Method -Uri $Uri -Headers $Headers -OutputType $OutputType }\n PositionMessage : At /Users/manson/GitHub/zerotrustassessment/src/powershell/private/core/Invoke-ZtGraphRequestCache.ps1:118 char:13\n + … $results = Invoke-ZtRetry -ScriptBlock { Invoke-MgGraphRequest -Meth …\n + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n PSScriptRoot : /Users/manson/GitHub/zerotrustassessment/src/powershell/private/core\n PSCommandPath : /Users/manson/GitHub/zerotrustassessment/src/powershell/private/core/Invoke-ZtGraphRequestCache.ps1\n InvocationName : Invoke-ZtRetry\n CommandOrigin : Internal\nScriptStackTrace : at , /Users/manson/GitHub/zerotrustassessment/src/powershell/private/core/Invoke-ZtGraphRequestCache.ps1: line 118\n at Invoke-ZtRetry, /Users/manson/GitHub/zerotrustassessment/src/powershell/private/core/Invoke-ZtRetry.ps1: line 51\n at Invoke-ZtGraphRequestCache, /Users/manson/GitHub/zerotrustassessment/src/powershell/private/core/Invoke-ZtGraphRequestCache.ps1: line 118\n at Invoke-ZtGraphRequest, /Users/manson/GitHub/zerotrustassessment/src/powershell/public/Invoke-ZtGraphRequest.ps1: line 226\n at Get-PolicyAssignmentTarget, /Users/manson/GitHub/zerotrustassessment/src/powershell/private/core/Get-PolicyAssignmentTarget.ps1: line 19\n at Test-Assessment-24541, /Users/manson/GitHub/zerotrustassessment/src/powershell/tests/Test-Assessment.24541.ps1: line 90\n at Invoke-ZtTest, /Users/manson/GitHub/zerotrustassessment/src/powershell/private/tests/Invoke-ZtTest.ps1: line 125\n at , /Users/manson/GitHub/zerotrustassessment/src/powershell/private/tests/Start-ZtTestExecution.ps1: line 106\n at , : line 62\n\n\r\n```\n\n","TestStatus":"Error","TestDescription":"If compliance policies for Windows devices aren't configured and assigned, threat actors can exploit unmanaged or noncompliant endpoints to gain unauthorized access to corporate resources, bypass security controls, and persist within the environment. Without enforced compliance, devices can lack critical security configurations like BitLocker encryption, password requirements, firewall settings, and OS version controls. These gaps increase the risk of data leakage, privilege escalation, and lateral movement. Inconsistent device compliance weakens the organization’s security posture and makes it harder to detect and remediate threats before significant damage occurs.\n\nEnforcing compliance policies ensures Windows devices meet core security requirements and supports Zero Trust by validating device health and reducing exposure to misconfigured endpoints.\n\n**Remediation action**\n\nCreate and assign Intune compliance policies to Windows devices to enforce organizational standards for secure access and management:\n- [Create and assign Intune compliance policies](https://learn.microsoft.com/intune/intune-service/protect/create-compliance-policy?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci#create-the-policy)\n- [Review the Windows compliance settings you can manage with Intune](https://learn.microsoft.com/intune/intune-service/protect/compliance-policy-create-windows?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci)\n","TestId":"24541"},{"TestImplementationCost":"High","TestPillar":"Identity","TestCategory":"Privileged access","SkippedReason":"UnderConstruction","TestImpact":"Low","TestAppliesTo":["Identity"],"TestSfiPillar":"Protect identities and secrets","TestSkipped":"UnderConstruction","TestMinimumLicense":null,"TestTags":["Identity"],"TestTitle":"Directory Sync account credentials haven't been rotated recently","TestRisk":"Low","TestResult":"\nPlanned for future release.\n","TestStatus":"Planned","TestDescription":"...\n\n**Remediation action**\n\n","TestId":"21833"},{"TestImplementationCost":"Low","TestPillar":"Network","TestCategory":"Global Secure Access","SkippedReason":null,"TestImpact":"Low","TestAppliesTo":null,"TestSfiPillar":"Protect networks","TestSkipped":"","TestMinimumLicense":"Entra_Premium_Internet_Access","TestTags":null,"TestTitle":"Web content filtering blocks high-risk categories","TestRisk":"High","TestResult":"\n❌ One or more high-risk web content filtering categories (Criminal activity, Hacking, Illegal software) are not blocked. Configure web content filtering policies to block these Liability categories to protect against security risks and policy violations.\n\n\n## [Web Content Filtering – Category block status](https://entra.microsoft.com/#view/Microsoft_Azure_Network_Access/WebFilteringPolicy.ReactView)\n\n| Category | Enforced by | CA enforced | Status |\n| :------- | :---------- | :---------- | :----- |\n| Criminal activity | None | N/A | ❌ Not blocked |\n| Hacking | None | N/A | ❌ Not blocked |\n| Illegal software | None | N/A | ❌ Not blocked |\n\n\n**Summary:**\n- Total required categories: 3\n- Categories blocked: 0\n- Categories not blocked: 3\n","TestStatus":"Failed","TestDescription":"When high-risk web content filtering categories such as Criminal activity, Hacking, and Illegal software are not blocked, users and devices connected through Global Secure Access remain exposed to dangerous attack vectors and liability risks. Sites categorized as Criminal activity provide guidance on committing illegal acts including fraud, building weapons, and evading detection, and users who access these resources may inadvertently download tools or scripts that threat actors can leverage to establish initial access to the corporate environment. Hacking sites promote unauthorized access techniques, distribute exploit code, and provide tutorials on stealing information and creating malicious software, enabling threat actors who compromise user devices to learn advanced attack methods and escalate their capabilities within the network. Illegal software sites distribute pirated applications, software cracks, and license key generators that frequently contain embedded malware, and users who download from these sources risk executing trojanized installers that establish persistence and enable lateral movement across corporate systems. The absence of blocking for these categories allows users to access content that introduces both security vulnerabilities and legal liability, as downloaded tools may violate software licensing agreements or facilitate unauthorized activities. Organizations that do not enforce blocking of these high-risk Liability categories through their Secure Web Gateway expose themselves to preventable attack vectors while potentially enabling policy violations that create regulatory and legal exposure.\n\n\n**Remediation action**\n\n1. [Configure web content filtering](https://learn.microsoft.com/en-us/entra/global-secure-access/how-to-configure-web-content-filtering) - Create web content filtering policies that block high-risk Liability categories including Criminal activity, Hacking, and Illegal software.\n\n2. [Web content filtering categories reference](https://learn.microsoft.com/en-us/entra/global-secure-access/reference-web-content-filtering-categories) - Review the complete list of available web categories and their descriptions to understand what content is blocked.\n\n3. [Create security profiles](https://learn.microsoft.com/en-us/entra/global-secure-access/how-to-configure-web-content-filtering#create-a-security-profile) - Group filtering policies into security profiles that can be linked to Conditional Access policies for user-aware enforcement.\n\n4. [Enable Internet Access traffic forwarding](https://learn.microsoft.com/en-us/entra/global-secure-access/how-to-manage-internet-access-profile) - Ensure the Internet Access traffic forwarding profile is enabled to route traffic through Global Secure Access for web content filtering to apply.\n\n5. [Link security profiles to Conditional Access](https://learn.microsoft.com/en-us/entra/global-secure-access/how-to-configure-web-content-filtering#create-and-link-conditional-access-policy) - Associate security profiles with Conditional Access policies to enforce web content filtering for targeted users and groups.\n\n","TestId":"27000"},{"TestImpact":"Medium","TestRisk":"High","TestSkipped":"","TestAppliesTo":null,"TestPillar":"Data","TestCategory":"Data Security Posture Management","TestDescription":"Until organizations configure Communication Compliance policies to capture Copilot interactions, they can’t see when users expose sensitive data to AI services. They also can’t tell how people use Copilot with confidential information or spot possible policy violations. As a result, users may unknowingly share customer records, financial data, source code, or trade secrets with AI services.\n\nCommunication Compliance policies that focus on Copilot interactions give organizations clear oversight of AI use while respecting privacy controls. These policies show how users work with sensitive data in AI features and help ensure teams follow data governance and compliance requirements.\n\n**Remediation action**\n\n- [Create and manage Communication Compliance policies](https://learn.microsoft.com/purview/communication-compliance-policies?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci)\n","TestTitle":"Communication compliance monitoring is configured for Microsoft Copilot","SkippedReason":null,"TestId":"35039","TestImplementationCost":"Medium","TestMinimumLicense":["EXCHANGE_S_ENTERPRISE"],"TestSfiPillar":"Protect tenants and production systems","TestResult":"\nCommunication Compliance rules targeting Copilot content are properly configured and enabled.\n\n### Copilot-Targeting Rules\n\n| Rule Name | Associated Policy |\n| :------ | :---- |\n| Copilot Data Protection | Copilot Data Protection |\n| Custom Policy 35040 | Custom Policy 35040 |\n| Microsoft 365 Copilot interactions | Microsoft 365 Copilot interactions |\n| test1 | test1 |\n\n### Enabled Policies\n\n| Policy Name | Enabled | Review Mailbox |\n| :------ | :---- | :---- |\n| Copilot Data Protection | True | SupervisoryReview{3bbbbd4f-cc0a-45ff-b0f5-c6023124c881}@contoso.onmicrosoft.com |\n| Custom Policy 35040 | True | SupervisoryReview{8fb152db-0f94-45f9-b29c-8764f3a5ccef}@contoso.onmicrosoft.com |\n| Microsoft 365 Copilot interactions | True | SupervisoryReview{8ce4a232-c7cf-4712-aee9-f02c9a9cd3e8}@contoso.onmicrosoft.com |\n| test1 | True | SupervisoryReview{7a05811d-28e7-4163-a013-d57c554fca5f}@contoso.onmicrosoft.com |\n\n### Activity Evidence\n\nRecent Copilot Matches (30 days): 0\n\n**Summary:**\n\n Status: ✅ Pass\n\n Total Copilot Rules Found: 4\n\n Enabled Policies with Copilot Rules: 4\n\n**Portal Access:**\n\n [Microsoft Purview Communication Compliance > Policies](https://purview.microsoft.com/communicationcompliance/policies)\n\n\n","TestStatus":"Passed","TestTags":null},{"TestImplementationCost":"","TestPillar":"Infrastructure","TestCategory":"Manage access and permissions","SkippedReason":null,"TestImpact":"","TestAppliesTo":null,"TestSfiPillar":"Protect tenants and isolate production systems","TestSkipped":"","TestMinimumLicense":"N/A","TestTags":null,"TestTitle":"Guest accounts with write permissions on Azure resources should be removed","TestRisk":"High","TestResult":"Guest accounts with write permissions on Azure resources should be removed\n\n| Subscription | Affected resource | Status | Azure portal |\n| :----------- | :---------------- | :----- | :----------- |\n| [Visual Studio Enterprise Subscription](https://portal.azure.com/#resource/subscriptions/54d3ea01-5a07-45d0-8d69-e5f5b0b20098) | [54d3ea01-5a07-45d0-8d69-e5f5b0b20098](https://portal.azure.com/#resource/subscriptions/54d3ea01-5a07-45d0-8d69-e5f5b0b20098) | ✅ | [View recommendation](https://portal.azure.com/#blade/Microsoft_Azure_Security/RecommendationsBlade/assessmentKey/0354476c-a12a-4fcc-a79d-f0ab7ffffdbb/resourceId/%2fsubscriptions%2f54d3ea01-5a07-45d0-8d69-e5f5b0b20098) |\n","TestStatus":"Passed","TestDescription":"Accounts with write permissions that have been provisioned outside of the Azure Active Directory tenant (different domain names), should be removed from your Azure resources.
These guest accounts are not managed to the same standards as enterprise tenant identities.
This makes them potential targets for threat actors looking to find ways to access your data without being noticed.
By removing these accounts, you can reduce the risk of unauthorized data access and potential breaches..
\n\n**Remediation action**\n\nReview the list of guest accounts that require access removal on the Accounts section. Select an account to view its role definitions and locate source scope. If you accept the risk for a specific account, use the exempt capability to exclude it from evaluation.
  1. Go to the Azure portal.
  2. Open Access control (IAM) at a scope, such as management group, subscription, resource group, or resource, where the guest user has a role assignment.
  3. Click the Role assignments tab to view all the role assignments.
  4. In the list of role assignments, add a checkmark next to the guest user with the role assignment you want to remove.
  5. Click Remove. In the remove role assignment message that appears, click Yes.
","TestId":"0354476c-a12a-4fcc-a79d-f0ab7ffffdbb"},{"TestImplementationCost":"Medium","TestPillar":"Identity","TestCategory":"Credential management","SkippedReason":"UnderConstruction","TestImpact":"Medium","TestAppliesTo":["Identity"],"TestSfiPillar":"Protect identities and secrets","TestSkipped":"UnderConstruction","TestMinimumLicense":"P1","TestTags":["Identity"],"TestTitle":"Self-Service Password Reset does not use Q & A","TestRisk":"Medium","TestResult":"\nPlanned for future release.\n\n","TestStatus":"Planned","TestDescription":"Allowing security questions as a self-service password reset (SSPR) method weakens the password reset process because answers are frequently guessable, reused across sites, or discoverable through open-source intelligence (OSINT). Threat actors enumerate or phish users, derive likely responses (family names, schools, and locations), and then trigger password reset flows to bypass stronger methods by exploiting the weaker knowledge-based gate. After they successfully reset a password on an account that isn't protected by multifactor authentication they can: gain valid primary credentials, establish session tokens, and laterally expand by registering more durable authentication methods, add forwarding rules, or exfiltrate sensitive data.\n\nEliminating this method removes a weak link in the password reset process. Some organizations might have specific business reasons for leaving security questions enabled, but this isn't recommended.\n\n**Remediation action**\n\n- [Disable security questions in SSPR policy](https://learn.microsoft.com/entra/identity/authentication/concept-authentication-security-questions?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci)\n- [Select authentication methods and registration options](https://learn.microsoft.com/entra/identity/authentication/tutorial-enable-sspr?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci#select-authentication-methods-and-registration-options)\n","TestId":"22072"},{"TestImpact":"Low","TestRisk":"High","TestSkipped":"NoCompatibleLicenseFound","TestAppliesTo":null,"TestPillar":"Network","TestCategory":"Global Secure Access","TestDescription":"Global Secure Access requires specific Microsoft Entra licenses to function, including Microsoft Entra Internet Access and Microsoft Entra Private Access, both of which require Microsoft Entra ID P1 as a prerequisite. Without valid licenses provisioned in the tenant, administrators can't configure traffic forwarding profiles, security policies, or remote network connections. If you don't assign licenses to users, their traffic doesn't route through Global Secure Access, and remains unprotected by security controls.\n\nWithout this protection:\n\n- Threat actors can bypass web content filtering, threat protection, and Conditional Access policies.\n- Expired or suspended subscriptions can halt the Global Secure Access service, creating security gaps where previously protected traffic flows go unmonitored.\n\n**Remediation action**\n- Review Global Secure Access licensing requirements and purchase appropriate licenses. For more information, see [Licensing overview](https://learn.microsoft.com/entra/global-secure-access/overview-what-is-global-secure-access?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci#licensing-overview).\n- Assign licenses to users through the Microsoft Entra admin center. For more information, see [Assign licenses to users](https://learn.microsoft.com/entra/fundamentals/license-users-groups?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci).\n- Use group-based licensing for easier management at scale. For more information, see [Group-based licensing](https://learn.microsoft.com/entra/fundamentals/concept-group-based-licensing?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci).\n- Monitor license utilization through Microsoft 365 admin center. For more information, see [Microsoft 365 admin center](https://admin.microsoft.com/Adminportal/Home#/licenses).\n- Review Microsoft Entra Suite as an alternative that includes both Internet Access and Private Access. For more information, see [What's new in Microsoft Entra](https://learn.microsoft.com/entra/fundamentals/whats-new?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci#microsoft-entra-suite).\n","TestTitle":"Global Secure Access licenses are available in the tenant and assigned to users","SkippedReason":"This test requires one of the following licenses: (\"Entra_Premium_Internet_Access\") OR (\"Entra_Premium_Private_Access\"). Please ensure your tenant has the appropriate licenses to run this test. See [Licensing & Service Plans](https://learn.microsoft.com/entra/identity/users/licensing-service-plan-reference)","TestId":"25375","TestImplementationCost":"Low","TestMinimumLicense":["Entra_Premium_Internet_Access","Entra_Premium_Private_Access"],"TestSfiPillar":"Protect networks","TestResult":"\nSkipped. This test requires one of the following licenses: (\"Entra_Premium_Internet_Access\") OR (\"Entra_Premium_Private_Access\"). Please ensure your tenant has the appropriate licenses to run this test. See [Licensing & Service Plans](https://learn.microsoft.com/entra/identity/users/licensing-service-plan-reference)\n\n","TestStatus":"Skipped","TestTags":null},{"TestImplementationCost":"Low","TestPillar":"Devices","TestCategory":"Device","SkippedReason":null,"TestImpact":"Medium","TestAppliesTo":null,"TestSfiPillar":"Protect networks","TestSkipped":"","TestMinimumLicense":"Intune","TestTags":null,"TestTitle":"Windows Firewall Policy is Created and Assigned","TestRisk":"High","TestResult":"\nAt least one Windows Firewall policy is created and assigned to a group.\n\n\n## Windows Firewall Configuration Policies\n\n| Policy Name | Status | Assignment Target |\n| :---------- | :----- | :---------------- |\n| [WF_Policy](https://intune.microsoft.com/#view/Microsoft_Intune_Workflows/SecurityManagementMenu/~/firewall) | ✅ Assigned | **Included:** WFgroup, My Test Device Group |\n| [WF_Policy2](https://intune.microsoft.com/#view/Microsoft_Intune_Workflows/SecurityManagementMenu/~/firewall) | ❌ Not assigned | None |\n| [WF_Policy3](https://intune.microsoft.com/#view/Microsoft_Intune_Workflows/SecurityManagementMenu/~/firewall) | ✅ Assigned | **Included:** All Devices, **Excluded:** My Test Device Group, WFgroup |\n\n\n\n","TestStatus":"Passed","TestDescription":"If policies for Windows Firewall aren't configured and assigned, threat actors can exploit unprotected endpoints to gain unauthorized access, move laterally, and escalate privileges within the environment. Without enforced firewall rules, attackers can bypass network segmentation, exfiltrate data, or deploy malware, increasing the risk of widespread compromise.\n\nEnforcing Windows Firewall policies ensures consistent application of inbound and outbound traffic controls, reducing exposure to unauthorized access and supporting Zero Trust through network segmentation and device-level protection.\n\n**Remediation action**\n\nConfigure and assign firewall policies for Windows in Intune to block unauthorized traffic and enforce consistent network protections across all managed devices:\n\n- [Configure firewall policies for Windows devices](https://learn.microsoft.com/intune/intune-service/protect/endpoint-security-firewall-policy?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci). Intune uses two complementary profiles to manage firewall settings:\n - **Windows Firewall** - Use this profile to configure overall firewall behavior based on network type.\n - **Windows Firewall rules** - Use this profile to define traffic rules for apps, ports, or IPs, tailored to specific groups or workloads. This Intune profile also supports use of [reusable settings groups](https://learn.microsoft.com/intune/intune-service/protect/endpoint-security-firewall-policy?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci#add-reusable-settings-groups-to-profiles-for-firewall-rules) to help simplify management of common settings you use for different profile instances.\n- [Assign policies in Intune](https://learn.microsoft.com/intune/intune-service/configuration/device-profile-assign?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci#assign-a-policy-to-users-or-groups)\n\nFor more information, see: \n- [Available Windows Firewall settings](https://learn.microsoft.com/intune/intune-service/protect/endpoint-security-firewall-profile-settings?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci#windows-firewall-profile)\n","TestId":"24540"},{"TestImpact":"Medium","TestRisk":"Medium","TestSkipped":"","TestAppliesTo":null,"TestPillar":"Data","TestCategory":"Data Loss Prevention (DLP)","TestDescription":"Adaptive Protection ensures that data loss prevention (DLP) policies are tailored to each user's risk profile, rather than applying the same rules to everyone. Without Adaptive Protection, organizations miss the chance to prevent insider threats because they can't respond to behavioral indicators like unusual data access or risky activities.\n\nBy integrating Insider Risk Management with DLP, Adaptive Protection uses machine learning to identify users as high, moderate, or low risk. This lets Adaptive Protection automatically apply stricter DLP controls to those at higher risk, while allowing more flexibility for others, an approach that helps protect sensitive data and supports operational efficiency.\n\n**Remediation action**\n\n- [Help dynamically mitigate risks with Adaptive Protection](https://learn.microsoft.com/purview/insider-risk-management-adaptive-protection?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci)\n","TestTitle":"Adaptive Protection in DLP Policies","SkippedReason":null,"TestId":"35032","TestImplementationCost":"Low","TestMinimumLicense":["EXCHANGE_S_ENTERPRISE"],"TestSfiPillar":"Protect tenants and production systems","TestResult":"\n✅ Adaptive Protection is configured in DLP policies, enabling risk-based, behavior-driven data protection through insider risk integration.\n\n\n### Adaptive Protection Summary\n\n| Metric | Count |\n| :----- | :---- |\n| Total DLP Rules | 8 |\n| Rules with Adaptive Protection | 1 |\n| Policies with Adaptive Protection | 1 |\n| Rules with Elevated Risk Level | 1 |\n| Rules with Moderate Risk Level | 0 |\n| Rules with Minor Risk Level | 0 |\n\n\n### DLP Rules with Adaptive Protection\n\n| Rule Name | Parent Policy | Enabled | Risk Levels |\n| :-------- | :------------ | :------ | :---------- |\n| Block elevated-risk financial data transfers | Adaptive Protection - Elevated Risk | ✅ Yes | Elevated |\n\n\n[View DLP Policies in Microsoft Purview Portal](https://purview.microsoft.com/datalossprevention/policies)\n\n\n","TestStatus":"Passed","TestTags":null},{"TestImplementationCost":"Medium","TestPillar":"Identity","TestCategory":"Monitoring","SkippedReason":null,"TestImpact":"Medium","TestAppliesTo":["Identity"],"TestSfiPillar":"Monitor and detect cyberthreats","TestSkipped":"","TestMinimumLicense":"P1","TestTags":["Application"],"TestTitle":"High priority Entra recommendations are addressed","TestRisk":"High","TestResult":"\nFound 6 unaddressed high priority Entra recommendations.\n\n\n## Unaddressed high priority Entra recommendations\n\n| Display Name | Status | Insights |\n| :--- | :--- | :--- |\n| Protect all users with a user risk policy | active | You have 86 of 88 users that don’t have a user risk policy enabled. |\n| Protect all users with a sign-in risk policy | active | You have 86 of 88 users that don't have a sign-in risk policy turned on. |\n| Ensure all users can complete multifactor authentication | active | You have 59 of 88 users that aren’t registered with MFA. |\n| Enable policy to block legacy authentication | active | You have 3 of 88 users that don’t have legacy authentication blocked. |\n| Require multifactor authentication for administrative roles | active | You have 8 of 26 users with administrative roles that aren’t registered and protected with MFA. |\n| Renew expiring application credentials | active | Your tenant has applications with credentials that will expire soon. |\n\n\n","TestStatus":"Failed","TestDescription":"Leaving high-priority Microsoft Entra recommendations unaddressed can create a gap in an organization’s security posture, offering threat actors opportunities to exploit known weaknesses. Not acting on these items might result in an increased attack surface area, suboptimal operations, or poor user experience. \n\n**Remediation action**\n\n- [Address all high priority recommendations in the Microsoft Entra admin center](https://learn.microsoft.com/entra/identity/monitoring-health/overview-recommendations?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci#how-does-it-work)\n","TestId":"22124"},{"TestImplementationCost":"Low","TestPillar":"Network","TestCategory":"Azure Network Security","SkippedReason":"This test is not applicable to the current environment.","TestImpact":"Low","TestAppliesTo":null,"TestSfiPillar":"Monitor and detect cyberthreats","TestSkipped":"NotApplicable","TestMinimumLicense":["Azure_Firewall_Standard","Azure_Firewall_Premium"],"TestTags":null,"TestTitle":"Diagnostic logging is enabled in Azure Firewall","TestRisk":"High","TestResult":"\nSkipped. This test is not applicable to the current environment.\n","TestStatus":"Skipped","TestDescription":"Azure Firewall processes all inbound and outbound network traffic for protected workloads, making it a critical control point for network security monitoring. When diagnostic logging is not enabled, security operations teams lose visibility into traffic patterns, denied connection attempts, threat intelligence matches, and IDPS signature detections. A threat actor who gains initial access to an environment can move laterally through the network without detection because no firewall logs are being captured or analyzed. The absence of logging prevents correlation of network events with other security telemetry, eliminating the ability to construct attack timelines during incident investigations. Furthermore, compliance frameworks such as PCI-DSS, HIPAA, and SOC 2 require organizations to maintain audit logs of network security events, and the lack of firewall diagnostic logging creates audit failures. Azure Firewall provides multiple log categories including application rule logs, network rule logs, NAT rule logs, threat intelligence logs, IDPS signature logs, and DNS proxy logs, all of which must be routed to a destination such as Log Analytics, Storage Account, or Event Hub to enable security monitoring and forensic analysis.\n\n**Remediation action**\n\nCreate a Log Analytics workspace for storing Azure Firewall logs\n- [Create a Log Analytics workspace](https://learn.microsoft.com/en-us/azure/azure-monitor/logs/quick-create-workspace)\n\nConfigure diagnostic settings for Azure Firewall to enable log collection\n- [Create diagnostic settings in Azure Monitor](https://learn.microsoft.com/en-us/azure/azure-monitor/essentials/create-diagnostic-settings)\n\nEnable structured logs (resource-specific mode) for improved query performance and cost optimization\n- [Azure Firewall structured logs](https://learn.microsoft.com/en-us/azure/firewall/monitor-firewall#structured-azure-firewall-logs)\n\nUse Azure Firewall Workbook for visualizing and analyzing firewall logs\n- [Azure Firewall Workbook](https://learn.microsoft.com/en-us/azure/firewall/firewall-workbook)\n\nMonitor Azure Firewall metrics and logs for security operations\n- [Monitor Azure Firewall](https://learn.microsoft.com/en-us/azure/firewall/monitor-firewall)\n\n","TestId":26887},{"TestImplementationCost":"Low","TestPillar":"Identity","TestCategory":"Access control","SkippedReason":"UnderConstruction","TestImpact":"Low","TestAppliesTo":["Identity"],"TestSfiPillar":"Protect identities and secrets","TestSkipped":"UnderConstruction","TestMinimumLicense":"P1","TestTags":["Identity"],"TestTitle":"Require password reset notifications for administrator roles","TestRisk":"High","TestResult":"\nPlanned for future release.\n\n","TestStatus":"Planned","TestDescription":"Configuring password reset notifications for administrator roles in Microsoft Entra ID enhances security by notifying privileged administrators when another administrator resets their password. This visibility helps detect unauthorized or suspicious activity that could indicate credential compromise or insider threats. Without these notifications, malicious actors could exploit elevated privileges to establish persistence, escalate access, or extract sensitive data. Proactive notifications support quick action, preserve privileged access integrity, and strengthen the overall security posture. \n\n**Remediation action**\n\n- [Notify all admins when other admins reset their passwords](https://learn.microsoft.com/entra/identity/authentication/concept-sspr-howitworks?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci#notify-all-admins-when-other-admins-reset-their-passwords)\n","TestId":"21891"},{"TestImplementationCost":"Medium","TestPillar":"Identity","TestCategory":"Access control","SkippedReason":null,"TestImpact":"Medium","TestAppliesTo":null,"TestSfiPillar":"Protect identities and secrets","TestSkipped":"","TestMinimumLicense":"P1","TestTags":null,"TestTitle":"Reduce the user-visible password surface area","TestRisk":"High","TestResult":"\nYour organization has implemented multiple passwordless authentication methods reducing password exposure.\n## Passwordless authentication methods\n\n| Method | State | Include targets | Authentication mode | Status |\n| :----- | :---- | :-------------- | :------------------ | :----- |\n| FIDO2 Security Keys | ✅ Enabled | All users | N/A | ✅ Pass |\n| Microsoft Authenticator | ✅ Enabled | All users | ✅ any | ✅ Pass |\n\n","TestStatus":"Passed","TestDescription":"Organizations with extensive user-facing password surfaces expose multiple entry points for threat actors to launch credential-based attacks. Frequent user interactions with password prompts across applications, devices, and workflows increase the risk of exploitation. Threat actors often begin with credential stuffing—using compromised credentials from data breaches—followed by password spraying to test common passwords across multiple accounts. Once initial access is gained, they conduct credential discovery by examining browser password stores, cached credentials in memory, and credential managers to harvest additional authentication materials. These stolen credentials enable lateral movement, allowing attackers to access more systems and applications, often escalating privileges by targeting administrative accounts that still rely on password authentication. In the persistence phase, attackers may create backdoor accounts with password-based access or weaken defenses by altering password policies. To evade detection, they leverage legitimate authentication channels, blending in with normal user activity while maintaining persistent access to organizational resources. \n\n**Remediation action**\n\n * [Enable passwordless authentication methods](https://learn.microsoft.com/en-us/entra/identity/authentication/how-to-plan-prerequisites-phishing-resistant-passwordless-authentication)\n\n * [Deploy FIDO2 security keys](https://learn.microsoft.com/en-us/entra/identity/authentication/how-to-enable-passkey-fido2)\n\n","TestId":"21889"},{"TestImplementationCost":"Medium","TestPillar":"Identity","TestCategory":"Access control","SkippedReason":"UnderConstruction","TestImpact":"Low","TestAppliesTo":["Identity"],"TestSfiPillar":"Protect identities and secrets","TestSkipped":"UnderConstruction","TestMinimumLicense":null,"TestTags":["Identity"],"TestTitle":"Privileged roles have access reviews","TestRisk":"Medium","TestResult":"\nPlanned for future release.\n","TestStatus":"Planned","TestDescription":"...\n\n**Remediation action**\n\n","TestId":"21855"},{"TestImplementationCost":"High","TestPillar":"Network","TestCategory":"Global Secure Access","SkippedReason":null,"TestImpact":"Medium","TestAppliesTo":null,"TestSfiPillar":"Protect networks","TestSkipped":"","TestMinimumLicense":"Entra_Premium_Internet_Access","TestTags":null,"TestTitle":"Sensitive data exfiltration through file transfers is prevented by network content filtering policies","TestRisk":"High","TestResult":"\n❌ No file policy is configured. File transfers are unmonitored and the organization is exposed to data exfiltration risk.\n\n\n","TestStatus":"Failed","TestDescription":"Without network content filtering through file policies, threat actors can exfiltrate data to unsanctioned destinations through browsers, applications, add-ins, and APIs. When file policies are not configured, threat actors exploit unmanaged cloud applications and generative AI tools as exfiltration channels for sensitive information.\n\n**Remediation action**\n\nFollow these steps to configure file policy protection:\n\n- [Configure web content filtering policies in Global Secure Access, which covers the foundational approach for creating filtering policies including file policies](https://learn.microsoft.com/en-us/entra/global-secure-access/how-to-configure-web-content-filtering)\n- [Create and manage security profiles that group filtering policies for enforcement through Conditional Access](https://learn.microsoft.com/en-us/entra/global-secure-access/concept-traffic-forwarding)\n- [Link security profiles to Conditional Access policies for user-aware and context-aware enforcement of network security policies](https://learn.microsoft.com/en-us/entra/identity/conditional-access/concept-conditional-access-session)\n- [Deploy the Global Secure Access client on end-user devices to enable traffic acquisition and policy enforcement](https://learn.microsoft.com/en-us/entra/global-secure-access/how-to-install-windows-client)\n\n","TestId":"25413"},{"TestImplementationCost":"Low","TestPillar":"Identity","TestCategory":"Credential management","SkippedReason":null,"TestImpact":"Low","TestAppliesTo":null,"TestSfiPillar":"Protect identities and secrets","TestSkipped":"","TestMinimumLicense":"P1","TestTags":null,"TestTitle":"Enable custom banned passwords","TestRisk":"Medium","TestResult":"\nCustom banned passwords are properly configured with organization-specific terms to prevent predictable password patterns.\n\n\n## Password protection settings\n\n| Enforce custom list | Custom banned password list | Number of terms |\n| :------------------ | :-------------------------- | :-------------- |\n| [Yes](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/AuthenticationMethodsMenuBlade/~/PasswordProtection/fromNav/) | test | 1 |\n\n\n\n","TestStatus":"Passed","TestDescription":"Organizations that don't populate and enforce the custom banned password list expose themselves to a systematic attack chain where threat actors exploit predictable organizational password patterns. These threat actors typically start with reconnaissance phases, where they gather open-source intelligence (OSINT) from websites, social media, and public records to identify likely password components. With this knowledge, they launch password spray attacks that test organization-specific password variations across multiple user accounts, staying under lockout thresholds to avoid detection. Without the protection the custom banned password list offers, employees often add familiar organizational terms to their passwords, like locations, product names, and industry terms, creating consistent attack vectors. \n\nThe custom banned password list helps organizations plug this critical gap to prevent easily guessed passwords that could lead to initial access and subsequent lateral movement within the environment.\n\n**Remediation action**\n\n- [Learn how to enable custom banned password protection and add organizational terms](https://learn.microsoft.com/entra/identity/authentication/tutorial-configure-custom-password-protection?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci)\n","TestId":"21848"},{"TestImplementationCost":"Medium","TestPillar":"Identity","TestCategory":"External collaboration","SkippedReason":null,"TestImpact":"Medium","TestAppliesTo":null,"TestSfiPillar":"Protect tenants and isolate production systems","TestSkipped":"","TestMinimumLicense":["P2","Governance"],"TestTags":null,"TestTitle":"All entitlement management assignment policies that apply to external users require connected organizations","TestRisk":"Medium","TestResult":"\nAssignment policies without connected organization restrictions were found.\n## Evaluated assignment policies\n| Access package | Assignment policy | Target scope | Status |\n| :--- | :--- | :--- | :--- |\n| [PS-GraphCmdLetScriptTest4](https://entra.microsoft.com/#view/Microsoft_AAD_ERM/DashboardBlade/~/elmEntitlement/menuId/) | 21929Test | allExternalUsers | ❌ Fail |\n| [PS-GraphCmdLetScriptTest4](https://entra.microsoft.com/#view/Microsoft_AAD_ERM/DashboardBlade/~/elmEntitlement/menuId/) | External | allConfiguredConnectedOrganizationUsers | ⚠️ Investigate |\n| [Get user info demo](https://entra.microsoft.com/#view/Microsoft_AAD_ERM/DashboardBlade/~/elmEntitlement/menuId/) | Initial Policy | specificConnectedOrganizationUsers | ✅ Pass |\n| [UserInfo](https://entra.microsoft.com/#view/Microsoft_AAD_ERM/DashboardBlade/~/elmEntitlement/menuId/) | Initial Policy | allConfiguredConnectedOrganizationUsers | ⚠️ Investigate |\n\n\n","TestStatus":"Failed","TestDescription":"Access packages configured to allow \"All users\" instead of specific connected organizations expose your organization to uncontrolled external access. Threat actors can exploit this by requesting access through compromised external accounts from unauthorized organizations, bypassing the principle of least privilege. This enables initial access, reconnaissance, privilege escalation, and lateral movement within your environment. \n\n**Remediation action**\n\n- [Define trusted organizations as connected organizations](https://learn.microsoft.com/entra/id-governance/entitlement-management-organization?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci#view-the-list-of-connected-organizations)\n- [Configure access packages to only allow specific connected organizations](https://learn.microsoft.com/entra/id-governance/entitlement-management-access-package-create?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci#allow-users-not-in-your-directory-to-request-the-access-package)\n","TestId":"21875"},{"TestImplementationCost":"Low","TestPillar":"Network","TestCategory":"Azure Network Security","SkippedReason":"This test is not applicable to the current environment.","TestImpact":"Low","TestAppliesTo":null,"TestSfiPillar":"Protect networks","TestSkipped":"NotApplicable","TestMinimumLicense":["DDoS_Network_Protection","DDoS_IP_Protection"],"TestTags":null,"TestTitle":"Diagnostic logging is enabled for DDoS-protected public IPs","TestRisk":"Medium","TestResult":"\nSkipped. This test is not applicable to the current environment.\n","TestStatus":"Skipped","TestDescription":"When Azure DDoS Protection is enabled for public IP addresses, diagnostic logging provides critical visibility into attack patterns, mitigation actions, and traffic flow data. Without diagnostic logs enabled, security teams lack the observability needed to understand attack characteristics, validate mitigation effectiveness, and perform post-incident analysis. Azure DDoS Protection generates three categories of diagnostic logs: DDoSProtectionNotifications (alerts when attacks are detected and when mitigation starts/stops), DDoSMitigationFlowLogs (detailed flow-level information during active attack mitigation), and DDoSMitigationReports (comprehensive attack summaries with traffic statistics and mitigation actions). These logs are essential for security operations to detect ongoing attacks, investigate incidents, meet compliance requirements, and tune protection policies. The absence of logging prevents correlation of network events with other security telemetry, eliminating the ability to construct attack timelines during incident investigations. Furthermore, compliance frameworks such as PCI-DSS, HIPAA, and SOC 2 require organizations to maintain audit logs of network security events, and the lack of DDoS diagnostic logging creates audit failures.\n\n**Remediation action**\n\nConfigure diagnostic settings for DDoS-protected public IP addresses\n- [Configure Azure DDoS Protection diagnostic logging](https://learn.microsoft.com/en-us/azure/ddos-protection/diagnostic-logging)\n\nView and configure DDoS diagnostic logs in the Azure portal\n- [View and configure DDoS diagnostic logging](https://learn.microsoft.com/en-us/azure/ddos-protection/diagnostic-logging#configure-ddos-diagnostic-logs)\n\nCreate a Log Analytics workspace for storing DDoS Protection logs\n- [Create a Log Analytics workspace](https://learn.microsoft.com/en-us/azure/azure-monitor/logs/quick-create-workspace)\n\nMonitor and analyze DDoS attack telemetry\n- [Azure DDoS Protection monitoring and logging](https://learn.microsoft.com/en-us/azure/ddos-protection/ddos-protection-overview#monitoring-and-logging)\n\nView and analyze DDoS logs for incident investigation\n- [Tutorial: View and analyze DDoS logs](https://learn.microsoft.com/en-us/azure/ddos-protection/view-logs)\n\n","TestId":26886},{"TestImplementationCost":"High","TestPillar":"Identity","TestCategory":"Access control","SkippedReason":null,"TestImpact":"High","TestAppliesTo":null,"TestSfiPillar":"Protect identities and secrets","TestSkipped":"","TestMinimumLicense":"P1","TestTags":null,"TestTitle":"All sign-in activity comes from managed devices","TestRisk":"High","TestResult":"\n❌ Not all sign-in activity comes from managed devices.\n\n### Managed device conditional access policy summary\n\nThe table below lists all Conditional Access policies that require a compliant device or a hybrid joined device.\n| Name | All users | All apps | Compliant device | Hybrid joined device | Policy state | Status |\n| :--- | :---: | :---: | :---: | :---: | :--- | :--- |\n| [\\[ellis\\] - CA policy for Compliant devices](https://entra.microsoft.com/#view/Microsoft_AAD_ConditionalAccess/PolicyBlade/policyId/dfde11d6-2433-45dc-86dc-f191dcac3bd9) | 🔴 | 🔴 | 🟢 | 🔴 | 🔴 Disabled | ❌ Fail |\n| [\\[ellis\\] - Require app protection policy](https://entra.microsoft.com/#view/Microsoft_AAD_ConditionalAccess/PolicyBlade/policyId/6909c0fb-c830-42b6-a438-c41d4010518f) | 🔴 | 🔴 | 🟢 | 🔴 | 🟢 Enabled | ❌ Fail |\n| [ALEX - MFA for risky sign-ins](https://entra.microsoft.com/#view/Microsoft_AAD_ConditionalAccess/PolicyBlade/policyId/5167662e-2022-45a5-825c-4514e5a0cfd4) | 🔴 | 🟢 | 🟢 | 🟢 | 🔴 Disabled | ❌ Fail |\n| [All sign-in activity comes from managed devices](https://entra.microsoft.com/#view/Microsoft_AAD_ConditionalAccess/PolicyBlade/policyId/7701ec7b-8983-4dd2-ae60-27cb0b2d3c6d) | 🟢 | 🟢 | 🟢 | 🟢 | 🟡 Report-only | ❌ Fail |\n| [Device compliance #1](https://entra.microsoft.com/#view/Microsoft_AAD_ConditionalAccess/PolicyBlade/policyId/2965e1d4-6146-41a5-abae-5219abf7d68f) | 🔴 | 🟢 | 🟢 | 🟢 | 🔴 Disabled | ❌ Fail |\n| [Device compliancy](https://entra.microsoft.com/#view/Microsoft_AAD_ConditionalAccess/PolicyBlade/policyId/206c9071-89d7-4b57-adaf-87f78a4bd7f5) | 🔴 | 🟢 | 🟢 | 🟢 | 🔴 Disabled | ❌ Fail |\n| [Require compliant or hybrid Azure AD joined device for admins](https://entra.microsoft.com/#view/Microsoft_AAD_ConditionalAccess/PolicyBlade/policyId/5ee30a46-6df0-48ff-b60b-45073b7e4e3e) | 🔴 | 🟢 | 🟢 | 🟢 | 🔴 Disabled | ❌ Fail |\n| [Require compliant or hybrid Azure AD joined device or multifactor authentication for all users](https://entra.microsoft.com/#view/Microsoft_AAD_ConditionalAccess/PolicyBlade/policyId/05439c0a-90b2-45e9-92cc-0e13ddc3b9c3) | 🔴 | 🟢 | 🟢 | 🟢 | 🔴 Disabled | ❌ Fail |\n| [Require compliant or hybrid Azure AD joined device or multifactor authentication for all users](https://entra.microsoft.com/#view/Microsoft_AAD_ConditionalAccess/PolicyBlade/policyId/ee4fdb05-5aec-4616-b2da-6d16a2cb2a54) | 🔴 | 🟢 | 🟢 | 🟢 | 🔴 Disabled | ❌ Fail |\n| [Securing security info registration](https://entra.microsoft.com/#view/Microsoft_AAD_ConditionalAccess/PolicyBlade/policyId/28ba1d93-c70c-4c7f-93e4-852705472e3d) | 🟢 | 🔴 | 🟢 | 🟢 | 🔴 Disabled | ❌ Fail |\n\n\n","TestStatus":"Failed","TestDescription":"Requiring sign-ins from managed devices ensures that users access organizational resources only from devices that meet your security and compliance requirements. Unmanaged devices lack organizational security controls and endpoint protection, creating potential entry points for attackers. Using Conditional Access to require compliant or Microsoft Entra hybrid joined devices helps protect against credential theft and unauthorized access from untrusted endpoints.\n\n**Remediation action**\n\n- [Require compliant or hybrid joined devices with Conditional Access](https://learn.microsoft.com/entra/identity/conditional-access/policy-all-users-device-compliance?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci)\n- [Configure device compliance policies in Microsoft Intune](https://learn.microsoft.com/mem/intune/protect/device-compliance-get-started?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci)\n","TestId":"21892"},{"TestImplementationCost":"Medium","TestPillar":"Identity","TestCategory":"Application management","SkippedReason":null,"TestImpact":"Low","TestAppliesTo":["Identity"],"TestSfiPillar":"Protect networks","TestSkipped":"","TestMinimumLicense":"P1","TestTags":["Identity"],"TestTitle":"Tenant restrictions v2 are configured","TestRisk":"High","TestResult":"\nTenant Restrictions v2 policy is properly configured.\n\n\n## Tenant restriction settings\n\n\n| Policy Configured | External users and groups | External applications |\n| :---------------- | :------------------------ | :-------------------- |\n| [Yes](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/TenantRestrictions.ReactView/isDefault~/true/name//id/) | All external users and groups | All external applications |\n\n\n\n","TestStatus":"Passed","TestDescription":"Tenant Restrictions v2 (TRv2) allows organizations to enforce policies that restrict access to specified Microsoft Entra tenants, preventing unauthorized exfiltration of corporate data to external tenants using local accounts. Without TRv2, threat actors can exploit this vulnerability, which leads to potential data exfiltration and compliance violations, followed by credential harvesting if those external tenants have weaker controls. Once credentials are obtained, threat actors can gain initial access to these external tenants. TRv2 provides the mechanism to prevent users from authenticating to unauthorized tenants. Otherwise, threat actors can move laterally, escalate privileges, and potentially exfiltrate sensitive data, all while appearing as legitimate user activity that bypasses traditional data loss prevention controls focused on internal tenant monitoring.\n\nImplementing TRv2 enforces policies that restrict access to specified tenants, mitigating these risks by ensuring that authentication and data access are confined to authorized tenants only. \n\nIf this check passes, your tenant has a TRv2 policy configured but more steps are required to validate the scenario end-to-end.\n\n**Remediation action**\n- [Set up Tenant Restrictions v2](https://learn.microsoft.com/entra/external-id/tenant-restrictions-v2?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci)\n","TestId":"21793"},{"TestImplementationCost":"Medium","TestPillar":"Identity","TestCategory":"External collaboration","SkippedReason":"UnderConstruction","TestImpact":"Medium","TestAppliesTo":["Identity"],"TestSfiPillar":"Protect tenants and isolate production systems","TestSkipped":"UnderConstruction","TestMinimumLicense":"Free","TestTags":["Application"],"TestTitle":"All guests user strong authentication methods","TestRisk":"Medium","TestResult":"\nPlanned for future release.\n\n","TestStatus":"Planned","TestDescription":"External user accounts are often used to provide access to business partners who belong to organizations that have a business relationship with your organization. If these accounts are compromised in their organization, attackers can use the valid credentials to gain initial access to your environment, often bypassing traditional defenses due to their legitimacy.\n\nAttackers might gain access with external user accounts, if multifactor authentication (MFA) isn't universally enforced or if there are exceptions in place. They might also gain access by exploiting the vulnerabilities of weaker MFA methods like SMS and phone calls using social engineering techniques, such as SIM swapping or phishing, to intercept the authentication codes.\n\nOnce an attacker gains access to an account without MFA or a session with weak MFA methods, they might attempt to manipulate MFA settings (for example, registering attacker controlled methods) to establish persistence to plan and execute further attacks based on the privileges of the compromised accounts.\n\n**Remediation action**\n\n- [Deploy a Conditional Access policy to enforce authentication strength for guests](https://learn.microsoft.com/entra/identity/conditional-access/policy-guests-mfa-strength?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci).\n- For organizations with a closer business relationship and vetting on their MFA practices, consider deploying cross-tenant access settings to accept the MFA claim.\n - [Configure B2B collaboration cross-tenant access settings](https://learn.microsoft.com/entra/external-id/cross-tenant-access-settings-b2b-collaboration?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci#to-change-inbound-trust-settings-for-mfa-and-device-claims)\n","TestId":"21851"},{"TestImplementationCost":"Medium","TestPillar":"Devices","TestCategory":"Tenant","SkippedReason":null,"TestImpact":"Medium","TestAppliesTo":null,"TestSfiPillar":"Protect tenants and isolate production systems","TestSkipped":"","TestMinimumLicense":"Intune","TestTags":null,"TestTitle":"Windows Security Baseline is Configured and Assigned","TestRisk":"High","TestResult":"\nNo security baselines are configured or assigned to Windows devices in Intune.\n\n\n\n","TestStatus":"Failed","TestDescription":"Without properly configured and assigned Intune security baselines for Windows, devices remain vulnerable to a wide array of attack vectors that threat actors exploit to gain persistence and escalate privileges. Adversaries leverage default Windows configurations that lack hardened security settings to perform lateral movement using techniques like credential dumping, privilege escalation via unpatched vulnerabilities, and exploitation of weak authentication mechanisms. In the absence of enforced security baselines, threat actors can bypass critical security controls, maintain persistence through registry modifications, and exfiltrate sensitive data through unmonitored channels. Failing to implement a defense-in-depth strategy makes devices easier to exploit as attackers progress through the attack chain—from initial access to data exfiltration—ultimately compromising the organization’s security posture and increasing the risk of compliance violations.\n\nApplying security baselines ensures Windows devices are configured with hardened settings, reducing attack surface, enforcing defense-in-depth, and supporting Zero Trust by standardizing security controls across the environment.\n\n**Remediation action**\n\nConfigure and assign Intune security baselines to Windows devices to enforce standardized security settings and monitor compliance:\n- [Deploy security baselines to help secure Windows devices](https://learn.microsoft.com/intune/intune-service/protect/security-baselines-configure?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci#create-a-profile-for-a-security-baseline)\n- [Monitor security baseline compliance](https://learn.microsoft.com/intune/intune-service/protect/security-baselines-monitor?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci)\n","TestId":"24573"},{"TestImplementationCost":"Low","TestPillar":"Network","TestCategory":"Azure Network Security","SkippedReason":"This test is not applicable to the current environment.","TestImpact":"Low","TestAppliesTo":null,"TestSfiPillar":"Protect networks","TestSkipped":"NotApplicable","TestMinimumLicense":"Azure WAF","TestTags":null,"TestTitle":"Request Body Inspection is enabled in Application Gateway WAF","TestRisk":"High","TestResult":"\nNo Application Gateway WAF policies attached to Application Gateways found across subscriptions.\n","TestStatus":"Skipped","TestDescription":"Azure Application Gateway Web Application Firewall (WAF) provides centralized protection for web applications against common exploits and vulnerabilities at the regional level. Request body inspection is a critical capability that allows the WAF to analyze the content of HTTP POST, PUT, and PATCH request bodies for malicious patterns. When request body inspection is disabled, threat actors can craft attacks that embed malicious SQL statements, scripts, or command injection payloads within form submissions, API calls, or file uploads that bypass all WAF rule evaluation. This creates a direct path for exploitation where threat actors gain initial access through unprotected application endpoints, execute arbitrary commands or queries against backend databases through SQL injection, exfiltrate sensitive data including credentials and customer information, establish persistence by modifying application data or injecting backdoors, and pivot to internal systems through compromised application server credentials. The WAF's managed rule sets, including OWASP Core Rule Set and Microsoft's Bot Manager rules, cannot evaluate threats they cannot see; disabling request body inspection renders these protections ineffective against body-based attack vectors that represent the majority of modern web application attacks.\n\n**Remediation action**\n\nOverview of WAF capabilities on Application Gateway including request body inspection\n- [What is Azure Web Application Firewall on Azure Application Gateway?](https://learn.microsoft.com/en-us/azure/web-application-firewall/ag/ag-overview)\n\nGuidance on creating and configuring WAF policies including request body inspection settings\n- [Create Web Application Firewall policies for Application Gateway](https://learn.microsoft.com/en-us/azure/web-application-firewall/ag/create-waf-policy-ag)\n\nFAQ and best practices for tuning WAF including request body inspection limits\n- [Tuning Web Application Firewall for Azure Application Gateway](https://learn.microsoft.com/en-us/azure/web-application-firewall/ag/application-gateway-waf-faq)\n\n","TestId":26879},{"TestImplementationCost":"Low","TestPillar":"Identity","TestCategory":"Monitoring","SkippedReason":"UnderConstruction","TestImpact":"High","TestAppliesTo":["Identity"],"TestSfiPillar":"Monitor and detect cyberthreats","TestSkipped":"UnderConstruction","TestMinimumLicense":"P1","TestTags":["Identity"],"TestTitle":"No legacy authentication sign-in activity","TestRisk":"Medium","TestResult":"\nPlanned for future release.\n\n","TestStatus":"Planned","TestDescription":"Legacy authentication protocols such as basic authentication for SMTP and IMAP don't support modern security features like multifactor authentication (MFA), which is crucial for protecting against unauthorized access. This lack of protection makes accounts using these protocols vulnerable to password-based attacks, and provides attackers with a means to gain initial access using stolen or guessed credentials.\n\nWhen an attacker successfully gains unauthorized access to credentials, they can use them to access linked services, using the weak authentication method as an entry point. Attackers who gain access through legacy authentication might make changes to Microsoft Exchange, such as configuring mail forwarding rules or changing other settings, allowing them to maintain continued access to sensitive communications.\n\nLegacy authentication also provides attackers with a consistent method to reenter a system using compromised credentials without triggering security alerts or requiring reauthentication.\n\nFrom there, attackers can use legacy protocols to access other systems that are accessible via the compromised account, facilitating lateral movement. Attackers using legacy protocols can blend in with legitimate user activities, making it difficult for security teams to distinguish between normal usage and malicious behavior.\n\n**Remediation action**\n\n- [Exchange protocols can be deactivated in Exchange](https://learn.microsoft.com/exchange/clients-and-mobile-in-exchange-online/disable-basic-authentication-in-exchange-online?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci)\n- [Legacy authentication protocols can be blocked with Conditional Access](https://learn.microsoft.com/entra/identity/conditional-access/policy-block-legacy-authentication?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci)\n- [Sign-ins using legacy authentication workbook to help determine whether it's safe to turn off legacy authentication](https://learn.microsoft.com/entra/identity/monitoring-health/workbook-legacy-authentication?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci)\n","TestId":"21795"},{"TestImplementationCost":"Low","TestPillar":"Identity","TestCategory":"Access control","SkippedReason":null,"TestImpact":"Medium","TestAppliesTo":null,"TestSfiPillar":"Protect identities and secrets","TestSkipped":"","TestMinimumLicense":"P1","TestTags":null,"TestTitle":"Privileged users have short-lived sign-in sessions","TestRisk":"Medium","TestResult":"\n## Privileged User Sign-In Sessions\n\n**Total Privileged Roles Found:** 34\n\n**CA Policies Targeting Roles:** 8\n\n**Recommended Sign In Session Hours:** 4\n\n**Policies with Compliant Frequency (≤4 hours):** 1\n\n### Conditional Access Policies by Privileged Role\n\n#### Global Administrator\n\n**Status:** ❌ No CA policies assigned\n\n*No Conditional Access policies target this privileged role.*\n\n#### User Administrator\n\n**Status:** ❌ No CA policies assigned\n\n*No Conditional Access policies target this privileged role.*\n\n#### Helpdesk Administrator\n\n**Status:** ✅ Covered\n\n| Policy Name | Sign-In Frequency | Compliant |\n| :--- | :--- | :--- |\n| [j-test admin](https://entra.microsoft.com/#view/Microsoft_AAD_ConditionalAccess/PolicyBlade/policyId/6c0ef46a-3b58-43a9-b451-7464a16d91d7) | 1 hours | ✅ |\n\n#### Partner Tier1 Support\n\n**Status:** ❌ No CA policies assigned\n\n*No Conditional Access policies target this privileged role.*\n\n#### Partner Tier2 Support\n\n**Status:** ❌ No CA policies assigned\n\n*No Conditional Access policies target this privileged role.*\n\n#### Directory Writers\n\n**Status:** ❌ No CA policies assigned\n\n*No Conditional Access policies target this privileged role.*\n\n#### Application Administrator\n\n**Status:** ✅ Covered\n\n| Policy Name | Sign-In Frequency | Compliant |\n| :--- | :--- | :--- |\n| [j-test admin](https://entra.microsoft.com/#view/Microsoft_AAD_ConditionalAccess/PolicyBlade/policyId/6c0ef46a-3b58-43a9-b451-7464a16d91d7) | 1 hours | ✅ |\n\n#### Application Developer\n\n**Status:** ❌ No CA policies assigned\n\n*No Conditional Access policies target this privileged role.*\n\n#### Security Reader\n\n**Status:** ❌ No CA policies assigned\n\n*No Conditional Access policies target this privileged role.*\n\n#### Security Administrator\n\n**Status:** ✅ Covered\n\n| Policy Name | Sign-In Frequency | Compliant |\n| :--- | :--- | :--- |\n| [j-test admin](https://entra.microsoft.com/#view/Microsoft_AAD_ConditionalAccess/PolicyBlade/policyId/6c0ef46a-3b58-43a9-b451-7464a16d91d7) | 1 hours | ✅ |\n\n#### Privileged Role Administrator\n\n**Status:** ✅ Covered\n\n| Policy Name | Sign-In Frequency | Compliant |\n| :--- | :--- | :--- |\n| [j-test admin](https://entra.microsoft.com/#view/Microsoft_AAD_ConditionalAccess/PolicyBlade/policyId/6c0ef46a-3b58-43a9-b451-7464a16d91d7) | 1 hours | ✅ |\n\n#### Intune Administrator\n\n**Status:** ❌ No CA policies assigned\n\n*No Conditional Access policies target this privileged role.*\n\n#### Cloud Application Administrator\n\n**Status:** ✅ Covered\n\n| Policy Name | Sign-In Frequency | Compliant |\n| :--- | :--- | :--- |\n| [j-test admin](https://entra.microsoft.com/#view/Microsoft_AAD_ConditionalAccess/PolicyBlade/policyId/6c0ef46a-3b58-43a9-b451-7464a16d91d7) | 1 hours | ✅ |\n\n#### Conditional Access Administrator\n\n**Status:** ✅ Covered\n\n| Policy Name | Sign-In Frequency | Compliant |\n| :--- | :--- | :--- |\n| [j-test admin](https://entra.microsoft.com/#view/Microsoft_AAD_ConditionalAccess/PolicyBlade/policyId/6c0ef46a-3b58-43a9-b451-7464a16d91d7) | 1 hours | ✅ |\n\n#### Cloud Device Administrator\n\n**Status:** ❌ No CA policies assigned\n\n*No Conditional Access policies target this privileged role.*\n\n#### Authentication Administrator\n\n**Status:** ✅ Covered\n\n| Policy Name | Sign-In Frequency | Compliant |\n| :--- | :--- | :--- |\n| [j-test admin](https://entra.microsoft.com/#view/Microsoft_AAD_ConditionalAccess/PolicyBlade/policyId/6c0ef46a-3b58-43a9-b451-7464a16d91d7) | 1 hours | ✅ |\n\n#### Privileged Authentication Administrator\n\n**Status:** ✅ Covered\n\n| Policy Name | Sign-In Frequency | Compliant |\n| :--- | :--- | :--- |\n| [j-test admin](https://entra.microsoft.com/#view/Microsoft_AAD_ConditionalAccess/PolicyBlade/policyId/6c0ef46a-3b58-43a9-b451-7464a16d91d7) | 1 hours | ✅ |\n\n#### B2C IEF Keyset Administrator\n\n**Status:** ❌ No CA policies assigned\n\n*No Conditional Access policies target this privileged role.*\n\n#### External Identity Provider Administrator\n\n**Status:** ❌ No CA policies assigned\n\n*No Conditional Access policies target this privileged role.*\n\n#### Security Operator\n\n**Status:** ❌ No CA policies assigned\n\n*No Conditional Access policies target this privileged role.*\n\n#### Global Reader\n\n**Status:** ❌ No CA policies assigned\n\n*No Conditional Access policies target this privileged role.*\n\n#### Password Administrator\n\n**Status:** ✅ Covered\n\n| Policy Name | Sign-In Frequency | Compliant |\n| :--- | :--- | :--- |\n| [j-test admin](https://entra.microsoft.com/#view/Microsoft_AAD_ConditionalAccess/PolicyBlade/policyId/6c0ef46a-3b58-43a9-b451-7464a16d91d7) | 1 hours | ✅ |\n\n#### Hybrid Identity Administrator\n\n**Status:** ❌ No CA policies assigned\n\n*No Conditional Access policies target this privileged role.*\n\n#### Domain Name Administrator\n\n**Status:** ❌ No CA policies assigned\n\n*No Conditional Access policies target this privileged role.*\n\n#### AI Administrator\n\n**Status:** ❌ No CA policies assigned\n\n*No Conditional Access policies target this privileged role.*\n\n#### AI Reader\n\n**Status:** ❌ No CA policies assigned\n\n*No Conditional Access policies target this privileged role.*\n\n#### Identity Governance Administrator\n\n**Status:** ❌ No CA policies assigned\n\n*No Conditional Access policies target this privileged role.*\n\n#### Authentication Extensibility Administrator\n\n**Status:** ❌ No CA policies assigned\n\n*No Conditional Access policies target this privileged role.*\n\n#### Lifecycle Workflows Administrator\n\n**Status:** ❌ No CA policies assigned\n\n*No Conditional Access policies target this privileged role.*\n\n#### Attribute Provisioning Reader\n\n**Status:** ❌ No CA policies assigned\n\n*No Conditional Access policies target this privileged role.*\n\n#### Attribute Provisioning Administrator\n\n**Status:** ❌ No CA policies assigned\n\n*No Conditional Access policies target this privileged role.*\n\n#### Authentication Extensibility Password Administrator\n\n**Status:** ❌ No CA policies assigned\n\n*No Conditional Access policies target this privileged role.*\n\n#### Agent ID Administrator\n\n**Status:** ❌ No CA policies assigned\n\n*No Conditional Access policies target this privileged role.*\n\n#### ExamStudyTest\n\n**Status:** ❌ No CA policies assigned\n\n*No Conditional Access policies target this privileged role.*\n\n❌ **Not all privileged roles are covered by compliant sign-in frequency controls.**\n\n**Recommendation:** Configure Conditional Access policies to enforce sign-in frequency of 4 hours or less for ALL privileged roles.\n\n\n","TestStatus":"Failed","TestDescription":"When privileged users are allowed to maintain long-lived sign-in sessions without periodic reauthentication, threat actors can gain extended windows of opportunity to exploit compromised credentials or hijack active sessions. Once a privileged account is compromised through techniques like credential theft, phishing, or session fixation, extended session timeouts allow threat actors to maintain persistence within the environment for prolonged periods. With long-lived sessions, threat actors can perform lateral movement across systems, escalate privileges further, and access sensitive resources without triggering another authentication challenge. The extended session duration also increases the window for session hijacking attacks, where threat actors can steal session tokens and impersonate the privileged user. Once a threat actor is established in a privileged session, they can:\n\n- Create backdoor accounts\n- Modify security policies\n- Access sensitive data\n- Establish more persistence mechanisms\n\nThe lack of periodic reauthentication requirements means that even if the original compromise is detected, the threat actor might continue operating undetected using the hijacked privileged session until the session naturally expires or the user manually signs out.\n\n**Remediation action**\n\n- [Learn about Conditional Access adaptive session lifetime policies](https://learn.microsoft.com/entra/identity/conditional-access/concept-session-lifetime?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci)\n- [Configure sign-in frequency for privileged users with Conditional Access policies ](https://learn.microsoft.com/entra/identity/conditional-access/howto-conditional-access-session-lifetime?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci)\n","TestId":21825},{"TestImpact":"Low","TestRisk":"Low","TestSkipped":"","TestAppliesTo":null,"TestPillar":"Data","TestCategory":"Information Protection","TestDescription":"When an organization doesn’t use custom branding templates, people outside the company who receive encrypted messages could see a generic Microsoft‑branded portal. Because the portal doesn’t reflect the organization’s identity, recipients can be less confident about where the message came from.\n\nCustom branding templates let organizations add their logo, colors, disclaimers, and contact details to the portal. These elements help the portal look familiar to recipients and can support trust when they view and interact with encrypted messages.\n\n**Remediation action**\n\n- [Add your organization's brand to your encrypted messages](https://learn.microsoft.com/purview/add-your-organization-brand-to-encrypted-messages?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci)\n","TestTitle":"OME Custom Branding Templates","SkippedReason":null,"TestId":"35027","TestImplementationCost":"Low","TestMinimumLicense":["RMS_S_PREMIUM"],"TestSfiPillar":"Protect tenants and production systems","TestResult":"\n❌ OME custom branding is not configured; the encryption portal uses generic Microsoft branding.\n\n**Summary:**\n\n- Total OME Configurations: 1\n- Configured with Custom Branding: 0\n\n**Configuration Details:**\n\n| Configuration identity | Email text | Logo configured | Background color | Portal text | Introduction text | Disclaimer text |\n|:-----------------------|:-----------|:----------------|:-----------------|:------------|:------------------|:----------------|\n| OME Configuration | ❌ None | ❌ No | ❌ None | ❌ None | ❌ None | ❌ None |\n\n","TestStatus":"Failed","TestTags":null},{"TestImplementationCost":"Medium","TestPillar":"Identity","TestCategory":"Application management","SkippedReason":null,"TestImpact":"Medium","TestAppliesTo":["Identity"],"TestSfiPillar":"Protect identities and secrets","TestSkipped":"","TestMinimumLicense":"Free","TestTags":["Application"],"TestTitle":"Applications don't have certificates with expiration longer than 180 days","TestRisk":"High","TestResult":"\nFound 3 applications and 7 service principals with certificates longer than 180 days\n\n\n## Applications with long-lived credentials\n\n| Application | Certificate expiry |\n| :--- | :--- |\n| [Automation](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/ApplicationMenuBlade/~/Credentials/appId/dc7d83b5-d38b-4488-8952-7abf02e71590) | 2125-03-03 |\n| [Custom-App-Test](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/ApplicationMenuBlade/~/Credentials/appId/ddb4f0e6-8018-4359-96c1-7473704bde43) | 2028-11-05 |\n| [ZeroTrustTest](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/ApplicationMenuBlade/~/Credentials/appId/3835a2fc-573d-4c4b-a4a3-993a1a156607) | 2028-10-04 |\n\n\n## Service principals with long-lived credentials\n\n| Service principal | App owner tenant | Certificate expiry |\n| :--- | :--- | :--- |\n| [21869testapp](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/SignOn/objectId/e69e29be-ba40-445a-9824-a3a45e0ae57a/appId/dd63d132-18fb-4f2e-aec4-82b97f30301f/preferredSingleSignOnMode/saml/servicePrincipalType/Application/fromNav/) | | 2028-10-27 |\n| [APP-2732_Genesys Cloud TCCC-G-TFS-Prod](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/SignOn/objectId/ba63bb52-182c-4ec6-9cc8-ad2287cf51ed/appId/76249b01-8747-4db4-843f-6478d5b32b14/preferredSingleSignOnMode/saml/servicePrincipalType/Application/fromNav/) | | 2028-07-30 |\n| [Azure AD SAML Toolkit](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/SignOn/objectId/4317fd0a-dcee-45bf-8e94-9a66638b11e0/appId/6f5ed68c-9fad-4d78-bf88-2b16bbe16338/preferredSingleSignOnMode/saml/servicePrincipalType/Application/fromNav/) | | 2028-10-11 |\n| [charlie AWS Account](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/SignOn/objectId/39861745-eda1-4e3c-8358-d0ba931f12bb/appId/d3a04f85-a969-436b-bf4d-eae0a91efb4c/preferredSingleSignOnMode/saml/servicePrincipalType/Application/fromNav/) | | 2028-01-07 |\n| [charlie- Genesys Cloud for Azure](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/SignOn/objectId/84dc13ec-5754-4745-90f9-5cc92a5ded28/appId/9c599cd2-9fb0-4815-b65c-83be33f5df1b/preferredSingleSignOnMode/saml/servicePrincipalType/Application/fromNav/) | | 2028-07-30 |\n| [SumoLogic](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/SignOn/objectId/144df581-a0c9-4280-9739-0c3612ab9ccf/appId/1b6c36b2-f2b1-43d3-b74f-8d52c44fc9c1/preferredSingleSignOnMode/saml/servicePrincipalType/Application/fromNav/) | | 2027-02-15 |\n| [claimtest](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/SignOn/objectId/f7b07e81-79a0-4e51-b93a-169b8f2f6c4e/appId/f816d68b-aec7-4eab-9ebc-bd23b0d04e35/preferredSingleSignOnMode/saml/servicePrincipalType/Application/fromNav/) | | 2028-02-26 |\n\n\n","TestStatus":"Failed","TestDescription":"Certificates, if not securely stored, can be extracted and exploited by attackers, leading to unauthorized access. Long-lived certificates are more likely to be exposed over time. Credentials, when exposed, provide attackers with the ability to blend their activities with legitimate operations, making it easier to bypass security controls. If an attacker compromises an application's certificate, they can escalate their privileges within the system, leading to broader access and control, depending on the privileges of the application.\n\n**Remediation action**\n\n- [Define certificate based application configuration](https://devblogs.microsoft.com/identity/app-management-policy/)\n- [Define trusted certificate authorities for apps and service principals in the tenant](https://learn.microsoft.com/graph/api/resources/certificatebasedapplicationconfiguration?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci)\n- [Define application management policies](https://learn.microsoft.com/graph/api/resources/applicationauthenticationmethodpolicy?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci)\n- [Enforce secret and certificate standards](https://learn.microsoft.com/entra/identity/enterprise-apps/tutorial-enforce-secret-standards?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci)\n- [Create a least-privileged custom role to rotate application credentials](https://learn.microsoft.com/entra/identity/role-based-access-control/custom-create?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci)\n","TestId":"21773"},{"TestImpact":"Medium","TestRisk":"Medium","TestSkipped":"","TestAppliesTo":null,"TestPillar":"Data","TestCategory":"Microsoft Purview Message Encryption","TestDescription":"The SimplifiedClientAccessEnabled setting controls whether the Protect button appears in Outlook on the web. This button lets users quickly add encryption to their emails. If the setting is not turned on, users cannot use the Protect button and must find other ways to encrypt their messages.\n\nTo enable this setting, AzureRMSLicensingEnabled must also be active. Azure Rights Management encryption service provides the encryption technology needed for the Protect button to work.\n\n**Remediation action**\n\n- [Manage the display of the Encrypt button in Outlook on the web](https://learn.microsoft.com/purview/manage-office-365-message-encryption?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci#manage-the-display-of-the-encrypt-button-in-outlook-on-the-web)\n","TestTitle":"Office 365 Message Encryption (OME) - SimplifiedClientAccessEnabled","SkippedReason":null,"TestId":"35026","TestImplementationCost":"Low","TestMinimumLicense":["RMS_S_PREMIUM"],"TestSfiPillar":"Protect tenants and production systems","TestResult":"\n✅ SimplifiedClientAccessEnabled is true (Protect button enabled) and AzureRMSLicensingEnabled is true (encryption foundation active).\n\n\n### OME SimplifiedClientAccess Status\n\n| Setting | Value |\n| :------ | :---- |\n| SimplifiedClientAccessEnabled | True |\n| AzureRMSLicensingEnabled | True |\n| InternalLicensingEnabled | True |\n\n\n**Summary:**\n\n* Protect Button Status: ✅ Enabled\n\n\n","TestStatus":"Passed","TestTags":null},{"TestImplementationCost":"Low","TestPillar":"Identity","TestCategory":"Access control","SkippedReason":null,"TestImpact":"Medium","TestAppliesTo":["Identity"],"TestSfiPillar":"Protect identities and secrets","TestSkipped":"","TestMinimumLicense":"P1","TestTags":["User","Credential"],"TestTitle":"Block legacy authentication policies are configured","TestRisk":"Medium","TestResult":"\nConditional Access to block legacy Authentication are configured and enabled.\n\n - [Block legacy authentication](https://entra.microsoft.com/#view/Microsoft_AAD_ConditionalAccess/PolicyBlade/policyId/4086128c-3850-48ac-8962-e19a956828bd) (Report-only)\n - [Block legacy authentication - Testing](https://entra.microsoft.com/#view/Microsoft_AAD_ConditionalAccess/PolicyBlade/policyId/bedecc1e-85c9-4d54-b885-cefe6bcc8763) (Report-only)\n - [Block access except Compliant Network](https://entra.microsoft.com/#view/Microsoft_AAD_ConditionalAccess/PolicyBlade/policyId/9ee6df4b-165d-4f86-a176-0ddcc4ad886c)\n\n\n","TestStatus":"Passed","TestDescription":"Legacy authentication protocols such as basic authentication for SMTP and IMAP don't support modern security features like multifactor authentication (MFA), which is crucial for protecting against unauthorized access. This lack of protection makes accounts using these protocols vulnerable to password-based attacks, and provides attackers with a means to gain initial access using stolen or guessed credentials.\n\nWhen an attacker successfully gains unauthorized access to credentials, they can use them to access linked services, using the weak authentication method as an entry point. Attackers who gain access through legacy authentication might make changes to Microsoft Exchange, such as configuring mail forwarding rules or changing other settings, allowing them to maintain continued access to sensitive communications.\n\nLegacy authentication also provides attackers with a consistent method to reenter a system using compromised credentials without triggering security alerts or requiring reauthentication.\n\nFrom there, attackers can use legacy protocols to access other systems that are accessible via the compromised account, facilitating lateral movement. Attackers using legacy protocols can blend in with legitimate user activities, making it difficult for security teams to distinguish between normal usage and malicious behavior.\n\n**Remediation action**\n\n- [Deploy a Conditional Access policy to Block legacy authentication](https://learn.microsoft.com/entra/identity/conditional-access/policy-block-legacy-authentication?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci)\n","TestId":"21796"},{"TestImplementationCost":"Medium","TestPillar":"Identity","TestCategory":"Application management","SkippedReason":null,"TestImpact":"Medium","TestAppliesTo":null,"TestSfiPillar":"Protect engineering systems","TestSkipped":"","TestMinimumLicense":"P1","TestTags":null,"TestTitle":"Enterprise applications must require explicit assignment or scoped provisioning","TestRisk":"Medium","TestResult":"\nFound enterprise applications that lack both assignment requirements and provisioning scoping.\n## Applications without provisioning jobs (1)\n\n| Display name | Reason |\n| :----------- | :----- |\n| [21869testapp](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/Overview/objectId/e69e29be-ba40-445a-9824-a3a45e0ae57a/appId/dd63d132-18fb-4f2e-aec4-82b97f30301f) | No provisioning jobs configured |\n\n\n\n","TestStatus":"Failed","TestDescription":"When enterprise applications lack both explicit assignment requirements AND scoped provisioning controls, threat actors can exploit this dual weakness to gain unauthorized access to sensitive applications and data. The highest risk occurs when applications are configured with the default setting: \"Assignment required\" is set to \"No\" *and* provisioning isn't required or scoped. This dangerous combination allows threat actors who compromise any user account within the tenant to immediately access applications with broad user bases, expanding their attack surface and potential for lateral movement within the organization.\n\nWhile an application with open assignment but proper provisioning scoping (such as department-based filters or group membership requirements) maintains security controls through the provisioning layer, applications lacking both controls create unrestricted access pathways that threat actors can exploit. When applications provision accounts for all users without assignment restrictions, threat actors can abuse compromised accounts to conduct reconnaissance activities, enumerate sensitive data across multiple systems, or use the applications as staging points for further attacks against connected resources. This unrestricted access model is dangerous for applications that have elevated permissions or are connected to critical business systems. Threat actors can use any compromised user account to access sensitive information, modify data, or perform unauthorized actions that the application's permissions allow. The absence of both assignment controls and provisioning scoping also prevents organizations from implementing proper access governance. Without proper governance, it's difficult to track who has access to which applications, when access was granted, and whether access should be revoked based on role changes or employment status. Furthermore, applications with broad provisioning scopes can create cascading security risks where a single compromised account provides access to an entire ecosystem of connected applications and services.\n\n**Remediation action**\n- Evaluate business requirements to determine appropriate access control method. [Restrict a Microsoft Entra app to a set of users](https://learn.microsoft.com/entra/identity-platform/howto-restrict-your-app-to-a-set-of-users?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci).\n- Configure enterprise applications to require assignment for sensitive applications. [Learn about the \"Assignment required\" enterprise application property](https://learn.microsoft.com/entra/identity/enterprise-apps/application-properties?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci#assignment-required).\n- Implement scoped provisioning based on groups, departments, or attributes. [Create scoping filters](https://learn.microsoft.com/entra/identity/app-provisioning/define-conditional-rules-for-provisioning-user-accounts?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci#create-scoping-filters).\n","TestId":"21869"},{"TestImplementationCost":"Medium","TestPillar":"Identity","TestCategory":"Access control; Credential management","SkippedReason":null,"TestImpact":"Low","TestAppliesTo":null,"TestSfiPillar":"Protect identities and secrets","TestSkipped":"","TestMinimumLicense":"P1","TestTags":null,"TestTitle":"All user sign in activity uses phishing-resistant authentication methods","TestRisk":"Medium","TestResult":"\n❌ Not all users are protected by Conditional Access policies requiring phishing-resistant authentication methods.\n\n**Reason**: Found policies with user exclusions that create coverage gaps\n## Conditional Access Policies with Phishing-Resistant Authentication (Issues Found)\n\n| Policy | Authentication strength | Included Users | Excluded Users |\n| :---------- | :---------------------- | :------------- | :------------- |\n| [Security regisrtation info](https://entra.microsoft.com/#view/Microsoft_AAD_ConditionalAccess/PolicyBlade/policyId/508ae024-d4c4-42bf-a8c9-40257c214c10) | [Multifactor authentication](https://entra.microsoft.com/#view/Microsoft_AAD_ConditionalAccess/ConditionalAccessBlade/~/AuthStrengths/menuId//fromNav/Identity) | All Users | ⚠️ 3 users |\n\n\n\n","TestStatus":"Failed","TestDescription":"Phishing-resistant authentication methods like passkeys and FIDO2 security keys provide the strongest protection against credential theft and sophisticated phishing attacks. Traditional MFA methods remain vulnerable to adversary-in-the-middle attacks and social engineering. Enforcing phishing-resistant methods for all users through Conditional Access policies helps prevent unauthorized access even when attackers attempt to intercept authentication flows.\n\n**Remediation action**\n\n- [Configure Conditional Access for all users with MFA strength](https://learn.microsoft.com/entra/identity/conditional-access/policy-all-users-mfa-strength?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci)\n- [Deploy phishing-resistant passwordless authentication](https://learn.microsoft.com/entra/identity/authentication/how-to-deploy-phishing-resistant-passwordless-authentication?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci)\n","TestId":"21784"},{"TestImplementationCost":"High","TestPillar":null,"TestCategory":"Application management","SkippedReason":"UnderConstruction","TestImpact":"Low","TestAppliesTo":["Identity"],"TestSfiPillar":"","TestSkipped":"UnderConstruction","TestMinimumLicense":null,"TestTags":["Identity"],"TestTitle":"Line-of-business and partner apps use MSAL","TestRisk":"Medium","TestResult":"\nPlanned for future release.\n","TestStatus":"Planned","TestDescription":"...\n\n**Remediation action**\n\n","TestId":"21778"},{"TestImpact":"Low","TestRisk":"Low","TestSkipped":"NoCompatibleLicenseFound","TestAppliesTo":null,"TestPillar":"Network","TestCategory":"Global Secure Access","TestDescription":"Global Secure Access maintains a system bypass list of destinations that are automatically excluded from Transport Layer Security (TLS) inspection. These bypass destinations represent known incompatibilities such as certificate pinning, mutual TLS requirements, or other technical constraints. Custom bypass rules that duplicate destinations in the system bypass list are redundant and serve no functional purpose.\n\nRedundant rules consume policy capacity, create administrative overhead, and can cause confusion about which rules are necessary. TLS inspection supports up to 1,000 rules and 8,000 destinations per tenant. Maintaining a clean policy configuration with only necessary custom bypass rules improves manageability, simplifies security audits, and ensures that policy capacity is available for legitimate business requirements.\n\n**Remediation action**\n\n- Review and remove redundant custom TLS inspection bypass rules in the Microsoft Entra admin center. Navigate to **Global Secure Access** > **Secure** > **TLS inspection policies**.\n- Review [the destinations included in the system bypass list](https://learn.microsoft.com/entra/global-secure-access/faq-transport-layer-security?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci#what-destinations-are-included-in-the-system-bypass).\n","TestTitle":"TLS inspection custom bypass rules don't duplicate system bypass destinations","SkippedReason":"This test requires one of the following licenses: (\"Entra_Premium_Internet_Access\"). Please ensure your tenant has the appropriate licenses to run this test. See [Licensing & Service Plans](https://learn.microsoft.com/entra/identity/users/licensing-service-plan-reference)","TestId":"27004","TestImplementationCost":"Low","TestMinimumLicense":["Entra_Premium_Internet_Access"],"TestSfiPillar":"Protect networks","TestResult":"\nSkipped. This test requires one of the following licenses: (\"Entra_Premium_Internet_Access\"). Please ensure your tenant has the appropriate licenses to run this test. See [Licensing & Service Plans](https://learn.microsoft.com/entra/identity/users/licensing-service-plan-reference)\n\n","TestStatus":"Skipped","TestTags":null},{"TestImpact":"Low","TestRisk":"Medium","TestSkipped":"NoCompatibleLicenseFound","TestAppliesTo":null,"TestPillar":"Network","TestCategory":"Global Secure Access","TestDescription":"Global Secure Access deployment logs track the status and progress of configuration changes across the global network. These changes include forwarding profile redistributions, remote network updates, filtering profile changes, and changes to Conditional Access settings. If deployment logs show failed deployments, threat actors can exploit inconsistent security configurations where some edge locations have outdated or misconfigured policies.\n\nIf you don't monitor deployment logs:\n\n- Failed deployments can leave security gaps such as outdated forwarding profiles that don't route traffic through security inspection, or filtering profiles that don't block malicious destinations.\n- Administrators might remain unaware of outdated configurations, believing that changes are applied uniformly.\n- Deployment failures that create exploitable gaps can go undetected.\n\n**Remediation action**\n\n- Follow the steps in [How to use the Global Secure Access deployment logs](https://learn.microsoft.com/entra/global-secure-access/how-to-view-deployment-logs?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci) to:\n - Access and review deployment logs in the Microsoft Entra admin center to identify failed deployments.\n - For failed deployments, examine the error message in the `status.message` field and retry the configuration change that triggered the failure.\n - Monitor deployment notifications that appear in the admin center when making configuration changes to catch failures in real-time.\n- If deployments consistently fail for remote networks, [review the underlying remote network configuration](https://learn.microsoft.com/entra/global-secure-access/how-to-manage-remote-networks?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci) for errors.\n- For forwarding profile deployment failures, [verify traffic forwarding configuration](https://learn.microsoft.com/entra/global-secure-access/concept-traffic-forwarding?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci).\n","TestTitle":"Global Secure Access deployment logs are populated and reviewed","SkippedReason":"This test requires one of the following licenses: (\"Entra_Premium_Internet_Access\") OR (\"Entra_Premium_Private_Access\"). Please ensure your tenant has the appropriate licenses to run this test. See [Licensing & Service Plans](https://learn.microsoft.com/entra/identity/users/licensing-service-plan-reference)","TestId":"25422","TestImplementationCost":"Low","TestMinimumLicense":["Entra_Premium_Internet_Access","Entra_Premium_Private_Access"],"TestSfiPillar":"Monitor and detect cyberthreats","TestResult":"\nSkipped. This test requires one of the following licenses: (\"Entra_Premium_Internet_Access\") OR (\"Entra_Premium_Private_Access\"). Please ensure your tenant has the appropriate licenses to run this test. See [Licensing & Service Plans](https://learn.microsoft.com/entra/identity/users/licensing-service-plan-reference)\n\n","TestStatus":"Skipped","TestTags":null},{"TestImplementationCost":"Low","TestPillar":"Devices","TestCategory":"Device","SkippedReason":null,"TestImpact":"Medium","TestAppliesTo":null,"TestSfiPillar":"Protect tenants and isolate production systems","TestSkipped":"","TestMinimumLicense":"Intune","TestTags":null,"TestTitle":"macOS update policy is configured and assigned","TestRisk":"High","TestResult":"\nAt least one macOS update policy is assigned to a group.\n\n\n## macOS Update Policies\n\n| Policy Name | Status | Assignment Target |\n| :---------- | :----- | :---------------- |\n| [macOS_Update_1](https://intune.microsoft.com/#view/Microsoft_Intune_DeviceSettings/DevicesMenu/~/iOSiPadOSUpdate) | ✅ Assigned | **Included:** All Devices, **Excluded:** WFgroup |\n| [alex_macOS_SoftwareUpdate](https://intune.microsoft.com/#view/Microsoft_Intune_DeviceSettings/DevicesMenu/~/configuration) | ✅ Assigned | **Included:** All Devices, **Excluded:** WFgroup |\n| [alex_macOS_SoftwareUpdateEnforceLatest](https://intune.microsoft.com/#view/Microsoft_Intune_DeviceSettings/DevicesMenu/~/configuration) | ❌ Not assigned | None |\n\n\n\n","TestStatus":"Passed","TestDescription":"If macOS update policies aren’t properly configured and assigned, threat actors can exploit unpatched vulnerabilities in macOS devices within the organization. Without enforced update policies, devices remain on outdated software versions, increasing the attack surface for privilege escalation, remote code execution, or persistence techniques. Threat actors can leverage these weaknesses to gain initial access, escalate privileges, and move laterally within the environment. If policies exist but aren’t assigned to device groups, endpoints remain unprotected, and compliance gaps go undetected. This can result in widespread compromise, data exfiltration, and operational disruption.\n\nEnforcing macOS update policies ensures devices receive timely patches, reducing the risk of exploitation and supporting Zero Trust by maintaining a secure, compliant device fleet.\n\n**Remediation action**\n\nConfigure and assign macOS update policies in Intune to enforce timely patching and reduce risk from unpatched vulnerabilities: \n- [Manage macOS software updates in Intune](https://learn.microsoft.com/intune/intune-service/protect/software-updates-macos?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci)\n","TestId":"24690"},{"TestImplementationCost":"Low","TestPillar":"Identity","TestCategory":"Credential management","SkippedReason":null,"TestImpact":"Low","TestAppliesTo":null,"TestSfiPillar":"Protect identities and secrets","TestSkipped":"","TestMinimumLicense":"P1","TestTags":null,"TestTitle":"Microsoft Authenticator app report suspicious activity setting is enabled","TestRisk":"Medium","TestResult":"\nAuthenticator app report suspicious activity is [not enabled](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/AuthenticationMethodsMenuBlade/~/AuthMethodsSettings).\n\n","TestStatus":"Failed","TestDescription":"Threat actors increasingly rely on prompt bombing and real-time phishing proxies to coerce or trick users into approving fraudulent multifactor authentication (MFA) challenges. Without the Microsoft Authenticator app's **Report suspicious activity** capability enabled, an attacker can iterate until a fatigued user accepts. This type of attack can lead to privilege escalation, persistence, lateral movement into sensitive workloads, data exfiltration, or destructive actions.\n\nWhen reporting is enabled for all users, any unexpected push or phone prompt can be actively flagged, immediately elevating the user to high user risk and generating a high-fidelity user risk detection (userReportedSuspiciousActivity) that risk-based Conditional Access policies or other response automation can use to block or require secure remediation. \n\n**Remediation action**\n\n- [Enable the report suspicious activity setting in the Microsoft Authenticator app](https://learn.microsoft.com/entra/identity/authentication/howto-mfa-mfasettings?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci#report-suspicious-activity)\n","TestId":"21841"},{"TestImpact":"Medium","TestRisk":"High","TestSkipped":"NoCompatibleLicenseFound","TestAppliesTo":null,"TestPillar":"Network","TestCategory":"Global Secure Access","TestDescription":"If you don't deploy Microsoft Entra Private Access sensors to domain controllers, threat actors can exploit Kerberos authentication requests from any device on the network, including unmanaged or compromised endpoints. They can use this vulnerability to get service tickets for on-premises resources without multifactor authentication or device compliance validation.\n\nIf you don't deploy Private Access sensors to domain controllers:\n\n- Threat actors can request Kerberos tickets for privileged resources such as file shares, database servers, and remote desktop services. This vulnerability enables lateral movement across the on-premises environment.\n- Conditional Access policies don't apply to Kerberos authentication, because it operates within a perimeter-based trust model where any authenticated user can request tickets regardless of authentication strength or device posture.\n- Compromised user credentials obtained through phishing or credential theft can be immediately used to access domain-authenticated resources without triggering multifactor authentication requirements.\n\n**Remediation action**\n\n- [Configure Microsoft Entra Private Access for Active Directory domain controllers](https://learn.microsoft.com/entra/global-secure-access/how-to-configure-domain-controllers?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci).\n","TestTitle":"Private Access sensors are enforcing strong authentication policies on domain controllers","SkippedReason":"This test requires one of the following licenses: (\"Entra_Premium_Private_Access\"). Please ensure your tenant has the appropriate licenses to run this test. See [Licensing & Service Plans](https://learn.microsoft.com/entra/identity/users/licensing-service-plan-reference)","TestId":"25403","TestImplementationCost":"Medium","TestMinimumLicense":["Entra_Premium_Private_Access"],"TestSfiPillar":"Protect networks","TestResult":"\nSkipped. This test requires one of the following licenses: (\"Entra_Premium_Private_Access\"). Please ensure your tenant has the appropriate licenses to run this test. See [Licensing & Service Plans](https://learn.microsoft.com/entra/identity/users/licensing-service-plan-reference)\n\n","TestStatus":"Skipped","TestTags":null},{"TestImpact":"High","TestRisk":"Medium","TestSkipped":"","TestAppliesTo":null,"TestPillar":"Data","TestCategory":"Label Policy Configuration","TestDescription":"When users attach sensitive documents to emails, the email should inherit the highest sensitivity label from attachments to maintain consistent protection. Without this setting enabled, users might send unlabeled emails that contain sensitive attachments, creating a mismatch between the email's sensitivity and its actual content.\n\nEmail label inheritance automatically applies the attachment's highest priority label to the email message, ensuring protection levels match and prevent accidental data exposure.\n\n**Remediation action**\n\n- [Publish sensitivity labels](https://learn.microsoft.com/purview/create-sensitivity-labels?tabs=modern-label-scheme&wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci#publish-sensitivity-labels-by-creating-a-label-policy) to [Configure label inheritance from email attachments](https://learn.microsoft.com/purview/sensitivity-labels-office-apps?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci#configure-label-inheritance-from-email-attachments).\n","TestTitle":"Email label inheritance from attachments configured","SkippedReason":null,"TestId":"35014","TestImplementationCost":"Low","TestMinimumLicense":["RMS_S_PREMIUM"],"TestSfiPillar":"Protect tenants and production systems","TestResult":"\n❌ Email label inheritance is not configured. No label policies have the `attachmentaction` setting enabled, or no labels are scoped to both files and emails to participate in inheritance.\n\n\n### [Dual-scoped labels (ready for inheritance)](https://purview.microsoft.com/informationprotection/informationprotectionlabels/sensitivitylabels)\n\n| Label name | Content type | Priority |\n| :--------- | :----------- | :------- |\n| alex-test-label-1-display | Files & Emails | 0 |\n| 35010Test | Files & Emails | 1 |\n| peyton | Files & Emails | 3 |\n| test-35012-1 | Files & Emails | 4 |\n| test35036 | Files & Emails | 6 |\n| 35014-parker | Files & Emails | 8 |\n\n**Summary:**\n\n- Policies with attachmentaction enabled: 0\n- Labels with Files & Emails scope: 6\n- Inheritance setting found: False\n\n\n","TestStatus":"Failed","TestTags":null},{"TestImplementationCost":"Medium","TestPillar":"Identity","TestCategory":"Access control","SkippedReason":"UnderConstruction","TestImpact":"Medium","TestAppliesTo":["Identity"],"TestSfiPillar":"Protect identities and secrets","TestSkipped":"UnderConstruction","TestMinimumLicense":null,"TestTags":["Identity"],"TestTitle":"Guest access is restricted","TestRisk":"Medium","TestResult":"\nPlanned for future release.\n","TestStatus":"Planned","TestDescription":"...\n\n**Remediation action**\n\n","TestId":"21821"},{"TestImplementationCost":"Low","TestPillar":"Identity","TestCategory":"Credential management","SkippedReason":null,"TestImpact":"Low","TestAppliesTo":["Identity"],"TestSfiPillar":"Protect identities and secrets","TestSkipped":"","TestMinimumLicense":"P1","TestTags":["Identity"],"TestTitle":"Temporary access pass restricted to one-time use","TestRisk":"Low","TestResult":"\nTemporary Access Pass is configured for one-time use only.\n\n\n## Temporary Access Pass Configuration\n\n| Setting | Value | Status |\n| :------ | :---- | :----- |\n| [One-time use restriction](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/AuthenticationMethodsMenuBlade/~/AdminAuthMethods/fromNav/) | Enabled | ✅ Pass |\n\n\n","TestStatus":"Passed","TestDescription":"When Temporary Access Pass (TAP) is configured to allow multiple uses, threat actors who compromise the credential can reuse it repeatedly during its validity period, extending their unauthorized access window beyond the intended single bootstrapping event. This situation creates an extended opportunity for threat actors to establish persistence by registering additional strong authentication methods under the compromised account during the credential lifetime. A reusable TAP that falls into the wrong hands lets threat actors conduct reconnaissance activities across multiple sessions, gradually mapping the environment and identifying high-value targets while maintaining legitimate-looking access patterns. The compromised TAP can also serve as a reliable backdoor mechanism, allowing threat actors to maintain access even if other compromised credentials are detected and revoked, since the TAP appears as a legitimate administrative tool in security logs.\n\n**Remediation action**\n\n- [Configure Temporary Access Pass for one-time use in authentication methods policy](https://learn.microsoft.com/entra/identity/authentication/howto-authentication-temporary-access-pass?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci#enable-the-temporary-access-pass-policy)\n","TestId":"21846"},{"TestImplementationCost":"Medium","TestPillar":"Identity","TestCategory":"Credential management","SkippedReason":null,"TestImpact":"Medium","TestAppliesTo":null,"TestSfiPillar":"Protect identities and secrets","TestSkipped":"","TestMinimumLicense":"P1","TestTags":null,"TestTitle":"Migrate from legacy MFA and SSPR policies","TestRisk":"High","TestResult":"\nCombined registration is enabled.\n\n\n\n","TestStatus":"Passed","TestDescription":"Legacy multifactor authentication (MFA) and self-service password reset (SSPR) policies in Microsoft Entra ID manage authentication methods separately, leading to fragmented configurations and suboptimal user experience. Moreover, managing these policies independently increases administrative overhead and the risk of misconfiguration. \n\nMigrating to the combined Authentication Methods policy consolidates the management of MFA, SSPR, and passwordless authentication methods into a single policy framework. This unification allows for more granular control, enabling administrators to target specific authentication methods to user groups and enforce consistent security measures across the organization. Additionally, the unified policy supports modern authentication methods, such as FIDO2 security keys and Windows Hello for Business, enhancing the organization's security posture.\n\nMicrosoft announced the deprecation of legacy MFA and SSPR policies, with a retirement date set for September 30, 2025. Organizations are advised to complete the migration to the Authentication Methods policy before this date to avoid potential disruptions and to benefit from the enhanced security and management capabilities of the unified policy.\n\n**Remediation action**\n\n- [Enable combined security information registration](https://learn.microsoft.com/entra/identity/authentication/howto-registration-mfa-sspr-combined?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci)\n- [How to migrate MFA and SSPR policy settings to the Authentication methods policy for Microsoft Entra ID](https://learn.microsoft.com/entra/identity/authentication/how-to-authentication-methods-manage?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci)\n","TestId":"21803"},{"TestImplementationCost":"Low","TestPillar":"Devices","TestCategory":"Data","SkippedReason":null,"TestImpact":"Low","TestAppliesTo":null,"TestSfiPillar":"Protect tenants and isolate production systems","TestSkipped":"","TestMinimumLicense":"Intune","TestTags":null,"TestTitle":"Corporate Wi-Fi Network on macOS Devices is Securely Managed ","TestRisk":"High","TestResult":"\nNo Enterprise Wi-Fi profile for macOS exists or none are assigned.\n\n\n\n","TestStatus":"Failed","TestDescription":"If Wi-Fi profiles aren't properly configured and assigned, macOS devices can fail to connect to secure networks or connect insecurely, exposing corporate data to interception or unauthorized access. Without centralized management, devices rely on manual configuration, increasing the risk of misconfiguration, weak authentication, and connection to rogue networks. These gaps can lead to data interception, unauthorized network access, and compliance violations.\n\nCentrally managing Wi-Fi profiles for macOS devices in Intune ensures secure and consistent connectivity to enterprise networks. This enforces authentication and encryption standards, simplifies onboarding, and supports Zero Trust by reducing exposure to untrusted networks.\n\n**Remediation action**\n\nUse Intune to configure and assign secure Wi-Fi profiles for macOS devices to enforce authentication and encryption standards:\n\n- [Configure Wi-Fi settings for macOS devices in Intune](https://learn.microsoft.com/intune/intune-service/configuration/wi-fi-settings-configure?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci#create-the-profile)\n\nFor more information, see:\n\n- [Review the available Wi-Fi settings for macOS devices in Microsoft Intune](https://learn.microsoft.com/intune/intune-service/configuration/wi-fi-settings-macos?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci)\n","TestId":"24870"},{"TestImplementationCost":"Low","TestPillar":"Identity","TestCategory":"Devices","SkippedReason":null,"TestImpact":"Low","TestAppliesTo":null,"TestSfiPillar":"Protect tenants and isolate production systems","TestSkipped":"","TestMinimumLicense":"Free","TestTags":null,"TestTitle":"Restrict nonadministrator users from recovering the BitLocker keys for their owned devices","TestRisk":"High","TestResult":"\n[Non-administrator users are restricted from recovering BitLocker keys for their owned devices](https://entra.microsoft.com/#view/Microsoft_AAD_Devices/DevicesMenuBlade/~/DeviceSettings/menuId/Overview)\n\n","TestStatus":"Passed","TestDescription":"When non-administrator users can access their own BitLocker keys, threat actors who compromise user credentials gain direct access to encryption keys without requiring privilege escalation. Once attackers obtain BitLocker keys, they can decrypt sensitive data stored on the device, including cached credentials, local databases, and confidential files.\n\nWithout proper restrictions, a single compromised user account provides immediate access to all encrypted data on that device, negating the primary security benefit of disk encryption and creating a pathway for lateral movement. \n\n**Remediation action**\n\n- [Restrict non-admin users from recovering the BitLocker key(s) for their owned devices](https://learn.microsoft.com/entra/identity/devices/manage-device-identities?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci#configure-device-settings)\n","TestId":"21954"},{"TestImpact":"Medium","TestRisk":"High","TestSkipped":"NoCompatibleLicenseFound","TestAppliesTo":null,"TestPillar":"Network","TestCategory":"Global Secure Access","TestDescription":"When Microsoft Entra Private Access applications lack user or group assignments, users can't establish tunnels through the application to reach the configured fully qualified domain names (FQDNs) and IP addresses. This restriction prevents access to protected internal resources. Without assignments, organizations can't enforce Conditional Access policies because these policies require explicit user-to-application relationships to evaluate risk signals, device compliance, and authentication strength requirements.\n\nWithout user assignments on Private Access applications:\n\n- Organizations lose the ability to enforce least privilege access controls where users get access only to the specific resources they need.\n- Organizations can't apply risk-based access policies that block or challenge authentication based on sign-in risk, user risk, or device compliance.\n- Identity protection signals that detect credential compromise, impossible travel, or anonymous IP addresses can't protect private resources.\n\n**Remediation action**\n\n- [Assign users and groups to Private Access applications](https://learn.microsoft.com/entra/global-secure-access/how-to-configure-per-app-access?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci#assign-users-and-groups) to enable Zero Trust access controls and Conditional Access enforcement.\n","TestTitle":"All Private Access apps have user or group assignments","SkippedReason":"This test requires one of the following licenses: (\"Entra_Premium_Private_Access\"). Please ensure your tenant has the appropriate licenses to run this test. See [Licensing & Service Plans](https://learn.microsoft.com/entra/identity/users/licensing-service-plan-reference)","TestId":"25481","TestImplementationCost":"Low","TestMinimumLicense":["Entra_Premium_Private_Access"],"TestSfiPillar":"Protect networks","TestResult":"\nSkipped. This test requires one of the following licenses: (\"Entra_Premium_Private_Access\"). Please ensure your tenant has the appropriate licenses to run this test. See [Licensing & Service Plans](https://learn.microsoft.com/entra/identity/users/licensing-service-plan-reference)\n\n","TestStatus":"Skipped","TestTags":null},{"TestImplementationCost":"Medium","TestPillar":"Network","TestCategory":"Azure Network Security","SkippedReason":"This test is not applicable to the current environment.","TestImpact":"Low","TestAppliesTo":null,"TestSfiPillar":"Protect networks","TestSkipped":"NotApplicable","TestMinimumLicense":"Azure_WAF","TestTags":null,"TestTitle":"Rate Limiting is Enabled in Azure Front Door WAF","TestRisk":"High","TestResult":"\nNo Azure Front Door WAF policies attached to Azure Front Door found.\n","TestStatus":"Skipped","TestDescription":"Azure Front Door Web Application Firewall (WAF) supports rate limiting through custom rules that restrict the number of requests clients can make within a specified time window across the global edge network. Rate limiting is a critical defense mechanism that protects applications from abuse by throttling clients that exceed defined request thresholds before traffic reaches origin servers.\n\nWithout rate limiting configured, threat actors can execute brute force attacks, credential stuffing attacks, API abuse, and application-layer denial of service attacks that flood endpoints with requests to exhaust server capacity.\n\nRate limiting rules use the `RateLimitRule` rule type and allow administrators to define thresholds based on request count per minute, with the ability to group requests by client IP address. When a client exceeds the configured threshold, the WAF can block subsequent requests, log the violation, issue a CAPTCHA challenge, or redirect to a custom page.\n\nThis check identifies Azure Front Door WAF policies that are attached to an Azure Front Door and verifies that at least one rate limiting rule is configured and enabled.\n\n**Remediation action**\n\n- [Azure Web Application Firewall on Azure Front Door](https://learn.microsoft.com/en-us/azure/web-application-firewall/afds/afds-overview)\n- [Web Application Firewall custom rules for Azure Front Door](https://learn.microsoft.com/en-us/azure/web-application-firewall/afds/waf-front-door-custom-rules)\n- [Rate limiting for Azure Front Door WAF](https://learn.microsoft.com/en-us/azure/web-application-firewall/afds/waf-front-door-rate-limit)\n- [Tutorial: Create a Web Application Firewall policy on Azure Front Door](https://learn.microsoft.com/en-us/azure/web-application-firewall/afds/waf-front-door-create-portal)\n\n","TestId":27018},{"TestImplementationCost":"Medium","TestPillar":"Identity","TestCategory":"Access control","SkippedReason":"UnderConstruction","TestImpact":"Low","TestAppliesTo":["Identity"],"TestSfiPillar":"Protect identities and secrets","TestSkipped":"UnderConstruction","TestMinimumLicense":null,"TestTags":["Identity"],"TestTitle":"No nested groups in PIM for groups","TestRisk":"Medium","TestResult":"\nPlanned for future release.\n","TestStatus":"Planned","TestDescription":"...\n\n**Remediation action**\n\n","TestId":"21882"},{"TestImpact":"Medium","TestRisk":"High","TestSkipped":"","TestAppliesTo":null,"TestPillar":"Data","TestCategory":"Data Security Posture Management","TestDescription":"Until organizations use Insider Risk Management with Adaptive Protection, they could fail to detect insider threats, risky behaviors such as misuse of legitimate access to exfiltrate data, or unsafe AI scenarios where users expose sensitive data to large language models or unauthorized cloud AI services.\n\nInsider Risk Management works with Data Loss Prevention (DLP) to combine user behavior signals with content-based rules, helping teams detect risks early and respond before sensitive data is exposed or compromised.\n\n**Remediation action**\n\n- [Create and configure Insider Risk Management policies](https://learn.microsoft.com/purview/insider-risk-management-policies?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci)\n- [Help dynamically mitigate risks with Adaptive Protection](https://learn.microsoft.com/purview/insider-risk-management-adaptive-protection?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci)\n","TestTitle":"Insider Risk Management Policies Enabled for Risky AI Usage","SkippedReason":null,"TestId":"35038","TestImplementationCost":"Medium","TestMinimumLicense":["EXCHANGE_S_ENTERPRISE"],"TestSfiPillar":"Protect tenants and production systems","TestResult":"\n❌ No Insider Risk Management Policies are enabled with Adaptive Protection, creating a critical gap in insider threat detection and risky AI usage prevention.\n## Summary\n\n- **Total IRM Policies:** 2\n- **Enabled Policies with Adaptive Protection:** 0\n## [IRM Policies](https://purview.microsoft.com/insiderriskmgmt/policiespage)\n\n| Policy Name | Enabled | Adaptive Protection (OptInDrpForDlp) | Created Date |\n|:---|:---|:---|:---|\n| Data leaks quick policy - 1/13/2026 | ✅ Enabled | ❌ Disabled | 2026-01-13 |\n| IRM_Tenant_Setting_0817c655-a853-4d8f-9723-3a333b5b9235 | ✅ Enabled | ❌ Disabled | 2026-01-09 |\n\n\n","TestStatus":"Failed","TestTags":null},{"TestImplementationCost":"Low","TestPillar":"Network","TestCategory":"Azure Network Security","SkippedReason":"This test is not applicable to the current environment.","TestImpact":"Low","TestAppliesTo":null,"TestSfiPillar":"Protect networks","TestSkipped":"NotApplicable","TestMinimumLicense":"Azure_Firewall_Premium","TestTags":null,"TestTitle":"Inspection of Outbound TLS Traffic is Enabled on Azure Firewall","TestRisk":"High","TestResult":"\nSkipped. This test is not applicable to the current environment.\n","TestStatus":"Skipped","TestDescription":"Azure Firewall Premium offers Transport Layer Security (TLS) inspection to decrypt and inspect outbound and east-west TLS traffic, and inbound TLS traffic when used with Azure Application Gateway. TLS inspection is critical for detecting advanced threats that use encrypted channels to evade traditional security controls.\n\nWhen TLS inspection is enabled, Azure Firewall uses a customer-provided CA certificate stored in Azure Key Vault to decrypt, inspect, and then re-encrypt traffic before forwarding it to its destination. This enables advanced security capabilities such as IDPS and URL filtering to analyze encrypted traffic and identify malicious activity that would otherwise remain hidden.\n\nThis check verifies that Azure Firewall Premium has TLS inspection enabled. Without TLS inspection, the firewall cannot inspect encrypted payloads, significantly limiting visibility into threats that leverage TLS to evade detection.\n\n**Remediation action**\n\n- [Azure Firewall Premium features implementation guide](https://learn.microsoft.com/en-us/azure/firewall/premium-features)\n- [Deploy and configure Enterprise CA certificates for Azure Firewall](https://learn.microsoft.com/en-us/azure/firewall/premium-deploy-certificates-enterprise-ca)\n- [Azure Firewall Premium certificates](https://learn.microsoft.com/en-us/azure/firewall/premium-certificates)\n\n","TestId":25550},{"TestImplementationCost":"Medium","TestPillar":"Identity","TestCategory":"Access control","SkippedReason":"UnderConstruction","TestImpact":"Low","TestAppliesTo":["Identity"],"TestSfiPillar":"Protect identities and secrets","TestSkipped":"UnderConstruction","TestMinimumLicense":null,"TestTags":["Identity"],"TestTitle":"Azure subscriptions used by Identity Governance are secured consistently with Identity Governance roles","TestRisk":"High","TestResult":"\nPlanned for future release.\n","TestStatus":"Planned","TestDescription":"...\n\n**Remediation action**\n\n","TestId":"21881"},{"TestImpact":"Low","TestRisk":"High","TestSkipped":"NoCompatibleLicenseFound","TestAppliesTo":null,"TestPillar":"Network","TestCategory":"Network security","TestDescription":"When Microsoft 365 traffic bypasses Global Secure Access, organizations lose visibility and control over their most critical productivity workloads. Threat actors who exploit unmonitored Microsoft 365 connections can exfiltrate sensitive data through SharePoint, OneDrive, or Exchange without triggering security policies or generating actionable telemetry. Token theft and replay attacks become more difficult to detect when traffic doesn't flow through the Security Service Edge because source IP correlation with sign-in logs and Conditional Access evaluation can't be applied consistently.\n\nOrganizations with significant bypassed traffic, whether due to incomplete client deployment, misconfigured forwarding profiles, or users on unmanaged devices, create blind spots where adversary-in-the-middle attacks, credential harvesting, and unauthorized data transfers can proceed undetected. Traffic that bypasses Global Secure Access also can't benefit from compliant network checks in Conditional Access policies, tenant restrictions, or source IP restoration, leaving significant security controls ineffective.\n\n**Remediation action**\n- Enable and configure the Microsoft traffic profile. For more information, see [Enable Microsoft traffic profile](https://learn.microsoft.com/entra/global-secure-access/how-to-manage-microsoft-profile?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci).\n- Deploy the Global Secure Access client to all managed devices. For more information, see [Deploy Global Secure Access client](https://learn.microsoft.com/entra/global-secure-access/how-to-install-windows-client?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci).\n- Review and configure traffic forwarding rules appropriately. For more information, see [Review traffic forwarding rules](https://learn.microsoft.com/entra/global-secure-access/concept-microsoft-traffic-profile?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci).\n","TestTitle":"Microsoft 365 traffic is actively flowing through Global Secure Access","SkippedReason":"This test requires one of the following licenses: (\"Entra_Premium_Private_Access\") OR (\"Entra_Premium_Internet_Access\"). Please ensure your tenant has the appropriate licenses to run this test. See [Licensing & Service Plans](https://learn.microsoft.com/entra/identity/users/licensing-service-plan-reference)","TestId":"25376","TestImplementationCost":"Medium","TestMinimumLicense":["Entra_Premium_Private_Access","Entra_Premium_Internet_Access"],"TestSfiPillar":"Protect networks","TestResult":"\nSkipped. This test requires one of the following licenses: (\"Entra_Premium_Private_Access\") OR (\"Entra_Premium_Internet_Access\"). Please ensure your tenant has the appropriate licenses to run this test. See [Licensing & Service Plans](https://learn.microsoft.com/entra/identity/users/licensing-service-plan-reference)\n\n","TestStatus":"Skipped","TestTags":null},{"TestImplementationCost":"Low","TestPillar":"Identity","TestCategory":"Access control","SkippedReason":"UnderConstruction","TestImpact":"Low","TestAppliesTo":["Identity"],"TestSfiPillar":"Protect identities and secrets","TestSkipped":"UnderConstruction","TestMinimumLicense":null,"TestTags":["Identity"],"TestTitle":"Directory sync account is locked down to specific named location","TestRisk":"Low","TestResult":"\nPlanned for future release.\n","TestStatus":"Planned","TestDescription":"...\n\n**Remediation action**\n\n","TestId":"21834"},{"TestImpact":"Medium","TestRisk":"High","TestSkipped":"","TestAppliesTo":null,"TestPillar":"Data","TestCategory":"Advanced Classification","TestDescription":"Exact data match (EDM) is an advanced sensitive information type that detects organization-specific data by matching exact values against an uploaded reference database. Unlike pattern-based sensitive information types (SITs) that detect common formats, EDM identifies things like customer lists, employee IDs, or proprietary codes unique to your organization. Without EDM, auto-labeling policies and DLP rules can't detect this proprietary data, leaving it at risk of exposure.\n\n**Remediation action**\n\n- [Learn about exact data match based sensitive information types](https://learn.microsoft.com/purview/sit-learn-about-exact-data-match-based-sits?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci)\n- [Get started with exact data match based sensitive information types](https://learn.microsoft.com/purview/sit-get-started-exact-data-match-based-sits-overview?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci)\n","TestTitle":"Exact Data Match (EDM) Configurations","SkippedReason":null,"TestId":"35034","TestImplementationCost":"Medium","TestMinimumLicense":["EXCHANGE_S_ENTERPRISE"],"TestSfiPillar":"Protect tenants and production systems","TestResult":"\n✅ Exact Data Match (EDM) schemas are configured, enabling detection of organization-specific sensitive data patterns.\n\n\n## [Exact Data Match Schemas](https://purview.microsoft.com/informationprotection/dataclassification/exactdatamatch)\n\n| Schema name | Description | Version | Created date | Modified date |\n| :---------- | :---------- | :------ | :----------- | :------------ |\n| test | test edm | 1 | 01/28/2026 20:41:04 | 01/28/2026 20:41:04 |\n| test35034 | testing | 2 | 01/28/2026 20:40:03 | 01/28/2026 20:43:26 |\n\n**Summary:**\n* Total EDM Schemas: 2\n\n\n","TestStatus":"Passed","TestTags":null},{"TestImpact":"Medium","TestRisk":"Medium","TestSkipped":"NoCompatibleLicenseFound","TestAppliesTo":null,"TestPillar":"Network","TestCategory":"Global Secure Access","TestDescription":"Category-based filtering provides broader protection than URL-specific rules. Blocking entire website categories like malware, phishing, hacking, and criminal activity prevents access to thousands of malicious sites at once. Filtering policies that only target specific URLs or domains require constant maintenance and leave gaps as threat actors register new malicious domains daily.\n\n**Remediation action**\n\n- [Review available web content filtering categories](https://learn.microsoft.com/entra/global-secure-access/reference-web-content-filtering-categories?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci)\n- [Configure category-based filtering rules](https://learn.microsoft.com/entra/global-secure-access/how-to-configure-web-content-filtering?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci)\n","TestTitle":"Web content filtering uses category-based rules","SkippedReason":"This test requires one of the following licenses: (\"Entra_Premium_Internet_Access\"). Please ensure your tenant has the appropriate licenses to run this test. See [Licensing & Service Plans](https://learn.microsoft.com/entra/identity/users/licensing-service-plan-reference)","TestId":"25409","TestImplementationCost":"Medium","TestMinimumLicense":["Entra_Premium_Internet_Access"],"TestSfiPillar":"Protect networks","TestResult":"\nSkipped. This test requires one of the following licenses: (\"Entra_Premium_Internet_Access\"). Please ensure your tenant has the appropriate licenses to run this test. See [Licensing & Service Plans](https://learn.microsoft.com/entra/identity/users/licensing-service-plan-reference)\n\n","TestStatus":"Skipped","TestTags":null},{"TestImpact":"Low","TestRisk":"High","TestSkipped":"NoCompatibleLicenseFound","TestAppliesTo":null,"TestPillar":"Network","TestCategory":"Global Secure Access","TestDescription":"Universal Continuous Access Evaluation (Universal CAE) validates network access tokens every time a connection is established through Global Secure Access tunnels. Without Universal CAE, tokens remain valid for 60 to 90 minutes regardless of changes to user state.\n\nWithout this protection:\n\n- A threat actor who obtains a token through theft or replay can continue accessing all Global Secure Access-protected resources even after the user's account is disabled or password is reset.\n- Critical events like session revocation or high user risk detection don't prompt immediate reauthentication.\n- Departing employees or malicious insiders maintain network-level access to private corporate resources for up to 90 minutes after remediation action is taken.\n- Token replay attacks from different IP addresses aren't blocked without Strict Enforcement mode.\n\n**Remediation action**\n- Review the [Universal CAE](https://learn.microsoft.com/entra/global-secure-access/concept-universal-continuous-access-evaluation?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci) capabilities for Global Secure Access.\n- Remove or modify Conditional Access policies that disable CAE for Global Secure Access workloads. For more information, see [Continuous access evaluation](https://learn.microsoft.com/entra/identity/conditional-access/concept-continuous-access-evaluation?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci).\n- Configure Universal CAE to use Strict Enforcement mode for enhanced token replay protection. For more information, see [Universal Continuous Access Evaluation](https://learn.microsoft.com/entra/global-secure-access/concept-universal-continuous-access-evaluation?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci#strict-enforcement-mode).\n","TestTitle":"Network validation is configured through Universal Continuous Access Evaluation","SkippedReason":"This test requires one of the following licenses: (\"Entra_Premium_Private_Access\") OR (\"Entra_Premium_Internet_Access\"). Please ensure your tenant has the appropriate licenses to run this test. See [Licensing & Service Plans](https://learn.microsoft.com/entra/identity/users/licensing-service-plan-reference)","TestId":"25371","TestImplementationCost":"Low","TestMinimumLicense":["Entra_Premium_Private_Access","Entra_Premium_Internet_Access"],"TestSfiPillar":"Protect networks","TestResult":"\nSkipped. This test requires one of the following licenses: (\"Entra_Premium_Private_Access\") OR (\"Entra_Premium_Internet_Access\"). Please ensure your tenant has the appropriate licenses to run this test. See [Licensing & Service Plans](https://learn.microsoft.com/entra/identity/users/licensing-service-plan-reference)\n\n","TestStatus":"Skipped","TestTags":null},{"TestImplementationCost":"","TestPillar":"Infrastructure","TestCategory":"Remediate vulnerabilities","SkippedReason":"This test is not applicable to the current environment.","TestImpact":"","TestAppliesTo":null,"TestSfiPillar":"Protect tenants and isolate production systems","TestSkipped":"NotApplicable","TestMinimumLicense":"N/A","TestTags":null,"TestTitle":"Machines should have vulnerability findings resolved","TestRisk":"Low","TestResult":"Vulnerability assessment scanner is not deployed on the machine, Unsupported OS\n\n| Subscription | Resource group | Resource type | Affected resource | Status | Azure portal |\n| :----------- | :------------- | :------------ | :---------------- | :----- | :----------- |\n| [Visual Studio Enterprise Subscription](https://portal.azure.com/#resource/subscriptions/54d3ea01-5a07-45d0-8d69-e5f5b0b20098) | indiavm_group | virtualmachines | [india-2](https://portal.azure.com/#resource/subscriptions/54d3ea01-5a07-45d0-8d69-e5f5b0b20098/resourceGroups/INDIAVM_GROUP/providers/Microsoft.Compute/virtualMachines/india-2) | N/A | [View recommendation](https://portal.azure.com/#blade/Microsoft_Azure_Security/RecommendationsBlade/assessmentKey/1195afff-c881-495e-9bc5-1486211ae03f/resourceId/%2fsubscriptions%2f54d3ea01-5a07-45d0-8d69-e5f5b0b20098%2fresourceGroups%2fINDIAVM_GROUP%2fproviders%2fMicrosoft.Compute%2fvirtualMachines%2findia-2) |\n| [Visual Studio Enterprise Subscription](https://portal.azure.com/#resource/subscriptions/54d3ea01-5a07-45d0-8d69-e5f5b0b20098) | indiavm_group | virtualmachines | [indiavm](https://portal.azure.com/#resource/subscriptions/54d3ea01-5a07-45d0-8d69-e5f5b0b20098/resourceGroups/INDIAVM_GROUP/providers/Microsoft.Compute/virtualMachines/indiavm) | N/A | [View recommendation](https://portal.azure.com/#blade/Microsoft_Azure_Security/RecommendationsBlade/assessmentKey/1195afff-c881-495e-9bc5-1486211ae03f/resourceId/%2fsubscriptions%2f54d3ea01-5a07-45d0-8d69-e5f5b0b20098%2fresourceGroups%2fINDIAVM_GROUP%2fproviders%2fMicrosoft.Compute%2fvirtualMachines%2findiavm) |\n","TestStatus":"Skipped","TestDescription":"Resolving vulnerability findings on virtual machines is a recommended step in maintaining a secure environment.
\nThese findings, identified by vulnerability assessment solutions, highlight potential weaknesses that could be exploited by malicious actors.
\nIf these vulnerabilities are not addressed, they could lead to unauthorized access, data breaches, or even system failure.
\nTherefore, it is important to resolve these findings promptly to ensure the security and integrity of the virtual machines.
\n\n**Remediation action**\n\nReview and remediate vulnerabilities discovered by the vulnerability assessment solutions.","TestId":"1195afff-c881-495e-9bc5-1486211ae03f"},{"TestImplementationCost":"Medium","TestPillar":"Identity","TestCategory":"External collaboration","SkippedReason":null,"TestImpact":"Medium","TestAppliesTo":null,"TestSfiPillar":"Protect identities and secrets","TestSkipped":"","TestMinimumLicense":"P2","TestTags":null,"TestTitle":"All entitlement management assignment policies that apply to external users require approval","TestRisk":"Medium","TestResult":"\nNo access package assignment policies found that apply to external users.\n\n","TestStatus":"Passed","TestDescription":"Access package assignment policies that allow external users to request access should require approval. Without an approval gate, external users can self-provision access to organizational resources without oversight. Requiring approval ensures that a designated approver reviews each request, providing an opportunity to validate the requestor's identity and business justification before granting access.\n\n**Remediation action**\n\n- [Configure approval for access package assignment policies](https://learn.microsoft.com/entra/id-governance/entitlement-management-access-package-approval-policy?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci)\n- [Review access package policies for external users](https://learn.microsoft.com/entra/id-governance/entitlement-management-access-package-request-policy?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci)\n","TestId":"21879"},{"TestImplementationCost":"Low","TestPillar":"Identity","TestCategory":"Credential management","SkippedReason":null,"TestImpact":"Low","TestAppliesTo":null,"TestSfiPillar":"Protect identities and secrets","TestSkipped":"","TestMinimumLicense":"P1","TestTags":null,"TestTitle":"Smart lockout threshold set to 10 or less","TestRisk":"Medium","TestResult":"\nSmart lockout threshold is configured above 10.\n## Smart lockout configuration\n\n| Setting | Value |\n| :---- | :---- |\n| [Lockout threshold](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/AuthenticationMethodsMenuBlade/~/PasswordProtection/fromNav/) | 11 attempts|\n\n\n","TestStatus":"Failed","TestDescription":"When the smart lockout threshold is set to more than 10, threat actors can exploit the configuration to conduct reconnaissance, identify valid user accounts without triggering lockout protections, and establish initial access without detection. Once attackers gain initial access, they can move laterally through the environment by using the compromised account to access resources and escalate privileges.\n\nSmart lockout helps lock out bad actors who try to guess your users' passwords or use brute force methods to get in. Smart lockout recognizes sign-ins that come from valid users and treats them differently than ones of attackers and other unknown sources. A threshold of more than 10 provides insufficient protection against automated password spray attacks, making it easier for threat actors to compromise accounts while evading detection mechanisms. \n\n**Remediation action**\n\n- [Set Microsoft Entra smart lockout threshold to 10 or less](https://learn.microsoft.com/entra/identity/authentication/howto-password-smart-lockout?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci).\n","TestId":"21850"},{"TestImplementationCost":"Low","TestPillar":"Network","TestCategory":"Azure Network Security","SkippedReason":"This test is not applicable to the current environment.","TestImpact":"Low","TestAppliesTo":null,"TestSfiPillar":"Protect networks","TestSkipped":"NotApplicable","TestMinimumLicense":"Azure WAF","TestTags":null,"TestTitle":"HTTP DDoS Protection Ruleset is Enabled in Application Gateway WAF","TestRisk":"High","TestResult":"\nNo Application Gateway WAF policies found attached to Application Gateways.\n","TestStatus":"Skipped","TestDescription":"Azure Application Gateway Web Application Firewall (WAF) provides HTTP DDoS protection through the Microsoft HTTP DDoS Ruleset (Microsoft_HTTPDDoSRuleSet), which detects and mitigates volumetric HTTP-based attacks at the application layer. Unlike network-layer DDoS attacks that target bandwidth and infrastructure, HTTP-based DDoS attacks exploit the application layer by sending seemingly legitimate HTTP requests at extremely high volumes to exhaust server resources, database connections, and application threads. \n\nWithout HTTP DDoS protection enabled, threat actors can execute HTTP flood attacks that overwhelm backend servers with GET or POST requests at rates far exceeding normal traffic patterns, slowloris attacks that hold connections open by sending partial HTTP requests to exhaust connection pools, and high-frequency request patterns designed to trigger resource-intensive operations like complex database queries or file processing. \n\nThe HTTP DDoS ruleset contains rule groups like ExcessiveRequests with rules 500100 and 500110 that detect abnormal request rates based on configurable sensitivity levels (High, Medium, Low) and can block, log, or redirect malicious traffic. These rules identify clients making excessive requests within short time windows and can automatically block them before they impact application performance. By enabling this ruleset on Application Gateway WAF policies, malicious HTTP traffic is identified and blocked at the gateway before reaching backend application servers, preserving application availability and protecting infrastructure from resource exhaustion attacks.\n\n**Remediation action**\n\n- [What is Azure Web Application Firewall on Azure Application Gateway?](https://learn.microsoft.com/en-us/azure/web-application-firewall/ag/ag-overview) - Overview of WAF capabilities on Application Gateway including DDoS protection rulesets\n- [Web Application Firewall CRS rule groups and rules](https://learn.microsoft.com/en-us/azure/web-application-firewall/ag/application-gateway-crs-rulegroups-rules) - Documentation of available managed rulesets including HTTP DDoS rules\n- [Create Web Application Firewall policies for Application Gateway](https://learn.microsoft.com/en-us/azure/web-application-firewall/ag/create-waf-policy-ag) - Step-by-step guidance on creating and configuring WAF policies with managed rulesets\n- [Azure DDoS Protection overview](https://learn.microsoft.com/en-us/azure/ddos-protection/ddos-protection-overview) - Overview of Azure DDoS Protection capabilities including application-layer protection\n\n","TestId":27015},{"TestImplementationCost":"Low","TestPillar":"Identity","TestCategory":"Credential management","SkippedReason":"UnderConstruction","TestImpact":"Low","TestAppliesTo":["Identity"],"TestSfiPillar":"Protect identities and secrets","TestSkipped":"UnderConstruction","TestMinimumLicense":"P1","TestTags":["Identity"],"TestTitle":"Enable SSPR","TestRisk":"Low","TestResult":"\nPlanned for future release.\n\n","TestStatus":"Planned","TestDescription":"Without Self-Service Password Reset (SSPR) enabled, users with password-related issues must contact help desk support, which can cause in operational delays and lost productivity. There are also potential security vulnerabilities during the extended timeframe required for administrative password resets. These delays not only reduce employee efficiency (especially in time-sensitive roles), but also increase support costs and strain IT resources. During these periods, threat actors might exploit locked accounts through social engineering attacks targeting help desk personnel. Threat actors can potentially convince support staff to reset passwords for accounts they don't legitimately control, enabling initial access to user credentials.\n\nWhen users are unable to reset their own passwords through secure, automated processes, they frequently resort to insecure workarounds. Examples include sharing accounts with colleagues, using weak passwords that are easier to remember, or writing down passwords in discoverable locations, all of which expand the attack surface for credential harvesting techniques. The lack of SSPR forces users to maintain static passwords for longer periods between administrative resets. This type of password policy increases the likelihood that compromised credentials from previous breaches or password spray attacks remain valid and usable by threat actors. The absence of user-controlled password reset capabilities also delays the response time for users to secure their accounts when they suspect compromise. This delay allows threat actors extended persistence within compromised accounts to perform reconnaissance, establish other access methods, or exfiltrate sensitive data before the account is eventually reset through administrative channels \n\n**Remediation action**\n\n- [Enable Self-Service Password Reset](https://learn.microsoft.com/entra/identity/authentication/tutorial-enable-sspr?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci)\n","TestId":"21870"},{"TestImplementationCost":"Medium","TestPillar":"Identity","TestCategory":"External collaboration","SkippedReason":null,"TestImpact":"Medium","TestAppliesTo":["Identity"],"TestSfiPillar":"Protect tenants and isolate production systems","TestSkipped":"","TestMinimumLicense":"Free","TestTags":["Identity"],"TestTitle":"Allow/Deny lists of domains to restrict external collaboration are configured","TestRisk":"Medium","TestResult":"\nAllow/Deny lists of domains to restrict external collaboration are not configured.\n\n","TestStatus":"Failed","TestDescription":"Limiting guest access to a known and approved list of tenants helps to prevent threat actors from exploiting unrestricted guest access to establish initial access through compromised external accounts or by creating accounts in untrusted tenants. Threat actors who gain access through an unrestricted domain can discover internal resources, users, and applications to perform additional attacks. \n\nOrganizations should take inventory and configure an allowlist or blocklist to control B2B collaboration invitations from specific organizations. Without these controls, threat actors might use social engineering techniques to obtain invitations from legitimate internal users. \n\n**Remediation action**\n\n- Learn how to [set up a list of approved domains](https://learn.microsoft.com/entra/external-id/allow-deny-list?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci#add-an-allowlist).\n","TestId":"21874"},{"TestImplementationCost":"High","TestPillar":"Identity","TestCategory":"Access control","SkippedReason":"UnderConstruction","TestImpact":"High","TestAppliesTo":["Identity"],"TestSfiPillar":"Protect identities and secrets","TestSkipped":"UnderConstruction","TestMinimumLicense":null,"TestTags":["Identity"],"TestTitle":"All app assignment and group membership is governed","TestRisk":"Medium","TestResult":"\nPlanned for future release.\n","TestStatus":"Planned","TestDescription":"...\n\n**Remediation action**\n\n","TestId":"21897"},{"TestImplementationCost":"Low","TestPillar":"Devices","TestCategory":"Device","SkippedReason":null,"TestImpact":"Low","TestAppliesTo":null,"TestSfiPillar":"Protect identities and secrets","TestSkipped":"","TestMinimumLicense":"Intune","TestTags":null,"TestTitle":"Windows BitLocker policy is configured and assigned","TestRisk":"High","TestResult":"\nNo Windows BitLocker policy is configured or assigned.\n\n\n\n","TestStatus":"Failed","TestDescription":"Without a properly configured and assigned BitLocker policy in Intune, threat actors can exploit unencrypted Windows devices to gain unauthorized access to sensitive corporate data. Devices that lack enforced encryption are vulnerable to physical attacks, like disk removal or booting from external media, allowing attackers to bypass operating system security controls. These attacks can result in data exfiltration, credential theft, and further lateral movement within the environment.\n\nEnforcing BitLocker across managed Windows devices is critical for compliance with data protection regulations and for reducing the risk of data breaches.\n\n**Remediation action**\n\nUse Intune to enforce BitLocker encryption and monitor compliance across all managed Windows devices: \n- [Create a BitLocker policy for Windows devices in Intune](https://learn.microsoft.com/intune/intune-service/protect/encrypt-devices?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci#create-and-deploy-policy)\n- [Assign policies in Intune](https://learn.microsoft.com/intune/intune-service/configuration/device-profile-assign?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci#assign-a-policy-to-users-or-groups)\n- [Monitor device encryption with Intune](https://learn.microsoft.com/intune/intune-service/protect/encryption-monitor?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci)\n","TestId":"24550"},{"TestImplementationCost":"Medium","TestPillar":"Identity","TestCategory":"Access control","SkippedReason":null,"TestImpact":"Low","TestAppliesTo":null,"TestSfiPillar":"Protect identities and secrets","TestSkipped":"","TestMinimumLicense":"P1","TestTags":null,"TestTitle":"Privileged Microsoft Entra built-in roles are targeted with Conditional Access policies to enforce phishing-resistant methods","TestRisk":"High","TestResult":"\nSome privileged built-in roles don't have Conditional Access policies to enforce phishing-resistant authentication.\n\n\n\n## Conditional Access policies with phishing resistant authentication policies \n\nFound 4 phishing resistant Conditional Access policies.\n\n - [MFA CA Policy](https://entra.microsoft.com/#view/Microsoft_AAD_ConditionalAccess/PolicyBlade/policyId/e589544c-0c92-432e-86ae-4e4ef103eac8)\n - [Guest-Meferna-Woodgrove-PhishingResistantAuthStrength](https://entra.microsoft.com/#view/Microsoft_AAD_ConditionalAccess/PolicyBlade/policyId/0f0a0c1c-41b0-4c18-ae20-d02492d03737)\n - [NewphishingCA](https://entra.microsoft.com/#view/Microsoft_AAD_ConditionalAccess/PolicyBlade/policyId/3fe49849-5ab6-4717-a22d-aa42536eb560) (Disabled)\n - [test_21783](https://entra.microsoft.com/#view/Microsoft_AAD_ConditionalAccess/PolicyBlade/policyId/4028bb9f-c5f8-4035-9522-f0e3bdbacbcb)\n\n\n## Privileged roles\n\nFound 2 of 33 privileged built-in roles protected by phishing resistant authentication.\n\n| Role name | Phishing resistance enforced |\n| :--- | :---: |\n| Hybrid Identity Administrator | ✅ |\n| Security Administrator | ✅ |\n| Agent ID Administrator | ❌ |\n| AI Administrator | ❌ |\n| AI Reader | ❌ |\n| Application Administrator | ❌ |\n| Application Developer | ❌ |\n| Attribute Provisioning Administrator | ❌ |\n| Attribute Provisioning Reader | ❌ |\n| Authentication Administrator | ❌ |\n| Authentication Extensibility Administrator | ❌ |\n| Authentication Extensibility Password Administrator | ❌ |\n| B2C IEF Keyset Administrator | ❌ |\n| Cloud Application Administrator | ❌ |\n| Cloud Device Administrator | ❌ |\n| Conditional Access Administrator | ❌ |\n| Directory Writers | ❌ |\n| Domain Name Administrator | ❌ |\n| External Identity Provider Administrator | ❌ |\n| Global Administrator | ❌ |\n| Global Reader | ❌ |\n| Helpdesk Administrator | ❌ |\n| Identity Governance Administrator | ❌ |\n| Intune Administrator | ❌ |\n| Lifecycle Workflows Administrator | ❌ |\n| Partner Tier1 Support | ❌ |\n| Partner Tier2 Support | ❌ |\n| Password Administrator | ❌ |\n| Privileged Authentication Administrator | ❌ |\n| Privileged Role Administrator | ❌ |\n| Security Operator | ❌ |\n| Security Reader | ❌ |\n| User Administrator | ❌ |\n## Authentication strength policies\n\nFound 2 custom phishing resistant authentication strength policies.\n\n - [ACSC Maturity Level 3](https://entra.microsoft.com/#view/Microsoft_AAD_ConditionalAccess/ConditionalAccessBlade/~/AuthStrengths/fromNav/)\n - [Phishing-resistant MFA](https://entra.microsoft.com/#view/Microsoft_AAD_ConditionalAccess/ConditionalAccessBlade/~/AuthStrengths/fromNav/)\n\n\n","TestStatus":"Failed","TestDescription":"Without phishing-resistant authentication methods, privileged users are more vulnerable to phishing attacks. These types of attacks trick users into revealing their credentials to grant unauthorized access to attackers. If non-phishing-resistant authentication methods are used, attackers might intercept credentials and tokens, through methods like adversary-in-the-middle attacks, undermining the security of the privileged account.\n\nOnce a privileged account or session is compromised due to weak authentication methods, attackers might manipulate the account to maintain long-term access, create other backdoors, or modify user permissions. Attackers can also use the compromised privileged account to escalate their access even further, potentially gaining control over more sensitive systems.\n\n**Remediation action**\n\n- [Get started with a phishing-resistant passwordless authentication deployment](https://learn.microsoft.com/entra/identity/authentication/how-to-plan-prerequisites-phishing-resistant-passwordless-authentication?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci)\n- [Ensure that privileged accounts register and use phishing resistant methods](https://learn.microsoft.com/entra/identity/authentication/concept-authentication-strengths?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci#authentication-strengths)\n- [Deploy a Conditional Access policy to target privileged accounts and require phishing resistant credentials](https://learn.microsoft.com/entra/identity/conditional-access/policy-admin-phish-resistant-mfa?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci)\n- [Monitor authentication method activity](https://learn.microsoft.com/entra/identity/monitoring-health/concept-usage-insights-report?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci#authentication-methods-activity)\n","TestId":"21783"},{"TestImpact":"Low","TestRisk":"High","TestSkipped":"NotConnectedToService","TestAppliesTo":null,"TestPillar":"Data","TestCategory":"SharePoint Online","TestDescription":"When sensitivity label integration is disabled (the default) in SharePoint, files in SharePoint and OneDrive can't be labeled or display existing labels, and can't benefit from the additional protection of sensitivity labels that apply encryption. This protection gap leaves sensitive files unclassified and vulnerable to unauthorized access and external sharing.\n\nEnabling sensitivity labels in SharePoint allows users to apply labels by using Office for the web and SharePoint. It's also a requirement for default labeling for these locations, and for auto-labeling policies that can classify files automatically. Sensitivity labels for these files can also strengthen security for Microsoft 365 Copilot, and be used with data loss prevention policies and other Microsoft Purview solutions.\n\n**Remediation action**\n\n- [Enable sensitivity labels for files in SharePoint and OneDrive](https://learn.microsoft.com/purview/sensitivity-labels-sharepoint-onedrive-files?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci)\n","TestTitle":"Sensitivity labels are enabled for SharePoint and OneDrive","SkippedReason":"This test requires connection to the service(s) \"SharePointOnline\" currently disconnected. Please use _Connect-ZtAssessment_ to connect.","TestId":"35005","TestImplementationCost":"Low","TestMinimumLicense":["RMS_S_PREMIUM"],"TestSfiPillar":"Protect tenants and production systems","TestResult":"\nSkipped. This test requires connection to the service(s) \"SharePointOnline\" currently disconnected. Please use _Connect-ZtAssessment_ to connect.\n\n","TestStatus":"Skipped","TestTags":null},{"TestImplementationCost":"Low","TestPillar":"Identity","TestCategory":"Access control","SkippedReason":null,"TestImpact":"Low","TestAppliesTo":["Identity"],"TestSfiPillar":"Protect identities and secrets","TestSkipped":"","TestMinimumLicense":"P1","TestTags":["Identity"],"TestTitle":"Authentication transfer is blocked","TestRisk":"High","TestResult":"\nAuthentication transfer is blocked by Conditional Access Policy(s).\n## Conditional Access Policies targeting Authentication Transfer\n\n\n| Policy Name | Policy ID | State | Created | Modified |\n| :---------- | :-------- | :---- | :------ | :------- |\n| [Block Device Code](https://entra.microsoft.com/#view/Microsoft_AAD_ConditionalAccess/PolicyBlade/policyId/db2153a1-40a2-457f-917c-c280b204b5cd) | db2153a1-40a2-457f-917c-c280b204b5cd | enabled | 02/28/2024 00:22:50 | 2026-07-01 |\n\n\n\n","TestStatus":"Passed","TestDescription":"Blocking authentication transfer in Microsoft Entra ID is a critical security control. It helps protect against token theft and replay attacks by preventing the use of device tokens to silently authenticate on other devices or browsers. When authentication transfer is enabled, a threat actor who gains access to one device can access resources to nonapproved devices, bypassing standard authentication and device compliance checks. When administrators block this flow, organizations can ensure that each authentication request must originate from the original device, maintaining the integrity of the device compliance and user session context.\n\n**Remediation action**\n\n- [Deploy a Conditional Access policy to block authentication transfer](https://learn.microsoft.com/entra/identity/conditional-access/policy-block-authentication-flows?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci#authentication-transfer-policies)\n","TestId":"21828"},{"TestImplementationCost":"Low","TestPillar":"Identity","TestCategory":"Credential management","SkippedReason":null,"TestImpact":"Low","TestAppliesTo":null,"TestSfiPillar":"Protect identities and secrets","TestSkipped":"","TestMinimumLicense":"Free","TestTags":null,"TestTitle":"Security key attestation is enforced","TestRisk":"High","TestResult":"\nSecurity key attestation is not enforced, allowing unverified or potentially compromised security keys to be registered.\n## [Security key attestation policy details](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ConfigureAuthMethodsBlade/authMethod~/%7B%22%40odata.type%22%3A%22%23microsoft.graph.fido2AuthenticationMethodConfiguration%22%2C%22id%22%3A%22Fido2%22%2C%22state%22%3A%22enabled%22%2C%22isSelfServiceRegistrationAllowed%22%3Atrue%2C%22isAttestationEnforced%22%3Afalse%2C%22excludeTargets%22%3A%5B%7B%22id%22%3A%2243b7bc87-77eb-4263-abad-e3c2478f0a35%22%2C%22targetType%22%3A%22group%22%2C%22displayName%22%3A%22eam-block-user%22%7D%5D%2C%22keyRestrictions%22%3A%7B%22isEnforced%22%3Afalse%2C%22enforcementType%22%3A%22allow%22%2C%22aaGuids%22%3A%5B%22de1e552d-db1d-4423-a619-566b625cdc84%22%2C%2290a3ccdf-635c-4729-a248-9b709135078f%22%2C%2277010bd7-212a-4fc9-b236-d2ca5e9d4084%22%2C%22b6ede29c-3772-412c-8a78-539c1f4c62d2%22%2C%22ee041bce-25e5-4cdb-8f86-897fd6418464%22%2C%2273bb0cd4-e502-49b8-9c6f-b59445bf720b%22%5D%7D%2C%22includeTargets%40odata.context%22%3A%22https%3A%2F%2Fgraph.microsoft.com%2Fbeta%2F%24metadata%23policies%2FauthenticationMethodsPolicy%2FauthenticationMethodConfigurations('Fido2')%2Fmicrosoft.graph.fido2AuthenticationMethodConfiguration%2FincludeTargets%22%2C%22includeTargets%22%3A%5B%7B%22targetType%22%3A%22group%22%2C%22id%22%3A%22all_users%22%2C%22isRegistrationRequired%22%3Afalse%7D%5D%2C%22enabled%22%3Atrue%2C%22target%22%3A%22All%20users%2C%20excluding%201%20group%22%2C%22isAllUsers%22%3Atrue%2C%22voiceDisabled%22%3Afalse%7D/canModify~/true/voiceDisabled~/false/userMemberIds~/%5B%5D/userId/1ce4078f-f795-4baf-aa55-1fdfcc2ebfe6/isCiamTenant~/false/isCiamTrialTenant~/false)\n- **Enforce attestation** : False ❌\n- **Key restriction policy** :\n - **Enforce key restrictions** : False\n - **Restrict specific keys** : Allow\n - **AAGUID** :\n - de1e552d-db1d-4423-a619-566b625cdc84\n - 90a3ccdf-635c-4729-a248-9b709135078f\n - 77010bd7-212a-4fc9-b236-d2ca5e9d4084\n - b6ede29c-3772-412c-8a78-539c1f4c62d2\n - ee041bce-25e5-4cdb-8f86-897fd6418464\n - 73bb0cd4-e502-49b8-9c6f-b59445bf720b\n\n\n","TestStatus":"Failed","TestDescription":"When security key attestation isn't enforced, threat actors can exploit weak or compromised authentication hardware to establish persistent presence within organizational environments. Without attestation validation, malicious actors can register unauthorized or counterfeit FIDO2 security keys that bypass hardware-backed security controls, enabling them to perform credential stuffing attacks using fabricated authenticators that mimic legitimate security keys. This initial access lets threat actors escalate privileges by using the trusted nature of hardware authentication methods, then move laterally through the environment by registering more compromised security keys on high-privilege accounts. The lack of attestation enforcement creates a pathway for threat actors to establish command and control through persistent hardware-based authentication methods, ultimately leading to data exfiltration or system compromise while maintaining the appearance of legitimate hardware-secured authentication throughout the attack chain. \n\n**Remediation action**\n\n- [Enable attestation enforcement through the Authentication methods policy configuration](https://learn.microsoft.com/entra/identity/authentication/how-to-enable-passkey-fido2?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci#enable-passkey-fido2-authentication-method).\n- [Configure approved list of security keys by Authenticator Attestation Globally Unique Identifier (AAGUID)](https://learn.microsoft.com/entra/identity/authentication/concept-fido2-hardware-vendor?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci).\n","TestId":"21840"},{"TestImplementationCost":"Medium","TestPillar":"Devices","TestCategory":"Device","SkippedReason":null,"TestImpact":"Medium","TestAppliesTo":null,"TestSfiPillar":"Protect tenants and isolate production systems","TestSkipped":"","TestMinimumLicense":"Intune","TestTags":null,"TestTitle":"Windows Update policies are enforced to reduce risk from unpatched vulnerabilities","TestRisk":"High","TestResult":"\nWindows Update policy is assigned and enforced.\n\n\n| Policy Name | Status | Assignment |\n| :---------- | :------------- | :--------- |\n| [PROD](https://intune.microsoft.com/#view/Microsoft_Intune_DeviceSettings/DevicesWindowsMenu/~/windows10Update) | ✅ Assigned | **Included:** All Devices, **Excluded:** WFgroup |\n\n\n\n","TestStatus":"Passed","TestDescription":"If Windows Update policies aren't enforced across all corporate Windows devices, threat actors can exploit unpatched vulnerabilities to gain unauthorized access, escalate privileges, and move laterally within the environment. The attack chain often begins with device compromise via phishing, malware, or exploitation of known vulnerabilities, and is followed by attempts to bypass security controls. Without enforced update policies, attackers leverage outdated software to persist in the environment, increasing the risk of privilege escalation and domain-wide compromise.\n\nEnforcing Windows Update policies ensures timely patching of security flaws, disrupting attacker persistence, and reducing the risk of widespread compromise.\n\n**Remediation action**\n\nStart with [Manage Windows software updates in Intune](https://learn.microsoft.com/intune/device-updates/windows/configure?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci) to understand the available Windows Update policy types and how to configure them.\n\nIntune includes the following Windows update policy type: \n- [Windows quality updates policy](https://learn.microsoft.com/intune/device-updates/windows/quality-updates?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci) - *to install the regular monthly updates for Windows.*\n- [Expedite updates policy](https://learn.microsoft.com/intune/device-updates/windows/expedite-updates?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci) - *to quickly install critical security patches.*\n- [Feature updates policy](https://learn.microsoft.com/intune/device-updates/windows/feature-updates?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci)\n- [Update rings policy](https://learn.microsoft.com/intune/device-updates/windows/update-rings?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci) - *to manage how and when devices install feature and quality updates.*\n- [Windows driver updates](https://learn.microsoft.com/intune/device-updates/windows/driver-updates?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci) - *to update hardware components.*\n","TestId":"24553"},{"TestImplementationCost":"High","TestPillar":"Identity","TestCategory":"Access control","SkippedReason":"UnderConstruction","TestImpact":"Medium","TestAppliesTo":["Identity"],"TestSfiPillar":"Protect identities and secrets","TestSkipped":"UnderConstruction","TestMinimumLicense":null,"TestTags":["Identity"],"TestTitle":"All supported access lifecycle resources are managed with entitlement management packages","TestRisk":"Medium","TestResult":"\nPlanned for future release.\n","TestStatus":"Planned","TestDescription":"...\n\n**Remediation action**\n\n","TestId":"21898"},{"TestImplementationCost":"High","TestPillar":"Identity","TestCategory":"Access control","SkippedReason":"UnderConstruction","TestImpact":"Low","TestAppliesTo":["Identity"],"TestSfiPillar":"Protect identities and secrets","TestSkipped":"UnderConstruction","TestMinimumLicense":null,"TestTags":["Identity"],"TestTitle":"All risk detections are triaged","TestRisk":"High","TestResult":"\nPlanned for future release.\n","TestStatus":"Planned","TestDescription":"...\n\n**Remediation action**\n\n","TestId":"21864"},{"TestImplementationCost":"Low","TestPillar":"Devices","TestCategory":"Tenant","SkippedReason":null,"TestImpact":"Medium","TestAppliesTo":null,"TestSfiPillar":"Protect tenants and isolate production systems","TestSkipped":"","TestMinimumLicense":"Intune","TestTags":null,"TestTitle":"macOS Compliance Policy is Created and Assigned","TestRisk":"High","TestResult":"\nNo compliance policy for macOS exists or none are assigned.\n\n\n## macOS Compliance Policies\n\n| Policy Name | Status | Assignment Target |\n| :---------- | :----- | :---------------- |\n| [My macOS policy](https://intune.microsoft.com/#view/Microsoft_Intune_DeviceSettings/DevicesMenu/~/compliance) | ❌ Not assigned | None |\n\n\n\n","TestStatus":"Failed","TestDescription":"If compliance policies for macOS devices aren't configured and assigned, threat actors can exploit unmanaged or noncompliant endpoints to gain unauthorized access to corporate resources, bypass security controls, and persist within the environment. Without enforced compliance, macOS devices can lack critical security configurations like data storage encryption, password requirements, and OS version controls. These gaps increase the risk of data leakage, privilege escalation, and lateral movement. Inconsistent device compliance weakens the organization’s security posture and makes it harder to detect and remediate threats before significant damage occurs.\n\nEnforcing compliance policies ensures macOS devices meet core security requirements and supports Zero Trust by validating device health and reducing exposure to misconfigured endpoints.\n\n**Remediation actions**\n\nCreate and assign Intune compliance policies to macOS devices to enforce organizational standards for secure access and management: \n- [Create and assign Intune compliance policies](https://learn.microsoft.com/intune/intune-service/protect/create-compliance-policy?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci#create-the-policy)\n- [Review the macOS compliance settings you can manage with Intune](https://learn.microsoft.com/intune/intune-service/protect/compliance-policy-create-mac-os?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci)\n","TestId":"24542"},{"TestImplementationCost":"Medium","TestPillar":"Identity","TestCategory":"Application management","SkippedReason":null,"TestImpact":"Low","TestAppliesTo":null,"TestSfiPillar":"Monitor and detect cyberthreats","TestSkipped":"","TestMinimumLicense":"P1","TestTags":null,"TestTitle":"Enterprise applications with high privilege Microsoft Graph API permissions have owners","TestRisk":"High","TestResult":"\nNot all enterprise applications with high privilege permissions have owners\n\n## Applications lacking sufficient owners\n\n| App name | Multi-tenant | Permission | Classification | Owner count |\n| :-------- | :------------ | :---------- | :------------- | :----------- |\n| [idPowerToys - CI](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/Overview/objectId/b66231c2-9568-46f1-b61e-c5f8fd9edee4/appId/50827722-4f53-48ba-ae58-db63bb53626b) | True | Agreement.Read.All, CrossTenantInformation.ReadBasic.All, Directory.Read.All, offline_access, openid, Policy.Read.All, profile, User.Read | High | 0 |\n| [idPowerToys - Release](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/Overview/objectId/4654e05d-9f59-4925-807c-8eb2306e1cb1/appId/904e4864-f3c3-4d2f-ace2-c37a4ed55145) | True | Agreement.Read.All, CrossTenantInformation.ReadBasic.All, Directory.Read.All, offline_access, openid, Policy.Read.All, profile, User.Read | High | 0 |\n| [Azure AD Assessment](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/Overview/objectId/6c74be7f-bcc9-4541-bfe1-f113b90b0497/appId/68bc31c0-f891-4f4c-9309-c6104f7be41b) | False | Application.Read.All, AuditLog.Read.All, Directory.Read.All, Group.Read.All, offline_access, openid, Organization.Read.All, Policy.Read.All, profile, Reports.Read.All, RoleManagement.Read.Directory, SecurityEvents.Read.All, User.Read.All, UserAuthenticationMethod.Read.All | High | 0 |\n| [idPowerToys for Desktop](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/Overview/objectId/24cc58d8-2844-4974-b7cd-21c8a470e6bb/appId/520aa3af-bd78-4631-8f87-d48d356940ed) | True | Agreement.Read.All, CrossTenantInformation.ReadBasic.All, Directory.Read.All, offline_access, openid, Policy.Read.All, profile | High | 0 |\n| [entraChatAppMultiTenant](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/Overview/objectId/855a57ff-88a6-4ad0-85d7-4f46d742730e/appId/5e00b345-a805-42a0-9caa-7d6cb761c668) | True | APIConnectors.Read.All, Application.ReadWrite.All, AuditLog.Read.All, Directory.ReadWrite.All, EventListener.ReadWrite.All, Group.Read.All, IdentityUserFlow.Read.All, offline_access, openid, Policy.Read.All, Policy.ReadWrite.AuthenticationFlows, Policy.ReadWrite.AuthenticationMethod, Policy.ReadWrite.ConditionalAccess, Policy.ReadWrite.TrustFramework, profile, TrustFrameworkKeySet.Read.All, User.Read | High | 0 |\n| [Intune Documentation](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/Overview/objectId/97b66fb0-f682-41e0-9aef-47f170c2abae/appId/56066daa-baba-438f-89d0-7ea3be2e2222) | True | DeviceManagementApps.Read.All, DeviceManagementConfiguration.Read.All, DeviceManagementManagedDevices.Read.All, DeviceManagementRBAC.Read.All, DeviceManagementServiceConfig.Read.All, Group.Read.All, offline_access, openid, profile, User.Read | High | 0 |\n| [Automation](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/Overview/objectId/f79df990-9ad2-4142-b5fd-8945ff334da3/appId/dc7d83b5-d38b-4488-8952-7abf02e71590) | False | Directory.ReadWrite.All, User.Read | High | 1 |\n| [M365PronounKit](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/Overview/objectId/6bf7c616-88e8-4f7c-bdad-452e561fa777/appId/eea28244-3eec-4820-beae-d4a2c0bcc235) | False | User.ReadWrite.All | High | 0 |\n| [test public client](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/Overview/objectId/5e80ea33-31fa-49fd-9a94-61894bd1a6c9/appId/79a0c604-f215-4c52-8fbe-641d08aa7937) | False | User.Read.All | High | 0 |\n| [InfinityDemo](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/Overview/objectId/bac0ba57-1876-448e-96bf-6f0481c99fda/appId/fef811e1-2354-43b0-961b-248fe15e737d) | False | Directory.Read.All, User.Read | High | 0 |\n| [Lokka](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/Overview/objectId/1abc3899-a5df-40ab-8aa7-95d31edd4c01/appId/f581405a-9e57-4e81-91f1-40cd62f7595e) | False | DeviceManagementConfiguration.ReadWrite.All, Directory.ReadWrite.All, DirectoryRecommendations.Read.All, IdentityRiskEvent.Read.All, Mail.Read, Mail.Send, Policy.Read.All, Policy.ReadWrite.Authorization, Policy.ReadWrite.ConditionalAccess, PrivilegedAccess.Read.AzureAD, PrivilegedAccess.Read.AzureADGroup, Reports.Read.All, User.Read.All, UserAuthenticationMethod.Read.All | High | 0 |\n| [Maester DevOps Account - GitHub - Secret (demo)](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/Overview/objectId/e31cd01e-afaf-4cc3-8d15-d3f9f7eb61e8/appId/d0dc5f0a-bf75-41a4-9272-d5ec2345c963) | False | DeviceManagementConfiguration.Read.All, DeviceManagementManagedDevices.Read.All, Directory.Read.All, DirectoryRecommendations.Read.All, IdentityRiskEvent.Read.All, Mail.Send, Policy.Read.All, Policy.Read.ConditionalAccess, PrivilegedAccess.Read.AzureAD, Reports.Read.All, RoleEligibilitySchedule.Read.Directory, RoleManagement.Read.All, SecurityIdentitiesHealth.Read.All, SecurityIdentitiesSensors.Read.All, SharePointTenantSettings.Read.All, UserAuthenticationMethod.Read.All | High | 0 |\n| [MyTestForBlock](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/Overview/objectId/e9fca357-cccd-4ec4-840f-7482f6f02818/appId/14a3ba45-3246-4fbe-8c3b-c3922e68232b) | False | User.Read.All | High | 0 |\n| [PnPPowerShell](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/Overview/objectId/6d2e8d37-82b8-41e7-aa95-443a7401e8b8/appId/1d93462e-0f39-4e4c-898a-b6b1df5fa997) | False | Sites.FullControl.All, TermStore.Read.All, User.Read, User.Read.All, User.ReadWrite.All | High | 0 |\n| [Postman](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/Overview/objectId/aa64efdb-2d05-4c81-a9e5-80294bf0afac/appId/7fb37b38-ce4f-4675-9263-0cd3404b4925) | False | Directory.ReadWrite.All, Mail.ReadWrite, Policy.Read.All, User.Read | High | 0 |\n| [SharePoint Version App](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/Overview/objectId/666a58ef-c3e5-4efc-828a-2ab3c0120677/appId/2bb68591-782c-4c64-9415-bdf9414ae400) | False | Sites.Read.All, User.Read | High | 0 |\n| [Trello](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/Overview/objectId/3d6c91cf-d48f-4272-ac4c-9f989bbec779/appId/d77611ee-5051-4383-9af3-5ba3627306a7) | False | Application.Read.All | High | 0 |\n| [testuserread](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/Overview/objectId/89bd9c7a-0c81-4a0a-9153-ff7cd0b81352/appId/9fe2675c-7fc5-4895-8470-eed989ea0d63) | False | GroupMember.Read.All, User.Read.All | High | 0 |\n| [My Doc Gen](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/Overview/objectId/a445d652-f72d-4a88-9493-79d3c3c23d1b/appId/e580347d-d0aa-4aa1-9113-5daa0bb1c805) | False | Agreement.Read.All, CrossTenantInformation.ReadBasic.All, Directory.Read.All, offline_access, openid, Policy.Read.All, profile, User.Read | High | 0 |\n| [MyZt](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/Overview/objectId/716038b1-2811-40fc-8622-93e093890af0/appId/eee51d92-0bb5-4467-be6a-8f24ef677e4d) | False | Agreement.Read.All, CrossTenantInformation.ReadBasic.All, DeviceManagementApps.Read.All, DeviceManagementConfiguration.Read.All, DeviceManagementRBAC.Read.All, DeviceManagementServiceConfig.Read.All, Directory.Read.All, offline_access, openid, Policy.Read.All, PrivilegedEligibilitySchedule.Read.AzureADGroup, profile, RoleAssignmentSchedule.Read.Directory, RoleEligibilitySchedule.Read.Directory, User.Read | High | 0 |\n| [MyZtA\\[\\[](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/Overview/objectId/d2a2a09d-7562-45fc-a950-36fedfb790f8/appId/d159fcf5-a613-435b-8195-8add3cdf4bff) | False | Agreement.Read.All, CrossTenantInformation.ReadBasic.All, DeviceManagementApps.Read.All, DeviceManagementConfiguration.Read.All, DeviceManagementRBAC.Read.All, DeviceManagementServiceConfig.Read.All, Directory.Read.All, Policy.Read.All, PrivilegedEligibilitySchedule.Read.AzureADGroup, RoleAssignmentSchedule.Read.Directory, RoleEligibilitySchedule.Read.Directory, User.Read | High | 0 |\n| [Maester DevOps Account](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/Overview/objectId/d54232da-de3b-4874-aef2-5203dbd7342a/appId/d99dd249-6ab3-4e92-be40-81af11658359) | False | Directory.Read.All, DirectoryRecommendations.Read.All, IdentityRiskEvent.Read.All, Mail.Send, Policy.Read.All, PrivilegedAccess.Read.AzureAD, Reports.Read.All, User.Read | High | 0 |\n| [Graph PS - Zero Trust Workshop](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/Overview/objectId/f6e8dfdd-4c84-441f-ae6e-f2f51fd20699/appId/a9632ced-c276-4c2b-9288-3a34b755eaa9) | False | AuditLog.Read.All, CrossTenantInformation.ReadBasic.All, Directory.Read.All, DirectoryRecommendations.Read.All, IdentityRiskEvent.Read.All, offline_access, openid, Policy.Read.All, Policy.Read.ConditionalAccess, PrivilegedAccess.Read.AzureAD, profile, Reports.Read.All, RoleEligibilitySchedule.Read.Directory, RoleEligibilitySchedule.ReadWrite.Directory, RoleManagement.Read.All, UserAuthenticationMethod.Read.All | High | 0 |\n| [Maester DevOps Account - GitHub](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/Overview/objectId/ce3af345-b0e0-4b15-808c-937d825bcf03/appId/f050a85f-390b-4d43-85a0-2196b706bfd6) | False | DeviceManagementConfiguration.Read.All, DeviceManagementManagedDevices.Read.All, Directory.Read.All, DirectoryRecommendations.Read.All, IdentityRiskEvent.Read.All, Mail.Send, Policy.Read.All, Policy.Read.ConditionalAccess, PrivilegedAccess.Read.AzureAD, Reports.Read.All, RoleEligibilitySchedule.Read.Directory, RoleManagement.Read.All, SharePointTenantSettings.Read.All, UserAuthenticationMethod.Read.All | High | 0 |\n| [Maester DevOps Account - New GitHub Action](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/Overview/objectId/7c1885fd-fdf8-413a-86a6-f8867914272f/appId/143cb1b1-81af-4999-a292-a8c537601119) | False | DeviceManagementConfiguration.Read.All, DeviceManagementManagedDevices.Read.All, Directory.Read.All, DirectoryRecommendations.Read.All, IdentityRiskEvent.Read.All, Policy.Read.All, Policy.Read.ConditionalAccess, PrivilegedAccess.Read.AzureAD, Reports.Read.All, RoleEligibilitySchedule.Read.Directory, RoleEligibilitySchedule.ReadWrite.Directory, RoleManagement.Read.All, SharePointTenantSettings.Read.All, User.Read, UserAuthenticationMethod.Read.All | High | 0 |\n| [Maester Automation App](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/Overview/objectId/e3972142-1d36-4e7d-a777-ecd64619fcab/appId/55635484-743e-42e2-a78e-6bc15050ebde) | False | DeviceManagementConfiguration.Read.All, DeviceManagementManagedDevices.Read.All, Directory.Read.All, DirectoryRecommendations.Read.All, IdentityRiskEvent.Read.All, Mail.Send, Policy.Read.All, Policy.Read.ConditionalAccess, PrivilegedAccess.Read.AzureAD, Reports.Read.All, RoleEligibilitySchedule.Read.Directory, RoleEligibilitySchedule.ReadWrite.Directory, RoleManagement.Read.All, SharePointTenantSettings.Read.All, User.Read, UserAuthenticationMethod.Read.All | High | 0 |\n| [contoso-tenant-devops-7576c63d-bc90-4ae4-9f1c-0d959fb520db](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/Overview/objectId/c5632968-35cd-445d-926e-16e0afc9160e/appId/e876f7cb-13f3-48a4-8329-66d7b1fa33fb) | False | Directory.ReadWrite.All, Policy.ReadWrite.Authorization, Policy.ReadWrite.DeviceConfiguration | High | 0 |\n| [contoso-Maester-54d3ea01-5a07-45d0-8d69-e5f5b0b20098](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/Overview/objectId/4faa0456-5ecb-49f3-bb9a-2dbe516e939a/appId/a8c184ae-8ddf-41f3-8881-c090b43c385f) | False | Directory.Read.All, DirectoryRecommendations.Read.All, Mail.Send, Policy.Read.All, Reports.Read.All | High | 0 |\n| [contoso-maester-demo-39ecb2b6-d900-496e-886f-d112cca4f1a9](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/Overview/objectId/cc578aea-b1bd-434d-86d2-8a22c5728ded/appId/efec213e-0a85-4d7a-938f-3d97edd4ade0) | False | DeviceManagementConfiguration.Read.All, DeviceManagementManagedDevices.Read.All, Directory.Read.All, DirectoryRecommendations.Read.All, IdentityRiskEvent.Read.All, Policy.Read.All, Policy.Read.ConditionalAccess, PrivilegedAccess.Read.AzureAD, Reports.Read.All, ReportSettings.Read.All, RoleEligibilitySchedule.Read.Directory, RoleManagement.Read.All, SecurityIdentitiesHealth.Read.All, SecurityIdentitiesSensors.Read.All, SharePointTenantSettings.Read.All, ThreatHunting.Read.All, UserAuthenticationMethod.Read.All | High | 0 |\n| [Agent Identity Blueprint Example 4208296](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/Overview/objectId/c845b130-ce1b-4124-96ca-465df0eaa10f/appId/d0e3212f-58a2-4511-8b56-bd57b023106d) | False | AgentIdUser.ReadWrite.IdentityParentedBy, Calendars.Read, Mail.Read, User.Read | High | 0 |\n| [Agent Identity Blueprint Example 4209295](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/Overview/objectId/20aaa39b-821d-40a5-8d8a-eff27f86bb4a/appId/f522f080-5192-4665-87a4-e1211b7adca6) | False | AgentIdUser.ReadWrite.IdentityParentedBy, Files.Read, User.Read | High | 0 |\n| [testSP](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/Overview/objectId/2361fd8a-fe89-4d07-9199-c117feb52b5e/appId/e47d8f25-5327-40f8-99fe-d832b99d938d) | False | AuditLog.Read.All, CrossTenantInformation.ReadBasic.All, DeviceManagementConfiguration.Read.All, DeviceManagementManagedDevices.Read.All, DeviceManagementRBAC.Read.All, DeviceManagementServiceConfig.Read.All, Directory.Read.All, DirectoryRecommendations.Read.All, EntitlementManagement.Read.All, IdentityRiskEvent.Read.All, IdentityRiskyUser.Read.All, InformationProtectionPolicy.Read.All, LifecycleWorkflows-Reports.Read.All, NetworkAccess-Reports.Read.All, NetworkAccessPolicy.Read.All, Policy.Read.ConditionalAccess, Policy.Read.PermissionGrant, PrivilegedAccess.Read.AzureAD, RoleManagement.Read.All, UserAuthenticationMethod.Read.All | High | 0 |\n| [idPowerToys](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/Overview/objectId/ad36b6e2-273d-4652-a505-8481f096e513/appId/6ce0484b-2ae6-4458-b2b9-b3369f42fd6f) | True | Agreement.Read.All, CrossTenantInformation.ReadBasic.All, Directory.Read.All, offline_access, openid, Policy.Read.All, profile, User.Read | High | 0 |\n| [Zero Trust Assessment](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/Overview/objectId/3dde25cc-223f-4a16-8e8f-6695940b9680/appId/e7dfcbb6-fe86-44a2-b512-8d361dcc3d30) | True | Agreement.Read.All, CrossTenantInformation.ReadBasic.All, DeviceManagementApps.Read.All, DeviceManagementConfiguration.Read.All, DeviceManagementRBAC.Read.All, DeviceManagementServiceConfig.Read.All, Directory.Read.All, offline_access, openid, Policy.Read.All, PrivilegedEligibilitySchedule.Read.AzureADGroup, profile, RoleAssignmentSchedule.Read.Directory, RoleEligibilitySchedule.Read.Directory, User.Read | High | 0 |\n| [ZT-PermissionTest](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/Overview/objectId/b264ce7f-a584-49bf-8dd4-d2a3971e97b9/appId/be667b5a-b863-4698-9f60-868ef968b857) | False | AuditLog.Read.All, CrossTenantInformation.ReadBasic.All, DeviceManagementApps.Read.All, DeviceManagementConfiguration.Read.All, DeviceManagementManagedDevices.Read.All, DeviceManagementRBAC.Read.All, DeviceManagementServiceConfig.Read.All, Directory.Read.All, DirectoryRecommendations.Read.All, EntitlementManagement.Read.All, IdentityRiskEvent.Read.All, IdentityRiskyServicePrincipal.Read.All, IdentityRiskyUser.Read.All, NetworkAccess.Read.All, offline_access, openid, Policy.Read.All, Policy.Read.ConditionalAccess, Policy.Read.PermissionGrant, PrivilegedAccess.Read.AzureAD, profile, Reports.Read.All, RoleManagement.Read.All, User.Read, UserAuthenticationMethod.Read.All | High | 0 |\n| [ZeroTrustTest](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/Overview/objectId/d07c6af4-09f7-403f-bdeb-fb6be0d5e9fe/appId/3835a2fc-573d-4c4b-a4a3-993a1a156607) | False | AuditLog.Read.All, Content.DelegatedWriter, Content.SuperUser, CrossTenantInformation.ReadBasic.All, CustomSecAttributeAssignment.Read.All, DeviceManagementApps.Read.All, DeviceManagementConfiguration.Read.All, DeviceManagementManagedDevices.Read.All, DeviceManagementRBAC.Read.All, DeviceManagementServiceConfig.Read.All, Directory.Read.All, DirectoryRecommendations.Read.All, EntitlementManagement.Read.All, IdentityRiskEvent.Read.All, IdentityRiskyServicePrincipal.Read.All, IdentityRiskyUser.Read.All, NetworkAccess.Read.All, offline_access, openid, Policy.Read.All, Policy.Read.ConditionalAccess, Policy.Read.PermissionGrant, PrivilegedAccess.Read.AzureAD, profile, Reports.Read.All, RoleManagement.Read.All, User.Read, UserAuthenticationMethod.Read.All | High | 0 |\n| [test](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/Overview/objectId/35cbeecb-be21-4596-9869-0157d84f2d67/appId/c823a25d-fe94-494c-91f6-c7d51bf2df82) | False | Sites.FullControl.All, User.Read | High | 0 |\n| [Custom-App-Test](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/Overview/objectId/38415a71-b77b-44d5-a276-539faabe0de7/appId/ddb4f0e6-8018-4359-96c1-7473704bde43) | False | Application.Read.All, AuditLog.Read.All, CrossTenantInformation.ReadBasic.All, CustomSecAttributeAssignment.Read.All, DeviceManagementConfiguration.Read.All, DeviceManagementManagedDevices.Read.All, DeviceManagementRBAC.Read.All, DeviceManagementServiceConfig.Read.All, Directory.Read.All, DirectoryRecommendations.Read.All, EntitlementManagement.Read.All, IdentityRiskEvent.Read.All, IdentityRiskyServicePrincipal.Read.All, IdentityRiskyUser.Read.All, Policy.Read.All, Policy.Read.ConditionalAccess, Policy.Read.PermissionGrant, PrivilegedAccess.Read.AzureAD, RoleManagement.Read.All, User.Read, UserAuthenticationMethod.Read.All | High | 0 |\n| [Maester DevOps Account](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/Overview/objectId/7c32eaee-ff26-4435-be3d-b4ced08f9edc/appId/303774c1-3c6f-4dfd-8505-f24e82f9212a) | False | Directory.Read.All, DirectoryRecommendations.Read.All, IdentityRiskEvent.Read.All, Policy.Read.All, Policy.Read.ConditionalAccess, PrivilegedAccess.Read.AzureAD, Reports.Read.All, RoleEligibilitySchedule.Read.Directory, RoleEligibilitySchedule.ReadWrite.Directory, RoleManagement.Read.All, SharePointTenantSettings.Read.All, User.Read, UserAuthenticationMethod.Read.All | High | 0 |\n| [entra-docs-email github DO NOT DELETE](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/Overview/objectId/7a94aec7-a5e3-48dd-b20f-3db74d689434/appId/ae06b71a-a0aa-4211-b846-fd74f25ccd45) | False | Mail.Send, User.Read | High | 0 |\n| [Maester DevOps Account - manson/maester-demo](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/Overview/objectId/fdce906b-d2f6-4738-8c76-e4559b9e17e8/appId/91c84d77-3dce-4fb0-b0de-474a8606c812) | False | DeviceManagementConfiguration.Read.All, DeviceManagementManagedDevices.Read.All, Directory.Read.All, DirectoryRecommendations.Read.All, IdentityRiskEvent.Read.All, Policy.Read.All, Policy.Read.ConditionalAccess, PrivilegedAccess.Read.AzureAD, Reports.Read.All, ReportSettings.Read.All, RoleEligibilitySchedule.Read.Directory, RoleManagement.Read.All, SecurityIdentitiesHealth.Read.All, SecurityIdentitiesSensors.Read.All, SharePointTenantSettings.Read.All, ThreatHunting.Read.All, UserAuthenticationMethod.Read.All | High | 0 |\n| [GitHub Actions App for Microsoft Info script](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/Overview/objectId/852b4218-67d2-4046-a9a6-f8b47430ccdf/appId/38535360-9f3e-4b1e-a41e-b4af46afcb0c) | False | Application.Read.All | High | 0 |\n| [GraphPermissionApp](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/Overview/objectId/a15dc834-08ce-4fd8-85de-3729fff8e34f/appId/d36fe320-bc28-40c8-a141-a512d65d112c) | False | Application.Read.All, User.Read | High | 0 |\n| [Graph Explorer](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/Overview/objectId/8f8f300a-870a-46ff-bdab-934e1436920d/appId/d3ce4cf8-6810-442d-b42e-375e14710095) | True | Directory.AccessAsUser.All, User.Read | High | 0 |\n| [Azure AD Assessment (Test)](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/Overview/objectId/d4cf4286-0fbe-424d-b4f2-65aa2c568631/appId/c62a9fcb-53bf-446e-8063-ea6e2bfcc023) | False | AuditLog.Read.All, Directory.AccessAsUser.All, Directory.ReadWrite.All, Group.ReadWrite.All, IdentityProvider.ReadWrite.All, offline_access, openid, Policy.ReadWrite.TrustFramework, PrivilegedAccess.ReadWrite.AzureAD, PrivilegedAccess.ReadWrite.AzureResources, profile, TrustFrameworkKeySet.ReadWrite.All, User.Invite.All | High | 0 |\n| [Reset Viral Users Redemption Status](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/Overview/objectId/3a8785da-9965-473f-a97c-25fefdc39fee/appId/cc7b0696-1956-408b-876a-ad6bf2b9890b) | False | Directory.ReadWrite.All, offline_access, openid, profile, User.Invite.All, User.Read, User.ReadWrite.All | High | 0 |\n| [Windows Virtual Desktop AME](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/Overview/objectId/8369f33c-da25-4a8a-866d-b0145e29ef29/appId/5a0aa725-4958-4b0c-80a9-34562e23f3b7) | True | Directory.Read.All, User.Read.All | High | 0 |\n| [Microsoft Sample Data Packs](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/Overview/objectId/63e1f0d4-bc2c-497a-bfe2-9eb4c8c2600e/appId/a1cffbc6-1cb3-44e4-a1d2-cee9cce700f1) | False | Application.ReadWrite.OwnedBy, Calendars.ReadWrite, Calendars.ReadWrite.All, Contacts.ReadWrite, Directory.ReadWrite.All, Files.ReadWrite, Files.ReadWrite.All, Group.ReadWrite.All, Mail.ReadWrite, Mail.Send, MailboxSettings.ReadWrite, Sites.FullControl.All, Sites.Manage.All, Sites.ReadWrite.All, User.ReadWrite, User.ReadWrite.All | High | 0 |\n| [Modern Workplace Concierge](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/Overview/objectId/ad1c51e8-f8a8-4bf2-ac09-a3a20cba5fa5/appId/c65c4011-1b90-4ec9-b5e9-1ee17786ad84) | True | Application.Read.All, DeviceManagementApps.ReadWrite.All, DeviceManagementConfiguration.ReadWrite.All, DeviceManagementRBAC.ReadWrite.All, DeviceManagementServiceConfig.ReadWrite.All, Group.ReadWrite.All, openid, Policy.Read.All, Policy.ReadWrite.ConditionalAccess, profile, RoleManagement.Read.Directory, User.Read, User.ReadBasic.All | High | 0 |\n\n\n","TestStatus":"Failed","TestDescription":"Without owners, enterprise applications become orphaned assets that threat actors can exploit through credential harvesting and privilege escalation techniques. These applications often retain elevated permissions and access to sensitive resources while lacking proper oversight and security governance. The elevation of privilege to owners can raise a security concern, depending on the application's permissions. More critically, applications without an owner can create uncertainty in security monitoring where threat actors can establish persistence by using existing application permissions to access data or create backdoor accounts without triggering ownership-based detection mechanisms.\n\nWhen applications lack owners, security teams can't effectively conduct application lifecycle management. This gap leaves applications with potentially excessive permissions, outdated configurations, or compromised credentials that threat actors can discover through enumeration techniques and exploit to move laterally within the environment. The absence of ownership also prevents proper access reviews and permission audits, allowing threat actors to maintain long-term access through applications that should be decommissioned or had their permissions reduced. Not maintaining a clean application portfolio can provide persistent access vectors that can be used for data exfiltration or further compromise of the environment.\n\n**Remediation action**\n\n- [Assign owners to applications](https://learn.microsoft.com/entra/identity/enterprise-apps/assign-app-owners?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci)\n","TestId":"21867"},{"TestImplementationCost":"Medium","TestPillar":"Devices","TestCategory":"Device","SkippedReason":null,"TestImpact":"Medium","TestAppliesTo":null,"TestSfiPillar":"Protect identities and secrets","TestSkipped":"","TestMinimumLicense":"Intune","TestTags":null,"TestTitle":"Windows Hello for Business Policy is Configured and Assigned","TestRisk":"High","TestResult":"\nWindows Hello for Business policy is not assigned or not enforced.\n\n\n## Windows Hello for Business Policy is Configured and Assigned\n\nWindows Hello For Business ([Tenant Wide Setting](https://intune.microsoft.com/#view/Microsoft_Intune_DeviceSettings/DevicesEnrollmentMenu/~/windowsEnrollment) ): ❓ Not Configured.\n\n| Policy Name | Status | Assignment |\n| :---------- | :----- | :--------- |\n| [Windows Hello for Business](https://intune.microsoft.com/#view/Microsoft_Intune_DeviceSettings/DevicesMenu/~/configuration) | ❌ Not assigned | None |\n\n\n\n","TestStatus":"Failed","TestDescription":"If policies for Windows Hello for Business (WHfB) aren't configured and assigned to all users and devices, threat actors can exploit weak authentication mechanisms—like passwords—to gain unauthorized access. This can lead to credential theft, privilege escalation, and lateral movement within the environment. Without strong, policy-driven authentication like WHfB, attackers can compromise devices and accounts, increasing the risk of widespread impact.\n\nEnforcing WHfB disrupts this attack chain by requiring strong, multifactor authentication, which helps reduce the risk of credential-based attacks and unauthorized access.\n\n**Remediation action**\n\nDeploy Windows Hello for Business in Intune to enforce strong, multifactor authentication: \n- [Configure a tenant-wide Windows Hello for Business policy](https://learn.microsoft.com/intune/intune-service/protect/windows-hello?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci#create-a-windows-hello-for-business-policy-for-device-enrollment) that applies at the time a device enrolls with Intune.\n- After enrollment, [configure Account protection profiles](https://learn.microsoft.com/intune/intune-service/protect/endpoint-security-account-protection-policy?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci#account-protection-profiles) and [assign](https://learn.microsoft.com/intune/intune-service/configuration/device-profile-assign?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci#assign-a-policy-to-users-or-groups) different configurations for Windows Hello for Business to different groups of users and devices.\n","TestId":"24551"},{"TestImplementationCost":"","TestPillar":"Infrastructure","TestCategory":"Implement security best practices","SkippedReason":null,"TestImpact":"","TestAppliesTo":null,"TestSfiPillar":"Protect tenants and isolate production systems","TestSkipped":"","TestMinimumLicense":"N/A","TestTags":null,"TestTitle":"There should be more than one owner assigned to subscriptions","TestRisk":"High","TestResult":"There should be more than one owner assigned to subscriptions\n\n| Subscription | Affected resource | Status | Azure portal |\n| :----------- | :---------------- | :----- | :----------- |\n| [Visual Studio Enterprise Subscription](https://portal.azure.com/#resource/subscriptions/54d3ea01-5a07-45d0-8d69-e5f5b0b20098) | [54d3ea01-5a07-45d0-8d69-e5f5b0b20098](https://portal.azure.com/#resource/subscriptions/54d3ea01-5a07-45d0-8d69-e5f5b0b20098) | ✅ | [View recommendation](https://portal.azure.com/#blade/Microsoft_Azure_Security/RecommendationsBlade/assessmentKey/2c79b4af-f830-b61e-92b9-63dfa30f16e4/resourceId/%2fsubscriptions%2f54d3ea01-5a07-45d0-8d69-e5f5b0b20098) |\n","TestStatus":"Passed","TestDescription":"Designate more than one subscription owner in order to have administrator access redundancy.\n\n**Remediation action**\n\nTo add another account with owner permissions to your subscription:
Click a subscription from the list of subscriptions below or click 'Take action' if you are coming from a specific subscription.
The Access control (IAM) page opens.
1. Click 'Add' to open the Add role assignment pane.
If you don't have permissions to assign roles, the Add role assignment option will be disabled
1. In the 'Role' drop-down list, select the Owner role.
2. In the Select list, select a user.
3. Select 'Save'.","TestId":"2c79b4af-f830-b61e-92b9-63dfa30f16e4"},{"TestImplementationCost":"Low","TestPillar":"Network","TestCategory":"Azure Network Security","SkippedReason":"This test is not applicable to the current environment.","TestImpact":"Low","TestAppliesTo":null,"TestSfiPillar":"Protect networks","TestSkipped":"NotApplicable","TestMinimumLicense":["Azure WAF","Azure Application Gateway Standard SKU"],"TestTags":null,"TestTitle":"Application Gateway WAF is Enabled in Prevention mode","TestRisk":"High","TestResult":"\nSkipped. This test is not applicable to the current environment.\n\n","TestStatus":"Skipped","TestDescription":"Azure Application Gateway Web Application Firewall (WAF) protects web applications from common exploits and vulnerabilities, including SQL injection, cross-site scripting, and other OWASP Top 10 threats. WAF operates in two modes: Detection and Prevention. Detection mode logs matched requests but doesn't block traffic, while Prevention mode actively blocks malicious requests before they reach the backend application. When WAF is in Detection mode, web applications remain exposed to exploitation even though threats are being identified.\n\nWithout WAF in Prevention mode:\n\n- Threat actors can exploit web application vulnerabilities such as SQL injection and cross-site scripting, because matched requests are only logged, not blocked.\n- Organizations lose the active protection that managed and custom WAF rules provide, which reduces WAF to an observability tool rather than a security control.\n\n**Remediation action**\n\n- [Configure WAF on Azure Application Gateway](https://learn.microsoft.com/azure/web-application-firewall/ag/ag-overview?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci#waf-modes) to switch the WAF policy from **Detection mode** to **Prevention mode**.\n- [Create and manage WAF policies for Application Gateway](https://learn.microsoft.com/azure/web-application-firewall/ag/create-waf-policy-ag?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci) to apply Prevention mode settings across all Application Gateway instances.\n","TestId":25541},{"TestImpact":"Low","TestRisk":"Medium","TestSkipped":"NoCompatibleLicenseFound","TestAppliesTo":null,"TestPillar":"Network","TestCategory":"Global Secure Access","TestDescription":"Without Global Secure Access logs integrated into a Microsoft Sentinel workspace, security operations teams lack centralized visibility into network traffic patterns, connection attempts, and access anomalies across Private Access, Internet Access, and Microsoft 365 traffic forwarding. Threat actors who compromise user credentials or devices can use these network access paths to perform reconnaissance, move laterally, or exfiltrate data without detection.\n\nWithout this integration:\n\n- Security teams can't correlate network-layer activities with identity-based signals in Microsoft Entra ID or endpoint detections.\n- Security information and event management (SIEM) systems can't apply behavioral analytics, threat intelligence correlation, or automated response playbooks to Global Secure Access traffic.\n- Security teams can't investigate historical network access patterns or hunt for threats across network and identity signals.\n\n**Remediation action**\n\n- [Configure Microsoft Entra diagnostic settings](https://learn.microsoft.com/entra/global-secure-access/how-to-sentinel-integration?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci) to send Global Secure Access logs to a Log Analytics workspace for Microsoft Sentinel integration.\n- [Enable all required Global Secure Access identity log categories](https://learn.microsoft.com/entra/identity/monitoring-health/concept-diagnostic-settings-logs-options?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci), including `NetworkAccessTrafficLogs`, `EnrichedOffice365AuditLogs`, `RemoteNetworkHealthLogs`, `NetworkAccessAlerts`, `NetworkAccessConnectionEvents`, and `NetworkAccessGenerativeAIInsights` in diagnostic settings.\n- [Integrate Microsoft Entra activity logs with Azure Monitor](https://learn.microsoft.com/entra/identity/monitoring-health/howto-integrate-activity-logs-with-azure-monitor-logs?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci) for centralized log collection.\n- [Configure a Microsoft Sentinel workspace](https://learn.microsoft.com/azure/sentinel/quickstart-onboard?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci) and install the Global Secure Access solution from the content hub.\n","TestTitle":"Network access activity is visible to security operations for threat detection and response","SkippedReason":"This test requires one of the following licenses: (\"Entra_Premium_Private_Access\") OR (\"Entra_Premium_Internet_Access\"). Please ensure your tenant has the appropriate licenses to run this test. See [Licensing & Service Plans](https://learn.microsoft.com/entra/identity/users/licensing-service-plan-reference)","TestId":"25419","TestImplementationCost":"Low","TestMinimumLicense":["Entra_Premium_Private_Access","Entra_Premium_Internet_Access"],"TestSfiPillar":"Monitor and detect cyberthreats","TestResult":"\nSkipped. This test requires one of the following licenses: (\"Entra_Premium_Private_Access\") OR (\"Entra_Premium_Internet_Access\"). Please ensure your tenant has the appropriate licenses to run this test. See [Licensing & Service Plans](https://learn.microsoft.com/entra/identity/users/licensing-service-plan-reference)\n\n","TestStatus":"Skipped","TestTags":null},{"TestImplementationCost":"Low","TestPillar":"Identity","TestCategory":"External collaboration","SkippedReason":null,"TestImpact":"Medium","TestAppliesTo":null,"TestSfiPillar":"Protect tenants and isolate production systems","TestSkipped":"","TestMinimumLicense":"P1","TestTags":null,"TestTitle":"Guests don't have long lived sign-in sessions","TestRisk":"Medium","TestResult":"\nGuests do have long lived sign-in sessions.\n\n\n## Sign-in frequency policies\n\n| Policy name | Sign-in frequency | Status |\n| :---------- | :---------------- | :----- |\n| [MT-Test-MtCaMfaForGuest](https://entra.microsoft.com/#view/Microsoft_AAD_ConditionalAccess/PolicyBlade/policyId/a16cd40e-1fa7-4151-82f0-baca22b68ede) | Not configured | ❌ |\n\n\n\n","TestStatus":"Failed","TestDescription":"Guest accounts with extended sign-in sessions increase the risk surface area that threat actors can exploit. When guest sessions persist beyond necessary timeframes, threat actors often attempt to gain initial access through credential stuffing, password spraying, or social engineering attacks. Once they gain access, they can maintain unauthorized access for extended periods without reauthentication challenges. These compromised and extended sessions:\n\n- Allow unauthorized access to Microsoft Entra artifacts, enabling threat actors to identify sensitive resources and map organizational structures.\n- Allow threat actors to persist within the network by using legitimate authentication tokens, making detection more challenging as the activity appears as typical user behavior.\n- Provides threat actors with a longer window of time to escalate privileges through techniques like accessing shared resources, discovering more credentials, or exploiting trust relationships between systems.\n\nWithout proper session controls, threat actors can achieve lateral movement across the organization's infrastructure, accessing critical data and systems that extend far beyond the original guest account's intended scope of access. \n\n**Remediation action**\n- [Configure adaptive session lifetime policies](https://learn.microsoft.com/entra/identity/conditional-access/howto-conditional-access-session-lifetime?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci) so sign-in frequency policies have shorter live sign-in sessions.\n","TestId":"21824"},{"TestImplementationCost":"Medium","TestPillar":"Identity","TestCategory":"Privileged access","SkippedReason":null,"TestImpact":"Low","TestAppliesTo":["Identity"],"TestSfiPillar":"Protect identities and secrets","TestSkipped":"","TestMinimumLicense":"P1","TestTags":["Credential"],"TestTitle":"Privileged accounts have phishing-resistant methods registered","TestRisk":"High","TestResult":"\nFound privileged users that have not yet registered phishing resistant authentication methods\n\n## Privileged users\n\nFound privileged users that have not registered phishing resistant authentication methods.\n\nUser | Role Name | Phishing resistant method registered |\n| :--- | :--- | :---: |\n|[Hayden Scott Test](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/UserAuthMethods/userId/6f467d0a-25ec-435c-8fb9-9d53eb21e02f/hidePreviewBanner~/true)| SharePoint Administrator | ❌ |\n|[Hayden Scott Test](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/UserAuthMethods/userId/6f467d0a-25ec-435c-8fb9-9d53eb21e02f/hidePreviewBanner~/true)| Global Reader | ❌ |\n|[Hayden Scott Test](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/UserAuthMethods/userId/6f467d0a-25ec-435c-8fb9-9d53eb21e02f/hidePreviewBanner~/true)| Exchange Administrator | ❌ |\n|[Alex Johnson](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/UserAuthMethods/userId/e436ca15-3a39-4dcc-819e-7dbb246cd46b/hidePreviewBanner~/true)| Global Administrator | ❌ |\n|[Alex Johnson](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/UserAuthMethods/userId/e436ca15-3a39-4dcc-819e-7dbb246cd46b/hidePreviewBanner~/true)| Billing Administrator | ❌ |\n|[Alex Johnson](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/UserAuthMethods/userId/e436ca15-3a39-4dcc-819e-7dbb246cd46b/hidePreviewBanner~/true)| Application Administrator | ❌ |\n|[Hayden Scott](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/UserAuthMethods/userId/0d6cfd05-fc46-440b-b605-66dd26dcd7d2/hidePreviewBanner~/true)| Global Reader | ❌ |\n|[Hayden Scott](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/UserAuthMethods/userId/c0b65b13-37b1-4081-bcfc-14844159b4a5/hidePreviewBanner~/true)| Global Administrator | ❌ |\n|[Hayden Scott](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/UserAuthMethods/userId/c0b65b13-37b1-4081-bcfc-14844159b4a5/hidePreviewBanner~/true)| Compliance Administrator | ❌ |\n|[Jordan Smith](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/UserAuthMethods/userId/bfaeba1e-1357-47de-9557-529caa103d5d/hidePreviewBanner~/true)| Application Administrator | ❌ |\n|[Jordan Smith](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/UserAuthMethods/userId/bfaeba1e-1357-47de-9557-529caa103d5d/hidePreviewBanner~/true)| AI Administrator | ❌ |\n|[Jordan Smith](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/UserAuthMethods/userId/bfaeba1e-1357-47de-9557-529caa103d5d/hidePreviewBanner~/true)| Exchange Administrator | ❌ |\n|[Jordan Smith](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/UserAuthMethods/userId/bfaeba1e-1357-47de-9557-529caa103d5d/hidePreviewBanner~/true)| Global Administrator | ❌ |\n|[Taylor Brown](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/UserAuthMethods/userId/2072badc-3cf0-4e84-b4c2-f9c065c46165/hidePreviewBanner~/true)| Global Administrator | ❌ |\n|[Casey Davis](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/UserAuthMethods/userId/58d9ed99-93ca-4674-8c5f-ec770f5ba17d/hidePreviewBanner~/true)| Global Reader | ❌ |\n|[ash-williams-test](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/UserAuthMethods/userId/c5c8ba63-4620-4e91-ac40-b66bebe07a0d/hidePreviewBanner~/true)| Global Reader | ❌ |\n|[ash-williams-test](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/UserAuthMethods/userId/c5c8ba63-4620-4e91-ac40-b66bebe07a0d/hidePreviewBanner~/true)| SharePoint Administrator | ❌ |\n|[ash-williams-test](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/UserAuthMethods/userId/c5c8ba63-4620-4e91-ac40-b66bebe07a0d/hidePreviewBanner~/true)| Exchange Administrator | ❌ |\n|[Morgan Wilson](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/UserAuthMethods/userId/5655cf54-34bc-4f36-bb74-44da35547975/hidePreviewBanner~/true)| Global Administrator | ❌ |\n|[Riley Martinez](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/UserAuthMethods/userId/653c7fdd-1b41-4229-992a-69cc35aad4f7/hidePreviewBanner~/true)| Application Administrator | ❌ |\n|[Cameron Anderson](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/UserAuthMethods/userId/1ce4078f-f795-4baf-aa55-1fdfcc2ebfe6/hidePreviewBanner~/true)| Global Reader | ❌ |\n|[Cameron Anderson](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/UserAuthMethods/userId/1ce4078f-f795-4baf-aa55-1fdfcc2ebfe6/hidePreviewBanner~/true)| Compliance Administrator | ❌ |\n|[Cameron Anderson](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/UserAuthMethods/userId/1ce4078f-f795-4baf-aa55-1fdfcc2ebfe6/hidePreviewBanner~/true)| Global Administrator | ❌ |\n|[Cameron Anderson](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/UserAuthMethods/userId/1ce4078f-f795-4baf-aa55-1fdfcc2ebfe6/hidePreviewBanner~/true)| Azure AD Joined Device Local Administrator | ❌ |\n|[Cameron Anderson](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/UserAuthMethods/userId/1ce4078f-f795-4baf-aa55-1fdfcc2ebfe6/hidePreviewBanner~/true)| Purview Workload Content Administrator | ❌ |\n|[Cameron Anderson](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/UserAuthMethods/userId/1ce4078f-f795-4baf-aa55-1fdfcc2ebfe6/hidePreviewBanner~/true)| Security Administrator | ❌ |\n|[Avery Thomas](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/UserAuthMethods/userId/f431700c-6d81-45b8-8f8d-581a8aa7cda6/hidePreviewBanner~/true)| Global Administrator | ❌ |\n|[Jamie Rodriguez](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/UserAuthMethods/userId/0b37813c-ae19-4399-982f-16587f17f9c0/hidePreviewBanner~/true)| Global Administrator | ❌ |\n|[Dakota Lee](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/UserAuthMethods/userId/e4bc6f4a-124f-469b-8951-3d5c34fb9741/hidePreviewBanner~/true)| User Administrator | ❌ |\n|[Skylar White](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/UserAuthMethods/userId/2a054082-8f05-4e05-8fce-4e35c3bb40cc/hidePreviewBanner~/true)| Application Administrator | ❌ |\n|[Jules Bailey](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/UserAuthMethods/userId/0145d508-50fd-4f86-a47a-bf1c043c8358/hidePreviewBanner~/true)| Global Administrator | ❌ |\n|[peyton-test](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/UserAuthMethods/userId/e0952dcb-8d63-496d-8661-05c86c1a51f0/hidePreviewBanner~/true)| Exchange Administrator | ❌ |\n|[peyton-test](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/UserAuthMethods/userId/e0952dcb-8d63-496d-8661-05c86c1a51f0/hidePreviewBanner~/true)| Global Reader | ❌ |\n|[peyton-test](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/UserAuthMethods/userId/e0952dcb-8d63-496d-8661-05c86c1a51f0/hidePreviewBanner~/true)| SharePoint Administrator | ❌ |\n|[Peyton Clark](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/UserAuthMethods/userId/7e92f268-bb12-469a-a869-210d596d4c1f/hidePreviewBanner~/true)| Global Reader | ❌ |\n|[Peyton Clark](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/UserAuthMethods/userId/7e92f268-bb12-469a-a869-210d596d4c1f/hidePreviewBanner~/true)| Global Administrator | ❌ |\n|[Charlie Lewis](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/UserAuthMethods/userId/5b0ec3ff-cea1-4eb9-8530-f2a66e5bec0a/hidePreviewBanner~/true)| Global Administrator | ❌ |\n|[Finley Robinson](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/UserAuthMethods/userId/990fd38a-c516-4e3f-82e4-d458a1ab0f91/hidePreviewBanner~/true)| Global Administrator | ❌ |\n|[Finley Robinson](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/UserAuthMethods/userId/990fd38a-c516-4e3f-82e4-d458a1ab0f91/hidePreviewBanner~/true)| Global Reader | ❌ |\n|[finley-test](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/UserAuthMethods/userId/d71ccc09-c0a3-4604-9d02-49f7a3715f49/hidePreviewBanner~/true)| Exchange Administrator | ❌ |\n|[finley-test](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/UserAuthMethods/userId/d71ccc09-c0a3-4604-9d02-49f7a3715f49/hidePreviewBanner~/true)| SharePoint Administrator | ❌ |\n|[finley-test](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/UserAuthMethods/userId/d71ccc09-c0a3-4604-9d02-49f7a3715f49/hidePreviewBanner~/true)| Global Reader | ❌ |\n|[Sam Parker](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/UserAuthMethods/userId/96d29f01-873c-46a3-b542-f7ee192cc675/hidePreviewBanner~/true)| Application Administrator | ❌ |\n|[On-Premises Directory Synchronization Service Account](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/UserAuthMethods/userId/33956e9a-cb54-42e9-94e8-d8f6ba05a55f/hidePreviewBanner~/true)| Directory Synchronization Accounts | ❌ |\n|[parker-test](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/UserAuthMethods/userId/c1bdb03c-0079-40b1-96a8-3595de3b94a2/hidePreviewBanner~/true)| Global Reader | ❌ |\n|[Ellis Cooper](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/UserAuthMethods/userId/1433571b-3d7c-4a56-a9cc-67580848bc73/hidePreviewBanner~/true)| Global Administrator | ❌ |\n|[Sage Bennett](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/UserAuthMethods/userId/518ce209-faf4-4717-add9-7129a669fa11/hidePreviewBanner~/true)| Agent ID Administrator | ❌ |\n|[Sage Bennett](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/UserAuthMethods/userId/518ce209-faf4-4717-add9-7129a669fa11/hidePreviewBanner~/true)| Global Secure Access Log Reader | ❌ |\n|[Sage Bennett](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/UserAuthMethods/userId/518ce209-faf4-4717-add9-7129a669fa11/hidePreviewBanner~/true)| Agent Registry Administrator | ❌ |\n|[Sage Bennett](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/UserAuthMethods/userId/518ce209-faf4-4717-add9-7129a669fa11/hidePreviewBanner~/true)| Privileged Role Administrator | ❌ |\n|[Sage Bennett](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/UserAuthMethods/userId/518ce209-faf4-4717-add9-7129a669fa11/hidePreviewBanner~/true)| Attribute Log Administrator | ❌ |\n|[Sage Bennett](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/UserAuthMethods/userId/518ce209-faf4-4717-add9-7129a669fa11/hidePreviewBanner~/true)| Attribute Definition Administrator | ❌ |\n|[Sage Bennett](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/UserAuthMethods/userId/518ce209-faf4-4717-add9-7129a669fa11/hidePreviewBanner~/true)| Attribute Assignment Administrator | ❌ |\n|[Sage Bennett](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/UserAuthMethods/userId/518ce209-faf4-4717-add9-7129a669fa11/hidePreviewBanner~/true)| Global Administrator | ❌ |\n|[Sage Bennett](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/UserAuthMethods/userId/518ce209-faf4-4717-add9-7129a669fa11/hidePreviewBanner~/true)| Global Reader | ❌ |\n|[Dakota Lee](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/UserAuthMethods/userId/210d3e96-015f-462d-b6d6-81e6023263df/hidePreviewBanner~/true)| Compliance Administrator | ❌ |\n|[Dakota Lee](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/UserAuthMethods/userId/210d3e96-015f-462d-b6d6-81e6023263df/hidePreviewBanner~/true)| Global Administrator | ❌ |\n|[Dakota Lee Test](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/UserAuthMethods/userId/43482f27-d1af-420f-84ba-e9148a700f45/hidePreviewBanner~/true)| Compliance Administrator | ❌ |\n|[Dakota Lee Test](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/UserAuthMethods/userId/43482f27-d1af-420f-84ba-e9148a700f45/hidePreviewBanner~/true)| Global Administrator | ❌ |\n|[Phoenix Gray](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/UserAuthMethods/userId/7094fb23-003a-4f81-9796-5daeaa603003/hidePreviewBanner~/true)| Global Administrator | ❌ |\n|[Rowan Foster](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/UserAuthMethods/userId/7804b01c-1223-4045-a393-43171298fa6b/hidePreviewBanner~/true)| Yammer Administrator | ❌ |\n|[Avery Brooks](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/UserAuthMethods/userId/a85798bd-652b-4eb9-ba90-3ee882df0179/hidePreviewBanner~/true)| Global Administrator | ❌ |\n|[Alex Wilber](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/UserAuthMethods/userId/f10bc459-0bcf-49d0-8f86-4553b8f015b8/hidePreviewBanner~/true)| Billing Administrator | ✅ |\n|[Quinn Garcia](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/UserAuthMethods/userId/ceef37b7-c865-48fb-80c9-4def11201854/hidePreviewBanner~/true)| Global Administrator | ✅ |\n|[Reese Harris](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/UserAuthMethods/userId/babe04c9-8340-4329-a727-a8cee0cd2b1a/hidePreviewBanner~/true)| Global Administrator | ✅ |\n|[Ash Williams](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/UserAuthMethods/userId/513f3db2-044c-41be-af14-431bf88a2b3e/hidePreviewBanner~/true)| Global Administrator | ✅ |\n|[Ash Williams](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/UserAuthMethods/userId/513f3db2-044c-41be-af14-431bf88a2b3e/hidePreviewBanner~/true)| Attribute Definition Administrator | ✅ |\n|[Ash Williams](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/UserAuthMethods/userId/513f3db2-044c-41be-af14-431bf88a2b3e/hidePreviewBanner~/true)| Attribute Assignment Administrator | ✅ |\n|[Drew Mitchell](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/UserAuthMethods/userId/df02402a-e291-42cc-b449-79366daa2a40/hidePreviewBanner~/true)| Azure Information Protection Administrator | ✅ |\n|[Drew Mitchell](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/UserAuthMethods/userId/df02402a-e291-42cc-b449-79366daa2a40/hidePreviewBanner~/true)| Compliance Administrator | ✅ |\n|[Drew Mitchell](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/UserAuthMethods/userId/df02402a-e291-42cc-b449-79366daa2a40/hidePreviewBanner~/true)| Global Administrator | ✅ |\n|[Drew Mitchell](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/UserAuthMethods/userId/df02402a-e291-42cc-b449-79366daa2a40/hidePreviewBanner~/true)| Application Administrator | ✅ |\n|[Drew Mitchell](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/UserAuthMethods/userId/df02402a-e291-42cc-b449-79366daa2a40/hidePreviewBanner~/true)| Purview Workload Content Administrator | ✅ |\n|[Drew Mitchell](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/UserAuthMethods/userId/df02402a-e291-42cc-b449-79366daa2a40/hidePreviewBanner~/true)| Global Reader | ✅ |\n\n\n","TestStatus":"Failed","TestDescription":"Without phishing-resistant authentication methods, privileged users are more vulnerable to phishing attacks. These types of attacks trick users into revealing their credentials to grant unauthorized access to attackers. If non-phishing-resistant authentication methods are used, attackers might intercept credentials and tokens, through methods like adversary-in-the-middle attacks, undermining the security of the privileged account.\n\nOnce a privileged account or session is compromised due to weak authentication methods, attackers might manipulate the account to maintain long-term access, create other backdoors, or modify user permissions. Attackers can also use the compromised privileged account to escalate their access even further, potentially gaining control over more sensitive systems.\n\n**Remediation action**\n\n- [Get started with a phishing-resistant passwordless authentication deployment](https://learn.microsoft.com/entra/identity/authentication/how-to-plan-prerequisites-phishing-resistant-passwordless-authentication?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci)\n- [Ensure that privileged accounts register and use phishing resistant methods](https://learn.microsoft.com/entra/identity/authentication/concept-authentication-strengths?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci#authentication-strengths)\n- [Deploy a Conditional Access policy to target privileged accounts and require phishing resistant credentials](https://learn.microsoft.com/entra/identity/conditional-access/policy-admin-phish-resistant-mfa?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci)\n- [Monitor authentication method activity](https://learn.microsoft.com/entra/identity/monitoring-health/concept-usage-insights-report?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci#authentication-methods-activity)\n","TestId":"21782"},{"TestImpact":"Medium","TestRisk":"Medium","TestSkipped":"NoCompatibleLicenseFound","TestAppliesTo":null,"TestPillar":"Network","TestCategory":"Global Secure Access","TestDescription":"Web content filtering policies are the foundation of internet access control in Global Secure Access. Without any configured policies, users have unrestricted access to all internet destinations, exposing the organization to malware, phishing sites, and inappropriate content. Create filtering policies to block dangerous website categories and establish baseline internet access controls.\n\n**Remediation action**\n\n- [Configure web content filtering policies](https://learn.microsoft.com/entra/global-secure-access/how-to-configure-web-content-filtering?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci)\n","TestTitle":"Web content filtering policies are configured","SkippedReason":"This test requires one of the following licenses: (\"Entra_Premium_Internet_Access\"). Please ensure your tenant has the appropriate licenses to run this test. See [Licensing & Service Plans](https://learn.microsoft.com/entra/identity/users/licensing-service-plan-reference)","TestId":"25408","TestImplementationCost":"Medium","TestMinimumLicense":["Entra_Premium_Internet_Access"],"TestSfiPillar":"Protect networks","TestResult":"\nSkipped. This test requires one of the following licenses: (\"Entra_Premium_Internet_Access\"). Please ensure your tenant has the appropriate licenses to run this test. See [Licensing & Service Plans](https://learn.microsoft.com/entra/identity/users/licensing-service-plan-reference)\n\n","TestStatus":"Skipped","TestTags":null},{"TestImplementationCost":"Medium","TestPillar":"Devices","TestCategory":"Tenant","SkippedReason":null,"TestImpact":"Medium","TestAppliesTo":null,"TestSfiPillar":"Protect tenants and isolate production systems","TestSkipped":"","TestMinimumLicense":"Intune","TestTags":null,"TestTitle":"macOS - Platform SSO is configured and assigned","TestRisk":"Medium","TestResult":"\nmacOS SSO policies are configured and assigned in Intune.\n\n\n## macOS SSO Policies\n\n| Policy Name | Status | Assignment Target |\n| :---------- | :----- | :---------------- |\n| [Platform SSO](https://intune.microsoft.com/#view/Microsoft_Intune_DeviceSettings/DevicesMenu/~/configuration) | ✅ Assigned | **Included:** All Users |\n\n\n\n","TestStatus":"Passed","TestDescription":"If Platform SSO policies aren't enforced on macOS devices, endpoints might rely on insecure or inconsistent authentication mechanisms, allowing attackers to bypass Conditional Access and compliance policies. This opens the door to lateral movement across cloud services and on-premises resources, especially when federated identities are used. Threat actors can persist by leveraging stolen tokens or cached credentials and exfiltrate sensitive data through unmanaged apps or browser sessions. The absence of SSO enforcement also undermines app protection policies and device posture assessments, making it difficult to detect and contain breaches. Ultimately, failure to configure and assign macOS Platform SSO policies compromises identity security and weakens the organization's Zero Trust posture.\n\nEnforcing Platform SSO policies on macOS devices ensures consistent, secure authentication across apps and services. This strengthens identity protection, supports Conditional Access enforcement, and aligns with Zero Trust by reducing reliance on local credentials and improving posture assessments.\n\n**Remediation action**\n\nUse Intune to configure and assign Platform SSO policies for macOS devices to enforce secure authentication and strengthen identity protection, see:\n\n- [Configure Platform SSO for macOS in Intune](https://learn.microsoft.com/intune/intune-service/configuration/platform-sso-macos?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci) – *Step-by-step guidance for enabling Platform SSO on macOS devices.*\n- [Single sign-on (SSO) overview and options for Apple devices in Microsoft Intune](https://learn.microsoft.com/intune/intune-service/configuration/use-enterprise-sso-plug-in-ios-ipados-macos?pivots=macos&wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci) – *Overview of SSO options available for Apple platforms.*\n","TestId":"24568"},{"TestImplementationCost":"Medium","TestPillar":"Identity","TestCategory":"Access control","SkippedReason":"UnderConstruction","TestImpact":"Medium","TestAppliesTo":["Identity"],"TestSfiPillar":"Protect identities and secrets","TestSkipped":"UnderConstruction","TestMinimumLicense":"P2","TestTags":["Identity"],"TestTitle":"Enable Microsoft Entra ID Protection policy to enforce multifactor authentication registration","TestRisk":"Low","TestResult":"\nPlanned for future release.\n\n","TestStatus":"Planned","TestDescription":"Require multifactor authentication (MFA) registration for all users. Based on studies, your account is more than 99% less likely to be compromised if you're using MFA. Even if you don't require MFA all the time, this policy ensures your users are ready when it's needed.\n\n**Remediation action**\n\n- [Configure the multifactor authentication registration policy](https://learn.microsoft.com/entra/id-protection/howto-identity-protection-configure-mfa-policy?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci)\n","TestId":"21893"},{"TestImplementationCost":"","TestPillar":"Infrastructure","TestCategory":"Restrict unauthorized network access","SkippedReason":null,"TestImpact":"","TestAppliesTo":null,"TestSfiPillar":"Protect tenants and isolate production systems","TestSkipped":"","TestMinimumLicense":"N/A","TestTags":null,"TestTitle":"IP forwarding on your virtual machine should be disabled","TestRisk":"Medium","TestResult":"IP forwarding on your virtual machine should be disabled\n\n| Subscription | Resource group | Resource type | Affected resource | Status | Azure portal |\n| :----------- | :------------- | :------------ | :---------------- | :----- | :----------- |\n| [Visual Studio Enterprise Subscription](https://portal.azure.com/#resource/subscriptions/54d3ea01-5a07-45d0-8d69-e5f5b0b20098) | indiavm_group | virtualmachines | [india-2](https://portal.azure.com/#resource/subscriptions/54d3ea01-5a07-45d0-8d69-e5f5b0b20098/resourceGroups/INDIAVM_GROUP/providers/Microsoft.Compute/virtualMachines/india-2) | ✅ | [View recommendation](https://portal.azure.com/#blade/Microsoft_Azure_Security/RecommendationsBlade/assessmentKey/c3b51c94-588b-426b-a892-24696f9e54cc/resourceId/%2fsubscriptions%2f54d3ea01-5a07-45d0-8d69-e5f5b0b20098%2fresourceGroups%2fINDIAVM_GROUP%2fproviders%2fMicrosoft.Compute%2fvirtualMachines%2findia-2) |\n| [Visual Studio Enterprise Subscription](https://portal.azure.com/#resource/subscriptions/54d3ea01-5a07-45d0-8d69-e5f5b0b20098) | indiavm_group | virtualmachines | [indiavm](https://portal.azure.com/#resource/subscriptions/54d3ea01-5a07-45d0-8d69-e5f5b0b20098/resourceGroups/INDIAVM_GROUP/providers/Microsoft.Compute/virtualMachines/indiavm) | ✅ | [View recommendation](https://portal.azure.com/#blade/Microsoft_Azure_Security/RecommendationsBlade/assessmentKey/c3b51c94-588b-426b-a892-24696f9e54cc/resourceId/%2fsubscriptions%2f54d3ea01-5a07-45d0-8d69-e5f5b0b20098%2fresourceGroups%2fINDIAVM_GROUP%2fproviders%2fMicrosoft.Compute%2fvirtualMachines%2findiavm) |\n","TestStatus":"Passed","TestDescription":"Defender for Cloud has discovered that IP forwarding is enabled on some of your virtual machines. Enabling IP forwarding on a virtual machine's NIC allows the machine to receive traffic addressed to other destinations. IP forwarding is rarely required (e.g., when using the VM as a network virtual appliance), and therefore, this should be reviewed by the network security team.\n\n**Remediation action**\n\nWe recommend you edit the IP configurations of the NICs belonging to some of your virtual machines.
To disable IP forwarding:
1. Select a VM from the list below, or click 'Take action' if you've arrived from a specific VM's recommendation blade.
2. In the 'Networking' blade, click on the NIC link ('Network Interface' in the top left).
3. In the 'IP configurations' blade, set the 'IP forwarding' field to 'Disabled'.
4. Click 'Save'.","TestId":"c3b51c94-588b-426b-a892-24696f9e54cc"},{"TestImpact":"Low","TestRisk":"High","TestSkipped":"NoCompatibleLicenseFound","TestAppliesTo":null,"TestPillar":"Network","TestCategory":"Global Secure Access","TestDescription":"Without extended retention for Global Secure Access audit and traffic logs, threat actors can operate beyond the default 30-day retention window, knowing that their activities are automatically purged before detection occurs. Security investigations often require historical analysis spanning weeks or months to identify compromise vectors, lateral movement patterns, and data exfiltration channels.\n\nWithout adequate log retention:\n\n- Security teams can't establish baseline behavior patterns, perform retrospective threat hunting, or correlate network access events across extended timeframes.\n- Organizations subject to regulatory frameworks like [GDPR](https://learn.microsoft.com/compliance/regulatory/gdpr?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci), HIPAA, PCI DSS, and SOX face compliance violations when they're unable to produce audit trails for mandated retention periods.\n- Root cause analysis during incident response is limited, potentially allowing threat actors to maintain persistence while organizations focus on visible symptoms.\n\n**Remediation action**\n\n- [Configure diagnostic settings with a Log Analytics workspace](https://learn.microsoft.com/entra/identity/monitoring-health/howto-integrate-activity-logs-with-azure-monitor-logs?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci) for an extended retention of 90-730 days, with query capabilities.\n- [Configure Log Analytics workspace retention](https://learn.microsoft.com/azure/azure-monitor/logs/data-retention-archive?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci) to meet organizational security and compliance requirements (minimum 90 days recommended).\n- [Enable table-level retention](https://learn.microsoft.com/azure/azure-monitor/logs/data-retention-archive?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci#configure-table-level-retention) for specific Global Secure Access tables to extend beyond workspace defaults.\n","TestTitle":"Network access logs are retained for security analysis and compliance requirements","SkippedReason":"This test requires one of the following licenses: (\"Entra_Premium_Private_Access\") OR (\"Entra_Premium_Internet_Access\"). Please ensure your tenant has the appropriate licenses to run this test. See [Licensing & Service Plans](https://learn.microsoft.com/entra/identity/users/licensing-service-plan-reference)","TestId":"25420","TestImplementationCost":"Low","TestMinimumLicense":["Entra_Premium_Private_Access","Entra_Premium_Internet_Access"],"TestSfiPillar":"Monitor and detect cyberthreats","TestResult":"\nSkipped. This test requires one of the following licenses: (\"Entra_Premium_Private_Access\") OR (\"Entra_Premium_Internet_Access\"). Please ensure your tenant has the appropriate licenses to run this test. See [Licensing & Service Plans](https://learn.microsoft.com/entra/identity/users/licensing-service-plan-reference)\n\n","TestStatus":"Skipped","TestTags":null},{"TestImplementationCost":"Low","TestPillar":"Identity","TestCategory":"Access control","SkippedReason":"UnderConstruction","TestImpact":"Low","TestAppliesTo":["Identity"],"TestSfiPillar":"Protect identities and secrets","TestSkipped":"UnderConstruction","TestMinimumLicense":null,"TestTags":["Identity"],"TestTitle":"No Active low priority Entra recommendations found","TestRisk":"Low","TestResult":"\nPlanned for future release.\n","TestStatus":"Planned","TestDescription":"...\n\n**Remediation action**\n\n","TestId":"21984"},{"TestImplementationCost":"","TestPillar":"Infrastructure","TestCategory":"Remediate vulnerabilities","SkippedReason":null,"TestImpact":"","TestAppliesTo":null,"TestSfiPillar":"Protect tenants and isolate production systems","TestSkipped":"","TestMinimumLicense":"N/A","TestTags":null,"TestTitle":"Machines should have a vulnerability assessment solution","TestRisk":"Medium","TestResult":"Machines should have a vulnerability assessment solution\n\n| Subscription | Resource group | Resource type | Affected resource | Status | Azure portal |\n| :----------- | :------------- | :------------ | :---------------- | :----- | :----------- |\n| [Visual Studio Enterprise Subscription](https://portal.azure.com/#resource/subscriptions/54d3ea01-5a07-45d0-8d69-e5f5b0b20098) | indiavm_group | virtualmachines | [india-2](https://portal.azure.com/#resource/subscriptions/54d3ea01-5a07-45d0-8d69-e5f5b0b20098/resourceGroups/INDIAVM_GROUP/providers/Microsoft.Compute/virtualMachines/india-2) | ❌ | [View recommendation](https://portal.azure.com/#blade/Microsoft_Azure_Security/RecommendationsBlade/assessmentKey/ffff0522-1e88-47fc-8382-2a80ba848f5d/resourceId/%2fsubscriptions%2f54d3ea01-5a07-45d0-8d69-e5f5b0b20098%2fresourceGroups%2fINDIAVM_GROUP%2fproviders%2fMicrosoft.Compute%2fvirtualMachines%2findia-2) |\n| [Visual Studio Enterprise Subscription](https://portal.azure.com/#resource/subscriptions/54d3ea01-5a07-45d0-8d69-e5f5b0b20098) | indiavm_group | virtualmachines | [indiavm](https://portal.azure.com/#resource/subscriptions/54d3ea01-5a07-45d0-8d69-e5f5b0b20098/resourceGroups/INDIAVM_GROUP/providers/Microsoft.Compute/virtualMachines/indiavm) | N/A | [View recommendation](https://portal.azure.com/#blade/Microsoft_Azure_Security/RecommendationsBlade/assessmentKey/ffff0522-1e88-47fc-8382-2a80ba848f5d/resourceId/%2fsubscriptions%2f54d3ea01-5a07-45d0-8d69-e5f5b0b20098%2fresourceGroups%2fINDIAVM_GROUP%2fproviders%2fMicrosoft.Compute%2fvirtualMachines%2findiavm) |\n","TestStatus":"Failed","TestDescription":"Defender for Cloud regularly checks your connected machines to ensure they're running vulnerability assessment tools. Use this recommendation to deploy a vulnerability assessment solution.\n\n**Remediation action**\n\nTo deploy a vulnerability assessment solution, in the \"Unhealthy resources\" tab, select the resources, then select \"Remediate\". Read the remediation details in the confirmation box, insert the relevant parameters if required and approve the remediation. Note: It can take several hours after remediation completes to see the resources in the 'Healthy resources' tab","TestId":"ffff0522-1e88-47fc-8382-2a80ba848f5d"},{"TestImplementationCost":"Medium","TestPillar":"Identity","TestCategory":"Credential management","SkippedReason":"UnderConstruction","TestImpact":"Medium","TestAppliesTo":["Identity"],"TestSfiPillar":"Protect identities and secrets","TestSkipped":"UnderConstruction","TestMinimumLicense":"P1","TestTags":["Identity"],"TestTitle":"Turn off Seamless SSO if there are is no usage","TestRisk":"Medium","TestResult":"\nPlanned for future release.\n\n","TestStatus":"Planned","TestDescription":"Microsoft Entra seamless single sign-on (Seamless SSO) is a legacy authentication feature designed to provide passwordless access for domain-joined devices that are not hybrid Microsoft Entra ID joined. Seamless SSO relies on Kerberos authentication and is primarily beneficial for older operating systems like Windows 7 and Windows 8.1, which do not support Primary Refresh Tokens (PRT). If these legacy systems are no longer present in the environment, continuing to use Seamless SSO introduces unnecessary complexity and potential security exposure. Threat actors could exploit misconfigured or stale Kerberos tickets, or compromise the `AZUREADSSOACC` computer account in Active Directory, which holds the Kerberos decryption key used by Microsoft Entra ID. Once compromised, attackers could impersonate users, bypass modern authentication controls, and gain unauthorized access to cloud resources. Disabling Seamless SSO in environments where it is no longer needed reduces the attack surface and enforces the use of modern, token-based authentication mechanisms that offer stronger protections. \n\n**Remediation action**\n\n- [Review how Seamless SSO works](https://learn.microsoft.com/entra/identity/hybrid/connect/how-to-connect-sso-how-it-works?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci)\n- [Disable Seamless SSO](https://learn.microsoft.com/entra/identity/hybrid/connect/how-to-connect-sso-faq?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci#how-can-i-disable-seamless-sso-)\n- [Clean up stale devices in Microsoft Entra ID](https://learn.microsoft.com/entra/identity/devices/manage-stale-devices?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci)\n","TestId":"21985"},{"TestImpact":"Medium","TestRisk":"Medium","TestSkipped":"","TestAppliesTo":null,"TestPillar":"Data","TestCategory":"Information Protection","TestDescription":"Without mail flow rules, organizations depend on users to manually apply sensitivity labels or encrypt messages. This approach can lead to inconsistencies and errors, which may result in sensitive emails being sent without proper protection and increase the risk of unauthorized access and data exfiltration.\n\nMail flow rules help automatically add encryption and set permissions for emails that meet certain conditions, such as:\n- Mail sent to people outside the company \n- Mail that contains sensitive information \n- Mail that must follow department-based requirements \nThis ensures that important messages are protected without relying on users to manually secure them.\n\n**Remediation action**\n\n- [Set up Message Encryption and mail flow rules to use Microsoft Purview Message Encryption](https://learn.microsoft.com/purview/set-up-new-message-encryption-capabilities?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci#next-steps-define-mail-flow-rules-to-use-microsoft-purview-message-encryption)\n","TestTitle":"Mail flow rules with rights protection","SkippedReason":null,"TestId":"35029","TestImplementationCost":"Medium","TestMinimumLicense":["RMS_S_PREMIUM2"],"TestSfiPillar":"Protect tenants and production systems","TestResult":"\n✅ Mail flow rules with rights protection are configured, automatically protecting sensitive emails through encryption and restriction policies.\n\n### [Protection rules configuration](https://admin.exchange.microsoft.com/#/transportrules)\n\n| Rule name | State | Priority | OME | RMS template | Classification | Last modified |\n| :--- | :--- | :--- | :--- | :--- | :--- | :--- |\n| [powershell_test](https://admin.exchange.microsoft.com/#/transportrules) | ✅ Enabled | 0 | No | Encrypt | N/A | 2026-02-09 |\n| [Encrypt mail for sky@contoso.com](https://admin.exchange.microsoft.com/#/transportrules) | ✅ Enabled | 1 | No | Encrypt | N/A | 2026-02-09 |\n\n### Rules by action type\n\n| Action type | Count |\n| :--- | :--- |\n| OME encryption rules | 0 |\n| RMS template application | 2 |\n| Classification rules | 0 |\n\n### Summary\n\n| Metric | Count |\n| :--- | :--- |\n| Total protection rules | 2 |\n| Enabled rules | 2 |\n| Disabled rules | 0 |\n| External email protection | ✅ Yes |\n\n","TestStatus":"Passed","TestTags":null},{"TestImpact":"Low","TestRisk":"High","TestSkipped":"NoCompatibleLicenseFound","TestAppliesTo":null,"TestPillar":"Network","TestCategory":"Global Secure Access","TestDescription":"When you connect remote networks to Global Secure Access through IPsec tunnels but don't set up cloud firewall policies, all internet-bound traffic from branch offices goes through the Security Service Edge without egress filtering controls. If a threat actor gains access to a branch office workstation, they can make outbound connections to command-and-control infrastructure, exfiltrate data over standard ports, or download malicious payloads without network-layer inspection.\n\nWithout Global Secure Access cloud firewall:\n\n- You can't enforce a deny-by-default posture or restrict outbound communications from branch networks to unauthorized internet destinations.\n- Threat actors can stage data for exfiltration, pivot to cloud resources, or move laterally without detection.\n- Traditional perimeter defenses might assume all egress is legitimate, resulting in gaps in security coverage.\n\nCloud firewall policies linked to the baseline profile provide centralized egress control for all remote network traffic. Administrators can use these policies to define granular filtering rules that restrict unauthorized outbound communications.\n\n**Remediation action**\n\n- As a prerequisite for cloud firewall, [configure remote networks for internet access](https://learn.microsoft.com/entra/global-secure-access/how-to-create-remote-networks?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci).\n- Follow the steps in [Configure Global Secure Access cloud firewall](https://learn.microsoft.com/entra/global-secure-access/how-to-configure-cloud-firewall?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci) to:\n - Create a cloud firewall policy with appropriate filtering rules.\n - Add or update firewall rules based on source IP, destination IP, ports, and protocols.\n - Link the cloud firewall policy to the baseline profile for remote networks.\n","TestTitle":"Global Secure Access cloud firewall protects branch office internet traffic","SkippedReason":"This test requires one of the following licenses: (\"Entra_Premium_Internet_Access\"). Please ensure your tenant has the appropriate licenses to run this test. See [Licensing & Service Plans](https://learn.microsoft.com/entra/identity/users/licensing-service-plan-reference)","TestId":"25416","TestImplementationCost":"Medium","TestMinimumLicense":["Entra_Premium_Internet_Access"],"TestSfiPillar":"Protect networks","TestResult":"\nSkipped. This test requires one of the following licenses: (\"Entra_Premium_Internet_Access\"). Please ensure your tenant has the appropriate licenses to run this test. See [Licensing & Service Plans](https://learn.microsoft.com/entra/identity/users/licensing-service-plan-reference)\n\n","TestStatus":"Skipped","TestTags":null},{"TestImplementationCost":"Low","TestPillar":"Identity","TestCategory":"Devices","SkippedReason":null,"TestImpact":"Medium","TestAppliesTo":null,"TestSfiPillar":"Protect engineering systems","TestSkipped":"","TestMinimumLicense":"Free","TestTags":null,"TestTitle":"Limit the maximum number of devices per user to 10","TestRisk":"High","TestResult":"\n[Maximum number of devices per user](https://entra.microsoft.com/#view/Microsoft_AAD_Devices/DevicesMenuBlade/~/DeviceSettings/menuId/Overview) is set to 10\n\n","TestStatus":"Passed","TestDescription":"Controlling device proliferation is important. Set a reasonable limit on the number of devices each user can register in your Microsoft Entra ID tenant. Limiting device registration maintains security while allowing business flexibility. Microsoft Entra ID lets users register up to 50 devices by default. Reducing this number to 10 minimizes the attack surface and simplifies device management.\n\n**Remediation action**\n\n- Learn how to [limit the maximum number of devices per user](https://learn.microsoft.com/entra/identity/devices/manage-device-identities?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci#configure-device-settings).\n","TestId":"21837"},{"TestImplementationCost":"Medium","TestPillar":"Identity","TestCategory":"Access control","SkippedReason":null,"TestImpact":"Medium","TestAppliesTo":["Identity"],"TestSfiPillar":"Accelerate response and remediation","TestSkipped":"","TestMinimumLicense":"P2","TestTags":["Identity"],"TestTitle":"Block high risk sign-ins","TestRisk":"High","TestResult":"\nSome high-risk sign-in attempts are not adequately mitigated by Conditional Access policies.\n\n","TestStatus":"Failed","TestDescription":"When high-risk sign-ins are not properly restricted through Conditional Access policies, organizations expose themselves to security vulnerabilities. Threat actors can exploit these gaps for initial access through compromised credentials, credential stuffing attacks, or anomalous sign-in patterns that Microsoft Entra ID Protection identifies as risky behaviors. Without appropriate restrictions, threat actors who successfully authenticate during high-risk scenarios can perform privilege escalation by misusing the authenticated session to access sensitive resources, modify security configurations, or conduct reconnaissance activities within the environment. Once threat actors establish access through uncontrolled high-risk sign-ins, they can achieve persistence by creating additional accounts, installing backdoors, or modifying authentication policies to maintain long-term access to the organization's resources. The unrestricted access enables threat actors to conduct lateral movement across systems and applications using the authenticated session, potentially accessing sensitive data stores, administrative interfaces, or critical business applications. Finally, threat actors achieve impact through data exfiltration, or compromise business-critical systems while maintaining plausible deniability by exploiting the fact that their risky authentication was not properly challenged or blocked.\n\n**Remediation action**\n\n- [Deploy a Conditional Access policy to require MFA for elevated sign-in risk](https://learn.microsoft.com/entra/identity/conditional-access/policy-risk-based-sign-in?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci)\n","TestId":"21799"},{"TestImplementationCost":"High","TestPillar":"Identity","TestCategory":"Monitoring","SkippedReason":"This test is for tenants that are licensed for Entra Workload ID. See [Entra Workload ID licensing](https://learn.microsoft.com/entra/workload-id/workload-identities-faqs)","TestImpact":"Low","TestAppliesTo":null,"TestSfiPillar":"Monitor and detect cyberthreats","TestSkipped":"NotLicensedEntraWorkloadID","TestMinimumLicense":"P2","TestTags":null,"TestTitle":"All risky workload identities are triaged","TestRisk":"High","TestResult":"\nSkipped. This test is for tenants that are licensed for Entra Workload ID. See [Entra Workload ID licensing](https://learn.microsoft.com/entra/workload-id/workload-identities-faqs)\n\n","TestStatus":"Skipped","TestDescription":"Compromised workload identities (service principals and applications) allow threat actors to gain persistent access without user interaction or multifactor authentication. Microsoft Entra ID Protection monitors these identities for suspicious activities like leaked credentials, anomalous API traffic, and malicious applications. Unaddressed risky workload identities enable privilege escalation, lateral movement, data exfiltration, and persistent backdoors that bypass traditional security controls. Organizations must systematically investigate and remediate these risks to prevent unauthorized access. \n\n**Remediation action**\n\n- [Investigate and remediate risky workload identities](https://learn.microsoft.com/entra/id-protection/concept-workload-identity-risk?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci#investigate-risky-workload-identities)\n- [Apply Conditional Access policies for workload identities](https://learn.microsoft.com/entra/identity/conditional-access/workload-identity?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci)\n","TestId":21862},{"TestImplementationCost":"Medium","TestPillar":"Network","TestCategory":"Global Secure Access","SkippedReason":null,"TestImpact":"Medium","TestAppliesTo":null,"TestSfiPillar":"Protect networks","TestSkipped":"","TestMinimumLicense":["AAD_PREMIUM","Entra_Premium_Private_Access"],"TestTags":null,"TestTitle":"Quick Access is enabled and bound to a connector","TestRisk":"High","TestResult":"\nQuick Access is not bound to a connector group with active connectors, or the Private Access traffic forwarding profile is not enabled.\n\n\n## [Quick Access Connector Binding Status](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/QuickAccessMenuBlade/~/GlobalSecureAccess)\n\n| Property | Value |\n| :--- | :--- |\n| Private Access Profile State | disabled |\n| Connector Group Name | Default |\n| Quick Access App Assigned | Yes |\n\n","TestStatus":"Failed","TestDescription":"When Quick Access is not configured or is not bound to a connector group with connectors, private network resources remain accessible through paths that bypass Global Secure Access controls. Threat actors who compromise user credentials can access internal FQDNs and IP ranges without Conditional Access evaluation, because the traffic does not route through the Global Secure Access service. Without connector-mediated traffic brokering, there is no enforcement point between the user and the private resource, which means Conditional Access policies targeting the Quick Access enterprise application do not apply. A threat actor can use stolen credentials to authenticate, reach internal resources over a VPN or direct network path, move between internal systems, and exfiltrate data without the organization having visibility through Global Secure Access traffic logs. Binding Quick Access to a connector group with connectors ensures that private network traffic routes through Global Secure Access, where Conditional Access policies, user assignments, and traffic logging apply.\n\n**Remediation action**\n\nConfigure Quick Access and connectors for Entra Private Access, and ensure the Private Access forwarding profile is enabled:\n- [Configure Quick Access for Global Secure Access Private Access](https://learn.microsoft.com/en-us/entra/global-secure-access/how-to-configure-quick-access)\n- [Configure connectors for Global Secure Access](https://learn.microsoft.com/en-us/entra/global-secure-access/how-to-configure-connectors)\n- [Enable the Private Access traffic forwarding profile](https://learn.microsoft.com/en-us/entra/global-secure-access/how-to-manage-private-access-profile)\n- [Understand Microsoft Entra Private Access concepts](https://learn.microsoft.com/en-us/entra/global-secure-access/concept-private-access)\n","TestId":"25393"},{"TestImplementationCost":"Low","TestPillar":"Devices","TestCategory":"Device","SkippedReason":null,"TestImpact":"Low","TestAppliesTo":null,"TestSfiPillar":"Protect identities and secrets","TestSkipped":"","TestMinimumLicense":"Intune","TestTags":null,"TestTitle":"Intune Local Users and Groups policy is created and assigned","TestRisk":"High","TestResult":"\nNo Local Users and Groups policy is configured or assigned.\n\n\n\n","TestStatus":"Failed","TestDescription":"Without a properly configured and assigned Local Users and Groups policy in Intune, threat actors can exploit unmanaged or misconfigured local accounts on Windows devices. This can lead to unauthorized privilege escalation, persistence, and lateral movement within the environment. If local administrator accounts aren't controlled, attackers can create hidden accounts or elevate privileges, bypassing compliance and security controls. This gap increases the risk of data exfiltration, ransomware deployment, and regulatory noncompliance.\n\nEnsuring that Local Users and Groups policies are enforced on managed Windows devices, by using account protection profiles, is critical to maintaining a secure and compliant device fleet.\n\n\n**Remediation action**\n\nConfigure and deploy a **Local user group membership** profile from Intune account protection policy to restrict and manage local account usage on Windows devices: \n- Create an [Account protection policy for endpoint security in Intune](https://learn.microsoft.com/intune/intune-service/protect/endpoint-security-account-protection-policy?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci#account-protection-profiles)\n- [Assign policies in Intune](https://learn.microsoft.com/intune/intune-service/configuration/device-profile-assign?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci#assign-a-policy-to-users-or-groups)\n","TestId":"24564"},{"TestImplementationCost":"Low","TestPillar":"Identity","TestCategory":"Access control","SkippedReason":null,"TestImpact":"Low","TestAppliesTo":null,"TestSfiPillar":"Protect identities and secrets","TestSkipped":"","TestMinimumLicense":"P1","TestTags":null,"TestTitle":"Microsoft Authenticator app shows sign-in context","TestRisk":"Medium","TestResult":"\nMicrosoft Authenticator shows application name and geographic location in push notifications.\n\n\n## Microsoft Authenticator settings\n\n\nFeature Settings:\n\n✅ **Application Name**\n- Status: Enabled\n- Include Target: All users\n- Exclude Target: No exclusions\n\n✅ **Geographic Location**\n- Status: Enabled\n- Include Target: All users\n- Exclude Target: No exclusions\n\n\n","TestStatus":"Passed","TestDescription":"Without sign-in context, threat actors can exploit authentication fatigue by flooding users with push notifications, increasing the chance that a user accidentally approves a malicious request. When users get generic push notifications without the application name or geographic location, they don't have the information they need to make informed approval decisions. This lack of context makes users vulnerable to social engineering attacks, especially when threat actors time their requests during periods of legitimate user activity. This vulnerability is especially dangerous when threat actors gain initial access through credential harvesting or password spraying attacks and then try to establish persistence by approving multifactor authentication (MFA) requests from unexpected applications or locations. Without contextual information, users can't detect unusual sign-in attempts, allowing threat actors to maintain access and escalate privileges by moving laterally through systems after bypassing the initial authentication barrier. Without application and location context, security teams also lose valuable telemetry for detecting suspicious authentication patterns that can indicate ongoing compromise or reconnaissance activities. \n\n**Remediation action**\nGive users the context they need to make informed approval decisions. Configure Microsoft Authenticator notifications by setting the Authentication methods policy to include the application name and geographic location. \n- [Use additional context in Authenticator notifications - Authentication methods policy](https://learn.microsoft.com/entra/identity/authentication/how-to-mfa-additional-context?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci)\n","TestId":"21802"},{"TestImplementationCost":"Medium","TestPillar":"Identity","TestCategory":"Application management","SkippedReason":null,"TestImpact":"Low","TestAppliesTo":["Identity"],"TestSfiPillar":"Protect identities and secrets","TestSkipped":"","TestMinimumLicense":"Free","TestTags":["Identity"],"TestTitle":"Service principals don't have certificates or credentials associated with them","TestRisk":"Medium","TestResult":"\nFound Service Principals with credentials configured in the tenant, which represents a security risk.\n\n\n## Service Principals with credentials configured in the tenant\n\n\n| Service Principal Name | Credentials Type | Credentials Expiration Date | Expiry Status |\n| :--------------------- | :--------------- | :-------------------------- | :------------ |\n| [21869testapp](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/Overview/objectId/e69e29be-ba40-445a-9824-a3a45e0ae57a/appId/dd63d132-18fb-4f2e-aec4-82b97f30301f) | Password Credentials | 2028-10-27 | ✅ Current |\n| [APP-2732_Genesys Cloud TCCC-G-TFS-Prod](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/Overview/objectId/ba63bb52-182c-4ec6-9cc8-ad2287cf51ed/appId/76249b01-8747-4db4-843f-6478d5b32b14) | Password Credentials | 2028-07-30 | ✅ Current |\n| [AWS Single-Account Access](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/Overview/objectId/dc89bf5d-83e8-4419-9162-3b9280a85755/appId/091edd89-b342-4bb5-9144-82fe6c913987) | Password Credentials | 2025-10-26 | ❗ Expired |\n| [Automation](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/Overview/objectId/f79df990-9ad2-4142-b5fd-8945ff334da3/appId/dc7d83b5-d38b-4488-8952-7abf02e71590) | Password Credentials | 2027-03-03 | ✅ Current |\n| [Azure AD SAML Toolkit](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/Overview/objectId/4317fd0a-dcee-45bf-8e94-9a66638b11e0/appId/6f5ed68c-9fad-4d78-bf88-2b16bbe16338) | Password Credentials | 2028-10-11 | ✅ Current |\n| [Dropbox Business](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/Overview/objectId/5eec0e98-b81a-422a-ab61-f8de2729330d/appId/f76d7d98-02ee-4e62-9345-36016a72e664) | Password Credentials | 2024-02-17 | ❗ Expired |\n| [charlie AWS Account](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/Overview/objectId/39861745-eda1-4e3c-8358-d0ba931f12bb/appId/d3a04f85-a969-436b-bf4d-eae0a91efb4c) | Password Credentials | 2028-01-07 | ✅ Current |\n| [charlie- Genesys Cloud for Azure](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/Overview/objectId/84dc13ec-5754-4745-90f9-5cc92a5ded28/appId/9c599cd2-9fb0-4815-b65c-83be33f5df1b) | Password Credentials | 2028-07-30 | ✅ Current |\n| [P2P Server](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/Overview/objectId/05c98ca9-d208-4d3e-ad24-911bfc3d028c/appId/2af9f5c5-0ffc-4d1c-ba2e-72cf6382df06) | Password Credentials | 2024-06-11 | ❗ Expired |\n| [Salesforce](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/Overview/objectId/13720002-03b6-462f-ac2f-765f0f9b3f58/appId/1a2a1d4c-1d76-44ec-95f4-3ed5345423a9) | Password Credentials | 2025-10-02 | ❗ Expired |\n| [Saml test entity id](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/Overview/objectId/d589a2e6-4a78-4cdd-901b-f574dc7880db/appId/6590313e-1c00-4c07-be28-72858e837a52) | Password Credentials | 2025-11-17 | ❗ Expired |\n| [ServiceNow](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/Overview/objectId/9a8af246-0d94-42eb-aaaf-836a9f9a4974/appId/ecbbb1c8-ef06-48c4-9211-9ffbfbc24b94) | Password Credentials | 2024-02-15 | ❗ Expired |\n| [SumoLogic](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/Overview/objectId/144df581-a0c9-4280-9739-0c3612ab9ccf/appId/1b6c36b2-f2b1-43d3-b74f-8d52c44fc9c1) | Password Credentials | 2027-02-15 | ✅ Current |\n| [claimtest](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/Overview/objectId/f7b07e81-79a0-4e51-b93a-169b8f2f6c4e/appId/f816d68b-aec7-4eab-9ebc-bd23b0d04e35) | Password Credentials | 2028-02-26 | ✅ Current |\n| [test](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/Overview/objectId/31e80a1b-3faa-4ce9-9794-2b77f61f20f7/appId/8ae2b566-71f5-467e-8960-cfe8da3a2cfa) | Password Credentials | 2025-10-10 | ❗ Expired |\n| [21869testapp](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/Overview/objectId/e69e29be-ba40-445a-9824-a3a45e0ae57a/appId/dd63d132-18fb-4f2e-aec4-82b97f30301f) | Key Credentials | 2028-10-27 | ✅ Current |\n| [APP-2732_Genesys Cloud TCCC-G-TFS-Prod](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/Overview/objectId/ba63bb52-182c-4ec6-9cc8-ad2287cf51ed/appId/76249b01-8747-4db4-843f-6478d5b32b14) | Key Credentials | 2028-07-30 | ✅ Current |\n| [AWS Single-Account Access](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/Overview/objectId/dc89bf5d-83e8-4419-9162-3b9280a85755/appId/091edd89-b342-4bb5-9144-82fe6c913987) | Key Credentials | 2025-10-26 | ❗ Expired |\n| [Azure AD SAML Toolkit](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/Overview/objectId/4317fd0a-dcee-45bf-8e94-9a66638b11e0/appId/6f5ed68c-9fad-4d78-bf88-2b16bbe16338) | Key Credentials | 2028-10-11 | ✅ Current |\n| [Dropbox Business](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/Overview/objectId/5eec0e98-b81a-422a-ab61-f8de2729330d/appId/f76d7d98-02ee-4e62-9345-36016a72e664) | Key Credentials | 2024-02-17 | ❗ Expired |\n| [charlie AWS Account](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/Overview/objectId/39861745-eda1-4e3c-8358-d0ba931f12bb/appId/d3a04f85-a969-436b-bf4d-eae0a91efb4c) | Key Credentials | 2028-01-07 | ✅ Current |\n| [charlie- Genesys Cloud for Azure](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/Overview/objectId/84dc13ec-5754-4745-90f9-5cc92a5ded28/appId/9c599cd2-9fb0-4815-b65c-83be33f5df1b) | Key Credentials | 2028-07-30 | ✅ Current |\n| [P2P Server](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/Overview/objectId/05c98ca9-d208-4d3e-ad24-911bfc3d028c/appId/2af9f5c5-0ffc-4d1c-ba2e-72cf6382df06) | Key Credentials | 2024-06-11 | ❗ Expired |\n| [Salesforce](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/Overview/objectId/13720002-03b6-462f-ac2f-765f0f9b3f58/appId/1a2a1d4c-1d76-44ec-95f4-3ed5345423a9) | Key Credentials | 2025-10-02 | ❗ Expired |\n| [Saml test entity id](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/Overview/objectId/d589a2e6-4a78-4cdd-901b-f574dc7880db/appId/6590313e-1c00-4c07-be28-72858e837a52) | Key Credentials | 2025-11-17 | ❗ Expired |\n| [ServiceNow](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/Overview/objectId/9a8af246-0d94-42eb-aaaf-836a9f9a4974/appId/ecbbb1c8-ef06-48c4-9211-9ffbfbc24b94) | Key Credentials | 2024-02-15 | ❗ Expired |\n| [SumoLogic](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/Overview/objectId/144df581-a0c9-4280-9739-0c3612ab9ccf/appId/1b6c36b2-f2b1-43d3-b74f-8d52c44fc9c1) | Key Credentials | 2027-02-15 | ✅ Current |\n| [claimtest](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/Overview/objectId/f7b07e81-79a0-4e51-b93a-169b8f2f6c4e/appId/f816d68b-aec7-4eab-9ebc-bd23b0d04e35) | Key Credentials | 2028-02-26 | ✅ Current |\n| [test](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/Overview/objectId/31e80a1b-3faa-4ce9-9794-2b77f61f20f7/appId/8ae2b566-71f5-467e-8960-cfe8da3a2cfa) | Key Credentials | 2025-10-10 | ❗ Expired |\n\n\n\n","TestStatus":"Investigate","TestDescription":"Service principals without proper authentication credentials (certificates or client secrets) create security vulnerabilities that allow threat actors to impersonate these identities. This can lead to unauthorized access, lateral movement within your environment, privilege escalation, and persistent access that's difficult to detect and remediate. \n\n**Remediation action**\n\n- For your organization's service principals: [Add certificates or client secrets to the app registration](https://learn.microsoft.com/entra/identity-platform/how-to-add-credentials?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci)\n- For external service principals: Review and remove any unnecessary credentials to reduce security risk\n","TestId":"21896"},{"TestImplementationCost":"Medium","TestPillar":"Identity","TestCategory":"Privileged access","SkippedReason":null,"TestImpact":"Medium","TestAppliesTo":["Identity"],"TestSfiPillar":"Protect tenants and isolate production systems","TestSkipped":"","TestMinimumLicense":"Free","TestTags":["Identity"],"TestTitle":"Permissions to create new tenants is limited to the Tenant Creator role","TestRisk":"High","TestResult":"\nNon-privileged users are restricted from creating tenants.\n\n\n\n","TestStatus":"Passed","TestDescription":"A threat actor or a well-intentioned but uninformed employee can create a new Microsoft Entra tenant if there are no restrictions in place. By default, the user who creates a tenant is automatically assigned the Global Administrator role. Without proper controls, this action fractures the identity perimeter by creating a tenant outside the organization's governance and visibility. It introduces risk though a shadow identity platform that can be exploited for token issuance, brand impersonation, consent phishing, or persistent staging infrastructure. Since the rogue tenant might not be tethered to the enterprise’s administrative or monitoring planes, traditional defenses are blind to its creation, activity, and potential misuse.\n\n**Remediation action**\n\nEnable the **Restrict non-admin users from creating tenants** setting. For users that need the ability to create tenants, assign them the Tenant Creator role. You can also review tenant creation events in the Microsoft Entra audit logs.\n\n- [Restrict member users' default permissions](https://learn.microsoft.com/entra/fundamentals/users-default-permissions?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci#restrict-member-users-default-permissions)\n- [Assign the Tenant Creator role](https://learn.microsoft.com/entra/identity/role-based-access-control/permissions-reference?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci#tenant-creator)\n- [Review tenant creation events](https://learn.microsoft.com/entra/identity/monitoring-health/reference-audit-activities?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci#core-directory). Look for OperationName==\"Create Company\", Category == \"DirectoryManagement\".\n","TestId":"21787"},{"TestImplementationCost":"Medium","TestPillar":"Network","TestCategory":"Azure Network Security","SkippedReason":"This test is not applicable to the current environment.","TestImpact":"Low","TestAppliesTo":null,"TestSfiPillar":"Protect networks","TestSkipped":"NotApplicable","TestMinimumLicense":"Azure WAF","TestTags":null,"TestTitle":"Rate Limiting is Enabled in Application Gateway WAF","TestRisk":"High","TestResult":"\nNo Application Gateway WAF policies found attached to Application Gateways.\n","TestStatus":"Skipped","TestDescription":"Azure Application Gateway Web Application Firewall (WAF) supports rate limiting through custom rules that restrict the number of requests clients can make within a specified time window. Rate limiting is a critical defense mechanism that protects applications from abuse by throttling clients that exceed defined request thresholds. \n\nWithout rate limiting configured, threat actors can execute brute force attacks that attempt thousands of password combinations per minute against authentication endpoints, credential stuffing attacks that test stolen credentials at scale, API abuse that extracts large volumes of data or consumes expensive backend resources, and application-layer denial of service attacks that flood endpoints with requests to exhaust server capacity. \n\nRate limiting rules use the `RateLimitRule` rule type and allow administrators to define thresholds based on request count per minute, with the ability to group requests by client IP address (using `groupBy` with `ClientAddr` variable) to track and limit individual clients. When a client exceeds the configured threshold, the WAF can block subsequent requests, log the violation, or redirect to a custom page. Unlike managed rulesets that detect attack patterns, rate limiting provides a quantitative defense that limits the impact of any volumetric attack regardless of whether the individual requests appear malicious. By configuring rate limiting on Application Gateway WAF, organizations can ensure that no single client can monopolize application resources or execute high-volume automated attacks.\n\n\n**Remediation action**\n\n- [What is Azure Web Application Firewall on Azure Application Gateway?](https://learn.microsoft.com/en-us/azure/web-application-firewall/ag/ag-overview) - Overview of WAF capabilities on Application Gateway including custom rules\n- [Create and use Web Application Firewall v2 custom rules on Application Gateway](https://learn.microsoft.com/en-us/azure/web-application-firewall/ag/create-custom-waf-rules) - Step-by-step guidance on creating custom rules including rate limiting\n- [Web Application Firewall custom rules](https://learn.microsoft.com/en-us/azure/web-application-firewall/ag/custom-waf-rules-overview) - Detailed documentation of custom rule types including RateLimitRule\n- [Rate limiting in Application Gateway WAF](https://learn.microsoft.com/en-us/azure/web-application-firewall/ag/rate-limiting-overview) - Overview of rate limiting capabilities and configuration options\n\n\n","TestId":27016},{"TestImplementationCost":"Medium","TestPillar":"Identity","TestCategory":"Identity governance","SkippedReason":null,"TestImpact":"Medium","TestAppliesTo":null,"TestSfiPillar":"Protect tenants and isolate production systems","TestSkipped":"","TestMinimumLicense":["P2","Governance"],"TestTags":null,"TestTitle":"All entitlement management packages that apply to guests have expirations or access reviews configured in their assignment policies","TestRisk":"Medium","TestResult":"\nAccess package assignment policies without expiration and without access reviews were found for external users.\n\n## [Access package assignment policies for external users](https://entra.microsoft.com/#view/Microsoft_AAD_ERM/DashboardBlade/~/elmEntitlement)\n\n| Access package | Assignment policy | Expiry configured | Access review configured | Status |\n| :------------- | :---------------- | :------------------ | :--------------------- | :----- |\n| PS-GraphCmdLetScriptTest4 | External | No | No | ❌ Non-compliant |\n| Get user info demo | Initial Policy | Yes | No | ✅ Compliant |\n| PS-GraphCmdLetScriptTest4 | 21929Test | No | Yes | ✅ Compliant |\n| UserInfo | Initial Policy | Yes | No | ✅ Compliant |\n\n\n","TestStatus":"Failed","TestDescription":"Access packages for guest users without expiration dates or access reviews allow indefinite access to organizational resources. Compromised or stale guest accounts enable threat actors to maintain persistent, undetected access for lateral movement, privilege escalation, and data exfiltration. Without periodic validation, organizations cannot identify when business relationships change or when guest access is no longer needed. \n\n**Remediation action**\n\n- [Configure lifecycle settings](https://learn.microsoft.com/entra/id-governance/entitlement-management-access-package-lifecycle-policy?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci)\n- [Configure access reviews](https://learn.microsoft.com/entra/id-governance/entitlement-management-access-reviews-create?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci)\n","TestId":"21929"},{"TestImplementationCost":"Medium","TestPillar":"Identity","TestCategory":"Monitoring","SkippedReason":"UnderConstruction","TestImpact":"Medium","TestAppliesTo":["Identity"],"TestSfiPillar":"Monitor and detect cyberthreats","TestSkipped":"UnderConstruction","TestMinimumLicense":"P1","TestTags":["Identity"],"TestTitle":"All user sign-in activity uses strong authentication methods","TestRisk":"Medium","TestResult":"\nPlanned for future release.\n\n","TestStatus":"Planned","TestDescription":"Attackers might gain access if multifactor authentication (MFA) isn't universally enforced or if there are exceptions in place. Attackers might gain access by exploiting vulnerabilities of weaker MFA methods like SMS and phone calls through social engineering techniques. These techniques might include SIM swapping or phishing, to intercept authentication codes.\n\nAttackers might use these accounts as entry points into the tenant. By using intercepted user sessions, attackers can disguise their activities as legitimate user actions, evade detection, and continue their attack without raising suspicion. From there, they might attempt to manipulate MFA settings to establish persistence, plan, and execute further attacks based on the privileges of compromised accounts.\n\n**Remediation action**\n\n- [Deploy multifactor authentication](https://learn.microsoft.com/entra/identity/authentication/howto-mfa-getstarted?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci)\n- [Get started with a phishing-resistant passwordless authentication deployment](https://learn.microsoft.com/entra/identity/authentication/how-to-plan-prerequisites-phishing-resistant-passwordless-authentication?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci)\n- [Deploy a Conditional Access policy to require phishing-resistant MFA for all users](https://learn.microsoft.com/entra/identity/conditional-access/policy-all-users-mfa-strength?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci)\n- [Review authentication methods activity](https://learn.microsoft.com/entra/identity/monitoring-health/concept-usage-insights-report?tabs=microsoft-entra-admin-center&wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci#authentication-methods-activity)\n","TestId":"21800"},{"TestImplementationCost":"Low","TestPillar":"Devices","TestCategory":"Device","SkippedReason":null,"TestImpact":"Low","TestAppliesTo":null,"TestSfiPillar":"Protect networks","TestSkipped":"","TestMinimumLicense":"Intune","TestTags":null,"TestTitle":"A Microsoft Defender Antivirus policy is created and assigned in Intune for macOS","TestRisk":"High","TestResult":"\nDefender Antivirus policies are configured and assigned in Intune for macOS.\n\n\n## A Microsoft Defender Antivirus policy is created and assigned in Intune for macOS\n\n| Policy Name | Status | Assignment |\n| :---------- | :----- | :--------- |\n| [macOS Defender Antivirus Policy](https://intune.microsoft.com/#view/Microsoft_Intune_Workflows/SecurityManagementMenu/~/antivirus) | ✅ Assigned | **Included:** antivirustest |\n\n\n\n","TestStatus":"Passed","TestDescription":"If Microsoft Defender Antivirus policies aren't properly configured and assigned to macOS devices in Intune, attackers can exploit unprotected endpoints to execute malware, disable antivirus protections, and persist in the environment. Without enforced policies, devices run outdated definitions, lack real-time protection, or have misconfigured scan schedules, increasing the risk of undetected threats and privilege escalation. This enables lateral movement across the network, credential harvesting, and data exfiltration. The absence of antivirus enforcement undermines device compliance, increases exposure of endpoints to zero-day threats, and can result in regulatory noncompliance. Attackers use these gaps to maintain persistence and evade detection, especially in environments without centralized policy enforcement.\n\nEnforcing Defender Antivirus policies ensures that macOS devices are consistently protected against malware, supports real-time threat detection, and aligns with Zero Trust by maintaining a secure and compliant endpoint posture.\n\n**Remediation action**\n\nUse Intune to configure and assign Microsoft Defender Antivirus policies for macOS devices to enforce real-time protection, maintain up-to-date definitions, and reduce exposure to malware: \n- [Configure Intune policies to manage Microsoft Defender Antivirus](https://learn.microsoft.com/intune/intune-service/protect/endpoint-security-antivirus-policy?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci#macos)\n- [Assign policies in Intune](https://learn.microsoft.com/intune/intune-service/configuration/device-profile-assign?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci#assign-a-policy-to-users-or-groups)\n","TestId":"24784"},{"TestImplementationCost":"Low","TestPillar":"Devices","TestCategory":"Tenant","SkippedReason":null,"TestImpact":"Low","TestAppliesTo":null,"TestSfiPillar":"Protect tenants and isolate production systems","TestSkipped":"","TestMinimumLicense":"Intune","TestTags":null,"TestTitle":"Intune Endpoint Analytics policy is created and assigned","TestRisk":"Low","TestResult":"\nEndpoint analytics policy is not created or not assigned.\n\nNo Endpoint Analytics policies found in this tenant.\n\n\n","TestStatus":"Failed","TestDescription":"If endpoint analytics isn't enabled, threat actors can exploit gaps in device health, performance, and security posture. Without the visibility endpoint analytics brings, it can be difficult for an organization to detect indicators such as anomalous device behavior, delayed patching, or configuration drift. These gaps allow attackers to establish persistence, escalate privileges, and move laterally across the environment. An absence of analytics data can impede rapid detection and response, allowing attackers to exploit unmonitored endpoints for command and control, data exfiltration, or further compromise.\n\nEnabling endpoint analytics provides visibility into device health and behavior, helping organizations detect risks, respond quickly to threats, and maintain a strong Zero Trust posture.\n\n**Remediation action**\n\nEnroll Windows devices into endpoint analytics in Intune to monitor device health and identify risks: \n- [Configure endpoint analytics](https://learn.microsoft.com/intune/endpoint-analytics/configure?pivots=intune&wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci)\n\nFor more information, see:\n- [What is endpoint analytics?](https://learn.microsoft.com/intune/endpoint-analytics/index?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci)\n","TestId":"24576"},{"TestImplementationCost":"Low","TestPillar":"Devices","TestCategory":"Tenant","SkippedReason":null,"TestImpact":"Low","TestAppliesTo":null,"TestSfiPillar":"Protect tenants and isolate production systems","TestSkipped":"","TestMinimumLicense":"Intune","TestTags":null,"TestTitle":"Intune Terms and Conditions Policy is configured and assigned","TestRisk":"Medium","TestResult":"\nNo Terms and Conditions policy exists or none are assigned.\n\n\n\n","TestStatus":"Failed","TestDescription":"If Terms and Conditions policies aren't configured and assigned in Intune, users can access corporate resources without agreeing to required legal, security, or usage terms. This omission exposes the organization to compliance risks, legal liabilities, and potential misuse of resources.\n\nEnforcing Terms and Conditions ensures users acknowledge and accept company policies before accessing sensitive data or systems, supporting regulatory compliance and responsible resource use.\n\n**Remediation action**\n\nCreate and assign Terms and Conditions policies in Intune to require user acceptance before granting access to corporate resources: \n- [Create terms and conditions policy](https://learn.microsoft.com/intune/intune-service/enrollment/terms-and-conditions-create?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci)\n","TestId":"24794"},{"TestImplementationCost":"Medium","TestPillar":"Devices","TestCategory":"Device","SkippedReason":null,"TestImpact":"Medium","TestAppliesTo":null,"TestSfiPillar":"Protect networks","TestSkipped":"","TestMinimumLicense":"Intune","TestTags":null,"TestTitle":"Attack Surface Reduction rules are applied to Windows devices to prevent exploitation of vulnerable system components","TestRisk":"High","TestResult":"\nNo Attack Surface Reduction policies found for Windows devices in Intune.\n\n**Required ASR Rules:**\n- Block execution of potentially obfuscated scripts\n- Block Win32 API calls from Office macros\n\n\n","TestStatus":"Failed","TestDescription":"If Intune profiles for Attack Surface Reduction (ASR) rules aren't properly configured and assigned to Windows devices, threat actors can exploit unprotected endpoints to execute obfuscated scripts and invoke Win32 API calls from Office macros. These techniques are commonly used in phishing campaigns and malware delivery, allowing attackers to bypass traditional antivirus defenses and gain initial access. Once inside, attackers escalate privileges, establish persistence, and move laterally across the network. Without ASR enforcement, devices remain vulnerable to script-based attacks and macro abuse, undermining the effectiveness of Microsoft Defender and exposing sensitive data to exfiltration. This gap in endpoint protection increases the likelihood of successful compromise and reduces the organization’s ability to contain and respond to threats.\n\nEnforcing ASR rules helps block common attack techniques such as script-based execution and macro abuse, reducing the risk of initial compromise and supporting Zero Trust by hardening endpoint defenses.\n\n**Remediation action**\n\nUse Intune to deploy **Attack Surface Reduction Rules** profiles for Windows devices to block high-risk behaviors and strengthen endpoint protection:\n- [Configure Intune profiles for Attack Surface Reduction Rules](https://learn.microsoft.com/intune/intune-service/protect/endpoint-security-asr-policy?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci#devices-managed-by-intune)\n- [Assign policies in Intune](https://learn.microsoft.com/intune/intune-service/configuration/device-profile-assign?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci#assign-a-policy-to-users-or-groups)\n\nFor more information, see: \n- [Attack surface reduction rules reference](https://learn.microsoft.com/defender-endpoint/attack-surface-reduction-rules-reference?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci) in the Microsoft Defender documentation.\n","TestId":"24574"},{"TestImplementationCost":"Low","TestPillar":"Devices","TestCategory":"Device","SkippedReason":null,"TestImpact":"High","TestAppliesTo":null,"TestSfiPillar":"Protect networks","TestSkipped":"","TestMinimumLicense":"Intune","TestTags":null,"TestTitle":"macOS - Firewall policy is created and assigned","TestRisk":"Medium","TestResult":"\nNo assigned macOS firewall policy was found in Intune.\n\n\n\n","TestStatus":"Failed","TestDescription":"Without a centrally managed firewall policy, macOS devices might rely on default or user-modified settings, which often fail to meet corporate security standards. This exposes devices to unsolicited inbound connections, enabling threat actors to exploit vulnerabilities, establish outbound command-and-control (C2) traffic for data exfiltration, and move laterally within the network—significantly escalating the scope and impact of a breach.\n\nEnforcing macOS Firewall policies ensures consistent control over inbound and outbound traffic, reducing exposure to unauthorized access and supporting Zero Trust through device-level protection and network segmentation.\n\n**Remediation action**\n\nConfigure and assign **macOS Firewall** profiles in Intune to block unauthorized traffic and enforce consistent network protections across all managed macOS devices:\n\n- [Configure the built-in firewall on macOS devices](https://learn.microsoft.com/intune/intune-service/protect/endpoint-security-firewall-policy?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci)\n- [Assign policies in Intune](https://learn.microsoft.com/intune/intune-service/configuration/device-profile-assign?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci#assign-a-policy-to-users-or-groups)\n\nFor more information, see: \n- [Available macOS firewall settings](https://learn.microsoft.com/intune/intune-service/protect/endpoint-security-firewall-profile-settings?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci#macos-firewall-profile)\n","TestId":"24552"},{"TestImplementationCost":"Low","TestPillar":"Network","TestCategory":"Azure Network Security","SkippedReason":"This test is not applicable to the current environment.","TestImpact":"Low","TestAppliesTo":null,"TestSfiPillar":"Protect networks","TestSkipped":"NotApplicable","TestMinimumLicense":"Azure WAF","TestTags":null,"TestTitle":"Request Body Inspection is enabled in Azure Front Door WAF","TestRisk":"High","TestResult":"\nNo Azure Front Door WAF policies attached to Azure Front Door found across subscriptions.\n","TestStatus":"Skipped","TestDescription":"Azure Front Door Web Application Firewall (WAF) provides centralized protection for web applications against common exploits and vulnerabilities. Request body inspection is a critical capability that allows the WAF to analyze the content of HTTP POST, PUT, and PATCH request bodies for malicious patterns. When request body inspection is disabled, threat actors can craft attacks that embed malicious SQL statements, scripts, or command injection payloads within form submissions, API calls, or file uploads that bypass all WAF rule evaluation. This creates a direct path for exploitation where threat actors gain initial access through unprotected application endpoints, execute arbitrary commands or queries against backend databases through SQL injection, exfiltrate sensitive data including credentials and customer information, establish persistence by modifying application data or injecting backdoors, and pivot to internal systems through compromised application server credentials. The WAF's managed rule sets, including OWASP Core Rule Set and Microsoft's threat intelligence-based rules, cannot evaluate threats they cannot see; disabling request body inspection renders these protections ineffective against body-based attack vectors that represent the majority of modern web application attacks.\n\n**Remediation action**\n\nOverview of WAF capabilities on Azure Front Door including request body inspection\n- [Azure Web Application Firewall on Azure Front Door](https://learn.microsoft.com/en-us/azure/web-application-firewall/afds/afds-overview)\n\nDetailed guidance on configuring WAF policy settings including request body inspection\n- [Policy settings for Web Application Firewall on Azure Front Door](https://learn.microsoft.com/en-us/azure/web-application-firewall/afds/waf-front-door-policy-settings)\n\nBest practices for tuning WAF including request body inspection limits\n- [Tuning Azure Web Application Firewall for Azure Front Door](https://learn.microsoft.com/en-us/azure/web-application-firewall/afds/waf-front-door-tuning)\n\n","TestId":26880},{"TestImplementationCost":"Low","TestPillar":"Network","TestCategory":"Azure Network Security","SkippedReason":null,"TestImpact":"Low","TestAppliesTo":null,"TestSfiPillar":"Protect networks","TestSkipped":"","TestMinimumLicense":["DDoS_Network_Protection","DDoS_IP_Protection"],"TestTags":null,"TestTitle":"DDoS Protection is enabled for all Public IP Addresses in VNETs","TestRisk":"High","TestResult":"\n❌ DDoS Protection is not enabled for one or more Public IP addresses. This includes public IPs with DDoS protection explicitly disabled, and public IPs that inherit from a VNET that does not have a DDoS Protection Plan enabled.\n\n\n## [Public IP addresses DDoS protection status](https://portal.azure.com/#view/HubsExtension/BrowseResource/resourceType/Microsoft.Network%2FpublicIPAddresses)\n\n| Public IP name | DDoS protection mode | Resource type | Associated VNET | VNET DDoS protection | Status |\n| :--- | :--- | :--- | :--- | :--- | :---: |\n| [india-2-ip](https://portal.azure.com/#resource/subscriptions/54d3ea01-5a07-45d0-8d69-e5f5b0b20098/resourceGroups/indiavm_group/providers/Microsoft.Network/publicIPAddresses/india-2-ip) | VirtualNetworkInherited | Network Interface | indiavm-vnet | ❌ Disabled | ❌ Fail |\n| [indiavm-ip](https://portal.azure.com/#resource/subscriptions/54d3ea01-5a07-45d0-8d69-e5f5b0b20098/resourceGroups/indiavm_group/providers/Microsoft.Network/publicIPAddresses/indiavm-ip) | ❌ Disabled | N/A | N/A | N/A | ❌ Fail |\n\n\n","TestStatus":"Failed","TestDescription":"DDoS attacks remain a major security and availability risk for customers with cloud-hosted applications. These attacks aim to overwhelm an application's compute, network, or memory resources, rendering it inaccessible to legitimate users. Any public-facing endpoint exposed to the internet can be a potential target for a DDoS attack. Azure DDoS Protection provides always-on monitoring and automatic mitigation against DDoS attacks targeting public-facing workloads.\n\nWithout Azure DDoS Protection (Network Protection or IP Protection), public IP addresses for services such as Application Gateways, Load Balancers, Azure Firewalls, Azure Bastion, Virtual Network Gateways, or virtual machines remain exposed to DDoS attacks that can overwhelm network bandwidth, exhaust system resources, and cause complete service unavailability. These attacks can disrupt access for legitimate users, degrade performance, and create cascading outages across dependent services.\n\nAzure DDoS Protection can be enabled in two ways:\n\n- DDoS IP Protection — Protection is explicitly enabled on individual public IP addresses by setting ddosSettings.protectionMode to Enabled.\n- DDoS Network Protection — Protection is enabled at the VNET level through a DDoS Protection Plan. Public IP addresses associated with resources in that VNET inherit the protection when ddosSettings.protectionMode is set to VirtualNetworkInherited. However, a public IP address with VirtualNetworkInherited is not protected unless the VNET actually has a DDoS Protection Plan associated and enableDdosProtection set to true.\nThis check verifies that every public IP address is actually covered by DDoS protection, either through DDoS IP Protection enabled directly on the public IP, or through DDoS Network Protection enabled on the VNET that the public IP's associated resource resides in. If this check does not pass, your workloads remain significantly more vulnerable to downtime, customer impact, and operational disruption during an attack.\n\n**Remediation action**\n\nTo enable DDoS Protection for public IP addresses, refer to the following Microsoft Learn documentation:\n\n- [Azure DDoS Protection overview](https://learn.microsoft.com/en-us/azure/ddos-protection/ddos-protection-overview)\n- [Quickstart: Create and configure Azure DDoS Network Protection using Azure portal](https://learn.microsoft.com/en-us/azure/ddos-protection/manage-ddos-protection)\n- [Quickstart: Create and configure Azure DDoS IP Protection using Azure portal](https://learn.microsoft.com/en-us/azure/ddos-protection/manage-ddos-ip-protection-portal)\n- [Azure DDoS Protection SKU comparison](https://learn.microsoft.com/en-us/azure/ddos-protection/ddos-protection-sku-comparison)\n\n","TestId":"25533"},{"TestImplementationCost":"","TestPillar":"Infrastructure","TestCategory":"Secure management ports","SkippedReason":"This test is not applicable to the current environment.","TestImpact":"","TestAppliesTo":null,"TestSfiPillar":"Protect tenants and isolate production systems","TestSkipped":"NotApplicable","TestMinimumLicense":"N/A","TestTags":null,"TestTitle":"Management ports of virtual machines should be protected with just-in-time network access control","TestRisk":"High","TestResult":"ServersStandardTierOnly\n\n| Subscription | Resource group | Resource type | Affected resource | Status | Azure portal |\n| :----------- | :------------- | :------------ | :---------------- | :----- | :----------- |\n| [Visual Studio Enterprise Subscription](https://portal.azure.com/#resource/subscriptions/54d3ea01-5a07-45d0-8d69-e5f5b0b20098) | indiavm_group | virtualmachines | [india-2](https://portal.azure.com/#resource/subscriptions/54d3ea01-5a07-45d0-8d69-e5f5b0b20098/resourceGroups/indiavm_group/providers/Microsoft.Compute/virtualMachines/india-2) | N/A | [View recommendation](https://portal.azure.com/#blade/Microsoft_Azure_Security/RecommendationsBlade/assessmentKey/805651bc-6ecd-4c73-9b55-97a19d0582d0/resourceId/%2fsubscriptions%2f54d3ea01-5a07-45d0-8d69-e5f5b0b20098%2fresourceGroups%2findiavm_group%2fproviders%2fMicrosoft.Compute%2fvirtualMachines%2findia-2) |\n| [Visual Studio Enterprise Subscription](https://portal.azure.com/#resource/subscriptions/54d3ea01-5a07-45d0-8d69-e5f5b0b20098) | indiavm_group | virtualmachines | [indiavm](https://portal.azure.com/#resource/subscriptions/54d3ea01-5a07-45d0-8d69-e5f5b0b20098/resourceGroups/indiavm_group/providers/Microsoft.Compute/virtualMachines/indiavm) | N/A | [View recommendation](https://portal.azure.com/#blade/Microsoft_Azure_Security/RecommendationsBlade/assessmentKey/805651bc-6ecd-4c73-9b55-97a19d0582d0/resourceId/%2fsubscriptions%2f54d3ea01-5a07-45d0-8d69-e5f5b0b20098%2fresourceGroups%2findiavm_group%2fproviders%2fMicrosoft.Compute%2fvirtualMachines%2findiavm) |\n","TestStatus":"Skipped","TestDescription":"Defender for Cloud has identified some overly-permissive inbound rules for management ports in your Network Security Group. Enable just-in-time access control to protect your VM from internet-based brute-force attacks. Learn more in Understanding just-in-time (JIT) VM access.\n\n**Remediation action**\n\nTo enable just-in-time VM access:
  • Select one or more VMs from the list below and select \"Remediate\", or select \"Take action\" if you've arrived from a recommendation for a specific VM.
  • On the \"JIT VM access configuration\" page, define the ports for which the just-in-time VM access will be applicable.
    • To add additional ports, select the \"Add\" button on the top left, or select an existing port and edit it.
    • On the \"Add port configuration\" pane, enter the required parameters.
  • Select \"Save\".
","TestId":"805651bc-6ecd-4c73-9b55-97a19d0582d0"},{"TestImplementationCost":"Low","TestPillar":"Identity","TestCategory":"External collaboration","SkippedReason":null,"TestImpact":"Medium","TestAppliesTo":["Identity"],"TestSfiPillar":"Protect tenants and isolate production systems","TestSkipped":"","TestMinimumLicense":"Free","TestTags":["ExternalCollaboration"],"TestTitle":"Guest can’t invite other guests","TestRisk":"Medium","TestResult":"\nTenant restricts who can invite guests.\n\n**Guest invite settings**\n\n * Guest invite restrictions → Member users and users assigned to specific admin roles can invite guest users including guests with member permissions\n\n","TestStatus":"Passed","TestDescription":"External user accounts are often used to provide access to business partners who belong to organizations that have a business relationship with your enterprise. If these accounts are compromised in their organization, attackers can use the valid credentials to gain initial access to your environment, often bypassing traditional defenses due to their legitimacy. \n\nAllowing external users to onboard other external users increases the risk of unauthorized access. If an attacker compromises an external user's account, they can use it to create more external accounts, multiplying their access points and making it harder to detect the intrusion.\n\n**Remediation action**\n\n- [Restrict who can invite guests to only users assigned to specific admin roles](https://learn.microsoft.com/entra/external-id/external-collaboration-settings-configure?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci#to-configure-guest-invite-settings)\n","TestId":"21791"},{"TestImpact":"Low","TestRisk":"High","TestSkipped":"","TestAppliesTo":null,"TestPillar":"Network","TestCategory":"Global Secure Access","TestDescription":"Excessive assignment of roles like Global Administrator and Global Secure Access Administrator create a path for threat actors to compromise these identities. With these roles an attacker can authenticate, manipulate security policies, create or elevate accounts, disable monitoring, access all corporate data, and more. Limit access to these roles to a small set of administrators, and enable monitoring of assignments and activation for groups, guests, service principals, and disabled accounts to reduce the attack surface and enforce least privilege.\n\n**Remediation action**\n\n- [Quinn Garcia accounts are configured appropriately](https://learn.microsoft.com/entra/fundamentals/zero-trust-protect-engineering-systems?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci#emergency-access-accounts-are-configured-appropriately)\n- [Limit Global Administrator and Global Secure Access Administrator role assignments to a small set of administrators.](https://learn.microsoft.com/entra/fundamentals/zero-trust-protect-identities?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci#high-global-administrator-to-privileged-user-ratio)\n- [Configure role settings to require approval for Global Administrator activation](https://learn.microsoft.com/entra/id-governance/privileged-identity-management/pim-how-to-change-default-settings?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci)\n","TestTitle":"Global and GSA admin privileges are tightly limited to prevent tenant-wide compromise","SkippedReason":null,"TestId":"25383","TestImplementationCost":"Low","TestMinimumLicense":["AAD_PREMIUM","AAD_PREMIUM_P2"],"TestSfiPillar":"Protect identities and secrets","TestResult":"\n❌ GA/GSA roles include groups, guests, or service principals requiring immediate review.\n\n\n## [Global Administrator assignments](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/RolesManagementMenuBlade/~/AllRoles)\n\n**Role Definition ID**: 62e90394-69f5-4237-9190-012177145e10 \n**Total Assignment Count**: 30 \n**Valid Assignment Count**: 25 \n**Issue Count**: 5 \n\n### ❌ Non-compliant assignments\n\n| Name | Principal name | Type | User type | Account enabled | Status |\n| :----------- | :-- | :--- | :-------- | :-------------- | :----- |\n| Dakota Lee | guest-user_external.com#EXT#@contoso.com | user | Guest | True | Fail |\n| Custom-App-Test | | servicePrincipal | | | Fail |\n| PIMGlobalAdmin | | group | | | Fail |\n| contoso-tenant-devops-7576c63d-bc90-4ae4-9f1c-0d959fb520db | | servicePrincipal | | | Fail |\n| Mailbox Migration Account | | servicePrincipal | | | Fail |\n\n### ✅ Valid Member User assignments\n\n| Name | Principal name | Type | User type | Account enabled | Status |\n| :----------- | :-- | :--- | :-------- | :-------------- | :----- |\n| Alex Johnson | alex@contoso.onmicrosoft.com | user | Member | True | Valid |\n| Hayden Scott | hayden@contoso.com | user | Member | True | Valid |\n| Jordan Smith | jordan@contoso.com | user | Member | True | Valid |\n| Taylor Brown | taylor@contoso.com | user | Member | True | Valid |\n| Morgan Wilson | morgan@contoso.com | user | Member | True | Valid |\n\n*Showing first 5 of 25 records. [View all assignments in Entra Portal](https://entra.microsoft.com/#view/Microsoft_Azure_PIMCommon/UserRolesViewModelMenuBlade/~/members/roleObjectId/62e90394-69f5-4237-9190-012177145e10/roleId/62e90394-69f5-4237-9190-012177145e10/roleTemplateId/62e90394-69f5-4237-9190-012177145e10/roleName/Global%20Administrator/isRoleCustom~/false/resourceScopeId/%2F/resourceId/0817c655-a853-4d8f-9723-3a333b5b9235)*\n\n\n## [Global Secure Access Administrator assignments](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/RolesManagementMenuBlade/~/AllRoles)\n\n**Role Definition ID**: ac434307-12b9-4fa1-a708-88bf58caabc1 \n**Total Assignment Count**: 0 \n**Valid Assignment Count**: 0 \n**Issue Count**: 0 \n\n\n\n","TestStatus":"Failed","TestTags":null},{"TestImpact":"Medium","TestRisk":"High","TestSkipped":"","TestAppliesTo":null,"TestPillar":"Data","TestCategory":"Advanced Classification","TestDescription":"Named entity sensitive information types (SITs) are prebuilt Microsoft classifiers that detect common sensitive entities like people's names, physical addresses, and medical terminology. They extend data protection beyond pattern matching into context aware classification, and can be used in auto-labeling policies and DLP rules without any custom development.\n\n**Remediation action**\n\n- [Learn about named entities](https://learn.microsoft.com/purview/sit-named-entities-learn?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci)\n- [Use named entities in your data loss prevention policies](https://learn.microsoft.com/purview/sit-named-entities-use?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci)\n","TestTitle":"Named Entity SITs Usage in Auto-Labeling and DLP Policies","SkippedReason":null,"TestId":"35035","TestImplementationCost":"Low","TestMinimumLicense":["EXCHANGE_S_ENTERPRISE"],"TestSfiPillar":"Protect tenants and production systems","TestResult":"\n✅ At least one auto-labeling or DLP policy rule uses a Named Entity SIT (such as 'All Full Names', 'All Physical Addresses', 'All Medical Terms and Conditions', or similar pre-built classifiers).\n\n\n\n### [Rules using named entity SITs](https://purview.microsoft.com/informationprotection/dataclassification/multicloudsensitiveinfotypes)\n| Rule name | Policy name | Named Entity SITs | Count | Workload | Type |\n| :--- | :--- | :--- | :--- | :--- | :--- |\n| U.S. Patriot Act Enhanced-ODB | [U.S. Patriot Act Enhanced](https://purview.microsoft.com/informationprotection/autolabeling) | U.S. Physical Addresses, All Full Names | 2 | Exchange, SharePoint, OneDriveForBusiness, PowerBI, Applications, Azure, AWS | Auto-Labeling |\n\n\n### Summary\n| Metric | Count |\n| :--- | :--- |\n| Named entity SITs in catalog | 60 |\n| Total auto-labeling rules | 2 |\n| Total DLP rules | 8 |\n| Auto-labeling rules using named entity SITs | 1 |\n| DLP rules using named entity SITs | 0 |\n\n","TestStatus":"Passed","TestTags":null},{"TestImpact":"Medium","TestRisk":"High","TestSkipped":"NoCompatibleLicenseFound","TestAppliesTo":null,"TestPillar":"Network","TestCategory":"Global Secure Access","TestDescription":"By using Transport Layer Security (TLS) inspection, Global Secure Access can decrypt encrypted HTTPS traffic and check it for threats, malicious content, and policy violations. If TLS inspection fails for a connection, that traffic bypasses security controls. Inspection failures can let potential malware delivery, command-and-control communications, or data exfiltration go undetected.\n\nFailure rates above 1% point to systemic problems. These problems include certificate trust issues on endpoints, incompatible applications that use certificate pinning without proper bypass rules, or certificate authority configuration errors. Threat actors can also intentionally create connections that cause TLS inspection failures.\n\n**Remediation action**\n\n- [Configure diagnostic settings to export traffic logs](https://learn.microsoft.com/entra/global-secure-access/how-to-view-traffic-logs?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci#configure-diagnostic-settings-to-export-logs) to a Log Analytics workspace. Use these logs to monitor TLS inspection success rates and investigate the root causes of failures.\n- Follow the steps in [Troubleshoot Global Secure Access Transport Layer Security inspection errors](https://learn.microsoft.com/entra/global-secure-access/troubleshoot-transport-layer-security?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci) to resolve common inspection failures.\n- For destinations with certificate pinning, [add TLS bypass rules](https://learn.microsoft.com/entra/global-secure-access/how-to-transport-layer-security?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci) to reduce failure rates while keeping inspection for other traffic.\n","TestTitle":"TLS inspection failure rate is below 1%","SkippedReason":"This test requires one of the following licenses: (\"Entra_Premium_Internet_Access\"). Please ensure your tenant has the appropriate licenses to run this test. See [Licensing & Service Plans](https://learn.microsoft.com/entra/identity/users/licensing-service-plan-reference)","TestId":"27003","TestImplementationCost":"Medium","TestMinimumLicense":["Entra_Premium_Internet_Access"],"TestSfiPillar":"Protect networks","TestResult":"\nSkipped. This test requires one of the following licenses: (\"Entra_Premium_Internet_Access\"). Please ensure your tenant has the appropriate licenses to run this test. See [Licensing & Service Plans](https://learn.microsoft.com/entra/identity/users/licensing-service-plan-reference)\n\n","TestStatus":"Skipped","TestTags":null},{"TestImplementationCost":"Low","TestPillar":"Identity","TestCategory":"Application management","SkippedReason":null,"TestImpact":"Low","TestAppliesTo":["Identity"],"TestSfiPillar":"Protect networks","TestSkipped":"","TestMinimumLicense":"P1","TestTags":["Identity"],"TestTitle":"Trusted network locations are configured to increase quality of risk detections","TestRisk":"Medium","TestResult":"\n✅ **Pass**: Trusted named locations are configured in Microsoft Entra ID to support location-based security controls.\n\n\n## All named locations\n\n5 [named locations](https://entra.microsoft.com/#view/Microsoft_AAD_ConditionalAccess/ConditionalAccessBlade/~/NamedLocations/menuId//fromNav/) found.\n\n| Name | Location type | Trusted | Creation date | Modified date |\n| :--- | :------------ | :------ | :------------ | :------------ |\n| Melbourne Branch | IP-based | Yes | Unknown | Unknown |\n| Boston Head Office | IP-based | Yes | Unknown | Unknown |\n| Untrusted Locations | Country-based | No | Unknown | Unknown |\n| Corporate IPs | IP-based | Yes | Unknown | Unknown |\n| Manson home | IP-based | Yes | 04/16/2025 04:55:11 | 04/16/2025 04:55:11 |\n\n\n\n","TestStatus":"Passed","TestDescription":"Without named locations configured in Microsoft Entra ID, threat actors can exploit the absence of location intelligence to conduct attacks without triggering location-based risk detections or security controls. When organizations fail to define named locations for trusted networks, branch offices, and known geographic regions, Microsoft Entra ID Protection can't assess location-based risk signals. Not having these policies in place can lead to increased false positives that create alert fatigue and potentially mask genuine threats. This configuration gap prevents the system from distinguishing between legitimate and illegitimate locations. For example, legitimate sign-ins from corporate networks and suspicious authentication attempts from high-risk locations (anonymous proxy networks, Tor exit nodes, or regions where the organization has no business presence). Threat actors can use this uncertainty to conduct credential stuffing attacks, password spray campaigns, and initial access attempts from malicious infrastructure without triggering location-based detections that would normally flag such activity as suspicious. Organizations can also lose the ability to implement adaptive security policies that could automatically apply stricter authentication requirements or block access entirely from untrusted geographic regions. Threat actors can maintain persistence and conduct lateral movement from any global location without encountering location-based security barriers, which should serve as an extra layer of defense against unauthorized access attempts.\n\n**Remediation action**\n\n- [Configure named locations to define trusted IP ranges and geographic regions for enhanced location-based risk detection and Conditional Access policy enforcement](https://learn.microsoft.com/entra/identity/conditional-access/concept-assignment-network?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci)\n","TestId":"21865"},{"TestImplementationCost":"Medium","TestPillar":"Identity","TestCategory":"External collaboration","SkippedReason":null,"TestImpact":"Low","TestAppliesTo":null,"TestSfiPillar":"Protect tenants and isolate production systems","TestSkipped":"","TestMinimumLicense":"Free","TestTags":null,"TestTitle":"Inactive guest identities are disabled or removed from the tenant","TestRisk":"Medium","TestResult":"\n❌ Found 3 inactive guest user(s) with no sign-in activity in the last 90 days:\n\n\n## Inactive guest accounts in the tenant\n\n\n| Display name | User principal name | Last sign-in date | Created date |\n| :----------- | :------------------ | :---------------- | :----------- |\n| [Ash Williams](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/overview/userId/a0883b7a-c6a8-440f-84f0-d6e1b79aaf4c/hidePreviewBanner~/true) | manson_manson.net#EXT#@contoso.onmicrosoft.com | 2025-08-10 | 2021-04-11 |\n| [Riley Martinez](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/overview/userId/653c7fdd-1b41-4229-992a-69cc35aad4f7/hidePreviewBanner~/true) | riley@contoso.onmicrosoft.com | | 2021-06-02 |\n| [Shonali Balakrishna](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/overview/userId/305bbf73-eee4-4e0c-9c7d-627e00ed3665/hidePreviewBanner~/true) | guest-user_external.com#EXT#@contoso.com | 2025-05-05 | 2025-03-25 |\n\n\n\n","TestStatus":"Failed","TestDescription":"When guest identities remain active but unused for extended periods, threat actors can exploit these dormant accounts as entry vectors into the organization. Inactive guest accounts represent a significant attack surface because they often maintain persistent access permissions to resources, applications, and data while remaining unmonitored by security teams. Threat actors frequently target these accounts through credential stuffing, password spraying, or by compromising the guest's home organization to gain lateral access. Once an inactive guest account is compromised, attackers can utilize existing access grants to:\n- Move laterally within the tenant\n- Escalate privileges through group memberships or application permissions\n- Establish persistence through techniques like creating more service principals or modifying existing permissions\n\nThe prolonged dormancy of these accounts provides attackers with extended dwell time to conduct reconnaissance, exfiltrate sensitive data, and establish backdoors without detection, as organizations typically focus monitoring efforts on active internal users rather than external guest accounts.\n\n**Remediation action**\n- [Monitor and clean up stale guest accounts](https://learn.microsoft.com/entra/identity/users/clean-up-stale-guest-accounts?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci)\n","TestId":"21858"},{"TestImpact":"Low","TestRisk":"Medium","TestSkipped":"NotConnectedToService","TestAppliesTo":null,"TestPillar":"Data","TestCategory":"Advanced Label Features","TestDescription":"The super user feature of the Azure Rights Management service grants designated accounts the ability to decrypt content your organization has encrypted by using this service, regardless of the original permissions assigned. Super users might be necessary for eDiscovery, data recovery, compliance investigations, and content migration. The super user feature ensures that authorized people and services can always read and inspect the data that the Azure Rights Management service encrypts for your organization.\n\nWhen you use a group to designate super user accounts, membership of that group must be carefully controlled and limited, for example, to service accounts used by compliance tools or eDiscovery platforms. Unless you have a feature or business need that requires the feature to be enabled all the time, Microsoft recommends keeping the feature disabled by default, and enabling it only when needed. When you use a group to designate super user accounts, use Microsoft Entra Privileged Identity Management (PIM) to reduce risk by enabling just‑in‑time access when required and minimizing permanent privilege.\n\n**Remediation action**\n\n- [Configure Azure Rights Management super users for discovery services or data recovery](https://learn.microsoft.com/purview/encryption-super-users?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci#security-best-practices-for-the-super-user-feature)\n","TestTitle":"Super user membership is configured for Microsoft Purview Information Protection","SkippedReason":"This test requires connection to the service(s) \"AipService\" currently disconnected. Please use _Connect-ZtAssessment_ to connect.","TestId":"35011","TestImplementationCost":"Medium","TestMinimumLicense":["RMS_S_PREMIUM2"],"TestSfiPillar":"Protect tenants and production systems","TestResult":"\nSkipped. This test requires connection to the service(s) \"AipService\" currently disconnected. Please use _Connect-ZtAssessment_ to connect.\n\n","TestStatus":"Skipped","TestTags":null},{"TestImpact":"Medium","TestRisk":"Medium","TestSkipped":"","TestAppliesTo":null,"TestPillar":"Data","TestCategory":"Data Security Posture Management","TestDescription":"Browser Data Loss Prevention (DLP) for cloud apps in Microsoft Edge for Business prevents users from uploading, downloading, copying, or pasting sensitive data to and from unmanaged cloud AI services (ChatGPT, Google Gemini, Claude, etc.) directly through the browser. Without Browser DLP policies for AI apps configured, users can access consumer AI services through Edge for Business and exfiltrate sensitive organizational data by uploading files or pasting confidential information, circumventing cloud-based DLP controls.\n\nBrowser DLP acts as the final enforcement point at the browser level, blocking data transfers to AI services even if data governance policies allow access to the service itself. Organizations using Microsoft 365 Copilot or allowing employee access to generative AI tools must enable Browser DLP policies targeting unmanaged AI apps to prevent uncontrolled data exposure. Browser DLP for AI apps requires PAYG billing activation, Intune-managed devices, and Edge for Business deployment to function.\n\n**Remediation action**\n\n**To enable Browser DLP for AI Apps (Minimal Setup):**\n\n1. **Activate PAYG Billing** (One-time setup)\n - Navigate to [Purview Settings > Account](https://purview.microsoft.com/settings/account)\n - Enable \"Purview Pay-as-You-Go billing\"\n - Activate trial or start paid subscription\n - This is the only hard requirement\n\n2. **Create Browser DLP Policy** (via Purview UI)\n - Navigate to [Microsoft Purview portal](https://purview.microsoft.com)\n - Data Loss Prevention > Policies > + Create policy\n - Choose \"Custom\" policy template\n - Name: \"Browser DLP - AI Apps\" (or similar)\n - Add locations: Select \"Edge for Business\"\n - Add cloud apps: Select \"All unmanaged AI apps\" OR add specific apps manually\n - Configure scope: All users or specific groups\n - Create rule:\n - Name: \"Block Sensitive Data to Unmanaged AI Apps\"\n - Condition: Content contains [pick sensitive info types: credit card, SSN, bank account, etc.]\n - Action: \"Restrict browser activities\" > Block file uploads and text sharing to unmanaged apps\n - Incident reports: Enable alerts for rule matches\n - Policy mode: Start with \"Simulate\" (TestWithoutNotifications) for testing\n - Enable policy\n\n3. **Deployment Requirements**\n - Managed devices: Intune enrollment required (Windows 10/11)\n - Browser: Edge for Business v144+\n - Microsoft Edge management automatically syncs policy\n\n4. **Validation**\n - Navigate to Activity Explorer in Purview\n - Filter: Enforcement Plane = \"Browser\"\n - Monitor for browser DLP activities\n - Review [Microsoft Defender](https://security.microsoft.com) for related alerts\n\n**Optional Enhancement: Add Collection Policies** (Data classification layer)\n- If you want more granular data classification, create collection policies targeting AI apps\n- Collection policies define what data to monitor (optional for basic protection)\n- Link collection policies to Browser DLP rules (if UI supports linking)\n\n**Via PowerShell (After PAYG activation):**\n```powershell\nConnect-ExchangeOnline\nConnect-IPPSSession\n\n# List browser DLP policies\nGet-DlpCompliancePolicy | Where-Object { $_.EnforcementPlanes -contains \"Browser\" } | Select-Object Name, Enabled, Mode\n\n# Enable specific policy\nSet-DlpCompliancePolicy -Identity -Enabled $true\n\n# List rules for browser policy\nGet-DlpCompliancePolicy | Where-Object { $_.EnforcementPlanes -contains \"Browser\" } | ForEach-Object { Get-DlpComplianceRule -Policy $_.Identity }\n```\n\n**For more information:**\n- [Learn about Browser DLP for Cloud Apps](https://learn.microsoft.com/en-us/purview/dlp-browser-dlp-learn)\n- [Create policy for browser cloud app protection](https://learn.microsoft.com/en-us/purview/dlp-create-policy-prevent-cloud-sharing-from-edge-biz)\n- [Create policy for AI app protection](https://learn.microsoft.com/en-us/purview/dlp-create-policy-block-to-ai-via-edge)\n- [Billing and PAYG activation](https://learn.microsoft.com/en-us/purview/purview-billing-models)\n","TestTitle":"Browser data loss prevention is enabled for AI apps via Edge for Business","SkippedReason":null,"TestId":"35041","TestImplementationCost":"High","TestMinimumLicense":["RMS_S_PREMIUM2"],"TestSfiPillar":"Protect tenants and production systems","TestResult":"\n✅ Browser Data Loss Prevention for AI Apps is configured and enabled via at least one active DLP policy with Browser enforcement, preventing sensitive data from being uploaded to or copied from unmanaged AI services through Edge for Business.\n\n\n**Browser DLP Configuration Summary:**\n\n* Browser DLP Policies Found: 1\n* Browser DLP Policies Enabled: 1\n* Enabled Policies with Rules: 1\n* Browser DLP Rules: 1\n\n## [Discovered Policies](https://purview.microsoft.com/datalossprevention/policies)\n\n| Policy name | Enabled | Mode | Enforcement planes | Policy category | Created by | Creation time (UTC) | Rules count |\n|:---|:---|:---|:---|:---|:---|:---|:---|\n| Browser DLP Test | True | TestWithoutNotifications | Browser | ApplicableToAI | Dakota Lee Test | 2026-02-13T07:18:47Z | 1 |\n\n","TestStatus":"Passed","TestTags":null},{"TestImplementationCost":"Low","TestPillar":"Devices","TestCategory":"Device","SkippedReason":null,"TestImpact":"Medium","TestAppliesTo":null,"TestSfiPillar":"Protect identities and secrets","TestSkipped":"","TestMinimumLicense":"Intune","TestTags":null,"TestTitle":"Intune macOS FileVault policy is created and Assigned","TestRisk":"High","TestResult":"\nNo relevant macOS FileVault encryption policies are configured or assigned.\n\n\n## Intune macOS FileVault policy is created and Assigned\n\n\n\n| Policy Name | Status | Assignment |\n| :---------- | :----- | :--------- |\n\n\n\n","TestStatus":"Failed","TestDescription":"Without properly configured and assigned FileVault encryption policies in Intune, threat actors can exploit physical access to unmanaged or misconfigured macOS devices to extract sensitive corporate data. Unencrypted devices allow attackers to bypass operating system-level security by booting from external media or removing the storage drive. These attacks can expose credentials, certificates, and cached authentication tokens, enabling privilege escalation and lateral movement. Additionally, unencrypted devices undermine compliance with data protection regulations and increase the risk of reputational damage and financial penalties in the event of a breach.\n\nEnforcing FileVault encryption protects data at rest on macOS devices, even if lost or stolen. It disrupts credential harvesting and lateral movement, supports regulatory compliance, and aligns with Zero Trust principles of device trust.\n\n**Remediation action**\n\nUse Intune to enforce FileVault encryption and monitor compliance on all managed macOS devices: \n- [Create a FileVault disk encryption policy for macOS in Intune](https://learn.microsoft.com/intune/intune-service/protect/encrypt-devices-filevault?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci#create-endpoint-security-policy-for-filevault)\n- [Assign policies in Intune](https://learn.microsoft.com/intune/intune-service/configuration/device-profile-assign?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci#assign-a-policy-to-users-or-groups)\n- [Monitor device encryption with Intune](https://learn.microsoft.com/intune/intune-service/protect/encryption-monitor?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci)\n","TestId":"24569"},{"TestImpact":"High","TestRisk":"Medium","TestSkipped":"","TestAppliesTo":null,"TestPillar":"Data","TestCategory":"sensitivity-labels","TestDescription":"Publishing too many labels globally creates confusion and decision paralysis for users, reducing adoption and increasing misclassification. When users face more than 25 labels, they struggle to identify the appropriate classification, leading to incorrect labels or avoiding the feature entirely.\n\nMicrosoft recommends no more than 25 labels in global policies, ideally organized as five main labels with up to five sublabels each. Use scoped policies to publish specialized labels only to specific users, groups, or departments, keeping the global label set focused on common scenarios.\n\n**Remediation action**\n\n- [Sensitivity label limitations per tenant](https://learn.microsoft.com/purview/sensitivity-labels?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci#sensitivity-label-limitations-per-tenant)\n- [Create and publish sensitivity labels](https://learn.microsoft.com/microsoft-365/compliance/create-sensitivity-labels?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci)\n","TestTitle":"Global Scope Label Count","SkippedReason":null,"TestId":"35015","TestImplementationCost":"Medium","TestMinimumLicense":["RMS_S_PREMIUM"],"TestSfiPillar":"Protect tenants and production systems","TestResult":"\n✅ 3 sensitivity labels are published in globally-scoped policies, within the recommended limit of 25.\n\n### [Global Label Policies](https://purview.microsoft.com/informationprotection/labelpolicies)\n\n| Policy Name | Global Workloads | Labels Published | Sample Labels |\n| :--- | :--- | :---: | :--- |\n| [true event](https://purview.microsoft.com/informationprotection/labelpolicies) | Exchange | 1 | Confidential – RMS |\n| [peyton](https://purview.microsoft.com/informationprotection/labelpolicies) | Exchange | 1 | peyton |\n| [test-policy-35012](https://purview.microsoft.com/informationprotection/labelpolicies) | Exchange | 1 | test-35012-1 |\n\n### Summary\n\n* **Total Unique Labels Published Globally:** 3\n* **Recommended Maximum:** 25\n* **Status:** Pass\n\n*Note: Labels appearing in multiple global policies are counted once (deduplicated).*\n\n\n","TestStatus":"Passed","TestTags":null},{"TestImplementationCost":"High","TestPillar":"Identity","TestCategory":"Access control","SkippedReason":null,"TestImpact":"Medium","TestAppliesTo":null,"TestSfiPillar":"Protect identities and secrets","TestSkipped":"","TestMinimumLicense":"Free","TestTags":null,"TestTitle":"Guest access is limited to approved tenants","TestRisk":"Medium","TestResult":"\nGuest access is not limited to approved tenants.\n\n\n## [Collaboration restrictions](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/CompanyRelationshipsMenuBlade/~/Settings/menuId/)\n\nThe tenant is configured to: **Allow invitations to be sent to any domain (most inclusive)** ❌\n\n","TestStatus":"Failed","TestDescription":"Without limiting guest access to approved tenants, threat actors can exploit unrestricted guest access to establish initial access through compromised external accounts or by creating accounts in untrusted tenants. Organizations can configure an allowlist or blocklist to control B2B collaboration invitations from specific organizations, and without these controls, threat actors can leverage social engineering techniques to obtain invitations from legitimate internal users. Once threat actors gain guest access through unrestricted domains, they can perform discovery activities to enumerate internal resources, users, and applications that guest accounts can access. The compromised guest account then serves as a persistent foothold, allowing threat actors to execute collection activities against accessible SharePoint sites, Teams channels, and other resources granted to guest users. From this position, threat actors can attempt lateral movement by exploiting trust relationships between the compromised tenant and partner organizations, or by leveraging guest permissions to access sensitive data that can be used for further credential compromise or business email compromise attacks.\n\n**Remediation action**\n\n- [Configure Domain-Based Allow or Deny Lists](https://learn.microsoft.com/en-us/entra/external-id/allow-deny-list)\n\n","TestId":"21822"},{"TestImplementationCost":"High","TestPillar":"Identity","TestCategory":"Access control","SkippedReason":"UnderConstruction","TestImpact":"Low","TestAppliesTo":["Identity"],"TestSfiPillar":"Protect identities and secrets","TestSkipped":"UnderConstruction","TestMinimumLicense":null,"TestTags":["Identity"],"TestTitle":"Block legacy Microsoft Online PowerShell module","TestRisk":"Low","TestResult":"\nPlanned for future release.\n","TestStatus":"Planned","TestDescription":"...\n\n**Remediation action**\n\n","TestId":"21843"},{"TestImpact":"Low","TestRisk":"High","TestSkipped":"NoCompatibleLicenseFound","TestAppliesTo":null,"TestPillar":"Network","TestCategory":"Global Secure Access","TestDescription":"Comprehensive deployment of the Global Secure Access client is foundational to achieving Zero Trust network security. If you don't deploy the Global Secure Access client to managed endpoints, those devices operate outside the organization's Security Service Edge controls. Threat actors can exploit unprotected endpoints to establish initial access, move laterally, or exfiltrate data without triggering network-level security policies.\n\nWithout the Global Secure Access client:\n\n- Devices can't benefit from compliant network checks in Conditional Access policies, source IP restoration, or tenant restrictions.\n- Credential theft and token replay attacks are more difficult to detect when traffic bypasses the security perimeter.\n- Managed endpoints can't access private applications through Microsoft Entra Private Access.\n\n**Remediation action**\n- Install the Global Secure Access client:\n - [Windows client](https://learn.microsoft.com/entra/global-secure-access/how-to-install-windows-client?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci)\n - [macOS client](https://learn.microsoft.com/entra/global-secure-access/how-to-install-macos-client?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci)\n - [iOS client](https://learn.microsoft.com/entra/global-secure-access/how-to-install-ios-client?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci)\n - [Android client](https://learn.microsoft.com/entra/global-secure-access/how-to-install-android-client?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci)\n- Monitor the Global Secure Access client health and connection status by using the [Global Secure Access dashboard](https://learn.microsoft.com/entra/global-secure-access/concept-traffic-dashboard?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci).\n","TestTitle":"Global Secure Access client is deployed on all managed endpoints","SkippedReason":"This test requires one of the following licenses: (\"Entra_Premium_Private_Access\") OR (\"Entra_Premium_Internet_Access\"). Please ensure your tenant has the appropriate licenses to run this test. See [Licensing & Service Plans](https://learn.microsoft.com/entra/identity/users/licensing-service-plan-reference)","TestId":"25372","TestImplementationCost":"Medium","TestMinimumLicense":["Entra_Premium_Private_Access","Entra_Premium_Internet_Access"],"TestSfiPillar":"Protect networks","TestResult":"\nSkipped. This test requires one of the following licenses: (\"Entra_Premium_Private_Access\") OR (\"Entra_Premium_Internet_Access\"). Please ensure your tenant has the appropriate licenses to run this test. See [Licensing & Service Plans](https://learn.microsoft.com/entra/identity/users/licensing-service-plan-reference)\n\n","TestStatus":"Skipped","TestTags":null},{"TestImplementationCost":"Medium","TestPillar":"Identity","TestCategory":"Credential management","SkippedReason":null,"TestImpact":"Medium","TestAppliesTo":["Identity"],"TestSfiPillar":"Protect identities and secrets","TestSkipped":"","TestMinimumLicense":"P1","TestTags":["Credential"],"TestTitle":"Users have strong authentication methods configured ","TestRisk":"Medium","TestResult":"\nFound users that have not yet registered phishing resistant authentication methods\n\n## Users strong authentication methods\n\nFound users that have not registered phishing resistant authentication methods.\n\nUser | Last sign in | Phishing resistant method registered |\n| :--- | :--- | :---: |\n|[Hayden Scott Test](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/UserAuthMethods/userId/6f467d0a-25ec-435c-8fb9-9d53eb21e02f/hidePreviewBanner~/true)| 2026-03-03 | ❌ |\n|[Alex Johnson](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/UserAuthMethods/userId/e436ca15-3a39-4dcc-819e-7dbb246cd46b/hidePreviewBanner~/true)| Unknown | ❌ |\n|[Hayden Scott](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/UserAuthMethods/userId/0d6cfd05-fc46-440b-b605-66dd26dcd7d2/hidePreviewBanner~/true)| 01/28/2026 12:30:09 | ❌ |\n|[Hayden Scott](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/UserAuthMethods/userId/c0b65b13-37b1-4081-bcfc-14844159b4a5/hidePreviewBanner~/true)| 05/18/2026 07:31:59 | ❌ |\n|[Agent User Example 3791943](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/UserAuthMethods/userId/76112b45-5214-4fa5-8054-30bafc588e5e/hidePreviewBanner~/true)| Unknown | ❌ |\n|[Agent User Example 3792567](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/UserAuthMethods/userId/7ecf3e6f-2343-455e-8d4f-73d661ac3ae3/hidePreviewBanner~/true)| Unknown | ❌ |\n|[Agent User Example 3792993](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/UserAuthMethods/userId/b5d9a21a-3d15-474b-abd0-21c8d3c65589/hidePreviewBanner~/true)| Unknown | ❌ |\n|[Agent User Example 4181693](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/UserAuthMethods/userId/d83e2c6c-7e80-4343-b8ec-7fc49b1b100d/hidePreviewBanner~/true)| Unknown | ❌ |\n|[Agent User Example 4208366](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/UserAuthMethods/userId/d0ce1a0b-90a1-4493-92ca-58abbe556065/hidePreviewBanner~/true)| Unknown | ❌ |\n|[Agent User Example 4208785](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/UserAuthMethods/userId/e3916bda-a99d-47c6-8a28-4f89540c32b8/hidePreviewBanner~/true)| Unknown | ❌ |\n|[Agent User Example 4209371](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/UserAuthMethods/userId/f863e6af-79b3-46e4-82a6-dc47ee626346/hidePreviewBanner~/true)| Unknown | ❌ |\n|[Jordan Smith](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/UserAuthMethods/userId/bfaeba1e-1357-47de-9557-529caa103d5d/hidePreviewBanner~/true)| 05/18/2026 12:58:28 | ❌ |\n|[Taylor Brown](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/UserAuthMethods/userId/2072badc-3cf0-4e84-b4c2-f9c065c46165/hidePreviewBanner~/true)| Unknown | ❌ |\n|[Casey Davis](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/UserAuthMethods/userId/58d9ed99-93ca-4674-8c5f-ec770f5ba17d/hidePreviewBanner~/true)| Unknown | ❌ |\n|[antivirustest](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/UserAuthMethods/userId/1d131633-dd0e-4438-8ceb-df7577d2e0fd/hidePreviewBanner~/true)| Unknown | ❌ |\n|[ash-williams-test](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/UserAuthMethods/userId/c5c8ba63-4620-4e91-ac40-b66bebe07a0d/hidePreviewBanner~/true)| 2026-03-03 | ❌ |\n|[Morgan Wilson](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/UserAuthMethods/userId/5655cf54-34bc-4f36-bb74-44da35547975/hidePreviewBanner~/true)| Unknown | ❌ |\n|[Riley Martinez](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/UserAuthMethods/userId/653c7fdd-1b41-4229-992a-69cc35aad4f7/hidePreviewBanner~/true)| Unknown | ❌ |\n|[Cameron Anderson](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/UserAuthMethods/userId/1ce4078f-f795-4baf-aa55-1fdfcc2ebfe6/hidePreviewBanner~/true)| 05/18/2026 07:26:20 | ❌ |\n|[Avery Thomas](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/UserAuthMethods/userId/f431700c-6d81-45b8-8f8d-581a8aa7cda6/hidePreviewBanner~/true)| 01/20/2024 08:00:27 | ❌ |\n|[Daniel Nguyen](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/UserAuthMethods/userId/ddfb9311-801e-4a84-9466-a18086768b73/hidePreviewBanner~/true)| Unknown | ❌ |\n|[David Kim](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/UserAuthMethods/userId/1b156c3d-79c5-44d2-a88c-23f69216777f/hidePreviewBanner~/true)| Unknown | ❌ |\n|[Emma Johnson](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/UserAuthMethods/userId/e498eab5-b6b5-493f-8353-b8c350083791/hidePreviewBanner~/true)| Unknown | ❌ |\n|[Faiza Malkia](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/UserAuthMethods/userId/36bf7e02-3abc-46aa-895f-cf95227377fd/hidePreviewBanner~/true)| Unknown | ❌ |\n|[Jamie Rodriguez](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/UserAuthMethods/userId/0b37813c-ae19-4399-982f-16587f17f9c0/hidePreviewBanner~/true)| 05/18/2026 07:34:56 | ❌ |\n|[Dakota Lee](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/UserAuthMethods/userId/e4bc6f4a-124f-469b-8951-3d5c34fb9741/hidePreviewBanner~/true)| 11/15/2023 18:36:22 | ❌ |\n|[Hamisi Khari](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/UserAuthMethods/userId/494995bf-5510-450c-a317-6d24f63cd15b/hidePreviewBanner~/true)| Unknown | ❌ |\n|[Henrietta Mueller](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/UserAuthMethods/userId/eb6a4040-3ff6-4911-a80d-68c701384c38/hidePreviewBanner~/true)| Unknown | ❌ |\n|[HR Agent](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/UserAuthMethods/userId/143c26fd-d308-4cb4-9c80-b54e66d6192c/hidePreviewBanner~/true)| Unknown | ❌ |\n|[Skylar White](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/UserAuthMethods/userId/2a054082-8f05-4e05-8fce-4e35c3bb40cc/hidePreviewBanner~/true)| 2023-12-12 | ❌ |\n|[Jules Bailey](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/UserAuthMethods/userId/0145d508-50fd-4f86-a47a-bf1c043c8358/hidePreviewBanner~/true)| Unknown | ❌ |\n|[James Thompson](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/UserAuthMethods/userId/ba635de8-4625-42eb-a59a-87f507ad9a9e/hidePreviewBanner~/true)| Unknown | ❌ |\n|[Jane Doe](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/UserAuthMethods/userId/57c41b80-a96a-4c06-8ab9-9539818a637f/hidePreviewBanner~/true)| Unknown | ❌ |\n|[Jessica Taylor](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/UserAuthMethods/userId/983164a3-87fa-4071-aa67-ff1530092df1/hidePreviewBanner~/true)| Unknown | ❌ |\n|[Johanna Lorenz](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/UserAuthMethods/userId/8994aee7-8c36-4e04-9116-8f21d8acdeb7/hidePreviewBanner~/true)| Unknown | ❌ |\n|[John Doe Test 1](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/UserAuthMethods/userId/69a2da18-6395-4a90-bde8-72e8aaa6c775/hidePreviewBanner~/true)| Unknown | ❌ |\n|[John Doe Test 1](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/UserAuthMethods/userId/fcebe3cc-ca26-49c6-9bb1-c9eafb243634/hidePreviewBanner~/true)| Unknown | ❌ |\n|[John1 Doe](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/UserAuthMethods/userId/77d4be98-c05d-4478-be25-3ee710b5247e/hidePreviewBanner~/true)| 2024-04-11 | ❌ |\n|[Joni Sherman](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/UserAuthMethods/userId/2da436f2-952a-47de-9dfe-84bd2f0d93e9/hidePreviewBanner~/true)| Unknown | ❌ |\n|[peyton-test](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/UserAuthMethods/userId/e0952dcb-8d63-496d-8661-05c86c1a51f0/hidePreviewBanner~/true)| 2026-03-03 | ❌ |\n|[Peyton Clark](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/UserAuthMethods/userId/7e92f268-bb12-469a-a869-210d596d4c1f/hidePreviewBanner~/true)| 03/17/2026 03:14:18 | ❌ |\n|[Lee Gu](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/UserAuthMethods/userId/0a9e313b-8777-4741-ba14-0f2724179117/hidePreviewBanner~/true)| Unknown | ❌ |\n|[Lidia Holloway](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/UserAuthMethods/userId/9188d3d3-386c-4145-a811-0d777a288e11/hidePreviewBanner~/true)| Unknown | ❌ |\n|[Lynne Robbins](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/UserAuthMethods/userId/8e5f7749-d5e7-46fc-8eb7-3b8ab7e20ae5/hidePreviewBanner~/true)| Unknown | ❌ |\n|[Charlie Lewis](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/UserAuthMethods/userId/5b0ec3ff-cea1-4eb9-8530-f2a66e5bec0a/hidePreviewBanner~/true)| 07/30/2025 03:28:21 | ❌ |\n|[Finley Robinson](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/UserAuthMethods/userId/990fd38a-c516-4e3f-82e4-d458a1ab0f91/hidePreviewBanner~/true)| 05/18/2026 08:23:54 | ❌ |\n|[finley-test](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/UserAuthMethods/userId/d71ccc09-c0a3-4604-9d02-49f7a3715f49/hidePreviewBanner~/true)| 2026-03-03 | ❌ |\n|[Sam Parker](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/UserAuthMethods/userId/96d29f01-873c-46a3-b542-f7ee192cc675/hidePreviewBanner~/true)| 06/28/2025 12:47:54 | ❌ |\n|[Ash Williams](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/UserAuthMethods/userId/a0883b7a-c6a8-440f-84f0-d6e1b79aaf4c/hidePreviewBanner~/true)| 2025-10-08 | ❌ |\n|[Michael Wong](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/UserAuthMethods/userId/63e4e634-15e4-4a85-bc9c-532855574377/hidePreviewBanner~/true)| Unknown | ❌ |\n|[Miriam Graham](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/UserAuthMethods/userId/f5745554-1894-4fb0-9560-65d6fc489724/hidePreviewBanner~/true)| Unknown | ❌ |\n|[Nestor Wilke](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/UserAuthMethods/userId/24b9254d-1bc5-435c-ad3d-7dbee86f8b9a/hidePreviewBanner~/true)| Unknown | ❌ |\n|[New User](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/UserAuthMethods/userId/6eef8ea0-1263-4973-9b0b-1e7aed0d21cd/hidePreviewBanner~/true)| Unknown | ❌ |\n|[No Location](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/UserAuthMethods/userId/696743fa-055b-42fb-aac4-ab451a4617d6/hidePreviewBanner~/true)| Unknown | ❌ |\n|[NoMail Enabled](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/UserAuthMethods/userId/a740d122-ee21-4354-9423-adccf8b6b233/hidePreviewBanner~/true)| Unknown | ❌ |\n|[Olivia Patel](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/UserAuthMethods/userId/03a5c332-4d75-47fd-b211-838e8cd0ee1b/hidePreviewBanner~/true)| Unknown | ❌ |\n|[On-Premises Directory Synchronization Service Account](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/UserAuthMethods/userId/33956e9a-cb54-42e9-94e8-d8f6ba05a55f/hidePreviewBanner~/true)| 06/17/2024 04:12:01 | ❌ |\n|[Patti Fernandez](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/UserAuthMethods/userId/3bae3a95-7605-4271-8418-e35733991834/hidePreviewBanner~/true)| Unknown | ❌ |\n|[Pradeep Gupta](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/UserAuthMethods/userId/ac712f60-0052-4911-8c5d-146cf9d4dc59/hidePreviewBanner~/true)| Unknown | ❌ |\n|[parker-test](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/UserAuthMethods/userId/c1bdb03c-0079-40b1-96a8-3595de3b94a2/hidePreviewBanner~/true)| 2026-09-03 | ❌ |\n|[Ellis Cooper](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/UserAuthMethods/userId/1433571b-3d7c-4a56-a9cc-67580848bc73/hidePreviewBanner~/true)| 09/23/2025 23:03:25 | ❌ |\n|[Rhea Stone](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/UserAuthMethods/userId/ac49a6e5-09c1-404b-915e-0d28574b3d72/hidePreviewBanner~/true)| Unknown | ❌ |\n|[Richard Wilkings](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/UserAuthMethods/userId/c27e2b23-c322-4a79-8c6f-9dba8fd9f4e2/hidePreviewBanner~/true)| Unknown | ❌ |\n|[Roi Fraguela](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/UserAuthMethods/userId/e0a814e5-5169-4af2-bb19-63930b42ac41/hidePreviewBanner~/true)| Unknown | ❌ |\n|[Ryan Chen](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/UserAuthMethods/userId/9605b9f8-9823-4c33-8018-57ad32d9fcb9/hidePreviewBanner~/true)| Unknown | ❌ |\n|[Sage Bennett](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/UserAuthMethods/userId/518ce209-faf4-4717-add9-7129a669fa11/hidePreviewBanner~/true)| 05/18/2026 07:55:35 | ❌ |\n|[Sandy](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/UserAuthMethods/userId/d5e32d0c-3f3c-43ef-abe1-75890a73f40c/hidePreviewBanner~/true)| Unknown | ❌ |\n|[Sarah Mehrotra](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/UserAuthMethods/userId/2d79a82a-ae19-461a-a0aa-807045ec3c4e/hidePreviewBanner~/true)| 05/18/2026 08:02:51 | ❌ |\n|[Sarah Mitchell](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/UserAuthMethods/userId/0ca3a9f0-7e3c-44c5-9638-250be0d94621/hidePreviewBanner~/true)| Unknown | ❌ |\n|[Shonali Balakrishna](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/UserAuthMethods/userId/305bbf73-eee4-4e0c-9c7d-627e00ed3665/hidePreviewBanner~/true)| 2025-05-05 | ❌ |\n|[Simon Burn](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/UserAuthMethods/userId/c3aab1a2-0733-438d-bc14-90dc8f6d876d/hidePreviewBanner~/true)| Unknown | ❌ |\n|[Sophia Rodriguez](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/UserAuthMethods/userId/d5d9f31f-c8d7-4b6c-bfca-b25b1cd4c1f1/hidePreviewBanner~/true)| Unknown | ❌ |\n|[Tegra Núnez](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/UserAuthMethods/userId/25e54254-3719-4c07-a880-3aee6bc60876/hidePreviewBanner~/true)| Unknown | ❌ |\n|[Tracy yu](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/UserAuthMethods/userId/80153e0b-dcce-42de-9df6-59a3fc89479b/hidePreviewBanner~/true)| Unknown | ❌ |\n|[Dakota Lee](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/UserAuthMethods/userId/210d3e96-015f-462d-b6d6-81e6023263df/hidePreviewBanner~/true)| 2026-01-05 | ❌ |\n|[Dakota Lee Test](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/UserAuthMethods/userId/43482f27-d1af-420f-84ba-e9148a700f45/hidePreviewBanner~/true)| 05/18/2026 08:24:19 | ❌ |\n|[Phoenix Gray](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/UserAuthMethods/userId/7094fb23-003a-4f81-9796-5daeaa603003/hidePreviewBanner~/true)| 2025-04-02 | ❌ |\n|[Rowan Foster](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/UserAuthMethods/userId/7804b01c-1223-4045-a393-43171298fa6b/hidePreviewBanner~/true)| Unknown | ❌ |\n|[usernonick](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/UserAuthMethods/userId/b531f68f-8d01-467b-9db6-a57438b0e8af/hidePreviewBanner~/true)| Unknown | ❌ |\n|[Avery Brooks](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/UserAuthMethods/userId/a85798bd-652b-4eb9-ba90-3ee882df0179/hidePreviewBanner~/true)| 02/19/2026 11:02:30 | ❌ |\n|[Wilna Rossouw](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/UserAuthMethods/userId/62cd4528-8e5d-4789-84f6-8b33d0af5ca7/hidePreviewBanner~/true)| Unknown | ❌ |\n|[Yakup Meredow](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/UserAuthMethods/userId/767bcbda-28a0-4e5f-841d-e918c5a1c229/hidePreviewBanner~/true)| Unknown | ❌ |\n|[Alex Wilber](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/UserAuthMethods/userId/f10bc459-0bcf-49d0-8f86-4553b8f015b8/hidePreviewBanner~/true)| 2026-03-05 | ✅ |\n|[Diego Siciliani](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/UserAuthMethods/userId/cdfa577c-972f-4399-98aa-1ec4be7fa6d1/hidePreviewBanner~/true)| 06/28/2025 23:31:12 | ✅ |\n|[Quinn Garcia](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/UserAuthMethods/userId/ceef37b7-c865-48fb-80c9-4def11201854/hidePreviewBanner~/true)| 2025-06-12 | ✅ |\n|[Reese Harris](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/UserAuthMethods/userId/babe04c9-8340-4329-a727-a8cee0cd2b1a/hidePreviewBanner~/true)| 04/20/2026 01:11:33 | ✅ |\n|[Ash Williams](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/UserAuthMethods/userId/513f3db2-044c-41be-af14-431bf88a2b3e/hidePreviewBanner~/true)| 05/18/2026 08:56:31 | ✅ |\n|[Drew Mitchell](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/UserAuthMethods/userId/df02402a-e291-42cc-b449-79366daa2a40/hidePreviewBanner~/true)| 05/16/2026 06:01:47 | ✅ |\n\n\n","TestStatus":"Failed","TestDescription":"Attackers might gain access if multifactor authentication (MFA) isn't universally enforced or if there are exceptions in place. Attackers might gain access by exploiting vulnerabilities of weaker MFA methods like SMS and phone calls through social engineering techniques. These techniques might include SIM swapping or phishing, to intercept authentication codes.\n\nAttackers might use these accounts as entry points into the tenant. By using intercepted user sessions, attackers can disguise their activities as legitimate user actions, evade detection, and continue their attack without raising suspicion. From there, they might attempt to manipulate MFA settings to establish persistence, plan, and execute further attacks based on the privileges of compromised accounts.\n\n**Remediation action**\n\n- [Deploy multifactor authentication](https://learn.microsoft.com/entra/identity/authentication/howto-mfa-getstarted?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci)\n- [Get started with a phishing-resistant passwordless authentication deployment](https://learn.microsoft.com/entra/identity/authentication/how-to-plan-prerequisites-phishing-resistant-passwordless-authentication?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci)\n- [Deploy a Conditional Access policy to require phishing-resistant MFA for all users](https://learn.microsoft.com/entra/identity/conditional-access/policy-all-users-mfa-strength?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci)\n- [Review authentication methods activity](https://learn.microsoft.com/entra/identity/monitoring-health/concept-usage-insights-report?tabs=microsoft-entra-admin-center&wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci#authentication-methods-activity)\n","TestId":"21801"},{"TestImplementationCost":"High","TestPillar":"Identity","TestCategory":"Application management","SkippedReason":null,"TestImpact":"Low","TestAppliesTo":["Identity"],"TestSfiPillar":"Protect engineering systems","TestSkipped":"","TestMinimumLicense":"P1","TestTags":["Identity"],"TestTitle":"App registrations use safe redirect URIs","TestRisk":"High","TestResult":"\nUnsafe redirect URIs found\n\n1️⃣ → Use of http(s) instead of https, 2️⃣ → Use of *.azurewebsites.net, 3️⃣ → Invalid URL, 4️⃣ → Domain not resolved\n\n| | Name | Unsafe redirect URIs |\n| :--- | :--- | :--- |\n| | [Azure AD SAML Toolkit](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/SignOn/objectId/4317fd0a-dcee-45bf-8e94-9a66638b11e0/appId/6f5ed68c-9fad-4d78-bf88-2b16bbe16338/preferredSingleSignOnMode/saml/servicePrincipalType/Application/fromNav/) | `2️⃣ https://samltoolkit.azurewebsites.net/SAML/Consume` | |\n| | [My nice app](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/SignOn/objectId/d41cfc13-11d1-4f93-835a-88e729725564/appId/2946f286-2b59-4f29-876c-0ed8bbe1c482/preferredSingleSignOnMode/saml/servicePrincipalType/Application/fromNav/) | `2️⃣ https://mysalmon.azurewebsites.net/login.saml` | |\n| | [MyVisualStudioMcpClient](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/SignOn/objectId/cae606b7-4a44-4d07-a7a5-a6fb285e41f1/appId/84ad8697-445d-4b26-affd-1b1459e97aae/preferredSingleSignOnMode/saml/servicePrincipalType/Application/fromNav/) | `1️⃣ http://127.0.0.1:33418` | |\n| | [MyVscode](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/SignOn/objectId/dfc83a5d-36e5-4506-ae9d-6ad5bb403377/appId/92abdce1-3952-4a8b-8720-e59257edd421/preferredSingleSignOnMode/saml/servicePrincipalType/Application/fromNav/) | `1️⃣ http://127.0.0.1:33418` | |\n| | [saml test app](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/SignOn/objectId/daa6074c-db6f-4bdc-a41b-bc0052c536a5/appId/c266d677-a5f8-47bc-9f0a-1b6fbe0bddad/preferredSingleSignOnMode/saml/servicePrincipalType/Application/fromNav/) | `2️⃣ https://appclaims.azurewebsites.net/signin-saml`, `2️⃣ https://appclaims.azurewebsites.net/signin-oidc` | |\n\n\n","TestStatus":"Failed","TestDescription":"OAuth applications configured with URLs that include wildcards, or URL shorteners increase the attack surface for threat actors. Insecure redirect URIs (reply URLs) might allow adversaries to manipulate authentication requests, hijack authorization codes, and intercept tokens by directing users to attacker-controlled endpoints. Wildcard entries expand the risk by permitting unintended domains to process authentication responses, while shortener URLs might facilitate phishing and token theft in uncontrolled environments. \n\nWithout strict validation of redirect URIs, attackers can bypass security controls, impersonate legitimate applications, and escalate their privileges. This misconfiguration enables persistence, unauthorized access, and lateral movement, as adversaries exploit weak OAuth enforcement to infiltrate protected resources undetected.\n\n**Remediation action**\n\n- [Check the redirect URIs for your application registrations.](https://learn.microsoft.com/entra/identity-platform/reply-url?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci) Make sure the redirect URIs don't have *.azurewebsites.net, wildcards, or URL shorteners.\n","TestId":"21885"},{"TestImplementationCost":"Medium","TestPillar":"Identity","TestCategory":"Access control","SkippedReason":"UnderConstruction","TestImpact":"Low","TestAppliesTo":["Identity"],"TestSfiPillar":"Protect identities and secrets","TestSkipped":"UnderConstruction","TestMinimumLicense":null,"TestTags":["Identity"],"TestTitle":"Guest identities are lifecycle managed with access reviews","TestRisk":"Medium","TestResult":"\nPlanned for future release.\n","TestStatus":"Planned","TestDescription":"...\n\n**Remediation action**\n\n","TestId":"21857"},{"TestImpact":"Low","TestRisk":"Medium","TestSkipped":"NoCompatibleLicenseFound","TestAppliesTo":null,"TestPillar":"Network","TestCategory":"Global Secure Access","TestDescription":"Creating filtering policies without linking them to a security profile or the baseline profile leaves them unenforced. Policies must be associated with either the baseline profile (applies to all internet traffic) or a security profile (applies through Conditional Access) to take effect. Unlinked policies provide no protection and create false confidence in your security posture.\n\n**Remediation action**\n\n- [Create security profiles and link filtering policies](https://learn.microsoft.com/entra/global-secure-access/how-to-configure-web-content-filtering?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci#create-a-security-profile)\n","TestTitle":"Web content filtering policies are linked to security profiles","SkippedReason":"This test requires one of the following licenses: (\"Entra_Premium_Internet_Access\"). Please ensure your tenant has the appropriate licenses to run this test. See [Licensing & Service Plans](https://learn.microsoft.com/entra/identity/users/licensing-service-plan-reference)","TestId":"25410","TestImplementationCost":"Medium","TestMinimumLicense":["Entra_Premium_Internet_Access"],"TestSfiPillar":"Protect networks","TestResult":"\nSkipped. This test requires one of the following licenses: (\"Entra_Premium_Internet_Access\"). Please ensure your tenant has the appropriate licenses to run this test. See [Licensing & Service Plans](https://learn.microsoft.com/entra/identity/users/licensing-service-plan-reference)\n\n","TestStatus":"Skipped","TestTags":null},{"TestImplementationCost":"Low","TestPillar":"Identity","TestCategory":"Privileged access","SkippedReason":"UnderConstruction","TestImpact":"Low","TestAppliesTo":["Identity"],"TestSfiPillar":"Protect tenants and isolate production systems","TestSkipped":"UnderConstruction","TestMinimumLicense":"P1","TestTags":["Identity"],"TestTitle":"Conditional Access protected actions are enabled","TestRisk":"Medium","TestResult":"\nPlanned for future release.\n\n","TestStatus":"Planned","TestDescription":"Threat actors who gain privileged access to a tenant can manipulate identity, access, and security configurations. This type of attack can result in environment-wide compromise and loss of control over organizational assets. Take action to protect high-impact management tasks associated with Conditional Access policies, cross-tenant access settings, hard deletions, and network locations that are critical to maintaining security.\n\nProtected actions let administrators secure these tasks with extra security controls, such as stronger authentication methods (passwordless MFA or phishing-resistant MFA), the use of Privileged Access Workstation (PAW) devices, or shorter session timeouts.\n\n**Remediation action**\n\n- [Add, test, or remove protected actions in Microsoft Entra ID](https://learn.microsoft.com/entra/identity/role-based-access-control/protected-actions-add?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci)\n","TestId":"21831"},{"TestImplementationCost":"Low","TestPillar":"Identity","TestCategory":"Access control","SkippedReason":"This test is for tenants that are licensed for Entra Workload ID. See [Entra Workload ID licensing](https://learn.microsoft.com/entra/workload-id/workload-identities-faqs)","TestImpact":"High","TestAppliesTo":null,"TestSfiPillar":"Accelerate response and remediation","TestSkipped":"NotLicensedEntraWorkloadID","TestMinimumLicense":"Workload","TestTags":null,"TestTitle":"Workload Identities are configured with risk-based policies","TestRisk":"Medium","TestResult":"\nSkipped. This test is for tenants that are licensed for Entra Workload ID. See [Entra Workload ID licensing](https://learn.microsoft.com/entra/workload-id/workload-identities-faqs)\n\n","TestStatus":"Skipped","TestDescription":"Set up risk-based Conditional Access policies for workload identities based on risk policy in Microsoft Entra ID to make sure only trusted and verified workloads use sensitive resources. Without these policies, threat actors can compromise workload identities with minimal detection and perform further attacks. Without conditional controls to detect anomalous activity and other risks, there's no check against malicious operations like token forgery, access to sensitive resources, and disruption of workloads. The lack of automated containment mechanisms increases dwell time and affects the confidentiality, integrity, and availability of critical services. \n\n**Remediation action**\nCreate a risk-based Conditional Access policy for workload identities.\n- [Create a risk-based Conditional Access policy](https://learn.microsoft.com/entra/identity/conditional-access/workload-identity?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci#create-a-risk-based-conditional-access-policy)\n","TestId":21883},{"TestImplementationCost":"Low","TestPillar":"Identity","TestCategory":"Credential management","SkippedReason":null,"TestImpact":"Low","TestAppliesTo":null,"TestSfiPillar":"Protect identities and secrets","TestSkipped":"","TestMinimumLicense":"Free","TestTags":null,"TestTitle":"Security key authentication method enabled","TestRisk":"High","TestResult":"\nSecurity key authentication method is enabled for your tenant, providing hardware-backed phishing-resistant authentication.\n\n\n## FIDO2 security key authentication settings\n\n✅ **FIDO2 authentication method**\n- Status: Enabled\n- Include targets: All users\n- Exclude targets: None\n\n\n\n","TestStatus":"Passed","TestDescription":"FIDO2 security keys provide hardware-backed, phishing-resistant authentication that protects against credential theft and unauthorized access. Security keys use cryptographic proof of identity bound to a specific device, making credentials impossible to replicate or phish. Enabling this authentication method allows users to register security keys for strong passwordless authentication.\n\n**Remediation action**\n\n- [Enable FIDO2 security key authentication method](https://learn.microsoft.com/entra/identity/authentication/how-to-enable-passkey-fido2?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci#enable-passkey-fido2-authentication-method)\n- [Manage authentication methods](https://learn.microsoft.com/entra/identity/authentication/concept-authentication-methods-manage?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci)\n","TestId":"21838"},{"TestImplementationCost":"Low","TestPillar":"Network","TestCategory":"Azure Network Security","SkippedReason":"This test is not applicable to the current environment.","TestImpact":"Low","TestAppliesTo":null,"TestSfiPillar":"Monitor and detect cyberthreats","TestSkipped":"NotApplicable","TestMinimumLicense":["DDoS_Network_Protection","DDoS_IP_Protection"],"TestTags":null,"TestTitle":"Metrics are enabled for DDoS-protected public IPs","TestRisk":"Medium","TestResult":"\nSkipped. This test is not applicable to the current environment.\n","TestStatus":"Skipped","TestDescription":"When Azure DDoS Protection is enabled for public IP addresses, enabling metrics provides essential real-time visibility into attack activity, mitigation effectiveness, and traffic patterns. Without metrics enabled on DDoS-protected public IPs, security teams lack the telemetry needed to detect ongoing attacks, validate that mitigation policies are working, and perform capacity planning. Azure DDoS Protection emits metrics such as \"Under DDoS attack or not\", inbound packets and bytes processed, packets and bytes dropped during mitigation, and TCP/UDP/SYN flood counters. These metrics are foundational for alerting, dashboards, and post-incident analysis. The absence of metrics prevents correlation of DDoS events with application performance issues and eliminates the ability to analyze attack patterns for proactive defense improvements. This check identifies all public IP addresses that are actually DDoS-protected — either through DDoS IP Protection enabled directly on the public IP, or through DDoS Network Protection inherited from a VNET that has a DDoS Protection Plan associated — and verifies that diagnostic settings are configured to capture metrics for security monitoring.\n\n**Remediation action**\n\nEnable metrics in diagnostic settings for DDoS-protected public IP addresses\n- [Azure DDoS Protection metrics and alerts](https://learn.microsoft.com/en-us/azure/ddos-protection/ddos-diagnostic-logs)\n\nConfigure diagnostic settings for Azure resources\n- [Configure diagnostic settings for Azure resources](https://learn.microsoft.com/en-us/azure/azure-monitor/essentials/diagnostic-settings)\n\nReview DDoS Protection capabilities and overview\n- [Azure DDoS Protection overview](https://learn.microsoft.com/en-us/azure/ddos-protection/ddos-protection-overview)\n\nEnable DDoS Network Protection on virtual networks\n- [Quickstart: Create and configure Azure DDoS Network Protection using Azure portal](https://learn.microsoft.com/en-us/azure/ddos-protection/manage-ddos-protection)\n\n","TestId":26885},{"TestImplementationCost":"Low","TestPillar":"Network","TestCategory":"Azure Network Security","SkippedReason":"This test is not applicable to the current environment.","TestImpact":"Low","TestAppliesTo":null,"TestSfiPillar":"Protect networks","TestSkipped":"NotApplicable","TestMinimumLicense":"Azure_Front_Door_Premium","TestTags":null,"TestTitle":"Bot protection rule set is enabled and assigned in Azure Front Door WAF","TestRisk":"High","TestResult":"\nSkipped. This test is not applicable to the current environment.\n","TestStatus":"Skipped","TestDescription":"Azure Front Door is a global, scalable entry point that uses the Microsoft global edge network to deliver fast, secure, and highly scalable web applications. Web Application Firewall (WAF) integrated with Azure Front Door provides protection against common web exploits and vulnerabilities at the network edge. The Bot Manager rule set is a managed rule set available exclusively in Azure Front Door Premium SKU that provides protection against malicious bots while allowing legitimate bots such as search engine crawlers to access your applications. When bot protection is not enabled, threat actors can deploy automated attacks against web applications including credential stuffing attacks that test stolen username/password combinations at scale, web scraping that extracts sensitive data or intellectual property, inventory hoarding bots that deplete product availability, and application-layer DDoS attacks that exhaust backend resources. The Bot Manager rule set categorizes bots into good bots, bad bots, and unknown bots, allowing security teams to configure appropriate actions for each category. Bad bots can be blocked or challenged with CAPTCHA, while good bots like Googlebot and Bingbot are allowed through. Without bot protection, organizations lack visibility into bot traffic patterns and cannot distinguish between human users and automated clients, making it impossible to defend against sophisticated bot-driven attacks that bypass traditional rate limiting and IP-based controls.\n\n**Remediation action**\n\nUpgrade to Azure Front Door Premium if currently using Standard SKU to access bot protection features\n- [Azure Front Door tier comparison](https://learn.microsoft.com/en-us/azure/frontdoor/standard-premium/tier-comparison)\n\nCreate a WAF policy with Premium SKU if one does not exist\n- [Create a WAF policy for Azure Front Door using the Azure portal](https://learn.microsoft.com/en-us/azure/web-application-firewall/afds/waf-front-door-create-portal)\n\nEnable the Bot Manager rule set in the WAF policy\n- [Configure bot protection for Web Application Firewall](https://learn.microsoft.com/en-us/azure/web-application-firewall/afds/waf-front-door-policy-configure-bot-protection)\n\nAssociate the WAF policy with your Azure Front Door profile via security policies\n- [Add security policy in Azure Front Door](https://learn.microsoft.com/en-us/azure/frontdoor/how-to-configure-endpoints#add-security-policy)\n\nConfigure bot protection rules to customize actions for different bot categories\n- [Bot protection rule set on Azure Front Door](https://learn.microsoft.com/en-us/azure/web-application-firewall/afds/afds-overview#bot-protection-rule-set)\n\nMonitor bot traffic using Azure Front Door logs and metrics\n- [Monitor metrics and logs in Azure Front Door](https://learn.microsoft.com/en-us/azure/frontdoor/front-door-diagnostics)\n\n","TestId":26884},{"TestImplementationCost":"","TestPillar":"Infrastructure","TestCategory":"Implement security best practices","SkippedReason":null,"TestImpact":"","TestAppliesTo":null,"TestSfiPillar":"Protect tenants and isolate production systems","TestSkipped":"","TestMinimumLicense":"N/A","TestTags":null,"TestTitle":"Subnets should be associated with a network security group","TestRisk":"Low","TestResult":"Subnets should be associated with a network security group\n\n| Subscription | Resource group | Resource type | Affected resource | Status | Azure portal |\n| :----------- | :------------- | :------------ | :---------------- | :----- | :----------- |\n| [Visual Studio Enterprise Subscription](https://portal.azure.com/#resource/subscriptions/54d3ea01-5a07-45d0-8d69-e5f5b0b20098) | indiavm_group | virtualnetworks | [default](https://portal.azure.com/#resource/subscriptions/54d3ea01-5a07-45d0-8d69-e5f5b0b20098/resourceGroups/indiavm_group/providers/Microsoft.Network/virtualNetworks/indiavm-vnet/subnets/default) | ❌ | [View recommendation](https://portal.azure.com/#blade/Microsoft_Azure_Security/RecommendationsBlade/assessmentKey/eade5b56-eefd-444f-95c8-23f29e5d93cb/resourceId/%2fsubscriptions%2f54d3ea01-5a07-45d0-8d69-e5f5b0b20098%2fresourceGroups%2findiavm_group%2fproviders%2fMicrosoft.Network%2fvirtualNetworks%2findiavm-vnet%2fsubnets%2fdefault) |\n| [Visual Studio Enterprise Subscription](https://portal.azure.com/#resource/subscriptions/54d3ea01-5a07-45d0-8d69-e5f5b0b20098) | charlie | virtualnetworks | [default](https://portal.azure.com/#resource/subscriptions/54d3ea01-5a07-45d0-8d69-e5f5b0b20098/resourceGroups/charlie/providers/Microsoft.Network/virtualNetworks/charlie-vnet/subnets/default) | ❌ | [View recommendation](https://portal.azure.com/#blade/Microsoft_Azure_Security/RecommendationsBlade/assessmentKey/eade5b56-eefd-444f-95c8-23f29e5d93cb/resourceId/%2fsubscriptions%2f54d3ea01-5a07-45d0-8d69-e5f5b0b20098%2fresourceGroups%2fcharlie%2fproviders%2fMicrosoft.Network%2fvirtualNetworks%2fcharlie-vnet%2fsubnets%2fdefault) |\n","TestStatus":"Failed","TestDescription":"Protect your subnet from potential threats by restricting access to it with a network security group (NSG). NSGs contain a list of Access Control List (ACL) rules that allow or deny network traffic to your subnet. When an NSG is associated with a subnet, the ACL rules apply to all the VM instances and integrated services in that subnet, but don't apply to internal traffic inside the subnet. To secure resources in the same subnet from one another, enable NSG directly on the resources as well.
Note that the following subnet types will be listed as not applicable: GatewaySubnet, AzureFirewallSubnet, AzureBastionSubnet.\n\n**Remediation action**\n\nTo enable Network Security Groups on your subnets:
1. Select a subnet to enable NSG on.
2. Click the 'Network security group' section.
3. Follow the steps and select an existing network security group to attach to this specific subnet.","TestId":"eade5b56-eefd-444f-95c8-23f29e5d93cb"},{"TestImpact":"Low","TestRisk":"Medium","TestSkipped":"NoCompatibleLicenseFound","TestAppliesTo":null,"TestPillar":"Network","TestCategory":"Global Secure Access","TestDescription":"Transport Layer Security (TLS) inspection bypass rules create exceptions where encrypted traffic skips deep packet inspection. Without regular review, bypass rules accumulate as temporary exceptions become permanent, applications are decommissioned while their rules remain, or initial justifications become obsolete. Threat actors target uninspected traffic channels. They know that malware command-and-control communications, data exfiltration, and credential theft over HTTPS evade detection when traffic bypasses TLS inspection. Policies not modified in over 90 days might contain stale bypass rules that create blind spots in your network security posture.\n\n**Remediation action**\n\n- Establish a quarterly review process for TLS inspection bypass rules, document a business justification for each bypass rule, and remove rules that are no longer necessary.\n- [Review and manage TLS inspection policies](https://learn.microsoft.com/graph/api/resources/networkaccess-tlsinspectionpolicy?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci) in the Microsoft Entra admin center under **Global Secure Access** > **Secure** > **TLS inspection**.\n- Review the steps in [Configure Transport Layer Security inspection policies](https://learn.microsoft.com/entra/global-secure-access/how-to-transport-layer-security?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci) to understand how to modify or remove bypass rules as part of the review process.\n","TestTitle":"TLS inspection bypass rules are regularly reviewed","SkippedReason":"This test requires one of the following licenses: (\"Entra_Premium_Internet_Access\"). Please ensure your tenant has the appropriate licenses to run this test. See [Licensing & Service Plans](https://learn.microsoft.com/entra/identity/users/licensing-service-plan-reference)","TestId":"27001","TestImplementationCost":"Medium","TestMinimumLicense":["Entra_Premium_Internet_Access"],"TestSfiPillar":"Protect networks","TestResult":"\nSkipped. This test requires one of the following licenses: (\"Entra_Premium_Internet_Access\"). Please ensure your tenant has the appropriate licenses to run this test. See [Licensing & Service Plans](https://learn.microsoft.com/entra/identity/users/licensing-service-plan-reference)\n\n","TestStatus":"Skipped","TestTags":null},{"TestImplementationCost":"Medium","TestPillar":"Identity","TestCategory":"Privileged access","SkippedReason":null,"TestImpact":"Low","TestAppliesTo":null,"TestSfiPillar":"Protect identities and secrets","TestSkipped":"","TestMinimumLicense":"P2","TestTags":null,"TestTitle":"Activation alert for all privileged role assignments","TestRisk":"Low","TestResult":"\nActivation alerts are configured for privileged role assignments.\n\n","TestStatus":"Passed","TestDescription":"Without activation alerts for privileged role assignments, threat actors can escalate privileges undetected. This lack of visibility creates a blind spot where attackers can activate the most privileged role and perform malicious actions such as creating backdoor accounts, modifying security policies, or accessing sensitive data.\n\nMonitoring these activation alerts can help security teams distinguish between authorized and unauthorized privilege escalation activities. \n\n**Remediation action**\n\n- [Configure notifications for privileged roles](https://learn.microsoft.com/entra/id-governance/privileged-identity-management/pim-how-to-change-default-settings?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci#require-justification-on-active-assignment)\n","TestId":"21820"},{"TestImplementationCost":"","TestPillar":"Infrastructure","TestCategory":"Restrict unauthorized network access","SkippedReason":null,"TestImpact":"","TestAppliesTo":null,"TestSfiPillar":"Protect tenants and isolate production systems","TestSkipped":"","TestMinimumLicense":"N/A","TestTags":null,"TestTitle":"Internet-facing virtual machines should be protected with network security groups","TestRisk":"High","TestResult":"Internet-facing virtual machines should be protected with network security groups\n\n| Subscription | Resource group | Resource type | Affected resource | Status | Azure portal |\n| :----------- | :------------- | :------------ | :---------------- | :----- | :----------- |\n| [Visual Studio Enterprise Subscription](https://portal.azure.com/#resource/subscriptions/54d3ea01-5a07-45d0-8d69-e5f5b0b20098) | indiavm_group | virtualmachines | [india-2](https://portal.azure.com/#resource/subscriptions/54d3ea01-5a07-45d0-8d69-e5f5b0b20098/resourceGroups/INDIAVM_GROUP/providers/Microsoft.Compute/virtualMachines/india-2) | ✅ | [View recommendation](https://portal.azure.com/#blade/Microsoft_Azure_Security/RecommendationsBlade/assessmentKey/483f12ed-ae23-447e-a2de-a67a10db4353/resourceId/%2fsubscriptions%2f54d3ea01-5a07-45d0-8d69-e5f5b0b20098%2fresourceGroups%2fINDIAVM_GROUP%2fproviders%2fMicrosoft.Compute%2fvirtualMachines%2findia-2) |\n| [Visual Studio Enterprise Subscription](https://portal.azure.com/#resource/subscriptions/54d3ea01-5a07-45d0-8d69-e5f5b0b20098) | indiavm_group | virtualmachines | [indiavm](https://portal.azure.com/#resource/subscriptions/54d3ea01-5a07-45d0-8d69-e5f5b0b20098/resourceGroups/INDIAVM_GROUP/providers/Microsoft.Compute/virtualMachines/indiavm) | ✅ | [View recommendation](https://portal.azure.com/#blade/Microsoft_Azure_Security/RecommendationsBlade/assessmentKey/483f12ed-ae23-447e-a2de-a67a10db4353/resourceId/%2fsubscriptions%2f54d3ea01-5a07-45d0-8d69-e5f5b0b20098%2fresourceGroups%2fINDIAVM_GROUP%2fproviders%2fMicrosoft.Compute%2fvirtualMachines%2findiavm) |\n","TestStatus":"Passed","TestDescription":"Protect your VM from potential threats by restricting access to it with a network security group (NSG). NSGs contain a list of Access Control List (ACL) rules that allow or deny network traffic to your VM from other instances, in or outside the same subnet.
To keep your machine as secure as possible, the VM access to the internet must be restricted and an NSG should be enabled on the subnet.
VMs with 'High' severity are internet-facing VMs.\n\n**Remediation action**\n\nTo protect a virtual machine with a Network Security Group:
1. Select a VM from the list below, or click \"Take action\" if you've arrived from a recommendation for a specific VM.
2. Assign the relevant NSG to the NIC or subnet for the VM you're protecting:
  a. To assign the NSG to the VM's subnet (recommended):
    i. In the Networking page, select the 'Virtual network/subnet'.
    ii. Open the \"Subnets\" menu.
    iii. Select the subnet where your VM is deployed.
    iv. Select the Network Security Group to assign to the subnet and click \"Save\".
  b. To assign the NSG to the NIC:
    i. In the Networking page, select the network interface that's associated with the selected VM.
    ii. In the Network interfaces page, select the 'Network security group' menu item.
    iii. Click 'Edit' at the top of the page.
    iv. Follow the on-screen instructions and select the Network Security Group to assign to this NIC.
Learn more.","TestId":"483f12ed-ae23-447e-a2de-a67a10db4353"},{"TestImplementationCost":"Low","TestPillar":"Network","TestCategory":"Azure Network Security","SkippedReason":"This test is not applicable to the current environment.","TestImpact":"Medium","TestAppliesTo":null,"TestSfiPillar":"Protect networks","TestSkipped":"NotApplicable","TestMinimumLicense":"Azure WAF","TestTags":null,"TestTitle":"CAPTCHA challenge is enabled in Azure Front Door WAF","TestRisk":"Medium","TestResult":"\nNo Azure Front Door WAF policies attached to Azure Front Door found.\n","TestStatus":"Skipped","TestDescription":"Azure Front Door Web Application Firewall (WAF) supports CAPTCHA challenge as a defense mechanism against sophisticated bots and automated tools across the global edge network. CAPTCHA challenge works by presenting users with a visual or audio puzzle that requires human cognitive ability to solve, proving that the request originates from a real human rather than an automated bot or script. When a request triggers a CAPTCHA challenge, the WAF responds with a challenge page containing the CAPTCHA puzzle that the user must solve to obtain a valid challenge cookie. If the user successfully completes the CAPTCHA, subsequent requests proceed normally until the cookie expires. Bots and automated tools that cannot solve the CAPTCHA puzzle are blocked from accessing protected resources at the edge before traffic reaches origin servers. CAPTCHA challenge is more effective than JavaScript challenge against advanced bots that use headless browsers with full JavaScript support, as it requires human-level cognition to pass. The `captchaExpirationInMinutes` setting in the policy controls how long the CAPTCHA cookie remains valid before the user must complete another challenge. CAPTCHA challenge provides the strongest level of interactive verification available in Azure Front Door WAF—it confirms human presence through an interactive puzzle rather than only verifying browser capability like JavaScript challenge. By configuring custom rules with CAPTCHA challenge action on Azure Front Door WAF, organizations can protect highly sensitive endpoints like login pages, registration forms, password reset flows, and payment pages from automated abuse while ensuring that only verified humans can access these resources across globally distributed edge locations.\n\n**Remediation action**\n\n- [Azure Web Application Firewall on Azure Front Door](https://learn.microsoft.com/en-us/azure/web-application-firewall/afds/afds-overview)\n- [Web Application Firewall custom rules for Azure Front Door](https://learn.microsoft.com/en-us/azure/web-application-firewall/afds/waf-front-door-custom-rules)\n- [Tutorial: Create a Web Application Firewall policy on Azure Front Door](https://learn.microsoft.com/en-us/azure/web-application-firewall/afds/waf-front-door-create-portal)\n- [Configure CAPTCHA challenge for Azure Front Door WAF](https://learn.microsoft.com/en-us/azure/web-application-firewall/afds/waf-front-door-tuning#captcha-challenge)\n\n","TestId":27020},{"TestImplementationCost":"Medium","TestPillar":"Devices","TestCategory":"Data","SkippedReason":null,"TestImpact":"Low","TestAppliesTo":null,"TestSfiPillar":"Protect networks","TestSkipped":"","TestMinimumLicense":"Intune","TestTags":null,"TestTitle":"Corporate Wi-Fi network on iOS devices is securely managed","TestRisk":"High","TestResult":"\nNo Enterprise Wi-Fi profile for iOS exists or none are assigned.\n\n\n## iOS WiFi Configuration Profiles\n\n| Policy Name | Wi-Fi Security Type | Status | Assignment |\n| :---------- | :----- | :--------- | :--------- |\n| [Wifi test WPAEnterprise](https://intune.microsoft.com/#view/Microsoft_Intune_DeviceSettings/DevicesIosMenu/~/configuration) | Enterprise | ❌ Not Assigned | None |\n\n\n\n","TestStatus":"Failed","TestDescription":"If Wi-Fi profiles aren't properly configured and assigned, users can connect insecurely or fail to connect to trusted networks, exposing corporate data to interception or unauthorized access. Without centralized management, devices rely on manual configuration, increasing the risk of misconfiguration, weak authentication, and connection to rogue networks.\n\nCentrally managing Wi-Fi profiles for iOS devices in Intune ensures secure and consistent connectivity to enterprise networks. This enforces authentication and encryption standards, simplifies onboarding, and supports Zero Trust by reducing exposure to untrusted networks.\n\n**Remediation action**\n\nUse Intune to configure and assign secure Wi-Fi profiles for iOS/iPadOS devices to enforce authentication and encryption standards:\n\n- [Deploy Wi-Fi profiles to devices in Microsoft Intune](https://learn.microsoft.com/intune/intune-service/configuration/wi-fi-settings-configure?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci#create-the-profile)\n\nFor more information, see: \n- [Review the available Wi-Fi settings for iOS and iPadOS devices in Microsoft Intune](https://learn.microsoft.com/intune/intune-service/configuration/wi-fi-settings-ios?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci)\n","TestId":"24839"},{"TestImpact":"Low","TestRisk":"Medium","TestSkipped":"NotConnectedToService","TestAppliesTo":null,"TestPillar":"Data","TestCategory":"SharePoint Online","TestDescription":"When PDF labeling is disabled (the default) in SharePoint, PDF files can't be labeled or display existing labels, which creates a protection gap. Unlike Office files, PDFs can circulate externally without visible classification markers, making it impossible for recipients to determine the handling requirements or for data loss prevention (DLP) policies to detect sensitive content.\n\nEnabling PDF labeling for SharePoint and OneDrive extends sensitivity label support to PDFs, allowing users to apply labels by using Office for the web and SharePoint, and supports other labeling methods such as auto-labeling policies to classify PDF content automatically.\n\n**Remediation action**\n\n- [Enable sensitivity labels for PDF files in SharePoint and OneDrive](https://learn.microsoft.com/purview/sensitivity-labels-sharepoint-onedrive-files?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci#adding-support-for-pdf)\n","TestTitle":"PDF labeling is enabled in SharePoint","SkippedReason":"This test requires connection to the service(s) \"SharePointOnline\" currently disconnected. Please use _Connect-ZtAssessment_ to connect.","TestId":"35006","TestImplementationCost":"Low","TestMinimumLicense":["RMS_S_PREMIUM"],"TestSfiPillar":"Protect tenants and production systems","TestResult":"\nSkipped. This test requires connection to the service(s) \"SharePointOnline\" currently disconnected. Please use _Connect-ZtAssessment_ to connect.\n\n","TestStatus":"Skipped","TestTags":null},{"TestImpact":"High","TestRisk":"Medium","TestSkipped":"","TestAppliesTo":null,"TestPillar":"Identity","TestCategory":"Access control","TestDescription":"Attackers might exploit valid but inactive applications that still have elevated privileges. These applications can be used to gain initial access without raising alarm because they’re legitimate applications. From there, attackers can use the application privileges to plan or execute other attacks. Attackers might also maintain access by manipulating the inactive application, such as by adding credentials. This persistence ensures that even if their primary access method is detected, they can regain access later.\n\n**Remediation action**\n\n- [Disable privileged service principals](https://learn.microsoft.com/graph/api/serviceprincipal-update?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci)\n- Investigate if the application has legitimate use cases\n- [If service principal doesn't have legitimate use cases, delete it](https://learn.microsoft.com/graph/api/serviceprincipal-delete?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci)\n","TestTitle":"Inactive applications don't have highly privileged permissions","SkippedReason":null,"TestId":"21770","TestImplementationCost":"Low","TestMinimumLicense":["AAD_PREMIUM"],"TestSfiPillar":"Protect engineering systems","TestResult":"\nInactive Application(s) with high privileges were found\n\n\n## Apps with privileged Graph permissions\n\n| | Name | Risk | Delegate Permission | Application Permission | App owner tenant | Last sign in|\n| :--- | :--- | :--- | :--- | :--- | :--- | :--- |\n| ❌ | [Windows Virtual Desktop AME](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/Overview/objectId/8369f33c-da25-4a8a-866d-b0145e29ef29/appId/5a0aa725-4958-4b0c-80a9-34562e23f3b7) | High | | User.Read.All, Directory.Read.All | MS Azure Cloud | Unknown | \n| ❌ | [Reset Viral Users Redemption Status](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/Overview/objectId/3a8785da-9965-473f-a97c-25fefdc39fee/appId/cc7b0696-1956-408b-876a-ad6bf2b9890b) | High | User.Read, User.Invite.All, User.ReadWrite.All, Directory.ReadWrite.All, offline_access, profile, openid | | Microsoft | Unknown | \n| ❌ | [Azure AD Assessment (Test)](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/Overview/objectId/d4cf4286-0fbe-424d-b4f2-65aa2c568631/appId/c62a9fcb-53bf-446e-8063-ea6e2bfcc023) | High | AuditLog.Read.All, Directory.AccessAsUser.All, Directory.ReadWrite.All, Group.ReadWrite.All, IdentityProvider.ReadWrite.All, Policy.ReadWrite.TrustFramework, PrivilegedAccess.ReadWrite.AzureAD, PrivilegedAccess.ReadWrite.AzureResources, TrustFrameworkKeySet.ReadWrite.All, User.Invite.All, offline_access, openid, profile | | Microsoft Accounts | Unknown | \n| ❌ | [Modern Workplace Concierge](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/Overview/objectId/ad1c51e8-f8a8-4bf2-ac09-a3a20cba5fa5/appId/c65c4011-1b90-4ec9-b5e9-1ee17786ad84) | High | openid, profile, RoleManagement.Read.Directory, Application.Read.All, User.ReadBasic.All, Group.ReadWrite.All, DeviceManagementRBAC.ReadWrite.All, Policy.ReadWrite.ConditionalAccess, Policy.Read.All, User.Read, DeviceManagementApps.ReadWrite.All, DeviceManagementConfiguration.ReadWrite.All, DeviceManagementServiceConfig.ReadWrite.All | | Nicolonsky Tech | Unknown | \n| ❌ | [Graph Explorer](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/Overview/objectId/8f8f300a-870a-46ff-bdab-934e1436920d/appId/d3ce4cf8-6810-442d-b42e-375e14710095) | High | User.Read, Directory.AccessAsUser.All | | graphExplorerMT | Unknown | \n| ❌ | [Microsoft Sample Data Packs](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/Overview/objectId/63e1f0d4-bc2c-497a-bfe2-9eb4c8c2600e/appId/a1cffbc6-1cb3-44e4-a1d2-cee9cce700f1) | High | Files.ReadWrite, User.ReadWrite | Contacts.ReadWrite, Sites.Manage.All, MailboxSettings.ReadWrite, Sites.ReadWrite.All, Calendars.ReadWrite, Sites.FullControl.All, Application.ReadWrite.OwnedBy, Calendars.ReadWrite.All, Mail.ReadWrite, User.ReadWrite.All, Directory.ReadWrite.All, Files.ReadWrite.All, Group.ReadWrite.All, Mail.Send | Microsoft | Unknown | \n| ✅ | [idPowerToys - CI](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/Overview/objectId/b66231c2-9568-46f1-b61e-c5f8fd9edee4/appId/50827722-4f53-48ba-ae58-db63bb53626b) | High | Agreement.Read.All, CrossTenantInformation.ReadBasic.All, Directory.Read.All, Policy.Read.All, User.Read, openid, profile, offline_access | | Manson | 2023-07-05 | \n| ✅ | [idPowerToys - Release](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/Overview/objectId/4654e05d-9f59-4925-807c-8eb2306e1cb1/appId/904e4864-f3c3-4d2f-ace2-c37a4ed55145) | High | Agreement.Read.All, CrossTenantInformation.ReadBasic.All, Directory.Read.All, Policy.Read.All, User.Read, openid, profile, offline_access | | Manson | 2023-10-24 | \n| ✅ | [Azure AD Assessment](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/Overview/objectId/6c74be7f-bcc9-4541-bfe1-f113b90b0497/appId/68bc31c0-f891-4f4c-9309-c6104f7be41b) | High | Organization.Read.All, RoleManagement.Read.Directory, Application.Read.All, User.Read.All, Group.Read.All, Policy.Read.All, Directory.Read.All, SecurityEvents.Read.All, UserAuthenticationMethod.Read.All, AuditLog.Read.All, Reports.Read.All, openid, offline_access, profile | | Microsoft | 2023-10-27 | \n| ✅ | [idPowerToys for Desktop](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/Overview/objectId/24cc58d8-2844-4974-b7cd-21c8a470e6bb/appId/520aa3af-bd78-4631-8f87-d48d356940ed) | High | Directory.Read.All, Policy.Read.All, Agreement.Read.All, CrossTenantInformation.ReadBasic.All, openid, profile, offline_access | | Manson | 2025-02-16 | \n| ✅ | [entraChatAppMultiTenant](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/Overview/objectId/855a57ff-88a6-4ad0-85d7-4f46d742730e/appId/5e00b345-a805-42a0-9caa-7d6cb761c668) | High | User.Read, openid, profile, offline_access, APIConnectors.Read.All, Application.ReadWrite.All, Policy.ReadWrite.AuthenticationFlows, Policy.Read.All, EventListener.ReadWrite.All, Policy.ReadWrite.AuthenticationMethod, Group.Read.All, AuditLog.Read.All, Policy.ReadWrite.ConditionalAccess, IdentityUserFlow.Read.All, Policy.ReadWrite.TrustFramework, TrustFrameworkKeySet.Read.All, Directory.ReadWrite.All | | JJ Industries | 2025-05-08 | \n| ✅ | [Intune Documentation](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/Overview/objectId/97b66fb0-f682-41e0-9aef-47f170c2abae/appId/56066daa-baba-438f-89d0-7ea3be2e2222) | High | User.Read, DeviceManagementConfiguration.Read.All, DeviceManagementApps.Read.All, DeviceManagementManagedDevices.Read.All, DeviceManagementRBAC.Read.All, DeviceManagementServiceConfig.Read.All, Group.Read.All, openid, profile, offline_access | | Ugur Koc Lab | 2025-09-01 | \n| ✅ | [Automation](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/Overview/objectId/f79df990-9ad2-4142-b5fd-8945ff334da3/appId/dc7d83b5-d38b-4488-8952-7abf02e71590) | High | User.Read | Directory.ReadWrite.All | Pora Inc. | 2025-09-09 | \n| ✅ | [M365PronounKit](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/Overview/objectId/6bf7c616-88e8-4f7c-bdad-452e561fa777/appId/eea28244-3eec-4820-beae-d4a2c0bcc235) | High | | User.ReadWrite.All | Pora | 2025-09-09 | \n| ✅ | [test public client](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/Overview/objectId/5e80ea33-31fa-49fd-9a94-61894bd1a6c9/appId/79a0c604-f215-4c52-8fbe-641d08aa7937) | High | | User.Read.All | Pora | 2025-09-09 | \n| ✅ | [InfinityDemo](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/Overview/objectId/bac0ba57-1876-448e-96bf-6f0481c99fda/appId/fef811e1-2354-43b0-961b-248fe15e737d) | High | User.Read, Directory.Read.All | | Pora | 2025-09-09 | \n| ✅ | [Lokka](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/Overview/objectId/1abc3899-a5df-40ab-8aa7-95d31edd4c01/appId/f581405a-9e57-4e81-91f1-40cd62f7595e) | High | | Mail.Send, DeviceManagementConfiguration.ReadWrite.All, DirectoryRecommendations.Read.All, Policy.ReadWrite.Authorization, PrivilegedAccess.Read.AzureAD, Reports.Read.All, IdentityRiskEvent.Read.All, Policy.Read.All, User.Read.All, PrivilegedAccess.Read.AzureADGroup, Mail.Read, Directory.ReadWrite.All, Policy.ReadWrite.ConditionalAccess, UserAuthenticationMethod.Read.All | Pora Inc. | 2025-09-09 | \n| ✅ | [Maester DevOps Account - GitHub - Secret (demo)](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/Overview/objectId/e31cd01e-afaf-4cc3-8d15-d3f9f7eb61e8/appId/d0dc5f0a-bf75-41a4-9272-d5ec2345c963) | High | | DirectoryRecommendations.Read.All, Reports.Read.All, PrivilegedAccess.Read.AzureAD, Directory.Read.All, IdentityRiskEvent.Read.All, Policy.Read.All, DeviceManagementManagedDevices.Read.All, RoleEligibilitySchedule.Read.Directory, RoleManagement.Read.All, SecurityIdentitiesSensors.Read.All, Policy.Read.ConditionalAccess, SecurityIdentitiesHealth.Read.All, DeviceManagementConfiguration.Read.All, SharePointTenantSettings.Read.All, UserAuthenticationMethod.Read.All, Mail.Send | Pora Inc. | 2025-09-09 | \n| ✅ | [MyTestForBlock](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/Overview/objectId/e9fca357-cccd-4ec4-840f-7482f6f02818/appId/14a3ba45-3246-4fbe-8c3b-c3922e68232b) | High | | User.Read.All | Pora | 2025-09-09 | \n| ✅ | [PnPPowerShell](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/Overview/objectId/6d2e8d37-82b8-41e7-aa95-443a7401e8b8/appId/1d93462e-0f39-4e4c-898a-b6b1df5fa997) | High | User.Read | User.ReadWrite.All, TermStore.Read.All, User.Read.All, Sites.FullControl.All | Pora | 2025-09-09 | \n| ✅ | [Postman](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/Overview/objectId/aa64efdb-2d05-4c81-a9e5-80294bf0afac/appId/7fb37b38-ce4f-4675-9263-0cd3404b4925) | High | Policy.Read.All, User.Read, Directory.ReadWrite.All, Mail.ReadWrite | Mail.ReadWrite, Directory.ReadWrite.All | Pora | 2025-09-09 | \n| ✅ | [SharePoint Version App](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/Overview/objectId/666a58ef-c3e5-4efc-828a-2ab3c0120677/appId/2bb68591-782c-4c64-9415-bdf9414ae400) | High | User.Read | Sites.Read.All, Sites.Read.All | Pora | 2025-09-09 | \n| ✅ | [Trello](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/Overview/objectId/3d6c91cf-d48f-4272-ac4c-9f989bbec779/appId/d77611ee-5051-4383-9af3-5ba3627306a7) | High | | Application.Read.All | Pora Inc. | 2025-09-09 | \n| ✅ | [testuserread](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/Overview/objectId/89bd9c7a-0c81-4a0a-9153-ff7cd0b81352/appId/9fe2675c-7fc5-4895-8470-eed989ea0d63) | High | | GroupMember.Read.All, User.Read.All | Pora | 2025-09-09 | \n| ✅ | [My Doc Gen](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/Overview/objectId/a445d652-f72d-4a88-9493-79d3c3c23d1b/appId/e580347d-d0aa-4aa1-9113-5daa0bb1c805) | High | User.Read, openid, profile, offline_access, Directory.Read.All, Policy.Read.All, Agreement.Read.All, CrossTenantInformation.ReadBasic.All | | Pora | 2025-09-09 | \n| ✅ | [MyZt](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/Overview/objectId/716038b1-2811-40fc-8622-93e093890af0/appId/eee51d92-0bb5-4467-be6a-8f24ef677e4d) | High | Agreement.Read.All, CrossTenantInformation.ReadBasic.All, Directory.Read.All, Policy.Read.All, User.Read, DeviceManagementServiceConfig.Read.All, DeviceManagementConfiguration.Read.All, DeviceManagementRBAC.Read.All, DeviceManagementApps.Read.All, RoleAssignmentSchedule.Read.Directory, RoleEligibilitySchedule.Read.Directory, PrivilegedEligibilitySchedule.Read.AzureADGroup, openid, profile, offline_access | | Pora | 2025-09-09 | \n| ✅ | [MyZtA\\[\\[](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/Overview/objectId/d2a2a09d-7562-45fc-a950-36fedfb790f8/appId/d159fcf5-a613-435b-8195-8add3cdf4bff) | High | RoleAssignmentSchedule.Read.Directory, RoleEligibilitySchedule.Read.Directory, Policy.Read.All, Agreement.Read.All, DeviceManagementConfiguration.Read.All, DeviceManagementApps.Read.All, DeviceManagementRBAC.Read.All, DeviceManagementServiceConfig.Read.All, User.Read, Directory.Read.All, PrivilegedEligibilitySchedule.Read.AzureADGroup, CrossTenantInformation.ReadBasic.All | | Pora | 2025-09-09 | \n| ✅ | [Maester DevOps Account](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/Overview/objectId/d54232da-de3b-4874-aef2-5203dbd7342a/appId/d99dd249-6ab3-4e92-be40-81af11658359) | High | User.Read | DirectoryRecommendations.Read.All, PrivilegedAccess.Read.AzureAD, Reports.Read.All, Mail.Send, Directory.Read.All, IdentityRiskEvent.Read.All, Policy.Read.All | Pora | 2025-09-09 | \n| ✅ | [Graph PS - Zero Trust Workshop](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/Overview/objectId/f6e8dfdd-4c84-441f-ae6e-f2f51fd20699/appId/a9632ced-c276-4c2b-9288-3a34b755eaa9) | High | AuditLog.Read.All, CrossTenantInformation.ReadBasic.All, Directory.Read.All, DirectoryRecommendations.Read.All, IdentityRiskEvent.Read.All, Policy.Read.All, Policy.Read.ConditionalAccess, PrivilegedAccess.Read.AzureAD, Reports.Read.All, RoleEligibilitySchedule.Read.Directory, RoleEligibilitySchedule.ReadWrite.Directory, RoleManagement.Read.All, UserAuthenticationMethod.Read.All, openid, profile, offline_access | | Pora | 2025-09-09 | \n| ✅ | [Maester DevOps Account - GitHub](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/Overview/objectId/ce3af345-b0e0-4b15-808c-937d825bcf03/appId/f050a85f-390b-4d43-85a0-2196b706bfd6) | High | | Policy.Read.ConditionalAccess, Directory.Read.All, IdentityRiskEvent.Read.All, Policy.Read.All, DirectoryRecommendations.Read.All, Reports.Read.All, PrivilegedAccess.Read.AzureAD, DeviceManagementConfiguration.Read.All, SharePointTenantSettings.Read.All, UserAuthenticationMethod.Read.All, Mail.Send, DeviceManagementManagedDevices.Read.All, RoleEligibilitySchedule.Read.Directory, RoleManagement.Read.All | Entra.Chat | 2025-09-09 | \n| ✅ | [Maester DevOps Account - New GitHub Action](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/Overview/objectId/7c1885fd-fdf8-413a-86a6-f8867914272f/appId/143cb1b1-81af-4999-a292-a8c537601119) | High | User.Read | Policy.Read.ConditionalAccess, Directory.Read.All, IdentityRiskEvent.Read.All, Policy.Read.All, DeviceManagementManagedDevices.Read.All, RoleEligibilitySchedule.Read.Directory, RoleEligibilitySchedule.ReadWrite.Directory, RoleManagement.Read.All, DeviceManagementConfiguration.Read.All, SharePointTenantSettings.Read.All, UserAuthenticationMethod.Read.All, DirectoryRecommendations.Read.All, Reports.Read.All, PrivilegedAccess.Read.AzureAD | Pora Inc. | 2025-09-09 | \n| ✅ | [Maester Automation App](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/Overview/objectId/e3972142-1d36-4e7d-a777-ecd64619fcab/appId/55635484-743e-42e2-a78e-6bc15050ebde) | High | User.Read | Policy.Read.ConditionalAccess, Mail.Send, Directory.Read.All, IdentityRiskEvent.Read.All, Policy.Read.All, DeviceManagementManagedDevices.Read.All, RoleEligibilitySchedule.Read.Directory, RoleEligibilitySchedule.ReadWrite.Directory, RoleManagement.Read.All, DeviceManagementConfiguration.Read.All, SharePointTenantSettings.Read.All, UserAuthenticationMethod.Read.All, DirectoryRecommendations.Read.All, Reports.Read.All, PrivilegedAccess.Read.AzureAD | Pora Inc. | 2025-09-09 | \n| ✅ | [contoso-tenant-devops-7576c63d-bc90-4ae4-9f1c-0d959fb520db](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/Overview/objectId/c5632968-35cd-445d-926e-16e0afc9160e/appId/e876f7cb-13f3-48a4-8329-66d7b1fa33fb) | High | | Directory.ReadWrite.All, Policy.ReadWrite.Authorization, Policy.ReadWrite.DeviceConfiguration | Pora Inc. | 2025-10-01 | \n| ✅ | [contoso-Maester-54d3ea01-5a07-45d0-8d69-e5f5b0b20098](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/Overview/objectId/4faa0456-5ecb-49f3-bb9a-2dbe516e939a/appId/a8c184ae-8ddf-41f3-8881-c090b43c385f) | High | | DirectoryRecommendations.Read.All, Reports.Read.All, Directory.Read.All, Policy.Read.All, Mail.Send | Pora | 2025-11-01 | \n| ✅ | [contoso-maester-demo-39ecb2b6-d900-496e-886f-d112cca4f1a9](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/Overview/objectId/cc578aea-b1bd-434d-86d2-8a22c5728ded/appId/efec213e-0a85-4d7a-938f-3d97edd4ade0) | High | | DirectoryRecommendations.Read.All, Reports.Read.All, ThreatHunting.Read.All, PrivilegedAccess.Read.AzureAD, ReportSettings.Read.All, Directory.Read.All, IdentityRiskEvent.Read.All, Policy.Read.All, Policy.Read.ConditionalAccess, DeviceManagementManagedDevices.Read.All, RoleEligibilitySchedule.Read.Directory, RoleManagement.Read.All, SecurityIdentitiesSensors.Read.All, DeviceManagementConfiguration.Read.All, SharePointTenantSettings.Read.All, UserAuthenticationMethod.Read.All, SecurityIdentitiesHealth.Read.All | Pora Inc. | 2025-11-01 | \n| ✅ | [MyVscode](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/Overview/objectId/dfc83a5d-36e5-4506-ae9d-6ad5bb403377/appId/92abdce1-3952-4a8b-8720-e59257edd421) | Unranked | MCP.AccessReview.Read.All, MCP.AdministrativeUnit.Read.All, MCP.Application.Read.All, MCP.AuditLog.Read.All, MCP.AuthenticationContext.Read.All, MCP.Device.Read.All, MCP.DirectoryRecommendations.Read.All, MCP.Domain.Read.All, MCP.EntitlementManagement.Read.All, MCP.GroupMember.Read.All, MCP.HealthMonitoringAlert.Read.All, MCP.IdentityRiskEvent.Read.All, MCP.IdentityRiskyServicePrincipal.Read.All, MCP.IdentityRiskyUser.Read.All, MCP.LicenseAssignment.Read.All, MCP.LifecycleWorkflows-CustomExt.Read.All, MCP.LifecycleWorkflows-Reports.Read.All, MCP.LifecycleWorkflows-Workflow.Read.All, MCP.LifecycleWorkflows-Workflow.ReadBasic.All, MCP.LifecycleWorkflows.Read.All, MCP.NetworkAccess-Reports.Read.All, MCP.NetworkAccess.Read.All, MCP.Organization.Read.All, MCP.Policy.Read.All, MCP.Policy.Read.ConditionalAccess, MCP.ProvisioningLog.Read.All, MCP.Reports.Read.All, MCP.RoleAssignmentSchedule.Read.Directory, MCP.RoleEligibilitySchedule.Read.Directory, MCP.RoleManagement.Read.Directory, MCP.Synchronization.Read.All, MCP.User.Read.All, MCP.UserAuthenticationMethod.Read.All | | Pora Inc. | 2025-11-15 | \n| ✅ | [Agent Identity Blueprint Example 4208296](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/Overview/objectId/c845b130-ce1b-4124-96ca-465df0eaa10f/appId/d0e3212f-58a2-4511-8b56-bd57b023106d) | High | User.Read, Mail.Read, Calendars.Read | AgentIdUser.ReadWrite.IdentityParentedBy | Pora Inc. | 2025-11-18 | \n| ✅ | [Agent Identity Blueprint Example 4209295](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/Overview/objectId/20aaa39b-821d-40a5-8d8a-eff27f86bb4a/appId/f522f080-5192-4665-87a4-e1211b7adca6) | High | User.Read, Files.Read | AgentIdUser.ReadWrite.IdentityParentedBy | Pora Inc. | 2025-11-18 | \n| ✅ | [testSP](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/Overview/objectId/2361fd8a-fe89-4d07-9199-c117feb52b5e/appId/e47d8f25-5327-40f8-99fe-d832b99d938d) | High | | CrossTenantInformation.ReadBasic.All, Policy.Read.ConditionalAccess, DeviceManagementRBAC.Read.All, Policy.Read.PermissionGrant, IdentityRiskyUser.Read.All, DeviceManagementServiceConfig.Read.All, DirectoryRecommendations.Read.All, PrivilegedAccess.Read.AzureAD, EntitlementManagement.Read.All, NetworkAccess-Reports.Read.All, Directory.Read.All, IdentityRiskEvent.Read.All, LifecycleWorkflows-Reports.Read.All, NetworkAccessPolicy.Read.All, DeviceManagementManagedDevices.Read.All, RoleManagement.Read.All, AuditLog.Read.All, DeviceManagementConfiguration.Read.All, InformationProtectionPolicy.Read.All, UserAuthenticationMethod.Read.All | Pora Inc. | 2025-11-27 | \n| ✅ | [idPowerToys](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/Overview/objectId/ad36b6e2-273d-4652-a505-8481f096e513/appId/6ce0484b-2ae6-4458-b2b9-b3369f42fd6f) | High | Agreement.Read.All, CrossTenantInformation.ReadBasic.All, Directory.Read.All, Policy.Read.All, User.Read, openid, profile, offline_access | | Manson | 2025-12-02 | \n| ✅ | [Zero Trust Assessment](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/Overview/objectId/3dde25cc-223f-4a16-8e8f-6695940b9680/appId/e7dfcbb6-fe86-44a2-b512-8d361dcc3d30) | High | Agreement.Read.All, CrossTenantInformation.ReadBasic.All, Directory.Read.All, Policy.Read.All, User.Read, DeviceManagementServiceConfig.Read.All, DeviceManagementConfiguration.Read.All, DeviceManagementRBAC.Read.All, DeviceManagementApps.Read.All, RoleAssignmentSchedule.Read.Directory, RoleEligibilitySchedule.Read.Directory, PrivilegedEligibilitySchedule.Read.AzureADGroup, openid, profile, offline_access | | Pora | 2026-03-07 | \n| ✅ | [ZT-PermissionTest](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/Overview/objectId/b264ce7f-a584-49bf-8dd4-d2a3971e97b9/appId/be667b5a-b863-4698-9f60-868ef968b857) | High | User.Read, AuditLog.Read.All, DeviceManagementConfiguration.Read.All, CrossTenantInformation.ReadBasic.All, Policy.Read.All, DeviceManagementApps.Read.All, Directory.Read.All, Reports.Read.All, DeviceManagementRBAC.Read.All, IdentityRiskyServicePrincipal.Read.All, DeviceManagementManagedDevices.Read.All, offline_access, DeviceManagementServiceConfig.Read.All, Policy.Read.ConditionalAccess, DirectoryRecommendations.Read.All, EntitlementManagement.Read.All, IdentityRiskEvent.Read.All, IdentityRiskyUser.Read.All, Policy.Read.PermissionGrant, NetworkAccess.Read.All, PrivilegedAccess.Read.AzureAD, RoleManagement.Read.All, UserAuthenticationMethod.Read.All, openid, profile | | Pora Inc. | 2026-03-13 | \n| ✅ | [ZeroTrustTest](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/Overview/objectId/d07c6af4-09f7-403f-bdeb-fb6be0d5e9fe/appId/3835a2fc-573d-4c4b-a4a3-993a1a156607) | High | User.Read, AuditLog.Read.All, DeviceManagementConfiguration.Read.All, CrossTenantInformation.ReadBasic.All, Policy.Read.All, CustomSecAttributeAssignment.Read.All, DirectoryRecommendations.Read.All, Policy.Read.ConditionalAccess, DeviceManagementApps.Read.All, DeviceManagementRBAC.Read.All, IdentityRiskyServicePrincipal.Read.All, DeviceManagementManagedDevices.Read.All, offline_access, DeviceManagementServiceConfig.Read.All, Reports.Read.All, Directory.Read.All, EntitlementManagement.Read.All, IdentityRiskEvent.Read.All, IdentityRiskyUser.Read.All, Policy.Read.PermissionGrant, NetworkAccess.Read.All, PrivilegedAccess.Read.AzureAD, RoleManagement.Read.All, UserAuthenticationMethod.Read.All, openid, profile | DeviceManagementManagedDevices.Read.All, RoleManagement.Read.All, IdentityRiskyUser.Read.All, Content.SuperUser, EntitlementManagement.Read.All, Content.DelegatedWriter, DeviceManagementServiceConfig.Read.All, DirectoryRecommendations.Read.All, PrivilegedAccess.Read.AzureAD, CrossTenantInformation.ReadBasic.All, CustomSecAttributeAssignment.Read.All, Policy.Read.ConditionalAccess, Directory.Read.All, IdentityRiskEvent.Read.All, DeviceManagementRBAC.Read.All, Policy.Read.PermissionGrant, AuditLog.Read.All, DeviceManagementConfiguration.Read.All, IdentityRiskyServicePrincipal.Read.All, UserAuthenticationMethod.Read.All | Pora Inc. | 2026-04-16 | \n| ✅ | [test](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/Overview/objectId/35cbeecb-be21-4596-9869-0157d84f2d67/appId/c823a25d-fe94-494c-91f6-c7d51bf2df82) | High | User.Read | Sites.FullControl.All | Pora | 2026-04-30 | \n| ✅ | [Custom-App-Test](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/Overview/objectId/38415a71-b77b-44d5-a276-539faabe0de7/appId/ddb4f0e6-8018-4359-96c1-7473704bde43) | High | User.Read | DeviceManagementServiceConfig.Read.All, DirectoryRecommendations.Read.All, PrivilegedAccess.Read.AzureAD, CrossTenantInformation.ReadBasic.All, CustomSecAttributeAssignment.Read.All, Policy.Read.ConditionalAccess, EntitlementManagement.Read.All, DeviceManagementManagedDevices.Read.All, RoleManagement.Read.All, Directory.Read.All, IdentityRiskEvent.Read.All, Policy.Read.All, DeviceManagementRBAC.Read.All, Policy.Read.PermissionGrant, AuditLog.Read.All, DeviceManagementConfiguration.Read.All, IdentityRiskyServicePrincipal.Read.All, UserAuthenticationMethod.Read.All, IdentityRiskyUser.Read.All, Application.Read.All | Pora Inc. | 2026-05-14 | \n| ✅ | [Maester DevOps Account](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/Overview/objectId/7c32eaee-ff26-4435-be3d-b4ced08f9edc/appId/303774c1-3c6f-4dfd-8505-f24e82f9212a) | High | User.Read | RoleEligibilitySchedule.Read.Directory, RoleEligibilitySchedule.ReadWrite.Directory, RoleManagement.Read.All, DirectoryRecommendations.Read.All, Reports.Read.All, PrivilegedAccess.Read.AzureAD, SharePointTenantSettings.Read.All, UserAuthenticationMethod.Read.All, Policy.Read.ConditionalAccess, Directory.Read.All, IdentityRiskEvent.Read.All, Policy.Read.All | Pora | 2026-05-17 | \n| ✅ | [entra-docs-email github DO NOT DELETE](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/Overview/objectId/7a94aec7-a5e3-48dd-b20f-3db74d689434/appId/ae06b71a-a0aa-4211-b846-fd74f25ccd45) | High | User.Read | Mail.Send | Pora Inc. | 2026-05-17 | \n| ✅ | [Maester DevOps Account - manson/maester-demo](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/Overview/objectId/fdce906b-d2f6-4738-8c76-e4559b9e17e8/appId/91c84d77-3dce-4fb0-b0de-474a8606c812) | High | | Policy.Read.ConditionalAccess, ReportSettings.Read.All, SecurityIdentitiesHealth.Read.All, DirectoryRecommendations.Read.All, Reports.Read.All, ThreatHunting.Read.All, PrivilegedAccess.Read.AzureAD, DeviceManagementConfiguration.Read.All, SharePointTenantSettings.Read.All, UserAuthenticationMethod.Read.All, DeviceManagementManagedDevices.Read.All, RoleEligibilitySchedule.Read.Directory, RoleManagement.Read.All, SecurityIdentitiesSensors.Read.All, Directory.Read.All, IdentityRiskEvent.Read.All, Policy.Read.All | Pora Inc. | 2026-05-17 | \n| ✅ | [GitHub Actions App for Microsoft Info script](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/Overview/objectId/852b4218-67d2-4046-a9a6-f8b47430ccdf/appId/38535360-9f3e-4b1e-a41e-b4af46afcb0c) | High | | Application.Read.All | Pora | 2026-05-18 | \n| ✅ | [GraphPermissionApp](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/Overview/objectId/a15dc834-08ce-4fd8-85de-3729fff8e34f/appId/d36fe320-bc28-40c8-a141-a512d65d112c) | High | User.Read | Application.Read.All | Pora Inc. | 2026-05-18 | \n| ✅ | [MessageCenterAccount github.com/manson/mc DO NOT DELETE](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/Overview/objectId/427b14ca-13b3-4911-b67e-9ff626614781/appId/778fad36-e4c1-4d40-a58e-9b5b64179d41) | Unranked | | ServiceMessage.Read.All | Entra.Chat | 2026-05-18 | \n| ✅ | [custommcp](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/Overview/objectId/fba0c411-7019-4c32-bec4-2f281824b698/appId/aca7e359-22cf-4d86-9338-6d6051245755) | Unranked | MCP.AccessReview.Read.All, MCP.AdministrativeUnit.Read.All, MCP.Application.Read.All, MCP.AuditLog.Read.All, MCP.AuthenticationContext.Read.All, MCP.Device.Read.All, MCP.DirectoryRecommendations.Read.All, MCP.Domain.Read.All, MCP.EntitlementManagement.Read.All, MCP.GroupMember.Read.All, MCP.HealthMonitoringAlert.Read.All, MCP.IdentityRiskEvent.Read.All, MCP.IdentityRiskyServicePrincipal.Read.All, MCP.IdentityRiskyUser.Read.All, MCP.LicenseAssignment.Read.All, MCP.LifecycleWorkflows-CustomExt.Read.All, MCP.LifecycleWorkflows-Reports.Read.All, MCP.LifecycleWorkflows-Workflow.Read.All, MCP.LifecycleWorkflows-Workflow.ReadBasic.All, MCP.LifecycleWorkflows.Read.All, MCP.NetworkAccess-Reports.Read.All, MCP.NetworkAccess.Read.All, MCP.Organization.Read.All, MCP.Policy.Read.All, MCP.Policy.Read.ConditionalAccess, MCP.ProvisioningLog.Read.All, MCP.Reports.Read.All, MCP.RoleAssignmentSchedule.Read.Directory, MCP.RoleEligibilitySchedule.Read.Directory, MCP.RoleManagement.Read.Directory, MCP.Synchronization.Read.All, MCP.UserAuthenticationMethod.Read.All | | Pora Inc. | Unknown | \n| ✅ | [ChatGPT](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/Overview/objectId/ede526ec-83dd-4e66-8ed0-98e05dca5454/appId/e0476654-c1d5-430b-ab80-70cbd947616a) | Unranked | MCP.AccessReview.Read.All, MCP.AdministrativeUnit.Read.All, MCP.Application.Read.All, MCP.AuditLog.Read.All, MCP.AuthenticationContext.Read.All, MCP.Device.Read.All, MCP.DirectoryRecommendations.Read.All, MCP.Domain.Read.All, MCP.EntitlementManagement.Read.All, MCP.GroupMember.Read.All, MCP.HealthMonitoringAlert.Read.All, MCP.IdentityRiskEvent.Read.All, MCP.IdentityRiskyServicePrincipal.Read.All, MCP.IdentityRiskyUser.Read.All, MCP.LicenseAssignment.Read.All, MCP.LifecycleWorkflows-CustomExt.Read.All, MCP.LifecycleWorkflows-Reports.Read.All, MCP.LifecycleWorkflows-Workflow.Read.All, MCP.LifecycleWorkflows-Workflow.ReadBasic.All, MCP.LifecycleWorkflows.Read.All, MCP.NetworkAccess-Reports.Read.All, MCP.NetworkAccess.Read.All, MCP.Organization.Read.All, MCP.Policy.Read.All, MCP.Policy.Read.ConditionalAccess, MCP.ProvisioningLog.Read.All, MCP.Reports.Read.All, MCP.RoleAssignmentSchedule.Read.Directory, MCP.RoleEligibilitySchedule.Read.Directory, MCP.RoleManagement.Read.Directory, MCP.Synchronization.Read.All, MCP.User.Read.All, MCP.UserAuthenticationMethod.Read.All | | OpenAI | Unknown | \n| ✅ | [TestMcPClient](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/Overview/objectId/cf30c6da-890f-4e66-b353-06adbae9933f/appId/55c372a3-9a33-42bb-ac50-7f49224fee47) | Unranked | MCP.AccessReview.Read.All, MCP.AdministrativeUnit.Read.All, MCP.Application.Read.All, MCP.AuditLog.Read.All, MCP.AuthenticationContext.Read.All, MCP.Device.Read.All, MCP.DirectoryRecommendations.Read.All, MCP.Domain.Read.All, MCP.EntitlementManagement.Read.All, MCP.GroupMember.Read.All, MCP.HealthMonitoringAlert.Read.All, MCP.IdentityRiskEvent.Read.All, MCP.IdentityRiskyServicePrincipal.Read.All, MCP.IdentityRiskyUser.Read.All, MCP.LicenseAssignment.Read.All, MCP.LifecycleWorkflows-CustomExt.Read.All, MCP.LifecycleWorkflows-Reports.Read.All, MCP.LifecycleWorkflows-Workflow.Read.All, MCP.LifecycleWorkflows-Workflow.ReadBasic.All, MCP.LifecycleWorkflows.Read.All, MCP.NetworkAccess-Reports.Read.All, MCP.NetworkAccess.Read.All, MCP.Organization.Read.All, MCP.Policy.Read.All, MCP.Policy.Read.ConditionalAccess, MCP.ProvisioningLog.Read.All, MCP.Reports.Read.All, MCP.RoleAssignmentSchedule.Read.Directory, MCP.RoleEligibilitySchedule.Read.Directory, MCP.RoleManagement.Read.Directory, MCP.Synchronization.Read.All, MCP.User.Read.All, MCP.UserAuthenticationMethod.Read.All | | Pora Inc. | Unknown | \n| ✅ | [MyTestMcPClient](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/Overview/objectId/84fbf039-0d23-41d0-b58b-f7a7b76a0486/appId/b6e43d0e-e33f-4223-bae4-144e5974ec3b) | Unranked | MCP.AccessReview.Read.All, MCP.AdministrativeUnit.Read.All, MCP.Application.Read.All, MCP.AuditLog.Read.All, MCP.AuthenticationContext.Read.All, MCP.Device.Read.All, MCP.DirectoryRecommendations.Read.All, MCP.Domain.Read.All, MCP.EntitlementManagement.Read.All, MCP.GroupMember.Read.All, MCP.HealthMonitoringAlert.Read.All, MCP.IdentityRiskEvent.Read.All, MCP.IdentityRiskyServicePrincipal.Read.All, MCP.IdentityRiskyUser.Read.All, MCP.LicenseAssignment.Read.All, MCP.LifecycleWorkflows-CustomExt.Read.All, MCP.LifecycleWorkflows-Reports.Read.All, MCP.LifecycleWorkflows-Workflow.Read.All, MCP.LifecycleWorkflows-Workflow.ReadBasic.All, MCP.LifecycleWorkflows.Read.All, MCP.NetworkAccess-Reports.Read.All, MCP.NetworkAccess.Read.All, MCP.Organization.Read.All, MCP.Policy.Read.All, MCP.Policy.Read.ConditionalAccess, MCP.ProvisioningLog.Read.All, MCP.Reports.Read.All, MCP.RoleAssignmentSchedule.Read.Directory, MCP.RoleEligibilitySchedule.Read.Directory, MCP.RoleManagement.Read.Directory, MCP.Synchronization.Read.All, MCP.User.Read.All, MCP.UserAuthenticationMethod.Read.All | | Pora Inc. | Unknown | \n| ✅ | [M365 MCP Client for Claude](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/Overview/objectId/73f345ba-56fb-4d92-b2f6-2fe168131092/appId/08ad6f98-a4f8-4635-bb8d-f1a3044760f0) | Unranked | MCP.AdministrativeUnit.Read.All, MCP.Application.Read.All, MCP.AuditLog.Read.All, MCP.AuthenticationContext.Read.All, MCP.Device.Read.All, MCP.DirectoryRecommendations.Read.All, MCP.Domain.Read.All, MCP.EntitlementManagement.Read.All, MCP.GroupMember.Read.All, MCP.HealthMonitoringAlert.Read.All, MCP.IdentityRiskEvent.Read.All, MCP.IdentityRiskyServicePrincipal.Read.All, MCP.IdentityRiskyUser.Read.All, MCP.LicenseAssignment.Read.All, MCP.LifecycleWorkflows-CustomExt.Read.All, MCP.LifecycleWorkflows-Reports.Read.All, MCP.LifecycleWorkflows-Workflow.Read.All, MCP.LifecycleWorkflows-Workflow.ReadBasic.All, MCP.LifecycleWorkflows.Read.All, MCP.NetworkAccess-Reports.Read.All, MCP.NetworkAccess.Read.All, MCP.Organization.Read.All, MCP.Policy.Read.All, MCP.Policy.Read.ConditionalAccess, MCP.ProvisioningLog.Read.All, MCP.Reports.Read.All, MCP.RoleAssignmentSchedule.Read.Directory, MCP.RoleEligibilitySchedule.Read.Directory, MCP.RoleManagement.Read.Directory, MCP.Synchronization.Read.All, MCP.User.Read.All, MCP.UserAuthenticationMethod.Read.All | | Anthropic | Unknown | \n| ✅ | [MyVisualStudioMcpClient](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/Overview/objectId/cae606b7-4a44-4d07-a7a5-a6fb285e41f1/appId/84ad8697-445d-4b26-affd-1b1459e97aae) | Unranked | MCP.AccessReview.Read.All, MCP.AdministrativeUnit.Read.All, MCP.Application.Read.All, MCP.AuditLog.Read.All, MCP.AuthenticationContext.Read.All, MCP.Device.Read.All, MCP.DirectoryRecommendations.Read.All, MCP.Domain.Read.All, MCP.EntitlementManagement.Read.All, MCP.GroupMember.Read.All, MCP.HealthMonitoringAlert.Read.All, MCP.IdentityRiskEvent.Read.All, MCP.IdentityRiskyServicePrincipal.Read.All, MCP.IdentityRiskyUser.Read.All, MCP.LicenseAssignment.Read.All, MCP.LifecycleWorkflows-CustomExt.Read.All, MCP.LifecycleWorkflows-Reports.Read.All, MCP.LifecycleWorkflows-Workflow.Read.All, MCP.LifecycleWorkflows-Workflow.ReadBasic.All, MCP.LifecycleWorkflows.Read.All, MCP.NetworkAccess-Reports.Read.All, MCP.NetworkAccess.Read.All, MCP.Organization.Read.All, MCP.Policy.Read.All, MCP.Policy.Read.ConditionalAccess, MCP.ProvisioningLog.Read.All, MCP.Reports.Read.All, MCP.RoleAssignmentSchedule.Read.Directory, MCP.RoleEligibilitySchedule.Read.Directory, MCP.RoleManagement.Read.Directory, MCP.Synchronization.Read.All, MCP.User.Read.All, MCP.UserAuthenticationMethod.Read.All | | Pora Inc. | Unknown | \n\n\n","TestStatus":"Failed","TestTags":null},{"TestImplementationCost":"Low","TestPillar":"Devices","TestCategory":"Tenant","SkippedReason":null,"TestImpact":"Medium","TestAppliesTo":null,"TestSfiPillar":"Protect tenants and isolate production systems","TestSkipped":"","TestMinimumLicense":"Intune","TestTags":null,"TestTitle":"Compliance policy assignment for iOS/iPadOS devices","TestRisk":"High","TestResult":"\nAt least one compliance policy for iOS/iPadOS exists and is assigned.\n\n\n## iOS/iPadOS Compliance Policies\n\n| Policy Name | Status | Assignment Target |\n| :---------- | :----- | :---------------- |\n| [My iOS policy](https://intune.microsoft.com/#view/Microsoft_Intune_DeviceSettings/DevicesMenu/~/compliance) | ✅ Assigned | **Included:** All Devices, All Users, **Excluded:** aad-conditional-access-excluded |\n\n\n\n","TestStatus":"Passed","TestDescription":"If compliance policies aren't assigned to iOS/iPadOS devices in Intune, threat actors can exploit noncompliant endpoints to gain unauthorized access to corporate resources, bypass security controls, and persist in the environment. Without enforced compliance, devices can lack critical security configurations like passcode requirements and OS version controls. These gaps increase the risk of data leakage, privilege escalation, and lateral movement. Inconsistent device compliance weakens the organization’s security posture and makes it harder to detect and remediate threats before significant damage occurs.\n\nEnforcing compliance policies ensures iOS/iPadOS devices meet core security requirements and supports Zero Trust by validating device health and reducing exposure to misconfigured or unmanaged endpoints.\n\n**Remediation action**\n\nCreate and assign Intune compliance policies to iOS/iPadOS devices to enforce organizational standards for secure access and management: \n- [Create a compliance policy in Microsoft Intune](https://learn.microsoft.com/intune/intune-service/protect/create-compliance-policy?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci#create-the-policy)\n- [Review the iOS/iPadOS compliance settings you can manage with Intune](https://learn.microsoft.com/intune/intune-service/protect/compliance-policy-create-ios?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci)\n","TestId":"24543"},{"TestImplementationCost":"Medium","TestPillar":"Network","TestCategory":"Global Secure Access","SkippedReason":null,"TestImpact":"Medium","TestAppliesTo":null,"TestSfiPillar":"Protect networks","TestSkipped":"","TestMinimumLicense":"P1","TestTags":null,"TestTitle":"Intelligent Local Access is enabled and configured","TestRisk":"Medium","TestResult":"\n✅ At least one private network is configured in your tenant.\n\n\n## Private Networks\n\nFound 1 private network(s) configured for Intelligent Local Access.\n\n| Network name | Id |\n| :--- | :--- |\n| [Test PN](https://entra.microsoft.com/#view/Microsoft_Azure_Network_Access/PrivateNetworks.ReactView) | 93060521-eab5-48e0-be22-30ce7aa0fd4f |\n\n\n\n","TestStatus":"Passed","TestDescription":"Intelligent Local Access (ILA) routes Microsoft Entra Private Access traffic locally instead of through the cloud, improving performance while maintaining policy enforcement. Without ILA, users might disable the Global Secure Access client to improve performance and bypass Conditional Access policies. Configure private networks for your user sites to ensure local routing while preserving security controls.\n\n**Remediation action**\n\n- [Enable Intelligent Local Network](https://learn.microsoft.com/entra/global-secure-access/enable-intelligent-local-access?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci)\n","TestId":"25405"},{"TestImplementationCost":"Medium","TestPillar":"Devices","TestCategory":"Device","SkippedReason":null,"TestImpact":"Low","TestAppliesTo":null,"TestSfiPillar":"Protect networks","TestSkipped":"","TestMinimumLicense":"Intune","TestTags":null,"TestTitle":"A Windows Defender Antivirus policy is created and assigned","TestRisk":"High","TestResult":"\nNo relevant Windows Defender Antivirus policies are configured or assigned.\n\n\n\n","TestStatus":"Failed","TestDescription":"If policies for Microsoft Defender Antivirus aren't properly configured and assigned in Intune, threat actors can exploit unprotected endpoints to execute malware, disable antivirus protections, and persist within the environment. Without enforced antivirus policies, devices operate with outdated definitions, disabled real-time protection, or misconfigured scan schedules. These gaps allow attackers to bypass detection, escalate privileges, and move laterally across the network. The absence of antivirus enforcement undermines device compliance, increases exposure to zero-day threats, and can result in regulatory noncompliance. Attackers leverage these weaknesses to maintain persistence and evade detection, especially in environments lacking centralized policy enforcement.\n\nEnforcing Defender Antivirus policies ensures consistent protection against malware, supports real-time threat detection, and aligns with Zero Trust by maintaining a secure and compliant endpoint posture.\n\n**Remediation action**\n\nConfigure and assign Intune policies for Microsoft Defender Antivirus to enforce real-time protection, maintain up-to-date definitions, and reduce exposure to malware:\n\n- [Configure Intune policies to manage Microsoft Defender Antivirus](https://learn.microsoft.com/intune/intune-service/protect/endpoint-security-antivirus-policy?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci#windows)\n- [Assign policies in Intune](https://learn.microsoft.com/intune/intune-service/configuration/device-profile-assign?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci#assign-a-policy-to-users-or-groups)\n","TestId":"24575"},{"TestImplementationCost":"Low","TestPillar":"Identity","TestCategory":"Privileged access","SkippedReason":null,"TestImpact":"Medium","TestAppliesTo":["Identity"],"TestSfiPillar":"Protect identities and secrets","TestSkipped":"","TestMinimumLicense":"Free","TestTags":["PrivilegedIdentity"],"TestTitle":"Privileged accounts are cloud native identities","TestRisk":"Medium","TestResult":"\nThis tenant has 3 privileged users that are synced from on-premises.\n\n## Privileged roles\n\n| Role name | User | Source | Status |\n| :--- | :--- | :--- | :---: |\n| Agent ID Administrator | [Sage Bennett](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/AdministrativeRole/userId/518ce209-faf4-4717-add9-7129a669fa11) | Cloud native identity | ✅ |\n| AI Administrator | [Jordan Smith](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/AdministrativeRole/userId/bfaeba1e-1357-47de-9557-529caa103d5d) | Cloud native identity | ✅ |\n| Application Administrator | [Skylar White](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/AdministrativeRole/userId/2a054082-8f05-4e05-8fce-4e35c3bb40cc) | Cloud native identity | ✅ |\n| Application Administrator | [Riley Martinez](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/AdministrativeRole/userId/653c7fdd-1b41-4229-992a-69cc35aad4f7) | Cloud native identity | ✅ |\n| Application Administrator | [Sam Parker](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/AdministrativeRole/userId/96d29f01-873c-46a3-b542-f7ee192cc675) | Cloud native identity | ✅ |\n| Application Administrator | [Jordan Smith](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/AdministrativeRole/userId/bfaeba1e-1357-47de-9557-529caa103d5d) | Cloud native identity | ✅ |\n| Application Administrator | [Drew Mitchell](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/AdministrativeRole/userId/df02402a-e291-42cc-b449-79366daa2a40) | Cloud native identity | ✅ |\n| Application Administrator | [Alex Johnson](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/AdministrativeRole/userId/e436ca15-3a39-4dcc-819e-7dbb246cd46b) | Cloud native identity | ✅ |\n| Global Administrator | [Jules Bailey](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/AdministrativeRole/userId/0145d508-50fd-4f86-a47a-bf1c043c8358) | Synced from on-premises | ❌ |\n| Global Administrator | [Jamie Rodriguez](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/AdministrativeRole/userId/0b37813c-ae19-4399-982f-16587f17f9c0) | Cloud native identity | ✅ |\n| Global Administrator | [Ellis Cooper](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/AdministrativeRole/userId/1433571b-3d7c-4a56-a9cc-67580848bc73) | Cloud native identity | ✅ |\n| Global Administrator | [Cameron Anderson](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/AdministrativeRole/userId/1ce4078f-f795-4baf-aa55-1fdfcc2ebfe6) | Cloud native identity | ✅ |\n| Global Administrator | [Taylor Brown](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/AdministrativeRole/userId/2072badc-3cf0-4e84-b4c2-f9c065c46165) | Cloud native identity | ✅ |\n| Global Administrator | [Dakota Lee](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/AdministrativeRole/userId/210d3e96-015f-462d-b6d6-81e6023263df) | Cloud native identity | ✅ |\n| Global Administrator | [Dakota Lee Test](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/AdministrativeRole/userId/43482f27-d1af-420f-84ba-e9148a700f45) | Cloud native identity | ✅ |\n| Global Administrator | [Ash Williams](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/AdministrativeRole/userId/513f3db2-044c-41be-af14-431bf88a2b3e) | Cloud native identity | ✅ |\n| Global Administrator | [Sage Bennett](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/AdministrativeRole/userId/518ce209-faf4-4717-add9-7129a669fa11) | Cloud native identity | ✅ |\n| Global Administrator | [Morgan Wilson](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/AdministrativeRole/userId/5655cf54-34bc-4f36-bb74-44da35547975) | Synced from on-premises | ❌ |\n| Global Administrator | [Charlie Lewis](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/AdministrativeRole/userId/5b0ec3ff-cea1-4eb9-8530-f2a66e5bec0a) | Cloud native identity | ✅ |\n| Global Administrator | [Phoenix Gray](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/AdministrativeRole/userId/7094fb23-003a-4f81-9796-5daeaa603003) | Cloud native identity | ✅ |\n| Global Administrator | [Peyton Clark](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/AdministrativeRole/userId/7e92f268-bb12-469a-a869-210d596d4c1f) | Cloud native identity | ✅ |\n| Global Administrator | [Finley Robinson](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/AdministrativeRole/userId/990fd38a-c516-4e3f-82e4-d458a1ab0f91) | Cloud native identity | ✅ |\n| Global Administrator | [Avery Brooks](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/AdministrativeRole/userId/a85798bd-652b-4eb9-ba90-3ee882df0179) | Cloud native identity | ✅ |\n| Global Administrator | [Reese Harris](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/AdministrativeRole/userId/babe04c9-8340-4329-a727-a8cee0cd2b1a) | Cloud native identity | ✅ |\n| Global Administrator | [Jordan Smith](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/AdministrativeRole/userId/bfaeba1e-1357-47de-9557-529caa103d5d) | Cloud native identity | ✅ |\n| Global Administrator | [Hayden Scott](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/AdministrativeRole/userId/c0b65b13-37b1-4081-bcfc-14844159b4a5) | Cloud native identity | ✅ |\n| Global Administrator | [Quinn Garcia](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/AdministrativeRole/userId/ceef37b7-c865-48fb-80c9-4def11201854) | Cloud native identity | ✅ |\n| Global Administrator | [Drew Mitchell](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/AdministrativeRole/userId/df02402a-e291-42cc-b449-79366daa2a40) | Cloud native identity | ✅ |\n| Global Administrator | [Alex Johnson](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/AdministrativeRole/userId/e436ca15-3a39-4dcc-819e-7dbb246cd46b) | Cloud native identity | ✅ |\n| Global Administrator | [Avery Thomas](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/AdministrativeRole/userId/f431700c-6d81-45b8-8f8d-581a8aa7cda6) | Cloud native identity | ✅ |\n| Global Reader | [Hayden Scott](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/AdministrativeRole/userId/0d6cfd05-fc46-440b-b605-66dd26dcd7d2) | Cloud native identity | ✅ |\n| Global Reader | [Cameron Anderson](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/AdministrativeRole/userId/1ce4078f-f795-4baf-aa55-1fdfcc2ebfe6) | Cloud native identity | ✅ |\n| Global Reader | [Sage Bennett](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/AdministrativeRole/userId/518ce209-faf4-4717-add9-7129a669fa11) | Cloud native identity | ✅ |\n| Global Reader | [Casey Davis](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/AdministrativeRole/userId/58d9ed99-93ca-4674-8c5f-ec770f5ba17d) | Synced from on-premises | ❌ |\n| Global Reader | [Hayden Scott Test](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/AdministrativeRole/userId/6f467d0a-25ec-435c-8fb9-9d53eb21e02f) | Cloud native identity | ✅ |\n| Global Reader | [Peyton Clark](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/AdministrativeRole/userId/7e92f268-bb12-469a-a869-210d596d4c1f) | Cloud native identity | ✅ |\n| Global Reader | [Finley Robinson](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/AdministrativeRole/userId/990fd38a-c516-4e3f-82e4-d458a1ab0f91) | Cloud native identity | ✅ |\n| Global Reader | [parker-test](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/AdministrativeRole/userId/c1bdb03c-0079-40b1-96a8-3595de3b94a2) | Cloud native identity | ✅ |\n| Global Reader | [ash-williams-test](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/AdministrativeRole/userId/c5c8ba63-4620-4e91-ac40-b66bebe07a0d) | Cloud native identity | ✅ |\n| Global Reader | [finley-test](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/AdministrativeRole/userId/d71ccc09-c0a3-4604-9d02-49f7a3715f49) | Cloud native identity | ✅ |\n| Global Reader | [Drew Mitchell](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/AdministrativeRole/userId/df02402a-e291-42cc-b449-79366daa2a40) | Cloud native identity | ✅ |\n| Global Reader | [peyton-test](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/AdministrativeRole/userId/e0952dcb-8d63-496d-8661-05c86c1a51f0) | Cloud native identity | ✅ |\n| Privileged Role Administrator | [Sage Bennett](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/AdministrativeRole/userId/518ce209-faf4-4717-add9-7129a669fa11) | Cloud native identity | ✅ |\n| Security Administrator | [Cameron Anderson](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/AdministrativeRole/userId/1ce4078f-f795-4baf-aa55-1fdfcc2ebfe6) | Cloud native identity | ✅ |\n| User Administrator | [Dakota Lee](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/AdministrativeRole/userId/e4bc6f4a-124f-469b-8951-3d5c34fb9741) | Cloud native identity | ✅ |\n\n\n","TestStatus":"Failed","TestDescription":"If an on-premises account is compromised and is synchronized to Microsoft Entra, the attacker might gain access to the tenant as well. This risk increases because on-premises environments typically have more attack surfaces due to older infrastructure and limited security controls. Attackers might also target the infrastructure and tools used to enable connectivity between on-premises environments and Microsoft Entra. These targets might include tools like Microsoft Entra Connect or Active Directory Federation Services, where they could impersonate or otherwise manipulate other on-premises user accounts.\n\nIf privileged cloud accounts are synchronized with on-premises accounts, an attacker who acquires credentials for on-premises can use those same credentials to access cloud resources and move laterally to the cloud environment.\n\n**Remediation action**\n\n- [Protecting Microsoft 365 from on-premises attacks](https://learn.microsoft.com/entra/architecture/protect-m365-from-on-premises-attacks?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci#specific-security-recommendations)\n\nFor each role with high privileges (assigned permanently or eligible through Microsoft Entra Privileged Identity Management), you should do the following actions:\n\n- Review the users that have onPremisesImmutableId and onPremisesSyncEnabled set. See [Microsoft Graph API user resource type](https://learn.microsoft.com/graph/api/resources/user?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci).\n- Create cloud-only user accounts for those individuals and remove their hybrid identity from privileged roles.\n","TestId":"21814"},{"TestImpact":"Low","TestRisk":"Medium","TestSkipped":"NoCompatibleLicenseFound","TestAppliesTo":null,"TestPillar":"Network","TestCategory":"Global Secure Access","TestDescription":"When Quick Access lacks user or group assignments, the service prevents connections to fully qualified domain names (FQDNs) and IP addresses that you configure in the application segments. This restriction disrupts access to internal resources like file shares, web applications, and databases. When users can't reach resources through the Global Secure Access client, they might seek alternative access methods that bypass security controls such as Conditional Access policies and multifactor authentication.\n\nIf you don't assign users to Quick Access:\n\n- Authorized users can't reach internal resources through Private Access, creating gaps in business continuity.\n- Administrators might implement temporary workarounds that weaken the organization's security posture.\n\n**Remediation action**\n\n- [Assign users and groups to Quick Access](https://learn.microsoft.com/entra/global-secure-access/how-to-configure-quick-access?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci) to enable Private Access connectivity to configured application segments.\n","TestTitle":"Quick Access has user or group assignments","SkippedReason":"This test requires one of the following licenses: (\"Entra_Premium_Private_Access\"). Please ensure your tenant has the appropriate licenses to run this test. See [Licensing & Service Plans](https://learn.microsoft.com/entra/identity/users/licensing-service-plan-reference)","TestId":"25480","TestImplementationCost":"Low","TestMinimumLicense":["Entra_Premium_Private_Access"],"TestSfiPillar":"Protect networks","TestResult":"\nSkipped. This test requires one of the following licenses: (\"Entra_Premium_Private_Access\"). Please ensure your tenant has the appropriate licenses to run this test. See [Licensing & Service Plans](https://learn.microsoft.com/entra/identity/users/licensing-service-plan-reference)\n\n","TestStatus":"Skipped","TestTags":null},{"TestImpact":"Medium","TestRisk":"Medium","TestSkipped":"","TestAppliesTo":null,"TestPillar":"Data","TestCategory":"Information Protection","TestDescription":"Setting a default label ensures a base level of protection settings for all new and edited items that support sensitivity labels, and for new containers such as Teams. Users can manually override the label if necessary, and other labeling methods such as auto-labeling can replace the default label with a label that has a higher sensitivity level. Setting a default sensitivity label extends your labeling reach and reduces decision fatigue for users, ensuring content has at least a minimum level of protection.\n\nUnlabeled content might bypass data loss prevention (DLP) policies, and other protection solutions that rely on label detection. If appropriate, set a different default sensitivity label for unlabeled documents and Loop components and pages, emails and meeting invites, new containers, and also a default label for Power BI content.\n\n**Remediation action**\n\n- [Publish sensitivity labels by creating a label policy](https://learn.microsoft.com/purview/create-sensitivity-labels?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci#publish-sensitivity-labels-by-creating-a-label-policy)\n- [Default label policy for Fabric and Power BI](https://learn.microsoft.com/fabric/governance/sensitivity-label-default-label-policy?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci)\n","TestTitle":"Default label configured for sensitivity labels","SkippedReason":null,"TestId":"35017","TestImplementationCost":"Low","TestMinimumLicense":["RMS_S_PREMIUM"],"TestSfiPillar":"Protect tenants and production systems","TestResult":"\n✅ Default labels are configured for at least one workload (Outlook, Teams/OneDrive, SharePoint/Microsoft 365 Groups, or Power BI) in at least one active sensitivity label policy.\n\n\n\n### [Enabled label policies](https://purview.microsoft.com/informationprotection/labelpolicies)\n| Policy name | Documents/Emails | Outlook | Power BI | SharePoint/Groups | Scope | Labels |\n| :--- | :--- | :--- | :--- | :--- | :--- | :--- |\n| 35035-Test-Policy | ✅ | ✅ | ❌ | ❌ | User/Group-Scoped | 1 |\n| Test Policy | ✅ | ✅ | ✅ | ❌ | User/Group-Scoped | 1 |\n| true event | ❌ | ❌ | ❌ | ❌ | Global | 1 |\n| userpolicy | ❌ | ❌ | ❌ | ❌ | User/Group-Scoped | 1 |\n| peyton | ✅ | ✅ | ✅ | ❌ | Global | 1 |\n| test-policy-35012 | ❌ | ❌ | ❌ | ❌ | Global | 1 |\n\n\n### Summary\n| Metric | Count |\n| :--- | :--- |\n| Total enabled label policies | 6 |\n| Policies with default labels | 3 |\n| Documents/Emails default | 3 |\n| Outlook default | 3 |\n| Power BI default | 2 |\n| SharePoint/Groups default | 0 |\n\n","TestStatus":"Passed","TestTags":null},{"TestImpact":"Medium","TestRisk":"High","TestSkipped":"NoCompatibleLicenseFound","TestAppliesTo":null,"TestPillar":"Network","TestCategory":"Global Secure Access","TestDescription":"When you configure Quick Access in Microsoft Entra Private Access without Conditional Access policies, threat actors who compromise user credentials gain unrestricted access to private resources. The Quick Access application serves as a container for private resources including FQDNs and IP addresses.\n\nWithout policy enforcement:\n\n- Compromised accounts provide a direct pathway to internal systems.\n- Threat actors operating from unmanaged devices or anomalous locations can access private resources indistinguishably from authorized users.\n- Lateral movement across the internal network and data exfiltration from private applications become possible.\n- Multifactor authentication requirements and device health checks can't be enforced.\n\n**Remediation action**\n\n- [Apply Conditional Access Policies to Microsoft Entra Private Access Apps](https://learn.microsoft.com/entra/global-secure-access/how-to-target-resource-private-access-apps?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci).\n","TestTitle":"Quick Access is bound to a Conditional Access policy","SkippedReason":"This test requires one of the following licenses: (\"Entra_Premium_Private_Access\"). Please ensure your tenant has the appropriate licenses to run this test. See [Licensing & Service Plans](https://learn.microsoft.com/entra/identity/users/licensing-service-plan-reference)","TestId":"25394","TestImplementationCost":"Low","TestMinimumLicense":["Entra_Premium_Private_Access"],"TestSfiPillar":"Protect networks","TestResult":"\nSkipped. This test requires one of the following licenses: (\"Entra_Premium_Private_Access\"). Please ensure your tenant has the appropriate licenses to run this test. See [Licensing & Service Plans](https://learn.microsoft.com/entra/identity/users/licensing-service-plan-reference)\n\n","TestStatus":"Skipped","TestTags":null},{"TestImplementationCost":"Medium","TestPillar":"Identity","TestCategory":"Privileged access","SkippedReason":"UnderConstruction","TestImpact":"Low","TestAppliesTo":["Identity"],"TestSfiPillar":"Protect identities and secrets","TestSkipped":"UnderConstruction","TestMinimumLicense":null,"TestTags":["Identity"],"TestTitle":"Privileged roles aren't assigned to stale identities","TestRisk":"Medium","TestResult":"\nPlanned for future release.\n\n","TestStatus":"Planned","TestDescription":"Privileged roles should not remain assigned to identities that show no recent sign-in activity. Stale accounts with administrative privileges are attractive targets for attackers because they can be compromised without triggering behavioral analytics alerts. Regularly reviewing and removing privileged role assignments from inactive identities reduces the risk of credential-based attacks and helps maintain least-privilege access.\n\n**Remediation action**\n\n- [Review privileged role assignments using access reviews](https://learn.microsoft.com/entra/id-governance/privileged-identity-management/pim-create-roles-and-resource-roles-review?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci)\n- [Remove privileged role assignments from inactive identities](https://learn.microsoft.com/entra/id-governance/privileged-identity-management/pim-resource-roles-assign-roles?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci#update-or-remove-an-existing-role-assignment)\n- [Configure automated access reviews for privileged roles](https://learn.microsoft.com/entra/id-governance/access-reviews-overview?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci)\n","TestId":"21854"},{"TestImplementationCost":"Low","TestPillar":"Network","TestCategory":"Azure Network Security","SkippedReason":"This test relies on capabilities not currently available (e.g., cmdlets that are not available on all platforms, Resolve-DnsName)","TestImpact":"Low","TestAppliesTo":null,"TestSfiPillar":"Protect networks","TestSkipped":"NotSupported","TestMinimumLicense":["Azure_Firewall_Standard","Azure_Firewall_Premium"],"TestTags":null,"TestTitle":"Threat intelligence is Enabled in Deny Mode on Azure Firewall","TestRisk":"High","TestResult":"\nSkipped. This test relies on capabilities not currently available (e.g., cmdlets that are not available on all platforms, Resolve-DnsName)\n\n","TestStatus":"Skipped","TestDescription":"Azure Firewall threat intelligence-based filtering alerts on and denies traffic to and from known malicious IP addresses, fully qualified domain names (FQDNs), and URLs sourced from the Microsoft Threat Intelligence feed. When you don't enable threat intelligence in `Alert and deny` mode, Azure Firewall doesn't actively block traffic to known malicious destinations.\n\nIf you don't enable threat intelligence in `Alert and deny` mode:\n\n- Threat actors can communicate with known malicious infrastructure, enabling data exfiltration and command-and-control communication without active blocking.\n- Organizations that use `Alert only` mode can see threat activity in logs but can't prevent connections to known bad destinations.\n- All firewall policy tiers remain exposed to threats that the Microsoft Threat Intelligence feed already identified.\n\n**Remediation action**\n\n- [Configure threat intelligence settings in Azure Firewall Manager](https://learn.microsoft.com/azure/firewall-manager/threat-intelligence-settings?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci) to set the threat intelligence mode to `Alert and deny` in the firewall policy.\n","TestId":25537},{"TestImplementationCost":"Medium","TestPillar":"Identity","TestCategory":"Access control","SkippedReason":null,"TestImpact":"Medium","TestAppliesTo":["Identity"],"TestSfiPillar":"Protect engineering systems","TestSkipped":"","TestMinimumLicense":"P1","TestTags":["Identity"],"TestTitle":"Resource-Specific Consent is restricted","TestRisk":"Medium","TestResult":"\nResource-Specific Consent is not restricted.\n\nThe current state is ManagedByMicrosoft.\n\n\n","TestStatus":"Failed","TestDescription":"Letting group owners consent to applications in Microsoft Entra ID creates a lateral escalation path that lets threat actors persist and steal data without admin credentials. If an attacker compromises a group owner account, they can register or use a malicious application and consent to high-privilege Graph API permissions scoped to the group. Attackers can potentially read all Teams messages, access SharePoint files, or manage group membership. This consent action creates a long-lived application identity with delegated or application permissions. The attacker maintains persistence with OAuth tokens, steals sensitive data from team channels and files, and impersonates users through messaging or email permissions. Without centralized enforcement of app consent policies, security teams lose visibility, and malicious applications spread under the radar, enabling multi-stage attacks across collaboration platforms.\n\n**Remediation action**\nConfigure preapproval of Resource-Specific Consent (RSC) permissions.\n- [Preapproval of RSC permissions](https://learn.microsoft.com/microsoftteams/platform/graph-api/rsc/preapproval-instruction-docs?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci)\n","TestId":"21810"},{"TestImplementationCost":"Low","TestPillar":"Network","TestCategory":"Azure Network Security","SkippedReason":"This test is not applicable to the current environment.","TestImpact":"Low","TestAppliesTo":null,"TestSfiPillar":"Protect networks","TestSkipped":"NotApplicable","TestMinimumLicense":"Azure WAF","TestTags":null,"TestTitle":"Default Ruleset is enabled in Application Gateway WAF","TestRisk":"High","TestResult":"\nNo Application Gateway WAF policies found attached to Application Gateways.\n","TestStatus":"Skipped","TestDescription":"Azure Application Gateway Web Application Firewall (WAF) provides centralized protection for web applications through managed rulesets that contain pre-configured detection signatures for known attack patterns.\n\nThe Microsoft Default Ruleset and OWASP Core Rule Set are continuously updated managed rulesets that protect against the most common and dangerous web vulnerabilities without requiring security expertise to configure.\n\nWhen no managed ruleset is enabled, the WAF policy provides no protection against known attack patterns, effectively operating as a pass-through despite being deployed.\n\nThreat actors routinely scan for unprotected web applications and exploit well-documented vulnerabilities using automated toolkits; without managed rules, attackers can execute SQL injection to extract or modify database contents, perform cross-site scripting to hijack user sessions and steal credentials, exploit local file inclusion to read sensitive configuration files, and leverage command injection to gain shell access on backend servers.\n\nThese attack techniques have known signatures that managed rulesets detect and block, but an empty or disabled ruleset configuration means the WAF cannot recognize these patterns and will allow malicious requests to reach backend applications unimpeded.\n\n\n**Remediation action**\n\n- [What is Azure Web Application Firewall on Azure Application Gateway?](https://learn.microsoft.com/en-us/azure/web-application-firewall/ag/ag-overview) - Overview of WAF capabilities on Application Gateway including managed rulesets\n- [Web Application Firewall CRS rule groups and rules](https://learn.microsoft.com/en-us/azure/web-application-firewall/ag/application-gateway-crs-rulegroups-rules) - Detailed documentation of available rulesets and rule groups\n- [Create Web Application Firewall policies for Application Gateway](https://learn.microsoft.com/en-us/azure/web-application-firewall/ag/create-waf-policy-ag) - Step-by-step guidance on creating and configuring WAF policies with managed rulesets\n\n\n","TestId":26881},{"TestImplementationCost":"High","TestPillar":"Identity","TestCategory":"Application management","SkippedReason":null,"TestImpact":"Low","TestAppliesTo":null,"TestSfiPillar":"Protect engineering systems","TestSkipped":"","TestMinimumLicense":"P1","TestTags":null,"TestTitle":"Emergency access accounts are configured appropriately","TestRisk":"High","TestResult":"\nQuinn Garcia accounts appear to be configured as per Microsoft guidance based on cloud-only state, registered phishing-resistant credentials and Conditional Access policy exclusions.\n\n**Summary:**\n- Total permanent Global Administrators: 20\n- Cloud-only GAs with phishing-resistant auth: 5\n- Quinn Garcia accounts (excluded from all CA): 3\n- Enabled Conditional Access policies: 17\n\n## Quinn Garcia accounts\n\n| Display name | UPN | Synced from on-premises | Authentication methods |\n| :----------- | :-- | :---------------------- | :--------------------- |\n| Quinn Garcia | [quinn@contoso.com](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/overview/userId/ceef37b7-c865-48fb-80c9-4def11201854) | No | password, phone, softwareOath, fido2 |\n| Reese Harris | [reese@contoso.com](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/overview/userId/babe04c9-8340-4329-a727-a8cee0cd2b1a) | No | password, temporaryAccessPass, microsoftAuthenticator, fido2, fido2 |\n| Ash Williams | [ash@contoso.com](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/overview/userId/513f3db2-044c-41be-af14-431bf88a2b3e) | No | password, email, phone, softwareOath, microsoftAuthenticator, microsoftAuthenticator, fido2, fido2, fido2, fido2, fido2, fido2, fido2, windowsHelloForBusiness, windowsHelloForBusiness, windowsHelloForBusiness, windowsHelloForBusiness, windowsHelloForBusiness |\n\n## All permanent Global Administrators\n\n| Display name | UPN | Cloud only | Phishing resistant auth | All CA excluded | CA policies missing exclusion |\n| :----------- | :-- | :--------: | :---------------------: | :---------: | :---------------------------- |\n| Quinn Garcia | [quinn@contoso.com](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/overview/userId/ceef37b7-c865-48fb-80c9-4def11201854) | ✅ | ✅ | ✅ | None |\n| Ash Williams | [ash@contoso.com](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/overview/userId/513f3db2-044c-41be-af14-431bf88a2b3e) | ✅ | ✅ | ✅ | None |\n| Reese Harris | [reese@contoso.com](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/overview/userId/babe04c9-8340-4329-a727-a8cee0cd2b1a) | ✅ | ✅ | ✅ | None |\n| Hayden Scott | [hayden@contoso.com](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/overview/userId/c0b65b13-37b1-4081-bcfc-14844159b4a5) | ✅ | ✅ | ❌ | [MFA - All users](https://entra.microsoft.com/#view/Microsoft_AAD_ConditionalAccess/PolicyBlade/policyId/474ddef4-5620-4e7a-8976-6e9b095b2675), [testdevicereg21872](https://entra.microsoft.com/#view/Microsoft_AAD_ConditionalAccess/PolicyBlade/policyId/620a9c5c-09c4-4558-a0fe-7fc8b3540992), [Security regisrtation info](https://entra.microsoft.com/#view/Microsoft_AAD_ConditionalAccess/PolicyBlade/policyId/508ae024-d4c4-42bf-a8c9-40257c214c10) |\n| Drew Mitchell | [drew@contoso.com](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/overview/userId/df02402a-e291-42cc-b449-79366daa2a40) | ✅ | ✅ | ❌ | [MFA - All users](https://entra.microsoft.com/#view/Microsoft_AAD_ConditionalAccess/PolicyBlade/policyId/474ddef4-5620-4e7a-8976-6e9b095b2675), [j-test admin](https://entra.microsoft.com/#view/Microsoft_AAD_ConditionalAccess/PolicyBlade/policyId/6c0ef46a-3b58-43a9-b451-7464a16d91d7), [Block Device Code](https://entra.microsoft.com/#view/Microsoft_AAD_ConditionalAccess/PolicyBlade/policyId/db2153a1-40a2-457f-917c-c280b204b5cd), [testdevicereg21872](https://entra.microsoft.com/#view/Microsoft_AAD_ConditionalAccess/PolicyBlade/policyId/620a9c5c-09c4-4558-a0fe-7fc8b3540992), [Security regisrtation info](https://entra.microsoft.com/#view/Microsoft_AAD_ConditionalAccess/PolicyBlade/policyId/508ae024-d4c4-42bf-a8c9-40257c214c10) |\n| Avery Thomas | [avery@contoso.com](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/overview/userId/f431700c-6d81-45b8-8f8d-581a8aa7cda6) | ✅ | ❌ | ❌ | [MFA - All users](https://entra.microsoft.com/#view/Microsoft_AAD_ConditionalAccess/PolicyBlade/policyId/474ddef4-5620-4e7a-8976-6e9b095b2675), [Block Device Code](https://entra.microsoft.com/#view/Microsoft_AAD_ConditionalAccess/PolicyBlade/policyId/db2153a1-40a2-457f-917c-c280b204b5cd), [testdevicereg21872](https://entra.microsoft.com/#view/Microsoft_AAD_ConditionalAccess/PolicyBlade/policyId/620a9c5c-09c4-4558-a0fe-7fc8b3540992), [Security regisrtation info](https://entra.microsoft.com/#view/Microsoft_AAD_ConditionalAccess/PolicyBlade/policyId/508ae024-d4c4-42bf-a8c9-40257c214c10) |\n| Peyton Clark | [peyton@contoso.com](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/overview/userId/7e92f268-bb12-469a-a869-210d596d4c1f) | ✅ | ❌ | ❌ | [MFA - All users](https://entra.microsoft.com/#view/Microsoft_AAD_ConditionalAccess/PolicyBlade/policyId/474ddef4-5620-4e7a-8976-6e9b095b2675), [Block Device Code](https://entra.microsoft.com/#view/Microsoft_AAD_ConditionalAccess/PolicyBlade/policyId/db2153a1-40a2-457f-917c-c280b204b5cd), [testdevicereg21872](https://entra.microsoft.com/#view/Microsoft_AAD_ConditionalAccess/PolicyBlade/policyId/620a9c5c-09c4-4558-a0fe-7fc8b3540992), [Security regisrtation info](https://entra.microsoft.com/#view/Microsoft_AAD_ConditionalAccess/PolicyBlade/policyId/508ae024-d4c4-42bf-a8c9-40257c214c10) |\n| Avery Brooks | [avery.brooks@contoso.com](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/overview/userId/a85798bd-652b-4eb9-ba90-3ee882df0179) | ✅ | ❌ | ❌ | [MFA - All users](https://entra.microsoft.com/#view/Microsoft_AAD_ConditionalAccess/PolicyBlade/policyId/474ddef4-5620-4e7a-8976-6e9b095b2675), [Block Device Code](https://entra.microsoft.com/#view/Microsoft_AAD_ConditionalAccess/PolicyBlade/policyId/db2153a1-40a2-457f-917c-c280b204b5cd), [testdevicereg21872](https://entra.microsoft.com/#view/Microsoft_AAD_ConditionalAccess/PolicyBlade/policyId/620a9c5c-09c4-4558-a0fe-7fc8b3540992), [Security regisrtation info](https://entra.microsoft.com/#view/Microsoft_AAD_ConditionalAccess/PolicyBlade/policyId/508ae024-d4c4-42bf-a8c9-40257c214c10) |\n| Sage Bennett | [sage@contoso.com](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/overview/userId/518ce209-faf4-4717-add9-7129a669fa11) | ✅ | ❌ | ❌ | [Block Device Code](https://entra.microsoft.com/#view/Microsoft_AAD_ConditionalAccess/PolicyBlade/policyId/db2153a1-40a2-457f-917c-c280b204b5cd), [testdevicereg21872](https://entra.microsoft.com/#view/Microsoft_AAD_ConditionalAccess/PolicyBlade/policyId/620a9c5c-09c4-4558-a0fe-7fc8b3540992), [Security regisrtation info](https://entra.microsoft.com/#view/Microsoft_AAD_ConditionalAccess/PolicyBlade/policyId/508ae024-d4c4-42bf-a8c9-40257c214c10) |\n| Finley Robinson | [finley.robinson@contoso.com](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/overview/userId/990fd38a-c516-4e3f-82e4-d458a1ab0f91) | ✅ | ❌ | ❌ | [testdevicereg21872](https://entra.microsoft.com/#view/Microsoft_AAD_ConditionalAccess/PolicyBlade/policyId/620a9c5c-09c4-4558-a0fe-7fc8b3540992), [Security regisrtation info](https://entra.microsoft.com/#view/Microsoft_AAD_ConditionalAccess/PolicyBlade/policyId/508ae024-d4c4-42bf-a8c9-40257c214c10) |\n| Ellis Cooper | [ellis@contoso.com](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/overview/userId/1433571b-3d7c-4a56-a9cc-67580848bc73) | ✅ | ❌ | ❌ | [MFA - All users](https://entra.microsoft.com/#view/Microsoft_AAD_ConditionalAccess/PolicyBlade/policyId/474ddef4-5620-4e7a-8976-6e9b095b2675), [Block Device Code](https://entra.microsoft.com/#view/Microsoft_AAD_ConditionalAccess/PolicyBlade/policyId/db2153a1-40a2-457f-917c-c280b204b5cd), [testdevicereg21872](https://entra.microsoft.com/#view/Microsoft_AAD_ConditionalAccess/PolicyBlade/policyId/620a9c5c-09c4-4558-a0fe-7fc8b3540992), [\\[ellis\\] - Require app protection policy](https://entra.microsoft.com/#view/Microsoft_AAD_ConditionalAccess/PolicyBlade/policyId/6909c0fb-c830-42b6-a438-c41d4010518f), [Security regisrtation info](https://entra.microsoft.com/#view/Microsoft_AAD_ConditionalAccess/PolicyBlade/policyId/508ae024-d4c4-42bf-a8c9-40257c214c10) |\n| Cameron Anderson | [cameron@contoso.com](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/overview/userId/1ce4078f-f795-4baf-aa55-1fdfcc2ebfe6) | ✅ | ❌ | ❌ | [MFA - All users](https://entra.microsoft.com/#view/Microsoft_AAD_ConditionalAccess/PolicyBlade/policyId/474ddef4-5620-4e7a-8976-6e9b095b2675), [j-test admin](https://entra.microsoft.com/#view/Microsoft_AAD_ConditionalAccess/PolicyBlade/policyId/6c0ef46a-3b58-43a9-b451-7464a16d91d7), [Block Device Code](https://entra.microsoft.com/#view/Microsoft_AAD_ConditionalAccess/PolicyBlade/policyId/db2153a1-40a2-457f-917c-c280b204b5cd), [testdevicereg21872](https://entra.microsoft.com/#view/Microsoft_AAD_ConditionalAccess/PolicyBlade/policyId/620a9c5c-09c4-4558-a0fe-7fc8b3540992), [Security regisrtation info](https://entra.microsoft.com/#view/Microsoft_AAD_ConditionalAccess/PolicyBlade/policyId/508ae024-d4c4-42bf-a8c9-40257c214c10) |\n| Taylor Brown | [taylor@contoso.com](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/overview/userId/2072badc-3cf0-4e84-b4c2-f9c065c46165) | ✅ | ❌ | ❌ | [MFA - All users](https://entra.microsoft.com/#view/Microsoft_AAD_ConditionalAccess/PolicyBlade/policyId/474ddef4-5620-4e7a-8976-6e9b095b2675), [Block Device Code](https://entra.microsoft.com/#view/Microsoft_AAD_ConditionalAccess/PolicyBlade/policyId/db2153a1-40a2-457f-917c-c280b204b5cd), [testdevicereg21872](https://entra.microsoft.com/#view/Microsoft_AAD_ConditionalAccess/PolicyBlade/policyId/620a9c5c-09c4-4558-a0fe-7fc8b3540992), [Security regisrtation info](https://entra.microsoft.com/#view/Microsoft_AAD_ConditionalAccess/PolicyBlade/policyId/508ae024-d4c4-42bf-a8c9-40257c214c10) |\n| Dakota Lee | [guest-user_external.com#EXT#@contoso.com](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/overview/userId/210d3e96-015f-462d-b6d6-81e6023263df) | ✅ | ❌ | ❌ | [MFA - All users](https://entra.microsoft.com/#view/Microsoft_AAD_ConditionalAccess/PolicyBlade/policyId/474ddef4-5620-4e7a-8976-6e9b095b2675), [Block Device Code](https://entra.microsoft.com/#view/Microsoft_AAD_ConditionalAccess/PolicyBlade/policyId/db2153a1-40a2-457f-917c-c280b204b5cd), [testdevicereg21872](https://entra.microsoft.com/#view/Microsoft_AAD_ConditionalAccess/PolicyBlade/policyId/620a9c5c-09c4-4558-a0fe-7fc8b3540992), [Security regisrtation info](https://entra.microsoft.com/#view/Microsoft_AAD_ConditionalAccess/PolicyBlade/policyId/508ae024-d4c4-42bf-a8c9-40257c214c10) |\n| Dakota Lee Test | [dakota-test@contoso.com](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/overview/userId/43482f27-d1af-420f-84ba-e9148a700f45) | ✅ | ❌ | ❌ | [MFA - All users](https://entra.microsoft.com/#view/Microsoft_AAD_ConditionalAccess/PolicyBlade/policyId/474ddef4-5620-4e7a-8976-6e9b095b2675), [Block Device Code](https://entra.microsoft.com/#view/Microsoft_AAD_ConditionalAccess/PolicyBlade/policyId/db2153a1-40a2-457f-917c-c280b204b5cd), [testdevicereg21872](https://entra.microsoft.com/#view/Microsoft_AAD_ConditionalAccess/PolicyBlade/policyId/620a9c5c-09c4-4558-a0fe-7fc8b3540992), [Security regisrtation info](https://entra.microsoft.com/#view/Microsoft_AAD_ConditionalAccess/PolicyBlade/policyId/508ae024-d4c4-42bf-a8c9-40257c214c10) |\n| Charlie Lewis | [charlie@contoso.com](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/overview/userId/5b0ec3ff-cea1-4eb9-8530-f2a66e5bec0a) | ✅ | ❌ | ❌ | [MFA - All users](https://entra.microsoft.com/#view/Microsoft_AAD_ConditionalAccess/PolicyBlade/policyId/474ddef4-5620-4e7a-8976-6e9b095b2675), [Block Device Code](https://entra.microsoft.com/#view/Microsoft_AAD_ConditionalAccess/PolicyBlade/policyId/db2153a1-40a2-457f-917c-c280b204b5cd), [testdevicereg21872](https://entra.microsoft.com/#view/Microsoft_AAD_ConditionalAccess/PolicyBlade/policyId/620a9c5c-09c4-4558-a0fe-7fc8b3540992), [Security regisrtation info](https://entra.microsoft.com/#view/Microsoft_AAD_ConditionalAccess/PolicyBlade/policyId/508ae024-d4c4-42bf-a8c9-40257c214c10) |\n| Phoenix Gray | [phoenix@contoso.com](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/overview/userId/7094fb23-003a-4f81-9796-5daeaa603003) | ✅ | ❌ | ❌ | [MFA - All users](https://entra.microsoft.com/#view/Microsoft_AAD_ConditionalAccess/PolicyBlade/policyId/474ddef4-5620-4e7a-8976-6e9b095b2675), [Block Device Code](https://entra.microsoft.com/#view/Microsoft_AAD_ConditionalAccess/PolicyBlade/policyId/db2153a1-40a2-457f-917c-c280b204b5cd), [testdevicereg21872](https://entra.microsoft.com/#view/Microsoft_AAD_ConditionalAccess/PolicyBlade/policyId/620a9c5c-09c4-4558-a0fe-7fc8b3540992), [Security regisrtation info](https://entra.microsoft.com/#view/Microsoft_AAD_ConditionalAccess/PolicyBlade/policyId/508ae024-d4c4-42bf-a8c9-40257c214c10) |\n| Jordan Smith | [jordan@contoso.com](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/overview/userId/bfaeba1e-1357-47de-9557-529caa103d5d) | ✅ | ❌ | ❌ | [MFA - All users](https://entra.microsoft.com/#view/Microsoft_AAD_ConditionalAccess/PolicyBlade/policyId/474ddef4-5620-4e7a-8976-6e9b095b2675), [j-test admin](https://entra.microsoft.com/#view/Microsoft_AAD_ConditionalAccess/PolicyBlade/policyId/6c0ef46a-3b58-43a9-b451-7464a16d91d7), [Block Device Code](https://entra.microsoft.com/#view/Microsoft_AAD_ConditionalAccess/PolicyBlade/policyId/db2153a1-40a2-457f-917c-c280b204b5cd), [testdevicereg21872](https://entra.microsoft.com/#view/Microsoft_AAD_ConditionalAccess/PolicyBlade/policyId/620a9c5c-09c4-4558-a0fe-7fc8b3540992), [Security regisrtation info](https://entra.microsoft.com/#view/Microsoft_AAD_ConditionalAccess/PolicyBlade/policyId/508ae024-d4c4-42bf-a8c9-40257c214c10) |\n| Jamie Rodriguez | [jamie@contoso.com](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/overview/userId/0b37813c-ae19-4399-982f-16587f17f9c0) | ✅ | ❌ | ❌ | [MFA - All users](https://entra.microsoft.com/#view/Microsoft_AAD_ConditionalAccess/PolicyBlade/policyId/474ddef4-5620-4e7a-8976-6e9b095b2675), [Block Device Code](https://entra.microsoft.com/#view/Microsoft_AAD_ConditionalAccess/PolicyBlade/policyId/db2153a1-40a2-457f-917c-c280b204b5cd), [testdevicereg21872](https://entra.microsoft.com/#view/Microsoft_AAD_ConditionalAccess/PolicyBlade/policyId/620a9c5c-09c4-4558-a0fe-7fc8b3540992), [Security regisrtation info](https://entra.microsoft.com/#view/Microsoft_AAD_ConditionalAccess/PolicyBlade/policyId/508ae024-d4c4-42bf-a8c9-40257c214c10), [Block access except Compliant Network](https://entra.microsoft.com/#view/Microsoft_AAD_ConditionalAccess/PolicyBlade/policyId/9ee6df4b-165d-4f86-a176-0ddcc4ad886c) |\n| Jules Bailey | [jules@contoso.com](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/overview/userId/0145d508-50fd-4f86-a47a-bf1c043c8358) | ❌ | ❌ | ❌ | [MFA - All users](https://entra.microsoft.com/#view/Microsoft_AAD_ConditionalAccess/PolicyBlade/policyId/474ddef4-5620-4e7a-8976-6e9b095b2675), [Block Device Code](https://entra.microsoft.com/#view/Microsoft_AAD_ConditionalAccess/PolicyBlade/policyId/db2153a1-40a2-457f-917c-c280b204b5cd), [testdevicereg21872](https://entra.microsoft.com/#view/Microsoft_AAD_ConditionalAccess/PolicyBlade/policyId/620a9c5c-09c4-4558-a0fe-7fc8b3540992), [Security regisrtation info](https://entra.microsoft.com/#view/Microsoft_AAD_ConditionalAccess/PolicyBlade/policyId/508ae024-d4c4-42bf-a8c9-40257c214c10) |\n\n\n\n","TestStatus":"Passed","TestDescription":"Microsoft recommends that organizations have two cloud-only Quinn Garcia accounts permanently assigned the [Global Administrator](https://learn.microsoft.com/entra/identity/role-based-access-control/permissions-reference?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci#global-administrator) role. These accounts are highly privileged and aren't assigned to specific individuals. The accounts are limited to emergency or \"break glass\" scenarios where normal accounts can't be used or all other administrators are accidentally locked out.\n\n**Remediation action**\n\n- Create accounts following the [Quinn Garcia account recommendations](https://learn.microsoft.com/entra/identity/role-based-access-control/security-emergency-access?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci).\n","TestId":"21835"},{"TestImplementationCost":"Low","TestPillar":"Devices","TestCategory":"Device","SkippedReason":null,"TestImpact":"Medium","TestAppliesTo":null,"TestSfiPillar":"Protect tenants and isolate production systems","TestSkipped":"","TestMinimumLicense":"Intune","TestTags":null,"TestTitle":"An iOS update policy is created and assigned","TestRisk":"High","TestResult":"\nAn iOS update policy is configured and assigned.\n\n\n## iOS Update Policies\n\n| Policy Name | Status | Assignment Target |\n| :---------- | :----- | :---------------- |\n| [iOS_Update_1](https://intune.microsoft.com/#view/Microsoft_Intune_DeviceSettings/DevicesMenu/~/iOSiPadOSUpdate) | ❌ Not assigned | None |\n| [alex_ios_DDM_SoftwareUpdate](https://intune.microsoft.com/#view/Microsoft_Intune_DeviceSettings/DevicesMenu/~/configuration) | ✅ Assigned | **Included:** All Devices, **Excluded:** WFgroup |\n| [alex_ios_DDM_SoftwareUpdateEnforceLatest](https://intune.microsoft.com/#view/Microsoft_Intune_DeviceSettings/DevicesMenu/~/configuration) | ✅ Assigned | **Included:** All Devices, **Excluded:** WFgroup |\n| [alex_ios_policy1](https://intune.microsoft.com/#view/Microsoft_Intune_DeviceSettings/DevicesMenu/~/configuration) | ❌ Not assigned | None |\n| [alex_ios_policy2](https://intune.microsoft.com/#view/Microsoft_Intune_DeviceSettings/DevicesMenu/~/configuration) | ✅ Assigned | **Included:** All Users |\n\n\n\n","TestStatus":"Passed","TestDescription":"If iOS update policies aren’t configured and assigned, threat actors can exploit unpatched vulnerabilities in outdated operating systems on managed devices. The absence of enforced update policies allows attackers to use known exploits to gain initial access, escalate privileges, and move laterally within the environment. Without timely updates, devices remain susceptible to exploits that have already been addressed by Apple, enabling threat actors to bypass security controls, deploy malware, or exfiltrate sensitive data. This attack chain begins with device compromise through an unpatched vulnerability, followed by persistence and potential data breach that impacts both organizational security and compliance posture.\n\nEnforcing update policies disrupts this chain by ensuring devices are consistently protected against known threats.\n\n**Remediation action**\n\nConfigure and assign iOS/iPadOS update policies in Intune to enforce timely patching and reduce risk from unpatched vulnerabilities: \n- [Manage iOS/iPadOS software updates in Intune](https://learn.microsoft.com/intune/intune-service/protect/software-updates-guide-ios-ipados?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci)\n- [Assign policies in Intune](https://learn.microsoft.com/intune/intune-service/configuration/device-profile-assign?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci#assign-a-policy-to-users-or-groups)\n","TestId":"24554"},{"TestImplementationCost":"Low","TestPillar":"Identity","TestCategory":"Monitoring","SkippedReason":null,"TestImpact":"Low","TestAppliesTo":["Identity"],"TestSfiPillar":"Monitor and detect cyberthreats","TestSkipped":"","TestMinimumLicense":"P2","TestTags":["Identity"],"TestTitle":"Activation alert for highly privileged role assignments","TestRisk":"High","TestResult":"\nRole notifications are not properly configured.\n\nNote: To save time, this check stops when it finds the first role that does not have notifications. After fixing this role and all other roles, we recommend running the check again to verify.\n\n\n## Notifications for high privileged roles\n\n\n| Role Name | Notification Scenario | Notification Type | Default Recipients Enabled | Additional Recipients |\n| :-------- | :-------------------- | :---------------- | :------------------------- | :-------------------- |\n| AI Administrator | Send notifications when members are assigned as eligible to this role | Role assignment alert | True | |\n| AI Administrator | Send notifications when members are assigned as eligible to this role | Notification to the assigned user (assignee) | True | |\n| AI Administrator | Send notifications when members are assigned as eligible to this role | Request to approve a role assignment renewal/extension | True | |\n| AI Administrator | Send notifications when members are assigned as active to this role | Role assignment alert | True | |\n| AI Administrator | Send notifications when members are assigned as active to this role | Notification to the assigned user (assignee) | True | |\n| AI Administrator | Send notifications when members are assigned as active to this role | Request to approve a role assignment renewal/extension | True | |\n| AI Administrator | Send notifications when eligible members activate this role | Role activation alert | True | |\n| AI Administrator | Send notifications when eligible members activate this role | Notification to activated user (requestor) | True | |\n| AI Administrator | Send notifications when eligible members activate this role | Request to approve an activation | True | |\n| AI Reader | Send notifications when members are assigned as eligible to this role | Role assignment alert | True | |\n| AI Reader | Send notifications when members are assigned as eligible to this role | Notification to the assigned user (assignee) | True | |\n| AI Reader | Send notifications when members are assigned as eligible to this role | Request to approve a role assignment renewal/extension | True | |\n| AI Reader | Send notifications when members are assigned as active to this role | Role assignment alert | True | |\n| AI Reader | Send notifications when members are assigned as active to this role | Notification to the assigned user (assignee) | True | |\n| AI Reader | Send notifications when members are assigned as active to this role | Request to approve a role assignment renewal/extension | True | |\n| AI Reader | Send notifications when eligible members activate this role | Role activation alert | True | |\n| AI Reader | Send notifications when eligible members activate this role | Notification to activated user (requestor) | True | |\n| AI Reader | Send notifications when eligible members activate this role | Request to approve an activation | True | |\n| Agent ID Administrator | Send notifications when members are assigned as eligible to this role | Role assignment alert | True | |\n| Agent ID Administrator | Send notifications when members are assigned as eligible to this role | Notification to the assigned user (assignee) | True | |\n| Agent ID Administrator | Send notifications when members are assigned as eligible to this role | Request to approve a role assignment renewal/extension | True | |\n| Agent ID Administrator | Send notifications when members are assigned as active to this role | Role assignment alert | True | |\n| Agent ID Administrator | Send notifications when members are assigned as active to this role | Notification to the assigned user (assignee) | True | |\n| Agent ID Administrator | Send notifications when members are assigned as active to this role | Request to approve a role assignment renewal/extension | True | |\n| Agent ID Administrator | Send notifications when eligible members activate this role | Role activation alert | True | |\n| Agent ID Administrator | Send notifications when eligible members activate this role | Notification to activated user (requestor) | True | |\n| Agent ID Administrator | Send notifications when eligible members activate this role | Request to approve an activation | True | |\n| Application Administrator | Send notifications when members are assigned as eligible to this role | Role assignment alert | True | jordan@contoso.com |\n| Application Administrator | Send notifications when members are assigned as eligible to this role | Notification to the assigned user (assignee) | True | ash@contoso.com |\n| Application Administrator | Send notifications when members are assigned as eligible to this role | Request to approve a role assignment renewal/extension | True | |\n| Application Administrator | Send notifications when members are assigned as active to this role | Role assignment alert | True | |\n| Application Administrator | Send notifications when members are assigned as active to this role | Notification to the assigned user (assignee) | True | |\n| Application Administrator | Send notifications when members are assigned as active to this role | Request to approve a role assignment renewal/extension | True | |\n| Application Administrator | Send notifications when eligible members activate this role | Role activation alert | True | |\n| Application Administrator | Send notifications when eligible members activate this role | Notification to activated user (requestor) | True | |\n| Application Administrator | Send notifications when eligible members activate this role | Request to approve an activation | True | |\n| Application Developer | Send notifications when members are assigned as eligible to this role | Role assignment alert | True | jordan@contoso.com |\n| Application Developer | Send notifications when members are assigned as eligible to this role | Notification to the assigned user (assignee) | True | |\n| Application Developer | Send notifications when members are assigned as eligible to this role | Request to approve a role assignment renewal/extension | True | |\n| Application Developer | Send notifications when members are assigned as active to this role | Role assignment alert | True | |\n| Application Developer | Send notifications when members are assigned as active to this role | Notification to the assigned user (assignee) | True | |\n| Application Developer | Send notifications when members are assigned as active to this role | Request to approve a role assignment renewal/extension | True | |\n| Application Developer | Send notifications when eligible members activate this role | Role activation alert | True | |\n| Application Developer | Send notifications when eligible members activate this role | Notification to activated user (requestor) | True | |\n| Application Developer | Send notifications when eligible members activate this role | Request to approve an activation | True | |\n| Attribute Provisioning Administrator | Send notifications when members are assigned as eligible to this role | Role assignment alert | True | |\n| Attribute Provisioning Administrator | Send notifications when members are assigned as eligible to this role | Notification to the assigned user (assignee) | True | |\n| Attribute Provisioning Administrator | Send notifications when members are assigned as eligible to this role | Request to approve a role assignment renewal/extension | True | |\n| Attribute Provisioning Administrator | Send notifications when members are assigned as active to this role | Role assignment alert | True | |\n| Attribute Provisioning Administrator | Send notifications when members are assigned as active to this role | Notification to the assigned user (assignee) | True | |\n| Attribute Provisioning Administrator | Send notifications when members are assigned as active to this role | Request to approve a role assignment renewal/extension | True | |\n| Attribute Provisioning Administrator | Send notifications when eligible members activate this role | Role activation alert | True | |\n| Attribute Provisioning Administrator | Send notifications when eligible members activate this role | Notification to activated user (requestor) | True | |\n| Attribute Provisioning Administrator | Send notifications when eligible members activate this role | Request to approve an activation | True | |\n| Attribute Provisioning Reader | Send notifications when members are assigned as eligible to this role | Role assignment alert | True | |\n| Attribute Provisioning Reader | Send notifications when members are assigned as eligible to this role | Notification to the assigned user (assignee) | True | |\n| Attribute Provisioning Reader | Send notifications when members are assigned as eligible to this role | Request to approve a role assignment renewal/extension | True | |\n| Attribute Provisioning Reader | Send notifications when members are assigned as active to this role | Role assignment alert | True | |\n| Attribute Provisioning Reader | Send notifications when members are assigned as active to this role | Notification to the assigned user (assignee) | True | |\n| Attribute Provisioning Reader | Send notifications when members are assigned as active to this role | Request to approve a role assignment renewal/extension | True | |\n| Attribute Provisioning Reader | Send notifications when eligible members activate this role | Role activation alert | True | |\n| Attribute Provisioning Reader | Send notifications when eligible members activate this role | Notification to activated user (requestor) | True | |\n| Attribute Provisioning Reader | Send notifications when eligible members activate this role | Request to approve an activation | True | |\n| Authentication Administrator | Send notifications when members are assigned as eligible to this role | Role assignment alert | True | |\n| Authentication Administrator | Send notifications when members are assigned as eligible to this role | Notification to the assigned user (assignee) | True | |\n| Authentication Administrator | Send notifications when members are assigned as eligible to this role | Request to approve a role assignment renewal/extension | True | |\n| Authentication Administrator | Send notifications when members are assigned as active to this role | Role assignment alert | True | |\n| Authentication Administrator | Send notifications when members are assigned as active to this role | Notification to the assigned user (assignee) | True | |\n| Authentication Administrator | Send notifications when members are assigned as active to this role | Request to approve a role assignment renewal/extension | True | |\n| Authentication Administrator | Send notifications when eligible members activate this role | Role activation alert | True | |\n| Authentication Administrator | Send notifications when eligible members activate this role | Notification to activated user (requestor) | True | |\n| Authentication Administrator | Send notifications when eligible members activate this role | Request to approve an activation | True | |\n| Authentication Extensibility Administrator | Send notifications when members are assigned as eligible to this role | Role assignment alert | True | |\n| Authentication Extensibility Administrator | Send notifications when members are assigned as eligible to this role | Notification to the assigned user (assignee) | True | |\n| Authentication Extensibility Administrator | Send notifications when members are assigned as eligible to this role | Request to approve a role assignment renewal/extension | True | |\n| Authentication Extensibility Administrator | Send notifications when members are assigned as active to this role | Role assignment alert | True | |\n| Authentication Extensibility Administrator | Send notifications when members are assigned as active to this role | Notification to the assigned user (assignee) | True | |\n| Authentication Extensibility Administrator | Send notifications when members are assigned as active to this role | Request to approve a role assignment renewal/extension | True | |\n| Authentication Extensibility Administrator | Send notifications when eligible members activate this role | Role activation alert | True | |\n| Authentication Extensibility Administrator | Send notifications when eligible members activate this role | Notification to activated user (requestor) | True | |\n| Authentication Extensibility Administrator | Send notifications when eligible members activate this role | Request to approve an activation | True | |\n| Authentication Extensibility Password Administrator | Send notifications when members are assigned as eligible to this role | Role assignment alert | True | |\n| Authentication Extensibility Password Administrator | Send notifications when members are assigned as eligible to this role | Notification to the assigned user (assignee) | True | |\n| Authentication Extensibility Password Administrator | Send notifications when members are assigned as eligible to this role | Request to approve a role assignment renewal/extension | True | |\n| Authentication Extensibility Password Administrator | Send notifications when members are assigned as active to this role | Role assignment alert | True | |\n| Authentication Extensibility Password Administrator | Send notifications when members are assigned as active to this role | Notification to the assigned user (assignee) | True | |\n| Authentication Extensibility Password Administrator | Send notifications when members are assigned as active to this role | Request to approve a role assignment renewal/extension | True | |\n| Authentication Extensibility Password Administrator | Send notifications when eligible members activate this role | Role activation alert | True | |\n| Authentication Extensibility Password Administrator | Send notifications when eligible members activate this role | Notification to activated user (requestor) | True | |\n| Authentication Extensibility Password Administrator | Send notifications when eligible members activate this role | Request to approve an activation | True | |\n| B2C IEF Keyset Administrator | Send notifications when members are assigned as eligible to this role | Role assignment alert | True | |\n| B2C IEF Keyset Administrator | Send notifications when members are assigned as eligible to this role | Notification to the assigned user (assignee) | True | |\n| B2C IEF Keyset Administrator | Send notifications when members are assigned as eligible to this role | Request to approve a role assignment renewal/extension | True | |\n| B2C IEF Keyset Administrator | Send notifications when members are assigned as active to this role | Role assignment alert | True | |\n| B2C IEF Keyset Administrator | Send notifications when members are assigned as active to this role | Notification to the assigned user (assignee) | True | |\n| B2C IEF Keyset Administrator | Send notifications when members are assigned as active to this role | Request to approve a role assignment renewal/extension | True | |\n| B2C IEF Keyset Administrator | Send notifications when eligible members activate this role | Role activation alert | True | |\n| B2C IEF Keyset Administrator | Send notifications when eligible members activate this role | Notification to activated user (requestor) | True | |\n| B2C IEF Keyset Administrator | Send notifications when eligible members activate this role | Request to approve an activation | True | |\n| Cloud Application Administrator | Send notifications when members are assigned as eligible to this role | Role assignment alert | True | |\n| Cloud Application Administrator | Send notifications when members are assigned as eligible to this role | Notification to the assigned user (assignee) | True | |\n| Cloud Application Administrator | Send notifications when members are assigned as eligible to this role | Request to approve a role assignment renewal/extension | True | |\n| Cloud Application Administrator | Send notifications when members are assigned as active to this role | Role assignment alert | True | |\n| Cloud Application Administrator | Send notifications when members are assigned as active to this role | Notification to the assigned user (assignee) | True | |\n| Cloud Application Administrator | Send notifications when members are assigned as active to this role | Request to approve a role assignment renewal/extension | True | |\n| Cloud Application Administrator | Send notifications when eligible members activate this role | Role activation alert | True | |\n| Cloud Application Administrator | Send notifications when eligible members activate this role | Notification to activated user (requestor) | True | |\n| Cloud Application Administrator | Send notifications when eligible members activate this role | Request to approve an activation | True | |\n| Cloud Device Administrator | Send notifications when members are assigned as eligible to this role | Role assignment alert | True | |\n| Cloud Device Administrator | Send notifications when members are assigned as eligible to this role | Notification to the assigned user (assignee) | True | |\n| Cloud Device Administrator | Send notifications when members are assigned as eligible to this role | Request to approve a role assignment renewal/extension | True | |\n| Cloud Device Administrator | Send notifications when members are assigned as active to this role | Role assignment alert | True | |\n| Cloud Device Administrator | Send notifications when members are assigned as active to this role | Notification to the assigned user (assignee) | True | |\n| Cloud Device Administrator | Send notifications when members are assigned as active to this role | Request to approve a role assignment renewal/extension | True | |\n| Cloud Device Administrator | Send notifications when eligible members activate this role | Role activation alert | True | |\n| Cloud Device Administrator | Send notifications when eligible members activate this role | Notification to activated user (requestor) | True | |\n| Cloud Device Administrator | Send notifications when eligible members activate this role | Request to approve an activation | True | |\n| Conditional Access Administrator | Send notifications when members are assigned as eligible to this role | Role assignment alert | True | |\n| Conditional Access Administrator | Send notifications when members are assigned as eligible to this role | Notification to the assigned user (assignee) | True | |\n| Conditional Access Administrator | Send notifications when members are assigned as eligible to this role | Request to approve a role assignment renewal/extension | True | |\n| Conditional Access Administrator | Send notifications when members are assigned as active to this role | Role assignment alert | True | |\n| Conditional Access Administrator | Send notifications when members are assigned as active to this role | Notification to the assigned user (assignee) | True | |\n| Conditional Access Administrator | Send notifications when members are assigned as active to this role | Request to approve a role assignment renewal/extension | True | |\n| Conditional Access Administrator | Send notifications when eligible members activate this role | Role activation alert | True | |\n| Conditional Access Administrator | Send notifications when eligible members activate this role | Notification to activated user (requestor) | True | |\n| Conditional Access Administrator | Send notifications when eligible members activate this role | Request to approve an activation | True | |\n| Directory Writers | Send notifications when members are assigned as eligible to this role | Role assignment alert | True | |\n| Directory Writers | Send notifications when members are assigned as eligible to this role | Notification to the assigned user (assignee) | True | |\n| Directory Writers | Send notifications when members are assigned as eligible to this role | Request to approve a role assignment renewal/extension | True | |\n| Directory Writers | Send notifications when members are assigned as active to this role | Role assignment alert | True | |\n| Directory Writers | Send notifications when members are assigned as active to this role | Notification to the assigned user (assignee) | True | |\n| Directory Writers | Send notifications when members are assigned as active to this role | Request to approve a role assignment renewal/extension | True | |\n| Directory Writers | Send notifications when eligible members activate this role | Role activation alert | True | |\n| Directory Writers | Send notifications when eligible members activate this role | Notification to activated user (requestor) | True | |\n| Directory Writers | Send notifications when eligible members activate this role | Request to approve an activation | True | |\n| Domain Name Administrator | Send notifications when members are assigned as eligible to this role | Role assignment alert | True | |\n| Domain Name Administrator | Send notifications when members are assigned as eligible to this role | Notification to the assigned user (assignee) | True | |\n| Domain Name Administrator | Send notifications when members are assigned as eligible to this role | Request to approve a role assignment renewal/extension | True | |\n| Domain Name Administrator | Send notifications when members are assigned as active to this role | Role assignment alert | True | |\n| Domain Name Administrator | Send notifications when members are assigned as active to this role | Notification to the assigned user (assignee) | True | |\n| Domain Name Administrator | Send notifications when members are assigned as active to this role | Request to approve a role assignment renewal/extension | True | |\n| Domain Name Administrator | Send notifications when eligible members activate this role | Role activation alert | True | |\n| Domain Name Administrator | Send notifications when eligible members activate this role | Notification to activated user (requestor) | True | |\n| Domain Name Administrator | Send notifications when eligible members activate this role | Request to approve an activation | True | |\n| ExamStudyTest | Send notifications when members are assigned as eligible to this role | Role assignment alert | True | |\n| ExamStudyTest | Send notifications when members are assigned as eligible to this role | Notification to the assigned user (assignee) | True | |\n| ExamStudyTest | Send notifications when members are assigned as eligible to this role | Request to approve a role assignment renewal/extension | True | |\n| ExamStudyTest | Send notifications when members are assigned as active to this role | Role assignment alert | True | |\n| ExamStudyTest | Send notifications when members are assigned as active to this role | Notification to the assigned user (assignee) | True | |\n| ExamStudyTest | Send notifications when members are assigned as active to this role | Request to approve a role assignment renewal/extension | True | |\n| ExamStudyTest | Send notifications when eligible members activate this role | Role activation alert | True | |\n| ExamStudyTest | Send notifications when eligible members activate this role | Notification to activated user (requestor) | True | |\n| ExamStudyTest | Send notifications when eligible members activate this role | Request to approve an activation | True | |\n| External Identity Provider Administrator | Send notifications when members are assigned as eligible to this role | Role assignment alert | True | |\n| External Identity Provider Administrator | Send notifications when members are assigned as eligible to this role | Notification to the assigned user (assignee) | True | |\n| External Identity Provider Administrator | Send notifications when members are assigned as eligible to this role | Request to approve a role assignment renewal/extension | True | |\n| External Identity Provider Administrator | Send notifications when members are assigned as active to this role | Role assignment alert | True | |\n| External Identity Provider Administrator | Send notifications when members are assigned as active to this role | Notification to the assigned user (assignee) | True | |\n| External Identity Provider Administrator | Send notifications when members are assigned as active to this role | Request to approve a role assignment renewal/extension | True | |\n| External Identity Provider Administrator | Send notifications when eligible members activate this role | Role activation alert | True | |\n| External Identity Provider Administrator | Send notifications when eligible members activate this role | Notification to activated user (requestor) | True | |\n| External Identity Provider Administrator | Send notifications when eligible members activate this role | Request to approve an activation | True | |\n| Global Administrator | Send notifications when members are assigned as eligible to this role | Role assignment alert | False | |\n\n\n\n","TestStatus":"Failed","TestDescription":"Organizations without proper activation alerts for highly privileged roles lack visibility into when users access these critical permissions. Threat actors can exploit this monitoring gap to perform privilege escalation by activating highly privileged roles without detection, then establish persistence through admin account creation or security policy modifications. The absence of real-time alerts enables attackers to conduct lateral movement, modify audit configurations, and disable security controls without triggering immediate response procedures.\n\n**Remediation action**\n\n- [Configure Microsoft Entra role settings in Privileged Identity Management](https://learn.microsoft.com/entra/id-governance/privileged-identity-management/pim-how-to-change-default-settings?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci#require-justification-on-activation)\n","TestId":"21818"},{"TestImpact":"Low","TestRisk":"Low","TestSkipped":"NotConnectedToService","TestAppliesTo":null,"TestPillar":"Data","TestCategory":"SharePoint Online","TestDescription":"Information Rights Management (IRM) integration in SharePoint Online libraries is a legacy feature that has been replaced by Enhanced SharePoint Permissions (ESP). Any library using this legacy capability should be flagged to move to newer capabilities.\n\n**Remediation action**\n\nTo disable legacy IRM in SharePoint Online:\n1. Identify libraries currently using IRM protection (audit existing sites)\n2. Plan migration to modern sensitivity labels with encryption\n3. Connect to SharePoint Online: `Connect-SPOService -Url https://-admin.sharepoint.com`\n4. Disable legacy IRM: `Set-SPOTenant -IrmEnabled $false`\n5. Enable modern sensitivity labels: `Set-SPOTenant -EnableAIPIntegration $true`\n6. Configure and publish sensitivity labels with encryption to replace IRM policies\n\n- [Enable sensitivity labels for SharePoint and OneDrive](https://learn.microsoft.com/microsoft-365/compliance/sensitivity-labels-sharepoint-onedrive-files)\n- [SharePoint IRM and sensitivity labels (migration guidance)](https://learn.microsoft.com/microsoft-365/compliance/sensitivity-labels-sharepoint-onedrive-files#sharepoint-information-rights-management-irm-and-sensitivity-labels)\n- [Create and configure sensitivity labels with encryption](https://learn.microsoft.com/microsoft-365/compliance/encryption-sensitivity-labels)\n\n","TestTitle":"Information Rights Management is enabled in SharePoint Online","SkippedReason":"This test requires connection to the service(s) \"SharePointOnline\" currently disconnected. Please use _Connect-ZtAssessment_ to connect.","TestId":"35007","TestImplementationCost":"Low","TestMinimumLicense":["RMS_S_PREMIUM"],"TestSfiPillar":"","TestResult":"\nSkipped. This test requires connection to the service(s) \"SharePointOnline\" currently disconnected. Please use _Connect-ZtAssessment_ to connect.\n","TestStatus":"Skipped","TestTags":null},{"TestImplementationCost":"Low","TestPillar":"Network","TestCategory":"Global Secure Access","SkippedReason":null,"TestImpact":"High","TestAppliesTo":null,"TestSfiPillar":"Protect networks","TestSkipped":"","TestMinimumLicense":["AAD_PREMIUM","Entra_Premium_Internet_Access"],"TestTags":null,"TestTitle":"Global Secure Access signaling for Conditional Access is enabled","TestRisk":"Medium","TestResult":"\n❌ Global Secure Access signaling for Conditional Access is disabled. Conditional Access policies do not receive source IP or compliant network signals.\n\n\n\n### [Global Secure Access Conditional Access settings](https://entra.microsoft.com/#view/Microsoft_Azure_Network_Access/Security.ReactView)\n| Property | Value |\n| :--- | :--- |\n| Signaling status | ❌ Disabled |\n\n","TestStatus":"Failed","TestDescription":"When Global Secure Access routes user traffic through Microsoft's Security Service Edge, the original source IP of the user is replaced by the proxy egress IP. If Global Secure Access signaling for Conditional Access is not enabled, Microsoft Entra ID receives the proxy IP instead of the user's IP. Conditional Access policies that rely on named locations or trusted IP ranges evaluate the proxy IP, which does not correspond to the user's location. A threat actor who compromises user credentials can sign in from any location, and the location-based Conditional Access policy will evaluate the proxy IP, not the threat actor's IP, allowing the sign-in to proceed without triggering a location-based block or step-up authentication. In addition, Microsoft Entra ID Protection risk detections that depend on source IP — such as impossible travel, unfamiliar sign-in properties, and anomalous token — operate on the proxy IP, reducing their ability to detect anomalies. Sign-in logs record the proxy IP, which prevents security operations teams from correlating sign-in events to user locations during incident response. Enabling signaling restores the original source IP to Microsoft Entra ID and Microsoft Graph, and allows Conditional Access to enforce compliant network checks, which verify that the user connects through the Global Secure Access tunnel. \n\n**Remediation actions**\n\n1. [Enable Global Secure Access signaling for Conditional Access in the Microsoft Entra admin center under Global Secure Access > Settings > Session management > Adaptive Access](https://learn.microsoft.com/entra/global-secure-access/how-to-source-ip-restoration)\n\n2. [Understand how Universal Conditional Access works with Global Secure Access traffic profiles](https://learn.microsoft.com/entra/global-secure-access/concept-universal-conditional-access)\n\n3. [Configure compliant network check to require users to connect through Global Secure Access](https://learn.microsoft.com/entra/global-secure-access/how-to-compliant-network)\n\n","TestId":"25380"},{"TestImplementationCost":"High","TestPillar":"Identity","TestCategory":"Monitoring","SkippedReason":null,"TestImpact":"Low","TestAppliesTo":["Identity"],"TestSfiPillar":"Monitor and detect cyberthreats","TestSkipped":"","TestMinimumLicense":"P2","TestTags":["Identity"],"TestTitle":"All high-risk sign-ins are triaged","TestRisk":"High","TestResult":"\nFound **9** untriaged high-risk sign ins.\n## Untriaged High-Risk Sign ins\n\n| Date | User Principal Name | Type | Risk Level |\n| :---- | :---- | :---- | :---- |\n| 04/19/2026 22:27:06 | finley.robinson@contoso.com | anonymizedIPAddress | High |\n| 04/21/2026 03:30:29 | finley.robinson@contoso.com | unfamiliarFeatures | High |\n| 05/06/2026 13:36:36 | finley.robinson@contoso.com | maliciousIPAddress | High |\n| 04/16/2026 20:18:45 | finley.robinson@contoso.com | unfamiliarFeatures | High |\n| 04/19/2026 21:50:48 | finley.robinson@contoso.com | unfamiliarFeatures | High |\n| 04/24/2026 15:18:48 | finley.robinson@contoso.com | unfamiliarFeatures | High |\n| 04/24/2026 19:17:28 | finley.robinson@contoso.com | anonymizedIPAddress | High |\n| 04/25/2026 13:32:56 | finley.robinson@contoso.com | maliciousIPAddress | High |\n| 05/05/2026 05:58:04 | finley.robinson@contoso.com | anonymizedIPAddress | High |\n\n\n","TestStatus":"Failed","TestDescription":"Risky sign-ins flagged by Microsoft Entra ID Protection indicate a high probability of unauthorized access attempts. Threat actors use these sign-ins to gain an initial foothold. If these sign-ins remain uninvestigated, adversaries can establish persistence by repeatedly authenticating under the guise of legitimate users. \n\nA lack of response lets attackers execute reconnaissance, attempt to escalate their access, and blend into normal patterns. When untriaged sign-ins continue to generate alerts and there's no intervention, security gaps widen, facilitating lateral movement and defense evasion, as adversaries recognize the absence of an active security response.\n\n**Remediation action**\n\n- [Investigate risky sign-ins](https://learn.microsoft.com/entra/id-protection/howto-identity-protection-investigate-risk?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci)\n- [Remediate risks and unblock users](https://learn.microsoft.com/entra/id-protection/howto-identity-protection-remediate-unblock?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci)\n","TestId":"21863"},{"TestImplementationCost":"Low","TestPillar":"Identity","TestCategory":"Application management","SkippedReason":null,"TestImpact":"Low","TestAppliesTo":["Identity"],"TestSfiPillar":"Protect engineering systems","TestSkipped":"","TestMinimumLicense":"P1","TestTags":["Application"],"TestTitle":"Inactive applications don’t have highly privileged Microsoft Entra built-in roles","TestRisk":"High","TestResult":"\nNo inactive applications with privileged Entra built-in roles\n\n\n## Apps with privileged Entra built-in roles\n\n| | Name | Role | Assignment | App owner tenant | Last sign in|\n| :--- | :--- | :--- | :--- | :--- | :--- |\n| ✅ | [Mailbox Migration Account](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/Overview/objectId/d22f071d-e8d3-41fc-a516-b29753cdd1f6/appId/b650c3c1-3395-40bb-8471-2a6a8b76d8a9) | Global Administrator, Application Administrator | Permanent | Pora Inc. | 2025-09-09 | \n| ✅ | [contoso-tenant-devops-7576c63d-bc90-4ae4-9f1c-0d959fb520db](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/Overview/objectId/c5632968-35cd-445d-926e-16e0afc9160e/appId/e876f7cb-13f3-48a4-8329-66d7b1fa33fb) | Global Administrator | Permanent | Pora Inc. | 2025-10-01 | \n| ✅ | [Custom-App-Test](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/Overview/objectId/38415a71-b77b-44d5-a276-539faabe0de7/appId/ddb4f0e6-8018-4359-96c1-7473704bde43) | Global Administrator | Permanent | Pora Inc. | 2026-05-14 | \n\n\n","TestStatus":"Passed","TestDescription":"Attackers might exploit valid but inactive applications that still have elevated privileges. These applications can be used to gain initial access without raising alarm because they're legitimate applications. From there, attackers can use the application privileges to plan or execute other attacks. Attackers might also maintain access by manipulating the inactive application, such as by adding credentials. This persistence ensures that even if their primary access method is detected, they can regain access later.\n\n**Remediation action**\n\n- [Disable inactive privileged service principals](https://learn.microsoft.com/graph/api/serviceprincipal-update?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci)\n- Investigate if the application has legitimate use cases. If so, [analyze if a OAuth2 permission is a better fit](https://learn.microsoft.com/entra/identity-platform/v2-app-types?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci)\n- [If service principal doesn't have legitimate use cases, delete it](https://learn.microsoft.com/graph/api/serviceprincipal-delete?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci)\n","TestId":"21771"},{"TestImplementationCost":"Medium","TestPillar":"Identity","TestCategory":"External collaboration","SkippedReason":"This test is for tenants that are licensed for Entra Workload ID. See [Entra Workload ID licensing](https://learn.microsoft.com/entra/workload-id/workload-identities-faqs)","TestImpact":"Low","TestAppliesTo":null,"TestSfiPillar":"Protect tenants and isolate production systems","TestSkipped":"NotLicensedEntraWorkloadID","TestMinimumLicense":"P1","TestTags":null,"TestTitle":"Conditional Access policies for workload identities based on known networks are configured","TestRisk":"High","TestResult":"\nSkipped. This test is for tenants that are licensed for Entra Workload ID. See [Entra Workload ID licensing](https://learn.microsoft.com/entra/workload-id/workload-identities-faqs)\n\n","TestStatus":"Skipped","TestDescription":"When workload identities operate without network-based Conditional Access restrictions, threat actors can compromise service principal credentials through various methods, such as exposed secrets in code repositories or intercepted authentication tokens. The threat actors can then use these credentials from any location globally. This unrestricted access enables threat actors to perform reconnaissance activities, enumerate resources, and map the tenant's infrastructure while appearing legitimate. Once the threat actor is established within the environment, they can move laterally between services, access sensitive data stores, and potentially escalate privileges by exploiting overly permissive service-to-service permissions. The lack of network restrictions makes it impossible to detect anomalous access patterns based on location. This gap allows threat actors to maintain persistent access and exfiltrate data over extended periods without triggering security alerts that would normally flag connections from unexpected networks or geographic locations. \n\n**Remediation action**\n\n- [Configure Conditional Access for workload identities](https://learn.microsoft.com/entra/identity/conditional-access/workload-identity?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci)\n- [Create named locations](https://learn.microsoft.com/entra/identity/conditional-access/concept-assignment-network?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci)\n- [Follow best practices for securing workload identities](https://learn.microsoft.com/entra/workload-id/workload-identities-overview?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci)\n","TestId":21884},{"TestImplementationCost":"Low","TestPillar":"Devices","TestCategory":"Device","SkippedReason":null,"TestImpact":"Low","TestAppliesTo":null,"TestSfiPillar":"Protect identities and secrets","TestSkipped":"","TestMinimumLicense":"Intune","TestTags":null,"TestTitle":"A macOS Cloud LAPS Policy is Created and Assigned","TestRisk":"High","TestResult":"\nNo macOS DEP tokens found in the tenant.\n\n\n\n","TestStatus":"Failed","TestDescription":"Without enforcing macOS LAPS policies during Automated Device Enrollment (ADE), threat actors can exploit static or reused local administrator passwords to escalate privileges, move laterally, and establish persistence. Devices provisioned without randomized credentials are vulnerable to credential harvesting and reuse across multiple endpoints, increasing the risk of domain-wide compromise.\n\nEnforcing macOS LAPS ensures that each device is provisioned with a unique, encrypted local administrator password managed by Intune. This disrupts the attack chain at the credential access and lateral movement stages, significantly reducing the risk of widespread compromise and aligning with Zero Trust principles of least privilege and credential hygiene.\n\n**Remediation action**\n\nUse Intune to configure macOS ADE profiles that provision a local admin account with a randomized and encrypted password, and that enables secure rotation: \n- [Configure macOS LAPS in Microsoft Intune](https://learn.microsoft.com/intune/intune-service/enrollment/macos-laps?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci)\n- [Rotate local admin password (macOS)](https://learn.microsoft.com/intune/intune-service/remote-actions/device-rotate-local-admin-password?pivots=macos&wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci)\n\nFor more information, see: \n- [macOS ADE setup guide](https://learn.microsoft.com/intune/intune-service/enrollment/device-enrollment-program-enroll-macos?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci)\n","TestId":"24561"}],"TenantInfo":{"ConfigDeviceCompliancePolicies":[{"Platform":"iOS/iPadOS","PolicyName":"My iOS policy","DefenderForEndPoint":"Clear","MinOsVersion":"4","MaxOsVersion":"5","RequirePswd":true,"MinPswdLength":5,"PasswordType":"Alphanumeric","PswdExpiryDays":34,"CountOfPreviousPswdToBlock":5,"RequireEncryption":"Not Applicable","RootedJailbrokenDevices":"Blocked","MaxDeviceThreatLevel":"Secured","RequireFirewall":"Not Applicable","MaxInactivityMin":0,"ActionForNoncomplianceDaysPushNotification":2.0,"ActionForNoncomplianceDaysSendEmail":2.0,"ActionForNoncomplianceDaysRemoteLock":2.0,"ActionForNoncomplianceDaysBlock":1.0,"ActionForNoncomplianceDaysRetire":3.0,"Scope":"Default","IncludedGroups":"","ExcludedGroups":""},{"Platform":"Android Enterprise (Personal)","PolicyName":"My android personally-owned","DefenderForEndPoint":"","MinOsVersion":"3","MaxOsVersion":"4","RequirePswd":"Yes","MinPswdLength":5,"PasswordType":null,"PswdExpiryDays":200,"CountOfPreviousPswdToBlock":12,"RequireEncryption":"Yes","RootedJailbrokenDevices":"Blocked","MaxDeviceThreatLevel":"Low","RequireFirewall":"Not Applicable","MaxInactivityMin":5,"ActionForNoncomplianceDaysPushNotification":"","ActionForNoncomplianceDaysSendEmail":"","ActionForNoncomplianceDaysRemoteLock":2.0,"ActionForNoncomplianceDaysBlock":2.0,"ActionForNoncomplianceDaysRetire":"Immediately","Scope":"Default","IncludedGroups":"","ExcludedGroups":""},{"Platform":"Windows 10 and later","PolicyName":"Min Windows Compliance","DefenderForEndPoint":"","MinOsVersion":null,"MaxOsVersion":null,"RequirePswd":"","MinPswdLength":null,"PasswordType":null,"PswdExpiryDays":null,"CountOfPreviousPswdToBlock":null,"RequireEncryption":"","RootedJailbrokenDevices":"Not Applicable","MaxDeviceThreatLevel":"Not Applicable","RequireFirewall":"","MaxInactivityMin":null,"ActionForNoncomplianceDaysPushNotification":"","ActionForNoncomplianceDaysSendEmail":"","ActionForNoncomplianceDaysRemoteLock":"","ActionForNoncomplianceDaysBlock":"Immediately","ActionForNoncomplianceDaysRetire":"","Scope":"Default","IncludedGroups":"","ExcludedGroups":""},{"Platform":"macOS","PolicyName":"My macOS policy","DefenderForEndPoint":"","MinOsVersion":"1","MaxOsVersion":"2","RequirePswd":"Yes","MinPswdLength":6,"PasswordType":null,"PswdExpiryDays":null,"CountOfPreviousPswdToBlock":null,"RequireEncryption":"Yes","RootedJailbrokenDevices":"Not Applicable","MaxDeviceThreatLevel":"","RequireFirewall":"Yes","MaxInactivityMin":15,"ActionForNoncomplianceDaysPushNotification":"","ActionForNoncomplianceDaysSendEmail":"","ActionForNoncomplianceDaysRemoteLock":4.0,"ActionForNoncomplianceDaysBlock":"Immediately","ActionForNoncomplianceDaysRetire":6.0,"Scope":"Default","IncludedGroups":"","ExcludedGroups":""},{"Platform":"Windows 10 and later","PolicyName":"TEST-1130-Compliance","DefenderForEndPoint":"","MinOsVersion":null,"MaxOsVersion":null,"RequirePswd":"","MinPswdLength":null,"PasswordType":null,"PswdExpiryDays":null,"CountOfPreviousPswdToBlock":null,"RequireEncryption":"","RootedJailbrokenDevices":"Not Applicable","MaxDeviceThreatLevel":"Not Applicable","RequireFirewall":"","MaxInactivityMin":null,"ActionForNoncomplianceDaysPushNotification":"","ActionForNoncomplianceDaysSendEmail":"","ActionForNoncomplianceDaysRemoteLock":"","ActionForNoncomplianceDaysBlock":"Immediately","ActionForNoncomplianceDaysRetire":"","Scope":"Default","IncludedGroups":"","ExcludedGroups":""},{"Platform":"Windows 10 and later","PolicyName":"My Windows policy","DefenderForEndPoint":"High","MinOsVersion":null,"MaxOsVersion":null,"RequirePswd":"Yes","MinPswdLength":5,"PasswordType":null,"PswdExpiryDays":22,"CountOfPreviousPswdToBlock":6,"RequireEncryption":"Yes","RootedJailbrokenDevices":"Not Applicable","MaxDeviceThreatLevel":"Not Applicable","RequireFirewall":"Yes","MaxInactivityMin":1,"ActionForNoncomplianceDaysPushNotification":"","ActionForNoncomplianceDaysSendEmail":"","ActionForNoncomplianceDaysRemoteLock":"","ActionForNoncomplianceDaysBlock":"Immediately","ActionForNoncomplianceDaysRetire":"Immediately","Scope":"Default","IncludedGroups":"","ExcludedGroups":""},{"Platform":"Android device administrator","PolicyName":"My android device policy","DefenderForEndPoint":"Clear","MinOsVersion":"2","MaxOsVersion":"3","RequirePswd":"Yes","MinPswdLength":null,"PasswordType":null,"PswdExpiryDays":null,"CountOfPreviousPswdToBlock":null,"RequireEncryption":"Yes","RootedJailbrokenDevices":"Blocked","MaxDeviceThreatLevel":"Low","RequireFirewall":"Not Applicable","MaxInactivityMin":1,"ActionForNoncomplianceDaysPushNotification":12.0,"ActionForNoncomplianceDaysSendEmail":"","ActionForNoncomplianceDaysRemoteLock":"Immediately","ActionForNoncomplianceDaysBlock":"Immediately","ActionForNoncomplianceDaysRetire":"Immediately","Scope":"Default","IncludedGroups":"","ExcludedGroups":""},{"Platform":"Android Enterprise (Corp)","PolicyName":"My android enterprise policy","DefenderForEndPoint":"Low","MinOsVersion":null,"MaxOsVersion":null,"RequirePswd":"Yes","MinPswdLength":4,"PasswordType":null,"PswdExpiryDays":200,"CountOfPreviousPswdToBlock":null,"RequireEncryption":"Yes","RootedJailbrokenDevices":"","MaxDeviceThreatLevel":"","RequireFirewall":"Not Applicable","MaxInactivityMin":15,"ActionForNoncomplianceDaysPushNotification":"","ActionForNoncomplianceDaysSendEmail":"","ActionForNoncomplianceDaysRemoteLock":"","ActionForNoncomplianceDaysBlock":"Immediately","ActionForNoncomplianceDaysRetire":"","Scope":"Default","IncludedGroups":"","ExcludedGroups":""},{"Platform":"Windows 8.1 and later","PolicyName":"My Windows 8 policy","DefenderForEndPoint":"Not Applicable","MinOsVersion":"1.1","MaxOsVersion":"2.1","RequirePswd":"Yes","MinPswdLength":null,"PasswordType":null,"PswdExpiryDays":22,"CountOfPreviousPswdToBlock":10,"RequireEncryption":"Yes","RootedJailbrokenDevices":"Not Applicable","MaxDeviceThreatLevel":"Not Applicable","RequireFirewall":"Not Applicable","MaxInactivityMin":240,"ActionForNoncomplianceDaysPushNotification":"","ActionForNoncomplianceDaysSendEmail":"","ActionForNoncomplianceDaysRemoteLock":"","ActionForNoncomplianceDaysBlock":"Immediately","ActionForNoncomplianceDaysRetire":4.0,"Scope":"Default","IncludedGroups":"","ExcludedGroups":""},{"Platform":"Android (AOSP)","PolicyName":"My android aosp policy","DefenderForEndPoint":"Not Applicable","MinOsVersion":"1","MaxOsVersion":"2","RequirePswd":"Yes","MinPswdLength":16,"PasswordType":null,"PswdExpiryDays":"Not Applicable","CountOfPreviousPswdToBlock":"Not Applicable","RequireEncryption":"Yes","RootedJailbrokenDevices":"Blocked","MaxDeviceThreatLevel":"Not Applicable","RequireFirewall":"Not Applicable","MaxInactivityMin":480,"ActionForNoncomplianceDaysPushNotification":"","ActionForNoncomplianceDaysSendEmail":"","ActionForNoncomplianceDaysRemoteLock":"Immediately","ActionForNoncomplianceDaysBlock":"Immediately","ActionForNoncomplianceDaysRetire":"","Scope":"Default","IncludedGroups":"","ExcludedGroups":""}],"OverviewAuthMethodsAllUsers":{"nodes":[{"value":85,"source":"Users","target":"Single factor"},{"value":980,"source":"Users","target":"Phishable"},{"value":185,"source":"Users","target":"Phish resistant"},{"value":420,"source":"Phishable","target":"Phone"},{"value":560,"source":"Phishable","target":"Authenticator"},{"value":125,"source":"Phish resistant","target":"Passkey"},{"value":60,"source":"Phish resistant","target":"WHfB"}],"description":"Strongest authentication method registered by all users."},"ConfigWindowsEnrollment":[{"Type":"MDM","PolicyName":"Microsoft Intune","AppliesTo":"Selected","Groups":"All active users"},{"Type":"MDM","PolicyName":"Microsoft Intune Enrollment","AppliesTo":"None","Groups":"Not Applicable"}],"OverviewCaMfaAllUsers":{"nodes":[{"value":394,"source":"User sign in","target":"No CA applied"},{"value":856,"source":"User sign in","target":"CA applied"},{"value":146,"source":"CA applied","target":"No MFA"},{"value":710,"source":"CA applied","target":"MFA"}],"description":"Over the past 30 days, 68.5% of sign-ins were protected by conditional access policies enforcing multifactor."},"OverviewCaDevicesAllUsers":{"nodes":[{"value":500,"source":"User sign in","target":"Unmanaged"},{"value":1150,"source":"User sign in","target":"Managed"},{"value":260,"source":"Managed","target":"Non-compliant"},{"value":890,"source":"Managed","target":"Compliant"}],"description":"Over the past 30 days, 71.2% of sign-ins were from compliant devices."},"OverviewAuthMethodsPrivilegedUsers":{"nodes":[{"value":2,"source":"Users","target":"Single factor"},{"value":28,"source":"Users","target":"Phishable"},{"value":15,"source":"Users","target":"Phish resistant"},{"value":8,"source":"Phishable","target":"Phone"},{"value":20,"source":"Phishable","target":"Authenticator"},{"value":12,"source":"Phish resistant","target":"Passkey"},{"value":3,"source":"Phish resistant","target":"WHfB"}],"description":"Strongest authentication method registered by privileged users."},"TenantOverview":{"GroupCount":340,"DeviceCount":765,"ManagedDeviceCount":733,"ApplicationCount":156,"UserCount":1250,"GuestCount":85},"DeviceOverview":{"ManagedDevices":{"enrolledDeviceCount":733,"lastModifiedDateTime":"2026-05-19T10:58:07.8413470+10:00","deviceExchangeAccessStateSummary":{"blockedDeviceCount":12,"quarantinedDeviceCount":5,"allowedDeviceCount":690,"unavailableDeviceCount":18,"unknownDeviceCount":8},"desktopCount":553,"mdmEnrolledCount":585,"mobileCount":180,"deviceOperatingSystemSummary":{"windowsCount":525,"unknownCount":0,"androidFullyManagedCount":0,"windowsMobileCount":0,"androidCorporateWorkProfileCount":20,"linuxCount":0,"androidDeviceAdminCount":0,"configMgrDeviceCount":0,"androidCount":105,"aospUserlessCount":0,"androidWorkProfileCount":50,"macOSCount":75,"androidDedicatedCount":35,"iosCount":75,"chromeOSCount":0,"aospUserAssociatedCount":0},"totalCount":733,"dualEnrolledDeviceCount":148},"DeviceCompliance":{"unknownDeviceCount":5,"compliantDeviceCount":387,"inGracePeriodCount":15,"errorDeviceCount":8,"nonCompliantDeviceCount":106,"configManagerCount":0,"conflictDeviceCount":0,"remediatedDeviceCount":0,"notApplicableDeviceCount":4},"DeviceOwnership":{"personalCount":98,"corporateCount":427},"MobileSummary":{"nodes":[{"value":105,"source":"Mobile devices","target":"Android"},{"value":75,"source":"Mobile devices","target":"iOS"},{"value":72,"source":"Android","target":"Android (Company)"},{"value":33,"source":"Android","target":"Android (Personal)"},{"value":58,"source":"iOS","target":"iOS (Company)"},{"value":17,"source":"iOS","target":"iOS (Personal)"},{"value":60,"source":"Android (Company)","target":"Compliant"},{"value":12,"source":"Android (Company)","target":"Non-compliant"},{"value":10,"source":"Android (Personal)","target":"Compliant"},{"value":23,"source":"Android (Personal)","target":"Non-compliant"},{"value":52,"source":"iOS (Company)","target":"Compliant"},{"value":6,"source":"iOS (Company)","target":"Non-compliant"},{"value":11,"source":"iOS (Personal)","target":"Compliant"},{"value":6,"source":"iOS (Personal)","target":"Non-compliant"}],"totalDevices":180,"description":"Mobile devices by compliance status."},"DesktopDevicesSummary":{"nodes":[{"value":585,"source":"Desktop devices","target":"Windows"},{"value":75,"source":"Desktop devices","target":"macOS"},{"value":285,"source":"Windows","target":"Entra joined"},{"value":100,"source":"Windows","target":"Entra registered"},{"value":200,"source":"Windows","target":"Entra hybrid joined"},{"value":171,"source":"Entra joined","target":"Compliant"},{"value":42,"source":"Entra joined","target":"Non-compliant"},{"value":72,"source":"Entra joined","target":"Unmanaged"},{"value":50,"source":"Entra hybrid joined","target":"Compliant"},{"value":23,"source":"Entra hybrid joined","target":"Non-compliant"},{"value":127,"source":"Entra hybrid joined","target":"Unmanaged"},{"value":60,"source":"Entra registered","target":"Compliant"},{"value":40,"source":"Entra registered","target":"Non-compliant"},{"value":0,"source":"Entra registered","target":"Unmanaged"},{"value":56,"source":"macOS","target":"Compliant"},{"value":15,"source":"macOS","target":"Non-compliant"},{"value":4,"source":"macOS","target":"Unmanaged"}],"totalDevices":660,"entrajoined":285,"entrahybridjoined":200,"description":"Desktop devices (Windows and macOS) by join type and compliance status.","entraregistered":100}},"ConfigDeviceEnrollmentRestriction":[{"Platform":"iOS/iPadOS","Priority":2,"Name":"iOS Restriction 2","MDM":"Blocked","MinVer":null,"MaxVer":null,"PersonallyOwned":"Allowed","BlockedManufacturers":"","Scope":"Default","AssignedTo":"All users"},{"Platform":"Android Enterprise (work profile)","Priority":1,"Name":"Andy Penn","MDM":"Allowed","MinVer":"5.0","MaxVer":"5.1.1","PersonallyOwned":"Allowed","BlockedManufacturers":"Samsung","Scope":"Biscope, Default","AssignedTo":"aad-conditional-access-allow-legacy-auth"},{"Platform":"Android device administrator","Priority":1,"Name":"Andy Penn","MDM":"Allowed","MinVer":"5.0","MaxVer":"6.0","PersonallyOwned":"Allowed","BlockedManufacturers":"Samsung","Scope":"Biscope, Default","AssignedTo":"aad-conditional-access-allow-legacy-auth"},{"Platform":"iOS/iPadOS","Priority":1,"Name":"iOS Restriction","MDM":"Allowed","MinVer":"9.0","MaxVer":"10.0","PersonallyOwned":"Blocked","BlockedManufacturers":"","Scope":"Default","AssignedTo":"aad-conditional-access-excluded, Avanade Users"},{"Platform":"Windows","Priority":1,"Name":"Win1","MDM":"Allowed","MinVer":null,"MaxVer":null,"PersonallyOwned":"Allowed","BlockedManufacturers":"","Scope":"Biscope, Default","AssignedTo":"All users"},{"Platform":"iOS/iPadOS","Priority":"Default","Name":"All users","MDM":"Allowed","MinVer":"9.0","MaxVer":"10.0","PersonallyOwned":"Blocked","BlockedManufacturers":"","Scope":"","AssignedTo":"All devices"},{"Platform":"Windows","Priority":"Default","Name":"All users","MDM":"Allowed","MinVer":"10.0","MaxVer":"11.0","PersonallyOwned":"Blocked","BlockedManufacturers":"","Scope":"","AssignedTo":"All devices"},{"Platform":"Android device administrator","Priority":"Default","Name":"All users","MDM":"Allowed","MinVer":"7.0","MaxVer":"8.0","PersonallyOwned":"Blocked","BlockedManufacturers":"Samsung","Scope":"","AssignedTo":"All devices"},{"Platform":"macOS","Priority":"Default","Name":"All users","MDM":"Allowed","MinVer":null,"MaxVer":null,"PersonallyOwned":"Blocked","BlockedManufacturers":"","Scope":"","AssignedTo":"All devices"},{"Platform":"Android Enterprise (work profile)","Priority":"Default","Name":"All users","MDM":"Allowed","MinVer":"5.0","MaxVer":"6.0","PersonallyOwned":"Blocked","BlockedManufacturers":"Samsung","Scope":"","AssignedTo":"All devices"}],"ConfigDeviceAppProtectionPolicies":[{"Platform":"Android","Name":"Android Policy","AppsPublic":"Cortana, Microsoft Dynamics 365 for phones, Field Service (Dynamics 365), Dynamics 365 Sales, Microsoft Dynamics 365 for tablets, Microsoft Invoicing, Microsoft Edge, Power Automate, Azure Information Protection, Microsoft Launcher, Microsoft Kaizala, Microsoft Power Apps, Microsoft Excel, Skype for Business, Microsoft 365 (Office) (China), Microsoft Office (HL), Microsoft 365 Copilot, Microsoft Lens, Microsoft OneNote, Microsoft Outlook, Microsoft PowerPoint, Microsoft Word, Microsoft Planner, Microsoft Power BI, Microsoft Defender Endpoint, Microsoft SharePoint, Microsoft OneDrive, Microsoft Teams, Microsoft To-Do, Microsoft Whiteboard, Work Folders, Microsoft 365 Admin, Viva Engage, Microsoft StaffHub","AppsCustom":"com.microsoft.d365.fs.mobile, com.microsoft.lists.public, com.microsoft.ramobile, com.microsoft.stream, com.oracle.java.pdfviewer","BackupOrgDataToICloudOrGoogle":"Allow","SendOrgDataToOtherApps":"Policy managed apps","AppsToExempt":"Trello:app:trello","SaveCopiesOfOrgData":"Block","AllowUserToSaveCopiesToSelectedServices":"Box, Local storage, OneDrive for Business, SharePoint, Photo library","DataProtectionTransferTelecommunicationDataTo":"A specific dialer app","DataProtectionReceiveDataFromOtherApps":"Policy managed apps","DataProtectionOpenDataIntoOrgDocuments":"","DataProtectionAllowUsersToOpenDataFromSelectedServices":"","DataProtectionRestrictCutCopyBetweenOtherApps":"","DataProtectionCutCopyCharacterLimitForAnyApp":"","DataProtectionEncryptOrgData":"","DataProtectionSyncPolicyManagedAppDataWithNativeApps":"","DataProtectionPrintingOrgData":"","DataProtectionRestrictWebContentTransferWithOtherApps":"","DataProtectionOrgDataNotifications":"","ConditionalLaunchAppMaxPinAttempts":"","ConditionalLaunchAppOfflineGracePeriodBlockAccess":"","ConditionalLaunchAppOfflineGracePeriodWipeData":"","ConditionalLaunchAppDisabedAccount":"","ConditionalLaunchAppMinAppVersion":"","ConditionalLaunchDeviceRootedJailbrokenDevices":"Block access","ConditionalLaunchDevicePrimaryMtdService":"","ConditionalLaunchDeviceMaxAllowedDeviceThreatLevel":"","ConditionalLaunchDeviceMinOsVersion":"","ConditionalLaunchDeviceMaxOsVersion":"","Scope":"Default","IncludedGroups":"","ExcludedGroups":""},{"Platform":"iOS/iPadOS","Name":"iOS Policy","AppsPublic":"Adobe Acrobat Reader, Cortana, Microsoft Dynamics 365, Microsoft Invoicing, Microsoft Dynamics 365 for phones, Field Service (Dynamics 365), Dynamics 365 Sales, Skype for Business, Microsoft Kaizala, Microsoft Power Apps, Microsoft Edge, Microsoft 365 Admin, Microsoft Excel, Microsoft Outlook, Microsoft PowerPoint, Microsoft Word, Microsoft Lens, Microsoft 365 Copilot, Microsoft OneNote, Microsoft Planner, Microsoft Power BI, Power Automate, Azure Information Protection, Microsoft Defender Endpoint, Microsoft SharePoint, Microsoft StaffHub, Microsoft OneDrive, Microsoft Teams, Microsoft To-Do, Microsoft Whiteboard, Work Folders, Vera for Intune, Viva Engage","AppsCustom":"com.microsoft.d365.fs.mobile, com.microsoft.ramobile, com.microsoft.splists, com.microsoft.stream, com.microsoft.visio, my.manson.net","BackupOrgDataToICloudOrGoogle":"Block","SendOrgDataToOtherApps":"Policy managed apps with OS sharing","AppsToExempt":"","SaveCopiesOfOrgData":"Allow","AllowUserToSaveCopiesToSelectedServices":"Box, Local storage, OneDrive for Business, SharePoint, Photo library","DataProtectionTransferTelecommunicationDataTo":"A specific dialer app","DataProtectionReceiveDataFromOtherApps":"None","DataProtectionOpenDataIntoOrgDocuments":"","DataProtectionAllowUsersToOpenDataFromSelectedServices":"","DataProtectionRestrictCutCopyBetweenOtherApps":"","DataProtectionCutCopyCharacterLimitForAnyApp":"","DataProtectionEncryptOrgData":"","DataProtectionSyncPolicyManagedAppDataWithNativeApps":"","DataProtectionPrintingOrgData":"","DataProtectionRestrictWebContentTransferWithOtherApps":"","DataProtectionOrgDataNotifications":"","ConditionalLaunchAppMaxPinAttempts":"","ConditionalLaunchAppOfflineGracePeriodBlockAccess":"","ConditionalLaunchAppOfflineGracePeriodWipeData":"","ConditionalLaunchAppDisabedAccount":"","ConditionalLaunchAppMinAppVersion":"","ConditionalLaunchDeviceRootedJailbrokenDevices":"Wipe data","ConditionalLaunchDevicePrimaryMtdService":"","ConditionalLaunchDeviceMaxAllowedDeviceThreatLevel":"","ConditionalLaunchDeviceMinOsVersion":"","ConditionalLaunchDeviceMaxOsVersion":"","Scope":"Default","IncludedGroups":"","ExcludedGroups":""},{"Platform":"Windows","Name":"Windows Info Protect","AppsPublic":"","AppsCustom":"","BackupOrgDataToICloudOrGoogle":"","SendOrgDataToOtherApps":"","AppsToExempt":"","SaveCopiesOfOrgData":"","AllowUserToSaveCopiesToSelectedServices":"","DataProtectionTransferTelecommunicationDataTo":null,"DataProtectionReceiveDataFromOtherApps":null,"DataProtectionOpenDataIntoOrgDocuments":"","DataProtectionAllowUsersToOpenDataFromSelectedServices":"","DataProtectionRestrictCutCopyBetweenOtherApps":"","DataProtectionCutCopyCharacterLimitForAnyApp":"","DataProtectionEncryptOrgData":"","DataProtectionSyncPolicyManagedAppDataWithNativeApps":"","DataProtectionPrintingOrgData":"","DataProtectionRestrictWebContentTransferWithOtherApps":"","DataProtectionOrgDataNotifications":"","ConditionalLaunchAppMaxPinAttempts":"","ConditionalLaunchAppOfflineGracePeriodBlockAccess":"","ConditionalLaunchAppOfflineGracePeriodWipeData":"","ConditionalLaunchAppDisabedAccount":"","ConditionalLaunchAppMinAppVersion":"","ConditionalLaunchDeviceRootedJailbrokenDevices":null,"ConditionalLaunchDevicePrimaryMtdService":"","ConditionalLaunchDeviceMaxAllowedDeviceThreatLevel":"","ConditionalLaunchDeviceMinOsVersion":"","ConditionalLaunchDeviceMaxOsVersion":"","Scope":"Default","IncludedGroups":"","ExcludedGroups":""}]},"EndOfJson":"EndOfJson","IsDemo":"true"};var REACT_LAZY_TYPE=Symbol.for("react.lazy"),use=React$1[" use ".trim().toString()];function isPromiseLike(value2){return typeof value2=="object"&&value2!==null&&"then"in value2}__name(isPromiseLike,"isPromiseLike");function isLazyComponent(element2){return element2!=null&&typeof element2=="object"&&"$$typeof"in element2&&element2.$$typeof===REACT_LAZY_TYPE&&"_payload"in element2&&isPromiseLike(element2._payload)}__name(isLazyComponent,"isLazyComponent");function createSlot$2(ownerName){const SlotClone=createSlotClone$2(ownerName),Slot2=reactExports.forwardRef((props,forwardedRef)=>{let{children:children2,...slotProps}=props;isLazyComponent(children2)&&typeof use=="function"&&(children2=use(children2._payload));const childrenArray=reactExports.Children.toArray(children2),slottable=childrenArray.find(isSlottable$2);if(slottable){const newElement=slottable.props.children,newChildren=childrenArray.map(child=>child===slottable?reactExports.Children.count(newElement)>1?reactExports.Children.only(null):reactExports.isValidElement(newElement)?newElement.props.children:null:child);return jsxRuntimeExports.jsx(SlotClone,{...slotProps,ref:forwardedRef,children:reactExports.isValidElement(newElement)?reactExports.cloneElement(newElement,void 0,newChildren):null})}return jsxRuntimeExports.jsx(SlotClone,{...slotProps,ref:forwardedRef,children:children2})});return Slot2.displayName=`${ownerName}.Slot`,Slot2}__name(createSlot$2,"createSlot$2");var Slot$1=createSlot$2("Slot");function createSlotClone$2(ownerName){const SlotClone=reactExports.forwardRef((props,forwardedRef)=>{let{children:children2,...slotProps}=props;if(isLazyComponent(children2)&&typeof use=="function"&&(children2=use(children2._payload)),reactExports.isValidElement(children2)){const childrenRef=getElementRef$2(children2),props2=mergeProps$2(slotProps,children2.props);return children2.type!==reactExports.Fragment&&(props2.ref=forwardedRef?composeRefs(forwardedRef,childrenRef):childrenRef),reactExports.cloneElement(children2,props2)}return reactExports.Children.count(children2)>1?reactExports.Children.only(null):null});return SlotClone.displayName=`${ownerName}.SlotClone`,SlotClone}__name(createSlotClone$2,"createSlotClone$2");var SLOTTABLE_IDENTIFIER$3=Symbol("radix.slottable");function isSlottable$2(child){return reactExports.isValidElement(child)&&typeof child.type=="function"&&"__radixId"in child.type&&child.type.__radixId===SLOTTABLE_IDENTIFIER$3}__name(isSlottable$2,"isSlottable$2");function mergeProps$2(slotProps,childProps){const overrideProps={...childProps};for(const propName in childProps){const slotPropValue=slotProps[propName],childPropValue=childProps[propName];/^on[A-Z]/.test(propName)?slotPropValue&&childPropValue?overrideProps[propName]=(...args)=>{const result=childPropValue(...args);return slotPropValue(...args),result}:slotPropValue&&(overrideProps[propName]=slotPropValue):propName==="style"?overrideProps[propName]={...slotPropValue,...childPropValue}:propName==="className"&&(overrideProps[propName]=[slotPropValue,childPropValue].filter(Boolean).join(" "))}return{...slotProps,...overrideProps}}__name(mergeProps$2,"mergeProps$2");function getElementRef$2(element2){let getter=Object.getOwnPropertyDescriptor(element2.props,"ref")?.get,mayWarn=getter&&"isReactWarning"in getter&&getter.isReactWarning;return mayWarn?element2.ref:(getter=Object.getOwnPropertyDescriptor(element2,"ref")?.get,mayWarn=getter&&"isReactWarning"in getter&&getter.isReactWarning,mayWarn?element2.props.ref:element2.props.ref||element2.ref)}__name(getElementRef$2,"getElementRef$2");const buttonVariants=cva("inline-flex items-center justify-center whitespace-nowrap rounded-md text-sm font-medium ring-offset-background transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50",{variants:{variant:{default:"bg-primary text-primary-foreground hover:bg-primary/90",destructive:"bg-destructive text-destructive-foreground hover:bg-destructive/90",outline:"border border-input bg-background hover:bg-accent hover:text-accent-foreground",secondary:"bg-secondary text-secondary-foreground hover:bg-secondary/80",ghost:"hover:bg-accent hover:text-accent-foreground",link:"text-primary underline-offset-4 hover:underline"},size:{default:"h-10 px-4 py-2",sm:"h-9 rounded-md px-3",lg:"h-11 rounded-md px-8",icon:"h-10 w-10"}},defaultVariants:{variant:"default",size:"default"}}),Button=reactExports.forwardRef(({className,variant,size:size2,asChild=!1,...props},ref)=>{const Comp=asChild?Slot$1:"button";return jsxRuntimeExports.jsx(Comp,{className:cn$2(buttonVariants({variant,size:size2,className})),ref,...props})});Button.displayName="Button";function createSlot$1(ownerName){const SlotClone=createSlotClone$1(ownerName),Slot2=reactExports.forwardRef((props,forwardedRef)=>{const{children:children2,...slotProps}=props,childrenArray=reactExports.Children.toArray(children2),slottable=childrenArray.find(isSlottable$1);if(slottable){const newElement=slottable.props.children,newChildren=childrenArray.map(child=>child===slottable?reactExports.Children.count(newElement)>1?reactExports.Children.only(null):reactExports.isValidElement(newElement)?newElement.props.children:null:child);return jsxRuntimeExports.jsx(SlotClone,{...slotProps,ref:forwardedRef,children:reactExports.isValidElement(newElement)?reactExports.cloneElement(newElement,void 0,newChildren):null})}return jsxRuntimeExports.jsx(SlotClone,{...slotProps,ref:forwardedRef,children:children2})});return Slot2.displayName=`${ownerName}.Slot`,Slot2}__name(createSlot$1,"createSlot$1");function createSlotClone$1(ownerName){const SlotClone=reactExports.forwardRef((props,forwardedRef)=>{const{children:children2,...slotProps}=props;if(reactExports.isValidElement(children2)){const childrenRef=getElementRef$1(children2),props2=mergeProps$1(slotProps,children2.props);return children2.type!==reactExports.Fragment&&(props2.ref=forwardedRef?composeRefs(forwardedRef,childrenRef):childrenRef),reactExports.cloneElement(children2,props2)}return reactExports.Children.count(children2)>1?reactExports.Children.only(null):null});return SlotClone.displayName=`${ownerName}.SlotClone`,SlotClone}__name(createSlotClone$1,"createSlotClone$1");var SLOTTABLE_IDENTIFIER$2=Symbol("radix.slottable");function isSlottable$1(child){return reactExports.isValidElement(child)&&typeof child.type=="function"&&"__radixId"in child.type&&child.type.__radixId===SLOTTABLE_IDENTIFIER$2}__name(isSlottable$1,"isSlottable$1");function mergeProps$1(slotProps,childProps){const overrideProps={...childProps};for(const propName in childProps){const slotPropValue=slotProps[propName],childPropValue=childProps[propName];/^on[A-Z]/.test(propName)?slotPropValue&&childPropValue?overrideProps[propName]=(...args)=>{const result=childPropValue(...args);return slotPropValue(...args),result}:slotPropValue&&(overrideProps[propName]=slotPropValue):propName==="style"?overrideProps[propName]={...slotPropValue,...childPropValue}:propName==="className"&&(overrideProps[propName]=[slotPropValue,childPropValue].filter(Boolean).join(" "))}return{...slotProps,...overrideProps}}__name(mergeProps$1,"mergeProps$1");function getElementRef$1(element2){let getter=Object.getOwnPropertyDescriptor(element2.props,"ref")?.get,mayWarn=getter&&"isReactWarning"in getter&&getter.isReactWarning;return mayWarn?element2.ref:(getter=Object.getOwnPropertyDescriptor(element2,"ref")?.get,mayWarn=getter&&"isReactWarning"in getter&&getter.isReactWarning,mayWarn?element2.props.ref:element2.props.ref||element2.ref)}__name(getElementRef$1,"getElementRef$1");function createCollection(name2){const PROVIDER_NAME2=name2+"CollectionProvider",[createCollectionContext,createCollectionScope2]=createContextScope$1(PROVIDER_NAME2),[CollectionProviderImpl,useCollectionContext]=createCollectionContext(PROVIDER_NAME2,{collectionRef:{current:null},itemMap:new Map}),CollectionProvider=__name(props=>{const{scope,children:children2}=props,ref=React.useRef(null),itemMap=React.useRef(new Map).current;return jsxRuntimeExports.jsx(CollectionProviderImpl,{scope,itemMap,collectionRef:ref,children:children2})},"CollectionProvider");CollectionProvider.displayName=PROVIDER_NAME2;const COLLECTION_SLOT_NAME=name2+"CollectionSlot",CollectionSlotImpl=createSlot$1(COLLECTION_SLOT_NAME),CollectionSlot=React.forwardRef((props,forwardedRef)=>{const{scope,children:children2}=props,context=useCollectionContext(COLLECTION_SLOT_NAME,scope),composedRefs=useComposedRefs(forwardedRef,context.collectionRef);return jsxRuntimeExports.jsx(CollectionSlotImpl,{ref:composedRefs,children:children2})});CollectionSlot.displayName=COLLECTION_SLOT_NAME;const ITEM_SLOT_NAME=name2+"CollectionItemSlot",ITEM_DATA_ATTR="data-radix-collection-item",CollectionItemSlotImpl=createSlot$1(ITEM_SLOT_NAME),CollectionItemSlot=React.forwardRef((props,forwardedRef)=>{const{scope,children:children2,...itemData}=props,ref=React.useRef(null),composedRefs=useComposedRefs(forwardedRef,ref),context=useCollectionContext(ITEM_SLOT_NAME,scope);return React.useEffect(()=>(context.itemMap.set(ref,{ref,...itemData}),()=>void context.itemMap.delete(ref))),jsxRuntimeExports.jsx(CollectionItemSlotImpl,{[ITEM_DATA_ATTR]:"",ref:composedRefs,children:children2})});CollectionItemSlot.displayName=ITEM_SLOT_NAME;function useCollection2(scope){const context=useCollectionContext(name2+"CollectionConsumer",scope);return React.useCallback(()=>{const collectionNode=context.collectionRef.current;if(!collectionNode)return[];const orderedNodes=Array.from(collectionNode.querySelectorAll(`[${ITEM_DATA_ATTR}]`));return Array.from(context.itemMap.values()).sort((a2,b2)=>orderedNodes.indexOf(a2.ref.current)-orderedNodes.indexOf(b2.ref.current))},[context.collectionRef,context.itemMap])}return __name(useCollection2,"useCollection"),[{Provider:CollectionProvider,Slot:CollectionSlot,ItemSlot:CollectionItemSlot},useCollection2,createCollectionScope2]}__name(createCollection,"createCollection");var DirectionContext=reactExports.createContext(void 0);function useDirection(localDir){const globalDir=reactExports.useContext(DirectionContext);return localDir||globalDir||"ltr"}__name(useDirection,"useDirection");const sides=["top","right","bottom","left"],min$3=Math.min,max$3=Math.max,round$1=Math.round,floor=Math.floor,createCoords=__name(v2=>({x:v2,y:v2}),"createCoords"),oppositeSideMap={left:"right",right:"left",bottom:"top",top:"bottom"},oppositeAlignmentMap={start:"end",end:"start"};function clamp$1(start2,value2,end){return max$3(start2,min$3(value2,end))}__name(clamp$1,"clamp$1");function evaluate(value2,param){return typeof value2=="function"?value2(param):value2}__name(evaluate,"evaluate");function getSide(placement){return placement.split("-")[0]}__name(getSide,"getSide");function getAlignment(placement){return placement.split("-")[1]}__name(getAlignment,"getAlignment");function getOppositeAxis(axis){return axis==="x"?"y":"x"}__name(getOppositeAxis,"getOppositeAxis");function getAxisLength(axis){return axis==="y"?"height":"width"}__name(getAxisLength,"getAxisLength");const yAxisSides=new Set(["top","bottom"]);function getSideAxis(placement){return yAxisSides.has(getSide(placement))?"y":"x"}__name(getSideAxis,"getSideAxis");function getAlignmentAxis(placement){return getOppositeAxis(getSideAxis(placement))}__name(getAlignmentAxis,"getAlignmentAxis");function getAlignmentSides(placement,rects,rtl){rtl===void 0&&(rtl=!1);const alignment=getAlignment(placement),alignmentAxis=getAlignmentAxis(placement),length=getAxisLength(alignmentAxis);let mainAlignmentSide=alignmentAxis==="x"?alignment===(rtl?"end":"start")?"right":"left":alignment==="start"?"bottom":"top";return rects.reference[length]>rects.floating[length]&&(mainAlignmentSide=getOppositePlacement(mainAlignmentSide)),[mainAlignmentSide,getOppositePlacement(mainAlignmentSide)]}__name(getAlignmentSides,"getAlignmentSides");function getExpandedPlacements(placement){const oppositePlacement=getOppositePlacement(placement);return[getOppositeAlignmentPlacement(placement),oppositePlacement,getOppositeAlignmentPlacement(oppositePlacement)]}__name(getExpandedPlacements,"getExpandedPlacements");function getOppositeAlignmentPlacement(placement){return placement.replace(/start|end/g,alignment=>oppositeAlignmentMap[alignment])}__name(getOppositeAlignmentPlacement,"getOppositeAlignmentPlacement");const lrPlacement=["left","right"],rlPlacement=["right","left"],tbPlacement=["top","bottom"],btPlacement=["bottom","top"];function getSideList(side,isStart,rtl){switch(side){case"top":case"bottom":return rtl?isStart?rlPlacement:lrPlacement:isStart?lrPlacement:rlPlacement;case"left":case"right":return isStart?tbPlacement:btPlacement;default:return[]}}__name(getSideList,"getSideList");function getOppositeAxisPlacements(placement,flipAlignment,direction,rtl){const alignment=getAlignment(placement);let list2=getSideList(getSide(placement),direction==="start",rtl);return alignment&&(list2=list2.map(side=>side+"-"+alignment),flipAlignment&&(list2=list2.concat(list2.map(getOppositeAlignmentPlacement)))),list2}__name(getOppositeAxisPlacements,"getOppositeAxisPlacements");function getOppositePlacement(placement){return placement.replace(/left|right|bottom|top/g,side=>oppositeSideMap[side])}__name(getOppositePlacement,"getOppositePlacement");function expandPaddingObject(padding){return{top:0,right:0,bottom:0,left:0,...padding}}__name(expandPaddingObject,"expandPaddingObject");function getPaddingObject(padding){return typeof padding!="number"?expandPaddingObject(padding):{top:padding,right:padding,bottom:padding,left:padding}}__name(getPaddingObject,"getPaddingObject");function rectToClientRect(rect){const{x:x2,y:y2,width,height}=rect;return{width,height,top:y2,left:x2,right:x2+width,bottom:y2+height,x:x2,y:y2}}__name(rectToClientRect,"rectToClientRect");function computeCoordsFromPlacement(_ref,placement,rtl){let{reference,floating}=_ref;const sideAxis=getSideAxis(placement),alignmentAxis=getAlignmentAxis(placement),alignLength=getAxisLength(alignmentAxis),side=getSide(placement),isVertical=sideAxis==="y",commonX=reference.x+reference.width/2-floating.width/2,commonY=reference.y+reference.height/2-floating.height/2,commonAlign=reference[alignLength]/2-floating[alignLength]/2;let coords;switch(side){case"top":coords={x:commonX,y:reference.y-floating.height};break;case"bottom":coords={x:commonX,y:reference.y+reference.height};break;case"right":coords={x:reference.x+reference.width,y:commonY};break;case"left":coords={x:reference.x-floating.width,y:commonY};break;default:coords={x:reference.x,y:reference.y}}switch(getAlignment(placement)){case"start":coords[alignmentAxis]-=commonAlign*(rtl&&isVertical?-1:1);break;case"end":coords[alignmentAxis]+=commonAlign*(rtl&&isVertical?-1:1);break}return coords}__name(computeCoordsFromPlacement,"computeCoordsFromPlacement");const computePosition$1=__name(async(reference,floating,config2)=>{const{placement="bottom",strategy="absolute",middleware=[],platform:platform2}=config2,validMiddleware=middleware.filter(Boolean),rtl=await(platform2.isRTL==null?void 0:platform2.isRTL(floating));let rects=await platform2.getElementRects({reference,floating,strategy}),{x:x2,y:y2}=computeCoordsFromPlacement(rects,placement,rtl),statefulPlacement=placement,middlewareData={},resetCount=0;for(let i2=0;i2({name:"arrow",options,async fn(state){const{x:x2,y:y2,placement,rects,platform:platform2,elements,middlewareData}=state,{element:element2,padding=0}=evaluate(options,state)||{};if(element2==null)return{};const paddingObject=getPaddingObject(padding),coords={x:x2,y:y2},axis=getAlignmentAxis(placement),length=getAxisLength(axis),arrowDimensions=await platform2.getDimensions(element2),isYAxis=axis==="y",minProp=isYAxis?"top":"left",maxProp=isYAxis?"bottom":"right",clientProp=isYAxis?"clientHeight":"clientWidth",endDiff=rects.reference[length]+rects.reference[axis]-coords[axis]-rects.floating[length],startDiff=coords[axis]-rects.reference[axis],arrowOffsetParent=await(platform2.getOffsetParent==null?void 0:platform2.getOffsetParent(element2));let clientSize=arrowOffsetParent?arrowOffsetParent[clientProp]:0;(!clientSize||!await(platform2.isElement==null?void 0:platform2.isElement(arrowOffsetParent)))&&(clientSize=elements.floating[clientProp]||rects.floating[length]);const centerToReference=endDiff/2-startDiff/2,largestPossiblePadding=clientSize/2-arrowDimensions[length]/2-1,minPadding=min$3(paddingObject[minProp],largestPossiblePadding),maxPadding=min$3(paddingObject[maxProp],largestPossiblePadding),min$12=minPadding,max2=clientSize-arrowDimensions[length]-maxPadding,center2=clientSize/2-arrowDimensions[length]/2+centerToReference,offset2=clamp$1(min$12,center2,max2),shouldAddOffset=!middlewareData.arrow&&getAlignment(placement)!=null&¢er2!==offset2&&rects.reference[length]/2-(center2side2<=0)){var _middlewareData$flip2,_overflowsData$filter;const nextIndex=(((_middlewareData$flip2=middlewareData.flip)==null?void 0:_middlewareData$flip2.index)||0)+1,nextPlacement=placements[nextIndex];if(nextPlacement&&(!(checkCrossAxis==="alignment"?initialSideAxis!==getSideAxis(nextPlacement):!1)||overflowsData.every(d=>getSideAxis(d.placement)===initialSideAxis?d.overflows[0]>0:!0)))return{data:{index:nextIndex,overflows:overflowsData},reset:{placement:nextPlacement}};let resetPlacement=(_overflowsData$filter=overflowsData.filter(d=>d.overflows[0]<=0).sort((a2,b2)=>a2.overflows[1]-b2.overflows[1])[0])==null?void 0:_overflowsData$filter.placement;if(!resetPlacement)switch(fallbackStrategy){case"bestFit":{var _overflowsData$filter2;const placement2=(_overflowsData$filter2=overflowsData.filter(d=>{if(hasFallbackAxisSideDirection){const currentSideAxis=getSideAxis(d.placement);return currentSideAxis===initialSideAxis||currentSideAxis==="y"}return!0}).map(d=>[d.placement,d.overflows.filter(overflow2=>overflow2>0).reduce((acc,overflow2)=>acc+overflow2,0)]).sort((a2,b2)=>a2[1]-b2[1])[0])==null?void 0:_overflowsData$filter2[0];placement2&&(resetPlacement=placement2);break}case"initialPlacement":resetPlacement=initialPlacement;break}if(placement!==resetPlacement)return{reset:{placement:resetPlacement}}}return{}}}},"flip$2");function getSideOffsets(overflow,rect){return{top:overflow.top-rect.height,right:overflow.right-rect.width,bottom:overflow.bottom-rect.height,left:overflow.left-rect.width}}__name(getSideOffsets,"getSideOffsets");function isAnySideFullyClipped(overflow){return sides.some(side=>overflow[side]>=0)}__name(isAnySideFullyClipped,"isAnySideFullyClipped");const hide$2=__name(function(options){return options===void 0&&(options={}),{name:"hide",options,async fn(state){const{rects}=state,{strategy="referenceHidden",...detectOverflowOptions}=evaluate(options,state);switch(strategy){case"referenceHidden":{const overflow=await detectOverflow(state,{...detectOverflowOptions,elementContext:"reference"}),offsets=getSideOffsets(overflow,rects.reference);return{data:{referenceHiddenOffsets:offsets,referenceHidden:isAnySideFullyClipped(offsets)}}}case"escaped":{const overflow=await detectOverflow(state,{...detectOverflowOptions,altBoundary:!0}),offsets=getSideOffsets(overflow,rects.floating);return{data:{escapedOffsets:offsets,escaped:isAnySideFullyClipped(offsets)}}}default:return{}}}}},"hide$2"),originSides=new Set(["left","top"]);async function convertValueToCoords(state,options){const{placement,platform:platform2,elements}=state,rtl=await(platform2.isRTL==null?void 0:platform2.isRTL(elements.floating)),side=getSide(placement),alignment=getAlignment(placement),isVertical=getSideAxis(placement)==="y",mainAxisMulti=originSides.has(side)?-1:1,crossAxisMulti=rtl&&isVertical?-1:1,rawValue=evaluate(options,state);let{mainAxis,crossAxis,alignmentAxis}=typeof rawValue=="number"?{mainAxis:rawValue,crossAxis:0,alignmentAxis:null}:{mainAxis:rawValue.mainAxis||0,crossAxis:rawValue.crossAxis||0,alignmentAxis:rawValue.alignmentAxis};return alignment&&typeof alignmentAxis=="number"&&(crossAxis=alignment==="end"?alignmentAxis*-1:alignmentAxis),isVertical?{x:crossAxis*crossAxisMulti,y:mainAxis*mainAxisMulti}:{x:mainAxis*mainAxisMulti,y:crossAxis*crossAxisMulti}}__name(convertValueToCoords,"convertValueToCoords");const offset$2=__name(function(options){return options===void 0&&(options=0),{name:"offset",options,async fn(state){var _middlewareData$offse,_middlewareData$arrow;const{x:x2,y:y2,placement,middlewareData}=state,diffCoords=await convertValueToCoords(state,options);return placement===((_middlewareData$offse=middlewareData.offset)==null?void 0:_middlewareData$offse.placement)&&(_middlewareData$arrow=middlewareData.arrow)!=null&&_middlewareData$arrow.alignmentOffset?{}:{x:x2+diffCoords.x,y:y2+diffCoords.y,data:{...diffCoords,placement}}}}},"offset$2"),shift$2=__name(function(options){return options===void 0&&(options={}),{name:"shift",options,async fn(state){const{x:x2,y:y2,placement}=state,{mainAxis:checkMainAxis=!0,crossAxis:checkCrossAxis=!1,limiter={fn:__name(_ref=>{let{x:x3,y:y3}=_ref;return{x:x3,y:y3}},"fn")},...detectOverflowOptions}=evaluate(options,state),coords={x:x2,y:y2},overflow=await detectOverflow(state,detectOverflowOptions),crossAxis=getSideAxis(getSide(placement)),mainAxis=getOppositeAxis(crossAxis);let mainAxisCoord=coords[mainAxis],crossAxisCoord=coords[crossAxis];if(checkMainAxis){const minSide=mainAxis==="y"?"top":"left",maxSide=mainAxis==="y"?"bottom":"right",min2=mainAxisCoord+overflow[minSide],max2=mainAxisCoord-overflow[maxSide];mainAxisCoord=clamp$1(min2,mainAxisCoord,max2)}if(checkCrossAxis){const minSide=crossAxis==="y"?"top":"left",maxSide=crossAxis==="y"?"bottom":"right",min2=crossAxisCoord+overflow[minSide],max2=crossAxisCoord-overflow[maxSide];crossAxisCoord=clamp$1(min2,crossAxisCoord,max2)}const limitedCoords=limiter.fn({...state,[mainAxis]:mainAxisCoord,[crossAxis]:crossAxisCoord});return{...limitedCoords,data:{x:limitedCoords.x-x2,y:limitedCoords.y-y2,enabled:{[mainAxis]:checkMainAxis,[crossAxis]:checkCrossAxis}}}}}},"shift$2"),limitShift$2=__name(function(options){return options===void 0&&(options={}),{options,fn(state){const{x:x2,y:y2,placement,rects,middlewareData}=state,{offset:offset2=0,mainAxis:checkMainAxis=!0,crossAxis:checkCrossAxis=!0}=evaluate(options,state),coords={x:x2,y:y2},crossAxis=getSideAxis(placement),mainAxis=getOppositeAxis(crossAxis);let mainAxisCoord=coords[mainAxis],crossAxisCoord=coords[crossAxis];const rawOffset=evaluate(offset2,state),computedOffset=typeof rawOffset=="number"?{mainAxis:rawOffset,crossAxis:0}:{mainAxis:0,crossAxis:0,...rawOffset};if(checkMainAxis){const len=mainAxis==="y"?"height":"width",limitMin=rects.reference[mainAxis]-rects.floating[len]+computedOffset.mainAxis,limitMax=rects.reference[mainAxis]+rects.reference[len]-computedOffset.mainAxis;mainAxisCoordlimitMax&&(mainAxisCoord=limitMax)}if(checkCrossAxis){var _middlewareData$offse,_middlewareData$offse2;const len=mainAxis==="y"?"width":"height",isOriginSide=originSides.has(getSide(placement)),limitMin=rects.reference[crossAxis]-rects.floating[len]+(isOriginSide&&((_middlewareData$offse=middlewareData.offset)==null?void 0:_middlewareData$offse[crossAxis])||0)+(isOriginSide?0:computedOffset.crossAxis),limitMax=rects.reference[crossAxis]+rects.reference[len]+(isOriginSide?0:((_middlewareData$offse2=middlewareData.offset)==null?void 0:_middlewareData$offse2[crossAxis])||0)-(isOriginSide?computedOffset.crossAxis:0);crossAxisCoordlimitMax&&(crossAxisCoord=limitMax)}return{[mainAxis]:mainAxisCoord,[crossAxis]:crossAxisCoord}}}},"limitShift$2"),size$2=__name(function(options){return options===void 0&&(options={}),{name:"size",options,async fn(state){var _state$middlewareData,_state$middlewareData2;const{placement,rects,platform:platform2,elements}=state,{apply=__name(()=>{},"apply"),...detectOverflowOptions}=evaluate(options,state),overflow=await detectOverflow(state,detectOverflowOptions),side=getSide(placement),alignment=getAlignment(placement),isYAxis=getSideAxis(placement)==="y",{width,height}=rects.floating;let heightSide,widthSide;side==="top"||side==="bottom"?(heightSide=side,widthSide=alignment===(await(platform2.isRTL==null?void 0:platform2.isRTL(elements.floating))?"start":"end")?"left":"right"):(widthSide=side,heightSide=alignment==="end"?"top":"bottom");const maximumClippingHeight=height-overflow.top-overflow.bottom,maximumClippingWidth=width-overflow.left-overflow.right,overflowAvailableHeight=min$3(height-overflow[heightSide],maximumClippingHeight),overflowAvailableWidth=min$3(width-overflow[widthSide],maximumClippingWidth),noShift=!state.middlewareData.shift;let availableHeight=overflowAvailableHeight,availableWidth=overflowAvailableWidth;if((_state$middlewareData=state.middlewareData.shift)!=null&&_state$middlewareData.enabled.x&&(availableWidth=maximumClippingWidth),(_state$middlewareData2=state.middlewareData.shift)!=null&&_state$middlewareData2.enabled.y&&(availableHeight=maximumClippingHeight),noShift&&!alignment){const xMin=max$3(overflow.left,0),xMax=max$3(overflow.right,0),yMin=max$3(overflow.top,0),yMax=max$3(overflow.bottom,0);isYAxis?availableWidth=width-2*(xMin!==0||xMax!==0?xMin+xMax:max$3(overflow.left,overflow.right)):availableHeight=height-2*(yMin!==0||yMax!==0?yMin+yMax:max$3(overflow.top,overflow.bottom))}await apply({...state,availableWidth,availableHeight});const nextDimensions=await platform2.getDimensions(elements.floating);return width!==nextDimensions.width||height!==nextDimensions.height?{reset:{rects:!0}}:{}}}},"size$2");function hasWindow(){return typeof window<"u"}__name(hasWindow,"hasWindow");function getNodeName(node2){return isNode(node2)?(node2.nodeName||"").toLowerCase():"#document"}__name(getNodeName,"getNodeName");function getWindow(node2){var _node$ownerDocument;return(node2==null||(_node$ownerDocument=node2.ownerDocument)==null?void 0:_node$ownerDocument.defaultView)||window}__name(getWindow,"getWindow");function getDocumentElement(node2){var _ref;return(_ref=(isNode(node2)?node2.ownerDocument:node2.document)||window.document)==null?void 0:_ref.documentElement}__name(getDocumentElement,"getDocumentElement");function isNode(value2){return hasWindow()?value2 instanceof Node||value2 instanceof getWindow(value2).Node:!1}__name(isNode,"isNode");function isElement(value2){return hasWindow()?value2 instanceof Element||value2 instanceof getWindow(value2).Element:!1}__name(isElement,"isElement");function isHTMLElement(value2){return hasWindow()?value2 instanceof HTMLElement||value2 instanceof getWindow(value2).HTMLElement:!1}__name(isHTMLElement,"isHTMLElement");function isShadowRoot(value2){return!hasWindow()||typeof ShadowRoot>"u"?!1:value2 instanceof ShadowRoot||value2 instanceof getWindow(value2).ShadowRoot}__name(isShadowRoot,"isShadowRoot");const invalidOverflowDisplayValues=new Set(["inline","contents"]);function isOverflowElement(element2){const{overflow,overflowX,overflowY,display}=getComputedStyle$1(element2);return/auto|scroll|overlay|hidden|clip/.test(overflow+overflowY+overflowX)&&!invalidOverflowDisplayValues.has(display)}__name(isOverflowElement,"isOverflowElement");const tableElements$1=new Set(["table","td","th"]);function isTableElement(element2){return tableElements$1.has(getNodeName(element2))}__name(isTableElement,"isTableElement");const topLayerSelectors=[":popover-open",":modal"];function isTopLayer(element2){return topLayerSelectors.some(selector=>{try{return element2.matches(selector)}catch{return!1}})}__name(isTopLayer,"isTopLayer");const transformProperties=["transform","translate","scale","rotate","perspective"],willChangeValues=["transform","translate","scale","rotate","perspective","filter"],containValues=["paint","layout","strict","content"];function isContainingBlock(elementOrCss){const webkit=isWebKit(),css=isElement(elementOrCss)?getComputedStyle$1(elementOrCss):elementOrCss;return transformProperties.some(value2=>css[value2]?css[value2]!=="none":!1)||(css.containerType?css.containerType!=="normal":!1)||!webkit&&(css.backdropFilter?css.backdropFilter!=="none":!1)||!webkit&&(css.filter?css.filter!=="none":!1)||willChangeValues.some(value2=>(css.willChange||"").includes(value2))||containValues.some(value2=>(css.contain||"").includes(value2))}__name(isContainingBlock,"isContainingBlock");function getContainingBlock(element2){let currentNode=getParentNode(element2);for(;isHTMLElement(currentNode)&&!isLastTraversableNode(currentNode);){if(isContainingBlock(currentNode))return currentNode;if(isTopLayer(currentNode))return null;currentNode=getParentNode(currentNode)}return null}__name(getContainingBlock,"getContainingBlock");function isWebKit(){return typeof CSS>"u"||!CSS.supports?!1:CSS.supports("-webkit-backdrop-filter","none")}__name(isWebKit,"isWebKit");const lastTraversableNodeNames=new Set(["html","body","#document"]);function isLastTraversableNode(node2){return lastTraversableNodeNames.has(getNodeName(node2))}__name(isLastTraversableNode,"isLastTraversableNode");function getComputedStyle$1(element2){return getWindow(element2).getComputedStyle(element2)}__name(getComputedStyle$1,"getComputedStyle$1");function getNodeScroll(element2){return isElement(element2)?{scrollLeft:element2.scrollLeft,scrollTop:element2.scrollTop}:{scrollLeft:element2.scrollX,scrollTop:element2.scrollY}}__name(getNodeScroll,"getNodeScroll");function getParentNode(node2){if(getNodeName(node2)==="html")return node2;const result=node2.assignedSlot||node2.parentNode||isShadowRoot(node2)&&node2.host||getDocumentElement(node2);return isShadowRoot(result)?result.host:result}__name(getParentNode,"getParentNode");function getNearestOverflowAncestor(node2){const parentNode=getParentNode(node2);return isLastTraversableNode(parentNode)?node2.ownerDocument?node2.ownerDocument.body:node2.body:isHTMLElement(parentNode)&&isOverflowElement(parentNode)?parentNode:getNearestOverflowAncestor(parentNode)}__name(getNearestOverflowAncestor,"getNearestOverflowAncestor");function getOverflowAncestors(node2,list2,traverseIframes){var _node$ownerDocument2;list2===void 0&&(list2=[]),traverseIframes===void 0&&(traverseIframes=!0);const scrollableAncestor=getNearestOverflowAncestor(node2),isBody=scrollableAncestor===((_node$ownerDocument2=node2.ownerDocument)==null?void 0:_node$ownerDocument2.body),win=getWindow(scrollableAncestor);if(isBody){const frameElement=getFrameElement(win);return list2.concat(win,win.visualViewport||[],isOverflowElement(scrollableAncestor)?scrollableAncestor:[],frameElement&&traverseIframes?getOverflowAncestors(frameElement):[])}return list2.concat(scrollableAncestor,getOverflowAncestors(scrollableAncestor,[],traverseIframes))}__name(getOverflowAncestors,"getOverflowAncestors");function getFrameElement(win){return win.parent&&Object.getPrototypeOf(win.parent)?win.frameElement:null}__name(getFrameElement,"getFrameElement");function getCssDimensions(element2){const css=getComputedStyle$1(element2);let width=parseFloat(css.width)||0,height=parseFloat(css.height)||0;const hasOffset=isHTMLElement(element2),offsetWidth=hasOffset?element2.offsetWidth:width,offsetHeight=hasOffset?element2.offsetHeight:height,shouldFallback=round$1(width)!==offsetWidth||round$1(height)!==offsetHeight;return shouldFallback&&(width=offsetWidth,height=offsetHeight),{width,height,$:shouldFallback}}__name(getCssDimensions,"getCssDimensions");function unwrapElement(element2){return isElement(element2)?element2:element2.contextElement}__name(unwrapElement,"unwrapElement");function getScale(element2){const domElement=unwrapElement(element2);if(!isHTMLElement(domElement))return createCoords(1);const rect=domElement.getBoundingClientRect(),{width,height,$:$2}=getCssDimensions(domElement);let x2=($2?round$1(rect.width):rect.width)/width,y2=($2?round$1(rect.height):rect.height)/height;return(!x2||!Number.isFinite(x2))&&(x2=1),(!y2||!Number.isFinite(y2))&&(y2=1),{x:x2,y:y2}}__name(getScale,"getScale");const noOffsets=createCoords(0);function getVisualOffsets(element2){const win=getWindow(element2);return!isWebKit()||!win.visualViewport?noOffsets:{x:win.visualViewport.offsetLeft,y:win.visualViewport.offsetTop}}__name(getVisualOffsets,"getVisualOffsets");function shouldAddVisualOffsets(element2,isFixed,floatingOffsetParent){return isFixed===void 0&&(isFixed=!1),!floatingOffsetParent||isFixed&&floatingOffsetParent!==getWindow(element2)?!1:isFixed}__name(shouldAddVisualOffsets,"shouldAddVisualOffsets");function getBoundingClientRect(element2,includeScale,isFixedStrategy,offsetParent){includeScale===void 0&&(includeScale=!1),isFixedStrategy===void 0&&(isFixedStrategy=!1);const clientRect=element2.getBoundingClientRect(),domElement=unwrapElement(element2);let scale=createCoords(1);includeScale&&(offsetParent?isElement(offsetParent)&&(scale=getScale(offsetParent)):scale=getScale(element2));const visualOffsets=shouldAddVisualOffsets(domElement,isFixedStrategy,offsetParent)?getVisualOffsets(domElement):createCoords(0);let x2=(clientRect.left+visualOffsets.x)/scale.x,y2=(clientRect.top+visualOffsets.y)/scale.y,width=clientRect.width/scale.x,height=clientRect.height/scale.y;if(domElement){const win=getWindow(domElement),offsetWin=offsetParent&&isElement(offsetParent)?getWindow(offsetParent):offsetParent;let currentWin=win,currentIFrame=getFrameElement(currentWin);for(;currentIFrame&&offsetParent&&offsetWin!==currentWin;){const iframeScale=getScale(currentIFrame),iframeRect=currentIFrame.getBoundingClientRect(),css=getComputedStyle$1(currentIFrame),left2=iframeRect.left+(currentIFrame.clientLeft+parseFloat(css.paddingLeft))*iframeScale.x,top=iframeRect.top+(currentIFrame.clientTop+parseFloat(css.paddingTop))*iframeScale.y;x2*=iframeScale.x,y2*=iframeScale.y,width*=iframeScale.x,height*=iframeScale.y,x2+=left2,y2+=top,currentWin=getWindow(currentIFrame),currentIFrame=getFrameElement(currentWin)}}return rectToClientRect({width,height,x:x2,y:y2})}__name(getBoundingClientRect,"getBoundingClientRect");function getWindowScrollBarX(element2,rect){const leftScroll=getNodeScroll(element2).scrollLeft;return rect?rect.left+leftScroll:getBoundingClientRect(getDocumentElement(element2)).left+leftScroll}__name(getWindowScrollBarX,"getWindowScrollBarX");function getHTMLOffset(documentElement,scroll){const htmlRect=documentElement.getBoundingClientRect(),x2=htmlRect.left+scroll.scrollLeft-getWindowScrollBarX(documentElement,htmlRect),y2=htmlRect.top+scroll.scrollTop;return{x:x2,y:y2}}__name(getHTMLOffset,"getHTMLOffset");function convertOffsetParentRelativeRectToViewportRelativeRect(_ref){let{elements,rect,offsetParent,strategy}=_ref;const isFixed=strategy==="fixed",documentElement=getDocumentElement(offsetParent),topLayer=elements?isTopLayer(elements.floating):!1;if(offsetParent===documentElement||topLayer&&isFixed)return rect;let scroll={scrollLeft:0,scrollTop:0},scale=createCoords(1);const offsets=createCoords(0),isOffsetParentAnElement=isHTMLElement(offsetParent);if((isOffsetParentAnElement||!isOffsetParentAnElement&&!isFixed)&&((getNodeName(offsetParent)!=="body"||isOverflowElement(documentElement))&&(scroll=getNodeScroll(offsetParent)),isHTMLElement(offsetParent))){const offsetRect=getBoundingClientRect(offsetParent);scale=getScale(offsetParent),offsets.x=offsetRect.x+offsetParent.clientLeft,offsets.y=offsetRect.y+offsetParent.clientTop}const htmlOffset=documentElement&&!isOffsetParentAnElement&&!isFixed?getHTMLOffset(documentElement,scroll):createCoords(0);return{width:rect.width*scale.x,height:rect.height*scale.y,x:rect.x*scale.x-scroll.scrollLeft*scale.x+offsets.x+htmlOffset.x,y:rect.y*scale.y-scroll.scrollTop*scale.y+offsets.y+htmlOffset.y}}__name(convertOffsetParentRelativeRectToViewportRelativeRect,"convertOffsetParentRelativeRectToViewportRelativeRect");function getClientRects(element2){return Array.from(element2.getClientRects())}__name(getClientRects,"getClientRects");function getDocumentRect(element2){const html2=getDocumentElement(element2),scroll=getNodeScroll(element2),body=element2.ownerDocument.body,width=max$3(html2.scrollWidth,html2.clientWidth,body.scrollWidth,body.clientWidth),height=max$3(html2.scrollHeight,html2.clientHeight,body.scrollHeight,body.clientHeight);let x2=-scroll.scrollLeft+getWindowScrollBarX(element2);const y2=-scroll.scrollTop;return getComputedStyle$1(body).direction==="rtl"&&(x2+=max$3(html2.clientWidth,body.clientWidth)-width),{width,height,x:x2,y:y2}}__name(getDocumentRect,"getDocumentRect");const SCROLLBAR_MAX=25;function getViewportRect(element2,strategy){const win=getWindow(element2),html2=getDocumentElement(element2),visualViewport=win.visualViewport;let width=html2.clientWidth,height=html2.clientHeight,x2=0,y2=0;if(visualViewport){width=visualViewport.width,height=visualViewport.height;const visualViewportBased=isWebKit();(!visualViewportBased||visualViewportBased&&strategy==="fixed")&&(x2=visualViewport.offsetLeft,y2=visualViewport.offsetTop)}const windowScrollbarX=getWindowScrollBarX(html2);if(windowScrollbarX<=0){const doc=html2.ownerDocument,body=doc.body,bodyStyles=getComputedStyle(body),bodyMarginInline=doc.compatMode==="CSS1Compat"&&parseFloat(bodyStyles.marginLeft)+parseFloat(bodyStyles.marginRight)||0,clippingStableScrollbarWidth=Math.abs(html2.clientWidth-body.clientWidth-bodyMarginInline);clippingStableScrollbarWidth<=SCROLLBAR_MAX&&(width-=clippingStableScrollbarWidth)}else windowScrollbarX<=SCROLLBAR_MAX&&(width+=windowScrollbarX);return{width,height,x:x2,y:y2}}__name(getViewportRect,"getViewportRect");const absoluteOrFixed=new Set(["absolute","fixed"]);function getInnerBoundingClientRect(element2,strategy){const clientRect=getBoundingClientRect(element2,!0,strategy==="fixed"),top=clientRect.top+element2.clientTop,left2=clientRect.left+element2.clientLeft,scale=isHTMLElement(element2)?getScale(element2):createCoords(1),width=element2.clientWidth*scale.x,height=element2.clientHeight*scale.y,x2=left2*scale.x,y2=top*scale.y;return{width,height,x:x2,y:y2}}__name(getInnerBoundingClientRect,"getInnerBoundingClientRect");function getClientRectFromClippingAncestor(element2,clippingAncestor,strategy){let rect;if(clippingAncestor==="viewport")rect=getViewportRect(element2,strategy);else if(clippingAncestor==="document")rect=getDocumentRect(getDocumentElement(element2));else if(isElement(clippingAncestor))rect=getInnerBoundingClientRect(clippingAncestor,strategy);else{const visualOffsets=getVisualOffsets(element2);rect={x:clippingAncestor.x-visualOffsets.x,y:clippingAncestor.y-visualOffsets.y,width:clippingAncestor.width,height:clippingAncestor.height}}return rectToClientRect(rect)}__name(getClientRectFromClippingAncestor,"getClientRectFromClippingAncestor");function hasFixedPositionAncestor(element2,stopNode){const parentNode=getParentNode(element2);return parentNode===stopNode||!isElement(parentNode)||isLastTraversableNode(parentNode)?!1:getComputedStyle$1(parentNode).position==="fixed"||hasFixedPositionAncestor(parentNode,stopNode)}__name(hasFixedPositionAncestor,"hasFixedPositionAncestor");function getClippingElementAncestors(element2,cache){const cachedResult=cache.get(element2);if(cachedResult)return cachedResult;let result=getOverflowAncestors(element2,[],!1).filter(el=>isElement(el)&&getNodeName(el)!=="body"),currentContainingBlockComputedStyle=null;const elementIsFixed=getComputedStyle$1(element2).position==="fixed";let currentNode=elementIsFixed?getParentNode(element2):element2;for(;isElement(currentNode)&&!isLastTraversableNode(currentNode);){const computedStyle=getComputedStyle$1(currentNode),currentNodeIsContaining=isContainingBlock(currentNode);!currentNodeIsContaining&&computedStyle.position==="fixed"&&(currentContainingBlockComputedStyle=null),(elementIsFixed?!currentNodeIsContaining&&!currentContainingBlockComputedStyle:!currentNodeIsContaining&&computedStyle.position==="static"&&!!currentContainingBlockComputedStyle&&absoluteOrFixed.has(currentContainingBlockComputedStyle.position)||isOverflowElement(currentNode)&&!currentNodeIsContaining&&hasFixedPositionAncestor(element2,currentNode))?result=result.filter(ancestor=>ancestor!==currentNode):currentContainingBlockComputedStyle=computedStyle,currentNode=getParentNode(currentNode)}return cache.set(element2,result),result}__name(getClippingElementAncestors,"getClippingElementAncestors");function getClippingRect(_ref){let{element:element2,boundary,rootBoundary,strategy}=_ref;const clippingAncestors=[...boundary==="clippingAncestors"?isTopLayer(element2)?[]:getClippingElementAncestors(element2,this._c):[].concat(boundary),rootBoundary],firstClippingAncestor=clippingAncestors[0],clippingRect=clippingAncestors.reduce((accRect,clippingAncestor)=>{const rect=getClientRectFromClippingAncestor(element2,clippingAncestor,strategy);return accRect.top=max$3(rect.top,accRect.top),accRect.right=min$3(rect.right,accRect.right),accRect.bottom=min$3(rect.bottom,accRect.bottom),accRect.left=max$3(rect.left,accRect.left),accRect},getClientRectFromClippingAncestor(element2,firstClippingAncestor,strategy));return{width:clippingRect.right-clippingRect.left,height:clippingRect.bottom-clippingRect.top,x:clippingRect.left,y:clippingRect.top}}__name(getClippingRect,"getClippingRect");function getDimensions(element2){const{width,height}=getCssDimensions(element2);return{width,height}}__name(getDimensions,"getDimensions");function getRectRelativeToOffsetParent(element2,offsetParent,strategy){const isOffsetParentAnElement=isHTMLElement(offsetParent),documentElement=getDocumentElement(offsetParent),isFixed=strategy==="fixed",rect=getBoundingClientRect(element2,!0,isFixed,offsetParent);let scroll={scrollLeft:0,scrollTop:0};const offsets=createCoords(0);function setLeftRTLScrollbarOffset(){offsets.x=getWindowScrollBarX(documentElement)}if(__name(setLeftRTLScrollbarOffset,"setLeftRTLScrollbarOffset"),isOffsetParentAnElement||!isOffsetParentAnElement&&!isFixed)if((getNodeName(offsetParent)!=="body"||isOverflowElement(documentElement))&&(scroll=getNodeScroll(offsetParent)),isOffsetParentAnElement){const offsetRect=getBoundingClientRect(offsetParent,!0,isFixed,offsetParent);offsets.x=offsetRect.x+offsetParent.clientLeft,offsets.y=offsetRect.y+offsetParent.clientTop}else documentElement&&setLeftRTLScrollbarOffset();isFixed&&!isOffsetParentAnElement&&documentElement&&setLeftRTLScrollbarOffset();const htmlOffset=documentElement&&!isOffsetParentAnElement&&!isFixed?getHTMLOffset(documentElement,scroll):createCoords(0),x2=rect.left+scroll.scrollLeft-offsets.x-htmlOffset.x,y2=rect.top+scroll.scrollTop-offsets.y-htmlOffset.y;return{x:x2,y:y2,width:rect.width,height:rect.height}}__name(getRectRelativeToOffsetParent,"getRectRelativeToOffsetParent");function isStaticPositioned(element2){return getComputedStyle$1(element2).position==="static"}__name(isStaticPositioned,"isStaticPositioned");function getTrueOffsetParent(element2,polyfill2){if(!isHTMLElement(element2)||getComputedStyle$1(element2).position==="fixed")return null;if(polyfill2)return polyfill2(element2);let rawOffsetParent=element2.offsetParent;return getDocumentElement(element2)===rawOffsetParent&&(rawOffsetParent=rawOffsetParent.ownerDocument.body),rawOffsetParent}__name(getTrueOffsetParent,"getTrueOffsetParent");function getOffsetParent(element2,polyfill2){const win=getWindow(element2);if(isTopLayer(element2))return win;if(!isHTMLElement(element2)){let svgOffsetParent=getParentNode(element2);for(;svgOffsetParent&&!isLastTraversableNode(svgOffsetParent);){if(isElement(svgOffsetParent)&&!isStaticPositioned(svgOffsetParent))return svgOffsetParent;svgOffsetParent=getParentNode(svgOffsetParent)}return win}let offsetParent=getTrueOffsetParent(element2,polyfill2);for(;offsetParent&&isTableElement(offsetParent)&&isStaticPositioned(offsetParent);)offsetParent=getTrueOffsetParent(offsetParent,polyfill2);return offsetParent&&isLastTraversableNode(offsetParent)&&isStaticPositioned(offsetParent)&&!isContainingBlock(offsetParent)?win:offsetParent||getContainingBlock(element2)||win}__name(getOffsetParent,"getOffsetParent");const getElementRects=__name(async function(data){const getOffsetParentFn=this.getOffsetParent||getOffsetParent,getDimensionsFn=this.getDimensions,floatingDimensions=await getDimensionsFn(data.floating);return{reference:getRectRelativeToOffsetParent(data.reference,await getOffsetParentFn(data.floating),data.strategy),floating:{x:0,y:0,width:floatingDimensions.width,height:floatingDimensions.height}}},"getElementRects");function isRTL(element2){return getComputedStyle$1(element2).direction==="rtl"}__name(isRTL,"isRTL");const platform={convertOffsetParentRelativeRectToViewportRelativeRect,getDocumentElement,getClippingRect,getOffsetParent,getElementRects,getClientRects,getDimensions,getScale,isElement,isRTL};function rectsAreEqual(a2,b2){return a2.x===b2.x&&a2.y===b2.y&&a2.width===b2.width&&a2.height===b2.height}__name(rectsAreEqual,"rectsAreEqual");function observeMove(element2,onMove){let io=null,timeoutId;const root2=getDocumentElement(element2);function cleanup(){var _io;clearTimeout(timeoutId),(_io=io)==null||_io.disconnect(),io=null}__name(cleanup,"cleanup");function refresh(skip,threshold2){skip===void 0&&(skip=!1),threshold2===void 0&&(threshold2=1),cleanup();const elementRectForRootMargin=element2.getBoundingClientRect(),{left:left2,top,width,height}=elementRectForRootMargin;if(skip||onMove(),!width||!height)return;const insetTop=floor(top),insetRight=floor(root2.clientWidth-(left2+width)),insetBottom=floor(root2.clientHeight-(top+height)),insetLeft=floor(left2),options={rootMargin:-insetTop+"px "+-insetRight+"px "+-insetBottom+"px "+-insetLeft+"px",threshold:max$3(0,min$3(1,threshold2))||1};let isFirstUpdate=!0;function handleObserve(entries){const ratio=entries[0].intersectionRatio;if(ratio!==threshold2){if(!isFirstUpdate)return refresh();ratio?refresh(!1,ratio):timeoutId=setTimeout(()=>{refresh(!1,1e-7)},1e3)}ratio===1&&!rectsAreEqual(elementRectForRootMargin,element2.getBoundingClientRect())&&refresh(),isFirstUpdate=!1}__name(handleObserve,"handleObserve");try{io=new IntersectionObserver(handleObserve,{...options,root:root2.ownerDocument})}catch{io=new IntersectionObserver(handleObserve,options)}io.observe(element2)}return __name(refresh,"refresh"),refresh(!0),cleanup}__name(observeMove,"observeMove");function autoUpdate(reference,floating,update2,options){options===void 0&&(options={});const{ancestorScroll=!0,ancestorResize=!0,elementResize=typeof ResizeObserver=="function",layoutShift=typeof IntersectionObserver=="function",animationFrame=!1}=options,referenceEl=unwrapElement(reference),ancestors=ancestorScroll||ancestorResize?[...referenceEl?getOverflowAncestors(referenceEl):[],...getOverflowAncestors(floating)]:[];ancestors.forEach(ancestor=>{ancestorScroll&&ancestor.addEventListener("scroll",update2,{passive:!0}),ancestorResize&&ancestor.addEventListener("resize",update2)});const cleanupIo=referenceEl&&layoutShift?observeMove(referenceEl,update2):null;let reobserveFrame=-1,resizeObserver=null;elementResize&&(resizeObserver=new ResizeObserver(_ref=>{let[firstEntry]=_ref;firstEntry&&firstEntry.target===referenceEl&&resizeObserver&&(resizeObserver.unobserve(floating),cancelAnimationFrame(reobserveFrame),reobserveFrame=requestAnimationFrame(()=>{var _resizeObserver;(_resizeObserver=resizeObserver)==null||_resizeObserver.observe(floating)})),update2()}),referenceEl&&!animationFrame&&resizeObserver.observe(referenceEl),resizeObserver.observe(floating));let frameId,prevRefRect=animationFrame?getBoundingClientRect(reference):null;animationFrame&&frameLoop2();function frameLoop2(){const nextRefRect=getBoundingClientRect(reference);prevRefRect&&!rectsAreEqual(prevRefRect,nextRefRect)&&update2(),prevRefRect=nextRefRect,frameId=requestAnimationFrame(frameLoop2)}return __name(frameLoop2,"frameLoop"),update2(),()=>{var _resizeObserver2;ancestors.forEach(ancestor=>{ancestorScroll&&ancestor.removeEventListener("scroll",update2),ancestorResize&&ancestor.removeEventListener("resize",update2)}),cleanupIo?.(),(_resizeObserver2=resizeObserver)==null||_resizeObserver2.disconnect(),resizeObserver=null,animationFrame&&cancelAnimationFrame(frameId)}}__name(autoUpdate,"autoUpdate");const offset$1=offset$2,shift$1=shift$2,flip$1=flip$2,size$1=size$2,hide$1=hide$2,arrow$2=arrow$3,limitShift$1=limitShift$2,computePosition=__name((reference,floating,options)=>{const cache=new Map,mergedOptions={platform,...options},platformWithCache={...mergedOptions.platform,_c:cache};return computePosition$1(reference,floating,{...mergedOptions,platform:platformWithCache})},"computePosition");var isClient=typeof document<"u",noop$2=__name(function(){},"noop"),index$1=isClient?reactExports.useLayoutEffect:noop$2;function deepEqual$1(a2,b2){if(a2===b2)return!0;if(typeof a2!=typeof b2)return!1;if(typeof a2=="function"&&a2.toString()===b2.toString())return!0;let length,i2,keys2;if(a2&&b2&&typeof a2=="object"){if(Array.isArray(a2)){if(length=a2.length,length!==b2.length)return!1;for(i2=length;i2--!==0;)if(!deepEqual$1(a2[i2],b2[i2]))return!1;return!0}if(keys2=Object.keys(a2),length=keys2.length,length!==Object.keys(b2).length)return!1;for(i2=length;i2--!==0;)if(!{}.hasOwnProperty.call(b2,keys2[i2]))return!1;for(i2=length;i2--!==0;){const key=keys2[i2];if(!(key==="_owner"&&a2.$$typeof)&&!deepEqual$1(a2[key],b2[key]))return!1}return!0}return a2!==a2&&b2!==b2}__name(deepEqual$1,"deepEqual$1");function getDPR(element2){return typeof window>"u"?1:(element2.ownerDocument.defaultView||window).devicePixelRatio||1}__name(getDPR,"getDPR");function roundByDPR(element2,value2){const dpr=getDPR(element2);return Math.round(value2*dpr)/dpr}__name(roundByDPR,"roundByDPR");function useLatestRef(value2){const ref=reactExports.useRef(value2);return index$1(()=>{ref.current=value2}),ref}__name(useLatestRef,"useLatestRef");function useFloating(options){options===void 0&&(options={});const{placement="bottom",strategy="absolute",middleware=[],platform:platform2,elements:{reference:externalReference,floating:externalFloating}={},transform:transform2=!0,whileElementsMounted,open}=options,[data,setData]=reactExports.useState({x:0,y:0,strategy,placement,middlewareData:{},isPositioned:!1}),[latestMiddleware,setLatestMiddleware]=reactExports.useState(middleware);deepEqual$1(latestMiddleware,middleware)||setLatestMiddleware(middleware);const[_reference,_setReference]=reactExports.useState(null),[_floating,_setFloating]=reactExports.useState(null),setReference=reactExports.useCallback(node2=>{node2!==referenceRef.current&&(referenceRef.current=node2,_setReference(node2))},[]),setFloating=reactExports.useCallback(node2=>{node2!==floatingRef.current&&(floatingRef.current=node2,_setFloating(node2))},[]),referenceEl=externalReference||_reference,floatingEl=externalFloating||_floating,referenceRef=reactExports.useRef(null),floatingRef=reactExports.useRef(null),dataRef=reactExports.useRef(data),hasWhileElementsMounted=whileElementsMounted!=null,whileElementsMountedRef=useLatestRef(whileElementsMounted),platformRef=useLatestRef(platform2),openRef=useLatestRef(open),update2=reactExports.useCallback(()=>{if(!referenceRef.current||!floatingRef.current)return;const config2={placement,strategy,middleware:latestMiddleware};platformRef.current&&(config2.platform=platformRef.current),computePosition(referenceRef.current,floatingRef.current,config2).then(data2=>{const fullData={...data2,isPositioned:openRef.current!==!1};isMountedRef.current&&!deepEqual$1(dataRef.current,fullData)&&(dataRef.current=fullData,reactDomExports.flushSync(()=>{setData(fullData)}))})},[latestMiddleware,placement,strategy,platformRef,openRef]);index$1(()=>{open===!1&&dataRef.current.isPositioned&&(dataRef.current.isPositioned=!1,setData(data2=>({...data2,isPositioned:!1})))},[open]);const isMountedRef=reactExports.useRef(!1);index$1(()=>(isMountedRef.current=!0,()=>{isMountedRef.current=!1}),[]),index$1(()=>{if(referenceEl&&(referenceRef.current=referenceEl),floatingEl&&(floatingRef.current=floatingEl),referenceEl&&floatingEl){if(whileElementsMountedRef.current)return whileElementsMountedRef.current(referenceEl,floatingEl,update2);update2()}},[referenceEl,floatingEl,update2,whileElementsMountedRef,hasWhileElementsMounted]);const refs=reactExports.useMemo(()=>({reference:referenceRef,floating:floatingRef,setReference,setFloating}),[setReference,setFloating]),elements=reactExports.useMemo(()=>({reference:referenceEl,floating:floatingEl}),[referenceEl,floatingEl]),floatingStyles=reactExports.useMemo(()=>{const initialStyles={position:strategy,left:0,top:0};if(!elements.floating)return initialStyles;const x2=roundByDPR(elements.floating,data.x),y2=roundByDPR(elements.floating,data.y);return transform2?{...initialStyles,transform:"translate("+x2+"px, "+y2+"px)",...getDPR(elements.floating)>=1.5&&{willChange:"transform"}}:{position:strategy,left:x2,top:y2}},[strategy,transform2,elements.floating,data.x,data.y]);return reactExports.useMemo(()=>({...data,update:update2,refs,elements,floatingStyles}),[data,update2,refs,elements,floatingStyles])}__name(useFloating,"useFloating");const arrow$1=__name(options=>{function isRef(value2){return{}.hasOwnProperty.call(value2,"current")}return __name(isRef,"isRef"),{name:"arrow",options,fn(state){const{element:element2,padding}=typeof options=="function"?options(state):options;return element2&&isRef(element2)?element2.current!=null?arrow$2({element:element2.current,padding}).fn(state):{}:element2?arrow$2({element:element2,padding}).fn(state):{}}}},"arrow$1"),offset=__name((options,deps)=>({...offset$1(options),options:[options,deps]}),"offset"),shift=__name((options,deps)=>({...shift$1(options),options:[options,deps]}),"shift"),limitShift=__name((options,deps)=>({...limitShift$1(options),options:[options,deps]}),"limitShift"),flip=__name((options,deps)=>({...flip$1(options),options:[options,deps]}),"flip"),size=__name((options,deps)=>({...size$1(options),options:[options,deps]}),"size"),hide=__name((options,deps)=>({...hide$1(options),options:[options,deps]}),"hide"),arrow=__name((options,deps)=>({...arrow$1(options),options:[options,deps]}),"arrow");var NAME$2="Arrow",Arrow$1=reactExports.forwardRef((props,forwardedRef)=>{const{children:children2,width=10,height=5,...arrowProps}=props;return jsxRuntimeExports.jsx(Primitive$2.svg,{...arrowProps,ref:forwardedRef,width,height,viewBox:"0 0 30 10",preserveAspectRatio:"none",children:props.asChild?children2:jsxRuntimeExports.jsx("polygon",{points:"0,0 30,0 15,10"})})});Arrow$1.displayName=NAME$2;var Root$5=Arrow$1;function useSize(element2){const[size2,setSize]=reactExports.useState(void 0);return useLayoutEffect2(()=>{if(element2){setSize({width:element2.offsetWidth,height:element2.offsetHeight});const resizeObserver=new ResizeObserver(entries=>{if(!Array.isArray(entries)||!entries.length)return;const entry=entries[0];let width,height;if("borderBoxSize"in entry){const borderSizeEntry=entry.borderBoxSize,borderSize=Array.isArray(borderSizeEntry)?borderSizeEntry[0]:borderSizeEntry;width=borderSize.inlineSize,height=borderSize.blockSize}else width=element2.offsetWidth,height=element2.offsetHeight;setSize({width,height})});return resizeObserver.observe(element2,{box:"border-box"}),()=>resizeObserver.unobserve(element2)}else setSize(void 0)},[element2]),size2}__name(useSize,"useSize");var POPPER_NAME="Popper",[createPopperContext,createPopperScope]=createContextScope$1(POPPER_NAME),[PopperProvider,usePopperContext]=createPopperContext(POPPER_NAME),Popper=__name(props=>{const{__scopePopper,children:children2}=props,[anchor,setAnchor]=reactExports.useState(null);return jsxRuntimeExports.jsx(PopperProvider,{scope:__scopePopper,anchor,onAnchorChange:setAnchor,children:children2})},"Popper");Popper.displayName=POPPER_NAME;var ANCHOR_NAME$1="PopperAnchor",PopperAnchor=reactExports.forwardRef((props,forwardedRef)=>{const{__scopePopper,virtualRef,...anchorProps}=props,context=usePopperContext(ANCHOR_NAME$1,__scopePopper),ref=reactExports.useRef(null),composedRefs=useComposedRefs(forwardedRef,ref),anchorRef=reactExports.useRef(null);return reactExports.useEffect(()=>{const previousAnchor=anchorRef.current;anchorRef.current=virtualRef?.current||ref.current,previousAnchor!==anchorRef.current&&context.onAnchorChange(anchorRef.current)}),virtualRef?null:jsxRuntimeExports.jsx(Primitive$2.div,{...anchorProps,ref:composedRefs})});PopperAnchor.displayName=ANCHOR_NAME$1;var CONTENT_NAME$6="PopperContent",[PopperContentProvider,useContentContext]=createPopperContext(CONTENT_NAME$6),PopperContent=reactExports.forwardRef((props,forwardedRef)=>{const{__scopePopper,side="bottom",sideOffset=0,align="center",alignOffset=0,arrowPadding=0,avoidCollisions=!0,collisionBoundary=[],collisionPadding:collisionPaddingProp=0,sticky="partial",hideWhenDetached=!1,updatePositionStrategy="optimized",onPlaced,...contentProps}=props,context=usePopperContext(CONTENT_NAME$6,__scopePopper),[content2,setContent]=reactExports.useState(null),composedRefs=useComposedRefs(forwardedRef,node2=>setContent(node2)),[arrow$12,setArrow]=reactExports.useState(null),arrowSize=useSize(arrow$12),arrowWidth=arrowSize?.width??0,arrowHeight=arrowSize?.height??0,desiredPlacement=side+(align!=="center"?"-"+align:""),collisionPadding=typeof collisionPaddingProp=="number"?collisionPaddingProp:{top:0,right:0,bottom:0,left:0,...collisionPaddingProp},boundary=Array.isArray(collisionBoundary)?collisionBoundary:[collisionBoundary],hasExplicitBoundaries=boundary.length>0,detectOverflowOptions={padding:collisionPadding,boundary:boundary.filter(isNotNull),altBoundary:hasExplicitBoundaries},{refs,floatingStyles,placement,isPositioned,middlewareData}=useFloating({strategy:"fixed",placement:desiredPlacement,whileElementsMounted:__name((...args)=>autoUpdate(...args,{animationFrame:updatePositionStrategy==="always"}),"whileElementsMounted"),elements:{reference:context.anchor},middleware:[offset({mainAxis:sideOffset+arrowHeight,alignmentAxis:alignOffset}),avoidCollisions&&shift({mainAxis:!0,crossAxis:!1,limiter:sticky==="partial"?limitShift():void 0,...detectOverflowOptions}),avoidCollisions&&flip({...detectOverflowOptions}),size({...detectOverflowOptions,apply:__name(({elements,rects,availableWidth,availableHeight})=>{const{width:anchorWidth,height:anchorHeight}=rects.reference,contentStyle=elements.floating.style;contentStyle.setProperty("--radix-popper-available-width",`${availableWidth}px`),contentStyle.setProperty("--radix-popper-available-height",`${availableHeight}px`),contentStyle.setProperty("--radix-popper-anchor-width",`${anchorWidth}px`),contentStyle.setProperty("--radix-popper-anchor-height",`${anchorHeight}px`)},"apply")}),arrow$12&&arrow({element:arrow$12,padding:arrowPadding}),transformOrigin({arrowWidth,arrowHeight}),hideWhenDetached&&hide({strategy:"referenceHidden",...detectOverflowOptions})]}),[placedSide,placedAlign]=getSideAndAlignFromPlacement(placement),handlePlaced=useCallbackRef$1(onPlaced);useLayoutEffect2(()=>{isPositioned&&handlePlaced?.()},[isPositioned,handlePlaced]);const arrowX=middlewareData.arrow?.x,arrowY=middlewareData.arrow?.y,cannotCenterArrow=middlewareData.arrow?.centerOffset!==0,[contentZIndex,setContentZIndex]=reactExports.useState();return useLayoutEffect2(()=>{content2&&setContentZIndex(window.getComputedStyle(content2).zIndex)},[content2]),jsxRuntimeExports.jsx("div",{ref:refs.setFloating,"data-radix-popper-content-wrapper":"",style:{...floatingStyles,transform:isPositioned?floatingStyles.transform:"translate(0, -200%)",minWidth:"max-content",zIndex:contentZIndex,"--radix-popper-transform-origin":[middlewareData.transformOrigin?.x,middlewareData.transformOrigin?.y].join(" "),...middlewareData.hide?.referenceHidden&&{visibility:"hidden",pointerEvents:"none"}},dir:props.dir,children:jsxRuntimeExports.jsx(PopperContentProvider,{scope:__scopePopper,placedSide,onArrowChange:setArrow,arrowX,arrowY,shouldHideArrow:cannotCenterArrow,children:jsxRuntimeExports.jsx(Primitive$2.div,{"data-side":placedSide,"data-align":placedAlign,...contentProps,ref:composedRefs,style:{...contentProps.style,animation:isPositioned?void 0:"none"}})})})});PopperContent.displayName=CONTENT_NAME$6;var ARROW_NAME$3="PopperArrow",OPPOSITE_SIDE={top:"bottom",right:"left",bottom:"top",left:"right"},PopperArrow=reactExports.forwardRef(__name(function(props,forwardedRef){const{__scopePopper,...arrowProps}=props,contentContext=useContentContext(ARROW_NAME$3,__scopePopper),baseSide=OPPOSITE_SIDE[contentContext.placedSide];return jsxRuntimeExports.jsx("span",{ref:contentContext.onArrowChange,style:{position:"absolute",left:contentContext.arrowX,top:contentContext.arrowY,[baseSide]:0,transformOrigin:{top:"",right:"0 0",bottom:"center 0",left:"100% 0"}[contentContext.placedSide],transform:{top:"translateY(100%)",right:"translateY(50%) rotate(90deg) translateX(-50%)",bottom:"rotate(180deg)",left:"translateY(50%) rotate(-90deg) translateX(50%)"}[contentContext.placedSide],visibility:contentContext.shouldHideArrow?"hidden":void 0},children:jsxRuntimeExports.jsx(Root$5,{...arrowProps,ref:forwardedRef,style:{...arrowProps.style,display:"block"}})})},"PopperArrow2"));PopperArrow.displayName=ARROW_NAME$3;function isNotNull(value2){return value2!==null}__name(isNotNull,"isNotNull");var transformOrigin=__name(options=>({name:"transformOrigin",options,fn(data){const{placement,rects,middlewareData}=data,isArrowHidden=middlewareData.arrow?.centerOffset!==0,arrowWidth=isArrowHidden?0:options.arrowWidth,arrowHeight=isArrowHidden?0:options.arrowHeight,[placedSide,placedAlign]=getSideAndAlignFromPlacement(placement),noArrowAlign={start:"0%",center:"50%",end:"100%"}[placedAlign],arrowXCenter=(middlewareData.arrow?.x??0)+arrowWidth/2,arrowYCenter=(middlewareData.arrow?.y??0)+arrowHeight/2;let x2="",y2="";return placedSide==="bottom"?(x2=isArrowHidden?noArrowAlign:`${arrowXCenter}px`,y2=`${-arrowHeight}px`):placedSide==="top"?(x2=isArrowHidden?noArrowAlign:`${arrowXCenter}px`,y2=`${rects.floating.height+arrowHeight}px`):placedSide==="right"?(x2=`${-arrowHeight}px`,y2=isArrowHidden?noArrowAlign:`${arrowYCenter}px`):placedSide==="left"&&(x2=`${rects.floating.width+arrowHeight}px`,y2=isArrowHidden?noArrowAlign:`${arrowYCenter}px`),{data:{x:x2,y:y2}}}}),"transformOrigin");function getSideAndAlignFromPlacement(placement){const[side,align="center"]=placement.split("-");return[side,align]}__name(getSideAndAlignFromPlacement,"getSideAndAlignFromPlacement");var Root2$3=Popper,Anchor=PopperAnchor,Content$2=PopperContent,Arrow=PopperArrow,ENTRY_FOCUS="rovingFocusGroup.onEntryFocus",EVENT_OPTIONS={bubbles:!1,cancelable:!0},GROUP_NAME$2="RovingFocusGroup",[Collection$2,useCollection$2,createCollectionScope$2]=createCollection(GROUP_NAME$2),[createRovingFocusGroupContext,createRovingFocusGroupScope]=createContextScope$1(GROUP_NAME$2,[createCollectionScope$2]),[RovingFocusProvider,useRovingFocusContext]=createRovingFocusGroupContext(GROUP_NAME$2),RovingFocusGroup=reactExports.forwardRef((props,forwardedRef)=>jsxRuntimeExports.jsx(Collection$2.Provider,{scope:props.__scopeRovingFocusGroup,children:jsxRuntimeExports.jsx(Collection$2.Slot,{scope:props.__scopeRovingFocusGroup,children:jsxRuntimeExports.jsx(RovingFocusGroupImpl,{...props,ref:forwardedRef})})}));RovingFocusGroup.displayName=GROUP_NAME$2;var RovingFocusGroupImpl=reactExports.forwardRef((props,forwardedRef)=>{const{__scopeRovingFocusGroup,orientation,loop:loop2=!1,dir,currentTabStopId:currentTabStopIdProp,defaultCurrentTabStopId,onCurrentTabStopIdChange,onEntryFocus,preventScrollOnEntryFocus=!1,...groupProps}=props,ref=reactExports.useRef(null),composedRefs=useComposedRefs(forwardedRef,ref),direction=useDirection(dir),[currentTabStopId,setCurrentTabStopId]=useControllableState({prop:currentTabStopIdProp,defaultProp:defaultCurrentTabStopId??null,onChange:onCurrentTabStopIdChange,caller:GROUP_NAME$2}),[isTabbingBackOut,setIsTabbingBackOut]=reactExports.useState(!1),handleEntryFocus=useCallbackRef$1(onEntryFocus),getItems=useCollection$2(__scopeRovingFocusGroup),isClickFocusRef=reactExports.useRef(!1),[focusableItemsCount,setFocusableItemsCount]=reactExports.useState(0);return reactExports.useEffect(()=>{const node2=ref.current;if(node2)return node2.addEventListener(ENTRY_FOCUS,handleEntryFocus),()=>node2.removeEventListener(ENTRY_FOCUS,handleEntryFocus)},[handleEntryFocus]),jsxRuntimeExports.jsx(RovingFocusProvider,{scope:__scopeRovingFocusGroup,orientation,dir:direction,loop:loop2,currentTabStopId,onItemFocus:reactExports.useCallback(tabStopId=>setCurrentTabStopId(tabStopId),[setCurrentTabStopId]),onItemShiftTab:reactExports.useCallback(()=>setIsTabbingBackOut(!0),[]),onFocusableItemAdd:reactExports.useCallback(()=>setFocusableItemsCount(prevCount=>prevCount+1),[]),onFocusableItemRemove:reactExports.useCallback(()=>setFocusableItemsCount(prevCount=>prevCount-1),[]),children:jsxRuntimeExports.jsx(Primitive$2.div,{tabIndex:isTabbingBackOut||focusableItemsCount===0?-1:0,"data-orientation":orientation,...groupProps,ref:composedRefs,style:{outline:"none",...props.style},onMouseDown:composeEventHandlers(props.onMouseDown,()=>{isClickFocusRef.current=!0}),onFocus:composeEventHandlers(props.onFocus,event=>{const isKeyboardFocus=!isClickFocusRef.current;if(event.target===event.currentTarget&&isKeyboardFocus&&!isTabbingBackOut){const entryFocusEvent=new CustomEvent(ENTRY_FOCUS,EVENT_OPTIONS);if(event.currentTarget.dispatchEvent(entryFocusEvent),!entryFocusEvent.defaultPrevented){const items=getItems().filter(item=>item.focusable),activeItem=items.find(item=>item.active),currentItem=items.find(item=>item.id===currentTabStopId),candidateNodes=[activeItem,currentItem,...items].filter(Boolean).map(item=>item.ref.current);focusFirst$1(candidateNodes,preventScrollOnEntryFocus)}}isClickFocusRef.current=!1}),onBlur:composeEventHandlers(props.onBlur,()=>setIsTabbingBackOut(!1))})})}),ITEM_NAME$3="RovingFocusGroupItem",RovingFocusGroupItem=reactExports.forwardRef((props,forwardedRef)=>{const{__scopeRovingFocusGroup,focusable=!0,active=!1,tabStopId,children:children2,...itemProps}=props,autoId=useId(),id=tabStopId||autoId,context=useRovingFocusContext(ITEM_NAME$3,__scopeRovingFocusGroup),isCurrentTabStop=context.currentTabStopId===id,getItems=useCollection$2(__scopeRovingFocusGroup),{onFocusableItemAdd,onFocusableItemRemove,currentTabStopId}=context;return reactExports.useEffect(()=>{if(focusable)return onFocusableItemAdd(),()=>onFocusableItemRemove()},[focusable,onFocusableItemAdd,onFocusableItemRemove]),jsxRuntimeExports.jsx(Collection$2.ItemSlot,{scope:__scopeRovingFocusGroup,id,focusable,active,children:jsxRuntimeExports.jsx(Primitive$2.span,{tabIndex:isCurrentTabStop?0:-1,"data-orientation":context.orientation,...itemProps,ref:forwardedRef,onMouseDown:composeEventHandlers(props.onMouseDown,event=>{focusable?context.onItemFocus(id):event.preventDefault()}),onFocus:composeEventHandlers(props.onFocus,()=>context.onItemFocus(id)),onKeyDown:composeEventHandlers(props.onKeyDown,event=>{if(event.key==="Tab"&&event.shiftKey){context.onItemShiftTab();return}if(event.target!==event.currentTarget)return;const focusIntent=getFocusIntent(event,context.orientation,context.dir);if(focusIntent!==void 0){if(event.metaKey||event.ctrlKey||event.altKey||event.shiftKey)return;event.preventDefault();let candidateNodes=getItems().filter(item=>item.focusable).map(item=>item.ref.current);if(focusIntent==="last")candidateNodes.reverse();else if(focusIntent==="prev"||focusIntent==="next"){focusIntent==="prev"&&candidateNodes.reverse();const currentIndex=candidateNodes.indexOf(event.currentTarget);candidateNodes=context.loop?wrapArray$1(candidateNodes,currentIndex+1):candidateNodes.slice(currentIndex+1)}setTimeout(()=>focusFirst$1(candidateNodes))}}),children:typeof children2=="function"?children2({isCurrentTabStop,hasTabStop:currentTabStopId!=null}):children2})})});RovingFocusGroupItem.displayName=ITEM_NAME$3;var MAP_KEY_TO_FOCUS_INTENT={ArrowLeft:"prev",ArrowUp:"prev",ArrowRight:"next",ArrowDown:"next",PageUp:"first",Home:"first",PageDown:"last",End:"last"};function getDirectionAwareKey(key,dir){return dir!=="rtl"?key:key==="ArrowLeft"?"ArrowRight":key==="ArrowRight"?"ArrowLeft":key}__name(getDirectionAwareKey,"getDirectionAwareKey");function getFocusIntent(event,orientation,dir){const key=getDirectionAwareKey(event.key,dir);if(!(orientation==="vertical"&&["ArrowLeft","ArrowRight"].includes(key))&&!(orientation==="horizontal"&&["ArrowUp","ArrowDown"].includes(key)))return MAP_KEY_TO_FOCUS_INTENT[key]}__name(getFocusIntent,"getFocusIntent");function focusFirst$1(candidates,preventScroll=!1){const PREVIOUSLY_FOCUSED_ELEMENT=document.activeElement;for(const candidate of candidates)if(candidate===PREVIOUSLY_FOCUSED_ELEMENT||(candidate.focus({preventScroll}),document.activeElement!==PREVIOUSLY_FOCUSED_ELEMENT))return}__name(focusFirst$1,"focusFirst$1");function wrapArray$1(array2,startIndex){return array2.map((_2,index2)=>array2[(startIndex+index2)%array2.length])}__name(wrapArray$1,"wrapArray$1");var Root$4=RovingFocusGroup,Item$1=RovingFocusGroupItem;function createSlot(ownerName){const SlotClone=createSlotClone(ownerName),Slot2=reactExports.forwardRef((props,forwardedRef)=>{const{children:children2,...slotProps}=props,childrenArray=reactExports.Children.toArray(children2),slottable=childrenArray.find(isSlottable);if(slottable){const newElement=slottable.props.children,newChildren=childrenArray.map(child=>child===slottable?reactExports.Children.count(newElement)>1?reactExports.Children.only(null):reactExports.isValidElement(newElement)?newElement.props.children:null:child);return jsxRuntimeExports.jsx(SlotClone,{...slotProps,ref:forwardedRef,children:reactExports.isValidElement(newElement)?reactExports.cloneElement(newElement,void 0,newChildren):null})}return jsxRuntimeExports.jsx(SlotClone,{...slotProps,ref:forwardedRef,children:children2})});return Slot2.displayName=`${ownerName}.Slot`,Slot2}__name(createSlot,"createSlot");function createSlotClone(ownerName){const SlotClone=reactExports.forwardRef((props,forwardedRef)=>{const{children:children2,...slotProps}=props;if(reactExports.isValidElement(children2)){const childrenRef=getElementRef(children2),props2=mergeProps(slotProps,children2.props);return children2.type!==reactExports.Fragment&&(props2.ref=forwardedRef?composeRefs(forwardedRef,childrenRef):childrenRef),reactExports.cloneElement(children2,props2)}return reactExports.Children.count(children2)>1?reactExports.Children.only(null):null});return SlotClone.displayName=`${ownerName}.SlotClone`,SlotClone}__name(createSlotClone,"createSlotClone");var SLOTTABLE_IDENTIFIER$1=Symbol("radix.slottable");function isSlottable(child){return reactExports.isValidElement(child)&&typeof child.type=="function"&&"__radixId"in child.type&&child.type.__radixId===SLOTTABLE_IDENTIFIER$1}__name(isSlottable,"isSlottable");function mergeProps(slotProps,childProps){const overrideProps={...childProps};for(const propName in childProps){const slotPropValue=slotProps[propName],childPropValue=childProps[propName];/^on[A-Z]/.test(propName)?slotPropValue&&childPropValue?overrideProps[propName]=(...args)=>{const result=childPropValue(...args);return slotPropValue(...args),result}:slotPropValue&&(overrideProps[propName]=slotPropValue):propName==="style"?overrideProps[propName]={...slotPropValue,...childPropValue}:propName==="className"&&(overrideProps[propName]=[slotPropValue,childPropValue].filter(Boolean).join(" "))}return{...slotProps,...overrideProps}}__name(mergeProps,"mergeProps");function getElementRef(element2){let getter=Object.getOwnPropertyDescriptor(element2.props,"ref")?.get,mayWarn=getter&&"isReactWarning"in getter&&getter.isReactWarning;return mayWarn?element2.ref:(getter=Object.getOwnPropertyDescriptor(element2,"ref")?.get,mayWarn=getter&&"isReactWarning"in getter&&getter.isReactWarning,mayWarn?element2.props.ref:element2.props.ref||element2.ref)}__name(getElementRef,"getElementRef");var SELECTION_KEYS=["Enter"," "],FIRST_KEYS=["ArrowDown","PageUp","Home"],LAST_KEYS=["ArrowUp","PageDown","End"],FIRST_LAST_KEYS=[...FIRST_KEYS,...LAST_KEYS],SUB_OPEN_KEYS={ltr:[...SELECTION_KEYS,"ArrowRight"],rtl:[...SELECTION_KEYS,"ArrowLeft"]},SUB_CLOSE_KEYS={ltr:["ArrowLeft"],rtl:["ArrowRight"]},MENU_NAME="Menu",[Collection$1,useCollection$1,createCollectionScope$1]=createCollection(MENU_NAME),[createMenuContext,createMenuScope]=createContextScope$1(MENU_NAME,[createCollectionScope$1,createPopperScope,createRovingFocusGroupScope]),usePopperScope$1=createPopperScope(),useRovingFocusGroupScope$1=createRovingFocusGroupScope(),[MenuProvider,useMenuContext]=createMenuContext(MENU_NAME),[MenuRootProvider,useMenuRootContext]=createMenuContext(MENU_NAME),Menu=__name(props=>{const{__scopeMenu,open=!1,children:children2,dir,onOpenChange,modal=!0}=props,popperScope=usePopperScope$1(__scopeMenu),[content2,setContent]=reactExports.useState(null),isUsingKeyboardRef=reactExports.useRef(!1),handleOpenChange=useCallbackRef$1(onOpenChange),direction=useDirection(dir);return reactExports.useEffect(()=>{const handleKeyDown=__name(()=>{isUsingKeyboardRef.current=!0,document.addEventListener("pointerdown",handlePointer,{capture:!0,once:!0}),document.addEventListener("pointermove",handlePointer,{capture:!0,once:!0})},"handleKeyDown"),handlePointer=__name(()=>isUsingKeyboardRef.current=!1,"handlePointer");return document.addEventListener("keydown",handleKeyDown,{capture:!0}),()=>{document.removeEventListener("keydown",handleKeyDown,{capture:!0}),document.removeEventListener("pointerdown",handlePointer,{capture:!0}),document.removeEventListener("pointermove",handlePointer,{capture:!0})}},[]),jsxRuntimeExports.jsx(Root2$3,{...popperScope,children:jsxRuntimeExports.jsx(MenuProvider,{scope:__scopeMenu,open,onOpenChange:handleOpenChange,content:content2,onContentChange:setContent,children:jsxRuntimeExports.jsx(MenuRootProvider,{scope:__scopeMenu,onClose:reactExports.useCallback(()=>handleOpenChange(!1),[handleOpenChange]),isUsingKeyboardRef,dir:direction,modal,children:children2})})})},"Menu");Menu.displayName=MENU_NAME;var ANCHOR_NAME="MenuAnchor",MenuAnchor=reactExports.forwardRef((props,forwardedRef)=>{const{__scopeMenu,...anchorProps}=props,popperScope=usePopperScope$1(__scopeMenu);return jsxRuntimeExports.jsx(Anchor,{...popperScope,...anchorProps,ref:forwardedRef})});MenuAnchor.displayName=ANCHOR_NAME;var PORTAL_NAME$2="MenuPortal",[PortalProvider$1,usePortalContext$1]=createMenuContext(PORTAL_NAME$2,{forceMount:void 0}),MenuPortal=__name(props=>{const{__scopeMenu,forceMount,children:children2,container}=props,context=useMenuContext(PORTAL_NAME$2,__scopeMenu);return jsxRuntimeExports.jsx(PortalProvider$1,{scope:__scopeMenu,forceMount,children:jsxRuntimeExports.jsx(Presence,{present:forceMount||context.open,children:jsxRuntimeExports.jsx(Portal$2,{asChild:!0,container,children:children2})})})},"MenuPortal");MenuPortal.displayName=PORTAL_NAME$2;var CONTENT_NAME$5="MenuContent",[MenuContentProvider,useMenuContentContext]=createMenuContext(CONTENT_NAME$5),MenuContent=reactExports.forwardRef((props,forwardedRef)=>{const portalContext=usePortalContext$1(CONTENT_NAME$5,props.__scopeMenu),{forceMount=portalContext.forceMount,...contentProps}=props,context=useMenuContext(CONTENT_NAME$5,props.__scopeMenu),rootContext=useMenuRootContext(CONTENT_NAME$5,props.__scopeMenu);return jsxRuntimeExports.jsx(Collection$1.Provider,{scope:props.__scopeMenu,children:jsxRuntimeExports.jsx(Presence,{present:forceMount||context.open,children:jsxRuntimeExports.jsx(Collection$1.Slot,{scope:props.__scopeMenu,children:rootContext.modal?jsxRuntimeExports.jsx(MenuRootContentModal,{...contentProps,ref:forwardedRef}):jsxRuntimeExports.jsx(MenuRootContentNonModal,{...contentProps,ref:forwardedRef})})})})}),MenuRootContentModal=reactExports.forwardRef((props,forwardedRef)=>{const context=useMenuContext(CONTENT_NAME$5,props.__scopeMenu),ref=reactExports.useRef(null),composedRefs=useComposedRefs(forwardedRef,ref);return reactExports.useEffect(()=>{const content2=ref.current;if(content2)return hideOthers(content2)},[]),jsxRuntimeExports.jsx(MenuContentImpl,{...props,ref:composedRefs,trapFocus:context.open,disableOutsidePointerEvents:context.open,disableOutsideScroll:!0,onFocusOutside:composeEventHandlers(props.onFocusOutside,event=>event.preventDefault(),{checkForDefaultPrevented:!1}),onDismiss:__name(()=>context.onOpenChange(!1),"onDismiss")})}),MenuRootContentNonModal=reactExports.forwardRef((props,forwardedRef)=>{const context=useMenuContext(CONTENT_NAME$5,props.__scopeMenu);return jsxRuntimeExports.jsx(MenuContentImpl,{...props,ref:forwardedRef,trapFocus:!1,disableOutsidePointerEvents:!1,disableOutsideScroll:!1,onDismiss:__name(()=>context.onOpenChange(!1),"onDismiss")})}),Slot=createSlot("MenuContent.ScrollLock"),MenuContentImpl=reactExports.forwardRef((props,forwardedRef)=>{const{__scopeMenu,loop:loop2=!1,trapFocus,onOpenAutoFocus,onCloseAutoFocus,disableOutsidePointerEvents,onEntryFocus,onEscapeKeyDown,onPointerDownOutside,onFocusOutside,onInteractOutside,onDismiss,disableOutsideScroll,...contentProps}=props,context=useMenuContext(CONTENT_NAME$5,__scopeMenu),rootContext=useMenuRootContext(CONTENT_NAME$5,__scopeMenu),popperScope=usePopperScope$1(__scopeMenu),rovingFocusGroupScope=useRovingFocusGroupScope$1(__scopeMenu),getItems=useCollection$1(__scopeMenu),[currentItemId,setCurrentItemId]=reactExports.useState(null),contentRef=reactExports.useRef(null),composedRefs=useComposedRefs(forwardedRef,contentRef,context.onContentChange),timerRef=reactExports.useRef(0),searchRef=reactExports.useRef(""),pointerGraceTimerRef=reactExports.useRef(0),pointerGraceIntentRef=reactExports.useRef(null),pointerDirRef=reactExports.useRef("right"),lastPointerXRef=reactExports.useRef(0),ScrollLockWrapper=disableOutsideScroll?ReactRemoveScroll:reactExports.Fragment,scrollLockWrapperProps=disableOutsideScroll?{as:Slot,allowPinchZoom:!0}:void 0,handleTypeaheadSearch=__name(key=>{const search2=searchRef.current+key,items=getItems().filter(item=>!item.disabled),currentItem=document.activeElement,currentMatch=items.find(item=>item.ref.current===currentItem)?.textValue,values=items.map(item=>item.textValue),nextMatch=getNextMatch(values,search2,currentMatch),newItem=items.find(item=>item.textValue===nextMatch)?.ref.current;__name((function updateSearch(value2){searchRef.current=value2,window.clearTimeout(timerRef.current),value2!==""&&(timerRef.current=window.setTimeout(()=>updateSearch(""),1e3))}),"updateSearch")(search2),newItem&&setTimeout(()=>newItem.focus())},"handleTypeaheadSearch");reactExports.useEffect(()=>()=>window.clearTimeout(timerRef.current),[]),useFocusGuards();const isPointerMovingToSubmenu=reactExports.useCallback(event=>pointerDirRef.current===pointerGraceIntentRef.current?.side&&isPointerInGraceArea(event,pointerGraceIntentRef.current?.area),[]);return jsxRuntimeExports.jsx(MenuContentProvider,{scope:__scopeMenu,searchRef,onItemEnter:reactExports.useCallback(event=>{isPointerMovingToSubmenu(event)&&event.preventDefault()},[isPointerMovingToSubmenu]),onItemLeave:reactExports.useCallback(event=>{isPointerMovingToSubmenu(event)||(contentRef.current?.focus(),setCurrentItemId(null))},[isPointerMovingToSubmenu]),onTriggerLeave:reactExports.useCallback(event=>{isPointerMovingToSubmenu(event)&&event.preventDefault()},[isPointerMovingToSubmenu]),pointerGraceTimerRef,onPointerGraceIntentChange:reactExports.useCallback(intent=>{pointerGraceIntentRef.current=intent},[]),children:jsxRuntimeExports.jsx(ScrollLockWrapper,{...scrollLockWrapperProps,children:jsxRuntimeExports.jsx(FocusScope,{asChild:!0,trapped:trapFocus,onMountAutoFocus:composeEventHandlers(onOpenAutoFocus,event=>{event.preventDefault(),contentRef.current?.focus({preventScroll:!0})}),onUnmountAutoFocus:onCloseAutoFocus,children:jsxRuntimeExports.jsx(DismissableLayer,{asChild:!0,disableOutsidePointerEvents,onEscapeKeyDown,onPointerDownOutside,onFocusOutside,onInteractOutside,onDismiss,children:jsxRuntimeExports.jsx(Root$4,{asChild:!0,...rovingFocusGroupScope,dir:rootContext.dir,orientation:"vertical",loop:loop2,currentTabStopId:currentItemId,onCurrentTabStopIdChange:setCurrentItemId,onEntryFocus:composeEventHandlers(onEntryFocus,event=>{rootContext.isUsingKeyboardRef.current||event.preventDefault()}),preventScrollOnEntryFocus:!0,children:jsxRuntimeExports.jsx(Content$2,{role:"menu","aria-orientation":"vertical","data-state":getOpenState(context.open),"data-radix-menu-content":"",dir:rootContext.dir,...popperScope,...contentProps,ref:composedRefs,style:{outline:"none",...contentProps.style},onKeyDown:composeEventHandlers(contentProps.onKeyDown,event=>{const isKeyDownInside=event.target.closest("[data-radix-menu-content]")===event.currentTarget,isModifierKey=event.ctrlKey||event.altKey||event.metaKey,isCharacterKey=event.key.length===1;isKeyDownInside&&(event.key==="Tab"&&event.preventDefault(),!isModifierKey&&isCharacterKey&&handleTypeaheadSearch(event.key));const content2=contentRef.current;if(event.target!==content2||!FIRST_LAST_KEYS.includes(event.key))return;event.preventDefault();const candidateNodes=getItems().filter(item=>!item.disabled).map(item=>item.ref.current);LAST_KEYS.includes(event.key)&&candidateNodes.reverse(),focusFirst(candidateNodes)}),onBlur:composeEventHandlers(props.onBlur,event=>{event.currentTarget.contains(event.target)||(window.clearTimeout(timerRef.current),searchRef.current="")}),onPointerMove:composeEventHandlers(props.onPointerMove,whenMouse(event=>{const target=event.target,pointerXHasChanged=lastPointerXRef.current!==event.clientX;if(event.currentTarget.contains(target)&&pointerXHasChanged){const newDir=event.clientX>lastPointerXRef.current?"right":"left";pointerDirRef.current=newDir,lastPointerXRef.current=event.clientX}}))})})})})})})});MenuContent.displayName=CONTENT_NAME$5;var GROUP_NAME$1="MenuGroup",MenuGroup=reactExports.forwardRef((props,forwardedRef)=>{const{__scopeMenu,...groupProps}=props;return jsxRuntimeExports.jsx(Primitive$2.div,{role:"group",...groupProps,ref:forwardedRef})});MenuGroup.displayName=GROUP_NAME$1;var LABEL_NAME$1="MenuLabel",MenuLabel=reactExports.forwardRef((props,forwardedRef)=>{const{__scopeMenu,...labelProps}=props;return jsxRuntimeExports.jsx(Primitive$2.div,{...labelProps,ref:forwardedRef})});MenuLabel.displayName=LABEL_NAME$1;var ITEM_NAME$2="MenuItem",ITEM_SELECT="menu.itemSelect",MenuItem=reactExports.forwardRef((props,forwardedRef)=>{const{disabled=!1,onSelect,...itemProps}=props,ref=reactExports.useRef(null),rootContext=useMenuRootContext(ITEM_NAME$2,props.__scopeMenu),contentContext=useMenuContentContext(ITEM_NAME$2,props.__scopeMenu),composedRefs=useComposedRefs(forwardedRef,ref),isPointerDownRef=reactExports.useRef(!1),handleSelect=__name(()=>{const menuItem=ref.current;if(!disabled&&menuItem){const itemSelectEvent=new CustomEvent(ITEM_SELECT,{bubbles:!0,cancelable:!0});menuItem.addEventListener(ITEM_SELECT,event=>onSelect?.(event),{once:!0}),dispatchDiscreteCustomEvent(menuItem,itemSelectEvent),itemSelectEvent.defaultPrevented?isPointerDownRef.current=!1:rootContext.onClose()}},"handleSelect");return jsxRuntimeExports.jsx(MenuItemImpl,{...itemProps,ref:composedRefs,disabled,onClick:composeEventHandlers(props.onClick,handleSelect),onPointerDown:__name(event=>{props.onPointerDown?.(event),isPointerDownRef.current=!0},"onPointerDown"),onPointerUp:composeEventHandlers(props.onPointerUp,event=>{isPointerDownRef.current||event.currentTarget?.click()}),onKeyDown:composeEventHandlers(props.onKeyDown,event=>{const isTypingAhead=contentContext.searchRef.current!=="";disabled||isTypingAhead&&event.key===" "||SELECTION_KEYS.includes(event.key)&&(event.currentTarget.click(),event.preventDefault())})})});MenuItem.displayName=ITEM_NAME$2;var MenuItemImpl=reactExports.forwardRef((props,forwardedRef)=>{const{__scopeMenu,disabled=!1,textValue,...itemProps}=props,contentContext=useMenuContentContext(ITEM_NAME$2,__scopeMenu),rovingFocusGroupScope=useRovingFocusGroupScope$1(__scopeMenu),ref=reactExports.useRef(null),composedRefs=useComposedRefs(forwardedRef,ref),[isFocused,setIsFocused]=reactExports.useState(!1),[textContent,setTextContent]=reactExports.useState("");return reactExports.useEffect(()=>{const menuItem=ref.current;menuItem&&setTextContent((menuItem.textContent??"").trim())},[itemProps.children]),jsxRuntimeExports.jsx(Collection$1.ItemSlot,{scope:__scopeMenu,disabled,textValue:textValue??textContent,children:jsxRuntimeExports.jsx(Item$1,{asChild:!0,...rovingFocusGroupScope,focusable:!disabled,children:jsxRuntimeExports.jsx(Primitive$2.div,{role:"menuitem","data-highlighted":isFocused?"":void 0,"aria-disabled":disabled||void 0,"data-disabled":disabled?"":void 0,...itemProps,ref:composedRefs,onPointerMove:composeEventHandlers(props.onPointerMove,whenMouse(event=>{disabled?contentContext.onItemLeave(event):(contentContext.onItemEnter(event),event.defaultPrevented||event.currentTarget.focus({preventScroll:!0}))})),onPointerLeave:composeEventHandlers(props.onPointerLeave,whenMouse(event=>contentContext.onItemLeave(event))),onFocus:composeEventHandlers(props.onFocus,()=>setIsFocused(!0)),onBlur:composeEventHandlers(props.onBlur,()=>setIsFocused(!1))})})})}),CHECKBOX_ITEM_NAME$1="MenuCheckboxItem",MenuCheckboxItem=reactExports.forwardRef((props,forwardedRef)=>{const{checked=!1,onCheckedChange,...checkboxItemProps}=props;return jsxRuntimeExports.jsx(ItemIndicatorProvider,{scope:props.__scopeMenu,checked,children:jsxRuntimeExports.jsx(MenuItem,{role:"menuitemcheckbox","aria-checked":isIndeterminate(checked)?"mixed":checked,...checkboxItemProps,ref:forwardedRef,"data-state":getCheckedState(checked),onSelect:composeEventHandlers(checkboxItemProps.onSelect,()=>onCheckedChange?.(isIndeterminate(checked)?!0:!checked),{checkForDefaultPrevented:!1})})})});MenuCheckboxItem.displayName=CHECKBOX_ITEM_NAME$1;var RADIO_GROUP_NAME$1="MenuRadioGroup",[RadioGroupProvider,useRadioGroupContext]=createMenuContext(RADIO_GROUP_NAME$1,{value:void 0,onValueChange:__name(()=>{},"onValueChange")}),MenuRadioGroup=reactExports.forwardRef((props,forwardedRef)=>{const{value:value2,onValueChange,...groupProps}=props,handleValueChange=useCallbackRef$1(onValueChange);return jsxRuntimeExports.jsx(RadioGroupProvider,{scope:props.__scopeMenu,value:value2,onValueChange:handleValueChange,children:jsxRuntimeExports.jsx(MenuGroup,{...groupProps,ref:forwardedRef})})});MenuRadioGroup.displayName=RADIO_GROUP_NAME$1;var RADIO_ITEM_NAME$1="MenuRadioItem",MenuRadioItem=reactExports.forwardRef((props,forwardedRef)=>{const{value:value2,...radioItemProps}=props,context=useRadioGroupContext(RADIO_ITEM_NAME$1,props.__scopeMenu),checked=value2===context.value;return jsxRuntimeExports.jsx(ItemIndicatorProvider,{scope:props.__scopeMenu,checked,children:jsxRuntimeExports.jsx(MenuItem,{role:"menuitemradio","aria-checked":checked,...radioItemProps,ref:forwardedRef,"data-state":getCheckedState(checked),onSelect:composeEventHandlers(radioItemProps.onSelect,()=>context.onValueChange?.(value2),{checkForDefaultPrevented:!1})})})});MenuRadioItem.displayName=RADIO_ITEM_NAME$1;var ITEM_INDICATOR_NAME="MenuItemIndicator",[ItemIndicatorProvider,useItemIndicatorContext]=createMenuContext(ITEM_INDICATOR_NAME,{checked:!1}),MenuItemIndicator=reactExports.forwardRef((props,forwardedRef)=>{const{__scopeMenu,forceMount,...itemIndicatorProps}=props,indicatorContext=useItemIndicatorContext(ITEM_INDICATOR_NAME,__scopeMenu);return jsxRuntimeExports.jsx(Presence,{present:forceMount||isIndeterminate(indicatorContext.checked)||indicatorContext.checked===!0,children:jsxRuntimeExports.jsx(Primitive$2.span,{...itemIndicatorProps,ref:forwardedRef,"data-state":getCheckedState(indicatorContext.checked)})})});MenuItemIndicator.displayName=ITEM_INDICATOR_NAME;var SEPARATOR_NAME$1="MenuSeparator",MenuSeparator=reactExports.forwardRef((props,forwardedRef)=>{const{__scopeMenu,...separatorProps}=props;return jsxRuntimeExports.jsx(Primitive$2.div,{role:"separator","aria-orientation":"horizontal",...separatorProps,ref:forwardedRef})});MenuSeparator.displayName=SEPARATOR_NAME$1;var ARROW_NAME$2="MenuArrow",MenuArrow=reactExports.forwardRef((props,forwardedRef)=>{const{__scopeMenu,...arrowProps}=props,popperScope=usePopperScope$1(__scopeMenu);return jsxRuntimeExports.jsx(Arrow,{...popperScope,...arrowProps,ref:forwardedRef})});MenuArrow.displayName=ARROW_NAME$2;var SUB_NAME="MenuSub",[MenuSubProvider,useMenuSubContext]=createMenuContext(SUB_NAME),SUB_TRIGGER_NAME$1="MenuSubTrigger",MenuSubTrigger=reactExports.forwardRef((props,forwardedRef)=>{const context=useMenuContext(SUB_TRIGGER_NAME$1,props.__scopeMenu),rootContext=useMenuRootContext(SUB_TRIGGER_NAME$1,props.__scopeMenu),subContext=useMenuSubContext(SUB_TRIGGER_NAME$1,props.__scopeMenu),contentContext=useMenuContentContext(SUB_TRIGGER_NAME$1,props.__scopeMenu),openTimerRef=reactExports.useRef(null),{pointerGraceTimerRef,onPointerGraceIntentChange}=contentContext,scope={__scopeMenu:props.__scopeMenu},clearOpenTimer=reactExports.useCallback(()=>{openTimerRef.current&&window.clearTimeout(openTimerRef.current),openTimerRef.current=null},[]);return reactExports.useEffect(()=>clearOpenTimer,[clearOpenTimer]),reactExports.useEffect(()=>{const pointerGraceTimer=pointerGraceTimerRef.current;return()=>{window.clearTimeout(pointerGraceTimer),onPointerGraceIntentChange(null)}},[pointerGraceTimerRef,onPointerGraceIntentChange]),jsxRuntimeExports.jsx(MenuAnchor,{asChild:!0,...scope,children:jsxRuntimeExports.jsx(MenuItemImpl,{id:subContext.triggerId,"aria-haspopup":"menu","aria-expanded":context.open,"aria-controls":subContext.contentId,"data-state":getOpenState(context.open),...props,ref:composeRefs(forwardedRef,subContext.onTriggerChange),onClick:__name(event=>{props.onClick?.(event),!(props.disabled||event.defaultPrevented)&&(event.currentTarget.focus(),context.open||context.onOpenChange(!0))},"onClick"),onPointerMove:composeEventHandlers(props.onPointerMove,whenMouse(event=>{contentContext.onItemEnter(event),!event.defaultPrevented&&!props.disabled&&!context.open&&!openTimerRef.current&&(contentContext.onPointerGraceIntentChange(null),openTimerRef.current=window.setTimeout(()=>{context.onOpenChange(!0),clearOpenTimer()},100))})),onPointerLeave:composeEventHandlers(props.onPointerLeave,whenMouse(event=>{clearOpenTimer();const contentRect=context.content?.getBoundingClientRect();if(contentRect){const side=context.content?.dataset.side,rightSide=side==="right",bleed=rightSide?-5:5,contentNearEdge=contentRect[rightSide?"left":"right"],contentFarEdge=contentRect[rightSide?"right":"left"];contentContext.onPointerGraceIntentChange({area:[{x:event.clientX+bleed,y:event.clientY},{x:contentNearEdge,y:contentRect.top},{x:contentFarEdge,y:contentRect.top},{x:contentFarEdge,y:contentRect.bottom},{x:contentNearEdge,y:contentRect.bottom}],side}),window.clearTimeout(pointerGraceTimerRef.current),pointerGraceTimerRef.current=window.setTimeout(()=>contentContext.onPointerGraceIntentChange(null),300)}else{if(contentContext.onTriggerLeave(event),event.defaultPrevented)return;contentContext.onPointerGraceIntentChange(null)}})),onKeyDown:composeEventHandlers(props.onKeyDown,event=>{const isTypingAhead=contentContext.searchRef.current!=="";props.disabled||isTypingAhead&&event.key===" "||SUB_OPEN_KEYS[rootContext.dir].includes(event.key)&&(context.onOpenChange(!0),context.content?.focus(),event.preventDefault())})})})});MenuSubTrigger.displayName=SUB_TRIGGER_NAME$1;var SUB_CONTENT_NAME$1="MenuSubContent",MenuSubContent=reactExports.forwardRef((props,forwardedRef)=>{const portalContext=usePortalContext$1(CONTENT_NAME$5,props.__scopeMenu),{forceMount=portalContext.forceMount,...subContentProps}=props,context=useMenuContext(CONTENT_NAME$5,props.__scopeMenu),rootContext=useMenuRootContext(CONTENT_NAME$5,props.__scopeMenu),subContext=useMenuSubContext(SUB_CONTENT_NAME$1,props.__scopeMenu),ref=reactExports.useRef(null),composedRefs=useComposedRefs(forwardedRef,ref);return jsxRuntimeExports.jsx(Collection$1.Provider,{scope:props.__scopeMenu,children:jsxRuntimeExports.jsx(Presence,{present:forceMount||context.open,children:jsxRuntimeExports.jsx(Collection$1.Slot,{scope:props.__scopeMenu,children:jsxRuntimeExports.jsx(MenuContentImpl,{id:subContext.contentId,"aria-labelledby":subContext.triggerId,...subContentProps,ref:composedRefs,align:"start",side:rootContext.dir==="rtl"?"left":"right",disableOutsidePointerEvents:!1,disableOutsideScroll:!1,trapFocus:!1,onOpenAutoFocus:__name(event=>{rootContext.isUsingKeyboardRef.current&&ref.current?.focus(),event.preventDefault()},"onOpenAutoFocus"),onCloseAutoFocus:__name(event=>event.preventDefault(),"onCloseAutoFocus"),onFocusOutside:composeEventHandlers(props.onFocusOutside,event=>{event.target!==subContext.trigger&&context.onOpenChange(!1)}),onEscapeKeyDown:composeEventHandlers(props.onEscapeKeyDown,event=>{rootContext.onClose(),event.preventDefault()}),onKeyDown:composeEventHandlers(props.onKeyDown,event=>{const isKeyDownInside=event.currentTarget.contains(event.target),isCloseKey=SUB_CLOSE_KEYS[rootContext.dir].includes(event.key);isKeyDownInside&&isCloseKey&&(context.onOpenChange(!1),subContext.trigger?.focus(),event.preventDefault())})})})})})});MenuSubContent.displayName=SUB_CONTENT_NAME$1;function getOpenState(open){return open?"open":"closed"}__name(getOpenState,"getOpenState");function isIndeterminate(checked){return checked==="indeterminate"}__name(isIndeterminate,"isIndeterminate");function getCheckedState(checked){return isIndeterminate(checked)?"indeterminate":checked?"checked":"unchecked"}__name(getCheckedState,"getCheckedState");function focusFirst(candidates){const PREVIOUSLY_FOCUSED_ELEMENT=document.activeElement;for(const candidate of candidates)if(candidate===PREVIOUSLY_FOCUSED_ELEMENT||(candidate.focus(),document.activeElement!==PREVIOUSLY_FOCUSED_ELEMENT))return}__name(focusFirst,"focusFirst");function wrapArray(array2,startIndex){return array2.map((_2,index2)=>array2[(startIndex+index2)%array2.length])}__name(wrapArray,"wrapArray");function getNextMatch(values,search2,currentMatch){const normalizedSearch=search2.length>1&&Array.from(search2).every(char=>char===search2[0])?search2[0]:search2,currentMatchIndex=currentMatch?values.indexOf(currentMatch):-1;let wrappedValues=wrapArray(values,Math.max(currentMatchIndex,0));normalizedSearch.length===1&&(wrappedValues=wrappedValues.filter(v2=>v2!==currentMatch));const nextMatch=wrappedValues.find(value2=>value2.toLowerCase().startsWith(normalizedSearch.toLowerCase()));return nextMatch!==currentMatch?nextMatch:void 0}__name(getNextMatch,"getNextMatch");function isPointInPolygon$1(point2,polygon){const{x:x2,y:y2}=point2;let inside=!1;for(let i2=0,j2=polygon.length-1;i2y2!=yj>y2&&x2<(xj-xi)*(y2-yi)/(yj-yi)+xi&&(inside=!inside)}return inside}__name(isPointInPolygon$1,"isPointInPolygon$1");function isPointerInGraceArea(event,area){if(!area)return!1;const cursorPos={x:event.clientX,y:event.clientY};return isPointInPolygon$1(cursorPos,area)}__name(isPointerInGraceArea,"isPointerInGraceArea");function whenMouse(handler){return event=>event.pointerType==="mouse"?handler(event):void 0}__name(whenMouse,"whenMouse");var Root3$1=Menu,Anchor2=MenuAnchor,Portal=MenuPortal,Content2$3=MenuContent,Group=MenuGroup,Label$1=MenuLabel,Item2$1=MenuItem,CheckboxItem=MenuCheckboxItem,RadioGroup=MenuRadioGroup,RadioItem=MenuRadioItem,ItemIndicator=MenuItemIndicator,Separator$2=MenuSeparator,Arrow2=MenuArrow,SubTrigger=MenuSubTrigger,SubContent=MenuSubContent,DROPDOWN_MENU_NAME="DropdownMenu",[createDropdownMenuContext]=createContextScope$1(DROPDOWN_MENU_NAME,[createMenuScope]),useMenuScope=createMenuScope(),[DropdownMenuProvider,useDropdownMenuContext]=createDropdownMenuContext(DROPDOWN_MENU_NAME),DropdownMenu$1=__name(props=>{const{__scopeDropdownMenu,children:children2,dir,open:openProp,defaultOpen,onOpenChange,modal=!0}=props,menuScope=useMenuScope(__scopeDropdownMenu),triggerRef=reactExports.useRef(null),[open,setOpen]=useControllableState({prop:openProp,defaultProp:defaultOpen??!1,onChange:onOpenChange,caller:DROPDOWN_MENU_NAME});return jsxRuntimeExports.jsx(DropdownMenuProvider,{scope:__scopeDropdownMenu,triggerId:useId(),triggerRef,contentId:useId(),open,onOpenChange:setOpen,onOpenToggle:reactExports.useCallback(()=>setOpen(prevOpen=>!prevOpen),[setOpen]),modal,children:jsxRuntimeExports.jsx(Root3$1,{...menuScope,open,onOpenChange:setOpen,dir,modal,children:children2})})},"DropdownMenu$1");DropdownMenu$1.displayName=DROPDOWN_MENU_NAME;var TRIGGER_NAME$4="DropdownMenuTrigger",DropdownMenuTrigger$1=reactExports.forwardRef((props,forwardedRef)=>{const{__scopeDropdownMenu,disabled=!1,...triggerProps}=props,context=useDropdownMenuContext(TRIGGER_NAME$4,__scopeDropdownMenu),menuScope=useMenuScope(__scopeDropdownMenu);return jsxRuntimeExports.jsx(Anchor2,{asChild:!0,...menuScope,children:jsxRuntimeExports.jsx(Primitive$2.button,{type:"button",id:context.triggerId,"aria-haspopup":"menu","aria-expanded":context.open,"aria-controls":context.open?context.contentId:void 0,"data-state":context.open?"open":"closed","data-disabled":disabled?"":void 0,disabled,...triggerProps,ref:composeRefs(forwardedRef,context.triggerRef),onPointerDown:composeEventHandlers(props.onPointerDown,event=>{!disabled&&event.button===0&&event.ctrlKey===!1&&(context.onOpenToggle(),context.open||event.preventDefault())}),onKeyDown:composeEventHandlers(props.onKeyDown,event=>{disabled||(["Enter"," "].includes(event.key)&&context.onOpenToggle(),event.key==="ArrowDown"&&context.onOpenChange(!0),["Enter"," ","ArrowDown"].includes(event.key)&&event.preventDefault())})})})});DropdownMenuTrigger$1.displayName=TRIGGER_NAME$4;var PORTAL_NAME$1="DropdownMenuPortal",DropdownMenuPortal=__name(props=>{const{__scopeDropdownMenu,...portalProps}=props,menuScope=useMenuScope(__scopeDropdownMenu);return jsxRuntimeExports.jsx(Portal,{...menuScope,...portalProps})},"DropdownMenuPortal");DropdownMenuPortal.displayName=PORTAL_NAME$1;var CONTENT_NAME$4="DropdownMenuContent",DropdownMenuContent$1=reactExports.forwardRef((props,forwardedRef)=>{const{__scopeDropdownMenu,...contentProps}=props,context=useDropdownMenuContext(CONTENT_NAME$4,__scopeDropdownMenu),menuScope=useMenuScope(__scopeDropdownMenu),hasInteractedOutsideRef=reactExports.useRef(!1);return jsxRuntimeExports.jsx(Content2$3,{id:context.contentId,"aria-labelledby":context.triggerId,...menuScope,...contentProps,ref:forwardedRef,onCloseAutoFocus:composeEventHandlers(props.onCloseAutoFocus,event=>{hasInteractedOutsideRef.current||context.triggerRef.current?.focus(),hasInteractedOutsideRef.current=!1,event.preventDefault()}),onInteractOutside:composeEventHandlers(props.onInteractOutside,event=>{const originalEvent=event.detail.originalEvent,ctrlLeftClick=originalEvent.button===0&&originalEvent.ctrlKey===!0,isRightClick=originalEvent.button===2||ctrlLeftClick;(!context.modal||isRightClick)&&(hasInteractedOutsideRef.current=!0)}),style:{...props.style,"--radix-dropdown-menu-content-transform-origin":"var(--radix-popper-transform-origin)","--radix-dropdown-menu-content-available-width":"var(--radix-popper-available-width)","--radix-dropdown-menu-content-available-height":"var(--radix-popper-available-height)","--radix-dropdown-menu-trigger-width":"var(--radix-popper-anchor-width)","--radix-dropdown-menu-trigger-height":"var(--radix-popper-anchor-height)"}})});DropdownMenuContent$1.displayName=CONTENT_NAME$4;var GROUP_NAME="DropdownMenuGroup",DropdownMenuGroup=reactExports.forwardRef((props,forwardedRef)=>{const{__scopeDropdownMenu,...groupProps}=props,menuScope=useMenuScope(__scopeDropdownMenu);return jsxRuntimeExports.jsx(Group,{...menuScope,...groupProps,ref:forwardedRef})});DropdownMenuGroup.displayName=GROUP_NAME;var LABEL_NAME="DropdownMenuLabel",DropdownMenuLabel$1=reactExports.forwardRef((props,forwardedRef)=>{const{__scopeDropdownMenu,...labelProps}=props,menuScope=useMenuScope(__scopeDropdownMenu);return jsxRuntimeExports.jsx(Label$1,{...menuScope,...labelProps,ref:forwardedRef})});DropdownMenuLabel$1.displayName=LABEL_NAME;var ITEM_NAME$1="DropdownMenuItem",DropdownMenuItem$1=reactExports.forwardRef((props,forwardedRef)=>{const{__scopeDropdownMenu,...itemProps}=props,menuScope=useMenuScope(__scopeDropdownMenu);return jsxRuntimeExports.jsx(Item2$1,{...menuScope,...itemProps,ref:forwardedRef})});DropdownMenuItem$1.displayName=ITEM_NAME$1;var CHECKBOX_ITEM_NAME="DropdownMenuCheckboxItem",DropdownMenuCheckboxItem$1=reactExports.forwardRef((props,forwardedRef)=>{const{__scopeDropdownMenu,...checkboxItemProps}=props,menuScope=useMenuScope(__scopeDropdownMenu);return jsxRuntimeExports.jsx(CheckboxItem,{...menuScope,...checkboxItemProps,ref:forwardedRef})});DropdownMenuCheckboxItem$1.displayName=CHECKBOX_ITEM_NAME;var RADIO_GROUP_NAME="DropdownMenuRadioGroup",DropdownMenuRadioGroup=reactExports.forwardRef((props,forwardedRef)=>{const{__scopeDropdownMenu,...radioGroupProps}=props,menuScope=useMenuScope(__scopeDropdownMenu);return jsxRuntimeExports.jsx(RadioGroup,{...menuScope,...radioGroupProps,ref:forwardedRef})});DropdownMenuRadioGroup.displayName=RADIO_GROUP_NAME;var RADIO_ITEM_NAME="DropdownMenuRadioItem",DropdownMenuRadioItem$1=reactExports.forwardRef((props,forwardedRef)=>{const{__scopeDropdownMenu,...radioItemProps}=props,menuScope=useMenuScope(__scopeDropdownMenu);return jsxRuntimeExports.jsx(RadioItem,{...menuScope,...radioItemProps,ref:forwardedRef})});DropdownMenuRadioItem$1.displayName=RADIO_ITEM_NAME;var INDICATOR_NAME="DropdownMenuItemIndicator",DropdownMenuItemIndicator=reactExports.forwardRef((props,forwardedRef)=>{const{__scopeDropdownMenu,...itemIndicatorProps}=props,menuScope=useMenuScope(__scopeDropdownMenu);return jsxRuntimeExports.jsx(ItemIndicator,{...menuScope,...itemIndicatorProps,ref:forwardedRef})});DropdownMenuItemIndicator.displayName=INDICATOR_NAME;var SEPARATOR_NAME="DropdownMenuSeparator",DropdownMenuSeparator$1=reactExports.forwardRef((props,forwardedRef)=>{const{__scopeDropdownMenu,...separatorProps}=props,menuScope=useMenuScope(__scopeDropdownMenu);return jsxRuntimeExports.jsx(Separator$2,{...menuScope,...separatorProps,ref:forwardedRef})});DropdownMenuSeparator$1.displayName=SEPARATOR_NAME;var ARROW_NAME$1="DropdownMenuArrow",DropdownMenuArrow=reactExports.forwardRef((props,forwardedRef)=>{const{__scopeDropdownMenu,...arrowProps}=props,menuScope=useMenuScope(__scopeDropdownMenu);return jsxRuntimeExports.jsx(Arrow2,{...menuScope,...arrowProps,ref:forwardedRef})});DropdownMenuArrow.displayName=ARROW_NAME$1;var SUB_TRIGGER_NAME="DropdownMenuSubTrigger",DropdownMenuSubTrigger$1=reactExports.forwardRef((props,forwardedRef)=>{const{__scopeDropdownMenu,...subTriggerProps}=props,menuScope=useMenuScope(__scopeDropdownMenu);return jsxRuntimeExports.jsx(SubTrigger,{...menuScope,...subTriggerProps,ref:forwardedRef})});DropdownMenuSubTrigger$1.displayName=SUB_TRIGGER_NAME;var SUB_CONTENT_NAME="DropdownMenuSubContent",DropdownMenuSubContent$1=reactExports.forwardRef((props,forwardedRef)=>{const{__scopeDropdownMenu,...subContentProps}=props,menuScope=useMenuScope(__scopeDropdownMenu);return jsxRuntimeExports.jsx(SubContent,{...menuScope,...subContentProps,ref:forwardedRef,style:{...props.style,"--radix-dropdown-menu-content-transform-origin":"var(--radix-popper-transform-origin)","--radix-dropdown-menu-content-available-width":"var(--radix-popper-available-width)","--radix-dropdown-menu-content-available-height":"var(--radix-popper-available-height)","--radix-dropdown-menu-trigger-width":"var(--radix-popper-anchor-width)","--radix-dropdown-menu-trigger-height":"var(--radix-popper-anchor-height)"}})});DropdownMenuSubContent$1.displayName=SUB_CONTENT_NAME;var Root2$2=DropdownMenu$1,Trigger$3=DropdownMenuTrigger$1,Portal2=DropdownMenuPortal,Content2$2=DropdownMenuContent$1,Label2=DropdownMenuLabel$1,Item2=DropdownMenuItem$1,CheckboxItem2=DropdownMenuCheckboxItem$1,RadioItem2=DropdownMenuRadioItem$1,ItemIndicator2=DropdownMenuItemIndicator,Separator2=DropdownMenuSeparator$1,SubTrigger2=DropdownMenuSubTrigger$1,SubContent2=DropdownMenuSubContent$1;const DropdownMenu=Root2$2,DropdownMenuTrigger=Trigger$3,DropdownMenuSubTrigger=reactExports.forwardRef(({className,inset,children:children2,...props},ref)=>jsxRuntimeExports.jsxs(SubTrigger2,{ref,className:cn$2("flex cursor-default select-none items-center rounded-sm px-2 py-1.5 text-sm outline-none focus:bg-accent data-[state=open]:bg-accent",inset&&"pl-8",className),...props,children:[children2,jsxRuntimeExports.jsx(ChevronRight,{className:"ml-auto h-4 w-4"})]}));DropdownMenuSubTrigger.displayName=SubTrigger2.displayName;const DropdownMenuSubContent=reactExports.forwardRef(({className,...props},ref)=>jsxRuntimeExports.jsx(SubContent2,{ref,className:cn$2("z-50 min-w-[8rem] overflow-hidden rounded-md border bg-popover p-1 text-popover-foreground shadow-lg data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2",className),...props}));DropdownMenuSubContent.displayName=SubContent2.displayName;const DropdownMenuContent=reactExports.forwardRef(({className,sideOffset=4,...props},ref)=>jsxRuntimeExports.jsx(Portal2,{children:jsxRuntimeExports.jsx(Content2$2,{ref,sideOffset,className:cn$2("z-50 min-w-[8rem] overflow-hidden rounded-md border bg-popover p-1 text-popover-foreground shadow-md data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2",className),...props})}));DropdownMenuContent.displayName=Content2$2.displayName;const DropdownMenuItem=reactExports.forwardRef(({className,inset,...props},ref)=>jsxRuntimeExports.jsx(Item2,{ref,className:cn$2("relative flex cursor-default select-none items-center rounded-sm px-2 py-1.5 text-sm outline-none transition-colors focus:bg-accent focus:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50",inset&&"pl-8",className),...props}));DropdownMenuItem.displayName=Item2.displayName;const DropdownMenuCheckboxItem=reactExports.forwardRef(({className,children:children2,checked,...props},ref)=>jsxRuntimeExports.jsxs(CheckboxItem2,{ref,className:cn$2("relative flex cursor-default select-none items-center rounded-sm py-1.5 pl-8 pr-2 text-sm outline-none transition-colors focus:bg-accent focus:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50",className),checked,...props,children:[jsxRuntimeExports.jsx("span",{className:"absolute left-2 flex h-3.5 w-3.5 items-center justify-center",children:jsxRuntimeExports.jsx(ItemIndicator2,{children:jsxRuntimeExports.jsx(Check,{className:"h-4 w-4"})})}),children2]}));DropdownMenuCheckboxItem.displayName=CheckboxItem2.displayName;const DropdownMenuRadioItem=reactExports.forwardRef(({className,children:children2,...props},ref)=>jsxRuntimeExports.jsxs(RadioItem2,{ref,className:cn$2("relative flex cursor-default select-none items-center rounded-sm py-1.5 pl-8 pr-2 text-sm outline-none transition-colors focus:bg-accent focus:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50",className),...props,children:[jsxRuntimeExports.jsx("span",{className:"absolute left-2 flex h-3.5 w-3.5 items-center justify-center",children:jsxRuntimeExports.jsx(ItemIndicator2,{children:jsxRuntimeExports.jsx(Circle,{className:"h-2 w-2 fill-current"})})}),children2]}));DropdownMenuRadioItem.displayName=RadioItem2.displayName;const DropdownMenuLabel=reactExports.forwardRef(({className,inset,...props},ref)=>jsxRuntimeExports.jsx(Label2,{ref,className:cn$2("px-2 py-1.5 text-sm font-semibold",inset&&"pl-8",className),...props}));DropdownMenuLabel.displayName=Label2.displayName;const DropdownMenuSeparator=reactExports.forwardRef(({className,...props},ref)=>jsxRuntimeExports.jsx(Separator2,{ref,className:cn$2("-mx-1 my-1 h-px bg-muted",className),...props}));DropdownMenuSeparator.displayName=Separator2.displayName;function _objectWithoutPropertiesLoose$j(source,excluded){if(source==null)return{};var target={},sourceKeys=Object.keys(source),key,i2;for(i2=0;i2=0)&&(target[key]=source[key]);return target}__name(_objectWithoutPropertiesLoose$j,"_objectWithoutPropertiesLoose$j");var _excluded$e$1=["color"],ArrowDownIcon=reactExports.forwardRef(function(_ref,forwardedRef){var _ref$color=_ref.color,color=_ref$color===void 0?"currentColor":_ref$color,props=_objectWithoutPropertiesLoose$j(_ref,_excluded$e$1);return reactExports.createElement("svg",Object.assign({width:"15",height:"15",viewBox:"0 0 15 15",fill:"none",xmlns:"http://www.w3.org/2000/svg"},props,{ref:forwardedRef}),reactExports.createElement("path",{d:"M7.5 2C7.77614 2 8 2.22386 8 2.5L8 11.2929L11.1464 8.14645C11.3417 7.95118 11.6583 7.95118 11.8536 8.14645C12.0488 8.34171 12.0488 8.65829 11.8536 8.85355L7.85355 12.8536C7.75979 12.9473 7.63261 13 7.5 13C7.36739 13 7.24021 12.9473 7.14645 12.8536L3.14645 8.85355C2.95118 8.65829 2.95118 8.34171 3.14645 8.14645C3.34171 7.95118 3.65829 7.95118 3.85355 8.14645L7 11.2929L7 2.5C7 2.22386 7.22386 2 7.5 2Z",fill:color,fillRule:"evenodd",clipRule:"evenodd"}))}),_excluded$g$1=["color"],ArrowRightIcon=reactExports.forwardRef(function(_ref,forwardedRef){var _ref$color=_ref.color,color=_ref$color===void 0?"currentColor":_ref$color,props=_objectWithoutPropertiesLoose$j(_ref,_excluded$g$1);return reactExports.createElement("svg",Object.assign({width:"15",height:"15",viewBox:"0 0 15 15",fill:"none",xmlns:"http://www.w3.org/2000/svg"},props,{ref:forwardedRef}),reactExports.createElement("path",{d:"M8.14645 3.14645C8.34171 2.95118 8.65829 2.95118 8.85355 3.14645L12.8536 7.14645C13.0488 7.34171 13.0488 7.65829 12.8536 7.85355L8.85355 11.8536C8.65829 12.0488 8.34171 12.0488 8.14645 11.8536C7.95118 11.6583 7.95118 11.3417 8.14645 11.1464L11.2929 8H2.5C2.22386 8 2 7.77614 2 7.5C2 7.22386 2.22386 7 2.5 7H11.2929L8.14645 3.85355C7.95118 3.65829 7.95118 3.34171 8.14645 3.14645Z",fill:color,fillRule:"evenodd",clipRule:"evenodd"}))}),_excluded$j=["color"],ArrowUpIcon=reactExports.forwardRef(function(_ref,forwardedRef){var _ref$color=_ref.color,color=_ref$color===void 0?"currentColor":_ref$color,props=_objectWithoutPropertiesLoose$j(_ref,_excluded$j);return reactExports.createElement("svg",Object.assign({width:"15",height:"15",viewBox:"0 0 15 15",fill:"none",xmlns:"http://www.w3.org/2000/svg"},props,{ref:forwardedRef}),reactExports.createElement("path",{d:"M7.14645 2.14645C7.34171 1.95118 7.65829 1.95118 7.85355 2.14645L11.8536 6.14645C12.0488 6.34171 12.0488 6.65829 11.8536 6.85355C11.6583 7.04882 11.3417 7.04882 11.1464 6.85355L8 3.70711L8 12.5C8 12.7761 7.77614 13 7.5 13C7.22386 13 7 12.7761 7 12.5L7 3.70711L3.85355 6.85355C3.65829 7.04882 3.34171 7.04882 3.14645 6.85355C2.95118 6.65829 2.95118 6.34171 3.14645 6.14645L7.14645 2.14645Z",fill:color,fillRule:"evenodd",clipRule:"evenodd"}))}),_excluded$U=["color"],CheckCircledIcon=reactExports.forwardRef(function(_ref,forwardedRef){var _ref$color=_ref.color,color=_ref$color===void 0?"currentColor":_ref$color,props=_objectWithoutPropertiesLoose$j(_ref,_excluded$U);return reactExports.createElement("svg",Object.assign({width:"15",height:"15",viewBox:"0 0 15 15",fill:"none",xmlns:"http://www.w3.org/2000/svg"},props,{ref:forwardedRef}),reactExports.createElement("path",{d:"M7.49991 0.877045C3.84222 0.877045 0.877075 3.84219 0.877075 7.49988C0.877075 11.1575 3.84222 14.1227 7.49991 14.1227C11.1576 14.1227 14.1227 11.1575 14.1227 7.49988C14.1227 3.84219 11.1576 0.877045 7.49991 0.877045ZM1.82708 7.49988C1.82708 4.36686 4.36689 1.82704 7.49991 1.82704C10.6329 1.82704 13.1727 4.36686 13.1727 7.49988C13.1727 10.6329 10.6329 13.1727 7.49991 13.1727C4.36689 13.1727 1.82708 10.6329 1.82708 7.49988ZM10.1589 5.53774C10.3178 5.31191 10.2636 5.00001 10.0378 4.84109C9.81194 4.68217 9.50004 4.73642 9.34112 4.96225L6.51977 8.97154L5.35681 7.78706C5.16334 7.59002 4.84677 7.58711 4.64973 7.78058C4.45268 7.97404 4.44978 8.29061 4.64325 8.48765L6.22658 10.1003C6.33054 10.2062 6.47617 10.2604 6.62407 10.2483C6.77197 10.2363 6.90686 10.1591 6.99226 10.0377L10.1589 5.53774Z",fill:color,fillRule:"evenodd",clipRule:"evenodd"}))}),_excluded$W=["color"],ChevronDownIcon=reactExports.forwardRef(function(_ref,forwardedRef){var _ref$color=_ref.color,color=_ref$color===void 0?"currentColor":_ref$color,props=_objectWithoutPropertiesLoose$j(_ref,_excluded$W);return reactExports.createElement("svg",Object.assign({width:"15",height:"15",viewBox:"0 0 15 15",fill:"none",xmlns:"http://www.w3.org/2000/svg"},props,{ref:forwardedRef}),reactExports.createElement("path",{d:"M3.13523 6.15803C3.3241 5.95657 3.64052 5.94637 3.84197 6.13523L7.5 9.56464L11.158 6.13523C11.3595 5.94637 11.6759 5.95657 11.8648 6.15803C12.0536 6.35949 12.0434 6.67591 11.842 6.86477L7.84197 10.6148C7.64964 10.7951 7.35036 10.7951 7.15803 10.6148L3.15803 6.86477C2.95657 6.67591 2.94637 6.35949 3.13523 6.15803Z",fill:color,fillRule:"evenodd",clipRule:"evenodd"}))}),_excluded$1s=["color"],CrossCircledIcon=reactExports.forwardRef(function(_ref,forwardedRef){var _ref$color=_ref.color,color=_ref$color===void 0?"currentColor":_ref$color,props=_objectWithoutPropertiesLoose$j(_ref,_excluded$1s);return reactExports.createElement("svg",Object.assign({width:"15",height:"15",viewBox:"0 0 15 15",fill:"none",xmlns:"http://www.w3.org/2000/svg"},props,{ref:forwardedRef}),reactExports.createElement("path",{d:"M0.877075 7.49988C0.877075 3.84219 3.84222 0.877045 7.49991 0.877045C11.1576 0.877045 14.1227 3.84219 14.1227 7.49988C14.1227 11.1575 11.1576 14.1227 7.49991 14.1227C3.84222 14.1227 0.877075 11.1575 0.877075 7.49988ZM7.49991 1.82704C4.36689 1.82704 1.82708 4.36686 1.82708 7.49988C1.82708 10.6329 4.36689 13.1727 7.49991 13.1727C10.6329 13.1727 13.1727 10.6329 13.1727 7.49988C13.1727 4.36686 10.6329 1.82704 7.49991 1.82704ZM9.85358 5.14644C10.0488 5.3417 10.0488 5.65829 9.85358 5.85355L8.20713 7.49999L9.85358 9.14644C10.0488 9.3417 10.0488 9.65829 9.85358 9.85355C9.65832 10.0488 9.34173 10.0488 9.14647 9.85355L7.50002 8.2071L5.85358 9.85355C5.65832 10.0488 5.34173 10.0488 5.14647 9.85355C4.95121 9.65829 4.95121 9.3417 5.14647 9.14644L6.79292 7.49999L5.14647 5.85355C4.95121 5.65829 4.95121 5.3417 5.14647 5.14644C5.34173 4.95118 5.65832 4.95118 5.85358 5.14644L7.50002 6.79289L9.14647 5.14644C9.34173 4.95118 9.65832 4.95118 9.85358 5.14644Z",fill:color,fillRule:"evenodd",clipRule:"evenodd"}))}),_excluded$20=["color"],ExclamationTriangleIcon=reactExports.forwardRef(function(_ref,forwardedRef){var _ref$color=_ref.color,color=_ref$color===void 0?"currentColor":_ref$color,props=_objectWithoutPropertiesLoose$j(_ref,_excluded$20);return reactExports.createElement("svg",Object.assign({width:"15",height:"15",viewBox:"0 0 15 15",fill:"none",xmlns:"http://www.w3.org/2000/svg"},props,{ref:forwardedRef}),reactExports.createElement("path",{d:"M8.4449 0.608765C8.0183 -0.107015 6.9817 -0.107015 6.55509 0.608766L0.161178 11.3368C-0.275824 12.07 0.252503 13 1.10608 13H13.8939C14.7475 13 15.2758 12.07 14.8388 11.3368L8.4449 0.608765ZM7.4141 1.12073C7.45288 1.05566 7.54712 1.05566 7.5859 1.12073L13.9798 11.8488C14.0196 11.9154 13.9715 12 13.8939 12H1.10608C1.02849 12 0.980454 11.9154 1.02018 11.8488L7.4141 1.12073ZM6.8269 4.48611C6.81221 4.10423 7.11783 3.78663 7.5 3.78663C7.88217 3.78663 8.18778 4.10423 8.1731 4.48612L8.01921 8.48701C8.00848 8.766 7.7792 8.98664 7.5 8.98664C7.2208 8.98664 6.99151 8.766 6.98078 8.48701L6.8269 4.48611ZM8.24989 10.476C8.24989 10.8902 7.9141 11.226 7.49989 11.226C7.08567 11.226 6.74989 10.8902 6.74989 10.476C6.74989 10.0618 7.08567 9.72599 7.49989 9.72599C7.9141 9.72599 8.24989 10.0618 8.24989 10.476Z",fill:color,fillRule:"evenodd",clipRule:"evenodd"}))}),_excluded$37=["color"],MinusIcon=reactExports.forwardRef(function(_ref,forwardedRef){var _ref$color=_ref.color,color=_ref$color===void 0?"currentColor":_ref$color,props=_objectWithoutPropertiesLoose$j(_ref,_excluded$37);return reactExports.createElement("svg",Object.assign({width:"15",height:"15",viewBox:"0 0 15 15",fill:"none",xmlns:"http://www.w3.org/2000/svg"},props,{ref:forwardedRef}),reactExports.createElement("path",{d:"M2.25 7.5C2.25 7.22386 2.47386 7 2.75 7H12.25C12.5261 7 12.75 7.22386 12.75 7.5C12.75 7.77614 12.5261 8 12.25 8H2.75C2.47386 8 2.25 7.77614 2.25 7.5Z",fill:color,fillRule:"evenodd",clipRule:"evenodd"}))}),_excluded$3e=["color"],MoonIcon=reactExports.forwardRef(function(_ref,forwardedRef){var _ref$color=_ref.color,color=_ref$color===void 0?"currentColor":_ref$color,props=_objectWithoutPropertiesLoose$j(_ref,_excluded$3e);return reactExports.createElement("svg",Object.assign({width:"15",height:"15",viewBox:"0 0 15 15",fill:"none",xmlns:"http://www.w3.org/2000/svg"},props,{ref:forwardedRef}),reactExports.createElement("path",{d:"M2.89998 0.499976C2.89998 0.279062 2.72089 0.0999756 2.49998 0.0999756C2.27906 0.0999756 2.09998 0.279062 2.09998 0.499976V1.09998H1.49998C1.27906 1.09998 1.09998 1.27906 1.09998 1.49998C1.09998 1.72089 1.27906 1.89998 1.49998 1.89998H2.09998V2.49998C2.09998 2.72089 2.27906 2.89998 2.49998 2.89998C2.72089 2.89998 2.89998 2.72089 2.89998 2.49998V1.89998H3.49998C3.72089 1.89998 3.89998 1.72089 3.89998 1.49998C3.89998 1.27906 3.72089 1.09998 3.49998 1.09998H2.89998V0.499976ZM5.89998 3.49998C5.89998 3.27906 5.72089 3.09998 5.49998 3.09998C5.27906 3.09998 5.09998 3.27906 5.09998 3.49998V4.09998H4.49998C4.27906 4.09998 4.09998 4.27906 4.09998 4.49998C4.09998 4.72089 4.27906 4.89998 4.49998 4.89998H5.09998V5.49998C5.09998 5.72089 5.27906 5.89998 5.49998 5.89998C5.72089 5.89998 5.89998 5.72089 5.89998 5.49998V4.89998H6.49998C6.72089 4.89998 6.89998 4.72089 6.89998 4.49998C6.89998 4.27906 6.72089 4.09998 6.49998 4.09998H5.89998V3.49998ZM1.89998 6.49998C1.89998 6.27906 1.72089 6.09998 1.49998 6.09998C1.27906 6.09998 1.09998 6.27906 1.09998 6.49998V7.09998H0.499976C0.279062 7.09998 0.0999756 7.27906 0.0999756 7.49998C0.0999756 7.72089 0.279062 7.89998 0.499976 7.89998H1.09998V8.49998C1.09998 8.72089 1.27906 8.89997 1.49998 8.89997C1.72089 8.89997 1.89998 8.72089 1.89998 8.49998V7.89998H2.49998C2.72089 7.89998 2.89998 7.72089 2.89998 7.49998C2.89998 7.27906 2.72089 7.09998 2.49998 7.09998H1.89998V6.49998ZM8.54406 0.98184L8.24618 0.941586C8.03275 0.917676 7.90692 1.1655 8.02936 1.34194C8.17013 1.54479 8.29981 1.75592 8.41754 1.97445C8.91878 2.90485 9.20322 3.96932 9.20322 5.10022C9.20322 8.37201 6.82247 11.0878 3.69887 11.6097C3.45736 11.65 3.20988 11.6772 2.96008 11.6906C2.74563 11.702 2.62729 11.9535 2.77721 12.1072C2.84551 12.1773 2.91535 12.2458 2.98667 12.3128L3.05883 12.3795L3.31883 12.6045L3.50684 12.7532L3.62796 12.8433L3.81491 12.9742L3.99079 13.089C4.11175 13.1651 4.23536 13.2375 4.36157 13.3059L4.62496 13.4412L4.88553 13.5607L5.18837 13.6828L5.43169 13.7686C5.56564 13.8128 5.70149 13.8529 5.83857 13.8885C5.94262 13.9155 6.04767 13.9401 6.15405 13.9622C6.27993 13.9883 6.40713 14.0109 6.53544 14.0298L6.85241 14.0685L7.11934 14.0892C7.24637 14.0965 7.37436 14.1002 7.50322 14.1002C11.1483 14.1002 14.1032 11.1453 14.1032 7.50023C14.1032 7.25044 14.0893 7.00389 14.0623 6.76131L14.0255 6.48407C13.991 6.26083 13.9453 6.04129 13.8891 5.82642C13.8213 5.56709 13.7382 5.31398 13.6409 5.06881L13.5279 4.80132L13.4507 4.63542L13.3766 4.48666C13.2178 4.17773 13.0353 3.88295 12.8312 3.60423L12.6782 3.40352L12.4793 3.16432L12.3157 2.98361L12.1961 2.85951L12.0355 2.70246L11.8134 2.50184L11.4925 2.24191L11.2483 2.06498L10.9562 1.87446L10.6346 1.68894L10.3073 1.52378L10.1938 1.47176L9.95488 1.3706L9.67791 1.2669L9.42566 1.1846L9.10075 1.09489L8.83599 1.03486L8.54406 0.98184ZM10.4032 5.30023C10.4032 4.27588 10.2002 3.29829 9.83244 2.40604C11.7623 3.28995 13.1032 5.23862 13.1032 7.50023C13.1032 10.593 10.596 13.1002 7.50322 13.1002C6.63646 13.1002 5.81597 12.9036 5.08355 12.5522C6.5419 12.0941 7.81081 11.2082 8.74322 10.0416C8.87963 10.2284 9.10028 10.3497 9.34928 10.3497C9.76349 10.3497 10.0993 10.0139 10.0993 9.59971C10.0993 9.24256 9.84965 8.94373 9.51535 8.86816C9.57741 8.75165 9.63653 8.63334 9.6926 8.51332C9.88358 8.63163 10.1088 8.69993 10.35 8.69993C11.0403 8.69993 11.6 8.14028 11.6 7.44993C11.6 6.75976 11.0406 6.20024 10.3505 6.19993C10.3853 5.90487 10.4032 5.60464 10.4032 5.30023Z",fill:color,fillRule:"evenodd",clipRule:"evenodd"}))}),_excluded$3A=["color"],QuestionMarkCircledIcon=reactExports.forwardRef(function(_ref,forwardedRef){var _ref$color=_ref.color,color=_ref$color===void 0?"currentColor":_ref$color,props=_objectWithoutPropertiesLoose$j(_ref,_excluded$3A);return reactExports.createElement("svg",Object.assign({width:"15",height:"15",viewBox:"0 0 15 15",fill:"none",xmlns:"http://www.w3.org/2000/svg"},props,{ref:forwardedRef}),reactExports.createElement("path",{d:"M0.877075 7.49972C0.877075 3.84204 3.84222 0.876892 7.49991 0.876892C11.1576 0.876892 14.1227 3.84204 14.1227 7.49972C14.1227 11.1574 11.1576 14.1226 7.49991 14.1226C3.84222 14.1226 0.877075 11.1574 0.877075 7.49972ZM7.49991 1.82689C4.36689 1.82689 1.82708 4.36671 1.82708 7.49972C1.82708 10.6327 4.36689 13.1726 7.49991 13.1726C10.6329 13.1726 13.1727 10.6327 13.1727 7.49972C13.1727 4.36671 10.6329 1.82689 7.49991 1.82689ZM8.24993 10.5C8.24993 10.9142 7.91414 11.25 7.49993 11.25C7.08571 11.25 6.74993 10.9142 6.74993 10.5C6.74993 10.0858 7.08571 9.75 7.49993 9.75C7.91414 9.75 8.24993 10.0858 8.24993 10.5ZM6.05003 6.25C6.05003 5.57211 6.63511 4.925 7.50003 4.925C8.36496 4.925 8.95003 5.57211 8.95003 6.25C8.95003 6.74118 8.68002 6.99212 8.21447 7.27494C8.16251 7.30651 8.10258 7.34131 8.03847 7.37854L8.03841 7.37858C7.85521 7.48497 7.63788 7.61119 7.47449 7.73849C7.23214 7.92732 6.95003 8.23198 6.95003 8.7C6.95004 9.00376 7.19628 9.25 7.50004 9.25C7.8024 9.25 8.04778 9.00601 8.05002 8.70417L8.05056 8.7033C8.05924 8.6896 8.08493 8.65735 8.15058 8.6062C8.25207 8.52712 8.36508 8.46163 8.51567 8.37436L8.51571 8.37433C8.59422 8.32883 8.68296 8.27741 8.78559 8.21506C9.32004 7.89038 10.05 7.35382 10.05 6.25C10.05 4.92789 8.93511 3.825 7.50003 3.825C6.06496 3.825 4.95003 4.92789 4.95003 6.25C4.95003 6.55376 5.19628 6.8 5.50003 6.8C5.80379 6.8 6.05003 6.55376 6.05003 6.25Z",fill:color,fillRule:"evenodd",clipRule:"evenodd"}))}),_excluded$4e=["color"],StopwatchIcon=reactExports.forwardRef(function(_ref,forwardedRef){var _ref$color=_ref.color,color=_ref$color===void 0?"currentColor":_ref$color,props=_objectWithoutPropertiesLoose$j(_ref,_excluded$4e);return reactExports.createElement("svg",Object.assign({width:"15",height:"15",viewBox:"0 0 15 15",fill:"none",xmlns:"http://www.w3.org/2000/svg"},props,{ref:forwardedRef}),reactExports.createElement("path",{d:"M5.49998 0.5C5.49998 0.223858 5.72383 0 5.99998 0H7.49998H8.99998C9.27612 0 9.49998 0.223858 9.49998 0.5C9.49998 0.776142 9.27612 1 8.99998 1H7.99998V2.11922C9.09832 2.20409 10.119 2.56622 10.992 3.13572C11.0116 3.10851 11.0336 3.08252 11.058 3.05806L11.858 2.25806C12.1021 2.01398 12.4978 2.01398 12.7419 2.25806C12.986 2.50214 12.986 2.89786 12.7419 3.14194L11.967 3.91682C13.1595 5.07925 13.9 6.70314 13.9 8.49998C13.9 12.0346 11.0346 14.9 7.49998 14.9C3.96535 14.9 1.09998 12.0346 1.09998 8.49998C1.09998 5.13362 3.69904 2.3743 6.99998 2.11922V1H5.99998C5.72383 1 5.49998 0.776142 5.49998 0.5ZM2.09998 8.49998C2.09998 5.51764 4.51764 3.09998 7.49998 3.09998C10.4823 3.09998 12.9 5.51764 12.9 8.49998C12.9 11.4823 10.4823 13.9 7.49998 13.9C4.51764 13.9 2.09998 11.4823 2.09998 8.49998ZM7.99998 4.5C7.99998 4.22386 7.77612 4 7.49998 4C7.22383 4 6.99998 4.22386 6.99998 4.5V9.5C6.99998 9.77614 7.22383 10 7.49998 10C7.77612 10 7.99998 9.77614 7.99998 9.5V4.5Z",fill:color,fillRule:"evenodd",clipRule:"evenodd"}))}),_excluded$4i=["color"],SunIcon=reactExports.forwardRef(function(_ref,forwardedRef){var _ref$color=_ref.color,color=_ref$color===void 0?"currentColor":_ref$color,props=_objectWithoutPropertiesLoose$j(_ref,_excluded$4i);return reactExports.createElement("svg",Object.assign({width:"15",height:"15",viewBox:"0 0 15 15",fill:"none",xmlns:"http://www.w3.org/2000/svg"},props,{ref:forwardedRef}),reactExports.createElement("path",{d:"M7.5 0C7.77614 0 8 0.223858 8 0.5V2.5C8 2.77614 7.77614 3 7.5 3C7.22386 3 7 2.77614 7 2.5V0.5C7 0.223858 7.22386 0 7.5 0ZM2.1967 2.1967C2.39196 2.00144 2.70854 2.00144 2.90381 2.1967L4.31802 3.61091C4.51328 3.80617 4.51328 4.12276 4.31802 4.31802C4.12276 4.51328 3.80617 4.51328 3.61091 4.31802L2.1967 2.90381C2.00144 2.70854 2.00144 2.39196 2.1967 2.1967ZM0.5 7C0.223858 7 0 7.22386 0 7.5C0 7.77614 0.223858 8 0.5 8H2.5C2.77614 8 3 7.77614 3 7.5C3 7.22386 2.77614 7 2.5 7H0.5ZM2.1967 12.8033C2.00144 12.608 2.00144 12.2915 2.1967 12.0962L3.61091 10.682C3.80617 10.4867 4.12276 10.4867 4.31802 10.682C4.51328 10.8772 4.51328 11.1938 4.31802 11.3891L2.90381 12.8033C2.70854 12.9986 2.39196 12.9986 2.1967 12.8033ZM12.5 7C12.2239 7 12 7.22386 12 7.5C12 7.77614 12.2239 8 12.5 8H14.5C14.7761 8 15 7.77614 15 7.5C15 7.22386 14.7761 7 14.5 7H12.5ZM10.682 4.31802C10.4867 4.12276 10.4867 3.80617 10.682 3.61091L12.0962 2.1967C12.2915 2.00144 12.608 2.00144 12.8033 2.1967C12.9986 2.39196 12.9986 2.70854 12.8033 2.90381L11.3891 4.31802C11.1938 4.51328 10.8772 4.51328 10.682 4.31802ZM8 12.5C8 12.2239 7.77614 12 7.5 12C7.22386 12 7 12.2239 7 12.5V14.5C7 14.7761 7.22386 15 7.5 15C7.77614 15 8 14.7761 8 14.5V12.5ZM10.682 10.682C10.8772 10.4867 11.1938 10.4867 11.3891 10.682L12.8033 12.0962C12.9986 12.2915 12.9986 12.608 12.8033 12.8033C12.608 12.9986 12.2915 12.9986 12.0962 12.8033L10.682 11.3891C10.4867 11.1938 10.4867 10.8772 10.682 10.682ZM5.5 7.5C5.5 6.39543 6.39543 5.5 7.5 5.5C8.60457 5.5 9.5 6.39543 9.5 7.5C9.5 8.60457 8.60457 9.5 7.5 9.5C6.39543 9.5 5.5 8.60457 5.5 7.5ZM7.5 4.5C5.84315 4.5 4.5 5.84315 4.5 7.5C4.5 9.15685 5.84315 10.5 7.5 10.5C9.15685 10.5 10.5 9.15685 10.5 7.5C10.5 5.84315 9.15685 4.5 7.5 4.5Z",fill:color,fillRule:"evenodd",clipRule:"evenodd"}))}),_excluded$4W=["color"],ViewVerticalIcon=reactExports.forwardRef(function(_ref,forwardedRef){var _ref$color=_ref.color,color=_ref$color===void 0?"currentColor":_ref$color,props=_objectWithoutPropertiesLoose$j(_ref,_excluded$4W);return reactExports.createElement("svg",Object.assign({width:"15",height:"15",viewBox:"0 0 15 15",fill:"none",xmlns:"http://www.w3.org/2000/svg"},props,{ref:forwardedRef}),reactExports.createElement("path",{d:"M8 2H13.5C13.7761 2 14 2.22386 14 2.5V12.5C14 12.7761 13.7761 13 13.5 13H8V2ZM7 2H1.5C1.22386 2 1 2.22386 1 2.5V12.5C1 12.7761 1.22386 13 1.5 13H7V2ZM0 2.5C0 1.67157 0.671573 1 1.5 1H13.5C14.3284 1 15 1.67157 15 2.5V12.5C15 13.3284 14.3284 14 13.5 14H1.5C0.671573 14 0 13.3284 0 12.5V2.5Z",fill:color,fillRule:"evenodd",clipRule:"evenodd"}))});function useTheme(){const context=reactExports.useContext(ThemeProviderContext);if(context===void 0)throw new Error("useTheme must be used within a ThemeProvider");return context}__name(useTheme,"useTheme");function ModeToggle(){const{theme,setTheme}=useTheme(),toggleTheme=__name(()=>{if(theme==="dark")setTheme("light");else if(theme==="light")setTheme("dark");else{const systemTheme=window.matchMedia("(prefers-color-scheme: dark)").matches?"dark":"light";setTheme(systemTheme==="dark"?"light":"dark")}},"toggleTheme");return jsxRuntimeExports.jsxs(Button,{variant:"ghost",className:"w-9 px-0",onClick:toggleTheme,children:[jsxRuntimeExports.jsx(SunIcon,{className:"h-[1.2rem] w-[1.2rem] rotate-0 scale-100 transition-all dark:-rotate-90 dark:scale-0"}),jsxRuntimeExports.jsx(MoonIcon,{className:"absolute h-[1.2rem] w-[1.2rem] rotate-90 scale-0 transition-all dark:rotate-0 dark:scale-100"}),jsxRuntimeExports.jsx("span",{className:"sr-only",children:"Toggle theme"})]})}__name(ModeToggle,"ModeToggle");const allMenuItems=[{title:"Overview",to:""},{title:"Identity",to:"identity"},{title:"Devices",to:"devices"},{title:"Network",to:"network"},{title:"Infrastructure",to:"infrastructure"},{title:"Data",to:"data"},{title:"SecOps",to:"secops"},{title:"AI",to:"ai"}],mainMenu=allMenuItems.filter(item=>item.title==="Network"?reportData.TestResultSummary?.NetworkTotal!==void 0:item.title==="Data"?reportData.TestResultSummary?.DataTotal!==void 0:item.title==="Infrastructure"?reportData.TestResultSummary?.InfrastructureTotal!==void 0:item.title==="SecOps"?reportData.TestResultSummary?.SecOpsTotal!==void 0:item.title==="AI"?reportData.TestResultSummary?.AITotal!==void 0:!0);function clamp(value2,[min2,max2]){return Math.min(max2,Math.max(min2,value2))}__name(clamp,"clamp");function useStateMachine(initialState2,machine){return reactExports.useReducer((state,event)=>machine[state][event]??state,initialState2)}__name(useStateMachine,"useStateMachine");var SCROLL_AREA_NAME="ScrollArea",[createScrollAreaContext]=createContextScope$1(SCROLL_AREA_NAME),[ScrollAreaProvider,useScrollAreaContext]=createScrollAreaContext(SCROLL_AREA_NAME),ScrollArea=reactExports.forwardRef((props,forwardedRef)=>{const{__scopeScrollArea,type="hover",dir,scrollHideDelay=600,...scrollAreaProps}=props,[scrollArea,setScrollArea]=reactExports.useState(null),[viewport,setViewport]=reactExports.useState(null),[content2,setContent]=reactExports.useState(null),[scrollbarX,setScrollbarX]=reactExports.useState(null),[scrollbarY,setScrollbarY]=reactExports.useState(null),[cornerWidth,setCornerWidth]=reactExports.useState(0),[cornerHeight,setCornerHeight]=reactExports.useState(0),[scrollbarXEnabled,setScrollbarXEnabled]=reactExports.useState(!1),[scrollbarYEnabled,setScrollbarYEnabled]=reactExports.useState(!1),composedRefs=useComposedRefs(forwardedRef,node2=>setScrollArea(node2)),direction=useDirection(dir);return jsxRuntimeExports.jsx(ScrollAreaProvider,{scope:__scopeScrollArea,type,dir:direction,scrollHideDelay,scrollArea,viewport,onViewportChange:setViewport,content:content2,onContentChange:setContent,scrollbarX,onScrollbarXChange:setScrollbarX,scrollbarXEnabled,onScrollbarXEnabledChange:setScrollbarXEnabled,scrollbarY,onScrollbarYChange:setScrollbarY,scrollbarYEnabled,onScrollbarYEnabledChange:setScrollbarYEnabled,onCornerWidthChange:setCornerWidth,onCornerHeightChange:setCornerHeight,children:jsxRuntimeExports.jsx(Primitive$2.div,{dir:direction,...scrollAreaProps,ref:composedRefs,style:{position:"relative","--radix-scroll-area-corner-width":cornerWidth+"px","--radix-scroll-area-corner-height":cornerHeight+"px",...props.style}})})});ScrollArea.displayName=SCROLL_AREA_NAME;var VIEWPORT_NAME="ScrollAreaViewport",ScrollAreaViewport=reactExports.forwardRef((props,forwardedRef)=>{const{__scopeScrollArea,children:children2,nonce,...viewportProps}=props,context=useScrollAreaContext(VIEWPORT_NAME,__scopeScrollArea),ref=reactExports.useRef(null),composedRefs=useComposedRefs(forwardedRef,ref,context.onViewportChange);return jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment,{children:[jsxRuntimeExports.jsx("style",{dangerouslySetInnerHTML:{__html:"[data-radix-scroll-area-viewport]{scrollbar-width:none;-ms-overflow-style:none;-webkit-overflow-scrolling:touch;}[data-radix-scroll-area-viewport]::-webkit-scrollbar{display:none}"},nonce}),jsxRuntimeExports.jsx(Primitive$2.div,{"data-radix-scroll-area-viewport":"",...viewportProps,ref:composedRefs,style:{overflowX:context.scrollbarXEnabled?"scroll":"hidden",overflowY:context.scrollbarYEnabled?"scroll":"hidden",...props.style},children:jsxRuntimeExports.jsx("div",{ref:context.onContentChange,style:{minWidth:"100%",display:"table"},children:children2})})]})});ScrollAreaViewport.displayName=VIEWPORT_NAME;var SCROLLBAR_NAME="ScrollAreaScrollbar",ScrollAreaScrollbar=reactExports.forwardRef((props,forwardedRef)=>{const{forceMount,...scrollbarProps}=props,context=useScrollAreaContext(SCROLLBAR_NAME,props.__scopeScrollArea),{onScrollbarXEnabledChange,onScrollbarYEnabledChange}=context,isHorizontal=props.orientation==="horizontal";return reactExports.useEffect(()=>(isHorizontal?onScrollbarXEnabledChange(!0):onScrollbarYEnabledChange(!0),()=>{isHorizontal?onScrollbarXEnabledChange(!1):onScrollbarYEnabledChange(!1)}),[isHorizontal,onScrollbarXEnabledChange,onScrollbarYEnabledChange]),context.type==="hover"?jsxRuntimeExports.jsx(ScrollAreaScrollbarHover,{...scrollbarProps,ref:forwardedRef,forceMount}):context.type==="scroll"?jsxRuntimeExports.jsx(ScrollAreaScrollbarScroll,{...scrollbarProps,ref:forwardedRef,forceMount}):context.type==="auto"?jsxRuntimeExports.jsx(ScrollAreaScrollbarAuto,{...scrollbarProps,ref:forwardedRef,forceMount}):context.type==="always"?jsxRuntimeExports.jsx(ScrollAreaScrollbarVisible,{...scrollbarProps,ref:forwardedRef}):null});ScrollAreaScrollbar.displayName=SCROLLBAR_NAME;var ScrollAreaScrollbarHover=reactExports.forwardRef((props,forwardedRef)=>{const{forceMount,...scrollbarProps}=props,context=useScrollAreaContext(SCROLLBAR_NAME,props.__scopeScrollArea),[visible,setVisible]=reactExports.useState(!1);return reactExports.useEffect(()=>{const scrollArea=context.scrollArea;let hideTimer=0;if(scrollArea){const handlePointerEnter=__name(()=>{window.clearTimeout(hideTimer),setVisible(!0)},"handlePointerEnter"),handlePointerLeave=__name(()=>{hideTimer=window.setTimeout(()=>setVisible(!1),context.scrollHideDelay)},"handlePointerLeave");return scrollArea.addEventListener("pointerenter",handlePointerEnter),scrollArea.addEventListener("pointerleave",handlePointerLeave),()=>{window.clearTimeout(hideTimer),scrollArea.removeEventListener("pointerenter",handlePointerEnter),scrollArea.removeEventListener("pointerleave",handlePointerLeave)}}},[context.scrollArea,context.scrollHideDelay]),jsxRuntimeExports.jsx(Presence,{present:forceMount||visible,children:jsxRuntimeExports.jsx(ScrollAreaScrollbarAuto,{"data-state":visible?"visible":"hidden",...scrollbarProps,ref:forwardedRef})})}),ScrollAreaScrollbarScroll=reactExports.forwardRef((props,forwardedRef)=>{const{forceMount,...scrollbarProps}=props,context=useScrollAreaContext(SCROLLBAR_NAME,props.__scopeScrollArea),isHorizontal=props.orientation==="horizontal",debounceScrollEnd=useDebounceCallback(()=>send("SCROLL_END"),100),[state,send]=useStateMachine("hidden",{hidden:{SCROLL:"scrolling"},scrolling:{SCROLL_END:"idle",POINTER_ENTER:"interacting"},interacting:{SCROLL:"interacting",POINTER_LEAVE:"idle"},idle:{HIDE:"hidden",SCROLL:"scrolling",POINTER_ENTER:"interacting"}});return reactExports.useEffect(()=>{if(state==="idle"){const hideTimer=window.setTimeout(()=>send("HIDE"),context.scrollHideDelay);return()=>window.clearTimeout(hideTimer)}},[state,context.scrollHideDelay,send]),reactExports.useEffect(()=>{const viewport=context.viewport,scrollDirection=isHorizontal?"scrollLeft":"scrollTop";if(viewport){let prevScrollPos=viewport[scrollDirection];const handleScroll2=__name(()=>{const scrollPos=viewport[scrollDirection];prevScrollPos!==scrollPos&&(send("SCROLL"),debounceScrollEnd()),prevScrollPos=scrollPos},"handleScroll");return viewport.addEventListener("scroll",handleScroll2),()=>viewport.removeEventListener("scroll",handleScroll2)}},[context.viewport,isHorizontal,send,debounceScrollEnd]),jsxRuntimeExports.jsx(Presence,{present:forceMount||state!=="hidden",children:jsxRuntimeExports.jsx(ScrollAreaScrollbarVisible,{"data-state":state==="hidden"?"hidden":"visible",...scrollbarProps,ref:forwardedRef,onPointerEnter:composeEventHandlers(props.onPointerEnter,()=>send("POINTER_ENTER")),onPointerLeave:composeEventHandlers(props.onPointerLeave,()=>send("POINTER_LEAVE"))})})}),ScrollAreaScrollbarAuto=reactExports.forwardRef((props,forwardedRef)=>{const context=useScrollAreaContext(SCROLLBAR_NAME,props.__scopeScrollArea),{forceMount,...scrollbarProps}=props,[visible,setVisible]=reactExports.useState(!1),isHorizontal=props.orientation==="horizontal",handleResize=useDebounceCallback(()=>{if(context.viewport){const isOverflowX=context.viewport.offsetWidth{const{orientation="vertical",...scrollbarProps}=props,context=useScrollAreaContext(SCROLLBAR_NAME,props.__scopeScrollArea),thumbRef=reactExports.useRef(null),pointerOffsetRef=reactExports.useRef(0),[sizes,setSizes]=reactExports.useState({content:0,viewport:0,scrollbar:{size:0,paddingStart:0,paddingEnd:0}}),thumbRatio=getThumbRatio(sizes.viewport,sizes.content),commonProps={...scrollbarProps,sizes,onSizesChange:setSizes,hasThumb:thumbRatio>0&&thumbRatio<1,onThumbChange:__name(thumb=>thumbRef.current=thumb,"onThumbChange"),onThumbPointerUp:__name(()=>pointerOffsetRef.current=0,"onThumbPointerUp"),onThumbPointerDown:__name(pointerPos=>pointerOffsetRef.current=pointerPos,"onThumbPointerDown")};function getScrollPosition(pointerPos,dir){return getScrollPositionFromPointer(pointerPos,pointerOffsetRef.current,sizes,dir)}return __name(getScrollPosition,"getScrollPosition"),orientation==="horizontal"?jsxRuntimeExports.jsx(ScrollAreaScrollbarX,{...commonProps,ref:forwardedRef,onThumbPositionChange:__name(()=>{if(context.viewport&&thumbRef.current){const scrollPos=context.viewport.scrollLeft,offset2=getThumbOffsetFromScroll(scrollPos,sizes,context.dir);thumbRef.current.style.transform=`translate3d(${offset2}px, 0, 0)`}},"onThumbPositionChange"),onWheelScroll:__name(scrollPos=>{context.viewport&&(context.viewport.scrollLeft=scrollPos)},"onWheelScroll"),onDragScroll:__name(pointerPos=>{context.viewport&&(context.viewport.scrollLeft=getScrollPosition(pointerPos,context.dir))},"onDragScroll")}):orientation==="vertical"?jsxRuntimeExports.jsx(ScrollAreaScrollbarY,{...commonProps,ref:forwardedRef,onThumbPositionChange:__name(()=>{if(context.viewport&&thumbRef.current){const scrollPos=context.viewport.scrollTop,offset2=getThumbOffsetFromScroll(scrollPos,sizes);thumbRef.current.style.transform=`translate3d(0, ${offset2}px, 0)`}},"onThumbPositionChange"),onWheelScroll:__name(scrollPos=>{context.viewport&&(context.viewport.scrollTop=scrollPos)},"onWheelScroll"),onDragScroll:__name(pointerPos=>{context.viewport&&(context.viewport.scrollTop=getScrollPosition(pointerPos))},"onDragScroll")}):null}),ScrollAreaScrollbarX=reactExports.forwardRef((props,forwardedRef)=>{const{sizes,onSizesChange,...scrollbarProps}=props,context=useScrollAreaContext(SCROLLBAR_NAME,props.__scopeScrollArea),[computedStyle,setComputedStyle]=reactExports.useState(),ref=reactExports.useRef(null),composeRefs2=useComposedRefs(forwardedRef,ref,context.onScrollbarXChange);return reactExports.useEffect(()=>{ref.current&&setComputedStyle(getComputedStyle(ref.current))},[ref]),jsxRuntimeExports.jsx(ScrollAreaScrollbarImpl,{"data-orientation":"horizontal",...scrollbarProps,ref:composeRefs2,sizes,style:{bottom:0,left:context.dir==="rtl"?"var(--radix-scroll-area-corner-width)":0,right:context.dir==="ltr"?"var(--radix-scroll-area-corner-width)":0,"--radix-scroll-area-thumb-width":getThumbSize(sizes)+"px",...props.style},onThumbPointerDown:__name(pointerPos=>props.onThumbPointerDown(pointerPos.x),"onThumbPointerDown"),onDragScroll:__name(pointerPos=>props.onDragScroll(pointerPos.x),"onDragScroll"),onWheelScroll:__name((event,maxScrollPos)=>{if(context.viewport){const scrollPos=context.viewport.scrollLeft+event.deltaX;props.onWheelScroll(scrollPos),isScrollingWithinScrollbarBounds(scrollPos,maxScrollPos)&&event.preventDefault()}},"onWheelScroll"),onResize:__name(()=>{ref.current&&context.viewport&&computedStyle&&onSizesChange({content:context.viewport.scrollWidth,viewport:context.viewport.offsetWidth,scrollbar:{size:ref.current.clientWidth,paddingStart:toInt(computedStyle.paddingLeft),paddingEnd:toInt(computedStyle.paddingRight)}})},"onResize")})}),ScrollAreaScrollbarY=reactExports.forwardRef((props,forwardedRef)=>{const{sizes,onSizesChange,...scrollbarProps}=props,context=useScrollAreaContext(SCROLLBAR_NAME,props.__scopeScrollArea),[computedStyle,setComputedStyle]=reactExports.useState(),ref=reactExports.useRef(null),composeRefs2=useComposedRefs(forwardedRef,ref,context.onScrollbarYChange);return reactExports.useEffect(()=>{ref.current&&setComputedStyle(getComputedStyle(ref.current))},[ref]),jsxRuntimeExports.jsx(ScrollAreaScrollbarImpl,{"data-orientation":"vertical",...scrollbarProps,ref:composeRefs2,sizes,style:{top:0,right:context.dir==="ltr"?0:void 0,left:context.dir==="rtl"?0:void 0,bottom:"var(--radix-scroll-area-corner-height)","--radix-scroll-area-thumb-height":getThumbSize(sizes)+"px",...props.style},onThumbPointerDown:__name(pointerPos=>props.onThumbPointerDown(pointerPos.y),"onThumbPointerDown"),onDragScroll:__name(pointerPos=>props.onDragScroll(pointerPos.y),"onDragScroll"),onWheelScroll:__name((event,maxScrollPos)=>{if(context.viewport){const scrollPos=context.viewport.scrollTop+event.deltaY;props.onWheelScroll(scrollPos),isScrollingWithinScrollbarBounds(scrollPos,maxScrollPos)&&event.preventDefault()}},"onWheelScroll"),onResize:__name(()=>{ref.current&&context.viewport&&computedStyle&&onSizesChange({content:context.viewport.scrollHeight,viewport:context.viewport.offsetHeight,scrollbar:{size:ref.current.clientHeight,paddingStart:toInt(computedStyle.paddingTop),paddingEnd:toInt(computedStyle.paddingBottom)}})},"onResize")})}),[ScrollbarProvider,useScrollbarContext]=createScrollAreaContext(SCROLLBAR_NAME),ScrollAreaScrollbarImpl=reactExports.forwardRef((props,forwardedRef)=>{const{__scopeScrollArea,sizes,hasThumb,onThumbChange,onThumbPointerUp,onThumbPointerDown,onThumbPositionChange,onDragScroll,onWheelScroll,onResize,...scrollbarProps}=props,context=useScrollAreaContext(SCROLLBAR_NAME,__scopeScrollArea),[scrollbar,setScrollbar]=reactExports.useState(null),composeRefs2=useComposedRefs(forwardedRef,node2=>setScrollbar(node2)),rectRef=reactExports.useRef(null),prevWebkitUserSelectRef=reactExports.useRef(""),viewport=context.viewport,maxScrollPos=sizes.content-sizes.viewport,handleWheelScroll=useCallbackRef$1(onWheelScroll),handleThumbPositionChange=useCallbackRef$1(onThumbPositionChange),handleResize=useDebounceCallback(onResize,10);function handleDragScroll(event){if(rectRef.current){const x2=event.clientX-rectRef.current.left,y2=event.clientY-rectRef.current.top;onDragScroll({x:x2,y:y2})}}return __name(handleDragScroll,"handleDragScroll"),reactExports.useEffect(()=>{const handleWheel=__name(event=>{const element2=event.target;scrollbar?.contains(element2)&&handleWheelScroll(event,maxScrollPos)},"handleWheel");return document.addEventListener("wheel",handleWheel,{passive:!1}),()=>document.removeEventListener("wheel",handleWheel,{passive:!1})},[viewport,scrollbar,maxScrollPos,handleWheelScroll]),reactExports.useEffect(handleThumbPositionChange,[sizes,handleThumbPositionChange]),useResizeObserver(scrollbar,handleResize),useResizeObserver(context.content,handleResize),jsxRuntimeExports.jsx(ScrollbarProvider,{scope:__scopeScrollArea,scrollbar,hasThumb,onThumbChange:useCallbackRef$1(onThumbChange),onThumbPointerUp:useCallbackRef$1(onThumbPointerUp),onThumbPositionChange:handleThumbPositionChange,onThumbPointerDown:useCallbackRef$1(onThumbPointerDown),children:jsxRuntimeExports.jsx(Primitive$2.div,{...scrollbarProps,ref:composeRefs2,style:{position:"absolute",...scrollbarProps.style},onPointerDown:composeEventHandlers(props.onPointerDown,event=>{event.button===0&&(event.target.setPointerCapture(event.pointerId),rectRef.current=scrollbar.getBoundingClientRect(),prevWebkitUserSelectRef.current=document.body.style.webkitUserSelect,document.body.style.webkitUserSelect="none",context.viewport&&(context.viewport.style.scrollBehavior="auto"),handleDragScroll(event))}),onPointerMove:composeEventHandlers(props.onPointerMove,handleDragScroll),onPointerUp:composeEventHandlers(props.onPointerUp,event=>{const element2=event.target;element2.hasPointerCapture(event.pointerId)&&element2.releasePointerCapture(event.pointerId),document.body.style.webkitUserSelect=prevWebkitUserSelectRef.current,context.viewport&&(context.viewport.style.scrollBehavior=""),rectRef.current=null})})})}),THUMB_NAME="ScrollAreaThumb",ScrollAreaThumb=reactExports.forwardRef((props,forwardedRef)=>{const{forceMount,...thumbProps}=props,scrollbarContext=useScrollbarContext(THUMB_NAME,props.__scopeScrollArea);return jsxRuntimeExports.jsx(Presence,{present:forceMount||scrollbarContext.hasThumb,children:jsxRuntimeExports.jsx(ScrollAreaThumbImpl,{ref:forwardedRef,...thumbProps})})}),ScrollAreaThumbImpl=reactExports.forwardRef((props,forwardedRef)=>{const{__scopeScrollArea,style:style2,...thumbProps}=props,scrollAreaContext=useScrollAreaContext(THUMB_NAME,__scopeScrollArea),scrollbarContext=useScrollbarContext(THUMB_NAME,__scopeScrollArea),{onThumbPositionChange}=scrollbarContext,composedRef=useComposedRefs(forwardedRef,node2=>scrollbarContext.onThumbChange(node2)),removeUnlinkedScrollListenerRef=reactExports.useRef(void 0),debounceScrollEnd=useDebounceCallback(()=>{removeUnlinkedScrollListenerRef.current&&(removeUnlinkedScrollListenerRef.current(),removeUnlinkedScrollListenerRef.current=void 0)},100);return reactExports.useEffect(()=>{const viewport=scrollAreaContext.viewport;if(viewport){const handleScroll2=__name(()=>{if(debounceScrollEnd(),!removeUnlinkedScrollListenerRef.current){const listener=addUnlinkedScrollListener(viewport,onThumbPositionChange);removeUnlinkedScrollListenerRef.current=listener,onThumbPositionChange()}},"handleScroll");return onThumbPositionChange(),viewport.addEventListener("scroll",handleScroll2),()=>viewport.removeEventListener("scroll",handleScroll2)}},[scrollAreaContext.viewport,debounceScrollEnd,onThumbPositionChange]),jsxRuntimeExports.jsx(Primitive$2.div,{"data-state":scrollbarContext.hasThumb?"visible":"hidden",...thumbProps,ref:composedRef,style:{width:"var(--radix-scroll-area-thumb-width)",height:"var(--radix-scroll-area-thumb-height)",...style2},onPointerDownCapture:composeEventHandlers(props.onPointerDownCapture,event=>{const thumbRect=event.target.getBoundingClientRect(),x2=event.clientX-thumbRect.left,y2=event.clientY-thumbRect.top;scrollbarContext.onThumbPointerDown({x:x2,y:y2})}),onPointerUp:composeEventHandlers(props.onPointerUp,scrollbarContext.onThumbPointerUp)})});ScrollAreaThumb.displayName=THUMB_NAME;var CORNER_NAME="ScrollAreaCorner",ScrollAreaCorner=reactExports.forwardRef((props,forwardedRef)=>{const context=useScrollAreaContext(CORNER_NAME,props.__scopeScrollArea),hasBothScrollbarsVisible=!!(context.scrollbarX&&context.scrollbarY);return context.type!=="scroll"&&hasBothScrollbarsVisible?jsxRuntimeExports.jsx(ScrollAreaCornerImpl,{...props,ref:forwardedRef}):null});ScrollAreaCorner.displayName=CORNER_NAME;var ScrollAreaCornerImpl=reactExports.forwardRef((props,forwardedRef)=>{const{__scopeScrollArea,...cornerProps}=props,context=useScrollAreaContext(CORNER_NAME,__scopeScrollArea),[width,setWidth]=reactExports.useState(0),[height,setHeight]=reactExports.useState(0),hasSize=!!(width&&height);return useResizeObserver(context.scrollbarX,()=>{const height2=context.scrollbarX?.offsetHeight||0;context.onCornerHeightChange(height2),setHeight(height2)}),useResizeObserver(context.scrollbarY,()=>{const width2=context.scrollbarY?.offsetWidth||0;context.onCornerWidthChange(width2),setWidth(width2)}),hasSize?jsxRuntimeExports.jsx(Primitive$2.div,{...cornerProps,ref:forwardedRef,style:{width,height,position:"absolute",right:context.dir==="ltr"?0:void 0,left:context.dir==="rtl"?0:void 0,bottom:0,...props.style}}):null});function toInt(value2){return value2?parseInt(value2,10):0}__name(toInt,"toInt");function getThumbRatio(viewportSize,contentSize){const ratio=viewportSize/contentSize;return isNaN(ratio)?0:ratio}__name(getThumbRatio,"getThumbRatio");function getThumbSize(sizes){const ratio=getThumbRatio(sizes.viewport,sizes.content),scrollbarPadding=sizes.scrollbar.paddingStart+sizes.scrollbar.paddingEnd,thumbSize=(sizes.scrollbar.size-scrollbarPadding)*ratio;return Math.max(thumbSize,18)}__name(getThumbSize,"getThumbSize");function getScrollPositionFromPointer(pointerPos,pointerOffset,sizes,dir="ltr"){const thumbSizePx=getThumbSize(sizes),thumbCenter=thumbSizePx/2,offset2=pointerOffset||thumbCenter,thumbOffsetFromEnd=thumbSizePx-offset2,minPointerPos=sizes.scrollbar.paddingStart+offset2,maxPointerPos=sizes.scrollbar.size-sizes.scrollbar.paddingEnd-thumbOffsetFromEnd,maxScrollPos=sizes.content-sizes.viewport,scrollRange=dir==="ltr"?[0,maxScrollPos]:[maxScrollPos*-1,0];return linearScale([minPointerPos,maxPointerPos],scrollRange)(pointerPos)}__name(getScrollPositionFromPointer,"getScrollPositionFromPointer");function getThumbOffsetFromScroll(scrollPos,sizes,dir="ltr"){const thumbSizePx=getThumbSize(sizes),scrollbarPadding=sizes.scrollbar.paddingStart+sizes.scrollbar.paddingEnd,scrollbar=sizes.scrollbar.size-scrollbarPadding,maxScrollPos=sizes.content-sizes.viewport,maxThumbPos=scrollbar-thumbSizePx,scrollClampRange=dir==="ltr"?[0,maxScrollPos]:[maxScrollPos*-1,0],scrollWithoutMomentum=clamp(scrollPos,scrollClampRange);return linearScale([0,maxScrollPos],[0,maxThumbPos])(scrollWithoutMomentum)}__name(getThumbOffsetFromScroll,"getThumbOffsetFromScroll");function linearScale(input,output){return value2=>{if(input[0]===input[1]||output[0]===output[1])return output[0];const ratio=(output[1]-output[0])/(input[1]-input[0]);return output[0]+ratio*(value2-input[0])}}__name(linearScale,"linearScale");function isScrollingWithinScrollbarBounds(scrollPos,maxScrollPos){return scrollPos>0&&scrollPos{})=>{let prevPosition={left:node2.scrollLeft,top:node2.scrollTop},rAF=0;return __name((function loop2(){const position2={left:node2.scrollLeft,top:node2.scrollTop},isHorizontalScroll=prevPosition.left!==position2.left,isVerticalScroll=prevPosition.top!==position2.top;(isHorizontalScroll||isVerticalScroll)&&handler(),prevPosition=position2,rAF=window.requestAnimationFrame(loop2)}),"loop")(),()=>window.cancelAnimationFrame(rAF)},"addUnlinkedScrollListener");function useDebounceCallback(callback,delay){const handleCallback=useCallbackRef$1(callback),debounceTimerRef=reactExports.useRef(0);return reactExports.useEffect(()=>()=>window.clearTimeout(debounceTimerRef.current),[]),reactExports.useCallback(()=>{window.clearTimeout(debounceTimerRef.current),debounceTimerRef.current=window.setTimeout(handleCallback,delay)},[handleCallback,delay])}__name(useDebounceCallback,"useDebounceCallback");function useResizeObserver(element2,onResize){const handleResize=useCallbackRef$1(onResize);useLayoutEffect2(()=>{let rAF=0;if(element2){const resizeObserver=new ResizeObserver(()=>{cancelAnimationFrame(rAF),rAF=window.requestAnimationFrame(handleResize)});return resizeObserver.observe(element2),()=>{window.cancelAnimationFrame(rAF),resizeObserver.unobserve(element2)}}},[element2,handleResize])}__name(useResizeObserver,"useResizeObserver");function Logo(){return jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment,{children:[jsxRuntimeExports.jsx(Icons.logo,{className:"h-6 w-6"}),jsxRuntimeExports.jsx("span",{className:"font-bold",children:ztAppConfig.name})]})}__name(Logo,"Logo");var COLLAPSIBLE_NAME="Collapsible",[createCollapsibleContext,createCollapsibleScope]=createContextScope$1(COLLAPSIBLE_NAME),[CollapsibleProvider,useCollapsibleContext]=createCollapsibleContext(COLLAPSIBLE_NAME),Collapsible=reactExports.forwardRef((props,forwardedRef)=>{const{__scopeCollapsible,open:openProp,defaultOpen,disabled,onOpenChange,...collapsibleProps}=props,[open,setOpen]=useControllableState({prop:openProp,defaultProp:defaultOpen??!1,onChange:onOpenChange,caller:COLLAPSIBLE_NAME});return jsxRuntimeExports.jsx(CollapsibleProvider,{scope:__scopeCollapsible,disabled,contentId:useId(),open,onOpenToggle:reactExports.useCallback(()=>setOpen(prevOpen=>!prevOpen),[setOpen]),children:jsxRuntimeExports.jsx(Primitive$2.div,{"data-state":getState$1(open),"data-disabled":disabled?"":void 0,...collapsibleProps,ref:forwardedRef})})});Collapsible.displayName=COLLAPSIBLE_NAME;var TRIGGER_NAME$3="CollapsibleTrigger",CollapsibleTrigger=reactExports.forwardRef((props,forwardedRef)=>{const{__scopeCollapsible,...triggerProps}=props,context=useCollapsibleContext(TRIGGER_NAME$3,__scopeCollapsible);return jsxRuntimeExports.jsx(Primitive$2.button,{type:"button","aria-controls":context.contentId,"aria-expanded":context.open||!1,"data-state":getState$1(context.open),"data-disabled":context.disabled?"":void 0,disabled:context.disabled,...triggerProps,ref:forwardedRef,onClick:composeEventHandlers(props.onClick,context.onOpenToggle)})});CollapsibleTrigger.displayName=TRIGGER_NAME$3;var CONTENT_NAME$3="CollapsibleContent",CollapsibleContent=reactExports.forwardRef((props,forwardedRef)=>{const{forceMount,...contentProps}=props,context=useCollapsibleContext(CONTENT_NAME$3,props.__scopeCollapsible);return jsxRuntimeExports.jsx(Presence,{present:forceMount||context.open,children:__name(({present})=>jsxRuntimeExports.jsx(CollapsibleContentImpl,{...contentProps,ref:forwardedRef,present}),"children")})});CollapsibleContent.displayName=CONTENT_NAME$3;var CollapsibleContentImpl=reactExports.forwardRef((props,forwardedRef)=>{const{__scopeCollapsible,present,children:children2,...contentProps}=props,context=useCollapsibleContext(CONTENT_NAME$3,__scopeCollapsible),[isPresent,setIsPresent]=reactExports.useState(present),ref=reactExports.useRef(null),composedRefs=useComposedRefs(forwardedRef,ref),heightRef=reactExports.useRef(0),height=heightRef.current,widthRef=reactExports.useRef(0),width=widthRef.current,isOpen=context.open||isPresent,isMountAnimationPreventedRef=reactExports.useRef(isOpen),originalStylesRef=reactExports.useRef(void 0);return reactExports.useEffect(()=>{const rAF=requestAnimationFrame(()=>isMountAnimationPreventedRef.current=!1);return()=>cancelAnimationFrame(rAF)},[]),useLayoutEffect2(()=>{const node2=ref.current;if(node2){originalStylesRef.current=originalStylesRef.current||{transitionDuration:node2.style.transitionDuration,animationName:node2.style.animationName},node2.style.transitionDuration="0s",node2.style.animationName="none";const rect=node2.getBoundingClientRect();heightRef.current=rect.height,widthRef.current=rect.width,isMountAnimationPreventedRef.current||(node2.style.transitionDuration=originalStylesRef.current.transitionDuration,node2.style.animationName=originalStylesRef.current.animationName),setIsPresent(present)}},[context.open,present]),jsxRuntimeExports.jsx(Primitive$2.div,{"data-state":getState$1(context.open),"data-disabled":context.disabled?"":void 0,id:context.contentId,hidden:!isOpen,...contentProps,ref:composedRefs,style:{"--radix-collapsible-content-height":height?`${height}px`:void 0,"--radix-collapsible-content-width":width?`${width}px`:void 0,...props.style},children:isOpen&&children2})});function getState$1(open){return open?"open":"closed"}__name(getState$1,"getState$1");var Root$3=Collapsible,Trigger$2=CollapsibleTrigger,Content$1=CollapsibleContent,ACCORDION_NAME="Accordion",ACCORDION_KEYS=["Home","End","ArrowDown","ArrowUp","ArrowLeft","ArrowRight"],[Collection,useCollection,createCollectionScope]=createCollection(ACCORDION_NAME),[createAccordionContext]=createContextScope$1(ACCORDION_NAME,[createCollectionScope,createCollapsibleScope]),useCollapsibleScope=createCollapsibleScope(),Accordion$1=React.forwardRef((props,forwardedRef)=>{const{type,...accordionProps}=props,singleProps=accordionProps,multipleProps=accordionProps;return jsxRuntimeExports.jsx(Collection.Provider,{scope:props.__scopeAccordion,children:type==="multiple"?jsxRuntimeExports.jsx(AccordionImplMultiple,{...multipleProps,ref:forwardedRef}):jsxRuntimeExports.jsx(AccordionImplSingle,{...singleProps,ref:forwardedRef})})});Accordion$1.displayName=ACCORDION_NAME;var[AccordionValueProvider,useAccordionValueContext]=createAccordionContext(ACCORDION_NAME),[AccordionCollapsibleProvider,useAccordionCollapsibleContext]=createAccordionContext(ACCORDION_NAME,{collapsible:!1}),AccordionImplSingle=React.forwardRef((props,forwardedRef)=>{const{value:valueProp,defaultValue,onValueChange=__name(()=>{},"onValueChange"),collapsible=!1,...accordionSingleProps}=props,[value2,setValue]=useControllableState({prop:valueProp,defaultProp:defaultValue??"",onChange:onValueChange,caller:ACCORDION_NAME});return jsxRuntimeExports.jsx(AccordionValueProvider,{scope:props.__scopeAccordion,value:React.useMemo(()=>value2?[value2]:[],[value2]),onItemOpen:setValue,onItemClose:React.useCallback(()=>collapsible&&setValue(""),[collapsible,setValue]),children:jsxRuntimeExports.jsx(AccordionCollapsibleProvider,{scope:props.__scopeAccordion,collapsible,children:jsxRuntimeExports.jsx(AccordionImpl,{...accordionSingleProps,ref:forwardedRef})})})}),AccordionImplMultiple=React.forwardRef((props,forwardedRef)=>{const{value:valueProp,defaultValue,onValueChange=__name(()=>{},"onValueChange"),...accordionMultipleProps}=props,[value2,setValue]=useControllableState({prop:valueProp,defaultProp:defaultValue??[],onChange:onValueChange,caller:ACCORDION_NAME}),handleItemOpen=React.useCallback(itemValue=>setValue((prevValue=[])=>[...prevValue,itemValue]),[setValue]),handleItemClose=React.useCallback(itemValue=>setValue((prevValue=[])=>prevValue.filter(value22=>value22!==itemValue)),[setValue]);return jsxRuntimeExports.jsx(AccordionValueProvider,{scope:props.__scopeAccordion,value:value2,onItemOpen:handleItemOpen,onItemClose:handleItemClose,children:jsxRuntimeExports.jsx(AccordionCollapsibleProvider,{scope:props.__scopeAccordion,collapsible:!0,children:jsxRuntimeExports.jsx(AccordionImpl,{...accordionMultipleProps,ref:forwardedRef})})})}),[AccordionImplProvider,useAccordionContext]=createAccordionContext(ACCORDION_NAME),AccordionImpl=React.forwardRef((props,forwardedRef)=>{const{__scopeAccordion,disabled,dir,orientation="vertical",...accordionProps}=props,accordionRef=React.useRef(null),composedRefs=useComposedRefs(accordionRef,forwardedRef),getItems=useCollection(__scopeAccordion),isDirectionLTR=useDirection(dir)==="ltr",handleKeyDown=composeEventHandlers(props.onKeyDown,event=>{if(!ACCORDION_KEYS.includes(event.key))return;const target=event.target,triggerCollection=getItems().filter(item=>!item.ref.current?.disabled),triggerIndex=triggerCollection.findIndex(item=>item.ref.current===target),triggerCount=triggerCollection.length;if(triggerIndex===-1)return;event.preventDefault();let nextIndex=triggerIndex;const homeIndex=0,endIndex=triggerCount-1,moveNext=__name(()=>{nextIndex=triggerIndex+1,nextIndex>endIndex&&(nextIndex=homeIndex)},"moveNext"),movePrev=__name(()=>{nextIndex=triggerIndex-1,nextIndex{const{__scopeAccordion,value:value2,...accordionItemProps}=props,accordionContext=useAccordionContext(ITEM_NAME,__scopeAccordion),valueContext=useAccordionValueContext(ITEM_NAME,__scopeAccordion),collapsibleScope=useCollapsibleScope(__scopeAccordion),triggerId=useId(),open=value2&&valueContext.value.includes(value2)||!1,disabled=accordionContext.disabled||props.disabled;return jsxRuntimeExports.jsx(AccordionItemProvider,{scope:__scopeAccordion,open,disabled,triggerId,children:jsxRuntimeExports.jsx(Root$3,{"data-orientation":accordionContext.orientation,"data-state":getState(open),...collapsibleScope,...accordionItemProps,ref:forwardedRef,disabled,open,onOpenChange:__name(open2=>{open2?valueContext.onItemOpen(value2):valueContext.onItemClose(value2)},"onOpenChange")})})});AccordionItem$1.displayName=ITEM_NAME;var HEADER_NAME="AccordionHeader",AccordionHeader=React.forwardRef((props,forwardedRef)=>{const{__scopeAccordion,...headerProps}=props,accordionContext=useAccordionContext(ACCORDION_NAME,__scopeAccordion),itemContext=useAccordionItemContext(HEADER_NAME,__scopeAccordion);return jsxRuntimeExports.jsx(Primitive$2.h3,{"data-orientation":accordionContext.orientation,"data-state":getState(itemContext.open),"data-disabled":itemContext.disabled?"":void 0,...headerProps,ref:forwardedRef})});AccordionHeader.displayName=HEADER_NAME;var TRIGGER_NAME$2="AccordionTrigger",AccordionTrigger$1=React.forwardRef((props,forwardedRef)=>{const{__scopeAccordion,...triggerProps}=props,accordionContext=useAccordionContext(ACCORDION_NAME,__scopeAccordion),itemContext=useAccordionItemContext(TRIGGER_NAME$2,__scopeAccordion),collapsibleContext=useAccordionCollapsibleContext(TRIGGER_NAME$2,__scopeAccordion),collapsibleScope=useCollapsibleScope(__scopeAccordion);return jsxRuntimeExports.jsx(Collection.ItemSlot,{scope:__scopeAccordion,children:jsxRuntimeExports.jsx(Trigger$2,{"aria-disabled":itemContext.open&&!collapsibleContext.collapsible||void 0,"data-orientation":accordionContext.orientation,id:itemContext.triggerId,...collapsibleScope,...triggerProps,ref:forwardedRef})})});AccordionTrigger$1.displayName=TRIGGER_NAME$2;var CONTENT_NAME$2="AccordionContent",AccordionContent$1=React.forwardRef((props,forwardedRef)=>{const{__scopeAccordion,...contentProps}=props,accordionContext=useAccordionContext(ACCORDION_NAME,__scopeAccordion),itemContext=useAccordionItemContext(CONTENT_NAME$2,__scopeAccordion),collapsibleScope=useCollapsibleScope(__scopeAccordion);return jsxRuntimeExports.jsx(Content$1,{role:"region","aria-labelledby":itemContext.triggerId,"data-orientation":accordionContext.orientation,...collapsibleScope,...contentProps,ref:forwardedRef,style:{"--radix-accordion-content-height":"var(--radix-collapsible-content-height)","--radix-accordion-content-width":"var(--radix-collapsible-content-width)",...props.style}})});AccordionContent$1.displayName=CONTENT_NAME$2;function getState(open){return open?"open":"closed"}__name(getState,"getState");var Root2$1=Accordion$1,Item=AccordionItem$1,Header$1=AccordionHeader,Trigger2=AccordionTrigger$1,Content2$1=AccordionContent$1;const Accordion=Root2$1,AccordionItem=reactExports.forwardRef(({className,...props},ref)=>jsxRuntimeExports.jsx(Item,{ref,className:cn$2("border-b",className),...props}));AccordionItem.displayName="AccordionItem";const AccordionTrigger=reactExports.forwardRef(({className,children:children2,...props},ref)=>jsxRuntimeExports.jsx(Header$1,{className:"flex",children:jsxRuntimeExports.jsxs(Trigger2,{ref,className:cn$2("flex flex-1 items-center justify-between py-4 font-medium transition-all hover:underline [&[data-state=open]>svg]:rotate-180",className),...props,children:[children2,jsxRuntimeExports.jsx(ChevronDown,{className:"h-4 w-4 shrink-0 transition-transform duration-200"})]})}));AccordionTrigger.displayName=Trigger2.displayName;const AccordionContent=reactExports.forwardRef(({className,children:children2,...props},ref)=>jsxRuntimeExports.jsx(Content2$1,{ref,className:"overflow-hidden text-sm transition-all data-[state=closed]:animate-accordion-up data-[state=open]:animate-accordion-down",...props,children:jsxRuntimeExports.jsx("div",{className:cn$2("pb-4 pt-0",className),children:children2})}));AccordionContent.displayName=Content2$1.displayName;function Header(){const[open,setOpen]=reactExports.useState(!1),location2=useLocation();return console.log(reportData),jsxRuntimeExports.jsx("header",{className:"supports-backdrop-blur:bg-background/60 sticky top-0 z-50 w-full border-b bg-background/90 backdrop-blur",children:jsxRuntimeExports.jsxs("div",{className:"container px-4 md:px-8 flex h-14 items-center",children:[jsxRuntimeExports.jsxs("div",{className:"mr-4 hidden md:flex",children:[jsxRuntimeExports.jsx(NavLink,{to:"/",className:"mr-6 flex items-center space-x-2",children:jsxRuntimeExports.jsx(Logo,{})}),jsxRuntimeExports.jsx("nav",{className:"flex items-center space-x-6 text-sm font-medium",children:mainMenu.map((menu,index2)=>menu.items!==void 0?jsxRuntimeExports.jsxs(DropdownMenu,{children:[jsxRuntimeExports.jsxs(DropdownMenuTrigger,{className:cn$2("flex items-center py-1 focus:outline-none text-sm font-medium transition-colors hover:text-primary",menu.items.filter(subitem=>subitem.to!==void 0).map(subitem=>subitem.to).includes(location2.pathname)?"text-foreground":"text-foreground/60"),children:[menu.title,jsxRuntimeExports.jsx(ChevronDownIcon,{className:"ml-1 -mr-1 h-3 w-3 text-muted-foreground"})]}),jsxRuntimeExports.jsx(DropdownMenuContent,{className:"w-48",align:"start",forceMount:!0,children:menu.items.map((subitem,subindex)=>subitem.to!==void 0?jsxRuntimeExports.jsx(NavLink,{to:subitem.to,children:jsxRuntimeExports.jsx(DropdownMenuItem,{className:cn$2("hover:cursor-pointer",{"bg-muted":subitem.to===location2.pathname}),children:subitem.title})},subindex):subitem.label?jsxRuntimeExports.jsx(DropdownMenuLabel,{children:subitem.title},subindex):jsxRuntimeExports.jsx(DropdownMenuSeparator,{},subindex))})]},index2):jsxRuntimeExports.jsx(NavLink,{to:menu.to??"",className:__name(({isActive})=>cn$2("text-sm font-medium transition-colors hover:text-primary",isActive?"text-foreground":"text-foreground/60"),"className"),children:menu.title},index2))})]}),jsxRuntimeExports.jsxs(Sheet,{open,onOpenChange:setOpen,children:[jsxRuntimeExports.jsx(SheetTrigger,{asChild:!0,children:jsxRuntimeExports.jsxs(Button,{variant:"ghost",className:"mr-4 px-0 text-base hover:bg-transparent focus-visible:bg-transparent focus-visible:ring-0 focus-visible:ring-offset-0 md:hidden",children:[jsxRuntimeExports.jsx(ViewVerticalIcon,{className:"h-5 w-5"}),jsxRuntimeExports.jsx("span",{className:"sr-only",children:"Toggle Menu"})]})}),jsxRuntimeExports.jsxs(SheetContent,{side:"left",className:"pr-0 sm:max-w-xs",children:[jsxRuntimeExports.jsx(NavLink,{to:"/",onClick:__name(()=>setOpen(!1),"onClick"),className:"flex items-center space-x-2",children:jsxRuntimeExports.jsx(Logo,{})}),jsxRuntimeExports.jsx(ScrollArea,{className:"my-4 h-[calc(100vh-8rem)] pb-8 pl-8",children:jsxRuntimeExports.jsx(Accordion,{type:"single",collapsible:!0,className:"w-full",defaultValue:"item-"+mainMenu.findIndex(item=>item.items!==void 0?item.items.filter(subitem=>subitem.to!==void 0).map(subitem=>subitem.to).includes(location2.pathname):!1),children:jsxRuntimeExports.jsx("div",{className:"flex flex-col space-y-3",children:mainMenu.map((menu,index2)=>menu.items!==void 0?jsxRuntimeExports.jsxs(AccordionItem,{value:`item-${index2}`,className:"border-b-0 pr-6",children:[jsxRuntimeExports.jsx(AccordionTrigger,{className:cn$2("py-1 hover:no-underline hover:text-primary [&[data-state=open]]:text-primary",menu.items.filter(subitem=>subitem.to!==void 0).map(subitem=>subitem.to).includes(location2.pathname)?"text-foreground":"text-foreground/60"),children:jsxRuntimeExports.jsx("div",{className:"flex",children:menu.title})}),jsxRuntimeExports.jsx(AccordionContent,{className:"pb-1 pl-4",children:jsxRuntimeExports.jsx("div",{className:"mt-1",children:menu.items.map((submenu,subindex)=>submenu.to!==void 0?jsxRuntimeExports.jsx(NavLink,{to:submenu.to,onClick:__name(()=>setOpen(!1),"onClick"),className:__name(({isActive})=>cn$2("block justify-start py-1 h-auto font-normal hover:text-primary",isActive?"text-foreground":"text-foreground/60"),"className"),children:submenu.title},subindex):submenu.label!==""?null:jsxRuntimeExports.jsx("div",{className:"px-3"}))})})]},index2):jsxRuntimeExports.jsx(NavLink,{to:menu.to??"",onClick:__name(()=>setOpen(!1),"onClick"),className:__name(({isActive})=>cn$2("py-1 text-sm font-medium transition-colors hover:text-primary",isActive?"text-foreground":"text-foreground/60"),"className"),children:menu.title},index2))})})})]})]}),jsxRuntimeExports.jsxs("a",{href:"/",className:"mr-6 flex items-center space-x-2 md:hidden",children:[jsxRuntimeExports.jsx(Icons.logo,{className:"h-6 w-6"}),jsxRuntimeExports.jsx("span",{className:"font-bold inline-block",children:ztAppConfig.name})]}),jsxRuntimeExports.jsxs("div",{className:"flex flex-1 items-center justify-between space-x-2 md:justify-end",children:[jsxRuntimeExports.jsx("div",{className:"w-full flex-1 md:w-auto md:flex-none"}),jsxRuntimeExports.jsxs("nav",{className:"flex items-center space-x-2",children:[jsxRuntimeExports.jsx(ModeToggle,{}),jsxRuntimeExports.jsx("a",{href:ztAppConfig.github.url,title:ztAppConfig.github.title,target:"_blank",rel:"noreferrer",children:jsxRuntimeExports.jsxs("div",{className:cn$2(buttonVariants({variant:"ghost"}),"w-9 px-0"),children:[jsxRuntimeExports.jsx(Icons.gitHub,{className:"h-4 w-4"}),jsxRuntimeExports.jsx("span",{className:"sr-only",children:"GitHub"})]})})]}),jsxRuntimeExports.jsx("nav",{className:"flex items-center space-x-2",children:jsxRuntimeExports.jsxs(DropdownMenu,{children:[jsxRuntimeExports.jsx(DropdownMenuTrigger,{asChild:!0,children:jsxRuntimeExports.jsx(Button,{variant:"ghost",className:"relative h-8",children:reportData.TenantName})}),jsxRuntimeExports.jsxs(DropdownMenuContent,{className:"w-100",align:"end",forceMount:!0,children:[jsxRuntimeExports.jsx(DropdownMenuLabel,{className:"font-normal",children:jsxRuntimeExports.jsxs("div",{className:"flex flex-col space-y-1",children:[jsxRuntimeExports.jsx("p",{className:"text-sm font-medium leading-none",children:"Tenant"}),jsxRuntimeExports.jsx("p",{className:"text-xs leading-none text-muted-foreground",children:reportData.Domain})]})}),jsxRuntimeExports.jsx(DropdownMenuLabel,{className:"font-normal",children:jsxRuntimeExports.jsxs("div",{className:"flex flex-col space-y-1",children:[jsxRuntimeExports.jsx("p",{className:"text-sm font-medium leading-none",children:"Tenant ID"}),jsxRuntimeExports.jsx("p",{className:"text-xs leading-none text-muted-foreground",children:reportData.TenantId})]})}),jsxRuntimeExports.jsx(DropdownMenuSeparator,{}),jsxRuntimeExports.jsx(DropdownMenuLabel,{className:"font-normal",children:jsxRuntimeExports.jsxs("div",{className:"flex flex-col space-y-1",children:[jsxRuntimeExports.jsx("p",{className:"text-sm font-medium leading-none",children:"Assessment generated by"}),jsxRuntimeExports.jsx("p",{className:"text-xs leading-none text-muted-foreground",children:reportData.Account})]})}),jsxRuntimeExports.jsx(DropdownMenuSeparator,{}),jsxRuntimeExports.jsx(DropdownMenuLabel,{className:"font-normal",children:jsxRuntimeExports.jsxs("div",{className:"flex flex-col space-y-1",children:[jsxRuntimeExports.jsx("p",{className:"text-sm font-medium leading-none",children:"Assessment run on"}),jsxRuntimeExports.jsx("p",{className:"text-xs leading-none text-muted-foreground",children:new Date(reportData.ExecutedAt).toLocaleDateString("en",{day:"numeric",month:"long",year:"numeric",hour12:!0,hour:"numeric",minute:"numeric"})})]})}),jsxRuntimeExports.jsx(DropdownMenuSeparator,{}),jsxRuntimeExports.jsx(DropdownMenuLabel,{className:"font-normal",children:jsxRuntimeExports.jsxs("div",{className:"flex flex-col space-y-1",children:[jsxRuntimeExports.jsx("p",{className:"text-sm font-medium leading-none",children:"Version"}),jsxRuntimeExports.jsx("p",{className:"text-xs leading-none text-muted-foreground",children:reportData.CurrentVersion})]})})]})]})})]})]})})}__name(Header,"Header");function Footer(){const assessmentDate=__name(dateString=>{try{return new Date(dateString).toLocaleDateString("en-US",{year:"numeric",month:"long",day:"numeric"})}catch{return"Invalid Date"}},"formatDate")(reportData.ExecutedAt);return jsxRuntimeExports.jsx("footer",{className:"border-t bg-background/95 backdrop-blur supports-[backdrop-filter]:bg-background/60",children:jsxRuntimeExports.jsxs("div",{className:"container mx-auto px-4 py-8",children:[jsxRuntimeExports.jsxs("div",{className:"grid grid-cols-1 md:grid-cols-3 gap-8 items-start",children:[jsxRuntimeExports.jsxs("div",{className:"space-y-4",children:[jsxRuntimeExports.jsxs("div",{className:"flex items-center space-x-2",children:[jsxRuntimeExports.jsx(Icons.logo,{className:"h-6 w-6"}),jsxRuntimeExports.jsx("span",{className:"font-semibold text-foreground",children:"Zero Trust Assessment"})]}),jsxRuntimeExports.jsx("p",{className:"text-sm text-muted-foreground leading-relaxed",children:"An automated assessment tool that evaluates your Microsoft tenant's zero trust security posture."})]}),jsxRuntimeExports.jsxs("div",{className:"space-y-4",children:[jsxRuntimeExports.jsx("h4",{className:"font-semibold text-foreground",children:"Resources"}),jsxRuntimeExports.jsxs("div",{className:"space-y-2",children:[jsxRuntimeExports.jsx("a",{href:"https://aka.ms/zerotrust/assessment",target:"_blank",rel:"noreferrer noopener",className:"block text-sm text-muted-foreground hover:text-foreground transition-colors duration-200 hover:underline underline-offset-4",children:"Zero Trust Assessment"}),jsxRuntimeExports.jsx("a",{href:"https://aka.ms/zerotrust/workshop",target:"_blank",rel:"noreferrer noopener",className:"block text-sm text-muted-foreground hover:text-foreground transition-colors duration-200 hover:underline underline-offset-4",children:"Zero Trust Workshop"})]})]}),jsxRuntimeExports.jsxs("div",{className:"space-y-4",children:[jsxRuntimeExports.jsx("h4",{className:"font-semibold text-foreground",children:"Support"}),jsxRuntimeExports.jsxs("div",{className:"space-y-2",children:[jsxRuntimeExports.jsx("a",{href:"https://aka.ms/zerotrust/feedback",target:"_blank",rel:"noreferrer noopener",className:"block text-sm text-muted-foreground hover:text-foreground transition-colors duration-200 hover:underline underline-offset-4",children:"Share Feedback"}),jsxRuntimeExports.jsx("a",{href:"https://aka.ms/zerotrust/issues",target:"_blank",rel:"noreferrer noopener",className:"block text-sm text-muted-foreground hover:text-foreground transition-colors duration-200 hover:underline underline-offset-4",children:"Report Issues"}),jsxRuntimeExports.jsxs("a",{href:"https://github.com/microsoft/zerotrustassessment",target:"_blank",rel:"noreferrer noopener",className:"flex items-center space-x-2 text-sm text-muted-foreground hover:text-foreground transition-colors duration-200 hover:underline underline-offset-4",children:[jsxRuntimeExports.jsx(Icons.gitHub,{className:"h-4 w-4"}),jsxRuntimeExports.jsx("span",{children:"GitHub"})]})]})]})]}),jsxRuntimeExports.jsxs("div",{className:"border-t mt-8 pt-6 flex flex-col md:flex-row justify-between items-center space-y-4 md:space-y-0",children:[jsxRuntimeExports.jsxs("div",{className:"text-center md:text-left",children:[jsxRuntimeExports.jsxs("p",{className:"text-xs text-muted-foreground",children:["© ",new Date().getFullYear()," Microsoft Corporation. All rights reserved."]}),jsxRuntimeExports.jsx("p",{className:"text-xs text-muted-foreground mt-1",children:"This is a community project and not an official Microsoft product."})]}),jsxRuntimeExports.jsxs("div",{className:"flex items-center space-x-4 text-xs text-muted-foreground",children:[jsxRuntimeExports.jsx("a",{href:"https://privacy.microsoft.com/privacystatement",target:"_blank",rel:"noreferrer noopener",className:"hover:text-foreground transition-colors duration-200",children:"Privacy"}),jsxRuntimeExports.jsx("span",{children:"•"}),jsxRuntimeExports.jsx("a",{href:"https://www.microsoft.com/legal/terms-of-use",target:"_blank",rel:"noreferrer noopener",className:"hover:text-foreground transition-colors duration-200",children:"Terms"}),jsxRuntimeExports.jsx("span",{children:"•"}),jsxRuntimeExports.jsx("span",{children:assessmentDate})]}),jsxRuntimeExports.jsx("div",{className:"hidden"})]})]})})}__name(Footer,"Footer");function Applayout(){return jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment,{children:[jsxRuntimeExports.jsx(Header,{}),jsxRuntimeExports.jsx("div",{className:"flex-grow flex flex-col",children:jsxRuntimeExports.jsx("div",{className:"container max-w-6xl px-4 md:px-8 flex-grow flex flex-col",children:jsxRuntimeExports.jsx(Outlet,{})})}),jsxRuntimeExports.jsx("div",{className:"container max-w-6xl px-4 md:px-8",children:jsxRuntimeExports.jsx(Footer,{})})]})}__name(Applayout,"Applayout");function NoMatch(){return jsxRuntimeExports.jsx("div",{className:"bg-background text-foreground flex-grow flex items-center justify-center",children:jsxRuntimeExports.jsxs("div",{className:"space-y-4",children:[jsxRuntimeExports.jsx("h2",{className:"text-8xl mb-4",children:"404"}),jsxRuntimeExports.jsx("h1",{className:"text-3xl font-semibold",children:"Oops! Page not found"}),jsxRuntimeExports.jsx("p",{className:"text-sm text-muted-foreground",children:"We are sorry, but the page you requested was not found"}),jsxRuntimeExports.jsx(NavLink,{to:"/",className:buttonVariants(),children:"Back to Home"})]})})}__name(NoMatch,"NoMatch");var isArray_1,hasRequiredIsArray;function requireIsArray(){if(hasRequiredIsArray)return isArray_1;hasRequiredIsArray=1;var isArray2=Array.isArray;return isArray_1=isArray2,isArray_1}__name(requireIsArray,"requireIsArray");var _freeGlobal,hasRequired_freeGlobal;function require_freeGlobal(){if(hasRequired_freeGlobal)return _freeGlobal;hasRequired_freeGlobal=1;var define_global_default2={basename:""},freeGlobal=typeof define_global_default2=="object"&&define_global_default2&&define_global_default2.Object===Object&&define_global_default2;return _freeGlobal=freeGlobal,_freeGlobal}__name(require_freeGlobal,"require_freeGlobal");var _root,hasRequired_root;function require_root(){if(hasRequired_root)return _root;hasRequired_root=1;var freeGlobal=require_freeGlobal(),freeSelf=typeof self=="object"&&self&&self.Object===Object&&self,root2=freeGlobal||freeSelf||Function("return this")();return _root=root2,_root}__name(require_root,"require_root");var _Symbol,hasRequired_Symbol;function require_Symbol(){if(hasRequired_Symbol)return _Symbol;hasRequired_Symbol=1;var root2=require_root(),Symbol2=root2.Symbol;return _Symbol=Symbol2,_Symbol}__name(require_Symbol,"require_Symbol");var _getRawTag,hasRequired_getRawTag;function require_getRawTag(){if(hasRequired_getRawTag)return _getRawTag;hasRequired_getRawTag=1;var Symbol2=require_Symbol(),objectProto=Object.prototype,hasOwnProperty2=objectProto.hasOwnProperty,nativeObjectToString=objectProto.toString,symToStringTag=Symbol2?Symbol2.toStringTag:void 0;function getRawTag(value2){var isOwn=hasOwnProperty2.call(value2,symToStringTag),tag=value2[symToStringTag];try{value2[symToStringTag]=void 0;var unmasked=!0}catch{}var result=nativeObjectToString.call(value2);return unmasked&&(isOwn?value2[symToStringTag]=tag:delete value2[symToStringTag]),result}return __name(getRawTag,"getRawTag"),_getRawTag=getRawTag,_getRawTag}__name(require_getRawTag,"require_getRawTag");var _objectToString,hasRequired_objectToString;function require_objectToString(){if(hasRequired_objectToString)return _objectToString;hasRequired_objectToString=1;var objectProto=Object.prototype,nativeObjectToString=objectProto.toString;function objectToString(value2){return nativeObjectToString.call(value2)}return __name(objectToString,"objectToString"),_objectToString=objectToString,_objectToString}__name(require_objectToString,"require_objectToString");var _baseGetTag,hasRequired_baseGetTag;function require_baseGetTag(){if(hasRequired_baseGetTag)return _baseGetTag;hasRequired_baseGetTag=1;var Symbol2=require_Symbol(),getRawTag=require_getRawTag(),objectToString=require_objectToString(),nullTag="[object Null]",undefinedTag="[object Undefined]",symToStringTag=Symbol2?Symbol2.toStringTag:void 0;function baseGetTag(value2){return value2==null?value2===void 0?undefinedTag:nullTag:symToStringTag&&symToStringTag in Object(value2)?getRawTag(value2):objectToString(value2)}return __name(baseGetTag,"baseGetTag"),_baseGetTag=baseGetTag,_baseGetTag}__name(require_baseGetTag,"require_baseGetTag");var isObjectLike_1,hasRequiredIsObjectLike;function requireIsObjectLike(){if(hasRequiredIsObjectLike)return isObjectLike_1;hasRequiredIsObjectLike=1;function isObjectLike(value2){return value2!=null&&typeof value2=="object"}return __name(isObjectLike,"isObjectLike"),isObjectLike_1=isObjectLike,isObjectLike_1}__name(requireIsObjectLike,"requireIsObjectLike");var isSymbol_1,hasRequiredIsSymbol;function requireIsSymbol(){if(hasRequiredIsSymbol)return isSymbol_1;hasRequiredIsSymbol=1;var baseGetTag=require_baseGetTag(),isObjectLike=requireIsObjectLike(),symbolTag="[object Symbol]";function isSymbol(value2){return typeof value2=="symbol"||isObjectLike(value2)&&baseGetTag(value2)==symbolTag}return __name(isSymbol,"isSymbol"),isSymbol_1=isSymbol,isSymbol_1}__name(requireIsSymbol,"requireIsSymbol");var _isKey,hasRequired_isKey;function require_isKey(){if(hasRequired_isKey)return _isKey;hasRequired_isKey=1;var isArray2=requireIsArray(),isSymbol=requireIsSymbol(),reIsDeepProp=/\.|\[(?:[^[\]]*|(["'])(?:(?!\1)[^\\]|\\.)*?\1)\]/,reIsPlainProp=/^\w*$/;function isKey(value2,object2){if(isArray2(value2))return!1;var type=typeof value2;return type=="number"||type=="symbol"||type=="boolean"||value2==null||isSymbol(value2)?!0:reIsPlainProp.test(value2)||!reIsDeepProp.test(value2)||object2!=null&&value2 in Object(object2)}return __name(isKey,"isKey"),_isKey=isKey,_isKey}__name(require_isKey,"require_isKey");var isObject_1,hasRequiredIsObject;function requireIsObject(){if(hasRequiredIsObject)return isObject_1;hasRequiredIsObject=1;function isObject2(value2){var type=typeof value2;return value2!=null&&(type=="object"||type=="function")}return __name(isObject2,"isObject"),isObject_1=isObject2,isObject_1}__name(requireIsObject,"requireIsObject");var isFunction_1,hasRequiredIsFunction;function requireIsFunction(){if(hasRequiredIsFunction)return isFunction_1;hasRequiredIsFunction=1;var baseGetTag=require_baseGetTag(),isObject2=requireIsObject(),asyncTag="[object AsyncFunction]",funcTag="[object Function]",genTag="[object GeneratorFunction]",proxyTag="[object Proxy]";function isFunction2(value2){if(!isObject2(value2))return!1;var tag=baseGetTag(value2);return tag==funcTag||tag==genTag||tag==asyncTag||tag==proxyTag}return __name(isFunction2,"isFunction"),isFunction_1=isFunction2,isFunction_1}__name(requireIsFunction,"requireIsFunction");var _coreJsData,hasRequired_coreJsData;function require_coreJsData(){if(hasRequired_coreJsData)return _coreJsData;hasRequired_coreJsData=1;var root2=require_root(),coreJsData=root2["__core-js_shared__"];return _coreJsData=coreJsData,_coreJsData}__name(require_coreJsData,"require_coreJsData");var _isMasked,hasRequired_isMasked;function require_isMasked(){if(hasRequired_isMasked)return _isMasked;hasRequired_isMasked=1;var coreJsData=require_coreJsData(),maskSrcKey=(function(){var uid=/[^.]+$/.exec(coreJsData&&coreJsData.keys&&coreJsData.keys.IE_PROTO||"");return uid?"Symbol(src)_1."+uid:""})();function isMasked(func){return!!maskSrcKey&&maskSrcKey in func}return __name(isMasked,"isMasked"),_isMasked=isMasked,_isMasked}__name(require_isMasked,"require_isMasked");var _toSource,hasRequired_toSource;function require_toSource(){if(hasRequired_toSource)return _toSource;hasRequired_toSource=1;var funcProto=Function.prototype,funcToString=funcProto.toString;function toSource(func){if(func!=null){try{return funcToString.call(func)}catch{}try{return func+""}catch{}}return""}return __name(toSource,"toSource"),_toSource=toSource,_toSource}__name(require_toSource,"require_toSource");var _baseIsNative,hasRequired_baseIsNative;function require_baseIsNative(){if(hasRequired_baseIsNative)return _baseIsNative;hasRequired_baseIsNative=1;var isFunction2=requireIsFunction(),isMasked=require_isMasked(),isObject2=requireIsObject(),toSource=require_toSource(),reRegExpChar=/[\\^$.*+?()[\]{}|]/g,reIsHostCtor=/^\[object .+?Constructor\]$/,funcProto=Function.prototype,objectProto=Object.prototype,funcToString=funcProto.toString,hasOwnProperty2=objectProto.hasOwnProperty,reIsNative=RegExp("^"+funcToString.call(hasOwnProperty2).replace(reRegExpChar,"\\$&").replace(/hasOwnProperty|(function).*?(?=\\\()| for .+?(?=\\\])/g,"$1.*?")+"$");function baseIsNative(value2){if(!isObject2(value2)||isMasked(value2))return!1;var pattern=isFunction2(value2)?reIsNative:reIsHostCtor;return pattern.test(toSource(value2))}return __name(baseIsNative,"baseIsNative"),_baseIsNative=baseIsNative,_baseIsNative}__name(require_baseIsNative,"require_baseIsNative");var _getValue,hasRequired_getValue;function require_getValue(){if(hasRequired_getValue)return _getValue;hasRequired_getValue=1;function getValue(object2,key){return object2?.[key]}return __name(getValue,"getValue"),_getValue=getValue,_getValue}__name(require_getValue,"require_getValue");var _getNative,hasRequired_getNative;function require_getNative(){if(hasRequired_getNative)return _getNative;hasRequired_getNative=1;var baseIsNative=require_baseIsNative(),getValue=require_getValue();function getNative(object2,key){var value2=getValue(object2,key);return baseIsNative(value2)?value2:void 0}return __name(getNative,"getNative"),_getNative=getNative,_getNative}__name(require_getNative,"require_getNative");var _nativeCreate,hasRequired_nativeCreate;function require_nativeCreate(){if(hasRequired_nativeCreate)return _nativeCreate;hasRequired_nativeCreate=1;var getNative=require_getNative(),nativeCreate=getNative(Object,"create");return _nativeCreate=nativeCreate,_nativeCreate}__name(require_nativeCreate,"require_nativeCreate");var _hashClear,hasRequired_hashClear;function require_hashClear(){if(hasRequired_hashClear)return _hashClear;hasRequired_hashClear=1;var nativeCreate=require_nativeCreate();function hashClear(){this.__data__=nativeCreate?nativeCreate(null):{},this.size=0}return __name(hashClear,"hashClear"),_hashClear=hashClear,_hashClear}__name(require_hashClear,"require_hashClear");var _hashDelete,hasRequired_hashDelete;function require_hashDelete(){if(hasRequired_hashDelete)return _hashDelete;hasRequired_hashDelete=1;function hashDelete(key){var result=this.has(key)&&delete this.__data__[key];return this.size-=result?1:0,result}return __name(hashDelete,"hashDelete"),_hashDelete=hashDelete,_hashDelete}__name(require_hashDelete,"require_hashDelete");var _hashGet,hasRequired_hashGet;function require_hashGet(){if(hasRequired_hashGet)return _hashGet;hasRequired_hashGet=1;var nativeCreate=require_nativeCreate(),HASH_UNDEFINED="__lodash_hash_undefined__",objectProto=Object.prototype,hasOwnProperty2=objectProto.hasOwnProperty;function hashGet(key){var data=this.__data__;if(nativeCreate){var result=data[key];return result===HASH_UNDEFINED?void 0:result}return hasOwnProperty2.call(data,key)?data[key]:void 0}return __name(hashGet,"hashGet"),_hashGet=hashGet,_hashGet}__name(require_hashGet,"require_hashGet");var _hashHas,hasRequired_hashHas;function require_hashHas(){if(hasRequired_hashHas)return _hashHas;hasRequired_hashHas=1;var nativeCreate=require_nativeCreate(),objectProto=Object.prototype,hasOwnProperty2=objectProto.hasOwnProperty;function hashHas(key){var data=this.__data__;return nativeCreate?data[key]!==void 0:hasOwnProperty2.call(data,key)}return __name(hashHas,"hashHas"),_hashHas=hashHas,_hashHas}__name(require_hashHas,"require_hashHas");var _hashSet,hasRequired_hashSet;function require_hashSet(){if(hasRequired_hashSet)return _hashSet;hasRequired_hashSet=1;var nativeCreate=require_nativeCreate(),HASH_UNDEFINED="__lodash_hash_undefined__";function hashSet(key,value2){var data=this.__data__;return this.size+=this.has(key)?0:1,data[key]=nativeCreate&&value2===void 0?HASH_UNDEFINED:value2,this}return __name(hashSet,"hashSet"),_hashSet=hashSet,_hashSet}__name(require_hashSet,"require_hashSet");var _Hash,hasRequired_Hash;function require_Hash(){if(hasRequired_Hash)return _Hash;hasRequired_Hash=1;var hashClear=require_hashClear(),hashDelete=require_hashDelete(),hashGet=require_hashGet(),hashHas=require_hashHas(),hashSet=require_hashSet();function Hash2(entries){var index2=-1,length=entries==null?0:entries.length;for(this.clear();++index2-1}return __name(listCacheHas,"listCacheHas"),_listCacheHas=listCacheHas,_listCacheHas}__name(require_listCacheHas,"require_listCacheHas");var _listCacheSet,hasRequired_listCacheSet;function require_listCacheSet(){if(hasRequired_listCacheSet)return _listCacheSet;hasRequired_listCacheSet=1;var assocIndexOf=require_assocIndexOf();function listCacheSet(key,value2){var data=this.__data__,index2=assocIndexOf(data,key);return index2<0?(++this.size,data.push([key,value2])):data[index2][1]=value2,this}return __name(listCacheSet,"listCacheSet"),_listCacheSet=listCacheSet,_listCacheSet}__name(require_listCacheSet,"require_listCacheSet");var _ListCache,hasRequired_ListCache;function require_ListCache(){if(hasRequired_ListCache)return _ListCache;hasRequired_ListCache=1;var listCacheClear=require_listCacheClear(),listCacheDelete=require_listCacheDelete(),listCacheGet=require_listCacheGet(),listCacheHas=require_listCacheHas(),listCacheSet=require_listCacheSet();function ListCache(entries){var index2=-1,length=entries==null?0:entries.length;for(this.clear();++index20?1:-1},"mathSign"),isPercent=__name(function(value2){return O$4(value2)&&value2.indexOf("%")===value2.length-1},"isPercent"),isNumber$1=__name(function(value2){return isNumber$2(value2)&&!isNan(value2)},"isNumber"),isNullish=__name(function(value2){return isNil(value2)},"isNullish"),isNumOrStr=__name(function(value2){return isNumber$1(value2)||O$4(value2)},"isNumOrStr"),idCounter=0,uniqueId=__name(function(prefix2){var id=++idCounter;return"".concat(prefix2||"").concat(id)},"uniqueId"),getPercentValue=__name(function(percent,totalValue){var defaultValue=arguments.length>2&&arguments[2]!==void 0?arguments[2]:0,validate=arguments.length>3&&arguments[3]!==void 0?arguments[3]:!1;if(!isNumber$1(percent)&&!O$4(percent))return defaultValue;var value2;if(isPercent(percent)){var index2=percent.indexOf("%");value2=totalValue*parseFloat(percent.slice(0,index2))/100}else value2=+percent;return isNan(value2)&&(value2=defaultValue),validate&&value2>totalValue&&(value2=totalValue),value2},"getPercentValue"),getAnyElementOfObject=__name(function(obj){if(!obj)return null;var keys2=Object.keys(obj);return keys2&&keys2.length?obj[keys2[0]]:null},"getAnyElementOfObject"),hasDuplicate=__name(function(ary){if(!Array.isArray(ary))return!1;for(var len=ary.length,cache={},i2=0;i2=0)&&Object.prototype.propertyIsEnumerable.call(source,key)&&(target[key]=source[key])}return target}__name(_objectWithoutProperties$i,"_objectWithoutProperties$i");function _objectWithoutPropertiesLoose$i(source,excluded){if(source==null)return{};var target={};for(var key in source)if(Object.prototype.hasOwnProperty.call(source,key)){if(excluded.indexOf(key)>=0)continue;target[key]=source[key]}return target}__name(_objectWithoutPropertiesLoose$i,"_objectWithoutPropertiesLoose$i");var REACT_BROWSER_EVENT_MAP={click:"onClick",mousedown:"onMouseDown",mouseup:"onMouseUp",mouseover:"onMouseOver",mousemove:"onMouseMove",mouseout:"onMouseOut",mouseenter:"onMouseEnter",mouseleave:"onMouseLeave",touchcancel:"onTouchCancel",touchend:"onTouchEnd",touchmove:"onTouchMove",touchstart:"onTouchStart",contextmenu:"onContextMenu",dblclick:"onDoubleClick"},getDisplayName$1=__name(function(Comp){return typeof Comp=="string"?Comp:Comp?Comp.displayName||Comp.name||"Component":""},"getDisplayName"),lastChildren=null,lastResult=null,toArray$1=__name(function toArray(children2){if(children2===lastChildren&&Array.isArray(lastResult))return lastResult;var result=[];return reactExports.Children.forEach(children2,function(child){isNil(child)||(reactIsExports.isFragment(child)?result=result.concat(toArray(child.props.children)):result.push(child))}),lastResult=result,lastChildren=children2,result},"toArray");function findAllByType(children2,type){var result=[],types2=[];return Array.isArray(type)?types2=type.map(function(t2){return getDisplayName$1(t2)}):types2=[getDisplayName$1(type)],toArray$1(children2).forEach(function(child){var childType=ke(child,"type.displayName")||ke(child,"type.name");types2.indexOf(childType)!==-1&&result.push(child)}),result}__name(findAllByType,"findAllByType");function findChildByType(children2,type){var result=findAllByType(children2,type);return result&&result[0]}__name(findChildByType,"findChildByType");var validateWidthHeight=__name(function(el){if(!el||!el.props)return!1;var _el$props=el.props,width=_el$props.width,height=_el$props.height;return!(!isNumber$1(width)||width<=0||!isNumber$1(height)||height<=0)},"validateWidthHeight"),SVG_TAGS=["a","altGlyph","altGlyphDef","altGlyphItem","animate","animateColor","animateMotion","animateTransform","circle","clipPath","color-profile","cursor","defs","desc","ellipse","feBlend","feColormatrix","feComponentTransfer","feComposite","feConvolveMatrix","feDiffuseLighting","feDisplacementMap","feDistantLight","feFlood","feFuncA","feFuncB","feFuncG","feFuncR","feGaussianBlur","feImage","feMerge","feMergeNode","feMorphology","feOffset","fePointLight","feSpecularLighting","feSpotLight","feTile","feTurbulence","filter","font","font-face","font-face-format","font-face-name","font-face-url","foreignObject","g","glyph","glyphRef","hkern","image","line","lineGradient","marker","mask","metadata","missing-glyph","mpath","path","pattern","polygon","polyline","radialGradient","rect","script","set","stop","style","svg","switch","symbol","text","textPath","title","tref","tspan","use","view","vkern"],isSvgElement=__name(function(child){return child&&child.type&&O$4(child.type)&&SVG_TAGS.indexOf(child.type)>=0},"isSvgElement"),isValidSpreadableProp=__name(function(property,key,includeEvents,svgElementType){var _FilteredElementKeyMa,matchingElementTypeKeys=(_FilteredElementKeyMa=FilteredElementKeyMap?.[svgElementType])!==null&&_FilteredElementKeyMa!==void 0?_FilteredElementKeyMa:[];return key.startsWith("data-")||!Qe(property)&&(svgElementType&&matchingElementTypeKeys.includes(key)||SVGElementPropKeys.includes(key))||includeEvents&&EventKeys.includes(key)},"isValidSpreadableProp"),filterProps=__name(function(props,includeEvents,svgElementType){if(!props||typeof props=="function"||typeof props=="boolean")return null;var inputProps=props;if(reactExports.isValidElement(props)&&(inputProps=props.props),!isObject(inputProps))return null;var out={};return Object.keys(inputProps).forEach(function(key){var _inputProps;isValidSpreadableProp((_inputProps=inputProps)===null||_inputProps===void 0?void 0:_inputProps[key],key,includeEvents,svgElementType)&&(out[key]=inputProps[key])}),out},"filterProps"),isChildrenEqual=__name(function isChildrenEqual2(nextChildren,prevChildren){if(nextChildren===prevChildren)return!0;var count2=reactExports.Children.count(nextChildren);if(count2!==reactExports.Children.count(prevChildren))return!1;if(count2===0)return!0;if(count2===1)return isSingleChildEqual(Array.isArray(nextChildren)?nextChildren[0]:nextChildren,Array.isArray(prevChildren)?prevChildren[0]:prevChildren);for(var i2=0;i2=0)&&Object.prototype.propertyIsEnumerable.call(source,key)&&(target[key]=source[key])}return target}__name(_objectWithoutProperties$h,"_objectWithoutProperties$h");function _objectWithoutPropertiesLoose$h(source,excluded){if(source==null)return{};var target={};for(var key in source)if(Object.prototype.hasOwnProperty.call(source,key)){if(excluded.indexOf(key)>=0)continue;target[key]=source[key]}return target}__name(_objectWithoutPropertiesLoose$h,"_objectWithoutPropertiesLoose$h");function Surface(props){var children2=props.children,width=props.width,height=props.height,viewBox=props.viewBox,className=props.className,style2=props.style,title=props.title,desc=props.desc,others=_objectWithoutProperties$h(props,_excluded$h),svgView=viewBox||{width,height,x:0,y:0},layerClass=clsx("recharts-surface",className);return React.createElement("svg",_extends$u({},filterProps(others,!0,"svg"),{className:layerClass,width,height,style:style2,viewBox:"".concat(svgView.x," ").concat(svgView.y," ").concat(svgView.width," ").concat(svgView.height)}),React.createElement("title",null,title),React.createElement("desc",null,desc),children2)}__name(Surface,"Surface");var _excluded$g=["children","className"];function _extends$t(){return _extends$t=Object.assign?Object.assign.bind():function(target){for(var i2=1;i2=0)&&Object.prototype.propertyIsEnumerable.call(source,key)&&(target[key]=source[key])}return target}__name(_objectWithoutProperties$g,"_objectWithoutProperties$g");function _objectWithoutPropertiesLoose$g(source,excluded){if(source==null)return{};var target={};for(var key in source)if(Object.prototype.hasOwnProperty.call(source,key)){if(excluded.indexOf(key)>=0)continue;target[key]=source[key]}return target}__name(_objectWithoutPropertiesLoose$g,"_objectWithoutPropertiesLoose$g");var Layer=React.forwardRef(function(props,ref){var children2=props.children,className=props.className,others=_objectWithoutProperties$g(props,_excluded$g),layerClass=clsx("recharts-layer",className);return React.createElement("g",_extends$t({className:layerClass},filterProps(others,!0),{ref}),children2)}),warn=__name(function(condition,format2){for(var _len=arguments.length,args=new Array(_len>2?_len-2:0),_key=2;_key<_len;_key++)args[_key-2]=arguments[_key]},"warn2"),_baseSlice,hasRequired_baseSlice;function require_baseSlice(){if(hasRequired_baseSlice)return _baseSlice;hasRequired_baseSlice=1;function baseSlice(array2,start2,end){var index2=-1,length=array2.length;start2<0&&(start2=-start2>length?0:length+start2),end=end>length?length:end,end<0&&(end+=length),length=start2>end?0:end-start2>>>0,start2>>>=0;for(var result=Array(length);++index2=length?array2:baseSlice(array2,start2,end)}return __name(castSlice,"castSlice"),_castSlice=castSlice,_castSlice}__name(require_castSlice,"require_castSlice");var _hasUnicode,hasRequired_hasUnicode;function require_hasUnicode(){if(hasRequired_hasUnicode)return _hasUnicode;hasRequired_hasUnicode=1;var rsAstralRange="\\ud800-\\udfff",rsComboMarksRange="\\u0300-\\u036f",reComboHalfMarksRange="\\ufe20-\\ufe2f",rsComboSymbolsRange="\\u20d0-\\u20ff",rsComboRange=rsComboMarksRange+reComboHalfMarksRange+rsComboSymbolsRange,rsVarRange="\\ufe0e\\ufe0f",rsZWJ="\\u200d",reHasUnicode=RegExp("["+rsZWJ+rsAstralRange+rsComboRange+rsVarRange+"]");function hasUnicode(string2){return reHasUnicode.test(string2)}return __name(hasUnicode,"hasUnicode"),_hasUnicode=hasUnicode,_hasUnicode}__name(require_hasUnicode,"require_hasUnicode");var _asciiToArray,hasRequired_asciiToArray;function require_asciiToArray(){if(hasRequired_asciiToArray)return _asciiToArray;hasRequired_asciiToArray=1;function asciiToArray(string2){return string2.split("")}return __name(asciiToArray,"asciiToArray"),_asciiToArray=asciiToArray,_asciiToArray}__name(require_asciiToArray,"require_asciiToArray");var _unicodeToArray,hasRequired_unicodeToArray;function require_unicodeToArray(){if(hasRequired_unicodeToArray)return _unicodeToArray;hasRequired_unicodeToArray=1;var rsAstralRange="\\ud800-\\udfff",rsComboMarksRange="\\u0300-\\u036f",reComboHalfMarksRange="\\ufe20-\\ufe2f",rsComboSymbolsRange="\\u20d0-\\u20ff",rsComboRange=rsComboMarksRange+reComboHalfMarksRange+rsComboSymbolsRange,rsVarRange="\\ufe0e\\ufe0f",rsAstral="["+rsAstralRange+"]",rsCombo="["+rsComboRange+"]",rsFitz="\\ud83c[\\udffb-\\udfff]",rsModifier="(?:"+rsCombo+"|"+rsFitz+")",rsNonAstral="[^"+rsAstralRange+"]",rsRegional="(?:\\ud83c[\\udde6-\\uddff]){2}",rsSurrPair="[\\ud800-\\udbff][\\udc00-\\udfff]",rsZWJ="\\u200d",reOptMod=rsModifier+"?",rsOptVar="["+rsVarRange+"]?",rsOptJoin="(?:"+rsZWJ+"(?:"+[rsNonAstral,rsRegional,rsSurrPair].join("|")+")"+rsOptVar+reOptMod+")*",rsSeq=rsOptVar+reOptMod+rsOptJoin,rsSymbol="(?:"+[rsNonAstral+rsCombo+"?",rsCombo,rsRegional,rsSurrPair,rsAstral].join("|")+")",reUnicode=RegExp(rsFitz+"(?="+rsFitz+")|"+rsSymbol+rsSeq,"g");function unicodeToArray(string2){return string2.match(reUnicode)||[]}return __name(unicodeToArray,"unicodeToArray"),_unicodeToArray=unicodeToArray,_unicodeToArray}__name(require_unicodeToArray,"require_unicodeToArray");var _stringToArray,hasRequired_stringToArray;function require_stringToArray(){if(hasRequired_stringToArray)return _stringToArray;hasRequired_stringToArray=1;var asciiToArray=require_asciiToArray(),hasUnicode=require_hasUnicode(),unicodeToArray=require_unicodeToArray();function stringToArray(string2){return hasUnicode(string2)?unicodeToArray(string2):asciiToArray(string2)}return __name(stringToArray,"stringToArray"),_stringToArray=stringToArray,_stringToArray}__name(require_stringToArray,"require_stringToArray");var _createCaseFirst,hasRequired_createCaseFirst;function require_createCaseFirst(){if(hasRequired_createCaseFirst)return _createCaseFirst;hasRequired_createCaseFirst=1;var castSlice=require_castSlice(),hasUnicode=require_hasUnicode(),stringToArray=require_stringToArray(),toString2=requireToString();function createCaseFirst(methodName){return function(string2){string2=toString2(string2);var strSymbols=hasUnicode(string2)?stringToArray(string2):void 0,chr=strSymbols?strSymbols[0]:string2.charAt(0),trailing=strSymbols?castSlice(strSymbols,1).join(""):string2.slice(1);return chr[methodName]()+trailing}}return __name(createCaseFirst,"createCaseFirst"),_createCaseFirst=createCaseFirst,_createCaseFirst}__name(require_createCaseFirst,"require_createCaseFirst");var upperFirst_1,hasRequiredUpperFirst;function requireUpperFirst(){if(hasRequiredUpperFirst)return upperFirst_1;hasRequiredUpperFirst=1;var createCaseFirst=require_createCaseFirst(),upperFirst2=createCaseFirst("toUpperCase");return upperFirst_1=upperFirst2,upperFirst_1}__name(requireUpperFirst,"requireUpperFirst");var upperFirstExports=requireUpperFirst();const upperFirst=getDefaultExportFromCjs(upperFirstExports);function constant$2(x2){return __name(function(){return x2},"constant")}__name(constant$2,"constant$2");const cos=Math.cos,sin=Math.sin,sqrt$1=Math.sqrt,epsilon$1=1e-12,pi$1=Math.PI,tau$1=2*pi$1,pi=Math.PI,tau=2*pi,epsilon=1e-6,tauEpsilon=tau-epsilon;function append(strings){this._+=strings[0];for(let i2=1,n2=strings.length;i2=0))throw new Error(`invalid digits: ${digits}`);if(d>15)return append;const k2=10**d;return function(strings){this._+=strings[0];for(let i2=1,n2=strings.length;i2epsilon)if(!(Math.abs(y01*x21-y21*x01)>epsilon)||!r2)this._append`L${this._x1=x1},${this._y1=y1}`;else{let x20=x2-x0,y20=y2-y0,l21_2=x21*x21+y21*y21,l20_2=x20*x20+y20*y20,l21=Math.sqrt(l21_2),l01=Math.sqrt(l01_2),l2=r2*Math.tan((pi-Math.acos((l21_2+l01_2-l20_2)/(2*l21*l01)))/2),t01=l2/l01,t21=l2/l21;Math.abs(t01-1)>epsilon&&this._append`L${x1+t01*x01},${y1+t01*y01}`,this._append`A${r2},${r2},0,0,${+(y01*x20>x01*y20)},${this._x1=x1+t21*x21},${this._y1=y1+t21*y21}`}}arc(x2,y2,r2,a0,a1,ccw){if(x2=+x2,y2=+y2,r2=+r2,ccw=!!ccw,r2<0)throw new Error(`negative radius: ${r2}`);let dx=r2*Math.cos(a0),dy=r2*Math.sin(a0),x0=x2+dx,y0=y2+dy,cw=1^ccw,da=ccw?a0-a1:a1-a0;this._x1===null?this._append`M${x0},${y0}`:(Math.abs(this._x1-x0)>epsilon||Math.abs(this._y1-y0)>epsilon)&&this._append`L${x0},${y0}`,r2&&(da<0&&(da=da%tau+tau),da>tauEpsilon?this._append`A${r2},${r2},0,1,${cw},${x2-dx},${y2-dy}A${r2},${r2},0,1,${cw},${this._x1=x0},${this._y1=y0}`:da>epsilon&&this._append`A${r2},${r2},0,${+(da>=pi)},${cw},${this._x1=x2+r2*Math.cos(a1)},${this._y1=y2+r2*Math.sin(a1)}`)}rect(x2,y2,w2,h2){this._append`M${this._x0=this._x1=+x2},${this._y0=this._y1=+y2}h${w2=+w2}v${+h2}h${-w2}Z`}toString(){return this._}};__name(_Path,"Path");let Path=_Path;function withPath(shape){let digits=3;return shape.digits=function(_2){if(!arguments.length)return digits;if(_2==null)digits=null;else{const d=Math.floor(_2);if(!(d>=0))throw new RangeError(`invalid digits: ${_2}`);digits=d}return shape},()=>new Path(digits)}__name(withPath,"withPath");function array(x2){return typeof x2=="object"&&"length"in x2?x2:Array.from(x2)}__name(array,"array");function Linear(context){this._context=context}__name(Linear,"Linear");Linear.prototype={areaStart:__name(function(){this._line=0},"areaStart"),areaEnd:__name(function(){this._line=NaN},"areaEnd"),lineStart:__name(function(){this._point=0},"lineStart"),lineEnd:__name(function(){(this._line||this._line!==0&&this._point===1)&&this._context.closePath(),this._line=1-this._line},"lineEnd"),point:__name(function(x2,y2){switch(x2=+x2,y2=+y2,this._point){case 0:this._point=1,this._line?this._context.lineTo(x2,y2):this._context.moveTo(x2,y2);break;case 1:this._point=2;default:this._context.lineTo(x2,y2);break}},"point")};function sr(context){return new Linear(context)}__name(sr,"sr");function x$2(p2){return p2[0]}__name(x$2,"x$2");function y$1(p2){return p2[1]}__name(y$1,"y$1");function N$2(x2,y2){var defined3=constant$2(!0),context=null,curve=sr,output=null,path2=withPath(line);x2=typeof x2=="function"?x2:x2===void 0?x$2:constant$2(x2),y2=typeof y2=="function"?y2:y2===void 0?y$1:constant$2(y2);function line(data){var i2,n2=(data=array(data)).length,d,defined0=!1,buffer;for(context==null&&(output=curve(buffer=path2())),i2=0;i2<=n2;++i2)!(i2=j2;--k2)output.point(x0z[k2],y0z[k2]);output.lineEnd(),output.areaEnd()}defined0&&(x0z[i2]=+x0(d,i2,data),y0z[i2]=+y0(d,i2,data),output.point(x1?+x1(d,i2,data):x0z[i2],y1?+y1(d,i2,data):y0z[i2]))}if(buffer)return output=null,buffer+""||null}__name(area,"area");function arealine(){return N$2().defined(defined3).curve(curve).context(context)}return __name(arealine,"arealine"),area.x=function(_2){return arguments.length?(x0=typeof _2=="function"?_2:constant$2(+_2),x1=null,area):x0},area.x0=function(_2){return arguments.length?(x0=typeof _2=="function"?_2:constant$2(+_2),area):x0},area.x1=function(_2){return arguments.length?(x1=_2==null?null:typeof _2=="function"?_2:constant$2(+_2),area):x1},area.y=function(_2){return arguments.length?(y0=typeof _2=="function"?_2:constant$2(+_2),y1=null,area):y0},area.y0=function(_2){return arguments.length?(y0=typeof _2=="function"?_2:constant$2(+_2),area):y0},area.y1=function(_2){return arguments.length?(y1=_2==null?null:typeof _2=="function"?_2:constant$2(+_2),area):y1},area.lineX0=area.lineY0=function(){return arealine().x(x0).y(y0)},area.lineY1=function(){return arealine().x(x0).y(y1)},area.lineX1=function(){return arealine().x(x1).y(y0)},area.defined=function(_2){return arguments.length?(defined3=typeof _2=="function"?_2:constant$2(!!_2),area):defined3},area.curve=function(_2){return arguments.length?(curve=_2,context!=null&&(output=curve(context)),area):curve},area.context=function(_2){return arguments.length?(_2==null?context=output=null:output=curve(context=_2),area):context},area}__name(shapeArea,"shapeArea");const _Bump=class _Bump{constructor(context,x2){this._context=context,this._x=x2}areaStart(){this._line=0}areaEnd(){this._line=NaN}lineStart(){this._point=0}lineEnd(){(this._line||this._line!==0&&this._point===1)&&this._context.closePath(),this._line=1-this._line}point(x2,y2){switch(x2=+x2,y2=+y2,this._point){case 0:{this._point=1,this._line?this._context.lineTo(x2,y2):this._context.moveTo(x2,y2);break}case 1:this._point=2;default:{this._x?this._context.bezierCurveTo(this._x0=(this._x0+x2)/2,this._y0,this._x0,y2,x2,y2):this._context.bezierCurveTo(this._x0,this._y0=(this._y0+y2)/2,x2,this._y0,x2,y2);break}}this._x0=x2,this._y0=y2}};__name(_Bump,"Bump");let Bump=_Bump;function bumpX(context){return new Bump(context,!0)}__name(bumpX,"bumpX");function bumpY(context){return new Bump(context,!1)}__name(bumpY,"bumpY");const symbolCircle={draw(context,size2){const r2=sqrt$1(size2/pi$1);context.moveTo(r2,0),context.arc(0,0,r2,0,tau$1)}},symbolCross={draw(context,size2){const r2=sqrt$1(size2/5)/2;context.moveTo(-3*r2,-r2),context.lineTo(-r2,-r2),context.lineTo(-r2,-3*r2),context.lineTo(r2,-3*r2),context.lineTo(r2,-r2),context.lineTo(3*r2,-r2),context.lineTo(3*r2,r2),context.lineTo(r2,r2),context.lineTo(r2,3*r2),context.lineTo(-r2,3*r2),context.lineTo(-r2,r2),context.lineTo(-3*r2,r2),context.closePath()}},tan30=sqrt$1(1/3),tan30_2=tan30*2,symbolDiamond={draw(context,size2){const y2=sqrt$1(size2/tan30_2),x2=y2*tan30;context.moveTo(0,-y2),context.lineTo(x2,0),context.lineTo(0,y2),context.lineTo(-x2,0),context.closePath()}},symbolSquare={draw(context,size2){const w2=sqrt$1(size2),x2=-w2/2;context.rect(x2,x2,w2,w2)}},ka=.8908130915292852,kr$1=sin(pi$1/10)/sin(7*pi$1/10),kx=sin(tau$1/10)*kr$1,ky=-cos(tau$1/10)*kr$1,symbolStar={draw(context,size2){const r2=sqrt$1(size2*ka),x2=kx*r2,y2=ky*r2;context.moveTo(0,-r2),context.lineTo(x2,y2);for(let i2=1;i2<5;++i2){const a2=tau$1*i2/5,c2=cos(a2),s2=sin(a2);context.lineTo(s2*r2,-c2*r2),context.lineTo(c2*x2-s2*y2,s2*x2+c2*y2)}context.closePath()}},sqrt3=sqrt$1(3),symbolTriangle={draw(context,size2){const y2=-sqrt$1(size2/(sqrt3*3));context.moveTo(0,y2*2),context.lineTo(-sqrt3*y2,-y2),context.lineTo(sqrt3*y2,-y2),context.closePath()}},c$3=-.5,s$1=sqrt$1(3)/2,k$3=1/sqrt$1(12),a$1=(k$3/2+1)*3,symbolWye={draw(context,size2){const r2=sqrt$1(size2/a$1),x0=r2/2,y0=r2*k$3,x1=x0,y1=r2*k$3+r2,x2=-x1,y2=y1;context.moveTo(x0,y0),context.lineTo(x1,y1),context.lineTo(x2,y2),context.lineTo(c$3*x0-s$1*y0,s$1*x0+c$3*y0),context.lineTo(c$3*x1-s$1*y1,s$1*x1+c$3*y1),context.lineTo(c$3*x2-s$1*y2,s$1*x2+c$3*y2),context.lineTo(c$3*x0+s$1*y0,c$3*y0-s$1*x0),context.lineTo(c$3*x1+s$1*y1,c$3*y1-s$1*x1),context.lineTo(c$3*x2+s$1*y2,c$3*y2-s$1*x2),context.closePath()}};function Symbol$1(type,size2){let context=null,path2=withPath(symbol);type=typeof type=="function"?type:constant$2(type||symbolCircle),size2=typeof size2=="function"?size2:constant$2(size2===void 0?64:+size2);function symbol(){let buffer;if(context||(context=buffer=path2()),type.apply(this,arguments).draw(context,+size2.apply(this,arguments)),buffer)return context=null,buffer+""||null}return __name(symbol,"symbol"),symbol.type=function(_2){return arguments.length?(type=typeof _2=="function"?_2:constant$2(_2),symbol):type},symbol.size=function(_2){return arguments.length?(size2=typeof _2=="function"?_2:constant$2(+_2),symbol):size2},symbol.context=function(_2){return arguments.length?(context=_2??null,symbol):context},symbol}__name(Symbol$1,"Symbol$1");function noop$1(){}__name(noop$1,"noop$1");function point$8(that,x2,y2){that._context.bezierCurveTo((2*that._x0+that._x1)/3,(2*that._y0+that._y1)/3,(that._x0+2*that._x1)/3,(that._y0+2*that._y1)/3,(that._x0+4*that._x1+x2)/6,(that._y0+4*that._y1+y2)/6)}__name(point$8,"point$8");function Basis(context){this._context=context}__name(Basis,"Basis");Basis.prototype={areaStart:__name(function(){this._line=0},"areaStart"),areaEnd:__name(function(){this._line=NaN},"areaEnd"),lineStart:__name(function(){this._x0=this._x1=this._y0=this._y1=NaN,this._point=0},"lineStart"),lineEnd:__name(function(){switch(this._point){case 3:point$8(this,this._x1,this._y1);case 2:this._context.lineTo(this._x1,this._y1);break}(this._line||this._line!==0&&this._point===1)&&this._context.closePath(),this._line=1-this._line},"lineEnd"),point:__name(function(x2,y2){switch(x2=+x2,y2=+y2,this._point){case 0:this._point=1,this._line?this._context.lineTo(x2,y2):this._context.moveTo(x2,y2);break;case 1:this._point=2;break;case 2:this._point=3,this._context.lineTo((5*this._x0+this._x1)/6,(5*this._y0+this._y1)/6);default:point$8(this,x2,y2);break}this._x0=this._x1,this._x1=x2,this._y0=this._y1,this._y1=y2},"point")};function $e$1(context){return new Basis(context)}__name($e$1,"$e$1");function BasisClosed(context){this._context=context}__name(BasisClosed,"BasisClosed");BasisClosed.prototype={areaStart:noop$1,areaEnd:noop$1,lineStart:__name(function(){this._x0=this._x1=this._x2=this._x3=this._x4=this._y0=this._y1=this._y2=this._y3=this._y4=NaN,this._point=0},"lineStart"),lineEnd:__name(function(){switch(this._point){case 1:{this._context.moveTo(this._x2,this._y2),this._context.closePath();break}case 2:{this._context.moveTo((this._x2+2*this._x3)/3,(this._y2+2*this._y3)/3),this._context.lineTo((this._x3+2*this._x2)/3,(this._y3+2*this._y2)/3),this._context.closePath();break}case 3:{this.point(this._x2,this._y2),this.point(this._x3,this._y3),this.point(this._x4,this._y4);break}}},"lineEnd"),point:__name(function(x2,y2){switch(x2=+x2,y2=+y2,this._point){case 0:this._point=1,this._x2=x2,this._y2=y2;break;case 1:this._point=2,this._x3=x2,this._y3=y2;break;case 2:this._point=3,this._x4=x2,this._y4=y2,this._context.moveTo((this._x0+4*this._x1+x2)/6,(this._y0+4*this._y1+y2)/6);break;default:point$8(this,x2,y2);break}this._x0=this._x1,this._x1=x2,this._y0=this._y1,this._y1=y2},"point")};function er(context){return new BasisClosed(context)}__name(er,"er");function BasisOpen(context){this._context=context}__name(BasisOpen,"BasisOpen");BasisOpen.prototype={areaStart:__name(function(){this._line=0},"areaStart"),areaEnd:__name(function(){this._line=NaN},"areaEnd"),lineStart:__name(function(){this._x0=this._x1=this._y0=this._y1=NaN,this._point=0},"lineStart"),lineEnd:__name(function(){(this._line||this._line!==0&&this._point===3)&&this._context.closePath(),this._line=1-this._line},"lineEnd"),point:__name(function(x2,y2){switch(x2=+x2,y2=+y2,this._point){case 0:this._point=1;break;case 1:this._point=2;break;case 2:this._point=3;var x0=(this._x0+4*this._x1+x2)/6,y0=(this._y0+4*this._y1+y2)/6;this._line?this._context.lineTo(x0,y0):this._context.moveTo(x0,y0);break;case 3:this._point=4;default:point$8(this,x2,y2);break}this._x0=this._x1,this._x1=x2,this._y0=this._y1,this._y1=y2},"point")};function rr(context){return new BasisOpen(context)}__name(rr,"rr");function Bundle(context,beta){this._basis=new Basis(context),this._beta=beta}__name(Bundle,"Bundle");Bundle.prototype={lineStart:__name(function(){this._x=[],this._y=[],this._basis.lineStart()},"lineStart"),lineEnd:__name(function(){var x2=this._x,y2=this._y,j2=x2.length-1;if(j2>0)for(var x0=x2[0],y0=y2[0],dx=x2[j2]-x0,dy=y2[j2]-y0,i2=-1,t2;++i2<=j2;)t2=i2/j2,this._basis.point(this._beta*x2[i2]+(1-this._beta)*(x0+t2*dx),this._beta*y2[i2]+(1-this._beta)*(y0+t2*dy));this._x=this._y=null,this._basis.lineEnd()},"lineEnd"),point:__name(function(x2,y2){this._x.push(+x2),this._y.push(+y2)},"point")};const tr=__name((function custom(beta){function bundle(context){return beta===1?new Basis(context):new Bundle(context,beta)}return __name(bundle,"bundle"),bundle.beta=function(beta2){return custom(+beta2)},bundle}),"custom")(.85);function point$7(that,x2,y2){that._context.bezierCurveTo(that._x1+that._k*(that._x2-that._x0),that._y1+that._k*(that._y2-that._y0),that._x2+that._k*(that._x1-x2),that._y2+that._k*(that._y1-y2),that._x2,that._y2)}__name(point$7,"point$7");function Cardinal(context,tension){this._context=context,this._k=(1-tension)/6}__name(Cardinal,"Cardinal");Cardinal.prototype={areaStart:__name(function(){this._line=0},"areaStart"),areaEnd:__name(function(){this._line=NaN},"areaEnd"),lineStart:__name(function(){this._x0=this._x1=this._x2=this._y0=this._y1=this._y2=NaN,this._point=0},"lineStart"),lineEnd:__name(function(){switch(this._point){case 2:this._context.lineTo(this._x2,this._y2);break;case 3:point$7(this,this._x1,this._y1);break}(this._line||this._line!==0&&this._point===1)&&this._context.closePath(),this._line=1-this._line},"lineEnd"),point:__name(function(x2,y2){switch(x2=+x2,y2=+y2,this._point){case 0:this._point=1,this._line?this._context.lineTo(x2,y2):this._context.moveTo(x2,y2);break;case 1:this._point=2,this._x1=x2,this._y1=y2;break;case 2:this._point=3;default:point$7(this,x2,y2);break}this._x0=this._x1,this._x1=this._x2,this._x2=x2,this._y0=this._y1,this._y1=this._y2,this._y2=y2},"point")};const nr=__name((function custom2(tension){function cardinal(context){return new Cardinal(context,tension)}return __name(cardinal,"cardinal"),cardinal.tension=function(tension2){return custom2(+tension2)},cardinal}),"custom")(0);function CardinalClosed(context,tension){this._context=context,this._k=(1-tension)/6}__name(CardinalClosed,"CardinalClosed");CardinalClosed.prototype={areaStart:noop$1,areaEnd:noop$1,lineStart:__name(function(){this._x0=this._x1=this._x2=this._x3=this._x4=this._x5=this._y0=this._y1=this._y2=this._y3=this._y4=this._y5=NaN,this._point=0},"lineStart"),lineEnd:__name(function(){switch(this._point){case 1:{this._context.moveTo(this._x3,this._y3),this._context.closePath();break}case 2:{this._context.lineTo(this._x3,this._y3),this._context.closePath();break}case 3:{this.point(this._x3,this._y3),this.point(this._x4,this._y4),this.point(this._x5,this._y5);break}}},"lineEnd"),point:__name(function(x2,y2){switch(x2=+x2,y2=+y2,this._point){case 0:this._point=1,this._x3=x2,this._y3=y2;break;case 1:this._point=2,this._context.moveTo(this._x4=x2,this._y4=y2);break;case 2:this._point=3,this._x5=x2,this._y5=y2;break;default:point$7(this,x2,y2);break}this._x0=this._x1,this._x1=this._x2,this._x2=x2,this._y0=this._y1,this._y1=this._y2,this._y2=y2},"point")};const ir=__name((function custom3(tension){function cardinal(context){return new CardinalClosed(context,tension)}return __name(cardinal,"cardinal"),cardinal.tension=function(tension2){return custom3(+tension2)},cardinal}),"custom")(0);function CardinalOpen(context,tension){this._context=context,this._k=(1-tension)/6}__name(CardinalOpen,"CardinalOpen");CardinalOpen.prototype={areaStart:__name(function(){this._line=0},"areaStart"),areaEnd:__name(function(){this._line=NaN},"areaEnd"),lineStart:__name(function(){this._x0=this._x1=this._x2=this._y0=this._y1=this._y2=NaN,this._point=0},"lineStart"),lineEnd:__name(function(){(this._line||this._line!==0&&this._point===3)&&this._context.closePath(),this._line=1-this._line},"lineEnd"),point:__name(function(x2,y2){switch(x2=+x2,y2=+y2,this._point){case 0:this._point=1;break;case 1:this._point=2;break;case 2:this._point=3,this._line?this._context.lineTo(this._x2,this._y2):this._context.moveTo(this._x2,this._y2);break;case 3:this._point=4;default:point$7(this,x2,y2);break}this._x0=this._x1,this._x1=this._x2,this._x2=x2,this._y0=this._y1,this._y1=this._y2,this._y2=y2},"point")};const or=__name((function custom4(tension){function cardinal(context){return new CardinalOpen(context,tension)}return __name(cardinal,"cardinal"),cardinal.tension=function(tension2){return custom4(+tension2)},cardinal}),"custom")(0);function point$6(that,x2,y2){var x1=that._x1,y1=that._y1,x22=that._x2,y22=that._y2;if(that._l01_a>epsilon$1){var a2=2*that._l01_2a+3*that._l01_a*that._l12_a+that._l12_2a,n2=3*that._l01_a*(that._l01_a+that._l12_a);x1=(x1*a2-that._x0*that._l12_2a+that._x2*that._l01_2a)/n2,y1=(y1*a2-that._y0*that._l12_2a+that._y2*that._l01_2a)/n2}if(that._l23_a>epsilon$1){var b2=2*that._l23_2a+3*that._l23_a*that._l12_a+that._l12_2a,m2=3*that._l23_a*(that._l23_a+that._l12_a);x22=(x22*b2+that._x1*that._l23_2a-x2*that._l12_2a)/m2,y22=(y22*b2+that._y1*that._l23_2a-y2*that._l12_2a)/m2}that._context.bezierCurveTo(x1,y1,x22,y22,that._x2,that._y2)}__name(point$6,"point$6");function CatmullRom(context,alpha3){this._context=context,this._alpha=alpha3}__name(CatmullRom,"CatmullRom");CatmullRom.prototype={areaStart:__name(function(){this._line=0},"areaStart"),areaEnd:__name(function(){this._line=NaN},"areaEnd"),lineStart:__name(function(){this._x0=this._x1=this._x2=this._y0=this._y1=this._y2=NaN,this._l01_a=this._l12_a=this._l23_a=this._l01_2a=this._l12_2a=this._l23_2a=this._point=0},"lineStart"),lineEnd:__name(function(){switch(this._point){case 2:this._context.lineTo(this._x2,this._y2);break;case 3:this.point(this._x2,this._y2);break}(this._line||this._line!==0&&this._point===1)&&this._context.closePath(),this._line=1-this._line},"lineEnd"),point:__name(function(x2,y2){if(x2=+x2,y2=+y2,this._point){var x23=this._x2-x2,y23=this._y2-y2;this._l23_a=Math.sqrt(this._l23_2a=Math.pow(x23*x23+y23*y23,this._alpha))}switch(this._point){case 0:this._point=1,this._line?this._context.lineTo(x2,y2):this._context.moveTo(x2,y2);break;case 1:this._point=2;break;case 2:this._point=3;default:point$6(this,x2,y2);break}this._l01_a=this._l12_a,this._l12_a=this._l23_a,this._l01_2a=this._l12_2a,this._l12_2a=this._l23_2a,this._x0=this._x1,this._x1=this._x2,this._x2=x2,this._y0=this._y1,this._y1=this._y2,this._y2=y2},"point")};const lr=__name((function custom5(alpha3){function catmullRom(context){return alpha3?new CatmullRom(context,alpha3):new Cardinal(context,0)}return __name(catmullRom,"catmullRom"),catmullRom.alpha=function(alpha4){return custom5(+alpha4)},catmullRom}),"custom")(.5);function CatmullRomClosed(context,alpha3){this._context=context,this._alpha=alpha3}__name(CatmullRomClosed,"CatmullRomClosed");CatmullRomClosed.prototype={areaStart:noop$1,areaEnd:noop$1,lineStart:__name(function(){this._x0=this._x1=this._x2=this._x3=this._x4=this._x5=this._y0=this._y1=this._y2=this._y3=this._y4=this._y5=NaN,this._l01_a=this._l12_a=this._l23_a=this._l01_2a=this._l12_2a=this._l23_2a=this._point=0},"lineStart"),lineEnd:__name(function(){switch(this._point){case 1:{this._context.moveTo(this._x3,this._y3),this._context.closePath();break}case 2:{this._context.lineTo(this._x3,this._y3),this._context.closePath();break}case 3:{this.point(this._x3,this._y3),this.point(this._x4,this._y4),this.point(this._x5,this._y5);break}}},"lineEnd"),point:__name(function(x2,y2){if(x2=+x2,y2=+y2,this._point){var x23=this._x2-x2,y23=this._y2-y2;this._l23_a=Math.sqrt(this._l23_2a=Math.pow(x23*x23+y23*y23,this._alpha))}switch(this._point){case 0:this._point=1,this._x3=x2,this._y3=y2;break;case 1:this._point=2,this._context.moveTo(this._x4=x2,this._y4=y2);break;case 2:this._point=3,this._x5=x2,this._y5=y2;break;default:point$6(this,x2,y2);break}this._l01_a=this._l12_a,this._l12_a=this._l23_a,this._l01_2a=this._l12_2a,this._l12_2a=this._l23_2a,this._x0=this._x1,this._x1=this._x2,this._x2=x2,this._y0=this._y1,this._y1=this._y2,this._y2=y2},"point")};const ar=__name((function custom6(alpha3){function catmullRom(context){return alpha3?new CatmullRomClosed(context,alpha3):new CardinalClosed(context,0)}return __name(catmullRom,"catmullRom"),catmullRom.alpha=function(alpha4){return custom6(+alpha4)},catmullRom}),"custom")(.5);function CatmullRomOpen(context,alpha3){this._context=context,this._alpha=alpha3}__name(CatmullRomOpen,"CatmullRomOpen");CatmullRomOpen.prototype={areaStart:__name(function(){this._line=0},"areaStart"),areaEnd:__name(function(){this._line=NaN},"areaEnd"),lineStart:__name(function(){this._x0=this._x1=this._x2=this._y0=this._y1=this._y2=NaN,this._l01_a=this._l12_a=this._l23_a=this._l01_2a=this._l12_2a=this._l23_2a=this._point=0},"lineStart"),lineEnd:__name(function(){(this._line||this._line!==0&&this._point===3)&&this._context.closePath(),this._line=1-this._line},"lineEnd"),point:__name(function(x2,y2){if(x2=+x2,y2=+y2,this._point){var x23=this._x2-x2,y23=this._y2-y2;this._l23_a=Math.sqrt(this._l23_2a=Math.pow(x23*x23+y23*y23,this._alpha))}switch(this._point){case 0:this._point=1;break;case 1:this._point=2;break;case 2:this._point=3,this._line?this._context.lineTo(this._x2,this._y2):this._context.moveTo(this._x2,this._y2);break;case 3:this._point=4;default:point$6(this,x2,y2);break}this._l01_a=this._l12_a,this._l12_a=this._l23_a,this._l01_2a=this._l12_2a,this._l12_2a=this._l23_2a,this._x0=this._x1,this._x1=this._x2,this._x2=x2,this._y0=this._y1,this._y1=this._y2,this._y2=y2},"point")};const dr=__name((function custom7(alpha3){function catmullRom(context){return alpha3?new CatmullRomOpen(context,alpha3):new CardinalOpen(context,0)}return __name(catmullRom,"catmullRom"),catmullRom.alpha=function(alpha4){return custom7(+alpha4)},catmullRom}),"custom")(.5);function LinearClosed(context){this._context=context}__name(LinearClosed,"LinearClosed");LinearClosed.prototype={areaStart:noop$1,areaEnd:noop$1,lineStart:__name(function(){this._point=0},"lineStart"),lineEnd:__name(function(){this._point&&this._context.closePath()},"lineEnd"),point:__name(function(x2,y2){x2=+x2,y2=+y2,this._point?this._context.lineTo(x2,y2):(this._point=1,this._context.moveTo(x2,y2))},"point")};function ur(context){return new LinearClosed(context)}__name(ur,"ur");function sign(x2){return x2<0?-1:1}__name(sign,"sign");function slope3(that,x2,y2){var h0=that._x1-that._x0,h1=x2-that._x1,s0=(that._y1-that._y0)/(h0||h1<0&&-0),s1=(y2-that._y1)/(h1||h0<0&&-0),p2=(s0*h1+s1*h0)/(h0+h1);return(sign(s0)+sign(s1))*Math.min(Math.abs(s0),Math.abs(s1),.5*Math.abs(p2))||0}__name(slope3,"slope3");function slope2(that,t2){var h2=that._x1-that._x0;return h2?(3*(that._y1-that._y0)/h2-t2)/2:t2}__name(slope2,"slope2");function point$5(that,t02,t12){var x0=that._x0,y0=that._y0,x1=that._x1,y1=that._y1,dx=(x1-x0)/3;that._context.bezierCurveTo(x0+dx,y0+dx*t02,x1-dx,y1-dx*t12,x1,y1)}__name(point$5,"point$5");function MonotoneX(context){this._context=context}__name(MonotoneX,"MonotoneX");MonotoneX.prototype={areaStart:__name(function(){this._line=0},"areaStart"),areaEnd:__name(function(){this._line=NaN},"areaEnd"),lineStart:__name(function(){this._x0=this._x1=this._y0=this._y1=this._t0=NaN,this._point=0},"lineStart"),lineEnd:__name(function(){switch(this._point){case 2:this._context.lineTo(this._x1,this._y1);break;case 3:point$5(this,this._t0,slope2(this,this._t0));break}(this._line||this._line!==0&&this._point===1)&&this._context.closePath(),this._line=1-this._line},"lineEnd"),point:__name(function(x2,y2){var t12=NaN;if(x2=+x2,y2=+y2,!(x2===this._x1&&y2===this._y1)){switch(this._point){case 0:this._point=1,this._line?this._context.lineTo(x2,y2):this._context.moveTo(x2,y2);break;case 1:this._point=2;break;case 2:this._point=3,point$5(this,slope2(this,t12=slope3(this,x2,y2)),t12);break;default:point$5(this,this._t0,t12=slope3(this,x2,y2));break}this._x0=this._x1,this._x1=x2,this._y0=this._y1,this._y1=y2,this._t0=t12}},"point")};function MonotoneY(context){this._context=new ReflectContext(context)}__name(MonotoneY,"MonotoneY");(MonotoneY.prototype=Object.create(MonotoneX.prototype)).point=function(x2,y2){MonotoneX.prototype.point.call(this,y2,x2)};function ReflectContext(context){this._context=context}__name(ReflectContext,"ReflectContext");ReflectContext.prototype={moveTo:__name(function(x2,y2){this._context.moveTo(y2,x2)},"moveTo"),closePath:__name(function(){this._context.closePath()},"closePath"),lineTo:__name(function(x2,y2){this._context.lineTo(y2,x2)},"lineTo"),bezierCurveTo:__name(function(x1,y1,x2,y2,x3,y3){this._context.bezierCurveTo(y1,x1,y2,x2,y3,x3)},"bezierCurveTo")};function monotoneX(context){return new MonotoneX(context)}__name(monotoneX,"monotoneX");function monotoneY(context){return new MonotoneY(context)}__name(monotoneY,"monotoneY");function Natural(context){this._context=context}__name(Natural,"Natural");Natural.prototype={areaStart:__name(function(){this._line=0},"areaStart"),areaEnd:__name(function(){this._line=NaN},"areaEnd"),lineStart:__name(function(){this._x=[],this._y=[]},"lineStart"),lineEnd:__name(function(){var x2=this._x,y2=this._y,n2=x2.length;if(n2)if(this._line?this._context.lineTo(x2[0],y2[0]):this._context.moveTo(x2[0],y2[0]),n2===2)this._context.lineTo(x2[1],y2[1]);else for(var px=controlPoints(x2),py=controlPoints(y2),i0=0,i1=1;i1=0;--i2)a2[i2]=(r2[i2]-a2[i2+1])/b2[i2];for(b2[n2-1]=(x2[n2]+a2[n2-1])/2,i2=0;i2=0&&(this._t=1-this._t,this._line=1-this._line)},"lineEnd"),point:__name(function(x2,y2){switch(x2=+x2,y2=+y2,this._point){case 0:this._point=1,this._line?this._context.lineTo(x2,y2):this._context.moveTo(x2,y2);break;case 1:this._point=2;default:{if(this._t<=0)this._context.lineTo(this._x,y2),this._context.lineTo(x2,y2);else{var x1=this._x*(1-this._t)+x2*this._t;this._context.lineTo(x1,this._y),this._context.lineTo(x1,y2)}break}}this._x=x2,this._y=y2},"point")};function hr(context){return new Step(context,.5)}__name(hr,"hr");function stepBefore(context){return new Step(context,0)}__name(stepBefore,"stepBefore");function stepAfter(context){return new Step(context,1)}__name(stepAfter,"stepAfter");function xr(series,order2){if((n2=series.length)>1)for(var i2=1,j2,s0,s1=series[order2[0]],n2,m2=s1.length;i2=0;)o2[n2]=n2;return o2}__name(_r,"_r");function stackValue(d,key){return d[key]}__name(stackValue,"stackValue");function stackSeries(key){const series=[];return series.key=key,series}__name(stackSeries,"stackSeries");function shapeStack(){var keys2=constant$2([]),order2=_r,offset2=xr,value2=stackValue;function stack(data){var sz=Array.from(keys2.apply(this,arguments),stackSeries),i2,n2=sz.length,j2=-1,oz;for(const d of data)for(i2=0,++j2;i20){for(var i2,n2,j2=0,m2=series[0].length,y2;j20){for(var j2=0,s0=series[order2[0]],n2,m2=s0.length;j20)||!((m2=(s0=series[order2[0]]).length)>0))){for(var y2=0,j2=1,s0,m2,n2;j2=0)&&Object.prototype.propertyIsEnumerable.call(source,key)&&(target[key]=source[key])}return target}__name(_objectWithoutProperties$f,"_objectWithoutProperties$f");function _objectWithoutPropertiesLoose$f(source,excluded){if(source==null)return{};var target={};for(var key in source)if(Object.prototype.hasOwnProperty.call(source,key)){if(excluded.indexOf(key)>=0)continue;target[key]=source[key]}return target}__name(_objectWithoutPropertiesLoose$f,"_objectWithoutPropertiesLoose$f");var symbolFactories={symbolCircle,symbolCross,symbolDiamond,symbolSquare,symbolStar,symbolTriangle,symbolWye},RADIAN$2=Math.PI/180,getSymbolFactory=__name(function(type){var name2="symbol".concat(upperFirst(type));return symbolFactories[name2]||symbolCircle},"getSymbolFactory"),calculateAreaSize=__name(function(size2,sizeType,type){if(sizeType==="area")return size2;switch(type){case"cross":return 5*size2*size2/9;case"diamond":return .5*size2*size2/Math.sqrt(3);case"square":return size2*size2;case"star":{var angle=18*RADIAN$2;return 1.25*size2*size2*(Math.tan(angle)-Math.tan(angle*2)*Math.pow(Math.tan(angle),2))}case"triangle":return Math.sqrt(3)*size2*size2/4;case"wye":return(21-10*Math.sqrt(3))*size2*size2/8;default:return Math.PI*size2*size2/4}},"calculateAreaSize"),registerSymbol=__name(function(key,factory){symbolFactories["symbol".concat(upperFirst(key))]=factory},"registerSymbol"),Symbols=__name(function(_ref){var _ref$type=_ref.type,type=_ref$type===void 0?"circle":_ref$type,_ref$size=_ref.size,size2=_ref$size===void 0?64:_ref$size,_ref$sizeType=_ref.sizeType,sizeType=_ref$sizeType===void 0?"area":_ref$sizeType,rest=_objectWithoutProperties$f(_ref,_excluded$f),props=_objectSpread$C(_objectSpread$C({},rest),{},{type,size:size2,sizeType}),getPath4=__name(function(){var symbolFactory=getSymbolFactory(type),symbol=Symbol$1().type(symbolFactory).size(calculateAreaSize(size2,sizeType,type));return symbol()},"getPath"),className=props.className,cx2=props.cx,cy=props.cy,filteredProps=filterProps(props,!0);return cx2===+cx2&&cy===+cy&&size2===+size2?React.createElement("path",_extends$s({},filteredProps,{className:clsx("recharts-symbols",className),transform:"translate(".concat(cx2,", ").concat(cy,")"),d:getPath4()})):null},"Symbols");Symbols.registerSymbol=registerSymbol;function _typeof$I(o2){"@babel/helpers - typeof";return _typeof$I=typeof Symbol=="function"&&typeof Symbol.iterator=="symbol"?function(o3){return typeof o3}:function(o3){return o3&&typeof Symbol=="function"&&o3.constructor===Symbol&&o3!==Symbol.prototype?"symbol":typeof o3},_typeof$I(o2)}__name(_typeof$I,"_typeof$I");function _extends$r(){return _extends$r=Object.assign?Object.assign.bind():function(target){for(var i2=1;i2{titleId&&(document.getElementById(titleId)||console.error(MESSAGE))},[MESSAGE,titleId]),null},"TitleWarning"),DESCRIPTION_WARNING_NAME="DialogDescriptionWarning",DescriptionWarning=__name(({contentRef,descriptionId})=>{const MESSAGE=`Warning: Missing \`Description\` or \`aria-describedby={undefined}\` for {${useWarningContext(DESCRIPTION_WARNING_NAME).contentName}}.`;return reactExports.useEffect(()=>{const describedById=contentRef.current?.getAttribute("aria-describedby");descriptionId&&describedById&&(document.getElementById(descriptionId)||console.warn(MESSAGE))},[MESSAGE,contentRef,descriptionId]),null},"DescriptionWarning"),Root$6=Dialog,Trigger$4=DialogTrigger,Portal$1=DialogPortal,Overlay=DialogOverlay,Content$3=DialogContent,Title=DialogTitle,Description=DialogDescription,Close=DialogClose;const falsyToString=__name(value2=>typeof value2=="boolean"?`${value2}`:value2===0?"0":value2,"falsyToString"),cx=clsx,cva=__name((base,config2)=>props=>{var _config_compoundVariants;if(config2?.variants==null)return cx(base,props?.class,props?.className);const{variants,defaultVariants}=config2,getVariantClassNames=Object.keys(variants).map(variant=>{const variantProp=props?.[variant],defaultVariantProp=defaultVariants?.[variant];if(variantProp===null)return null;const variantKey=falsyToString(variantProp)||falsyToString(defaultVariantProp);return variants[variant][variantKey]}),propsWithoutUndefined=props&&Object.entries(props).reduce((acc,param)=>{let[key,value2]=param;return value2===void 0||(acc[key]=value2),acc},{}),getCompoundVariantClassNames=config2==null||(_config_compoundVariants=config2.compoundVariants)===null||_config_compoundVariants===void 0?void 0:_config_compoundVariants.reduce((acc,param)=>{let{class:cvClass,className:cvClassName,...compoundVariantOptions}=param;return Object.entries(compoundVariantOptions).every(param2=>{let[key,value2]=param2;return Array.isArray(value2)?value2.includes({...defaultVariants,...propsWithoutUndefined}[key]):{...defaultVariants,...propsWithoutUndefined}[key]===value2})?[...acc,cvClass,cvClassName]:acc},[]);return cx(base,getVariantClassNames,getCompoundVariantClassNames,props?.class,props?.className)},"cva");const toKebabCase=__name(string2=>string2.replace(/([a-z0-9])([A-Z])/g,"$1-$2").toLowerCase(),"toKebabCase"),mergeClasses=__name((...classes)=>classes.filter((className,index2,array2)=>!!className&&array2.indexOf(className)===index2).join(" "),"mergeClasses");var defaultAttributes={xmlns:"http://www.w3.org/2000/svg",width:24,height:24,viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:2,strokeLinecap:"round",strokeLinejoin:"round"};const Icon=reactExports.forwardRef(({color="currentColor",size:size2=24,strokeWidth=2,absoluteStrokeWidth,className="",children:children2,iconNode,...rest},ref)=>reactExports.createElement("svg",{ref,...defaultAttributes,width:size2,height:size2,stroke:color,strokeWidth:absoluteStrokeWidth?Number(strokeWidth)*24/Number(size2):strokeWidth,className:mergeClasses("lucide",className),...rest},[...iconNode.map(([tag,attrs])=>reactExports.createElement(tag,attrs)),...Array.isArray(children2)?children2:[children2]]));const createLucideIcon=__name((iconName,iconNode)=>{const Component=reactExports.forwardRef(({className,...props},ref)=>reactExports.createElement(Icon,{ref,iconNode,className:mergeClasses(`lucide-${toKebabCase(iconName)}`,className),...props}));return Component.displayName=`${iconName}`,Component},"createLucideIcon");const ArrowUpDown=createLucideIcon("ArrowUpDown",[["path",{d:"m21 16-4 4-4-4",key:"f6ql7i"}],["path",{d:"M17 20V4",key:"1ejh1v"}],["path",{d:"m3 8 4-4 4 4",key:"11wl7u"}],["path",{d:"M7 4v16",key:"1glfcx"}]]);const BadgeCheck=createLucideIcon("BadgeCheck",[["path",{d:"M3.85 8.62a4 4 0 0 1 4.78-4.77 4 4 0 0 1 6.74 0 4 4 0 0 1 4.78 4.78 4 4 0 0 1 0 6.74 4 4 0 0 1-4.77 4.78 4 4 0 0 1-6.75 0 4 4 0 0 1-4.78-4.77 4 4 0 0 1 0-6.76Z",key:"3c2336"}],["path",{d:"m9 12 2 2 4-4",key:"dzmm74"}]]);const Briefcase=createLucideIcon("Briefcase",[["path",{d:"M16 20V4a2 2 0 0 0-2-2h-4a2 2 0 0 0-2 2v16",key:"jecpp"}],["rect",{width:"20",height:"14",x:"2",y:"6",rx:"2",key:"i6l2r4"}]]);const Building2=createLucideIcon("Building2",[["path",{d:"M6 22V4a2 2 0 0 1 2-2h8a2 2 0 0 1 2 2v18Z",key:"1b4qmf"}],["path",{d:"M6 12H4a2 2 0 0 0-2 2v6a2 2 0 0 0 2 2h2",key:"i71pzd"}],["path",{d:"M18 9h2a2 2 0 0 1 2 2v9a2 2 0 0 1-2 2h-2",key:"10jefs"}],["path",{d:"M10 6h4",key:"1itunk"}],["path",{d:"M10 10h4",key:"tcdvrf"}],["path",{d:"M10 14h4",key:"kelpxr"}],["path",{d:"M10 18h4",key:"1ulq68"}]]);const Building=createLucideIcon("Building",[["rect",{width:"16",height:"20",x:"4",y:"2",rx:"2",ry:"2",key:"76otgf"}],["path",{d:"M9 22v-4h6v4",key:"r93iot"}],["path",{d:"M8 6h.01",key:"1dz90k"}],["path",{d:"M16 6h.01",key:"1x0f13"}],["path",{d:"M12 6h.01",key:"1vi96p"}],["path",{d:"M12 10h.01",key:"1nrarc"}],["path",{d:"M12 14h.01",key:"1etili"}],["path",{d:"M16 10h.01",key:"1m94wz"}],["path",{d:"M16 14h.01",key:"1gbofw"}],["path",{d:"M8 10h.01",key:"19clt8"}],["path",{d:"M8 14h.01",key:"6423bh"}]]);const ChartColumn=createLucideIcon("ChartColumn",[["path",{d:"M3 3v16a2 2 0 0 0 2 2h16",key:"c24i48"}],["path",{d:"M18 17V9",key:"2bz60n"}],["path",{d:"M13 17V5",key:"1frdt8"}],["path",{d:"M8 17v-3",key:"17ska0"}]]);const Check=createLucideIcon("Check",[["path",{d:"M20 6 9 17l-5-5",key:"1gmf2c"}]]);const ChevronDown=createLucideIcon("ChevronDown",[["path",{d:"m6 9 6 6 6-6",key:"qrunsl"}]]);const ChevronRight=createLucideIcon("ChevronRight",[["path",{d:"m9 18 6-6-6-6",key:"mthhwq"}]]);const CircleCheckBig=createLucideIcon("CircleCheckBig",[["path",{d:"M22 11.08V12a10 10 0 1 1-5.93-9.14",key:"g774vq"}],["path",{d:"m9 11 3 3L22 4",key:"1pflzl"}]]);const CircleCheck=createLucideIcon("CircleCheck",[["circle",{cx:"12",cy:"12",r:"10",key:"1mglay"}],["path",{d:"m9 12 2 2 4-4",key:"dzmm74"}]]);const Circle=createLucideIcon("Circle",[["circle",{cx:"12",cy:"12",r:"10",key:"1mglay"}]]);const Columns2=createLucideIcon("Columns2",[["rect",{width:"18",height:"18",x:"3",y:"3",rx:"2",key:"afitv7"}],["path",{d:"M12 3v18",key:"108xh3"}]]);const Eye=createLucideIcon("Eye",[["path",{d:"M2.062 12.348a1 1 0 0 1 0-.696 10.75 10.75 0 0 1 19.876 0 1 1 0 0 1 0 .696 10.75 10.75 0 0 1-19.876 0",key:"1nclc0"}],["circle",{cx:"12",cy:"12",r:"3",key:"1v7zrd"}]]);const Hash=createLucideIcon("Hash",[["line",{x1:"4",x2:"20",y1:"9",y2:"9",key:"4lhtct"}],["line",{x1:"4",x2:"20",y1:"15",y2:"15",key:"vyu0kd"}],["line",{x1:"10",x2:"8",y1:"3",y2:"21",key:"1ggp8o"}],["line",{x1:"16",x2:"14",y1:"3",y2:"21",key:"weycgp"}]]);const Info$1=createLucideIcon("Info",[["circle",{cx:"12",cy:"12",r:"10",key:"1mglay"}],["path",{d:"M12 16v-4",key:"1dtifu"}],["path",{d:"M12 8h.01",key:"e9boi3"}]]);const Layers3=createLucideIcon("Layers3",[["path",{d:"m12.83 2.18a2 2 0 0 0-1.66 0L2.6 6.08a1 1 0 0 0 0 1.83l8.58 3.91a2 2 0 0 0 1.66 0l8.58-3.9a1 1 0 0 0 0-1.83Z",key:"8b97xw"}],["path",{d:"m6.08 9.5-3.5 1.6a1 1 0 0 0 0 1.81l8.6 3.91a2 2 0 0 0 1.65 0l8.58-3.9a1 1 0 0 0 0-1.83l-3.5-1.59",key:"1e5n1m"}],["path",{d:"m6.08 14.5-3.5 1.6a1 1 0 0 0 0 1.81l8.6 3.91a2 2 0 0 0 1.65 0l8.58-3.9a1 1 0 0 0 0-1.83l-3.5-1.59",key:"1iwflc"}]]);const LoaderCircle=createLucideIcon("LoaderCircle",[["path",{d:"M21 12a9 9 0 1 1-6.219-8.56",key:"13zald"}]]);const Lock=createLucideIcon("Lock",[["rect",{width:"18",height:"11",x:"3",y:"11",rx:"2",ry:"2",key:"1w4ew1"}],["path",{d:"M7 11V7a5 5 0 0 1 10 0v4",key:"fwvmzm"}]]);const Luggage=createLucideIcon("Luggage",[["path",{d:"M6 20a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h12a2 2 0 0 1 2 2v10a2 2 0 0 1-2 2",key:"1m57jg"}],["path",{d:"M8 18V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v14",key:"1l99gc"}],["path",{d:"M10 20h4",key:"ni2waw"}],["circle",{cx:"16",cy:"20",r:"2",key:"1vifvg"}],["circle",{cx:"8",cy:"20",r:"2",key:"ckkr5m"}]]);const Maximize2=createLucideIcon("Maximize2",[["polyline",{points:"15 3 21 3 21 9",key:"mznyad"}],["polyline",{points:"9 21 3 21 3 15",key:"1avn1i"}],["line",{x1:"21",x2:"14",y1:"3",y2:"10",key:"ota7mn"}],["line",{x1:"3",x2:"10",y1:"21",y2:"14",key:"1atl0r"}]]);const Minimize2=createLucideIcon("Minimize2",[["polyline",{points:"4 14 10 14 10 20",key:"11kfnr"}],["polyline",{points:"20 10 14 10 14 4",key:"rlmsce"}],["line",{x1:"14",x2:"21",y1:"10",y2:"3",key:"o5lafz"}],["line",{x1:"3",x2:"10",y1:"21",y2:"14",key:"1atl0r"}]]);const MonitorSmartphone=createLucideIcon("MonitorSmartphone",[["path",{d:"M18 8V6a2 2 0 0 0-2-2H4a2 2 0 0 0-2 2v7a2 2 0 0 0 2 2h8",key:"10dyio"}],["path",{d:"M10 19v-3.96 3.15",key:"1irgej"}],["path",{d:"M7 19h5",key:"qswx4l"}],["rect",{width:"6",height:"10",x:"16",y:"12",rx:"2",key:"1egngj"}]]);const Monitor=createLucideIcon("Monitor",[["rect",{width:"20",height:"14",x:"2",y:"3",rx:"2",key:"48i651"}],["line",{x1:"8",x2:"16",y1:"21",y2:"21",key:"1svkeh"}],["line",{x1:"12",x2:"12",y1:"17",y2:"21",key:"vw1qmm"}]]);const OctagonX=createLucideIcon("OctagonX",[["path",{d:"m15 9-6 6",key:"1uzhvr"}],["path",{d:"M2.586 16.726A2 2 0 0 1 2 15.312V8.688a2 2 0 0 1 .586-1.414l4.688-4.688A2 2 0 0 1 8.688 2h6.624a2 2 0 0 1 1.414.586l4.688 4.688A2 2 0 0 1 22 8.688v6.624a2 2 0 0 1-.586 1.414l-4.688 4.688a2 2 0 0 1-1.414.586H8.688a2 2 0 0 1-1.414-.586z",key:"2d38gg"}],["path",{d:"m9 9 6 6",key:"z0biqf"}]]);const Settings=createLucideIcon("Settings",[["path",{d:"M12.22 2h-.44a2 2 0 0 0-2 2v.18a2 2 0 0 1-1 1.73l-.43.25a2 2 0 0 1-2 0l-.15-.08a2 2 0 0 0-2.73.73l-.22.38a2 2 0 0 0 .73 2.73l.15.1a2 2 0 0 1 1 1.72v.51a2 2 0 0 1-1 1.74l-.15.09a2 2 0 0 0-.73 2.73l.22.38a2 2 0 0 0 2.73.73l.15-.08a2 2 0 0 1 2 0l.43.25a2 2 0 0 1 1 1.73V20a2 2 0 0 0 2 2h.44a2 2 0 0 0 2-2v-.18a2 2 0 0 1 1-1.73l.43-.25a2 2 0 0 1 2 0l.15.08a2 2 0 0 0 2.73-.73l.22-.39a2 2 0 0 0-.73-2.73l-.15-.08a2 2 0 0 1-1-1.74v-.5a2 2 0 0 1 1-1.74l.15-.09a2 2 0 0 0 .73-2.73l-.22-.38a2 2 0 0 0-2.73-.73l-.15.08a2 2 0 0 1-2 0l-.43-.25a2 2 0 0 1-1-1.73V4a2 2 0 0 0-2-2z",key:"1qme2f"}],["circle",{cx:"12",cy:"12",r:"3",key:"1v7zrd"}]]);const ShieldCheck=createLucideIcon("ShieldCheck",[["path",{d:"M20 13c0 5-3.5 7.5-7.66 8.95a1 1 0 0 1-.67-.01C7.5 20.5 4 18 4 13V6a1 1 0 0 1 1-1c2 0 4.5-1.2 6.24-2.72a1.17 1.17 0 0 1 1.52 0C14.51 3.81 17 5 19 5a1 1 0 0 1 1 1z",key:"oel41y"}],["path",{d:"m9 12 2 2 4-4",key:"dzmm74"}]]);const Shield=createLucideIcon("Shield",[["path",{d:"M20 13c0 5-3.5 7.5-7.66 8.95a1 1 0 0 1-.67-.01C7.5 20.5 4 18 4 13V6a1 1 0 0 1 1-1c2 0 4.5-1.2 6.24-2.72a1.17 1.17 0 0 1 1.52 0C14.51 3.81 17 5 19 5a1 1 0 0 1 1 1z",key:"oel41y"}]]);const TriangleAlert=createLucideIcon("TriangleAlert",[["path",{d:"m21.73 18-8-14a2 2 0 0 0-3.48 0l-8 14A2 2 0 0 0 4 21h16a2 2 0 0 0 1.73-3",key:"wmoenq"}],["path",{d:"M12 9v4",key:"juzpu7"}],["path",{d:"M12 17h.01",key:"p32p05"}]]);const UserCog=createLucideIcon("UserCog",[["circle",{cx:"18",cy:"15",r:"3",key:"gjjjvw"}],["circle",{cx:"9",cy:"7",r:"4",key:"nufk8"}],["path",{d:"M10 15H6a4 4 0 0 0-4 4v2",key:"1nfge6"}],["path",{d:"m21.7 16.4-.9-.3",key:"12j9ji"}],["path",{d:"m15.2 13.9-.9-.3",key:"1fdjdi"}],["path",{d:"m16.6 18.7.3-.9",key:"heedtr"}],["path",{d:"m19.1 12.2.3-.9",key:"1af3ki"}],["path",{d:"m19.6 18.7-.4-1",key:"1x9vze"}],["path",{d:"m16.8 12.3-.4-1",key:"vqeiwj"}],["path",{d:"m14.3 16.6 1-.4",key:"1qlj63"}],["path",{d:"m20.7 13.8 1-.4",key:"1v5t8k"}]]);const User=createLucideIcon("User",[["path",{d:"M19 21v-2a4 4 0 0 0-4-4H9a4 4 0 0 0-4 4v2",key:"975kel"}],["circle",{cx:"12",cy:"7",r:"4",key:"17ys0d"}]]);const Users=createLucideIcon("Users",[["path",{d:"M16 21v-2a4 4 0 0 0-4-4H6a4 4 0 0 0-4 4v2",key:"1yyitq"}],["circle",{cx:"9",cy:"7",r:"4",key:"nufk8"}],["path",{d:"M22 21v-2a4 4 0 0 0-3-3.87",key:"kshegd"}],["path",{d:"M16 3.13a4 4 0 0 1 0 7.75",key:"1da9ce"}]]);const Wrench=createLucideIcon("Wrench",[["path",{d:"M14.7 6.3a1 1 0 0 0 0 1.4l1.6 1.6a1 1 0 0 0 1.4 0l3.77-3.77a6 6 0 0 1-7.94 7.94l-6.91 6.91a2.12 2.12 0 0 1-3-3l6.91-6.91a6 6 0 0 1 7.94-7.94l-3.76 3.76z",key:"cbrjhi"}]]);const X$3=createLucideIcon("X",[["path",{d:"M18 6 6 18",key:"1bl5f8"}],["path",{d:"m6 6 12 12",key:"d8bk6v"}]]);const Zap=createLucideIcon("Zap",[["path",{d:"M4 14a1 1 0 0 1-.78-1.63l9.9-10.2a.5.5 0 0 1 .86.46l-1.92 6.02A1 1 0 0 0 13 10h7a1 1 0 0 1 .78 1.63l-9.9 10.2a.5.5 0 0 1-.86-.46l1.92-6.02A1 1 0 0 0 11 14z",key:"1xq2db"}]]),Sheet=Root$6,SheetTrigger=Trigger$4,SheetPortal=Portal$1,SheetOverlay=reactExports.forwardRef(({className,...props},ref)=>jsxRuntimeExports.jsx(Overlay,{className:cn$2("fixed inset-0 z-50 bg-black/80 data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0",className),...props,ref}));SheetOverlay.displayName=Overlay.displayName;const sheetVariants=cva("fixed z-50 gap-4 bg-background p-6 shadow-lg transition ease-in-out data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:duration-300 data-[state=open]:duration-500",{variants:{side:{top:"inset-x-0 top-0 border-b data-[state=closed]:slide-out-to-top data-[state=open]:slide-in-from-top",bottom:"inset-x-0 bottom-0 border-t data-[state=closed]:slide-out-to-bottom data-[state=open]:slide-in-from-bottom",left:"inset-y-0 left-0 h-full w-3/4 border-r data-[state=closed]:slide-out-to-left data-[state=open]:slide-in-from-left sm:max-w-sm",right:"inset-y-0 right-0 h-full w-3/4 border-l data-[state=closed]:slide-out-to-right data-[state=open]:slide-in-from-right sm:max-w-sm"}},defaultVariants:{side:"right"}}),SheetContent=reactExports.forwardRef(({side="right",className,children:children2,allowMaximize=!1,...props},ref)=>{const[isMaximized,setIsMaximized]=reactExports.useState(!1),toggleMaximize=__name(()=>setIsMaximized(!isMaximized),"toggleMaximize");return jsxRuntimeExports.jsxs(SheetPortal,{children:[jsxRuntimeExports.jsx(SheetOverlay,{}),jsxRuntimeExports.jsxs(Content$3,{ref,className:cn$2(sheetVariants({side}),isMaximized&&side==="right"||isMaximized&&side==="left"?"!w-full !max-w-full":"",className),...props,children:[children2,jsxRuntimeExports.jsxs("div",{className:"absolute right-4 top-4 flex gap-2",children:[allowMaximize&&jsxRuntimeExports.jsxs("button",{onClick:toggleMaximize,className:"rounded-sm opacity-70 ring-offset-background transition-opacity hover:opacity-100 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 disabled:pointer-events-none data-[state=open]:bg-secondary",children:[isMaximized?jsxRuntimeExports.jsx(Minimize2,{className:"h-4 w-4"}):jsxRuntimeExports.jsx(Maximize2,{className:"h-4 w-4"}),jsxRuntimeExports.jsx("span",{className:"sr-only",children:isMaximized?"Minimize":"Maximize"})]}),jsxRuntimeExports.jsxs(Close,{className:"rounded-sm opacity-70 ring-offset-background transition-opacity hover:opacity-100 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 disabled:pointer-events-none data-[state=open]:bg-secondary",children:[jsxRuntimeExports.jsx(X$3,{className:"h-4 w-4"}),jsxRuntimeExports.jsx("span",{className:"sr-only",children:"Close"})]})]})]})]})});SheetContent.displayName=Content$3.displayName;const SheetHeader=__name(({className,...props})=>jsxRuntimeExports.jsx("div",{className:cn$2("flex flex-col space-y-2 text-center sm:text-left",className),...props}),"SheetHeader");SheetHeader.displayName="SheetHeader";const SheetTitle=reactExports.forwardRef(({className,...props},ref)=>jsxRuntimeExports.jsx(Title,{ref,className:cn$2("text-lg font-semibold text-foreground",className),...props}));SheetTitle.displayName=Title.displayName;const SheetDescription=reactExports.forwardRef(({className,...props},ref)=>jsxRuntimeExports.jsx(Description,{ref,className:cn$2("text-sm text-muted-foreground",className),...props}));SheetDescription.displayName=Description.displayName;const Icons={logo:__name(props=>jsxRuntimeExports.jsxs("svg",{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 18 18",...props,children:[jsxRuntimeExports.jsx("path",{"fill-rule":"evenodd","clip-rule":"evenodd",fill:"#F35123",d:"M0 0h7v7h-7z"}),jsxRuntimeExports.jsx("path",{"fill-rule":"evenodd","clip-rule":"evenodd",fill:"#01A4EF",d:"M0 9h7v7h-7z"}),jsxRuntimeExports.jsx("path",{"fill-rule":"evenodd","clip-rule":"evenodd",fill:"#7FBA00",d:"M9 0h7v7h-7z"}),jsxRuntimeExports.jsx("path",{"fill-rule":"evenodd","clip-rule":"evenodd",fill:"#FFB901",d:"M9 9h7v7h-7z"})]}),"logo"),gitHub:__name(props=>jsxRuntimeExports.jsx("svg",{viewBox:"0 0 438.549 438.549",...props,children:jsxRuntimeExports.jsx("path",{fill:"currentColor",d:"M409.132 114.573c-19.608-33.596-46.205-60.194-79.798-79.8-33.598-19.607-70.277-29.408-110.063-29.408-39.781 0-76.472 9.804-110.063 29.408-33.596 19.605-60.192 46.204-79.8 79.8C9.803 148.168 0 184.854 0 224.63c0 47.78 13.94 90.745 41.827 128.906 27.884 38.164 63.906 64.572 108.063 79.227 5.14.954 8.945.283 11.419-1.996 2.475-2.282 3.711-5.14 3.711-8.562 0-.571-.049-5.708-.144-15.417a2549.81 2549.81 0 01-.144-25.406l-6.567 1.136c-4.187.767-9.469 1.092-15.846 1-6.374-.089-12.991-.757-19.842-1.999-6.854-1.231-13.229-4.086-19.13-8.559-5.898-4.473-10.085-10.328-12.56-17.556l-2.855-6.57c-1.903-4.374-4.899-9.233-8.992-14.559-4.093-5.331-8.232-8.945-12.419-10.848l-1.999-1.431c-1.332-.951-2.568-2.098-3.711-3.429-1.142-1.331-1.997-2.663-2.568-3.997-.572-1.335-.098-2.43 1.427-3.289 1.525-.859 4.281-1.276 8.28-1.276l5.708.853c3.807.763 8.516 3.042 14.133 6.851 5.614 3.806 10.229 8.754 13.846 14.842 4.38 7.806 9.657 13.754 15.846 17.847 6.184 4.093 12.419 6.136 18.699 6.136 6.28 0 11.704-.476 16.274-1.423 4.565-.952 8.848-2.383 12.847-4.285 1.713-12.758 6.377-22.559 13.988-29.41-10.848-1.14-20.601-2.857-29.264-5.14-8.658-2.286-17.605-5.996-26.835-11.14-9.235-5.137-16.896-11.516-22.985-19.126-6.09-7.614-11.088-17.61-14.987-29.979-3.901-12.374-5.852-26.648-5.852-42.826 0-23.035 7.52-42.637 22.557-58.817-7.044-17.318-6.379-36.732 1.997-58.24 5.52-1.715 13.706-.428 24.554 3.853 10.85 4.283 18.794 7.952 23.84 10.994 5.046 3.041 9.089 5.618 12.135 7.708 17.705-4.947 35.976-7.421 54.818-7.421s37.117 2.474 54.823 7.421l10.849-6.849c7.419-4.57 16.18-8.758 26.262-12.565 10.088-3.805 17.802-4.853 23.134-3.138 8.562 21.509 9.325 40.922 2.279 58.24 15.036 16.18 22.559 35.787 22.559 58.817 0 16.178-1.958 30.497-5.853 42.966-3.9 12.471-8.941 22.457-15.125 29.979-6.191 7.521-13.901 13.85-23.131 18.986-9.232 5.14-18.182 8.85-26.84 11.136-8.662 2.286-18.415 4.004-29.263 5.146 9.894 8.562 14.842 22.077 14.842 40.539v60.237c0 3.422 1.19 6.279 3.572 8.562 2.379 2.279 6.136 2.95 11.276 1.995 44.163-14.653 80.185-41.062 108.068-79.226 27.88-38.161 41.825-81.126 41.825-128.906-.01-39.771-9.818-76.454-29.414-110.049z"})}),"gitHub")},ztAppConfig={name:"Zero Trust Assessment",github:{title:"GitHub",url:"https://github.com/microsoft/zerotrustassessment"}},reportData= {"ExecutedAt":"2026-05-19T00:21:38.163451+02:00","TenantId":"aaaabbbb-0000-cccc-1111-dddd2222eeee","TenantName":"Contoso","Domain":"contoso.com","Account":"admin@contoso.com","CurrentVersion":"2.1.8","LatestVersion":"2.2.0","TestResultSummary":{"IdentityPassed":85,"IdentityTotal":100,"DevicesPassed":25,"DevicesTotal":36,"NetworkPassed":34,"NetworkTotal":64,"DataPassed":24,"DataTotal":34,"InfrastructurePassed":7,"InfrastructureTotal":13,"SecOpsPassed":0,"SecOpsTotal":0,"AIPassed":5,"AITotal":14},"Tests":[{"TestImpact":"Low","TestRisk":"Medium","TestSkipped":"","TestAppliesTo":null,"TestPillar":"Data","TestCategory":"Information Protection","TestDescription":"Autolabeling policies only classify new and modified content. Existing files and emails remain unclassified and invisible to DLP policies that depend on label detection. On-demand scans let you manually trigger sensitive information type detection across specified locations to discover and retroactively classify historical content, giving you a complete view of your information protection posture rather than forward-looking coverage.\n\n**Remediation action**\n\n- [On-demand classification in Microsoft Purview](https://learn.microsoft.com/purview/on-demand-classification?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci)\n","TestTitle":"On-Demand scans configured for sensitive information discovery","SkippedReason":null,"TestId":"35022","TestImplementationCost":"Medium","TestMinimumLicense":["EXCHANGE_S_ENTERPRISE"],"TestSfiPillar":"Protect tenants and production systems","TestResult":"\n✅ At least one on-demand scan is configured in the organization, enabling discovery and classification of historical sensitive information.\n\n### On-Demand scan configuration summary\n\n**Scan details:**\n\n| Name | Sensitive information scan status | Workload | Sensitive information types detected | When created UTC | Last scan start time|\n|------|--------|----------|--------------|---------------|-----------------|\n| Test exchange | ImpactAssessmentCancelled | Exchange, SharePoint, OneDriveForBusiness, EndpointDevices | None | 2026-09-01 | |\n| Purview_35022_test | ClassificationComplete | Exchange, SharePoint, OneDriveForBusiness | None | 2026-04-02 | 2026-04-02 |\n| Item search | ClassificationInProgress | Exchange, SharePoint, OneDriveForBusiness | None | 2026-04-02 | 2026-04-02 |\n| Purview_35022 | ImpactAssessmentComplete | Exchange, SharePoint, OneDriveForBusiness | None | 01/27/2026 06:40:53 | |\n\n**Summary:**\n\n* **Total on-demand scans configured:** 4\n* **Scans by status:**\n * ClassificationComplete: 1\n * ClassificationInProgress: 1\n * ImpactAssessmentCancelled: 1\n * ImpactAssessmentComplete: 1\n* **Locations scanned:**\n * SharePoint: Yes\n * OneDrive: Yes\n * Exchange: Yes\n* **Most recent scan completion:** 02/04/2026 14:13:01\n\n[Microsoft Purview Portal > Information Protection > Classifiers > On-demand classification](https://purview.microsoft.com/informationprotection/dataclassification/colddatascans)\nor\n[Microsoft Purview Portal > Data Loss Prevention > Classifiers > On-demand classification](https://purview.microsoft.com/datalossprevention/dataclassification/colddatascans)\n\n\n","TestStatus":"Passed","TestTags":null},{"TestImpact":"Low","TestRisk":"Medium","TestSkipped":"NotConnectedToService","TestAppliesTo":null,"TestPillar":"Data","TestCategory":"SharePoint Online","TestDescription":"When you configure SharePoint with a default label for document libraries, any new files uploaded to that library, or existing files edited in the library will have that label applied if they don't already have a sensitivity label, or they have a sensitivity label but with lower priority. This location-based labeling offers a baseline level of protection and a form of automatic labeling without content inspection. When files aren't labeled, important files can bypass protection and remain vulnerable.\n\nThis configuration is most suitable for document libraries that contain files with the same level of sensitivity. It can be supplemented with auto-labeling policies that uses content inspection, and manual labeling with a higher priority sensitivity label if needed.\n\n**Remediation action**\n\n- [Configure a default sensitivity label for a SharePoint document library](https://learn.microsoft.com/purview/sensitivity-labels-sharepoint-default-label?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci)\n","TestTitle":"Default sensitivity labels are configured for SharePoint document libraries","SkippedReason":"This test requires connection to the service(s) \"SharePointOnline\" currently disconnected. Please use _Connect-ZtAssessment_ to connect.","TestId":"35008","TestImplementationCost":"Low","TestMinimumLicense":["RMS_S_PREMIUM2"],"TestSfiPillar":"Protect tenants and production systems","TestResult":"\nSkipped. This test requires connection to the service(s) \"SharePointOnline\" currently disconnected. Please use _Connect-ZtAssessment_ to connect.\n\n","TestStatus":"Skipped","TestTags":null},{"TestImplementationCost":"","TestPillar":"Infrastructure","TestCategory":"Manage access and permissions","SkippedReason":null,"TestImpact":"","TestAppliesTo":null,"TestSfiPillar":"Protect tenants and isolate production systems","TestSkipped":"","TestMinimumLicense":"N/A","TestTags":null,"TestTitle":"Disabled accounts with owner permissions on Azure resources should be removed","TestRisk":"High","TestResult":"Disabled accounts with owner permissions on Azure resources should be removed\n\n| Subscription | Affected resource | Status | Azure portal |\n| :----------- | :---------------- | :----- | :----------- |\n| [Visual Studio Enterprise Subscription](https://portal.azure.com/#resource/subscriptions/54d3ea01-5a07-45d0-8d69-e5f5b0b20098) | [54d3ea01-5a07-45d0-8d69-e5f5b0b20098](https://portal.azure.com/#resource/subscriptions/54d3ea01-5a07-45d0-8d69-e5f5b0b20098) | ✅ | [View recommendation](https://portal.azure.com/#blade/Microsoft_Azure_Security/RecommendationsBlade/assessmentKey/050ac097-3dda-4d24-ab6d-82568e7a50cf/resourceId/%2fsubscriptions%2f54d3ea01-5a07-45d0-8d69-e5f5b0b20098) |\n","TestStatus":"Passed","TestDescription":"It's important to remove accounts that have been disabled from signing in on Active Directory from your Azure resources.
These disabled accounts, especially those with owner permissions, can become targets for attackers.
If these accounts are compromised, attackers could gain unnoticed access to your data.
Therefore, to maintain a secure environment, we recommend removing these accounts from Azure resources..
\n\n**Remediation action**\n\nReview the list of accounts that are disabled from signing in on the Accounts section. Select an account to view its role definitions and locate the source scope. If you accept the risk for specific account, use the exempt capability to exclude it from evaluation.
  1. Go to the Azure portal.
  2. Open Access control (IAM) at a scope, such as management group, subscription, resource group, or resource, where the guest user has a role assignment.
  3. Click the Role assignments tab to view all the role assignments.
  4. In the list of role assignments, add a checkmark next to the disabled user with the role assignment you want to remove.
  5. Click Remove. In the remove role assignment message that appears, click Yes.
","TestId":"050ac097-3dda-4d24-ab6d-82568e7a50cf"},{"TestImplementationCost":"Low","TestPillar":"Identity","TestCategory":"Application management","SkippedReason":null,"TestImpact":"Low","TestAppliesTo":["Identity"],"TestSfiPillar":"Protect engineering systems","TestSkipped":"","TestMinimumLicense":"P1","TestTags":["Identity"],"TestTitle":"App registrations must not have dangling or abandoned domain redirect URIs","TestRisk":"High","TestResult":"\nUnsafe redirect URIs found\n\n1️⃣ → Use of http(s) instead of https, 2️⃣ → Use of *.azurewebsites.net, 3️⃣ → Invalid URL, 4️⃣ → Domain not resolved\n\n| | Name | Unsafe redirect URIs |\n| :--- | :--- | :--- |\n| | [21869testapp](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/SignOn/objectId/e69e29be-ba40-445a-9824-a3a45e0ae57a/appId/dd63d132-18fb-4f2e-aec4-82b97f30301f/preferredSingleSignOnMode/saml/servicePrincipalType/Application/fromNav/) | `4️⃣ https://testapp.local/callback` | |\n| | [Contoso Access Verifier](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/SignOn/objectId/41d3b041-9859-4830-8feb-72ffd7afad65/appId/a6af3433-bc44-4d27-9b35-81d10fd51315/preferredSingleSignOnMode/saml/servicePrincipalType/Application/fromNav/) | `4️⃣ https://demoeam2025.blob.core.windows.net/data/index.html` | |\n| | [My nice app](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/SignOn/objectId/d41cfc13-11d1-4f93-835a-88e729725564/appId/2946f286-2b59-4f29-876c-0ed8bbe1c482/preferredSingleSignOnMode/saml/servicePrincipalType/Application/fromNav/) | `4️⃣ https://mysalmon.azurewebsites.net/login.saml` | |\n| | [ServiceNow](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/SignOn/objectId/9a8af246-0d94-42eb-aaaf-836a9f9a4974/appId/ecbbb1c8-ef06-48c4-9211-9ffbfbc24b94/preferredSingleSignOnMode/saml/servicePrincipalType/Application/fromNav/) | `4️⃣ https://dev92989.service-now.com/navpage.do` | |\n| | [aad-extensions-app. Do not modify. Used by AAD for storing user data.](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/SignOn/objectId/b5277031-31cb-4a88-b5a1-316878166f55/appId/d211b2a1-0c5e-4be8-a40a-46033a0b6df2/preferredSingleSignOnMode/saml/servicePrincipalType/Application/fromNav/) | `4️⃣ https://contoso.onmicrosoft.com/cpimextensions` | |\n| | [saml test app](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/SignOn/objectId/daa6074c-db6f-4bdc-a41b-bc0052c536a5/appId/c266d677-a5f8-47bc-9f0a-1b6fbe0bddad/preferredSingleSignOnMode/saml/servicePrincipalType/Application/fromNav/) | `4️⃣ https://appclaims.azurewebsites.net/signin-saml`, `4️⃣ https://appclaims.azurewebsites.net/signin-oidc` | |\n\n\n","TestStatus":"Failed","TestDescription":"Unmaintained or orphaned redirect URIs in app registrations create significant security vulnerabilities when they reference domains that no longer point to active resources. Threat actors can exploit these \"dangling\" DNS entries by provisioning resources at abandoned domains, effectively taking control of redirect endpoints. This vulnerability enables attackers to intercept authentication tokens and credentials during OAuth 2.0 flows, which can lead to unauthorized access, session hijacking, and potential broader organizational compromise.\n\n**Remediation action**\n\n- [Redirect URI (reply URL) outline and restrictions](https://learn.microsoft.com/entra/identity-platform/reply-url?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci)\n","TestId":"21888"},{"TestImplementationCost":"Low","TestPillar":"Identity","TestCategory":"Application management","SkippedReason":null,"TestImpact":"Low","TestAppliesTo":["Identity"],"TestSfiPillar":"Protect tenants and isolate production systems","TestSkipped":"","TestMinimumLicense":"Free","TestTags":["Identity"],"TestTitle":"Guests are not assigned high privileged directory roles","TestRisk":"High","TestResult":"\nGuests with privileged roles were detected.\n\n\n## Guests with privileged roles\n\n\n| Role Name | User Name | User Principal Name | User Type | Assignment Type |\n| :-------- | :-------- | :------------------ | :-------- | :-------------- |\n| Application Administrator | [Riley Martinez](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/overview/userId/653c7fdd-1b41-4229-992a-69cc35aad4f7/hidePreviewBanner~/true) | riley@contoso.onmicrosoft.com | Guest | Eligible |\n| Global Administrator | [Dakota Lee](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/overview/userId/210d3e96-015f-462d-b6d6-81e6023263df/hidePreviewBanner~/true) | guest-user_external.com#EXT#@contoso.com | Guest | Permanent |\n\n\n\n","TestStatus":"Failed","TestDescription":"When guest users are assigned highly privileged directory roles such as Global Administrator or Privileged Role Administrator, organizations create significant security vulnerabilities that threat actors can exploit for initial access through compromised external accounts or business partner environments. Since guest users originate from external organizations without direct control of security policies, threat actors who compromise these external identities can gain privileged access to the target organization's Microsoft Entra tenant.\n\nWhen threat actors obtain access through compromised guest accounts with elevated privileges, they can escalate their own privilege to create other backdoor accounts, modify security policies, or assign themselves permanent roles within the organization. The compromised privileged guest accounts enable threat actors to establish persistence and then make all the changes they need to remain undetected. For example they could create cloud-only accounts, bypass Conditional Access policies applied to internal users, and maintain access even after the guest's home organization detects the compromise. Threat actors can then conduct lateral movement using administrative privileges to access sensitive resources, modify audit settings, or disable security monitoring across the entire tenant. Threat actors can reach complete compromise of the organization's identity infrastructure while maintaining plausible deniability through the external guest account origin. \n\n**Remediation action**\n\n- [Remove Guest users from privileged roles](https://learn.microsoft.com/entra/identity/role-based-access-control/best-practices?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci)\n","TestId":"22128"},{"TestImplementationCost":"High","TestPillar":"Identity","TestCategory":"Application management","SkippedReason":null,"TestImpact":"Low","TestAppliesTo":["Identity"],"TestSfiPillar":"Protect engineering systems","TestSkipped":"","TestMinimumLicense":"P1","TestTags":["Identity"],"TestTitle":"Service principals use safe redirect URIs","TestRisk":"High","TestResult":"\nUnsafe redirect URIs found\n\n1️⃣ → Use of http(s) instead of https, 2️⃣ → Use of *.azurewebsites.net, 3️⃣ → Invalid URL, 4️⃣ → Domain not resolved\n\n| | Name | Unsafe redirect URIs |App owner tenant |\n| :--- | :--- | :--- | :--- |\n| | [EAM Demo](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/Overview/objectId/24b12ae7-4648-4aae-b00c-6349a565d24c/appId/e6e0be31-7040-4084-ac44-600b67661f2c) | `2️⃣ https://eamdemo.azurewebsites.net` | 1852b10f-a011-428b-98f9-d09c37d477cf |\n| | [FIDO2-passkeys-MFA](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/Overview/objectId/1aa7e155-cbf8-4970-8458-05a0c7a2d1a5/appId/4fabcfc0-5c44-45a1-8c80-8537f0625949) | `2️⃣ https://fidomfaserver.azurewebsites.net/connect/authorize` | 1852b10f-a011-428b-98f9-d09c37d477cf |\n| | [Graph Explorer](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/Overview/objectId/8f8f300a-870a-46ff-bdab-934e1436920d/appId/d3ce4cf8-6810-442d-b42e-375e14710095) | `2️⃣ https://graphexplorer.azurewebsites.net/` | 5508eaf2-e7b4-4510-a4fb-9f5970550d80 |\n| | [Graph explorer (official site)](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/Overview/objectId/cd2e9b58-eb21-4a50-a338-33f9daa1599c/appId/de8bc8b5-d9f9-48b1-a8ad-b748da725064) | `2️⃣ https://graphtryit.azurewebsites.net`, `2️⃣ https://graphtryit.azurewebsites.net/` | 72f988bf-86f1-41af-91ab-2d7cd011db47 |\n| | [Internal_AccessScope](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/Overview/objectId/180a3ccb-3f2f-486f-8b56-025fc225166d/appId/3f9bd1ee-5a72-4ad3-b67d-cb016f935bcf) | `1️⃣ http://featureconfiguration.onmicrosoft.com/Internal_AccessScope` | 0d2db716-b331-4d7b-aa37-7f1ac9d35dae |\n| | [Modern Workplace Concierge](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/Overview/objectId/ad1c51e8-f8a8-4bf2-ac09-a3a20cba5fa5/appId/c65c4011-1b90-4ec9-b5e9-1ee17786ad84) | `2️⃣ https://mwconcierge.azurewebsites.net/` | 7955e1b3-cbad-49eb-9a84-e14aed7f3400 |\n| | [entraChatAppMultiTenant](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/Overview/objectId/855a57ff-88a6-4ad0-85d7-4f46d742730e/appId/5e00b345-a805-42a0-9caa-7d6cb761c668) | `2️⃣ https://entrachatapp.azurewebsites.net`, `2️⃣ https://entrachatapp.azurewebsites.net/redirect` | 8b047ec6-6d2e-481d-acfa-5d562c09f49a |\n\n\n","TestStatus":"Failed","TestDescription":"Non-Microsoft and multitenant applications configured with URLs that include wildcards, localhost, or URL shorteners increase the attack surface for threat actors. These insecure redirect URIs (reply URLs) might allow adversaries to manipulate authentication requests, hijack authorization codes, and intercept tokens by directing users to attacker-controlled endpoints. Wildcard entries expand the risk by permitting unintended domains to process authentication responses, while localhost and shortener URLs might facilitate phishing and token theft in uncontrolled environments.\n\nWithout strict validation of redirect URIs, attackers can bypass security controls, impersonate legitimate applications, and escalate their privileges. This misconfiguration enables persistence, unauthorized access, and lateral movement, as adversaries exploit weak OAuth enforcement to infiltrate protected resources undetected.\n\n**Remediation action**\n\n- [Check the redirect URIs for your application registrations.](https://learn.microsoft.com/entra/identity-platform/reply-url?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci) Make sure the redirect URIs don't have localhost, *.azurewebsites.net, wildcards, or URL shorteners.\n","TestId":"23183"},{"TestImplementationCost":"High","TestPillar":"Identity","TestCategory":"Application management","SkippedReason":null,"TestImpact":"Low","TestAppliesTo":null,"TestSfiPillar":"Protect identities and secrets","TestSkipped":"","TestMinimumLicense":"Free","TestTags":null,"TestTitle":"No usage of ADAL in the tenant","TestRisk":"Medium","TestResult":"\nNo ADAL applications found in the tenant.\n\n","TestStatus":"Passed","TestDescription":"Microsoft ended support and security fixes for ADAL on June 30, 2023. Continued ADAL usage bypasses modern security protections available only in MSAL, including Conditional Access enforcement, Continuous Access Evaluation (CAE), and advanced token protection. ADAL applications create security vulnerabilities by using weaker legacy authentication patterns, often calling deprecated Azure AD Graph endpoints, and preventing adoption of hardened authentication flows that could mitigate future security advisories. \n\n**Remediation action**\n\n- [Migrate applications to the Microsoft Authentication Library (MSAL)](https://learn.microsoft.com/entra/identity-platform/msal-migration?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci)\n","TestId":"21780"},{"TestImplementationCost":"Medium","TestPillar":"Identity","TestCategory":"Access control","SkippedReason":"UnderConstruction","TestImpact":"Low","TestAppliesTo":["Identity"],"TestSfiPillar":"Protect identities and secrets","TestSkipped":"UnderConstruction","TestMinimumLicense":null,"TestTags":["Identity"],"TestTitle":"All registered redirect URIs must have proper DNS records and ownerships","TestRisk":"Medium","TestResult":"\nPlanned for future release.\n","TestStatus":"Planned","TestDescription":"...\n\n**Remediation action**\n\n","TestId":"21887"},{"TestImplementationCost":"Low","TestPillar":"Identity","TestCategory":"Access control","SkippedReason":"UnderConstruction","TestImpact":"Low","TestAppliesTo":["Identity"],"TestSfiPillar":"Protect identities and secrets","TestSkipped":"UnderConstruction","TestMinimumLicense":"P1","TestTags":["Identity"],"TestTitle":"All groups in Conditional Access policies belong to a restricted management administrative unit","TestRisk":"Medium","TestResult":"\nPlanned for future release.\n","TestStatus":"Planned","TestDescription":"...\n\n**Remediation action**\n\n","TestId":"21832"},{"TestImpact":"Low","TestRisk":"High","TestSkipped":"","TestAppliesTo":null,"TestPillar":"Data","TestCategory":"Information Protection","TestDescription":"Auto-labeling greatly extends your labeling reach, by automatically labeling items based on content inspection. When you rely on just manual labeling, users might not always recognize what counts as sensitive data or might forget to label information during their daily tasks. Default labels offer a baseline of protection but don't take into consideration content that requires a higher level of protection. This leads to gaps in classification, allowing sensitive content to move through Microsoft 365 applications without proper labels or protection.\n\nYou can configure auto-labeling settings for labels that trigger when users open files in their Office apps, and auto-labeling policies that require no user interactions. Setting up at least one auto-labeling policy to detect sensitive content automatically labels this content, no matter what actions people take. In turn, this labeled content can be used with other Microsoft Purview solutions to increase your security, such as data loss prevention (DLP) rules and access restrictions.\n\n**Remediation action**\n\n- [Automatically apply a sensitivity label to Microsoft 365 data](https://learn.microsoft.com/purview/apply-sensitivity-label-automatically?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci)\n","TestTitle":"Auto-Labeling Policies Configured (All Workloads)","SkippedReason":null,"TestId":"35019","TestImplementationCost":"Medium","TestMinimumLicense":["EXCHANGE_S_ENTERPRISE"],"TestSfiPillar":"Protect tenants and production systems","TestResult":"\n✅ 2 auto-labeling policies exist in the organization, enabling automatic content classification.\n\n### [Auto-Labeling Policies](https://purview.microsoft.com/informationprotection/autolabeling)\n\n| Policy Name | Description | Enabled | Mode | Workload | Created | Last Modified |\n| :--- | :--- | :---: | :--- | :--- | :--- | :--- |\n| Japan Financial Data | | ✅ | TestWithoutNotifications | Exchange, SharePoint, OneDriveForBusiness, Applications, Azure, AWS | 2026-02-05 | 2026-02-05 |\n| U.S. Patriot Act Enhanced | | ✅ | TestWithoutNotifications | Exchange, SharePoint, OneDriveForBusiness, Applications, Azure, AWS | 2026-02-05 | 2026-02-06 |\n\n### Summary\n\n* **Total Auto-Labeling Policies:** 2\n\n**Workloads with Auto-Labeling Policies:**\n* Exchange/Outlook: [Yes]\n* SharePoint: [Yes]\n* OneDrive: [Yes]\n* Teams: [No]\n* Power BI: [No]\n\n* **Policy Creation Date Range:** 2026-02-05 to 2026-02-05\n\n💡 **Note:** This test validates policy existence only. Test 35020 validates that at least one policy is in enforcement mode.\n\n\n","TestStatus":"Passed","TestTags":null},{"TestImplementationCost":"Low","TestPillar":"Identity","TestCategory":"Access control","SkippedReason":null,"TestImpact":"Medium","TestAppliesTo":["Identity"],"TestSfiPillar":"Protect identities and secrets","TestSkipped":"","TestMinimumLicense":"P1","TestTags":["ConditionalAccess"],"TestTitle":"Restrict device code flow","TestRisk":"High","TestResult":"\nDevice code flow is properly restricted in the tenant.\n## Conditional Access Policies targeting Device Code Flow\n\n| Policy Name | Status | Target Users | Target Resources | Grant Controls |\n| :---------- | :----- | :----------- | :--------------- | :------------ |\n| [Block Device Code](https://entra.microsoft.com/#view/Microsoft_AAD_ConditionalAccess/PolicyBlade/policyId/db2153a1-40a2-457f-917c-c280b204b5cd) | Enabled | All Users, Excluded: 8 users/groups | All Applications | Block (ANY) |\n\n## Inactive Conditional Access Policies targeting Device Code Flow\nThese policies are not contributing to your security posture because they are not enabled:\n\n| Policy Name | Status | Target Users | Target Resources | Grant Controls |\n| :---------- | :----- | :----------- | :--------------- | :------------ |\n| [Block DCF](https://entra.microsoft.com/#view/Microsoft_AAD_ConditionalAccess/PolicyBlade/policyId/b5ff217b-3d84-4581-bd92-5d8f8b8bab6a) | Disabled | All Users, Excluded: 1 users/groups | All Applications | Block (ANY) |\n\n\n","TestStatus":"Passed","TestDescription":"Device code flow is a cross-device authentication flow designed for input-constrained devices. It can be exploited in phishing attacks, where an attacker initiates the flow and tricks a user into completing it on their device, thereby sending the user's tokens to the attacker. Given the security risks and the infrequent legitimate use of device code flow, you should enable a Conditional Access policy to block this flow by default.\n\n**Remediation action**\n\n- [Deploy a Conditional Access policy to block device code flow](https://learn.microsoft.com/entra/identity/conditional-access/policy-block-authentication-flows?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci#device-code-flow-policies).\n","TestId":"21808"},{"TestImplementationCost":"Medium","TestPillar":"Identity","TestCategory":"Credential management","SkippedReason":null,"TestImpact":"Low","TestAppliesTo":null,"TestSfiPillar":"Protect identities and secrets","TestSkipped":"","TestMinimumLicense":"Free","TestTags":null,"TestTitle":"Passkey authentication method enabled","TestRisk":"High","TestResult":"\nPasskey authentication method is enabled and configured for users in your tenant.\n## [Passkey authentication method details](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ConfigureAuthMethodsBlade/authMethod~/%7B%22%40odata.type%22%3A%22%23microsoft.graph.fido2AuthenticationMethodConfiguration%22%2C%22id%22%3A%22Fido2%22%2C%22state%22%3A%22enabled%22%2C%22isSelfServiceRegistrationAllowed%22%3Atrue%2C%22isAttestationEnforced%22%3Afalse%2C%22excludeTargets%22%3A%5B%7B%22id%22%3A%2243b7bc87-77eb-4263-abad-e3c2478f0a35%22%2C%22targetType%22%3A%22group%22%2C%22displayName%22%3A%22eam-block-user%22%7D%5D%2C%22keyRestrictions%22%3A%7B%22isEnforced%22%3Afalse%2C%22enforcementType%22%3A%22allow%22%2C%22aaGuids%22%3A%5B%22de1e552d-db1d-4423-a619-566b625cdc84%22%2C%2290a3ccdf-635c-4729-a248-9b709135078f%22%2C%2277010bd7-212a-4fc9-b236-d2ca5e9d4084%22%2C%22b6ede29c-3772-412c-8a78-539c1f4c62d2%22%2C%22ee041bce-25e5-4cdb-8f86-897fd6418464%22%2C%2273bb0cd4-e502-49b8-9c6f-b59445bf720b%22%5D%7D%2C%22includeTargets%40odata.context%22%3A%22https%3A%2F%2Fgraph.microsoft.com%2Fbeta%2F%24metadata%23policies%2FauthenticationMethodsPolicy%2FauthenticationMethodConfigurations('Fido2')%2Fmicrosoft.graph.fido2AuthenticationMethodConfiguration%2FincludeTargets%22%2C%22includeTargets%22%3A%5B%7B%22targetType%22%3A%22group%22%2C%22id%22%3A%22all_users%22%2C%22isRegistrationRequired%22%3Afalse%7D%5D%2C%22enabled%22%3Atrue%2C%22target%22%3A%22All%20users%2C%20excluding%201%20group%22%2C%22isAllUsers%22%3Atrue%2C%22voiceDisabled%22%3Afalse%7D/canModify~/true/voiceDisabled~/false/userMemberIds~/%5B%5D/userId/1ce4078f-f795-4baf-aa55-1fdfcc2ebfe6/isCiamTenant~/false/isCiamTrialTenant~/false)\n- **Status** : Enabled ✅\n- **Include targets** : All users\n- **Enforce attestation** : False\n- **Key restriction policy** :\n - **Enforce key restrictions** : False\n - **Restrict specific keys** : Allow\n\n\n","TestStatus":"Passed","TestDescription":"When passkey authentication isn't enabled in Microsoft Entra ID, organizations rely on password-based authentication methods that are vulnerable to phishing, credential theft, and replay attacks. Attackers can use stolen passwords to gain initial access, bypass traditional multifactor authentication through Adversary-in-the-Middle (AiTM) attacks, and establish persistent access through token theft.\n\nPasskeys provide phishing-resistant authentication using cryptographic proof that attackers can't phish, intercept, or replay. Enabling passkeys eliminates the foundational vulnerability that enables credential-based attack chains.\n\n**Remediation action**\n\n- Learn how to [enable the passkey authentication method](https://learn.microsoft.com/entra/identity/authentication/how-to-enable-passkey-fido2?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci#enable-passkey-fido2-authentication-method).\n- Learn how to [plan a phishing-resistant passwordless authentication deployment](https://learn.microsoft.com/entra/identity/authentication/how-to-plan-prerequisites-phishing-resistant-passwordless-authentication?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci).\n","TestId":"21839"},{"TestImplementationCost":"Medium","TestPillar":"Identity","TestCategory":"Credential management","SkippedReason":null,"TestImpact":"Medium","TestAppliesTo":["Identity"],"TestSfiPillar":"Protect identities and secrets","TestSkipped":"","TestMinimumLicense":"P1","TestTags":["Identity"],"TestTitle":"Weak authentication methods are disabled","TestRisk":"High","TestResult":"\nFound weak authentication methods that are still enabled.\n\n## Weak authentication methods\n| Method ID | Is method weak? | State |\n| :-------- | :-------------- | :---- |\n| Sms | Yes | enabled |\n| Voice | Yes | disabled |\n\n\n","TestStatus":"Failed","TestDescription":"When weak authentication methods like SMS and voice calls remain enabled in Microsoft Entra ID, threat actors can exploit these vulnerabilities through multiple attack vectors. Initially, attackers often conduct reconnaissance to identify organizations using these weaker authentication methods through social engineering or technical scanning. Then they can execute initial access through credential stuffing attacks, password spraying, or phishing campaigns targeting user credentials.\n\nOnce basic credentials are compromised, threat actors use these weaknesses in SMS and voice-based authentication. SMS messages can be intercepted through SIM swapping attacks, SS7 network vulnerabilities, or malware on mobile devices, while voice calls are susceptible to voice phishing (vishing) and call forwarding manipulation. With these weak second factors bypassed, attackers achieve persistence by registering their own authentication methods. Compromised accounts can be used to target higher-privileged users through internal phishing or social engineering, allowing attackers to escalate privileges within the organization. Finally, threat actors achieve their objectives through data exfiltration, lateral movement to critical systems, or deployment of other malicious tools, all while maintaining stealth by using legitimate authentication pathways that appear normal in security logs. \n\n**Remediation action**\n\n- [Deploy authentication method registration campaigns to encourage stronger methods](https://learn.microsoft.com/graph/api/authenticationmethodspolicy-update?view=graph-rest-beta&preserve-view=true&wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci)\n- [Disable authentication methods](https://learn.microsoft.com/entra/identity/authentication/concept-authentication-methods-manage?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci)\n- [Disable phone-based methods in legacy MFA settings](https://learn.microsoft.com/entra/identity/authentication/howto-mfa-mfasettings?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci)\n- [Deploy Conditional Access policies using authentication strength](https://learn.microsoft.com/entra/identity/authentication/concept-authentication-strength-how-it-works?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci)\n","TestId":"21804"},{"TestImplementationCost":"","TestPillar":"Infrastructure","TestCategory":"Manage access and permissions","SkippedReason":null,"TestImpact":"","TestAppliesTo":null,"TestSfiPillar":"Protect tenants and isolate production systems","TestSkipped":"","TestMinimumLicense":"N/A","TestTags":null,"TestTitle":"Guest accounts with owner permissions on Azure resources should be removed","TestRisk":"High","TestResult":"Guest accounts with owner permissions on Azure resources should be removed\n\n| Subscription | Affected resource | Status | Azure portal |\n| :----------- | :---------------- | :----- | :----------- |\n| [Visual Studio Enterprise Subscription](https://portal.azure.com/#resource/subscriptions/54d3ea01-5a07-45d0-8d69-e5f5b0b20098) | [54d3ea01-5a07-45d0-8d69-e5f5b0b20098](https://portal.azure.com/#resource/subscriptions/54d3ea01-5a07-45d0-8d69-e5f5b0b20098) | ❌ | [View recommendation](https://portal.azure.com/#blade/Microsoft_Azure_Security/RecommendationsBlade/assessmentKey/20606e75-05c4-48c0-9d97-add6daa2109a/resourceId/%2fsubscriptions%2f54d3ea01-5a07-45d0-8d69-e5f5b0b20098) |\n","TestStatus":"Failed","TestDescription":"Accounts with owner permissions that have been provisioned outside of the Azure Active Directory tenant (different domain names), should be removed from your Azure resources.
These guest accounts are not managed to the same standards as enterprise tenant identities.
This makes them potential targets for threat actors looking to find ways to access your data without being noticed.
By removing these accounts, you can reduce the risk of unauthorized data access and potential breaches.
\n\n**Remediation action**\n\nReview the list of guest accounts that require access removal on the Accounts section. Select an account to view its role definitions and locate source scope. If you accept the risk for a specific account, use the exempt capability to exclude it from evaluation.
  1. Go to the Azure portal.
  2. Open Access control (IAM) at a scope, such as management group, subscription, resource group, or resource, where the guest user has a role assignment.
  3. Click the Role assignments tab to view all the role assignments.
  4. In the list of role assignments, add a checkmark next to the guest user with the role assignment you want to remove.
  5. Click Remove. In the remove role assignment message that appears, click Yes.
","TestId":"20606e75-05c4-48c0-9d97-add6daa2109a"},{"TestImplementationCost":"Low","TestPillar":"Devices","TestCategory":"Tenant","SkippedReason":null,"TestImpact":"Medium","TestAppliesTo":null,"TestSfiPillar":"Protect tenants and isolate production systems","TestSkipped":"","TestMinimumLicense":"Intune","TestTags":null,"TestTitle":"Device enrollment notification is configured and assigned","TestRisk":"Medium","TestResult":"\nNo device enrollment notification is configured or assigned in Intune.\n\n\n\n","TestStatus":"Failed","TestDescription":"Without device enrollment notifications, users might be unaware that their device has been enrolled in Intune—particularly in cases of unauthorized or unexpected enrollment. This lack of visibility can delay user reporting of suspicious activity and increase the risk of unmanaged or compromised devices gaining access to corporate resources. Attackers who obtain user credentials or exploit self-enrollment flows can silently onboard devices, bypassing user scrutiny and enabling data exposure or lateral movement.\n\nEnrollment notifications provide users with improved visibility into device onboarding activity. They help detect unauthorized enrollment, reinforce secure provisioning practices, and support Zero Trust principles of visibility, verification, and user engagement.\n\n**Remediation action**\n\nConfigure Intune enrollment notifications to alert users when their device is enrolled and reinforce secure onboarding practices: \n- [Set up enrollment notifications in Intune](https://learn.microsoft.com/intune/intune-service/enrollment/enrollment-notifications?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci)\n","TestId":"24572"},{"TestImplementationCost":"","TestPillar":"Infrastructure","TestCategory":"Implement security best practices","SkippedReason":null,"TestImpact":"","TestAppliesTo":null,"TestSfiPillar":"Protect tenants and isolate production systems","TestSkipped":"","TestMinimumLicense":"N/A","TestTags":null,"TestTitle":"Guest accounts with read permissions on Azure resources should be removed","TestRisk":"High","TestResult":"Guest accounts with read permissions on Azure resources should be removed\n\n| Subscription | Affected resource | Status | Azure portal |\n| :----------- | :---------------- | :----- | :----------- |\n| [Visual Studio Enterprise Subscription](https://portal.azure.com/#resource/subscriptions/54d3ea01-5a07-45d0-8d69-e5f5b0b20098) | [54d3ea01-5a07-45d0-8d69-e5f5b0b20098](https://portal.azure.com/#resource/subscriptions/54d3ea01-5a07-45d0-8d69-e5f5b0b20098) | ✅ | [View recommendation](https://portal.azure.com/#blade/Microsoft_Azure_Security/RecommendationsBlade/assessmentKey/fde1c0c9-0fd2-4ecc-87b5-98956cbc1095/resourceId/%2fsubscriptions%2f54d3ea01-5a07-45d0-8d69-e5f5b0b20098) |\n","TestStatus":"Passed","TestDescription":"Accounts with read permissions that have been provisioned outside of the Azure Active Directory tenant (different domain names), should be removed from your Azure resources.
These guest accounts are not managed to the same standards as enterprise tenant identities.
This makes them potential targets for threat actors looking to find ways to access your data without being noticed.
By removing these accounts, you can reduce the risk of unauthorized data access and potential breaches.
\n\n**Remediation action**\n\nReview the list of guest accounts that require access removal on the Accounts section. Select an account to view its role definitions and locate source scope. If you accept the risk for a specific account, use the exempt capability to exclude it from evaluation.
  1. Go to the Azure portal.
  2. Open Access control (IAM) at a scope, such as management group, subscription, resource group, or resource, where the guest user has a role assignment.
  3. Click the Role assignments tab to view all the role assignments.
  4. In the list of role assignments, add a checkmark next to the guest user with the role assignment you want to remove.
  5. Click Remove. In the remove role assignment message that appears, click Yes.
","TestId":"fde1c0c9-0fd2-4ecc-87b5-98956cbc1095"},{"TestImpact":"Medium","TestRisk":"High","TestSkipped":"","TestAppliesTo":null,"TestPillar":"Data","TestCategory":"Data Security Posture Management","TestDescription":"Collection Policies provide the data ingestion layer that supports monitoring of enterprise AI app activity. When these policies are in place, Communication Compliance can collect signals from AI app interactions and help organizations understand where data protection risks may exist across AI‑enabled workflows. This visibility helps teams apply data protection controls more consistently as AI use expands beyond Microsoft Copilot.\n\t\t\nIn practice, users may accidentally share sensitive data with custom AI applications, Power Automate flows, AI Builder automations, or non‑Microsoft AI services that aren’t approved to handle confidential information. However, Communication Compliance policies that cover enterprise AI app interactions can help surface potential data exposure to these services and extend data protection practices to custom and third‑party AI solutions.\n\n**Remediation action**\n\n- [Create and Deploy collection policies](https://learn.microsoft.com/purview/collection-policies-create-deploy-policy?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci)\n- [Create and manage Communication Compliance policies](https://learn.microsoft.com/purview/communication-compliance-policies?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci)\n","TestTitle":"Communication compliance monitoring is configured for enterprise AI tools","SkippedReason":null,"TestId":"35040","TestImplementationCost":"Medium","TestMinimumLicense":["EXCHANGE_S_ENTERPRISE"],"TestSfiPillar":"Protect tenants and production systems","TestResult":"\n✅ Collection Policies are configured for data ingestion, Communication Compliance rules are configured to target enterprise AI apps (ConnectedAIApp and/or UnifiedGenAIWorkloads identified in RuleXml), AND at least one Communication Compliance policy is ENABLED with a ReviewMailbox configured, enabling the organization to detect and investigate unauthorized data sharing and policy violations through enterprise AI interactions.\n\n\n### [Data ingestion layer (Collection policies)](https://purview.microsoft.com/cc/dataclassification/dataandactivitydiscovery?tid=0817c655-a853-4d8f-9723-3a333b5b9235)\n\n| Policy name | Enabled | Mode | Workload | Activities | Enforcement planes | Created by | Last modified | Policy category |\n| :---------- | :------ | :--- | :------- | :--------- | :----------------- | :--------- | :------------ | :-------------- |\n| 35040-Test | ❌ False | ❌ Disable | Exchange, EndpointDevices, Applications | UploadText, DownloadText | Entra | Cameron Anderson | 2026-02-13 | ApplicableToAI |\n| 35040-test2 | ✅ True | ✅ Enable | Exchange, EndpointDevices | filecreated | Devices | Cameron Anderson | 2026-02-20 | ApplicableToAI |\n| DSPM for AI - Capture interactions for Copilot experiences | ✅ True | ✅ Enable | Exchange, Applications | UploadText, DownloadText | CopilotExperiences | Dakota Lee Test | 2026-05-11 | ApplicableToAI |\n| DSPM for AI - Capture interactions for enterprise AI apps | ✅ True | ✅ Enable | Exchange, Applications | UploadText, DownloadText | Entra | Dakota Lee Test | 2026-05-11 | ApplicableToAI |\n| DSPM for AI - Detect sensitive info shared with AI via network | ✅ True | ✅ Enable | Exchange, Applications | UploadText, UploadFile, DownloadText, DownloadFile | Network | Dakota Lee Test | 2026-05-11 | ApplicableToAI |\n\n### [Communication Compliance rules targeting Enterprise AI Apps](https://purview.microsoft.com/cc/policies?tid=0817c655-a853-4d8f-9723-3a333b5b9235)\n\n| Rule name | Associated policy | Workloads | UnifiedGenAIWorkloads |\n| :-------- | :---------------- | :-------- | :-------------------- |\n| Enterprise AI CC Test_Exchange_Content, Enterprise AI CC Test_Exchange_InPurview | Enterprise AI CC Test | ConnectedAIApp | ChatGPT.Enterprise, EntraApp, AzureAI |\n\n### [Enabled policies with review mailbox](https://purview.microsoft.com/cc/policies?tid=0817c655-a853-4d8f-9723-3a333b5b9235)\n\n| Policy name | Enabled | Review mailbox |\n| :---------- | :------ | :------------- |\n| Copilot Data Protection | ✅ True | ✅ SupervisoryReview{3bbbbd4f-cc0a-45ff-b0f5-c6023124c881}@contoso.onmicrosoft.com |\n| Custom Policy 35040 | ✅ True | ✅ SupervisoryReview{8fb152db-0f94-45f9-b29c-8764f3a5ccef}@contoso.onmicrosoft.com |\n| Enterprise AI CC Test | ✅ True | ✅ SupervisoryReview{efe29507-f54b-430a-8a92-f67bd2385dec}@contoso.onmicrosoft.com |\n| Microsoft 365 Copilot interactions | ✅ True | ✅ SupervisoryReview{8ce4a232-c7cf-4712-aee9-f02c9a9cd3e8}@contoso.onmicrosoft.com |\n| test1 | ✅ True | ✅ SupervisoryReview{7a05811d-28e7-4163-a013-d57c554fca5f}@contoso.onmicrosoft.com |\n\n\n**Summary:**\n- Collection Policies Configured: 5\n- Enterprise AI Rules Detected (with ConnectedAIApp or UnifiedGenAIWorkloads): 1\n- Policies Enabled with ReviewMailbox: 5\n\n","TestStatus":"Passed","TestTags":null},{"TestImplementationCost":"","TestPillar":"Infrastructure","TestCategory":"Remediate security configurations","SkippedReason":"This test is not applicable to the current environment.","TestImpact":"","TestAppliesTo":null,"TestSfiPillar":"Protect tenants and isolate production systems","TestSkipped":"NotApplicable","TestMinimumLicense":"N/A","TestTags":null,"TestTitle":"Vulnerabilities in security configuration on your Windows machines should be remediated (powered by Guest Configuration)","TestRisk":"Low","TestResult":"UnsupportedPricingPlan\n\n| Subscription | Resource group | Resource type | Affected resource | Status | Azure portal |\n| :----------- | :------------- | :------------ | :---------------- | :----- | :----------- |\n| [Visual Studio Enterprise Subscription](https://portal.azure.com/#resource/subscriptions/54d3ea01-5a07-45d0-8d69-e5f5b0b20098) | indiavm_group | virtualmachines | [india-2](https://portal.azure.com/#resource/subscriptions/54d3ea01-5a07-45d0-8d69-e5f5b0b20098/resourceGroups/indiavm_group/providers/Microsoft.Compute/virtualMachines/india-2) | N/A | [View recommendation](https://portal.azure.com/#blade/Microsoft_Azure_Security/RecommendationsBlade/assessmentKey/8c3d9ad0-3639-4686-9cd2-2b2ab2609bda/resourceId/%2fsubscriptions%2f54d3ea01-5a07-45d0-8d69-e5f5b0b20098%2fresourceGroups%2findiavm_group%2fproviders%2fMicrosoft.Compute%2fvirtualMachines%2findia-2) |\n| [Visual Studio Enterprise Subscription](https://portal.azure.com/#resource/subscriptions/54d3ea01-5a07-45d0-8d69-e5f5b0b20098) | indiavm_group | virtualmachines | [indiavm](https://portal.azure.com/#resource/subscriptions/54d3ea01-5a07-45d0-8d69-e5f5b0b20098/resourceGroups/indiavm_group/providers/Microsoft.Compute/virtualMachines/indiavm) | N/A | [View recommendation](https://portal.azure.com/#blade/Microsoft_Azure_Security/RecommendationsBlade/assessmentKey/8c3d9ad0-3639-4686-9cd2-2b2ab2609bda/resourceId/%2fsubscriptions%2f54d3ea01-5a07-45d0-8d69-e5f5b0b20098%2fresourceGroups%2findiavm_group%2fproviders%2fMicrosoft.Compute%2fvirtualMachines%2findiavm) |\n","TestStatus":"Skipped","TestDescription":"Addressing vulnerabilities in the security configuration of Windows machines is important to safeguard them from potential attacks.
These vulnerabilities, if left unattended, could be exploited by attackers to gain unauthorized access or disrupt system operations.
Remediation, powered by Guest Configuration, helps to ensure the security and integrity of the system, thereby reducing the risk of compromise.
\n\n**Remediation action**\n\n1. Select any of the findings below.
2. On the right pane opened, follow the instructions under 'Remediation' if exist.","TestId":"8c3d9ad0-3639-4686-9cd2-2b2ab2609bda"},{"TestImplementationCost":"Low","TestPillar":"Identity","TestCategory":"Access control","SkippedReason":"UnderConstruction","TestImpact":"Low","TestAppliesTo":["Identity"],"TestSfiPillar":"Protect identities and secrets","TestSkipped":"UnderConstruction","TestMinimumLicense":null,"TestTags":["Identity"],"TestTitle":"No Active Medium priority Entra recommendations found","TestRisk":"Medium","TestResult":"\nPlanned for future release.\n","TestStatus":"Planned","TestDescription":"...\n\n**Remediation action**\n\n","TestId":"21983"},{"TestImpact":"Low","TestRisk":"High","TestSkipped":"","TestAppliesTo":null,"TestPillar":"Data","TestCategory":"Data Security Posture Management","TestDescription":"Purview audit logging logs who accessed sensitive data, when policy violations occurred, and what administrative actions were taken across Microsoft 365. When audit logs are available, security teams can investigate incidents, perform eDiscovery, detect insider threats, and demonstrate controls to auditors and regulators.\n\nWithout audit logging enabled, threat actors can often operate undetected, and incident response becomes impossible due to lack of evidence. Organizations that fail to enable audit logging also risk noncompliance with regulatory requirements that mandate activity logging for sensitive operations.\n\n**Remediation action**\n\n- [Turn auditing on or off](https://learn.microsoft.com/purview/audit-log-enable-disable?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci)\n","TestTitle":"Purview audit logging enabled","SkippedReason":null,"TestId":"35037","TestImplementationCost":"Low","TestMinimumLicense":["RMS_S_PREMIUM"],"TestSfiPillar":"Protect tenants and production systems","TestResult":"\n❌ Purview Audit Logging is DISABLED, creating a critical visibility gap where unauthorized access, policy violations, and security incidents cannot be detected or investigated.\n\n\n\n### [Audit logging status](https://purview.microsoft.com/audit)\n| Configuration property | Value |\n| :--- | :--- |\n| Unified audit log ingestion enabled | False |\n| Audit log age limit | 90.00:00:00 |\n| Organization ID | FFO.extest.microsoft.com/Microsoft Exchange Hosted Organizations/contoso.onmicrosoft.com - FFO.extest.microsoft.com/Microsoft Exchange Hosted Organizations/contoso.onmicrosoft.com/Configuration |\n\n","TestStatus":"Failed","TestTags":null},{"TestImpact":"High","TestRisk":"High","TestSkipped":"","TestAppliesTo":null,"TestPillar":"Data","TestCategory":"Rights Management Service","TestDescription":"The Azure Rights Management service provides the foundational encryption and access control technology for Microsoft Purview Information Protection. It's used with sensitivity labels that apply encryption, protects emails with Microsoft Purview Message Encryption, and even used with the older protection technologies such as SharePoint IRM and mail flow rules that apply encryption. This service should be activated for the tenant before you configure any other information protection features.\n\n**Remediation action**\n\n- [Activate the Azure Rights Management service](https://learn.microsoft.com/purview/activate-rights-management-service?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci)\n","TestTitle":"Azure RMS Licensing Enabled","SkippedReason":null,"TestId":"35024","TestImplementationCost":"Low","TestMinimumLicense":["RMS_S_PREMIUM"],"TestSfiPillar":"Protect tenants and production systems","TestResult":"\n✅ Azure RMS is enabled at the tenant level, enabling all downstream encryption and rights management capabilities.\n\n\n### Azure RMS Status\n\n| Setting | Value |\n| :------ | :---- |\n| AzureRMSLicensingEnabled | True |\n| SimplifiedClientAccessEnabled | True |\n| InternalLicensingEnabled | True |\n| ExternalLicensingEnabled | True |\n| Configuration Created | 07/07/2020 05:00:17 |\n\n\n**Summary:**\n\n Azure RMS Service: ✅ Enabled\n\n\n","TestStatus":"Passed","TestTags":null},{"TestImplementationCost":"Medium","TestPillar":"Identity","TestCategory":"Privileged access","SkippedReason":"UnderConstruction","TestImpact":"Low","TestAppliesTo":["Identity"],"TestSfiPillar":"Monitor and detect cyberthreats","TestSkipped":"UnderConstruction","TestMinimumLicense":"P1","TestTags":["Authentication"],"TestTitle":"Privileged users sign in with phishing-resistant methods","TestRisk":"High","TestResult":"\nFound Accounts have not registered phishing resistant methods\n\n\n\n","TestStatus":"Planned","TestDescription":"Without phishing-resistant authentication methods, privileged users are more vulnerable to phishing attacks. These types of attacks trick users into revealing their credentials to grant unauthorized access to attackers. If non-phishing-resistant authentication methods are used, attackers might intercept credentials and tokens, through methods like adversary-in-the-middle attacks, undermining the security of the privileged account.\n\nOnce a privileged account or session is compromised due to weak authentication methods, attackers might manipulate the account to maintain long-term access, create other backdoors, or modify user permissions. Attackers can also use the compromised privileged account to escalate their access even further, potentially gaining control over more sensitive systems.\n\n**Remediation action**\n\n- [Get started with a phishing-resistant passwordless authentication deployment](https://learn.microsoft.com/entra/identity/authentication/how-to-plan-prerequisites-phishing-resistant-passwordless-authentication?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci)\n- [Ensure that privileged accounts register and use phishing resistant methods](https://learn.microsoft.com/entra/identity/authentication/concept-authentication-strengths?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci#authentication-strengths)\n- [Deploy a Conditional Access policy to target privileged accounts and require phishing resistant credentials](https://learn.microsoft.com/entra/identity/conditional-access/policy-admin-phish-resistant-mfa?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci)\n- [Monitor authentication method activity](https://learn.microsoft.com/entra/identity/monitoring-health/concept-usage-insights-report?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci#authentication-methods-activity)\n","TestId":"21781"},{"TestImplementationCost":"High","TestPillar":"Identity","TestCategory":"Privileged access","SkippedReason":null,"TestImpact":"Low","TestAppliesTo":["Identity"],"TestSfiPillar":"Protect identities and secrets","TestSkipped":"","TestMinimumLicense":"P2","TestTags":["Identity"],"TestTitle":"All privileged role assignments are activated just in time and not permanently active","TestRisk":"High","TestResult":"\nPrivileged users with permanent role assignments were found.\n\n\n## Privileged users with permanent role assignments\n\n\n| User | UPN | Role Name | Assignment Type |\n| :--- | :-- | :-------- | :-------------- |\n| [Reese Harris](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/AdministrativeRole/userId/babe04c9-8340-4329-a727-a8cee0cd2b1a/hidePreviewBanner~/true) | reese@contoso.com | Global Administrator | Permanent |\n| [Jordan Smith](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/AdministrativeRole/userId/bfaeba1e-1357-47de-9557-529caa103d5d/hidePreviewBanner~/true) | jordan@contoso.com | Application Administrator | Permanent |\n| [Jordan Smith](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/AdministrativeRole/userId/bfaeba1e-1357-47de-9557-529caa103d5d/hidePreviewBanner~/true) | jordan@contoso.com | AI Administrator | Permanent |\n| [Dakota Lee](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/AdministrativeRole/userId/e4bc6f4a-124f-469b-8951-3d5c34fb9741/hidePreviewBanner~/true) | dakota@contoso.com | User Administrator | Permanent |\n| [Avery Brooks](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/AdministrativeRole/userId/a85798bd-652b-4eb9-ba90-3ee882df0179/hidePreviewBanner~/true) | avery.brooks@contoso.com | Global Administrator | Permanent |\n| [Finley Robinson](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/AdministrativeRole/userId/990fd38a-c516-4e3f-82e4-d458a1ab0f91/hidePreviewBanner~/true) | finley.robinson@contoso.com | Global Administrator | Permanent |\n| [Finley Robinson](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/AdministrativeRole/userId/990fd38a-c516-4e3f-82e4-d458a1ab0f91/hidePreviewBanner~/true) | finley.robinson@contoso.com | Global Reader | Permanent |\n| [Taylor Brown](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/AdministrativeRole/userId/2072badc-3cf0-4e84-b4c2-f9c065c46165/hidePreviewBanner~/true) | taylor@contoso.com | Global Administrator | Permanent |\n| [Jamie Rodriguez](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/AdministrativeRole/userId/0b37813c-ae19-4399-982f-16587f17f9c0/hidePreviewBanner~/true) | jamie@contoso.com | Global Administrator | Permanent |\n| [Cameron Anderson](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/AdministrativeRole/userId/1ce4078f-f795-4baf-aa55-1fdfcc2ebfe6/hidePreviewBanner~/true) | cameron@contoso.com | Global Reader | Permanent |\n| [Drew Mitchell](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/AdministrativeRole/userId/df02402a-e291-42cc-b449-79366daa2a40/hidePreviewBanner~/true) | drew@contoso.com | Application Administrator | Permanent |\n| [Cameron Anderson](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/AdministrativeRole/userId/1ce4078f-f795-4baf-aa55-1fdfcc2ebfe6/hidePreviewBanner~/true) | cameron@contoso.com | Security Administrator | Permanent |\n| [Sage Bennett](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/AdministrativeRole/userId/518ce209-faf4-4717-add9-7129a669fa11/hidePreviewBanner~/true) | sage@contoso.com | Agent ID Administrator | Permanent |\n| [Sage Bennett](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/AdministrativeRole/userId/518ce209-faf4-4717-add9-7129a669fa11/hidePreviewBanner~/true) | sage@contoso.com | Global Administrator | Permanent |\n| [PimLevel](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/AdministrativeRole/userId/e8971185-8150-402e-b90f-5c1eb0d30dfe/hidePreviewBanner~/true) | | Application Administrator | Permanent |\n| [Ellis Cooper](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/AdministrativeRole/userId/1433571b-3d7c-4a56-a9cc-67580848bc73/hidePreviewBanner~/true) | ellis@contoso.com | Global Administrator | Permanent |\n| [Dakota Lee Test](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/AdministrativeRole/userId/43482f27-d1af-420f-84ba-e9148a700f45/hidePreviewBanner~/true) | dakota-test@contoso.com | Global Administrator | Permanent |\n| [Mailbox Migration Account](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/AdministrativeRole/userId/d22f071d-e8d3-41fc-a516-b29753cdd1f6/hidePreviewBanner~/true) | | Application Administrator | Permanent |\n| [Cameron Anderson](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/AdministrativeRole/userId/1ce4078f-f795-4baf-aa55-1fdfcc2ebfe6/hidePreviewBanner~/true) | cameron@contoso.com | Global Administrator | Permanent |\n| [Custom-App-Test](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/AdministrativeRole/userId/38415a71-b77b-44d5-a276-539faabe0de7/hidePreviewBanner~/true) | | Global Administrator | Permanent |\n| [Quinn Garcia](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/AdministrativeRole/userId/ceef37b7-c865-48fb-80c9-4def11201854/hidePreviewBanner~/true) | quinn@contoso.com | Global Administrator | Permanent |\n| [Peyton Clark](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/AdministrativeRole/userId/7e92f268-bb12-469a-a869-210d596d4c1f/hidePreviewBanner~/true) | peyton@contoso.com | Global Administrator | Permanent |\n| [Drew Mitchell](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/AdministrativeRole/userId/df02402a-e291-42cc-b449-79366daa2a40/hidePreviewBanner~/true) | drew@contoso.com | Global Administrator | Permanent |\n| [Mailbox Migration Account](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/AdministrativeRole/userId/d22f071d-e8d3-41fc-a516-b29753cdd1f6/hidePreviewBanner~/true) | | Global Administrator | Permanent |\n| [Hayden Scott Test](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/AdministrativeRole/userId/6f467d0a-25ec-435c-8fb9-9d53eb21e02f/hidePreviewBanner~/true) | hayden-test@contoso.com | Global Reader | Permanent |\n| [peyton-test](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/AdministrativeRole/userId/e0952dcb-8d63-496d-8661-05c86c1a51f0/hidePreviewBanner~/true) | peyton-test@contoso.com | Global Reader | Permanent |\n| [Jordan Smith](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/AdministrativeRole/userId/bfaeba1e-1357-47de-9557-529caa103d5d/hidePreviewBanner~/true) | jordan@contoso.com | Global Administrator | Permanent |\n| [contoso-tenant-devops-7576c63d-bc90-4ae4-9f1c-0d959fb520db](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/AdministrativeRole/userId/c5632968-35cd-445d-926e-16e0afc9160e/hidePreviewBanner~/true) | | Global Administrator | Permanent |\n| [Ash Williams](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/AdministrativeRole/userId/513f3db2-044c-41be-af14-431bf88a2b3e/hidePreviewBanner~/true) | ash@contoso.com | Global Administrator | Permanent |\n| [parker-test](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/AdministrativeRole/userId/c1bdb03c-0079-40b1-96a8-3595de3b94a2/hidePreviewBanner~/true) | parker-test@contoso.com | Global Reader | Permanent |\n| [Drew Mitchell](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/AdministrativeRole/userId/df02402a-e291-42cc-b449-79366daa2a40/hidePreviewBanner~/true) | drew@contoso.com | Global Reader | Permanent |\n| [Sage Bennett](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/AdministrativeRole/userId/518ce209-faf4-4717-add9-7129a669fa11/hidePreviewBanner~/true) | sage@contoso.com | Global Reader | Permanent |\n| [ash-williams-test](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/AdministrativeRole/userId/c5c8ba63-4620-4e91-ac40-b66bebe07a0d/hidePreviewBanner~/true) | ash.test@contoso.com | Global Reader | Permanent |\n| [Phoenix Gray](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/AdministrativeRole/userId/7094fb23-003a-4f81-9796-5daeaa603003/hidePreviewBanner~/true) | phoenix@contoso.com | Global Administrator | Permanent |\n| [Hayden Scott](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/AdministrativeRole/userId/c0b65b13-37b1-4081-bcfc-14844159b4a5/hidePreviewBanner~/true) | hayden@contoso.com | Global Administrator | Permanent |\n| [Hayden Scott](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/AdministrativeRole/userId/0d6cfd05-fc46-440b-b605-66dd26dcd7d2/hidePreviewBanner~/true) | hayden.p@contoso.com | Global Reader | Permanent |\n| [Peyton Clark](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/AdministrativeRole/userId/7e92f268-bb12-469a-a869-210d596d4c1f/hidePreviewBanner~/true) | peyton@contoso.com | Global Reader | Permanent |\n| [finley-test](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/AdministrativeRole/userId/d71ccc09-c0a3-4604-9d02-49f7a3715f49/hidePreviewBanner~/true) | finley-test@contoso.com | Global Reader | Permanent |\n| [Jules Bailey](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/AdministrativeRole/userId/0145d508-50fd-4f86-a47a-bf1c043c8358/hidePreviewBanner~/true) | jules@contoso.com | Global Administrator | Permanent |\n| [Dakota Lee](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/AdministrativeRole/userId/210d3e96-015f-462d-b6d6-81e6023263df/hidePreviewBanner~/true) | guest-user_external.com#EXT#@contoso.com | Global Administrator | Permanent |\n| [Charlie Lewis](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/AdministrativeRole/userId/5b0ec3ff-cea1-4eb9-8530-f2a66e5bec0a/hidePreviewBanner~/true) | charlie@contoso.com | Global Administrator | Permanent |\n| [Avery Thomas](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/AdministrativeRole/userId/f431700c-6d81-45b8-8f8d-581a8aa7cda6/hidePreviewBanner~/true) | avery@contoso.com | Global Administrator | Permanent |\n\n\n\n","TestStatus":"Failed","TestDescription":"Threat actors target privileged accounts because they have access to the data and resources they want. This might include more access to your Microsoft Entra tenant, data in Microsoft SharePoint, or the ability to establish long-term persistence. Without a just-in-time (JIT) activation model, administrative privileges remain continuously exposed, providing attackers with an extended window to operate undetected. Just-in-time access mitigates risk by enforcing time-limited privilege activation with extra controls such as approvals, justification, and Conditional Access policy, ensuring that high-risk permissions are granted only when needed and for a limited duration. This restriction minimizes the attack surface, disrupts lateral movement, and forces adversaries to trigger actions that can be specially monitored and denied when not expected. Without just-in-time access, compromised admin accounts grant indefinite control, letting attackers disable security controls, erase logs, and maintain stealth, amplifying the impact of a compromise.\n\nUse Microsoft Entra Privileged Identity Management (PIM) to provide time-bound just-in-time access to privileged role assignments. Use access reviews in Microsoft Entra ID Governance to regularly review privileged access to ensure continued need.\n\n**Remediation action**\n\n- [Start using Privileged Identity Management](https://learn.microsoft.com/entra/id-governance/privileged-identity-management/pim-getting-started?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci)\n- [Create an access review of Azure resource and Microsoft Entra roles in PIM](https://learn.microsoft.com/entra/id-governance/privileged-identity-management/pim-create-roles-and-resource-roles-review?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci)\n","TestId":"21815"},{"TestImplementationCost":"Low","TestPillar":"Devices","TestCategory":"Data","SkippedReason":null,"TestImpact":"Low","TestAppliesTo":null,"TestSfiPillar":"Protect networks","TestSkipped":"","TestMinimumLicense":"Intune","TestTags":null,"TestTitle":"Secure Wi-Fi profiles protect Android devices from unauthorized network access","TestRisk":"High","TestResult":"\nNo Enterprise Wi-Fi profile for android exists or none are assigned.\n\n\n\n","TestStatus":"Failed","TestDescription":"If Wi-Fi profiles aren't properly configured and assigned, Android devices can fail to connect to secure networks or connect insecurely, exposing corporate data to interception or unauthorized access. Without centralized management, devices rely on manual configuration, increasing the risk of misconfiguration, weak authentication, and connection to rogue networks.\n\nCentrally managing Wi-Fi profiles for Android devices in Intune ensures secure and consistent connectivity to enterprise networks. This enforces authentication and encryption standards, simplifies onboarding, and supports Zero Trust by reducing exposure to untrusted networks.\n\n\n\nUse Intune to configure secure Wi-Fi profiles that enforce authentication and encryption standards.\n\n**Remediation action**\n\nUse Intune to configure and assign secure Wi-Fi profiles for Android devices to enforce authentication and encryption standards: \n- [Deploy Wi-Fi profiles to devices in Microsoft Intune](https://learn.microsoft.com/intune/intune-service/configuration/wi-fi-settings-configure?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci#create-the-profile)\n\nFor more information, see: \n- [Review the available Wi-Fi settings for Android devices in Microsoft Intune](https://learn.microsoft.com/intune/intune-service/configuration/wi-fi-settings-android-enterprise?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci)\n","TestId":"24840"},{"TestImpact":"Medium","TestRisk":"Medium","TestSkipped":"","TestAppliesTo":null,"TestPillar":"Data","TestCategory":"Advanced Classification","TestDescription":"Trainable classifiers are machine learning-based classifiers that recognize content by meaning and context rather than fixed patterns. Unlike sensitive information types that match predefined formats, trainable classifiers can identify unstructured content like strategic plans, financial reports, or HR documents. Using trainable classifiers in auto-labeling policies, and data loss prevention (DLP) rules, extends protection to sensitive business content that pattern-based rules can't reliably capture.\n\n**Remediation action**\n\n- [Learn about trainable classifiers](https://learn.microsoft.com/purview/classifier-learn-about?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci)\n- [Get started with trainable classifiers](https://learn.microsoft.com/purview/trainable-classifiers-get-started-with?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci)\n","TestTitle":"Trainable Classifiers Usage in Policies","SkippedReason":null,"TestId":"35036","TestImplementationCost":"High","TestMinimumLicense":["EXCHANGE_S_ENTERPRISE"],"TestSfiPillar":"Protect tenants and production systems","TestResult":"\n✅ Trainable classifiers are integrated into auto-labeling and/or DLP policies, enabling AI-powered content classification for complex business documents.\n\n\n## [Trainable Classifier Usage in Policies](https://purview.microsoft.com/informationprotection/dataclassification/trainableclassifiers)\n\n**Trainable Classifiers in Auto-Labeling Rules:**\n\n| Rule name | Parent policy | Created date | Classifiers in rule |\n| :-------- | :------------ | :----------- | :------------------ |\n| U.S. Patriot Act Enhanced-ODB | U.S. Patriot Act Enhanced | 2026-02-05 | Targeted Harassment, Profanity |\n\n**Trainable Classifiers in DLP Rules:**\n\n| Rule name | Parent policy | Created date | Classifiers in rule |\n| :-------- | :------------ | :----------- | :------------------ |\n| test036 | Endpoint DLP - Financial Data | 2026-02-06 | Source code, Targeted Harassment, Profanity, Threat, Resume, ... |\n\n\n\n**Summary:**\n* Total Auto-Labeling Rules Using Classifiers: 1\n* Total DLP Rules Using Classifiers: 1\n\n\n","TestStatus":"Passed","TestTags":null},{"TestImplementationCost":"Medium","TestPillar":"Identity","TestCategory":"Hybrid infrastructure","SkippedReason":null,"TestImpact":"Low","TestAppliesTo":null,"TestSfiPillar":"Protect identities and secrets","TestSkipped":"","TestMinimumLicense":"Free","TestTags":null,"TestTitle":"Entra Connect Sync is configured with Service Principal Credentials","TestRisk":"High","TestResult":"\nFound enabled user accounts with Microsoft Entra Connect connector permissions.\n\n**Hybrid Identity Status**: True\n\n\n## Identities for Entra Connect Sync\n\n| Directory Synchronization Accounts Role Member | User Principal Name | Enabled | User Type |\n| :--------------------------------------------- | :------------------ | :------ | :-------- |\n| [On-Premises Directory Synchronization Service Account](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/overview/userId/33956e9a-cb54-42e9-94e8-d8f6ba05a55f) | Sync_DC1_demouser-demouser-d8475d81663f@contoso.onmicrosoft.com | ❌ Yes | Member |\n\n\n\n","TestStatus":"Failed","TestDescription":"Microsoft Entra Connect Sync using user accounts instead of service principals creates security vulnerabilities. Legacy user account authentication with passwords is more susceptible to credential theft and password attacks than service principal authentication with certificates. Compromised connector accounts allow threat actors to manipulate identity synchronization, create backdoor accounts, escalate privileges, or disrupt hybrid identity infrastructure. \n\n**Remediation action**\n\n- [Configure service principal authentication for Entra Connect](https://learn.microsoft.com/entra/identity/hybrid/connect/authenticate-application-id?tabs=default&wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci#onboard-to-application-based-authentication)\n- [Remove legacy Directory Synchronization Accounts](https://learn.microsoft.com/entra/identity/hybrid/connect/authenticate-application-id?tabs=default&wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci#remove-a-legacy-service-account)\n","TestId":"24570"},{"TestImplementationCost":"Low","TestPillar":"Devices","TestCategory":"Data","SkippedReason":null,"TestImpact":"High","TestAppliesTo":null,"TestSfiPillar":"Protect identities and secrets","TestSkipped":"","TestMinimumLicense":"Intune","TestTags":null,"TestTitle":"An app protection policy for iOS devices exists","TestRisk":"High","TestResult":"\nAt least one App protection policy for iOS exists and is assigned.\n\n\n## OS App Protection policies configured for iOS\n\n| Policy Name | Status | Assignment |\n| :---------- | :----- | :--------- |\n| [iOS Policy](https://intune.microsoft.com/#view/Microsoft_Intune_DeviceSettings/AppsMenu/~/protection) | ✅ Assigned | **Included:** WFgroup, **Excluded:** graph test |\n\n\n\n","TestStatus":"Passed","TestDescription":"Without app protection policies, corporate data accessed on iOS/iPadOS devices is vulnerable to leakage through unmanaged or personal apps. Users can unintentionally copy sensitive information into unsecured apps, store data outside corporate boundaries, or bypass authentication controls. This risk is especially high on BYOD devices, where personal and work contexts coexist, increasing the likelihood of data exfiltration or unauthorized access.\n\nApp protection policies ensure corporate data remains secure within approved apps, even on personal devices. These policies enforce encryption, restrict data sharing, and require authentication, reducing the risk of data leakage and aligning with Zero Trust principles of data protection and Conditional Access.\n \n**Remediation action**\n\nDeploy Intune app protection policies that encrypt corporate data, restrict sharing, and require authentication in approved iOS/iPadOS apps: \n- [Deploy Intune app protection policies](https://learn.microsoft.com/intune/intune-service/apps/app-protection-policies?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci#create-an-iosipados-or-android-app-protection-policy)\n- [Review the iOS app protection settings reference](https://learn.microsoft.com/intune/intune-service/apps/app-protection-policy-settings-ios?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci)\n\nFor more information, see: \n- [Learn about using app protection policies](https://learn.microsoft.com/intune/intune-service/apps/app-protection-policy?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci)\n","TestId":"24548"},{"TestImplementationCost":"Low","TestPillar":"Devices","TestCategory":"Data","SkippedReason":null,"TestImpact":"Medium","TestAppliesTo":null,"TestSfiPillar":"Protect tenants and isolate production systems","TestSkipped":"","TestMinimumLicense":"Intune","TestTags":null,"TestTitle":"Unmanaged and unprotected Apps are restricted from Accessing Corporate Data","TestRisk":"High","TestResult":"\nAt least one enabled conditional access policy with Application Protection exists for iOS and Android. The platforms could be part of same or different policy with the required grant control.\n\n\n## iOS & Android Conditional Access Policies\n\n| Policy Name | Platforms |\n| :---------- | :-------- |\n| [\\[ellis\\] - Require app protection policy](https://intune.microsoft.com/#view/Microsoft_AAD_ConditionalAccess/ConditionalAccessBlade/~/Policies) | android, iOS |\n\n\n","TestStatus":"Passed","TestDescription":"If Microsoft Entra Conditional Access policies aren't combined with app protection controls, users can connect to corporate resources through unmanaged or unsecured applications. This exposes sensitive data to risks such as data leakage, unauthorized access, and regulatory noncompliance. Without safeguards like app-level data protection, access restrictions, and data loss prevention, threat actors can exploit unprotected apps to bypass security controls and compromise organizational data.\n\nEnforcing Intune app protection policies within Conditional Access ensures only trusted apps can access corporate data. This supports Zero Trust by enforcing access decisions based on app trust, data containment, and usage restrictions.\n\n**Remediation action**\n\nConfigure app-based Conditional Access policies in Microsoft Entra and Intune to require app protection for access to corporate resources: \n- [Set up app-based Conditional Access policies with Intune](https://learn.microsoft.com/intune/intune-service/protect/app-based-conditional-access-intune-create?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci)\n\nFor more information, see: \n- [What is Conditional Access?](https://learn.microsoft.com/entra/identity/conditional-access/overview?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci)\n- [Learn about app-based Conditional Access policies with Intune](https://learn.microsoft.com/intune/intune-service/protect/app-based-conditional-access-intune?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci)\n","TestId":"24827"},{"TestImplementationCost":"High","TestPillar":"Identity","TestCategory":"Application management","SkippedReason":null,"TestImpact":"Low","TestAppliesTo":["Identity"],"TestSfiPillar":"Protect identities and secrets","TestSkipped":"","TestMinimumLicense":"Free","TestTags":["Identity"],"TestTitle":"Application Certificates need to be rotated on a regular basis","TestRisk":"High","TestResult":"\nFound 4 applications and 15 service principals in your tenant with certificates that have not been rotated within 180 days.\n\n\n## Applications with certificates that have not been rotated within 180 days\n\n| Application | Certificate Start Date |\n| :--- | :--- |\n| [Automation](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/ApplicationMenuBlade/~/Credentials/appId/dc7d83b5-d38b-4488-8952-7abf02e71590) | 2025-03-03 |\n| [InfinityDemo - Sample](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/ApplicationMenuBlade/~/Credentials/appId/20f152d5-856c-449d-aa07-81f5e510dfa7) | 2021-05-03 |\n| [M365PronounKit](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/ApplicationMenuBlade/~/Credentials/appId/eea28244-3eec-4820-beae-d4a2c0bcc235) | 2021-02-28 |\n| [test public client](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/ApplicationMenuBlade/~/Credentials/appId/79a0c604-f215-4c52-8fbe-641d08aa7937) | 2021-10-22 |\n\n\n## Service principals with certificates that have not been rotated within 180 days\n\n| Service principal | App owner tenant | Certificate Start Date |\n| :--- | :--- | :--- |\n| [21869testapp](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/SignOn/objectId/e69e29be-ba40-445a-9824-a3a45e0ae57a/appId/dd63d132-18fb-4f2e-aec4-82b97f30301f/preferredSingleSignOnMode/saml/servicePrincipalType/Application/fromNav/) | | 2025-10-27 |\n| [APP-2732_Genesys Cloud TCCC-G-TFS-Prod](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/SignOn/objectId/ba63bb52-182c-4ec6-9cc8-ad2287cf51ed/appId/76249b01-8747-4db4-843f-6478d5b32b14/preferredSingleSignOnMode/saml/servicePrincipalType/Application/fromNav/) | | 2025-07-30 |\n| [AWS Single-Account Access](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/SignOn/objectId/dc89bf5d-83e8-4419-9162-3b9280a85755/appId/091edd89-b342-4bb5-9144-82fe6c913987/preferredSingleSignOnMode/saml/servicePrincipalType/Application/fromNav/) | | 2022-10-26 |\n| [Azure AD SAML Toolkit](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/SignOn/objectId/4317fd0a-dcee-45bf-8e94-9a66638b11e0/appId/6f5ed68c-9fad-4d78-bf88-2b16bbe16338/preferredSingleSignOnMode/saml/servicePrincipalType/Application/fromNav/) | | 2025-10-11 |\n| [Dropbox Business](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/SignOn/objectId/5eec0e98-b81a-422a-ab61-f8de2729330d/appId/f76d7d98-02ee-4e62-9345-36016a72e664/preferredSingleSignOnMode/saml/servicePrincipalType/Application/fromNav/) | | 2021-02-17 |\n| [charlie AWS Account](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/SignOn/objectId/39861745-eda1-4e3c-8358-d0ba931f12bb/appId/d3a04f85-a969-436b-bf4d-eae0a91efb4c/preferredSingleSignOnMode/saml/servicePrincipalType/Application/fromNav/) | | 2025-01-07 |\n| [charlie- Genesys Cloud for Azure](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/SignOn/objectId/84dc13ec-5754-4745-90f9-5cc92a5ded28/appId/9c599cd2-9fb0-4815-b65c-83be33f5df1b/preferredSingleSignOnMode/saml/servicePrincipalType/Application/fromNav/) | | 2025-07-30 |\n| [P2P Server](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/SignOn/objectId/05c98ca9-d208-4d3e-ad24-911bfc3d028c/appId/2af9f5c5-0ffc-4d1c-ba2e-72cf6382df06/preferredSingleSignOnMode/saml/servicePrincipalType/Application/fromNav/) | | 2023-06-11 |\n| [SPO Version](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/SignOn/objectId/4c780b09-998f-4b35-b41f-b125dc9f729a/appId/2d6d9bf1-1f6e-48cf-bb02-31beec2f442e/preferredSingleSignOnMode/saml/servicePrincipalType/Application/fromNav/) | | 2023-11-17 |\n| [Salesforce](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/SignOn/objectId/13720002-03b6-462f-ac2f-765f0f9b3f58/appId/1a2a1d4c-1d76-44ec-95f4-3ed5345423a9/preferredSingleSignOnMode/saml/servicePrincipalType/Application/fromNav/) | | 2022-10-02 |\n| [Saml test entity id](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/SignOn/objectId/d589a2e6-4a78-4cdd-901b-f574dc7880db/appId/6590313e-1c00-4c07-be28-72858e837a52/preferredSingleSignOnMode/saml/servicePrincipalType/Application/fromNav/) | | 2022-11-17 |\n| [ServiceNow](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/SignOn/objectId/9a8af246-0d94-42eb-aaaf-836a9f9a4974/appId/ecbbb1c8-ef06-48c4-9211-9ffbfbc24b94/preferredSingleSignOnMode/saml/servicePrincipalType/Application/fromNav/) | | 2021-02-15 |\n| [SumoLogic](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/SignOn/objectId/144df581-a0c9-4280-9739-0c3612ab9ccf/appId/1b6c36b2-f2b1-43d3-b74f-8d52c44fc9c1/preferredSingleSignOnMode/saml/servicePrincipalType/Application/fromNav/) | | 2024-02-15 |\n| [claimtest](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/SignOn/objectId/f7b07e81-79a0-4e51-b93a-169b8f2f6c4e/appId/f816d68b-aec7-4eab-9ebc-bd23b0d04e35/preferredSingleSignOnMode/saml/servicePrincipalType/Application/fromNav/) | | 2025-02-26 |\n| [test](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/SignOn/objectId/31e80a1b-3faa-4ce9-9794-2b77f61f20f7/appId/8ae2b566-71f5-467e-8960-cfe8da3a2cfa/preferredSingleSignOnMode/saml/servicePrincipalType/Application/fromNav/) | | 2022-10-10 |\n\n\n","TestStatus":"Failed","TestDescription":"If certificates aren't rotated regularly, they can give threat actors an extended window to extract and exploit them, leading to unauthorized access. When credentials like these are exposed, attackers can blend their malicious activities with legitimate operations, making it easier to bypass security controls. If an attacker compromises an application’s certificate, they can escalate their privileges within the system, leading to broader access and control, depending on the application's privileges.\n\nQuery all of your service principals and application registrations that have certificate credentials. Make sure the certificate start date is less than 180 days.\n\n**Remediation action**\n\n- [Define an application management policy to manage certificate lifetimes](https://learn.microsoft.com/graph/api/resources/applicationauthenticationmethodpolicy?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci)\n- [Define a trusted certificate chain of trust](https://learn.microsoft.com/graph/api/resources/certificatebasedapplicationconfiguration?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci)\n- [Create a least privileged custom role to rotate application credentials](https://learn.microsoft.com/entra/identity/role-based-access-control/custom-create?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci) \n- [Learn more about app management policies to manage certificate based credentials](https://devblogs.microsoft.com/identity/app-management-policy/)\n","TestId":"21992"},{"TestImplementationCost":"Low","TestPillar":"Identity","TestCategory":"Access control","SkippedReason":null,"TestImpact":"Low","TestAppliesTo":["Identity"],"TestSfiPillar":"Protect identities and secrets","TestSkipped":"","TestMinimumLicense":"P1","TestTags":["Identity"],"TestTitle":"User sign-in activity uses token protection","TestRisk":"High","TestResult":"\nThe tenant is missing properly configured Token Protection policies.\n\n","TestStatus":"Failed","TestDescription":"A threat actor can intercept or extract authentication tokens from memory, local storage on a legitimate device, or by inspecting network traffic. The attacker might replay those tokens to bypass authentication controls on users and devices, get unauthorized access to sensitive data, or run further attacks. Because these tokens are valid and time bound, traditional anomaly detection often fails to flag the activity, which might allow sustained access until the token expires or is revoked.\n\nToken protection, also called token binding, helps prevent token theft by making sure a token is usable only from the intended device. Token protection uses cryptography so that without the client device key, no one can use the token.\n\n**Remediation action**\n\n- [Deploy a Conditional Access policy to require token protection](https://learn.microsoft.com/entra/identity/conditional-access/concept-token-protection?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci)\n","TestId":"21786"},{"TestImplementationCost":"High","TestPillar":"Identity","TestCategory":"Monitoring","SkippedReason":"This test is for tenants that are licensed for Entra Workload ID. See [Entra Workload ID licensing](https://learn.microsoft.com/entra/workload-id/workload-identities-faqs)","TestImpact":"Low","TestAppliesTo":null,"TestSfiPillar":"Protect identities and secrets","TestSkipped":"NotLicensedEntraWorkloadID","TestMinimumLicense":"P2","TestTags":null,"TestTitle":"All risky workload identity sign-ins are triaged","TestRisk":"High","TestResult":"\nSkipped. This test is for tenants that are licensed for Entra Workload ID. See [Entra Workload ID licensing](https://learn.microsoft.com/entra/workload-id/workload-identities-faqs)\n\n","TestStatus":"Skipped","TestDescription":"Threat actors increasingly target workload identities (applications, service principals, and managed identities) because they lack human factors and often use long-lived credentials. A compromise often looks like the following path:\n\n1. Credential abuse or key theft.\n1. Non-interactive sign-ins to cloud resources.\n1. Lateral movement via app permissions.\n1. Persistence through new secrets or role assignments.\n\nMicrosoft Entra ID Protection continuously generates risky workload identity detections and flags sign-in events with risk state and detail. Risky workload identity sign-ins that aren’t triaged (confirmed compromised, dismissed, or marked safe), detection fatigue, and a large alert backlog can be challenging for IT admins to manage. This heavy workload can let repeated malicious access, privilege escalation, and token replay to continue to go unnoticed. To make the workload manageable, address risky workload identity sign-ins in two parts:\n\n- Close the loop: Triage sign-ins and record an authoritative decision on each risky event.\n- Drive containment: Disable the service principal, rotate credentials, or revoke sessions.\n\n**Remediation action**\n\n- [Investigate risky workload identities and perform appropriate remediation ](https://learn.microsoft.com/entra/id-protection/concept-workload-identity-risk?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci)\n- [Dismiss workload identity risks when determined to be false positives](https://learn.microsoft.com/graph/api/riskyserviceprincipal-dismiss?view=graph-rest-1.0&preserve-view=true&wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci)\n- [Confirm compromised workload identities when risks are validated](https://learn.microsoft.com/graph/api/riskyserviceprincipal-confirmcompromised?view=graph-rest-1.0&preserve-view=true&wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci)\n","TestId":22659},{"TestImplementationCost":"Medium","TestPillar":"Identity","TestCategory":"Privileged access","SkippedReason":null,"TestImpact":"Low","TestAppliesTo":null,"TestSfiPillar":"Protect identities and secrets","TestSkipped":"","TestMinimumLicense":"Free","TestTags":null,"TestTitle":"High Global Administrator to privileged user ratio","TestRisk":"High","TestResult":"\nMore than 50% of privileged role assignments in the tenant are Global Administrator.\n## Privileged role assignment summary\n\n**Global administrator role count:** 22 (55%) - ❌ Failed\n\n**Other privileged role count:** 18 (45%)\n\n## User privileged role assignments\n\n| User | Global administrator | Other Privileged Role(s) |\n| :--- | :------------------- | :------ |\n| [Alex Johnson](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/AdministrativeRole/userId/e436ca15-3a39-4dcc-819e-7dbb246cd46b/hidePreviewBanner~/true) | Yes | Application Administrator |\n| [Hayden Scott](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/AdministrativeRole/userId/c0b65b13-37b1-4081-bcfc-14844159b4a5/hidePreviewBanner~/true) | Yes | - |\n| [Jordan Smith](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/AdministrativeRole/userId/bfaeba1e-1357-47de-9557-529caa103d5d/hidePreviewBanner~/true) | Yes | AI Administrator, Application Administrator |\n| [Taylor Brown](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/AdministrativeRole/userId/2072badc-3cf0-4e84-b4c2-f9c065c46165/hidePreviewBanner~/true) | Yes | - |\n| [Morgan Wilson](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/AdministrativeRole/userId/5655cf54-34bc-4f36-bb74-44da35547975/hidePreviewBanner~/true) | Yes | - |\n| [Cameron Anderson](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/AdministrativeRole/userId/1ce4078f-f795-4baf-aa55-1fdfcc2ebfe6/hidePreviewBanner~/true) | Yes | Global Reader, Security Administrator |\n| [Avery Thomas](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/AdministrativeRole/userId/f431700c-6d81-45b8-8f8d-581a8aa7cda6/hidePreviewBanner~/true) | Yes | - |\n| [Quinn Garcia](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/AdministrativeRole/userId/ceef37b7-c865-48fb-80c9-4def11201854/hidePreviewBanner~/true) | Yes | - |\n| [Jamie Rodriguez](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/AdministrativeRole/userId/0b37813c-ae19-4399-982f-16587f17f9c0/hidePreviewBanner~/true) | Yes | - |\n| [Jules Bailey](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/AdministrativeRole/userId/0145d508-50fd-4f86-a47a-bf1c043c8358/hidePreviewBanner~/true) | Yes | - |\n| [Reese Harris](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/AdministrativeRole/userId/babe04c9-8340-4329-a727-a8cee0cd2b1a/hidePreviewBanner~/true) | Yes | - |\n| [Peyton Clark](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/AdministrativeRole/userId/7e92f268-bb12-469a-a869-210d596d4c1f/hidePreviewBanner~/true) | Yes | Global Reader |\n| [Charlie Lewis](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/AdministrativeRole/userId/5b0ec3ff-cea1-4eb9-8530-f2a66e5bec0a/hidePreviewBanner~/true) | Yes | - |\n| [Finley Robinson](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/AdministrativeRole/userId/990fd38a-c516-4e3f-82e4-d458a1ab0f91/hidePreviewBanner~/true) | Yes | Global Reader |\n| [Ash Williams](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/AdministrativeRole/userId/513f3db2-044c-41be-af14-431bf88a2b3e/hidePreviewBanner~/true) | Yes | - |\n| [Drew Mitchell](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/AdministrativeRole/userId/df02402a-e291-42cc-b449-79366daa2a40/hidePreviewBanner~/true) | Yes | Application Administrator, Global Reader |\n| [Ellis Cooper](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/AdministrativeRole/userId/1433571b-3d7c-4a56-a9cc-67580848bc73/hidePreviewBanner~/true) | Yes | - |\n| [Sage Bennett](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/AdministrativeRole/userId/518ce209-faf4-4717-add9-7129a669fa11/hidePreviewBanner~/true) | Yes | Agent ID Administrator, Global Reader, Privileged Role Administrator |\n| [Dakota Lee](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/AdministrativeRole/userId/210d3e96-015f-462d-b6d6-81e6023263df/hidePreviewBanner~/true) | Yes | - |\n| [Dakota Lee Test](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/AdministrativeRole/userId/43482f27-d1af-420f-84ba-e9148a700f45/hidePreviewBanner~/true) | Yes | - |\n| [Phoenix Gray](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/AdministrativeRole/userId/7094fb23-003a-4f81-9796-5daeaa603003/hidePreviewBanner~/true) | Yes | - |\n| [Avery Brooks](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/AdministrativeRole/userId/a85798bd-652b-4eb9-ba90-3ee882df0179/hidePreviewBanner~/true) | Yes | - |\n| [Hayden Scott Test](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/AdministrativeRole/userId/6f467d0a-25ec-435c-8fb9-9d53eb21e02f/hidePreviewBanner~/true) | No | Global Reader |\n| [Hayden Scott](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/AdministrativeRole/userId/0d6cfd05-fc46-440b-b605-66dd26dcd7d2/hidePreviewBanner~/true) | No | Global Reader |\n| [Casey Davis](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/AdministrativeRole/userId/58d9ed99-93ca-4674-8c5f-ec770f5ba17d/hidePreviewBanner~/true) | No | Global Reader |\n| [ash-williams-test](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/AdministrativeRole/userId/c5c8ba63-4620-4e91-ac40-b66bebe07a0d/hidePreviewBanner~/true) | No | Global Reader |\n| [Riley Martinez](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/AdministrativeRole/userId/653c7fdd-1b41-4229-992a-69cc35aad4f7/hidePreviewBanner~/true) | No | Application Administrator |\n| [Dakota Lee](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/AdministrativeRole/userId/e4bc6f4a-124f-469b-8951-3d5c34fb9741/hidePreviewBanner~/true) | No | User Administrator |\n| [Skylar White](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/AdministrativeRole/userId/2a054082-8f05-4e05-8fce-4e35c3bb40cc/hidePreviewBanner~/true) | No | Application Administrator |\n| [peyton-test](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/AdministrativeRole/userId/e0952dcb-8d63-496d-8661-05c86c1a51f0/hidePreviewBanner~/true) | No | Global Reader |\n| [finley-test](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/AdministrativeRole/userId/d71ccc09-c0a3-4604-9d02-49f7a3715f49/hidePreviewBanner~/true) | No | Global Reader |\n| [Sam Parker](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/AdministrativeRole/userId/96d29f01-873c-46a3-b542-f7ee192cc675/hidePreviewBanner~/true) | No | Application Administrator |\n| [parker-test](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/AdministrativeRole/userId/c1bdb03c-0079-40b1-96a8-3595de3b94a2/hidePreviewBanner~/true) | No | Global Reader |\n\n\n","TestStatus":"Failed","TestDescription":"When organizations maintain a disproportionately high ratio of Global Administrators relative to their total privileged user population, they expose themselves to significant security risks that threat actors might exploit through various attack vectors. Excessive Global Administrator assignments create multiple high-value targets for threat actors who might leverage initial access through credential compromise, phishing attacks, or insider threats to gain unrestricted access to the entire Microsoft Entra ID tenant and connected Microsoft 365 services. \n\n**Remediation action**\n\n- [Minimize the number of Global Administrator role assignments](https://learn.microsoft.com/entra/identity/role-based-access-control/best-practices?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci#5-limit-the-number-of-global-administrators-to-less-than-5)\n","TestId":"21813"},{"TestImplementationCost":"Low","TestPillar":"Devices","TestCategory":"Tenant","SkippedReason":null,"TestImpact":"Medium","TestAppliesTo":null,"TestSfiPillar":"Protect tenants and isolate production systems","TestSkipped":"","TestMinimumLicense":"Intune","TestTags":null,"TestTitle":"Compliance Policy for Android Enterprise Personally-Owned Work Profile is configured and assigned","TestRisk":"High","TestResult":"\nAt least one compliance policy for Android Enterprise Personally-Owned Work Profile exists and is assigned.\n\n\n## Compliance policy assignment for Android Enterprise Fully managed device is configured and assigned\n\n| Policy Name | Status | Assignment |\n| :---------- | :----- | :--------- |\n| [My android personally-owned](https://intune.microsoft.com/#view/Microsoft_Intune_DeviceSettings/DevicesComplianceMenu/~/policies) | ✅ Assigned | **Included:** aad-conditional-access-allow-legacy-auth, **Excluded:** Executive Management, HR |\n\n\n","TestStatus":"Passed","TestDescription":"If compliance policies aren't assigned to Android Enterprise personally owned devices in Intune, threat actors can exploit noncompliant endpoints to gain unauthorized access to corporate resources, bypass security controls, and introduce vulnerabilities. Without enforced compliance, devices can lack critical security configurations like passcode requirements, data storage encryption, and OS version controls. These gaps increase the risk of data leakage and unauthorized access. Inconsistent device compliance weakens the organization’s security posture and makes it harder to detect and remediate threats before significant damage occurs.\n\nEnforcing compliance policies ensures that personally owned Android devices meet core security requirements and supports Zero Trust by validating device health and reducing exposure to misconfigured or unmanaged endpoints.\n\n**Remediation action**\n\nCreate and assign Intune compliance policies to Android Enterprise personally owned devices to enforce organizational standards for secure access and management: \n- [Create a compliance policy in Microsoft Intune](https://learn.microsoft.com/intune/intune-service/protect/create-compliance-policy?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci#create-the-policy)\n- [Review the Android Enterprise compliance settings you can manage with Intune](https://learn.microsoft.com/intune/intune-service/protect/compliance-policy-create-android-for-work?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci)\n","TestId":"24547"},{"TestImplementationCost":"Low","TestPillar":"Identity","TestCategory":"Access control","SkippedReason":null,"TestImpact":"Low","TestAppliesTo":null,"TestSfiPillar":"Protect tenants and isolate production systems","TestSkipped":"","TestMinimumLicense":"P1","TestTags":null,"TestTitle":"Enable protected actions to secure Conditional Access policy creation and changes","TestRisk":"High","TestResult":"\n\n### Conditional Access Policies by Protected Action\n\n#### Update basic properties for Conditional Access policies - ✅ Pass\n\n**Auth Context:** Require FIDO2 key (ID: c1)\n\n| Display Name | State | Authentication Context | Authentication Strength | Device Filters | SignIn Frequency |\n| :--- | :--- | :--- | :--- | :--- | :--- |\n| [AuthContext: Require FIDO2 ](https://entra.microsoft.com/#view/Microsoft_AAD_ConditionalAccess/PolicyBlade/policyId/) | Enabled | Require FIDO2 key | ✅ | ❌ | ✅ |\n| [Test-PA](https://entra.microsoft.com/#view/Microsoft_AAD_ConditionalAccess/PolicyBlade/policyId/) | Disabled | Require FIDO2 key,MFA,Strong auth | ✅ | ❌ | ✅ |\n\n#### Create Conditional Access policies - ✅ Pass\n\n**Auth Context:** Require FIDO2 key (ID: c1)\n\n| Display Name | State | Authentication Context | Authentication Strength | Device Filters | SignIn Frequency |\n| :--- | :--- | :--- | :--- | :--- | :--- |\n| [AuthContext: Require FIDO2 ](https://entra.microsoft.com/#view/Microsoft_AAD_ConditionalAccess/PolicyBlade/policyId/) | Enabled | Require FIDO2 key | ✅ | ❌ | ✅ |\n| [Test-PA](https://entra.microsoft.com/#view/Microsoft_AAD_ConditionalAccess/PolicyBlade/policyId/) | Disabled | Require FIDO2 key,MFA,Strong auth | ✅ | ❌ | ✅ |\n\n#### Delete Conditional Access policies - ✅ Pass\n\n**Auth Context:** Require FIDO2 key (ID: c1)\n\n| Display Name | State | Authentication Context | Authentication Strength | Device Filters | SignIn Frequency |\n| :--- | :--- | :--- | :--- | :--- | :--- |\n| [AuthContext: Require FIDO2 ](https://entra.microsoft.com/#view/Microsoft_AAD_ConditionalAccess/PolicyBlade/policyId/) | Enabled | Require FIDO2 key | ✅ | ❌ | ✅ |\n| [Test-PA](https://entra.microsoft.com/#view/Microsoft_AAD_ConditionalAccess/PolicyBlade/policyId/) | Disabled | Require FIDO2 key,MFA,Strong auth | ✅ | ❌ | ✅ |\n\n#### Update Conditional Access authentication context of Microsoft 365 role-based access control (RBAC) resource actions - ✅ Pass\n\n**Auth Context:** Require FIDO2 key (ID: c1)\n\n| Display Name | State | Authentication Context | Authentication Strength | Device Filters | SignIn Frequency |\n| :--- | :--- | :--- | :--- | :--- | :--- |\n| [AuthContext: Require FIDO2 ](https://entra.microsoft.com/#view/Microsoft_AAD_ConditionalAccess/PolicyBlade/policyId/) | Enabled | Require FIDO2 key | ✅ | ❌ | ✅ |\n| [Test-PA](https://entra.microsoft.com/#view/Microsoft_AAD_ConditionalAccess/PolicyBlade/policyId/) | Disabled | Require FIDO2 key,MFA,Strong auth | ✅ | ❌ | ✅ |\n\n\n\n","TestStatus":"Passed","TestDescription":"Threat actors who gain privileged access to a tenant can manipulate Conditional Access policies, potentially disabling critical security controls and enabling persistent access or lateral movement. This type of attack can result in environment-wide compromise by bypassing authentication and authorization barriers.\n\nProtected actions let administrators secure Conditional Access policy creation and modification with extra security controls, such as stronger authentication methods (passwordless MFA or phishing-resistant MFA), the use of Privileged Access Workstation (PAW) devices, or shorter session timeouts.\n\n**Remediation action**\n\n- [Add, test, or remove protected actions in Microsoft Entra ID](https://learn.microsoft.com/entra/identity/role-based-access-control/protected-actions-add?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci)\n","TestId":21964},{"TestImplementationCost":"Medium","TestPillar":"Identity","TestCategory":"Access control","SkippedReason":"UnderConstruction","TestImpact":"Low","TestAppliesTo":["Identity"],"TestSfiPillar":"Protect identities and secrets","TestSkipped":"UnderConstruction","TestMinimumLicense":null,"TestTags":["Identity"],"TestTitle":"GDAP admin least privilege","TestRisk":"Medium","TestResult":"\nPlanned for future release.\n","TestStatus":"Planned","TestDescription":"...\n\n**Remediation action**\n\n","TestId":"21859"},{"TestImplementationCost":"Low","TestPillar":"Devices","TestCategory":"Tenant","SkippedReason":null,"TestImpact":"Low","TestAppliesTo":null,"TestSfiPillar":"Protect tenants and isolate production systems","TestSkipped":"","TestMinimumLicense":"Intune","TestTags":null,"TestTitle":"Company Portal branding and support settings enhance user experience and trust","TestRisk":"Medium","TestResult":"\nNo Company Portal branding profile with support settings exists or none are assigned.\n\n\n## Company Portal Branding Profiles\n\n| Profile Name | Branding Properties | Status | Assignment Target |\n| :----------- | :------------------ | :----- | :---------------- |\n| [Default Branding profile.](https://intune.microsoft.com/#view/Microsoft_Intune_DeviceSettings/TenantAdminMenu/~/companyPortalBranding) | **Display Name**: Pora Labs Inc., **Contact Phone**: Not configured, **Contact Email**: ash@contoso.com | N/A | N/A |\n\n\n\n","TestStatus":"Failed","TestDescription":"If the Intune Company Portal branding isn't configured to represent your organization’s details, users can encounter a generic interface and lack direct support information. This reduces user trust, increases support overhead, and can lead to confusion or delays in resolving issues.\n\nCustomizing the Company Portal with your organization’s branding and support contact details improves user trust, streamlines support, and reinforces the legitimacy of device management communications.\n\n\n**Remediation action**\n\nConfigure the Intune Company Portal with your organization’s branding and support contact information to enhance user experience and reduce support overhead: \n- [Configure the Intune Company Portal](https://learn.microsoft.com/intune/intune-service/apps/company-portal-app?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci)\n","TestId":"24823"},{"TestImplementationCost":"Medium","TestPillar":null,"TestCategory":"Application management","SkippedReason":"UnderConstruction","TestImpact":"Low","TestAppliesTo":["Identity"],"TestSfiPillar":"","TestSkipped":"UnderConstruction","TestMinimumLicense":null,"TestTags":["Identity"],"TestTitle":"Use recent versions of Microsoft Applications","TestRisk":"Medium","TestResult":"\nPlanned for future release.\n","TestStatus":"Planned","TestDescription":"...\n\n**Remediation action**\n\n","TestId":"21779"},{"TestImplementationCost":"Medium","TestPillar":"Identity","TestCategory":"Access control","SkippedReason":null,"TestImpact":"Low","TestAppliesTo":null,"TestSfiPillar":"Protect identities and secrets","TestSkipped":"","TestMinimumLicense":"P1","TestTags":null,"TestTitle":"Token protection policies are configured","TestRisk":"Medium","TestResult":"\nToken protection policies are configured.\n\n### Token protection policy summary\n\nThe table below lists all the token protection Conditional Access policies found in the tenant.\n\n| Name | Policy state | Users | Applications | Token protection | Status |\n| :--- | :---: | :---: | :---: | :---: | :---: |\n| [Token protection](https://entra.microsoft.com/#view/Microsoft_AAD_ConditionalAccess/PolicyBlade/policyId/ff7b71d1-fa63-4073-a959-4790f299de0f) | 🟡 Report-only | All | Selected | 🟢 | ❌ Fail |\n| [token protection with 1 apps](https://entra.microsoft.com/#view/Microsoft_AAD_ConditionalAccess/PolicyBlade/policyId/c51217bf-4044-4001-bfe6-ed8ef2624beb) | 🟢 Enabled | Selected | Selected | 🟢 | ✅ Pass |\n\n","TestStatus":"Passed","TestDescription":"Token protection policies in Entra ID tenants are crucial for safeguarding authentication tokens from misuse and unauthorized access. Without these policies, threat actors can intercept and manipulate tokens, leading to unauthorized access to sensitive resources. This can result in data exfiltration, lateral movement within the network, and potential compromise of privileged accounts.\n\nWhen token protection is not properly configured, threat actors can exploit several attack vectors:\n\n1. **Token theft and replay attacks** - Attackers can steal authentication tokens from compromised devices and replay them from different locations\n2. **Session hijacking** - Without secure sign-in session controls, attackers can hijack legitimate user sessions\n3. **Cross-platform token abuse** - Tokens issued for one platform (like mobile) can be misused on other platforms (like web browsers)\n4. **Persistent access** - Compromised tokens can provide long-term unauthorized access without triggering security alerts\n\nThe attack chain typically involves initial access through token theft, followed by privilege escalation and persistence, ultimately leading to data exfiltration and impact across the organization's Microsoft 365 environment.\n\n**Remediation action**\n- [Configure Conditional Access policies as per the best practices](https://learn.microsoft.com/en-us/entra/identity/conditional-access/concept-token-protection#create-a-conditional-access-policy)\n- [Microsoft Entra Conditional Access token protection explained](https://learn.microsoft.com/en-us/entra/identity/conditional-access/concept-token-protection)\n- [Configure session controls in Conditional Access](https://learn.microsoft.com/en-us/entra/identity/conditional-access/concept-conditional-access-session)\n\n","TestId":21941},{"TestImplementationCost":"High","TestPillar":"Identity","TestCategory":"Access control","SkippedReason":"UnderConstruction","TestImpact":"Low","TestAppliesTo":["Identity"],"TestSfiPillar":"Protect identities and secrets","TestSkipped":"UnderConstruction","TestMinimumLicense":null,"TestTags":["Identity"],"TestTitle":"Application Certificate Credentials are managed using HSM","TestRisk":"Low","TestResult":"\nPlanned for future release.\n","TestStatus":"Planned","TestDescription":"...\n\n**Remediation action**\n\n","TestId":"21895"},{"TestImpact":"High","TestRisk":"Low","TestSkipped":"","TestAppliesTo":null,"TestPillar":"Data","TestCategory":"Encryption","TestDescription":"Double Key Encryption (DKE) provides an extra layer of protection for highly sensitive data by requiring two keys to decrypt content: one managed by Microsoft and one by the customer. This \"hold your own key\" approach ensures Microsoft can't decrypt content even with legal compulsion, meeting stringent regulatory requirements for data sovereignty.\n\nHowever, DKE introduces significant operational complexity including dedicated key service infrastructure, reduced feature compatibility, and increased support burden. Organizations should maintain 1-3 labels reserved for truly mission-critical or heavily regulated data, with documented business justification for each DKE label. Use standard encryption for general business content. Excessive DKE labels (4 or more) create management overhead, user confusion, and reduce collaboration. DKE should never be broadly deployed, as key service unavailability prevents access to business-critical documents.\n\n**Remediation action**\n\n- [Double Key Encryption](https://learn.microsoft.com/purview/double-key-encryption?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci)\n- [Set up Double Key Encryption](https://learn.microsoft.com/purview/double-key-encryption-setup?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci)\n","TestTitle":"Double Key Encryption (DKE) Labels","SkippedReason":null,"TestId":"35010","TestImplementationCost":"Medium","TestMinimumLicense":["RMS_S_PREMIUM2"],"TestSfiPillar":"Protect tenants and production systems","TestResult":"\n✅ DKE labels appropriately deployed (1-3 labels for mission-critical and regulated data).\n\n\n### Summary\n\n- Total Sensitivity Labels: 9\n- DKE Enabled Labels: 1\n\n### [Sensitivity Label Details](https://purview.microsoft.com/informationprotection/informationprotectionlabels/sensitivitylabels)\n\n| Label name | Disabled | DKE enabled | DKE endpoint url |\n|:-----------|:---------|:------------|:-----------------|\n| test-dke | False | True | https://entra.microsoft.com/#view/Microsoft_AAD_IAM/DirectoryRolesBlade |\n| alex-test-label-1 | False | False | N/A |\n| parker | False | False | N/A |\n| Confidential – RMS | False | False | N/A |\n| peyton | False | False | N/A |\n| test-35012-1 | False | False | N/A |\n| test-35012 | False | False | N/A |\n| test35036 | False | False | N/A |\n| 35014-parker | False | False | N/A |\n\n\n","TestStatus":"Passed","TestTags":null},{"TestImpact":"Medium","TestRisk":"High","TestSkipped":"","TestAppliesTo":null,"TestPillar":"Data","TestCategory":"Advanced Classification","TestDescription":"Custom sensitive information types (SITs) extend Microsoft Purview's built-in detection to cover organization-specific data patterns, proprietary identifiers, internal classification schemes, specialized industry codes, or other formats that built-in SITs don't match. Without custom SITs, auto-labeling policies and data loss prevention (DLP) rules rely exclusively on generic patterns and might miss sensitive data unique to your organization.\n\n**Remediation action**\n\n- [Create custom sensitive information types](https://learn.microsoft.com/purview/create-a-custom-sensitive-information-type?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci)\n","TestTitle":"Custom Sensitive Information Types (SITs) Configured","SkippedReason":null,"TestId":"35033","TestImplementationCost":"High","TestMinimumLicense":["EXCHANGE_S_ENTERPRISE"],"TestSfiPillar":"Protect tenants and production systems","TestResult":"\n✅ Custom Sensitive Information Types are configured, enabling detection of organization-specific sensitive data patterns.\n\n## [Custom Sensitive Information Types](https://purview.microsoft.com/informationprotection/dataclassification/sensinfoTypes)\n\n| Name | Description | Publisher |\n| :--- | :--- | :--- |\n| test-1 | testing | Pora Inc. |\n| test-35033 | custom SIT | Pora Inc. |\n\n**Summary:**\n* Total Custom SITs: 2\n\n\n","TestStatus":"Passed","TestTags":null},{"TestImplementationCost":"Low","TestPillar":"Devices","TestCategory":"Data","SkippedReason":null,"TestImpact":"Medium","TestAppliesTo":null,"TestSfiPillar":"Protect tenants and isolate production systems","TestSkipped":"","TestMinimumLicense":"Intune","TestTags":null,"TestTitle":"Non-compliant Devices are Restricted from Accessing Corporate Data ","TestRisk":"High","TestResult":"\nNo conditional access policy with device compliance exists for one or more platforms, and no policy applies to all platforms.\n\n\n## Conditional Access Policies with Device Compliance\n\n| Policy Name | Platforms |\n| :---------- | :-------- |\n| [\\[ellis\\] - Require app protection policy](https://intune.microsoft.com/#view/Microsoft_AAD_ConditionalAccess/ConditionalAccessBlade/~/Policies) | android, iOS |\n\n\n","TestStatus":"Failed","TestDescription":"If Microsoft Entra Conditional Access policies don't enforce device compliance, users can connect to corporate resources from devices that don't meet security standards. This exposes sensitive data to risks like malware, unauthorized access, and regulatory noncompliance. Without controls like encryption enforcement, device health checks, and access restrictions, threat actors can exploit noncompliant devices to bypass security measures and maintain persistence.\n\n\nRequiring device compliance in Conditional Access policies ensures only trusted and secure devices can access corporate resources. This supports Zero Trust by enforcing access decisions based on device health and compliance posture.\n\n**Remediation action**\n\nConfigure Conditional Access policies in Microsoft Entra to require device compliance before granting access to corporate resources: \n- [Create a device compliance-based Conditional Access policy](https://learn.microsoft.com/intune/intune-service/protect/create-conditional-access-intune?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci)\n\nFor more information, see:\n- [What is Conditional Access?](https://learn.microsoft.com/entra/identity/conditional-access/overview?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci)\n- [Integrate device compliance results with Conditional Access](https://learn.microsoft.com/intune/intune-service/protect/device-compliance-get-started?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci#integrate-with-conditional-access)\n","TestId":"24824"},{"TestImplementationCost":"Medium","TestPillar":"Identity","TestCategory":"Application management","SkippedReason":null,"TestImpact":"Low","TestAppliesTo":null,"TestSfiPillar":"Protect identities and secrets","TestSkipped":"","TestMinimumLicense":"Free","TestTags":null,"TestTitle":"Enforce standards for app secrets and certificates","TestRisk":"Medium","TestResult":"\n❌ Tenant app management policy is enabled but lacks active credential restrictions.`n`n\n\n## Policy configuration assessment\n\n| Property | Status | Value |\n| :------- | :----- | :---- |\n| Policy enabled | ✅ Yes | True |\n\n### Configuration details\n\n**Application restrictions**: ✅ Configured\n\n| Credential type | Restriction type | State | Status |\n| :-------------- | :--------------- | :---- | :----- |\n| Password credentials | passwordAddition | disabled | ⚠️ Configured but inactive |\n| Password credentials | symmetricKeyAddition | disabled | ⚠️ Configured but inactive |\n\n**Service principal restrictions**: ✅ Configured\n\n| Credential type | Restriction type | State | Status |\n| :-------------- | :--------------- | :---- | :----- |\n| Password credentials | passwordAddition | disabled | ⚠️ Configured but inactive |\n| Password credentials | symmetricKeyAddition | disabled | ⚠️ Configured but inactive |\n\n\n\n","TestStatus":"Failed","TestDescription":"Without proper application management policies, threat actors can exploit weak or misconfigured application credentials to get unauthorized access to organizational resources. Applications using long-lived password secrets or certificates create extended attack windows where compromised credentials stay valid for extended periods. If an application uses client secrets that are hardcoded in configuration files or have weak password requirements, threat actors can extract these credentials through different means, including source code repositories, configuration dumps, or memory analysis. If threat actors get these credentials, they can perform lateral movement within the environment, escalate privileges if the application has elevated permissions, establish persistence by creating more backdoor credentials, modify application configuration, or exfiltrate data. The lack of credential lifecycle management lets compromised credentials remain active indefinitely, giving threat actors sustained access to organizational assets and the ability to conduct data exfiltration, system manipulation, or deploy more malicious tools without detection. \n\nConfiguring appropriate app management policies helps organizations stay ahead of these threats.\n\n**Remediation action**\n\n- [Learn how to enforce secret and certificate standards using application management policies](https://learn.microsoft.com/entra/identity/enterprise-apps/tutorial-enforce-secret-standards?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci)\n","TestId":"21775"},{"TestImplementationCost":"Low","TestPillar":"Identity","TestCategory":"Privileged access","SkippedReason":null,"TestImpact":"Low","TestAppliesTo":null,"TestSfiPillar":"Protect engineering systems","TestSkipped":"","TestMinimumLicense":"Free","TestTags":null,"TestTitle":"Global Administrators don't have standing elevated access to all Azure subscriptions in the tenant","TestRisk":"High","TestResult":"\nStanding access to Root Management group was found.\n\n\n## Entra ID objects with standing access to Root Management group\n\n\n| Entra ID Object | Object ID | Principal type |\n| :-------------- | :-------- | :------------- |\n| ash@contoso.com | 513f3db2-044c-41be-af14-431bf88a2b3e | User |\n| charlie@contoso.com | 5b0ec3ff-cea1-4eb9-8530-f2a66e5bec0a | User |\n| peyton@contoso.com | 7e92f268-bb12-469a-a869-210d596d4c1f | User |\n| finley.robinson@contoso.com | 990fd38a-c516-4e3f-82e4-d458a1ab0f91 | User |\n| cameron@contoso.com | 1ce4078f-f795-4baf-aa55-1fdfcc2ebfe6 | User |\n| hayden@contoso.com | c0b65b13-37b1-4081-bcfc-14844159b4a5 | User |\n\n\n\n","TestStatus":"Failed","TestDescription":"Global Administrators with persistent access to Azure subscriptions expand the attack surface for threat actors. If a Global Administrator account is compromised, attackers can immediately enumerate resources, modify configurations, assign roles, and exfiltrate sensitive data across all subscriptions. Requiring just-in-time elevation for subscription access introduces detectable signals, slows attacker velocity, and routes high-impact operations through observable control points.\n\n**Remediation action**\n\n- [Get started with a phishing-resistant passwordless authentication deployment](https://learn.microsoft.com/entra/identity/authentication/how-to-plan-prerequisites-phishing-resistant-passwordless-authentication?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci)\n\n- [Ensure that privileged accounts register and use phishing resistant methods](https://learn.microsoft.com/entra/identity/authentication/concept-authentication-strengths?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci#authentication-strengths.md)\n\n- [Deploy Conditional Access policy to target privileged accounts and require phishing resistant credentials using authentication strengths](https://learn.microsoft.com/entra/identity/conditional-access/policy-admin-phish-resistant-mfa?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci)\n\n- [Monitor authentication method activity](https://learn.microsoft.com/entra/identity/monitoring-health/concept-usage-insights-report?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci#authentication-methods-activity.md)\n","TestId":"21788"},{"TestImplementationCost":"High","TestPillar":"Identity","TestCategory":"Monitoring","SkippedReason":null,"TestImpact":"Low","TestAppliesTo":["Identity"],"TestSfiPillar":"Monitor and detect cyberthreats","TestSkipped":"","TestMinimumLicense":"P2","TestTags":["Identity"],"TestTitle":"All risky users are triaged","TestRisk":"High","TestResult":"\nFound **1** untriaged high-risk users in Entra ID Protection.\n## Untriaged High-Risk Users\n\n| User | Risk level | Last updated | Risk detail |\n| :----------------- | :--------- | :-------------------- | :---------- |\n| finley.robinson@contoso.com | High | 05/05/2026 06:06:46 | none |\n\n\n","TestStatus":"Failed","TestDescription":"Users considered at high risk by Microsoft Entra ID Protection have a high probability of compromise by threat actors. Threat actors can gain initial access via compromised valid accounts, where their suspicious activities continue despite triggering risk indicators. This oversight can enable persistence as threat actors perform activities that normally warrant investigation, such as unusual login patterns or suspicious inbox manipulation. \n\nA lack of triage of these risky users allows for expanded reconnaissance activities and lateral movement, with anomalous behavior patterns continuing to generate uninvestigated alerts. Threat actors become emboldened as security teams show they aren't actively responding to risk indicators.\n\n**Remediation action**\n\n- [Investigate high risk users](https://learn.microsoft.com/entra/id-protection/howto-identity-protection-investigate-risk?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci) in Microsoft Entra ID Protection\n- [Remediate high risk users and unblock](https://learn.microsoft.com/entra/id-protection/howto-identity-protection-remediate-unblock?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci) in Microsoft Entra ID Protection\n","TestId":"21861"},{"TestImplementationCost":"Medium","TestPillar":"Identity","TestCategory":"Application management","SkippedReason":null,"TestImpact":"Medium","TestAppliesTo":["Identity"],"TestSfiPillar":"Protect identities and secrets","TestSkipped":"","TestMinimumLicense":"Free","TestTags":["Application"],"TestTitle":"Applications don't have secrets configured","TestRisk":"High","TestResult":"\nFound 46 applications and 16 service principals with client secrets configured.\n\n\n## Applications with client secrets\n\n| Application | Secret expiry |\n| :--- | :--- |\n| [AWS Account](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/ApplicationMenuBlade/~/Credentials/appId/2e311a1d-f5c0-41c6-b866-77af3289871e) | 2024-02-11 |\n| [Agent Identity Blueprint Example 12612901](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/ApplicationMenuBlade/~/Credentials/appId/ef1e370e-626b-4839-9340-83e62875489a) | 2026-05-25 |\n| [Agent Identity Blueprint Example 3792929](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/ApplicationMenuBlade/~/Credentials/appId/60253969-9e44-4e0b-85c0-abda1041272c) | 2026-11-02 |\n| [Agent Identity Blueprint Example 4208296](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/ApplicationMenuBlade/~/Credentials/appId/d0e3212f-58a2-4511-8b56-bd57b023106d) | 2026-02-16 |\n| [Agent Identity Blueprint Example 4208710](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/ApplicationMenuBlade/~/Credentials/appId/e79effd2-67cf-4caa-8879-b87389f47819) | 2026-02-16 |\n| [Agent Identity Blueprint Example 4209295](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/ApplicationMenuBlade/~/Credentials/appId/f522f080-5192-4665-87a4-e1211b7adca6) | 2026-02-16 |\n| [Agent0 API](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/ApplicationMenuBlade/~/Credentials/appId/a8a4a52c-9f15-4e2a-a8fe-c267cc3a6101) | 2026-05-28 |\n| [Atlassian - Jira](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/ApplicationMenuBlade/~/Credentials/appId/b0e53e94-b4b0-4632-98ae-e230af1f511c) | 2026-03-16 |\n| [Automation](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/ApplicationMenuBlade/~/Credentials/appId/dc7d83b5-d38b-4488-8952-7abf02e71590) | 2325-01-01 |\n| [Chopin Agent](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/ApplicationMenuBlade/~/Credentials/appId/7dcdc7c5-09a6-435f-9460-9382d32b7bc6) | 2026-02-18 |\n| [Entry Kiosk](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/ApplicationMenuBlade/~/Credentials/appId/b903f17a-87b0-460b-9978-962c812e4f98) | 2021-11-25 |\n| [Graph Filter](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/ApplicationMenuBlade/~/Credentials/appId/c94b2f6c-f4c2-4ab3-8d1a-6971b2c7e975) | 2024-09-16 |\n| [Graph PowerShell - Privileged Perms](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/ApplicationMenuBlade/~/Credentials/appId/c5338ce0-3e9e-4895-8f49-5e176836a348) | 2024-05-15 |\n| [GraphPermissionApp](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/ApplicationMenuBlade/~/Credentials/appId/d36fe320-bc28-40c8-a141-a512d65d112c) | 2027-10-26 |\n| [InfinityDemo](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/ApplicationMenuBlade/~/Credentials/appId/fef811e1-2354-43b0-961b-248fe15e737d) | 2022-11-02 |\n| [Lokka](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/ApplicationMenuBlade/~/Credentials/appId/f581405a-9e57-4e81-91f1-40cd62f7595e) | 2026-10-01 |\n| [M365PronounKit](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/ApplicationMenuBlade/~/Credentials/appId/eea28244-3eec-4820-beae-d4a2c0bcc235) | 2022-03-29 |\n| [Maester DevOps Account - GitHub - Secret (demo)](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/ApplicationMenuBlade/~/Credentials/appId/d0dc5f0a-bf75-41a4-9272-d5ec2345c963) | 2026-02-20 |\n| [Mailbox Migration Account](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/ApplicationMenuBlade/~/Credentials/appId/b650c3c1-3395-40bb-8471-2a6a8b76d8a9) | 2022-08-19 |\n| [Manson Nov 13 Test](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/ApplicationMenuBlade/~/Credentials/appId/d65bd82c-b625-48cd-b485-f61939b48727) | 2026-11-02 |\n| [Manson Test Agent](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/ApplicationMenuBlade/~/Credentials/appId/e6e0e568-682d-4640-a038-2f2489b1d2aa) | 2026-02-16 |\n| [Manson-Test-Nov13](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/ApplicationMenuBlade/~/Credentials/appId/516489b4-b179-4230-b149-440b5c78a7cc) | 2026-11-02 |\n| [MansonTestNov24](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/ApplicationMenuBlade/~/Credentials/appId/d4407e7a-9644-4e25-8df5-6e6da95a9013) | 2026-02-16 |\n| [Message Center](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/ApplicationMenuBlade/~/Credentials/appId/83f76a08-fa60-48e6-9cb5-fd8ced5ae314) | 2026-02-17 |\n| [MessageCenterAccount github.com/manson/mc DO NOT DELETE](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/ApplicationMenuBlade/~/Credentials/appId/778fad36-e4c1-4d40-a58e-9b5b64179d41) | 2124-02-21 |\n| [MyTestForBlock](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/ApplicationMenuBlade/~/Credentials/appId/14a3ba45-3246-4fbe-8c3b-c3922e68232b) | 2025-07-06 |\n| [PnPPowerShell](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/ApplicationMenuBlade/~/Credentials/appId/1d93462e-0f39-4e4c-898a-b6b1df5fa997) | 2022-03-29 |\n| [Postman](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/ApplicationMenuBlade/~/Credentials/appId/7fb37b38-ce4f-4675-9263-0cd3404b4925) | 2023-10-16 |\n| [RemixTest](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/ApplicationMenuBlade/~/Credentials/appId/d4588485-154e-4b32-935f-31ceaf993cdc) | 2024-06-24 |\n| [SharePoint On-Prem App Proxy](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/ApplicationMenuBlade/~/Credentials/appId/19a70df3-cddf-48c7-be44-97b25b9857f1) | 2025-12-12 |\n| [SharePoint Version App](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/ApplicationMenuBlade/~/Credentials/appId/2bb68591-782c-4c64-9415-bdf9414ae400) | 2024-05-15 |\n| [Trello](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/ApplicationMenuBlade/~/Credentials/appId/d77611ee-5051-4383-9af3-5ba3627306a7) | 2022-08-16 |\n| [WPNinja1](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/ApplicationMenuBlade/~/Credentials/appId/eee88dc1-4aab-42b3-b089-4a2cbb19b048) | 2026-05-24 |\n| [WebApplication3](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/ApplicationMenuBlade/~/Credentials/appId/bcdb1ed5-9470-41e6-821b-1fc42ae94cfb) | 2022-11-02 |\n| [WebApplication3_20210211261232](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/ApplicationMenuBlade/~/Credentials/appId/ac49e193-bd5f-40fe-b4ff-e62136419388) | 2022-11-02 |\n| [WebApplication4](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/ApplicationMenuBlade/~/Credentials/appId/b2d1f868-27ee-4ecd-ae81-0ee96b028605) | 2022-04-03 |\n| [WingtipToys App](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/ApplicationMenuBlade/~/Credentials/appId/56a89db1-6ed2-4171-88f6-b4f7597dbce3) | 2025-11-27 |\n| [aadgraphmggraph](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/ApplicationMenuBlade/~/Credentials/appId/24b66505-1142-452f-9472-2ecbb37deac1) | 2022-11-26 |\n| [agent0-blueprint](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/ApplicationMenuBlade/~/Credentials/appId/00b6bee4-a638-4260-9382-09301b3a1db9) | 2026-02-27 |\n| [da-typespec-todo-aad](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/ApplicationMenuBlade/~/Credentials/appId/9358444a-41ec-4a93-915a-4970b3f33738) | 2026-06-04 |\n| [entra-docs-email github DO NOT DELETE](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/ApplicationMenuBlade/~/Credentials/appId/ae06b71a-a0aa-4211-b846-fd74f25ccd45) | 2027-07-14 |\n| [sptest1](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/ApplicationMenuBlade/~/Credentials/appId/022dac2c-8763-4a45-bc41-34cf58e8e35d) | 2026-08-02 |\n| [test](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/ApplicationMenuBlade/~/Credentials/appId/99fbef85-8df4-44c5-ac4e-ec93a88a9b5b) | 2026-08-15 |\n| [test](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/ApplicationMenuBlade/~/Credentials/appId/4f50c653-dae4-44e7-ae2e-a081cce1f830) | 2023-02-25 |\n| [testSP](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/ApplicationMenuBlade/~/Credentials/appId/e47d8f25-5327-40f8-99fe-d832b99d938d) | 2026-05-26 |\n| [testuserread](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/ApplicationMenuBlade/~/Credentials/appId/9fe2675c-7fc5-4895-8470-eed989ea0d63) | 2025-09-03 |\n\n\n## Service Principals with client secrets\n\n| Service principal | App owner tenant | Secret expiry |\n| :--- | :--- | :--- |\n| [21869testapp](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/SignOn/objectId//appId/dd63d132-18fb-4f2e-aec4-82b97f30301f/preferredSingleSignOnMode/saml/servicePrincipalType/Application/fromNav/) | | 2028-10-27 |\n| [APP-2732_Genesys Cloud TCCC-G-TFS-Prod](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/SignOn/objectId//appId/76249b01-8747-4db4-843f-6478d5b32b14/preferredSingleSignOnMode/saml/servicePrincipalType/Application/fromNav/) | | 2028-07-30 |\n| [AWS Single-Account Access](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/SignOn/objectId//appId/091edd89-b342-4bb5-9144-82fe6c913987/preferredSingleSignOnMode/saml/servicePrincipalType/Application/fromNav/) | | 2025-10-26 |\n| [Automation](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/SignOn/objectId//appId/dc7d83b5-d38b-4488-8952-7abf02e71590/preferredSingleSignOnMode/saml/servicePrincipalType/Application/fromNav/) | | 2027-03-03 |\n| [Azure AD SAML Toolkit](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/SignOn/objectId//appId/6f5ed68c-9fad-4d78-bf88-2b16bbe16338/preferredSingleSignOnMode/saml/servicePrincipalType/Application/fromNav/) | | 2028-10-11 |\n| [Dropbox Business](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/SignOn/objectId//appId/f76d7d98-02ee-4e62-9345-36016a72e664/preferredSingleSignOnMode/saml/servicePrincipalType/Application/fromNav/) | | 2024-02-17 |\n| [charlie AWS Account](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/SignOn/objectId//appId/d3a04f85-a969-436b-bf4d-eae0a91efb4c/preferredSingleSignOnMode/saml/servicePrincipalType/Application/fromNav/) | | 2028-01-07 |\n| [charlie- Genesys Cloud for Azure](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/SignOn/objectId//appId/9c599cd2-9fb0-4815-b65c-83be33f5df1b/preferredSingleSignOnMode/saml/servicePrincipalType/Application/fromNav/) | | 2028-07-30 |\n| [P2P Server](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/SignOn/objectId//appId/2af9f5c5-0ffc-4d1c-ba2e-72cf6382df06/preferredSingleSignOnMode/saml/servicePrincipalType/Application/fromNav/) | | 2024-06-11 |\n| [SPO Version](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/SignOn/objectId//appId/2d6d9bf1-1f6e-48cf-bb02-31beec2f442e/preferredSingleSignOnMode/saml/servicePrincipalType/Application/fromNav/) | | 2024-11-17 |\n| [Salesforce](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/SignOn/objectId//appId/1a2a1d4c-1d76-44ec-95f4-3ed5345423a9/preferredSingleSignOnMode/saml/servicePrincipalType/Application/fromNav/) | | 2025-10-02 |\n| [Saml test entity id](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/SignOn/objectId//appId/6590313e-1c00-4c07-be28-72858e837a52/preferredSingleSignOnMode/saml/servicePrincipalType/Application/fromNav/) | | 2025-11-17 |\n| [ServiceNow](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/SignOn/objectId//appId/ecbbb1c8-ef06-48c4-9211-9ffbfbc24b94/preferredSingleSignOnMode/saml/servicePrincipalType/Application/fromNav/) | | 2024-02-15 |\n| [SumoLogic](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/SignOn/objectId//appId/1b6c36b2-f2b1-43d3-b74f-8d52c44fc9c1/preferredSingleSignOnMode/saml/servicePrincipalType/Application/fromNav/) | | 2027-02-15 |\n| [claimtest](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/SignOn/objectId//appId/f816d68b-aec7-4eab-9ebc-bd23b0d04e35/preferredSingleSignOnMode/saml/servicePrincipalType/Application/fromNav/) | | 2028-02-26 |\n| [test](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/SignOn/objectId//appId/8ae2b566-71f5-467e-8960-cfe8da3a2cfa/preferredSingleSignOnMode/saml/servicePrincipalType/Application/fromNav/) | | 2025-10-10 |\n\n\n","TestStatus":"Failed","TestDescription":"Applications that use client secrets might store them in configuration files, hardcode them in scripts, or risk their exposure in other ways. The complexities of secret management make client secrets susceptible to leaks and attractive to attackers. Client secrets, when exposed, provide attackers with the ability to blend their activities with legitimate operations, making it easier to bypass security controls. If an attacker compromises an application's client secret, they can escalate their privileges within the system, leading to broader access and control, depending on the permissions of the application.\n\nApplications and service principals that have permissions for Microsoft Graph APIs or other APIs have a higher risk because an attacker can potentially exploit these additional permissions.\n\n**Remediation action**\n\n- [Move applications away from shared secrets to managed identities and adopt more secure practices](https://learn.microsoft.com/entra/identity/enterprise-apps/migrate-applications-from-secrets?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci).\n - Use managed identities for Azure resources\n - Deploy Conditional Access policies for workload identities\n - Implement secret scanning\n - Deploy application authentication policies to enforce secure authentication practices\n - Create a least-privileged custom role to rotate application credentials\n - Ensure you have a process to triage and monitor applications\n","TestId":"21772"},{"TestImpact":"High","TestRisk":"Medium","TestSkipped":"","TestAppliesTo":null,"TestPillar":"Data","TestCategory":"Sensitivity Labels Configuration","TestDescription":"Container labels extend sensitivity labels beyond individual items to entire collaboration workspaces like Microsoft Teams, Microsoft 365 Groups, and SharePoint sites. These labels control workspace-level settings such as external sharing, guest access, device restrictions, and privacy.\n\nWithout container labels, users might be able to create Teams with external guest access even when handling confidential information. This action creates data exfiltration risks where properly labeled documents exist in improperly secured workspaces. Container labels can help to ensure that workspace security matches the sensitivity of stored content, for example, prevent documents labeled as \"Highly Confidential\" from residing in Teams sites that permit external sharing.\n\n**Remediation action**\n\n- [Use sensitivity labels to protect content in Microsoft Teams, Microsoft 365 groups, and SharePoint sites](https://learn.microsoft.com/purview/sensitivity-labels-teams-groups-sites?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci)\n","TestTitle":"Container labels are configured for Teams, Groups, and Sites","SkippedReason":null,"TestId":"35012","TestImplementationCost":"Medium","TestMinimumLicense":["RMS_S_PREMIUM2"],"TestSfiPillar":"Protect tenants and production systems","TestResult":"\n❌ No container labels are configured (acceptable if Teams/Groups not used; may be a gap if collaboration workspaces exist).\n\n\n## Summary\n\n| Metric | Value |\n|:---|:---|\n| Total sensitivity labels | 9 |\n| Container-protected labels | 0 |\n\n\n\n","TestStatus":"Failed","TestTags":null},{"TestImpact":"Low","TestRisk":"High","TestSkipped":"","TestAppliesTo":null,"TestPillar":"Data","TestCategory":"Entra","TestDescription":"Microsoft Rights Management Service (RMS) is the protection technology that enforces encryption for sensitivity labels and information protection policies. When users access encrypted content, their applications must authenticate to the RMS service (App ID: `00000012-0000-0000-c000-000000000000`) to decrypt the content. If Conditional Access policies incorrectly block or restrict this authentication - for example, by requiring multi-factor authentication (MFA), device compliance, or specific network locations - users will be unable to open encrypted emails, documents, or files protected by sensitivity labels.\nThis is most notable when trying to collaborate on MIP protected content from an external tenant to the source tenant.\nThe RMS service should be explicitly excluded from Conditional Access policies that enforce authentication controls, as the application itself is handling the decryption and the user has already authenticated through their primary client application. Blocking RMS authentication prevents the decryption process and breaks information protection workflows across Microsoft 365 services including Outlook, Word, Excel, PowerPoint, Teams, and SharePoint.\n\n**Remediation action**\n\nTo exclude RMS from Conditional Access policies:\n1. Navigate to [Microsoft Entra admin center > Entra ID > Conditional Access > Policies](https://entra.microsoft.com/#view/Microsoft_AAD_ConditionalAccess/ConditionalAccessBlade/~/Policies)\n2. Select the policy that is blocking RMS\n3. Under Target resources > All resources (formerly 'All cloud apps')\n4. Under Exclude, select 'Select resources' and add \"Microsoft Rights Management Services\" (App ID: `00000012-0000-0000-c000-000000000000`)\n5. Save the policy\n\n- [Microsoft Entra configuration for Azure Information Protection](https://learn.microsoft.com/purview/encryption-azure-ad-configuration)\n- [Conditional Access policies and encrypted documents](https://learn.microsoft.com/purview/encryption-azure-ad-configuration#conditional-access-policies-and-encrypted-documents)\n- [Conditional Access: Cloud apps, actions, and authentication context](https://learn.microsoft.com/entra/identity/conditional-access/concept-conditional-access-cloud-apps)\n\n","TestTitle":"Conditional Access RMS Exclusions","SkippedReason":null,"TestId":"35001","TestImplementationCost":"Low","TestMinimumLicense":["RMS_S_PREMIUM2"],"TestSfiPillar":"","TestResult":"\n❌ Microsoft Rights Management Service (RMS) is blocked or restricted by one or more Conditional Access policies.\n\n**Policies Affecting RMS:**\n\n| Policy Name | State | RMS Targeted | RMS Excluded | Grant Controls | Session Controls |\n| :--- | :--- | :--- | :--- | :--- | :--- |\n| [MFA - All users](https://entra.microsoft.com/#view/Microsoft_AAD_ConditionalAccess/PolicyBlade/policyId/474ddef4-5620-4e7a-8976-6e9b095b2675) | enabled | Yes | No | mfa | None |\n| [Guest-Meferna-Woodgrove-PhishingResistantAuthStrength](https://entra.microsoft.com/#view/Microsoft_AAD_ConditionalAccess/PolicyBlade/policyId/0f0a0c1c-41b0-4c18-ae20-d02492d03737) | enabled | Yes | No | None | None |\n| [Block Device Code](https://entra.microsoft.com/#view/Microsoft_AAD_ConditionalAccess/PolicyBlade/policyId/db2153a1-40a2-457f-917c-c280b204b5cd) | enabled | Yes | No | block | None |\n| [Block access except Compliant Network](https://entra.microsoft.com/#view/Microsoft_AAD_ConditionalAccess/PolicyBlade/policyId/9ee6df4b-165d-4f86-a176-0ddcc4ad886c) | enabled | Yes | No | block | None |\n| [ZTA Test - Block AI Agents with High Risk](https://entra.microsoft.com/#view/Microsoft_AAD_ConditionalAccess/PolicyBlade/policyId/a2eb4554-6a7e-4b08-8212-ca8fa3e67e32) | enabled | Yes | No | block | None |\n| [ZT-Test Agent Users](https://entra.microsoft.com/#view/Microsoft_AAD_ConditionalAccess/PolicyBlade/policyId/38498fd7-41cb-4fc3-8c88-513d4b13f0f1) | enabled | Yes | No | block | None |\n\n","TestStatus":"Failed","TestTags":null},{"TestImplementationCost":"Medium","TestPillar":"Identity","TestCategory":"Access control","SkippedReason":"UnderConstruction","TestImpact":"Low","TestAppliesTo":["Identity"],"TestSfiPillar":"Protect identities and secrets","TestSkipped":"UnderConstruction","TestMinimumLicense":null,"TestTags":["Identity"],"TestTitle":"All certificates Microsoft Entra Application Registrations and Service Principals must be issued by an approved certification authority","TestRisk":"Low","TestResult":"\nPlanned for future release.\n","TestStatus":"Planned","TestDescription":"...\n\n**Remediation action**\n\n","TestId":"21894"},{"TestImplementationCost":"Low","TestPillar":"Identity","TestCategory":"Credential management, Privileged access","SkippedReason":null,"TestImpact":"Low","TestAppliesTo":null,"TestSfiPillar":"Protect identities and secrets","TestSkipped":"","TestMinimumLicense":"P1","TestTags":null,"TestTitle":"Block administrators from using SSPR","TestRisk":"High","TestResult":"\n✅ Administrators are properly blocked from using Self-Service Password Reset, ensuring password changes go through controlled processes.\n\n","TestStatus":"Passed","TestDescription":"Self-Service Password Reset (SSPR) for administrators allows password changes to happen without strong secondary authentication factors or administrative oversight. Threat actors who compromise administrative credentials can use this capability to bypass other security controls and maintain persistent access to the environment.\n\nOnce compromised, attackers can immediately reset the password to lock out legitimate administrators. They can then establish persistence, escalate privileges, and deploy malicious payloads undetected.\n\n**Remediation action**\n\n- [Disable SSPR for administrators by updating the authorization policy](https://learn.microsoft.com/entra/identity/authentication/concept-sspr-policy?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci#administrator-reset-policy-differences)\n","TestId":"21842"},{"TestImplementationCost":"Low","TestPillar":"Identity","TestCategory":"External collaboration","SkippedReason":null,"TestImpact":"Low","TestAppliesTo":null,"TestSfiPillar":"Protect tenants and isolate production systems","TestSkipped":"","TestMinimumLicense":"Free","TestTags":null,"TestTitle":"Guest self-service sign-up via user flow is disabled","TestRisk":"Medium","TestResult":"\n[Guest self-service sign up via user flow](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/CompanyRelationshipsMenuBlade/~/Settings/menuId/ExternalIdentitiesGettingStarted) is disabled.\n\n\n","TestStatus":"Passed","TestDescription":"When guest self-service sign-up is enabled, threat actors can exploit it to establish unauthorized access by creating legitimate guest accounts without requiring approval from authorized personnel. These accounts can be scoped to specific services to reduce detection and effectively bypass invitation-based controls that validate external user legitimacy.\n\nOnce created, self-provisioned guest accounts provide persistent access to organizational resources and applications. Threat actors can use them to conduct reconnaissance activities to map internal systems, identify sensitive data repositories, and plan further attack vectors. This persistence allows adversaries to maintain access across restarts, credential changes, and other interruptions, while the guest account itself offers a seemingly legitimate identity that might evade security monitoring focused on external threats.\n\nAdditionally, compromised guest identities can be used to establish credential persistence and potentially escalate privileges. Attackers can exploit trust relationships between guest accounts and internal resources, or use the guest account as a staging ground for lateral movement toward more privileged organizational assets.\n\n**Remediation action**\n- [Configure guest self-service sign-up With Microsoft Entra External ID](https://learn.microsoft.com/entra/external-id/external-collaboration-settings-configure?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci#to-configure-guest-self-service-sign-up)\n","TestId":"21823"},{"TestImpact":"Medium","TestRisk":"Medium","TestSkipped":"","TestAppliesTo":null,"TestPillar":"Data","TestCategory":"Information Protection","TestDescription":"Without retention policies, emails persist indefinitely in user mailboxes, creating liability for regulatory violations (GDPR, HIPAA, SOX), increased eDiscovery costs, and uncontrolled storage expenses.\n\nRetention policies automatically manage email lifecycle by deleting or preserving messages based on compliance requirements, reducing legal risk, and ensuring regulatory record-keeping obligations are met.\n\n**Remediation action**\n\n- [Create and manage retention policies](https://learn.microsoft.com/purview/create-retention-policies?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci)\n","TestTitle":"Email retention policies are configured","SkippedReason":null,"TestId":"35028","TestImplementationCost":"Medium","TestMinimumLicense":["RMS_S_PREMIUM"],"TestSfiPillar":"Protect tenants and production systems","TestResult":"\n❌ No email retention policies are configured for Exchange Online, creating a compliance and legal risk where emails are retained indefinitely and eDiscovery scope is uncontrolled.\n\n\n### [Retention policies with Exchange scope](https://purview.microsoft.com/datalifecyclemanagement/retention)\n\n| Policy name | Enabled | Exchange scope | Mode |\n| :--- | :--- | :--- | :--- |\n| Email Retention - Standard | ❌ No | All | Enforce |\n| Email Retention - Tergeted | ❌ No | Finley Robinson | Enforce |\n\n\n### Retention rules for Exchange policies\n\n| Rule name | Parent policy | Enabled | Retention action | Retention period |\n| :--- | :--- | :--- | :--- | :--- |\n| Email Retention - Standard | Email Retention - Standard | ✅ Yes | KeepAndDelete | 2555 (Days) |\n| Email Retention - Tergeted | Email Retention - Tergeted | ✅ Yes | Keep | Unlimited (Days) |\n\n### Summary\n\n| Metric | Value |\n| :--- | :--- |\n| Total retention policies | 4 |\n| Enabled Exchange policies | 0 |\n| Active retention rules (Exchange) | 2 |\n\n","TestStatus":"Failed","TestTags":null},{"TestImplementationCost":"Low","TestPillar":"Identity","TestCategory":"Credential management","SkippedReason":null,"TestImpact":"Low","TestAppliesTo":null,"TestSfiPillar":"Protect identities and secrets","TestSkipped":"","TestMinimumLicense":"P1","TestTags":null,"TestTitle":"Temporary access pass is enabled","TestRisk":"Medium","TestResult":"\nTemporary Access Pass is enabled, targeting all users, and enforced with conditional access policies.\n\n**Configuration summary**\n\n[Temporary Access Pass](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/AuthenticationMethodsMenuBlade/~/AdminAuthMethods/fromNav/Identity): Enabled ✅\n\n[Conditional Access policy for Security info registration](https://entra.microsoft.com/#view/Microsoft_AAD_ConditionalAccess/ConditionalAccessBlade/~/Policies/fromNav/Identity): Enabled ✅\n\n[Authentication strength policy for Temporary Access Pass](https://entra.microsoft.com/#view/Microsoft_AAD_ConditionalAccess/AuthenticationStrength.ReactView/fromNav/Identity): Enabled ✅\n\n\n","TestStatus":"Passed","TestDescription":"Without Temporary Access Pass (TAP) enabled, organizations face significant challenges in securely bootstrapping user credentials, creating a vulnerability where users rely on weaker authentication mechanisms during their initial setup. When users cannot register phishing-resistant credentials like FIDO2 security keys or Windows Hello for Business due to lack of existing strong authentication methods, they remain exposed to credential-based attacks including phishing, password spray, or similar attacks. Threat actors can exploit this registration gap by targeting users during their most vulnerable state, when they have limited authentication options available and must rely on traditional username + password combinations. This exposure enables threat actors to compromise user accounts during the critical bootstrapping phase, allowing them to intercept or manipulate the registration process for stronger authentication methods, ultimately gaining persistent access to organizational resources and potentially escalating privileges before security controls are fully established. \n\nEnable TAP and use it with security info registration to secure this potential gap in your defenses.\n\n**Remediation action**\n\n- [Learn how to enable Temporary Access Pass in the Authentication methods policy](https://learn.microsoft.com/entra/identity/authentication/howto-authentication-temporary-access-pass?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci#enable-the-temporary-access-pass-policy)\n- [Learn how to update authentication strength policies to include Temporary Access Pass](https://learn.microsoft.com/entra/identity/authentication/concept-authentication-strength-advanced-options?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci)\n- [Learn how to create a Conditional Access policy for security info registration with authentication strength enforcement](https://learn.microsoft.com/entra/identity/conditional-access/policy-all-users-security-info-registration?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci)\n","TestId":"21845"},{"TestImplementationCost":"Low","TestPillar":"Devices","TestCategory":"Tenant","SkippedReason":null,"TestImpact":"Low","TestAppliesTo":null,"TestSfiPillar":"Protect tenants and isolate production systems","TestSkipped":"","TestMinimumLicense":"Intune","TestTags":null,"TestTitle":"Automatic Enrollment to Defender is enabled for Android Devices","TestRisk":"High","TestResult":"\nNo Microsoft Defender for Endpoint Connector found in the tenant.\n\n\n\n","TestStatus":"Failed","TestDescription":"If automatic enrollment into Microsoft Defender for Endpoint isn't configured for Android devices in Intune, managed endpoints might remain unprotected against mobile threats. Without Defender onboarding, devices lack advanced threat detection and response capabilities, increasing the risk of malware, phishing, and other mobile-based attacks. Unprotected devices can bypass security policies, access corporate resources, and expose sensitive data to compromise. This gap in mobile threat defense weakens the organization's Zero Trust posture and reduces visibility into endpoint health.\n\nEnabling automatic Defender enrollment ensures Android devices are protected by advanced threat detection and response capabilities. This supports Zero Trust by enforcing mobile threat protection, improving visibility, and reducing exposure to unmanaged or compromised endpoints.\n\n**Remediation action**\n\nUse Intune to configure automatic enrollment into Microsoft Defender for Endpoint for Android devices to enforce mobile threat protection:\n\n- [Integrate Microsoft Defender for Endpoint with Intune and Onboard Devices](https://learn.microsoft.com/intune/intune-service/protect/advanced-threat-protection-configure?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci)\n","TestId":"24871"},{"TestImplementationCost":"Low","TestPillar":"Identity","TestCategory":"Access control","SkippedReason":"UnderConstruction","TestImpact":"Low","TestAppliesTo":["Identity"],"TestSfiPillar":"Monitor and detect cyberthreats","TestSkipped":"UnderConstruction","TestMinimumLicense":"P2","TestTags":["Identity"],"TestTitle":"ID Protection notifications enabled","TestRisk":"High","TestResult":"\nPlanned for future release.\n\n","TestStatus":"Planned","TestDescription":"If you don't enable ID Protection notifications, your organization loses critical real-time alerts when threat actors compromise user accounts or conduct reconnaissance activities. When Microsoft Entra ID Protection detects accounts at risk, it sends email alerts with **Users at risk detected** as the subject and links to the **Users flagged for risk** report. Without these notifications, security teams remain unaware of active threats, allowing threat actors to maintain persistence in compromised accounts without being detected. You can feed these risks into tools like Conditional Access to make access decisions or send them to a security information and event management (SIEM) tool for investigation and correlation. Threat actors can use this detection gap to conduct lateral movement activities, privilege escalation attempts, or data exfiltration operations while administrators remain unaware of the ongoing compromise. The delayed response enables threat actors to establish more persistence mechanisms, change user permissions, or access sensitive resources before you can fix the issue. Without proactive notification of risk detections, organizations must rely solely on manual monitoring of risk reports, which significantly increases the time it takes to detect and respond to identity-based attacks. \n\n**Remediation action**\n\n- [Configure users at risk detected alerts](https://learn.microsoft.com/entra/id-protection/howto-identity-protection-configure-notifications?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci#configure-users-at-risk-detected-alerts)\n","TestId":"21798"},{"TestImplementationCost":"Medium","TestPillar":"Identity","TestCategory":"Application management","SkippedReason":null,"TestImpact":"High","TestAppliesTo":["Identity"],"TestSfiPillar":"Protect identities and secrets","TestSkipped":"","TestMinimumLicense":"Free","TestTags":["Identity"],"TestTitle":"User consent settings are restricted","TestRisk":"High","TestResult":"\n✅ **Pass**: User consent settings are properly restricted to prevent illicit consent grant attacks.\n\n\n## Authorization Policy Configuration\n\n\n**Current [user consent settings](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ConsentPoliciesMenuBlade/~/UserSettings)**\n\n- Allow user consent for apps from verified publishers, for selected permissions (Recommended).\nAll users can consent for permissions classified as \"low impact\", for apps from verified publishers or apps registered in this organization.\n\n\n","TestStatus":"Passed","TestDescription":"Without restricted user consent settings, threat actors can exploit permissive application consent configurations to gain unauthorized access to sensitive organizational data. When user consent is unrestricted, attackers can:\n\n- Use social engineering and illicit consent grant attacks to trick users into approving malicious applications.\n- Impersonate legitimate services to request broad permissions, such as access to email, files, calendars, and other critical business data.\n- Obtain legitimate OAuth tokens that bypass perimeter security controls, making access appear normal to security monitoring systems.\n- Establish persistent access to organizational resources, conduct reconnaissance across Microsoft 365 services, move laterally through connected systems, and potentially escalate privileges.\n\nUnrestricted user consent also limits an organization's ability to enforce centralized governance over application access, making it difficult to maintain visibility into which non-Microsoft applications have access to sensitive data. This gap creates compliance risks where unauthorized applications might violate data protection regulations or organizational security policies.\n\n**Remediation action**\n\n- [Configure restricted user consent settings](https://learn.microsoft.com/entra/identity/enterprise-apps/configure-user-consent?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci) to prevent illicit consent grants by disabling user consent or limiting it to verified publishers with low-risk permissions only.\n","TestId":"21776"},{"TestImplementationCost":"Low","TestPillar":"Identity","TestCategory":"Access control","SkippedReason":"UnderConstruction","TestImpact":"Low","TestAppliesTo":["Identity"],"TestSfiPillar":"Protect identities and secrets","TestSkipped":"UnderConstruction","TestMinimumLicense":null,"TestTags":["Identity"],"TestTitle":"All privileged role assignments have a recipient that can receive notifications","TestRisk":"Medium","TestResult":"\nPlanned for future release.\n","TestStatus":"Planned","TestDescription":"...\n\n**Remediation action**\n\n","TestId":"21899"},{"TestImplementationCost":"High","TestPillar":"Identity","TestCategory":"Access control","SkippedReason":null,"TestImpact":"High","TestAppliesTo":["Identity"],"TestSfiPillar":"Protect identities and secrets","TestSkipped":"","TestMinimumLicense":"P1","TestTags":["Identity"],"TestTitle":"Use cloud authentication","TestRisk":"High","TestResult":"\nAll domains are using cloud authentication.\n\n\n\n","TestStatus":"Passed","TestDescription":"An on-premises federation server introduces a critical attack surface by serving as a central authentication point for cloud applications. Threat actors often gain a foothold by compromising a privileged user such as a help desk representative or an operations engineer through attacks like phishing, credential stuffing, or exploiting weak passwords. They might also target unpatched vulnerabilities in infrastructure, use remote code execution exploits, attack the Kerberos protocol, or use pass-the-hash attacks to escalate privileges. Misconfigured remote access tools like remote desktop protocol (RDP), virtual private network (VPN), or jump servers provide other entry points, while supply chain compromises or malicious insiders further increase exposure. Once inside, threat actors can manipulate authentication flows, forge security tokens to impersonate any user, and pivot into cloud environments. Establishing persistence, they can disable security logs, evade detection, and exfiltrate sensitive data.\n\n**Remediation action**\n\n- [Migrate from federation to cloud authentication like Microsoft Entra Password hash synchronization (PHS)](https://learn.microsoft.com/entra/identity/hybrid/connect/migrate-from-federation-to-cloud-authentication?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci).\n","TestId":"21829"},{"TestImplementationCost":"Medium","TestPillar":"Identity","TestCategory":"Devices","SkippedReason":null,"TestImpact":"Low","TestAppliesTo":null,"TestSfiPillar":"Protect identities and secrets","TestSkipped":"","TestMinimumLicense":"P1","TestTags":null,"TestTitle":"Local Admin Password Solution is deployed","TestRisk":"High","TestResult":"\nLocal Admin Password Solution is deployed.\n## Local Admin Password Solution (LAPS) settings\n\n| Setting | Status |\n| :---- | :---- |\n|[Enable Microsoft Entra Local Administrator Password Solution (LAPS)](https://entra.microsoft.com/#view/Microsoft_AAD_Devices/DevicesMenuBlade/~/DeviceSettings/menuId/Overview) | Enabled\n\n\n","TestStatus":"Passed","TestDescription":"Without Local Admin Password Solution (LAPS) deployed, threat actors exploit static local administrator passwords to establish initial access. After threat actors compromise a single device with a shared local administrator credential, they can move laterally across the environment and authenticate to other systems sharing the same password. Compromised local administrator access gives threat actors system-level privileges, letting them disable security controls, install persistent backdoors, exfiltrate sensitive data, and establish command and control channels. \n\nThe automated password rotation and centralized management of LAPS closes this security gap and adds controls to help manage who has access to these critical accounts. Without solutions like LAPS, you can't detect or respond to unauthorized use of local administrator accounts, giving threat actors extended dwell time to achieve their objectives while remaining undetected.\n\n**Remediation action**\n\n- [Configure Windows Local Administrator Password Solution](https://learn.microsoft.com/entra/identity/devices/howto-manage-local-admin-passwords?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci).\n","TestId":"21953"},{"TestImplementationCost":"Low","TestPillar":"Identity","TestCategory":"Access control","SkippedReason":"UnderConstruction","TestImpact":"Low","TestAppliesTo":["Identity"],"TestSfiPillar":"Protect identities and secrets","TestSkipped":"UnderConstruction","TestMinimumLicense":null,"TestTags":["Identity"],"TestTitle":"Use PIM for Microsoft Entra privileged roles","TestRisk":"Medium","TestResult":"\nPlanned for future release.\n","TestStatus":"Planned","TestDescription":"...\n\n**Remediation action**\n\n","TestId":"21876"},{"TestImplementationCost":"Medium","TestPillar":"Identity","TestCategory":"External collaboration","SkippedReason":null,"TestImpact":"Low","TestAppliesTo":["Identity"],"TestSfiPillar":"Protect tenants and isolate production systems","TestSkipped":"","TestMinimumLicense":"Free","TestTags":["Identity"],"TestTitle":"Guests don't own apps in the tenant","TestRisk":"Medium","TestResult":"\nNo guest users own any applications or service principals in the tenant.\n\n","TestStatus":"Passed","TestDescription":"Without restrictions preventing guest users from registering and owning applications, threat actors can exploit external user accounts to establish persistent backdoor access to organizational resources through application registrations that might evade traditional security monitoring. When guest users own applications, compromised guest accounts can be used to exploit guest-owned applications that might have broad permissions. This vulnerability enables threat actors to request access to sensitive organizational data such as emails, files, and user information without the same level of scrutiny for internal user-owned applications.\n\nThis attack vector is dangerous because guest-owned applications can be configured to request high-privilege permissions and, once granted consent, provide threat actors with legitimate OAuth tokens. Furthermore, guest-owned applications can serve as command and control infrastructure, so threat actors can maintain access even after the compromised guest account is detected and remediated. Application credentials and permissions might persist independently of the original guest user account, so threat actors can retain access. Guest-owned applications also complicate security auditing and governance efforts, as organizations might have limited visibility into the purpose and security posture of applications registered by external users. These hidden weaknesses in the application lifecycle management make it difficult to assess the true scope of data access granted to non-Microsoft entities through seemingly legitimate application registrations.\n\n**Remediation action**\n- Remove guest users as owners from applications and service principals, and implement controls to prevent future guest user application ownership.\n- [Restrict guest user access permissions](https://learn.microsoft.com/entra/identity/users/users-restrict-guest-permissions?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci)\n","TestId":"21868"},{"TestImplementationCost":"Low","TestPillar":"Devices","TestCategory":"Tenant","SkippedReason":null,"TestImpact":"Low","TestAppliesTo":null,"TestSfiPillar":"Protect tenants and isolate production systems","TestSkipped":"","TestMinimumLicense":"Intune","TestTags":null,"TestTitle":"Intune Scope Tags are Configured for Delegated Administration","TestRisk":"Medium","TestResult":"\nDelegated administration is enforced with custom Intune Scope Tags assignments.\n\n\n## Scope Tags\n\n| Scope Tag Name | Status | Assignment Target |\n| :------------- | :----- | :---------------- |\n| [Biscope](https://intune.microsoft.com/#view/Microsoft_Intune_DeviceSettings/RolesLandingMenuBlade/~/scopeTags) | ✅ Assigned | **Included:** aad-conditional-access-excluded |\n\n\n\n","TestStatus":"Passed","TestDescription":"If Intune scope tags aren't properly configured for delegated administration, attackers who gain privileged access to Intune or Microsoft Entra ID can escalate privileges and access sensitive device configurations across the tenant. Without granular scope tags, administrative boundaries are unclear, allowing attackers to move laterally, manipulate device policies, exfiltrate configuration data, or deploy malicious settings to all users and devices. A single compromised admin account can impact the entire environment. The absence of delegated administration also undermines least-privileged access, making it difficult to contain breaches and enforce accountability. Attackers might exploit global administrator roles or misconfigured role-based access control (RBAC) assignments to bypass compliance policies and gain broad control over device management.\n\nEnforcing scope tags segments administrative access and aligns it with organizational boundaries. This limits the blast radius of compromised accounts, supports least-privilege access, and aligns with Zero Trust principles of segmentation, role-based control, and containment.\n\n**Remediation action**\n\nUse Intune scope tags and RBAC roles to limit admin access based on role, geography, or business unit: \n- [Learn how to create and deploy scope tags for distributed IT](https://learn.microsoft.com/intune/intune-service/fundamentals/scope-tags?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci)\n- [Implement role-based access control with Microsoft Intune](https://learn.microsoft.com/intune/intune-service/fundamentals/role-based-access-control?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci)\n","TestId":"24555"},{"TestImpact":"Low","TestRisk":"Medium","TestSkipped":"","TestAppliesTo":null,"TestPillar":"Data","TestCategory":"Information Protection","TestDescription":"OCR (optical character recognition) extends sensitive information type and trainable classifier detection to images across Exchange, SharePoint, OneDrive, Teams, and endpoint devices. Without OCR, DLP policies, and auto-labeling policies can't scan image-based content, scanned documents, screenshots, and invoices, leaving sensitive data in images unprotected. OCR requires Azure pay-as-you-go billing for Microsoft Syntex, and is configured at the tenant level.\n\n**Remediation action**\n\n- [Learn about and configure optical character recognition in Microsoft Purview](https://learn.microsoft.com/purview/ocr-learn-about?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci)\n","TestTitle":"OCR is enabled for sensitive information detection","SkippedReason":null,"TestId":"35023","TestImplementationCost":"Medium","TestMinimumLicense":["EXCHANGE_S_ENTERPRISE"],"TestSfiPillar":"Protect tenants and production systems","TestResult":"\n❌ OCR is configured but disabled at the tenant level.\n\n\n### OCR configuration status\n\n| Setting | Value |\n| :------ | :---- |\n| Configuration object exists | Yes |\n| OCR enabled (Tenant-level) | False |\n| Exchange location enabled | True |\n| SharePoint location enabled | True |\n| OneDrive location enabled | True |\n| Teams location enabled | True |\n| Endpoint location enabled | True |\n| OCR usage blocked | False |\n| Blockage reason | None |\n| Azure billing status | Configured |\n\n\n**Summary:**\n\n- OCR configuration: Configured\n- Active locations: 5\n\n[Microsoft Purview portal > Settings > Optical character recognition (OCR)](https://purview.microsoft.com/)\n\n\n","TestStatus":"Failed","TestTags":null},{"TestImplementationCost":"Medium","TestPillar":"Identity","TestCategory":"Access control","SkippedReason":null,"TestImpact":"High","TestAppliesTo":["Identity"],"TestSfiPillar":"Accelerate response and remediation","TestSkipped":"","TestMinimumLicense":"P2","TestTags":["Identity"],"TestTitle":"Restrict access to high risk users","TestRisk":"High","TestResult":"\nPasswordless authentication is enabled, but no policies to block high risk users are configured.\n## Passwordless Authentication Methods allowed in tenant\n\n| Authentication Method Name | State | Additional Info |\n| :------------------------ | :---- | :-------------- |\n| Fido2 | enabled | |\n\n## Conditional Access Policies targeting high risk users\n\nNo conditional access policies targeting high risk users found.\n\n### Inactive policies targeting high risk users (not contributing to security posture):\n\n| Conditional Access Policy Name | Status | Conditions |\n| :--------------------- | :----- | :--------- |\n| [Require password change for high-risk users](https://entra.microsoft.com/#view/Microsoft_AAD_ConditionalAccess/PolicyBlade/policyId/ddbc3bb1-3749-474f-b8c3-0d997118b24b) | Report-only | User Risk Level: High, Control: Block |\n| [Force Password Change](https://entra.microsoft.com/#view/Microsoft_AAD_ConditionalAccess/PolicyBlade/policyId/5848211d-96f2-40ae-92a4-af1aa8f48572) | Disabled | User Risk Level: High, Control: Password Change |\n| [CISA SCuBA.MS.AAD.2.3: Users detected as high risk SHALL be blocked.](https://entra.microsoft.com/#view/Microsoft_AAD_ConditionalAccess/PolicyBlade/policyId/94c7d8d0-5c8c-460d-8ace-364374250893) | Report-only | User Risk Level: High, Control: Block |\n\n\n","TestStatus":"Failed","TestDescription":"Assume high risk users are compromised by threat actors. Without investigation and remediation, threat actors can execute scripts, deploy malicious applications, or manipulate API calls to establish persistence, based on the potentially compromised user's permissions. Threat actors can then exploit misconfigurations or abuse OAuth tokens to move laterally across workloads like documents, SaaS applications, or Azure resources. Threat actors can gain access to sensitive files, customer records, or proprietary code and exfiltrate it to external repositories while maintaining stealth through legitimate cloud services. Finally, threat actors might disrupt operations by modifying configurations, encrypting data for ransom, or using the stolen information for further attacks, resulting in financial, reputational, and regulatory consequences.\n\nOrganizations using passwords can rely on password reset to automatically remediate risky users.\n\nOrganizations using passwordless credentials already mitigate most risk events that accrue to user risk levels, thus the volume of risky users should be considerably lower. Risky users in an organization that uses passwordless credentials must be blocked from access until the user risk is investigated and remediated.\n\n**Remediation action**\n\n- [Deploy a Conditional Access policy to require a secure password change for elevated user risk](https://learn.microsoft.com/entra/identity/conditional-access/policy-risk-based-user?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci).\n- Use Microsoft Entra ID Protection to [investigate risk further](https://learn.microsoft.com/entra/id-protection/howto-identity-protection-investigate-risk?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci).\n","TestId":"21797"},{"TestImplementationCost":"","TestPillar":"Infrastructure","TestCategory":"Secure management ports","SkippedReason":null,"TestImpact":"","TestAppliesTo":null,"TestSfiPillar":"Protect tenants and isolate production systems","TestSkipped":"","TestMinimumLicense":"N/A","TestTags":null,"TestTitle":"Management ports should be closed on your virtual machines","TestRisk":"Medium","TestResult":"Management ports should be closed on your virtual machines\n\n| Subscription | Resource group | Resource type | Affected resource | Status | Azure portal |\n| :----------- | :------------- | :------------ | :---------------- | :----- | :----------- |\n| [Visual Studio Enterprise Subscription](https://portal.azure.com/#resource/subscriptions/54d3ea01-5a07-45d0-8d69-e5f5b0b20098) | indiavm_group | virtualmachines | [india-2](https://portal.azure.com/#resource/subscriptions/54d3ea01-5a07-45d0-8d69-e5f5b0b20098/resourceGroups/INDIAVM_GROUP/providers/Microsoft.Compute/virtualMachines/india-2) | ❌ | [View recommendation](https://portal.azure.com/#blade/Microsoft_Azure_Security/RecommendationsBlade/assessmentKey/bc303248-3d14-44c2-96a0-55f5c326b5fe/resourceId/%2fsubscriptions%2f54d3ea01-5a07-45d0-8d69-e5f5b0b20098%2fresourceGroups%2fINDIAVM_GROUP%2fproviders%2fMicrosoft.Compute%2fvirtualMachines%2findia-2) |\n| [Visual Studio Enterprise Subscription](https://portal.azure.com/#resource/subscriptions/54d3ea01-5a07-45d0-8d69-e5f5b0b20098) | indiavm_group | virtualmachines | [indiavm](https://portal.azure.com/#resource/subscriptions/54d3ea01-5a07-45d0-8d69-e5f5b0b20098/resourceGroups/INDIAVM_GROUP/providers/Microsoft.Compute/virtualMachines/indiavm) | ✅ | [View recommendation](https://portal.azure.com/#blade/Microsoft_Azure_Security/RecommendationsBlade/assessmentKey/bc303248-3d14-44c2-96a0-55f5c326b5fe/resourceId/%2fsubscriptions%2f54d3ea01-5a07-45d0-8d69-e5f5b0b20098%2fresourceGroups%2fINDIAVM_GROUP%2fproviders%2fMicrosoft.Compute%2fvirtualMachines%2findiavm) |\n","TestStatus":"Failed","TestDescription":"Open remote management ports are exposing your VM to a high level of risk from Internet-based attacks. These attacks attempt to brute force credentials to gain admin access to the machine.\n\n**Remediation action**\n\nWe recommend that you edit the inbound rules of some of your virtual machines, to restrict access to specific source ranges.
To restrict access to your virtual machines:
1. Select a VM to restrict access to.
2. In the 'Networking' blade, click on each of the rules that allow management ports (for example, RDP-3389, WINRM-5985, SSH-22).
3. Either change the 'Action' property to 'Deny', or, improve the rule by applying a less permissive range of source IP ranges.
4. Click 'Save'.
Use Defender for Cloud's Just-in-time (JIT) virtual machine (VM) access to lock down inbound traffic to your Azure VMs by demand. Learn more in Understanding just-in-time (JIT) VM access.","TestId":"bc303248-3d14-44c2-96a0-55f5c326b5fe"},{"TestImplementationCost":"Medium","TestPillar":"Identity","TestCategory":"Identity governance","SkippedReason":null,"TestImpact":"Medium","TestAppliesTo":null,"TestSfiPillar":"Protect tenants and isolate production systems","TestSkipped":"","TestMinimumLicense":["P2","Governance"],"TestTags":null,"TestTitle":"All entitlement management policies have an expiration date","TestRisk":"Medium","TestResult":"\n❌ Not all entitlement management policies have expiration dates configured.\n### Entitlement Management Assignment Policies with Expiration Dates\n| Name | Expiration Type | Duration / End DateTime |\n| :--- | :--- | ---: |\n| [test Policy](https://entra.microsoft.com/#view/Microsoft_Azure_ELMAdmin/EntitlementMenuBlade/~/policies/entitlementId//catalogId//catalogName//entitlementName/test%20Policy) | afterDuration | P365D |\n| [All users](https://entra.microsoft.com/#view/Microsoft_Azure_ELMAdmin/EntitlementMenuBlade/~/policies/entitlementId//catalogId//catalogName//entitlementName/All%20users) | afterDateTime | 11/15/2027 12:59:59 |\n| [Initial Policy](https://entra.microsoft.com/#view/Microsoft_Azure_ELMAdmin/EntitlementMenuBlade/~/policies/entitlementId//catalogId//catalogName//entitlementName/Initial%20Policy) | afterDuration | P365D |\n| [Initial Policy](https://entra.microsoft.com/#view/Microsoft_Azure_ELMAdmin/EntitlementMenuBlade/~/policies/entitlementId//catalogId//catalogName//entitlementName/Initial%20Policy) | afterDuration | P365D |\n\n#### Policies missing expiration:\n| Name | Expiration Type | Duration / End DateTime |\n| :--- | :--- | ---: |\n| [21929Test](https://entra.microsoft.com/#view/Microsoft_Azure_ELMAdmin/EntitlementMenuBlade/~/policies/entitlementId//catalogId//catalogName//entitlementName/21929Test) | noExpiration | | |\n| [External](https://entra.microsoft.com/#view/Microsoft_Azure_ELMAdmin/EntitlementMenuBlade/~/policies/entitlementId//catalogId//catalogName//entitlementName/External) | noExpiration | | |\n| [All users](https://entra.microsoft.com/#view/Microsoft_Azure_ELMAdmin/EntitlementMenuBlade/~/policies/entitlementId//catalogId//catalogName//entitlementName/All%20users) | noExpiration | | |\n| [All users](https://entra.microsoft.com/#view/Microsoft_Azure_ELMAdmin/EntitlementMenuBlade/~/policies/entitlementId//catalogId//catalogName//entitlementName/All%20users) | noExpiration | | |\n\n\n","TestStatus":"Failed","TestDescription":"Entitlement management policies without expiration dates create persistent access that threat actors can exploit. When user assignments lack time bounds, compromised credentials maintain indefinite access, enabling attackers to establish persistence, escalate privileges through additional access packages, and conduct long-term malicious activities while remaining undetected. \n\n**Remediation action**\n\n- [Configure expiration settings for access packages](https://learn.microsoft.com/entra/id-governance/entitlement-management-access-package-lifecycle-policy?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci#specify-a-lifecycle)\n","TestId":"21878"},{"TestImplementationCost":"Low","TestPillar":"Identity","TestCategory":"Privileged access","SkippedReason":null,"TestImpact":"Low","TestAppliesTo":null,"TestSfiPillar":"Protect identities and secrets","TestSkipped":"","TestMinimumLicense":"P2","TestTags":null,"TestTitle":"Activation alert for Global Administrator role assignments","TestRisk":"Medium","TestResult":"\nActivation alerts are configured for Global Administrator role.\n\n| Role display name | Default recipients | Additional recipients |\n| :---------------- | :----------------- | :------------------- |\n| [Global Administrator](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/RolesManagementMenuBlade/~/AllRoles) | ✅ Enabled | peyton@contoso.com |\n\n\n","TestStatus":"Passed","TestDescription":"Without activation alerts for Global Administrator role assignments, threat actors can escalate privileges undetected. This lack of visibility creates a blind spot where attackers can activate the most privileged role and perform malicious actions such as creating backdoor accounts, modifying security policies, or accessing sensitive data.\n\nMonitoring these activation alerts can help security teams distinguish between authorized and unauthorized privilege escalation activities. \n\n**Remediation action**\n\n- [Configure notifications for privileged roles](https://learn.microsoft.com/entra/id-governance/privileged-identity-management/pim-how-to-change-default-settings?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci#require-justification-on-active-assignment)\n","TestId":"21819"},{"TestImpact":"Medium","TestRisk":"High","TestSkipped":"","TestAppliesTo":null,"TestPillar":"Data","TestCategory":"Data Loss Prevention (DLP)","TestDescription":"Without Data Loss Prevention (DLP) policies, employees can freely share sensitive information through email, file uploads, or Microsoft Teams communications, increasing the risk of data breaches and regulatory violations.\n\nDLP policies automatically monitor, detect, and prevent the disclosure of sensitive information across Microsoft 365 workloads, providing automated protection against unauthorized data exfiltration.\n\n**Remediation action**\n\n- [Create and configure DLP policies](https://learn.microsoft.com/purview/dlp-create-deploy-policy?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci)\n","TestTitle":"Data loss prevention policies are enabled","SkippedReason":null,"TestId":"35030","TestImplementationCost":"Medium","TestMinimumLicense":["EXCHANGE_S_ENTERPRISE"],"TestSfiPillar":"Protect tenants and production systems","TestResult":"\n✅ One or more DLP policies are enabled and configured, providing automated protection against sensitive data disclosure.\n\n## Data Loss Prevention Policy Summary\n\n**Total DLP Policies:** 7\n\n**Enabled Policies:** 7\n\n### DLP Policies Configuration\n\n| Policy Name | Enabled Status | Created Date | Last Modified Date |\n| :--- | :--- | :--- | :--- |\n| Custom policy | ✅ Yes | 2026-01-09 | 2026-05-13 |\n| Endpoint DLP - Financial Data | ✅ Yes | 2026-01-15 | 2026-02-06 |\n| Adaptive Protection - Elevated Risk | ✅ Yes | 2026-01-30 | 2026-02-06 |\n| Custom policy-2 | ✅ Yes | 2026-02-06 | 2026-02-06 |\n| Browser DLP Test | ✅ Yes | 2026-02-13 | 2026-02-13 |\n| Test - 61001 | ✅ Yes | 2026-05-12 | 2026-05-13 |\n| copilot-61001 | ✅ Yes | 2026-05-13 | 2026-05-13 |\n\n[View DLP Policies in Microsoft Purview Portal](https://purview.microsoft.com/datalossprevention/policies)\n\n\n","TestStatus":"Passed","TestTags":null},{"TestImplementationCost":"Low","TestPillar":"Identity","TestCategory":"Credential management","SkippedReason":null,"TestImpact":"Low","TestAppliesTo":null,"TestSfiPillar":"Protect identities and secrets","TestSkipped":"","TestMinimumLicense":"P1","TestTags":null,"TestTitle":"Smart lockout duration is set to a minimum of 60","TestRisk":"Medium","TestResult":"\nSmart Lockout duration is configured to 60 seconds or higher.\n## Smart Lockout Settings\n\n| Setting | Value |\n| :---- | :---- |\n| [Lockout Duration (seconds)](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/AuthenticationMethodsMenuBlade/~/PasswordProtection/fromNav/) | 60 |\n\n\n","TestStatus":"Passed","TestDescription":"When Smart Lockout duration is configured below the default 60 seconds, threat actors can exploit shortened lockout periods to conduct password spray and credential stuffing attacks more effectively. Reduced lockout windows allow attackers to resume authentication attempts more rapidly, increasing their success probability while potentially evading detection systems that rely on longer observation periods. \n\n**Remediation action**\n\n- [Set Smart Lockout duration to 60 seconds or higher](https://learn.microsoft.com/entra/identity/authentication/howto-password-smart-lockout?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci#manage-microsoft-entra-smart-lockout-values)\n","TestId":"21849"},{"TestImplementationCost":"Low","TestPillar":"Devices","TestCategory":"Tenant","SkippedReason":null,"TestImpact":"Low","TestAppliesTo":null,"TestSfiPillar":"Protect tenants and isolate production systems","TestSkipped":"","TestMinimumLicense":"P1","TestTags":null,"TestTitle":"Windows Automatic Enrollment is enabled","TestRisk":"High","TestResult":"\nWindows Automatic Enrollment is enabled.\n\n\n## Windows Automatic Enrollment\n\n| Policy Name | User Scope |\n| :---------- | :--------- |\n| [Microsoft Intune](https://intune.microsoft.com/#view/Microsoft_AAD_IAM/MdmConfiguration.ReactView/appId/0000000a-0000-0000-c000-000000000000/appName/Microsoft%20Intune) | ✅ Specific Groups |\n\n\n\n","TestStatus":"Passed","TestDescription":"If Windows automatic enrollment isn't enabled, unmanaged devices can become an entry point for attackers. Threat actors might use these devices to access corporate data, bypass compliance policies, and introduce vulnerabilities into the environment. Devices joined to Microsoft Entra without Intune enrollment create gaps in visibility and control. These unmanaged endpoints can expose weaknesses in the operating system or misconfigured applications that attackers can exploit.\n\nEnforcing automatic enrollment ensures Windows devices are managed from the start, enabling consistent policy enforcement and visibility into compliance. This supports Zero Trust by ensuring all devices are verified, monitored, and governed by security controls.\n\n**Remediation action**\n\nEnable automatic enrollment for Windows devices using Intune and Microsoft Entra to ensure all domain-joined or Entra-joined devices are managed: \n- [Enable Windows automatic enrollment](https://learn.microsoft.com/intune/intune-service/enrollment/windows-enroll?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci#enable-windows-automatic-enrollment)\n\nFor more information, see: \n- [Deployment guide - Enrollment for Windows](https://learn.microsoft.com/intune/intune-service/fundamentals/deployment-guide-enroll?tabs=work-profile%2Ccorporate-owned-apple%2Cautomatic-enrollment&wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci#enrollment-for-windows)\n","TestId":"24546"},{"TestImplementationCost":"Low","TestPillar":"Identity","TestCategory":"Application management","SkippedReason":null,"TestImpact":"Medium","TestAppliesTo":["Identity"],"TestSfiPillar":"Protect engineering systems","TestSkipped":"","TestMinimumLicense":"P1","TestTags":["Application"],"TestTitle":"Creating new applications and service principles is restricted to privileged users","TestRisk":"Medium","TestResult":"\nTenant is configured to prevent users from registering applications.\n\n**[Users can register applications](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserManagementMenuBlade/~/UserSettings/menuId/UserSettings)** → **No** ✅\n\n","TestStatus":"Passed","TestDescription":"If nonprivileged users can create applications and service principals, these accounts might be misconfigured or be granted more permissions than necessary, creating new vectors for attackers to gain initial access. Attackers can exploit these accounts to establish valid credentials in the environment and bypass some security controls.\n\nIf these nonprivileged accounts are mistakenly granted elevated application owner permissions, attackers can use them to move from a lower level of access to a more privileged level of access. Attackers who compromise nonprivileged accounts might add their own credentials or change the permissions associated with the applications created by the nonprivileged users to ensure they can continue to access the environment undetected.\n\nAttackers can use service principals to blend in with legitimate system processes and activities. Because service principals often perform automated tasks, malicious activities carried out under these accounts might not be flagged as suspicious.\n\n**Remediation action**\n\n- [Block nonprivileged users from creating apps](https://learn.microsoft.com/entra/identity/role-based-access-control/delegate-app-roles?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci)\n","TestId":"21807"},{"TestImplementationCost":"","TestPillar":"Infrastructure","TestCategory":"Protect applications against DDoS attacks","SkippedReason":"This test is not applicable to the current environment.","TestImpact":"","TestAppliesTo":null,"TestSfiPillar":"Protect tenants and isolate production systems","TestSkipped":"NotApplicable","TestMinimumLicense":"N/A","TestTags":null,"TestTitle":"Azure DDoS Protection Standard should be enabled","TestRisk":"Medium","TestResult":"VnetHasNoAppGateways\n\n| Subscription | Resource group | Resource type | Affected resource | Status | Azure portal |\n| :----------- | :------------- | :------------ | :---------------- | :----- | :----------- |\n| [Visual Studio Enterprise Subscription](https://portal.azure.com/#resource/subscriptions/54d3ea01-5a07-45d0-8d69-e5f5b0b20098) | indiavm_group | virtualnetworks | [indiavm-vnet](https://portal.azure.com/#resource/subscriptions/54d3ea01-5a07-45d0-8d69-e5f5b0b20098/resourceGroups/indiavm_group/providers/Microsoft.Network/virtualNetworks/indiavm-vnet) | N/A | [View recommendation](https://portal.azure.com/#blade/Microsoft_Azure_Security/RecommendationsBlade/assessmentKey/e3de1cc0-f4dd-3b34-e496-8b5381ba2d70/resourceId/%2fsubscriptions%2f54d3ea01-5a07-45d0-8d69-e5f5b0b20098%2fresourceGroups%2findiavm_group%2fproviders%2fMicrosoft.Network%2fvirtualNetworks%2findiavm-vnet) |\n| [Visual Studio Enterprise Subscription](https://portal.azure.com/#resource/subscriptions/54d3ea01-5a07-45d0-8d69-e5f5b0b20098) | charlie | virtualnetworks | [charlie-vnet](https://portal.azure.com/#resource/subscriptions/54d3ea01-5a07-45d0-8d69-e5f5b0b20098/resourceGroups/charlie/providers/Microsoft.Network/virtualNetworks/charlie-vnet) | N/A | [View recommendation](https://portal.azure.com/#blade/Microsoft_Azure_Security/RecommendationsBlade/assessmentKey/e3de1cc0-f4dd-3b34-e496-8b5381ba2d70/resourceId/%2fsubscriptions%2f54d3ea01-5a07-45d0-8d69-e5f5b0b20098%2fresourceGroups%2fcharlie%2fproviders%2fMicrosoft.Network%2fvirtualNetworks%2fcharlie-vnet) |\n","TestStatus":"Skipped","TestDescription":"Defender for Cloud has discovered virtual networks with Application Gateway or Azure Firewall resources that are unprotected by the DDoS protection service. These resources contain public IPs. Enable mitigation of network volumetric and protocol attacks.\n\n**Remediation action**\n\n
1. Select a virtual network to enable the DDoS protection service standard on.
2. Select the Standard option.
3. Click 'Save'.","TestId":"e3de1cc0-f4dd-3b34-e496-8b5381ba2d70"},{"TestImplementationCost":"Medium","TestPillar":"Identity","TestCategory":"Application management","SkippedReason":null,"TestImpact":"Low","TestAppliesTo":null,"TestSfiPillar":"Protect engineering systems","TestSkipped":"","TestMinimumLicense":"Free","TestTags":null,"TestTitle":"Enterprise applications have owners","TestRisk":"Medium","TestResult":"\nNot all enterprise applications have at least two owners.\n\n## Enterprise Application Ownership\n\n| App name | Multi-tenant | Permission | Classification | Owner count |\n| :-------- | :------------ | :---------- | :------------- | :----------- |\n| [Microsoft Assessment React](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/Overview/objectId/0a8b4459-b0c2-4cb8-baeb-c4c5a6a8f14b/appId/c4b110d7-6f1d-473d-aa9e-6e74b8b8bd4b) | False | offline_access, openid, profile, User.Read | Low | 0 |\n| [idPowerToys - CI](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/Overview/objectId/043dd83b-94ce-4d12-b54b-45d77979f05a/appId/0b75bb7b-d365-4c29-92ea-e2799d2a3fce) | False | offline_access, openid, profile, User.Read | Low | 0 |\n| [idPowerToys](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/Overview/objectId/30aa6cd2-1aab-42fd-a235-0521713f4532/appId/afe793df-19e0-455a-8403-2e863379bfaa) | False | offline_access, openid, profile, User.Read | Low | 0 |\n| [Canva](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/Overview/objectId/37ae3acb-5850-49e8-a0f8-cb06f5a77417/appId/2c0bebe0-bdb3-4909-8955-7ef311f0db22) | False | email, openid, profile, User.Read | Low | 0 |\n| [EAM Demo](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/Overview/objectId/24b12ae7-4648-4aae-b00c-6349a565d24c/appId/e6e0be31-7040-4084-ac44-600b67661f2c) | True | openid, profile | Low | 0 |\n| [Azure Static Web Apps](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/Overview/objectId/6b1f4a00-db4e-43ae-b62b-2286d4fcc4ea/appId/d414ee2d-73e5-4e5b-bb16-03ef55fea597) | False | email, openid, profile | Low | 0 |\n| [FIDO2-passkeys-MFA](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/Overview/objectId/1aa7e155-cbf8-4970-8458-05a0c7a2d1a5/appId/4fabcfc0-5c44-45a1-8c80-8537f0625949) | True | openid, profile | Low | 0 |\n| [Opticom](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/Overview/objectId/3f142d86-14ba-4173-9458-be7fb36b37f7/appId/dd939d5a-d248-4f58-a25f-26a6b3f5183e) | False | email, openid, profile, User.Read | Low | 0 |\n| [AWS Account](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/Overview/objectId/77198970-f1eb-4574-9a1a-6af175a283af/appId/2e311a1d-f5c0-41c6-b866-77af3289871e) | True | offline_access, openid, profile, User.Read | Low | 0 |\n| [graph-developer-proxy-samples](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/Overview/objectId/e6570bb8-fdea-4329-82e2-2809d8fb67a7/appId/3658d9e9-dc87-4345-b59b-184febcf6781) | True | Presence.Read.All, User.Read.All | Low | 0 |\n| [idpowerelectron](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/Overview/objectId/cb64f850-a076-42d5-8dd8-cfd67d9e67f1/appId/909fff82-5b0a-4ce5-b66d-db58ee1a925d) | True | offline_access, openid, profile | Low | 0 |\n| [Atlassian - Jira](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/Overview/objectId/2425e515-5720-4071-9fae-fd50f153c0aa/appId/b0e53e94-b4b0-4632-98ae-e230af1f511c) | False | User.Read | Low | 0 |\n| [Entry Kiosk](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/Overview/objectId/83adcc80-3a35-4fdc-9c5b-1f6b9061508e/appId/b903f17a-87b0-460b-9978-962c812e4f98) | False | User.Read | Low | 0 |\n| [SharePoint On-Prem App Proxy](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/Overview/objectId/53c7bdb1-cae2-43b0-9e2e-d8605395ceec/appId/19a70df3-cddf-48c7-be44-97b25b9857f1) | False | User.Read | Low | 0 |\n| [WebApplication4](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/Overview/objectId/5bc56e47-7a8a-4e71-b25f-8c4e373f40a6/appId/b2d1f868-27ee-4ecd-ae81-0ee96b028605) | False | User.Read | Low | 0 |\n| [MyTokenTestApp](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/Overview/objectId/60923f18-748f-42bb-a0b2-ee60d44e17fc/appId/6a846cb7-35ad-41b2-b10a-0c5decde9855) | False | openid, profile | Low | 1 |\n| [Microsoft Graph PowerShell - Used by Team Incredibles](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/Overview/objectId/e67821d9-a20b-43ef-9c34-76a321643b4f/appId/2935f660-810c-41ff-b9ad-168cc649e36f) | False | offline_access, openid, profile, User.Read | Low | 0 |\n| [CachingSampleApp](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/Overview/objectId/59187561-8df5-4792-b3a4-f6ca8b54bfc7/appId/3d6835ff-f7f4-4a83-adb5-67ccdd934717) | False | offline_access, openid, profile, User.Read | Low | 0 |\n| [Demo](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/Overview/objectId/552daa69-8057-4684-8c93-2c41963aff01/appId/f864cc86-0f4f-4861-9583-2580817e4f88) | False | openid, profile | Low | 0 |\n| [Lokka-2-interactive](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/Overview/objectId/794b2542-39aa-433c-90c6-6ab5df851ffc/appId/e6ea9510-0e81-465a-ae7b-efaff41bd719) | False | User.Read, User.Read.All | Low | 0 |\n| [Contoso Access Verifier](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/Overview/objectId/41d3b041-9859-4830-8feb-72ffd7afad65/appId/a6af3433-bc44-4d27-9b35-81d10fd51315) | False | openid, profile, User.Read | Low | 0 |\n| [ASPNET-Tutorial](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/Overview/objectId/6e2f1852-1b3c-4516-a078-551846b5cf49/appId/059da61d-d02e-40ee-8140-6842d5819f18) | False | User.Read | Low | 0 |\n| [PowerShell Gallery ](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/Overview/objectId/a07b4145-250d-4a58-98eb-ab57e7e77d53/appId/d53deec6-b5c5-4953-8d80-73d001fd31e5) | False | email, openid, profile | Low | 0 |\n| [Manson Nov 13 Test](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/Overview/objectId/e515f788-f41c-4c34-aeaa-fded2cc006ed/appId/d65bd82c-b625-48cd-b485-f61939b48727) | False | AgentIdUser.ReadWrite.IdentityParentedBy, User.Read | Low | 0 |\n| [Manson-Test-Nov13](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/Overview/objectId/4499f84e-928d-44c7-a288-51fc4c4374e0/appId/516489b4-b179-4230-b149-440b5c78a7cc) | False | AgentIdUser.ReadWrite.IdentityParentedBy, User.Read | Low | 0 |\n| [Agent Identity Blueprint Example 3792929](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/Overview/objectId/a746a0f2-205f-49fb-ab32-b17b7ccf8cb8/appId/60253969-9e44-4e0b-85c0-abda1041272c) | False | AgentIdUser.ReadWrite.IdentityParentedBy, User.Read | Low | 0 |\n| [MyVscode](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/Overview/objectId/dfc83a5d-36e5-4506-ae9d-6ad5bb403377/appId/92abdce1-3952-4a8b-8720-e59257edd421) | False | MCP.AccessReview.Read.All, MCP.AdministrativeUnit.Read.All, MCP.Application.Read.All, MCP.AuditLog.Read.All, MCP.AuthenticationContext.Read.All, MCP.Device.Read.All, MCP.DirectoryRecommendations.Read.All, MCP.Domain.Read.All, MCP.EntitlementManagement.Read.All, MCP.GroupMember.Read.All, MCP.HealthMonitoringAlert.Read.All, MCP.IdentityRiskEvent.Read.All, MCP.IdentityRiskyServicePrincipal.Read.All, MCP.IdentityRiskyUser.Read.All, MCP.LicenseAssignment.Read.All, MCP.LifecycleWorkflows-CustomExt.Read.All, MCP.LifecycleWorkflows-Reports.Read.All, MCP.LifecycleWorkflows-Workflow.Read.All, MCP.LifecycleWorkflows-Workflow.ReadBasic.All, MCP.LifecycleWorkflows.Read.All, MCP.NetworkAccess-Reports.Read.All, MCP.NetworkAccess.Read.All, MCP.Organization.Read.All, MCP.Policy.Read.All, MCP.Policy.Read.ConditionalAccess, MCP.ProvisioningLog.Read.All, MCP.Reports.Read.All, MCP.RoleAssignmentSchedule.Read.Directory, MCP.RoleEligibilitySchedule.Read.Directory, MCP.RoleManagement.Read.Directory, MCP.Synchronization.Read.All, MCP.User.Read.All, MCP.UserAuthenticationMethod.Read.All | Unranked | 0 |\n| [MansonTestNov24](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/Overview/objectId/8eb7566e-6766-407d-b02e-562bce27c389/appId/d4407e7a-9644-4e25-8df5-6e6da95a9013) | False | AgentIdUser.ReadWrite.IdentityParentedBy, User.Read | Low | 0 |\n| [Manson Test Agent](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/Overview/objectId/4a371380-42bf-44df-9aab-0485be48bbef/appId/e6e0e568-682d-4640-a038-2f2489b1d2aa) | False | AgentIdUser.ReadWrite.IdentityParentedBy, User.Read | Low | 0 |\n| [Agent Identity Blueprint Example 4208710](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/Overview/objectId/7c8d289b-aa63-497f-a4bf-6f98d2323e7c/appId/e79effd2-67cf-4caa-8879-b87389f47819) | False | AgentIdUser.ReadWrite.IdentityParentedBy, User.Read | Low | 0 |\n| [Chopin Agent](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/Overview/objectId/09ac3973-23bc-4ea8-abbb-ce4ed641f39e/appId/7dcdc7c5-09a6-435f-9460-9382d32b7bc6) | False | AgentIdUser.ReadWrite.IdentityParentedBy, User.Read | Low | 0 |\n| [AADInternals OSINT](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/Overview/objectId/8aa2d89a-65ce-4b30-87a6-7c0aae6a55da/appId/08449b24-4aa6-4049-93ef-0c17b87c8d98) | True | openid, profile | Low | 0 |\n| [Agent0 API](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/Overview/objectId/8b627fed-f28e-4749-b5ca-05fa9be291a0/appId/a8a4a52c-9f15-4e2a-a8fe-c267cc3a6101) | False | User.Read | Low | 0 |\n| [agent0-blueprint](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/Overview/objectId/6d92662d-d10d-4a03-8c77-4f904ce22c44/appId/00b6bee4-a638-4260-9382-09301b3a1db9) | False | AgentIdentity.CreateAsManager, User.Read | Low | 0 |\n| [Agent Identity Blueprint Example 12612901](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/Overview/objectId/fe22156d-6b3b-45e4-867a-646e08707dcf/appId/ef1e370e-626b-4839-9340-83e62875489a) | False | AgentIdentity.CreateAsManager, User.Read | Low | 0 |\n| [Message Center](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/Overview/objectId/158f6ef9-a65d-45f2-bdf0-b0a1db70ebd4/appId/83f76a08-fa60-48e6-9cb5-fd8ced5ae314) | False | ServiceMessage.Read.All, User.Read | Low | 0 |\n| [MessageCenterAccount github.com/manson/mc DO NOT DELETE](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/Overview/objectId/427b14ca-13b3-4911-b67e-9ff626614781/appId/778fad36-e4c1-4d40-a58e-9b5b64179d41) | False | ServiceMessage.Read.All | Unranked | 0 |\n| [MyTestMcPClient](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/Overview/objectId/84fbf039-0d23-41d0-b58b-f7a7b76a0486/appId/b6e43d0e-e33f-4223-bae4-144e5974ec3b) | False | MCP.AccessReview.Read.All, MCP.AdministrativeUnit.Read.All, MCP.Application.Read.All, MCP.AuditLog.Read.All, MCP.AuthenticationContext.Read.All, MCP.Device.Read.All, MCP.DirectoryRecommendations.Read.All, MCP.Domain.Read.All, MCP.EntitlementManagement.Read.All, MCP.GroupMember.Read.All, MCP.HealthMonitoringAlert.Read.All, MCP.IdentityRiskEvent.Read.All, MCP.IdentityRiskyServicePrincipal.Read.All, MCP.IdentityRiskyUser.Read.All, MCP.LicenseAssignment.Read.All, MCP.LifecycleWorkflows-CustomExt.Read.All, MCP.LifecycleWorkflows-Reports.Read.All, MCP.LifecycleWorkflows-Workflow.Read.All, MCP.LifecycleWorkflows-Workflow.ReadBasic.All, MCP.LifecycleWorkflows.Read.All, MCP.NetworkAccess-Reports.Read.All, MCP.NetworkAccess.Read.All, MCP.Organization.Read.All, MCP.Policy.Read.All, MCP.Policy.Read.ConditionalAccess, MCP.ProvisioningLog.Read.All, MCP.Reports.Read.All, MCP.RoleAssignmentSchedule.Read.Directory, MCP.RoleEligibilitySchedule.Read.Directory, MCP.RoleManagement.Read.Directory, MCP.Synchronization.Read.All, MCP.User.Read.All, MCP.UserAuthenticationMethod.Read.All | Unranked | 0 |\n| [TestMcPClient](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/Overview/objectId/cf30c6da-890f-4e66-b353-06adbae9933f/appId/55c372a3-9a33-42bb-ac50-7f49224fee47) | False | MCP.AccessReview.Read.All, MCP.AdministrativeUnit.Read.All, MCP.Application.Read.All, MCP.AuditLog.Read.All, MCP.AuthenticationContext.Read.All, MCP.Device.Read.All, MCP.DirectoryRecommendations.Read.All, MCP.Domain.Read.All, MCP.EntitlementManagement.Read.All, MCP.GroupMember.Read.All, MCP.HealthMonitoringAlert.Read.All, MCP.IdentityRiskEvent.Read.All, MCP.IdentityRiskyServicePrincipal.Read.All, MCP.IdentityRiskyUser.Read.All, MCP.LicenseAssignment.Read.All, MCP.LifecycleWorkflows-CustomExt.Read.All, MCP.LifecycleWorkflows-Reports.Read.All, MCP.LifecycleWorkflows-Workflow.Read.All, MCP.LifecycleWorkflows-Workflow.ReadBasic.All, MCP.LifecycleWorkflows.Read.All, MCP.NetworkAccess-Reports.Read.All, MCP.NetworkAccess.Read.All, MCP.Organization.Read.All, MCP.Policy.Read.All, MCP.Policy.Read.ConditionalAccess, MCP.ProvisioningLog.Read.All, MCP.Reports.Read.All, MCP.RoleAssignmentSchedule.Read.Directory, MCP.RoleEligibilitySchedule.Read.Directory, MCP.RoleManagement.Read.Directory, MCP.Synchronization.Read.All, MCP.User.Read.All, MCP.UserAuthenticationMethod.Read.All | Unranked | 0 |\n| [Calendar Pro](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/Overview/objectId/36e156e4-4566-44a0-b05c-a112017086b5/appId/fb507a6d-2eaa-4f1f-b43a-140f388c4445) | False | email, offline_access, openid, profile, User.Read, User.ReadBasic.All | Low | 0 |\n| [MyVisualStudioMcpClient](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/Overview/objectId/cae606b7-4a44-4d07-a7a5-a6fb285e41f1/appId/84ad8697-445d-4b26-affd-1b1459e97aae) | False | MCP.AccessReview.Read.All, MCP.AdministrativeUnit.Read.All, MCP.Application.Read.All, MCP.AuditLog.Read.All, MCP.AuthenticationContext.Read.All, MCP.Device.Read.All, MCP.DirectoryRecommendations.Read.All, MCP.Domain.Read.All, MCP.EntitlementManagement.Read.All, MCP.GroupMember.Read.All, MCP.HealthMonitoringAlert.Read.All, MCP.IdentityRiskEvent.Read.All, MCP.IdentityRiskyServicePrincipal.Read.All, MCP.IdentityRiskyUser.Read.All, MCP.LicenseAssignment.Read.All, MCP.LifecycleWorkflows-CustomExt.Read.All, MCP.LifecycleWorkflows-Reports.Read.All, MCP.LifecycleWorkflows-Workflow.Read.All, MCP.LifecycleWorkflows-Workflow.ReadBasic.All, MCP.LifecycleWorkflows.Read.All, MCP.NetworkAccess-Reports.Read.All, MCP.NetworkAccess.Read.All, MCP.Organization.Read.All, MCP.Policy.Read.All, MCP.Policy.Read.ConditionalAccess, MCP.ProvisioningLog.Read.All, MCP.Reports.Read.All, MCP.RoleAssignmentSchedule.Read.Directory, MCP.RoleEligibilitySchedule.Read.Directory, MCP.RoleManagement.Read.Directory, MCP.Synchronization.Read.All, MCP.User.Read.All, MCP.UserAuthenticationMethod.Read.All | Unranked | 0 |\n| [Thunderbird](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/Overview/objectId/f0b3210a-52eb-4beb-a386-01a0a28aadff/appId/9e5f94bc-e8a4-4e73-b8be-63364c29d753) | False | IMAP.AccessAsUser.All, offline_access, POP.AccessAsUser.All, SMTP.Send | Low | 0 |\n| [WPNinja1](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/Overview/objectId/8b75d9d0-1b26-4143-98d0-e87df8b835b1/appId/eee88dc1-4aab-42b3-b089-4a2cbb19b048) | False | AgentIdentity.CreateAsManager, User.Read | Low | 0 |\n| [custommcp](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/Overview/objectId/fba0c411-7019-4c32-bec4-2f281824b698/appId/aca7e359-22cf-4d86-9338-6d6051245755) | False | MCP.AccessReview.Read.All, MCP.AdministrativeUnit.Read.All, MCP.Application.Read.All, MCP.AuditLog.Read.All, MCP.AuthenticationContext.Read.All, MCP.Device.Read.All, MCP.DirectoryRecommendations.Read.All, MCP.Domain.Read.All, MCP.EntitlementManagement.Read.All, MCP.GroupMember.Read.All, MCP.HealthMonitoringAlert.Read.All, MCP.IdentityRiskEvent.Read.All, MCP.IdentityRiskyServicePrincipal.Read.All, MCP.IdentityRiskyUser.Read.All, MCP.LicenseAssignment.Read.All, MCP.LifecycleWorkflows-CustomExt.Read.All, MCP.LifecycleWorkflows-Reports.Read.All, MCP.LifecycleWorkflows-Workflow.Read.All, MCP.LifecycleWorkflows-Workflow.ReadBasic.All, MCP.LifecycleWorkflows.Read.All, MCP.NetworkAccess-Reports.Read.All, MCP.NetworkAccess.Read.All, MCP.Organization.Read.All, MCP.Policy.Read.All, MCP.Policy.Read.ConditionalAccess, MCP.ProvisioningLog.Read.All, MCP.Reports.Read.All, MCP.RoleAssignmentSchedule.Read.Directory, MCP.RoleEligibilitySchedule.Read.Directory, MCP.RoleManagement.Read.Directory, MCP.Synchronization.Read.All, MCP.UserAuthenticationMethod.Read.All | Unranked | 0 |\n| [M365 MCP Client for Claude](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/Overview/objectId/73f345ba-56fb-4d92-b2f6-2fe168131092/appId/08ad6f98-a4f8-4635-bb8d-f1a3044760f0) | True | MCP.AdministrativeUnit.Read.All, MCP.Application.Read.All, MCP.AuditLog.Read.All, MCP.AuthenticationContext.Read.All, MCP.Device.Read.All, MCP.DirectoryRecommendations.Read.All, MCP.Domain.Read.All, MCP.EntitlementManagement.Read.All, MCP.GroupMember.Read.All, MCP.HealthMonitoringAlert.Read.All, MCP.IdentityRiskEvent.Read.All, MCP.IdentityRiskyServicePrincipal.Read.All, MCP.IdentityRiskyUser.Read.All, MCP.LicenseAssignment.Read.All, MCP.LifecycleWorkflows-CustomExt.Read.All, MCP.LifecycleWorkflows-Reports.Read.All, MCP.LifecycleWorkflows-Workflow.Read.All, MCP.LifecycleWorkflows-Workflow.ReadBasic.All, MCP.LifecycleWorkflows.Read.All, MCP.NetworkAccess-Reports.Read.All, MCP.NetworkAccess.Read.All, MCP.Organization.Read.All, MCP.Policy.Read.All, MCP.Policy.Read.ConditionalAccess, MCP.ProvisioningLog.Read.All, MCP.Reports.Read.All, MCP.RoleAssignmentSchedule.Read.Directory, MCP.RoleEligibilitySchedule.Read.Directory, MCP.RoleManagement.Read.Directory, MCP.Synchronization.Read.All, MCP.User.Read.All, MCP.UserAuthenticationMethod.Read.All | Unranked | 0 |\n| [ChatGPT](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/Overview/objectId/ede526ec-83dd-4e66-8ed0-98e05dca5454/appId/e0476654-c1d5-430b-ab80-70cbd947616a) | False | MCP.AccessReview.Read.All, MCP.AdministrativeUnit.Read.All, MCP.Application.Read.All, MCP.AuditLog.Read.All, MCP.AuthenticationContext.Read.All, MCP.Device.Read.All, MCP.DirectoryRecommendations.Read.All, MCP.Domain.Read.All, MCP.EntitlementManagement.Read.All, MCP.GroupMember.Read.All, MCP.HealthMonitoringAlert.Read.All, MCP.IdentityRiskEvent.Read.All, MCP.IdentityRiskyServicePrincipal.Read.All, MCP.IdentityRiskyUser.Read.All, MCP.LicenseAssignment.Read.All, MCP.LifecycleWorkflows-CustomExt.Read.All, MCP.LifecycleWorkflows-Reports.Read.All, MCP.LifecycleWorkflows-Workflow.Read.All, MCP.LifecycleWorkflows-Workflow.ReadBasic.All, MCP.LifecycleWorkflows.Read.All, MCP.NetworkAccess-Reports.Read.All, MCP.NetworkAccess.Read.All, MCP.Organization.Read.All, MCP.Policy.Read.All, MCP.Policy.Read.ConditionalAccess, MCP.ProvisioningLog.Read.All, MCP.Reports.Read.All, MCP.RoleAssignmentSchedule.Read.Directory, MCP.RoleEligibilitySchedule.Read.Directory, MCP.RoleManagement.Read.Directory, MCP.Synchronization.Read.All, MCP.User.Read.All, MCP.UserAuthenticationMethod.Read.All | Unranked | 0 |\n\n\n","TestStatus":"Failed","TestDescription":"Enterprise applications without owners become orphaned assets that threat actors can exploit. These applications often retain elevated permissions and access to sensitive resources while lacking proper oversight and security governance.\n\nApplications without owners create blind spots in security monitoring where attackers can establish persistence by leveraging existing application permissions to access data or create backdoor accounts. The absence of ownership also prevents proper access reviews and permission audits, allowing applications with excessive permissions or outdated configurations to remain unmanaged.\n\nAssigning owners enables effective application lifecycle management and ensures proper security oversight. \n\n**Remediation action**\n\n- [Assign enterprise application owners](https://learn.microsoft.com/entra/identity/enterprise-apps/assign-app-owners?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci)\n","TestId":"24518"},{"TestImpact":"Low","TestRisk":"High","TestSkipped":"","TestAppliesTo":null,"TestPillar":"Data","TestCategory":"sensitivity-labels","TestDescription":"Sensitivity labels are the foundation of Microsoft Purview Information Protection. They enable organizations to classify and protect sensitive data across Microsoft 365, on-premises locations, and non-Microsoft applications.\n\nWithout sensitivity labels, organizations lack a standardized way to protect their data, leaving it vulnerable to unauthorized access and sharing. A well-designed label taxonomy typically includes 3-7 top-level labels—too many labels overwhelm users and reduce effectiveness.\n\n**Remediation action**\n\n- [Get started with sensitivity labels](https://learn.microsoft.com/purview/get-started-with-sensitivity-labels?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci)\n- [Create and configure sensitivity labels and their policies](https://learn.microsoft.com/purview/create-sensitivity-labels?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci)\n","TestTitle":"Total Sensitivity Labels Configured","SkippedReason":null,"TestId":"35003","TestImplementationCost":"Medium","TestMinimumLicense":["RMS_S_PREMIUM"],"TestSfiPillar":"Protect tenants and production systems","TestResult":"\n✅ At least one sensitivity label is configured in the tenant.\n\n### Sensitivity Label Configuration Summary\n\n**Label Statistics:**\n* Total Label Count: 9\n* Top-Level Labels Count: 9\n* Sub-Labels Count: 0\n\n**Sample Labels** (up to 5):\n| Label Name | Priority | Parent Label |\n|:---|:---|:---|\n| alex-test-label-1-display | 0 | None |\n| 35010Test | 1 | None |\n| Confidential – RMS | 2 | None |\n| peyton | 3 | None |\n| test-35012-1 | 4 | None |\n\n[Manage Sensitivity Labels in Microsoft Purview](https://purview.microsoft.com/informationprotection/informationprotectionlabels/sensitivitylabels)\n\n\n","TestStatus":"Passed","TestTags":null},{"TestImplementationCost":"Medium","TestPillar":"Identity","TestCategory":"Application management","SkippedReason":null,"TestImpact":"Medium","TestAppliesTo":["Identity"],"TestSfiPillar":"Protect tenants and isolate production systems","TestSkipped":"","TestMinimumLicense":"Free","TestTags":["Identity"],"TestTitle":"All guests have a sponsor","TestRisk":"Medium","TestResult":"\n✅ All guest accounts in the tenant have an assigned sponsor.\n\n","TestStatus":"Passed","TestDescription":"Inviting external guests is beneficial for organizational collaboration. However, in the absence of an assigned internal sponsor for each guest, these accounts might persist within the directory without clear accountability. This oversight creates a risk: threat actors could potentially compromise an unused or unmonitored guest account, and then establish an initial foothold within the tenant. Once granted access as an apparent \"legitimate\" user, an attacker might explore accessible resources and attempt privilege escalation, which could ultimately expose sensitive information or critical systems. An unmonitored guest account might therefore become the vector for unauthorized data access or a significant security breach. A typical attack sequence might use the following pattern, all achieved under the guise of a standard external collaborator:\n\n1. Initial access gained through compromised guest credentials\n1. Persistence due to a lack of oversight.\n1. Further escalation or lateral movement if the guest account possesses group memberships or elevated permissions.\n1. Execution of malicious objectives. \n\nMandating that every guest account is assigned to a sponsor directly mitigates this risk. Such a requirement ensures that each external user is linked to a responsible internal party who is expected to regularly monitor and attest to the guest's ongoing need for access. The sponsor feature within Microsoft Entra ID supports accountability by tracking the inviter and preventing the proliferation of \"orphaned\" guest accounts. When a sponsor manages the guest account lifecycle, such as removing access when collaboration concludes, the opportunity for threat actors to exploit neglected accounts is substantially reduced. This best practice is consistent with Microsoft’s guidance to require sponsorship for business guests as part of an effective guest access governance strategy. It strikes a balance between enabling collaboration and enforcing security, as it guarantees that each guest user's presence and permissions remain under ongoing internal oversight.\n\n**Remediation action**\n- For each guest user that has no sponsor, assign a sponsor in Microsoft Entra ID.\n - [Add a sponsor to a guest user in the Microsoft Entra admin center](https://learn.microsoft.com/entra/external-id/b2b-sponsors?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci)\n - [Add a sponsor to a guest user using Microsoft Graph](https://learn.microsoft.com/graph/api/user-post-sponsors?view=graph-rest-1.0&preserve-view=true&wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci)\n","TestId":"21877"},{"TestImplementationCost":"Low","TestPillar":"Identity","TestCategory":"Access control","SkippedReason":"UnderConstruction","TestImpact":"Medium","TestAppliesTo":["Identity"],"TestSfiPillar":"Protect identities and secrets","TestSkipped":"UnderConstruction","TestMinimumLicense":null,"TestTags":["Identity"],"TestTitle":"Require password reset notifications for user roles","TestRisk":"Medium","TestResult":"\nPlanned for future release.\n","TestStatus":"Planned","TestDescription":"...\n\n**Remediation action**\n\n","TestId":"21890"},{"TestImplementationCost":"Low","TestPillar":"Identity","TestCategory":"Access control","SkippedReason":"UnderConstruction","TestImpact":"Low","TestAppliesTo":["Identity"],"TestSfiPillar":"Protect identities and secrets","TestSkipped":"UnderConstruction","TestMinimumLicense":null,"TestTags":["Identity"],"TestTitle":"Azure resources used by Microsoft Entra only allow access from privileged roles","TestRisk":"High","TestResult":"\nPlanned for future release.\n","TestStatus":"Planned","TestDescription":"...\n\n**Remediation action**\n\n","TestId":"21912"},{"TestImplementationCost":"Low","TestPillar":"Identity","TestCategory":"Access control","SkippedReason":null,"TestImpact":"Medium","TestAppliesTo":["Identity"],"TestSfiPillar":"Protect identities and secrets","TestSkipped":"","TestMinimumLicense":"P1","TestTags":["Identity"],"TestTitle":"Require multifactor authentication for device join and device registration using user action","TestRisk":"High","TestResult":"\n**Properly configured Conditional Access policies found** that require MFA for device registration/join actions.\n## Device Settings Configuration\n\n| Setting | Value | Recommended Value | Status |\n| :------ | :---- | :---------------- | :----- |\n| Require Multi-Factor Authentication to register or join devices | No | No | ✅ Correctly configured |\n\n## Device Registration/Join Conditional Access Policies\n\n| Policy Name | State | Requires MFA | Status |\n| :---------- | :---- | :----------- | :----- |\n| [testdevicereg21872](https://entra.microsoft.com/#view/Microsoft_AAD_ConditionalAccess/PolicyBlade/policyId/620a9c5c-09c4-4558-a0fe-7fc8b3540992) | enabled | Yes | ✅ Properly configured |\n\n\n","TestStatus":"Passed","TestDescription":"Threat actors can exploit the lack of multifactor authentication during new device registration. Once authenticated, they can register rogue devices, establish persistence, and circumvent security controls tied to trusted endpoints. This foothold enables attackers to exfiltrate sensitive data, deploy malicious applications, or move laterally, depending on the permissions of the accounts being used by the attacker. Without MFA enforcement, risk escalates as adversaries can continuously reauthenticate, evade detection, and execute objectives.\n\n**Remediation action**\n\n- [Deploy a Conditional Access policy to require multifactor authentication for device registration](https://learn.microsoft.com/entra/identity/conditional-access/policy-all-users-device-registration?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci).\n","TestId":"21872"},{"TestImplementationCost":"Low","TestPillar":"Identity","TestCategory":"External collaboration","SkippedReason":null,"TestImpact":"Medium","TestAppliesTo":["Identity"],"TestSfiPillar":"Protect tenants and isolate production systems","TestSkipped":"","TestMinimumLicense":"Free","TestTags":["Application"],"TestTitle":"Guests have restricted access to directory objects","TestRisk":"Medium","TestResult":"\n✅ Validated guest user access is restricted.\n\n","TestStatus":"Passed","TestDescription":"External user accounts are often used to provide access to business partners who belong to organizations that have a business relationship with your enterprise. If these accounts are compromised in their organization, attackers can use the valid credentials to gain initial access to your environment, often bypassing traditional defenses due to their legitimacy. \n\nExternal accounts with permissions to read directory object permissions provide attackers with broader initial access if compromised. These accounts allow attackers to gather additional information from the directory for reconnaissance.\n\n**Remediation action**\n\n- [Restrict guest access to their own directory objects](https://learn.microsoft.com/entra/external-id/external-collaboration-settings-configure?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci#to-configure-guest-user-access)\n","TestId":"21792"},{"TestImplementationCost":"Low","TestPillar":"Identity","TestCategory":"Application management","SkippedReason":null,"TestImpact":"Low","TestAppliesTo":["Identity"],"TestSfiPillar":"Protect identities and secrets","TestSkipped":"","TestMinimumLicense":"Free","TestTags":["Identity"],"TestTitle":"Admin consent workflow is enabled","TestRisk":"High","TestResult":"\nAdmin consent workflow is disabled.\n\nThe adminConsentRequestPolicy.isEnabled property is set to false.\n\n","TestStatus":"Failed","TestDescription":"Enabling the Admin consent workflow in a Microsoft Entra tenant is a vital security measure that mitigates risks associated with unauthorized application access and privilege escalation. This check is important because it ensures that any application requesting elevated permission undergoes a review process by designated administrators before consent is granted. The admin consent workflow in Microsoft Entra ID notifies reviewers who evaluate and approve or deny consent requests based on the application's legitimacy and necessity. If this check doesn't pass, meaning the workflow is disabled, any application can request and potentially receive elevated permissions without administrative review. This poses a substantial security risk, as malicious actors could exploit this lack of oversight to gain unauthorized access to sensitive data, perform privilege escalation, or execute other malicious activities.\n\n**Remediation action**\n\nFor admin consent requests, set the **Users can request admin consent to apps they are unable to consent to** setting to **Yes**. Specify other settings, such as who can review requests.\n\n- [Enable the admin consent workflow](https://learn.microsoft.com/entra/identity/enterprise-apps/configure-admin-consent-workflow?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci#enable-the-admin-consent-workflow)\n- Or use the [Update adminConsentRequestPolicy](https://learn.microsoft.com/graph/api/adminconsentrequestpolicy-update?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci) API to set the `isEnabled` property to true and other settings\n","TestId":"21809"},{"TestImplementationCost":"","TestPillar":"Infrastructure","TestCategory":"Restrict unauthorized network access","SkippedReason":null,"TestImpact":"","TestAppliesTo":null,"TestSfiPillar":"Protect tenants and isolate production systems","TestSkipped":"","TestMinimumLicense":"N/A","TestTags":null,"TestTitle":"All network ports should be restricted on network security groups associated to your virtual machine","TestRisk":"High","TestResult":"All network ports should be restricted on network security groups associated to your virtual machine\n\n| Subscription | Resource group | Resource type | Affected resource | Status | Azure portal |\n| :----------- | :------------- | :------------ | :---------------- | :----- | :----------- |\n| [Visual Studio Enterprise Subscription](https://portal.azure.com/#resource/subscriptions/54d3ea01-5a07-45d0-8d69-e5f5b0b20098) | indiavm_group | virtualmachines | [india-2](https://portal.azure.com/#resource/subscriptions/54d3ea01-5a07-45d0-8d69-e5f5b0b20098/resourceGroups/INDIAVM_GROUP/providers/Microsoft.Compute/virtualMachines/india-2) | ❌ | [View recommendation](https://portal.azure.com/#blade/Microsoft_Azure_Security/RecommendationsBlade/assessmentKey/3b20e985-f71f-483b-b078-f30d73936d43/resourceId/%2fsubscriptions%2f54d3ea01-5a07-45d0-8d69-e5f5b0b20098%2fresourceGroups%2fINDIAVM_GROUP%2fproviders%2fMicrosoft.Compute%2fvirtualMachines%2findia-2) |\n| [Visual Studio Enterprise Subscription](https://portal.azure.com/#resource/subscriptions/54d3ea01-5a07-45d0-8d69-e5f5b0b20098) | indiavm_group | virtualmachines | [indiavm](https://portal.azure.com/#resource/subscriptions/54d3ea01-5a07-45d0-8d69-e5f5b0b20098/resourceGroups/INDIAVM_GROUP/providers/Microsoft.Compute/virtualMachines/indiavm) | ✅ | [View recommendation](https://portal.azure.com/#blade/Microsoft_Azure_Security/RecommendationsBlade/assessmentKey/3b20e985-f71f-483b-b078-f30d73936d43/resourceId/%2fsubscriptions%2f54d3ea01-5a07-45d0-8d69-e5f5b0b20098%2fresourceGroups%2fINDIAVM_GROUP%2fproviders%2fMicrosoft.Compute%2fvirtualMachines%2findiavm) |\n","TestStatus":"Failed","TestDescription":"Defender for Cloud has identified some of your network security groups' inbound rules to be too permissive. Inbound rules should not allow access from 'Any' or 'Internet' ranges. This can potentially enable attackers to target your resources.\n\n**Remediation action**\n\nWe recommend that you edit the inbound rules of some of your virtual machines, to restrict access to specific source ranges.
To restrict access to your virtual machines:
1. Select a VM to restrict access to.
2. In the 'Networking' blade, click the Network Security Group with overly permissive rules.
3. In the 'Network security group' blade, click on each of the rules that are overly permissive.
4. Improve the rule by applying less permissive source IP ranges.
5. Apply the suggested changes and click 'Save'.
If some or all of these virtual machines do not need to be accessed directly from the Internet, then you can also consider removing the public IP associated to them.","TestId":"3b20e985-f71f-483b-b078-f30d73936d43"},{"TestImplementationCost":"Low","TestPillar":"Identity","TestCategory":"Application management","SkippedReason":null,"TestImpact":"Low","TestAppliesTo":["Identity"],"TestSfiPillar":"Protect identities and secrets","TestSkipped":"","TestMinimumLicense":"Free","TestTags":["Identity"],"TestTitle":"Microsoft services applications don't have credentials configured","TestRisk":"High","TestResult":"\nNo Microsoft services applications have credentials configured in the tenant.\n\n","TestStatus":"Passed","TestDescription":"Microsoft services applications that operate in your tenant are identified as service principals with the owner organization ID \"f8cdef31-a31e-4b4a-93e4-5f571e91255a.\" When these service principals have credentials configured in your tenant, they might create potential attack vectors that threat actors can exploit. If an administrator added the credentials and they're no longer needed, they can become a target for attackers. Although less likely when proper preventive and detective controls are in place on privileged activities, threat actors can also maliciously add credentials. In either case, threat actors can use these credentials to authenticate as the service principal, gaining the same permissions and access rights as the Microsoft service application. This initial access can lead to privilege escalation if the application has high-level permissions, allowing lateral movement across the tenant. Attackers can then proceed to data exfiltration or persistence establishment through creating other backdoor credentials.\n\nWhen credentials (like client secrets or certificates) are configured for these service principals in your tenant, it means someone - either an administrator or a malicious actor - enabled them to authenticate independently within your environment. These credentials should be investigated to determine their legitimacy and necessity. If they're no longer needed, they should be removed to reduce the risk. \n\nIf this check doesn't pass, the recommendation is to \"investigate\" because you need to identify and review any applications with unused credentials configured.\n\n**Remediation action**\n\n- Confirm if the credentials added are still valid use cases. If not, remove credentials from Microsoft service applications to reduce security risk. \n - In the Microsoft Entra admin center, browse to **Entra ID** > **App registrations** and select the affected application.\n - Go to the **Certificates & secrets** section and remove any credentials that are no longer needed.\n","TestId":"21774"},{"TestImplementationCost":"Low","TestPillar":"Identity","TestCategory":"Credential management","SkippedReason":null,"TestImpact":"Low","TestAppliesTo":null,"TestSfiPillar":"Protect identities and secrets","TestSkipped":"","TestMinimumLicense":"P1","TestTags":null,"TestTitle":"Password protection for on-premises is enabled","TestRisk":"High","TestResult":"\n\n❌ **Fail**: Password protection for on-premises is not set to 'Enforce' mode.\n\n## Password Protection Settings\n\n| Setting | Value |\n| :---- | :---- |\n| Password Protection for Active Directory Domain Services | ✅ Enabled |\n| Enabled Mode (Audit/Enforce) | ❌ Audit |\n\n\n","TestStatus":"Failed","TestDescription":"When on-premises password protection isn’t enabled or enforced, threat actors can use low-and-slow password spray with common variants, such as season+year+symbol or local terms, to gain initial access to Active Directory Domain Services accounts. Domain Controllers (DCs) can accept weak passwords when either of the following statements are true:\n\n- Microsoft Entra Password Protection DC agent isn't installed\n- The password protection tenant setting is disabled or in audit-only mode\n\nWith valid on-premises credentials, attackers laterally move by reusing passwords across endpoints, escalate to domain admin through local admin reuse or service accounts, and persist by adding backdoors, while weak or disabled enforcement produces fewer blocking events and predictable signals. Microsoft’s design requires a proxy that brokers policy from Microsoft Entra ID and a DC agent that enforces the combined global and tenant custom banned lists on password change/reset; consistent enforcement requires DC agent coverage on all DCs in a domain and using Enforced mode after audit evaluation.\n\n**Remediation action**\n\n- [Deploy Microsoft Entra password protection](https://learn.microsoft.com/entra/identity/authentication/howto-password-ban-bad-on-premises-deploy?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci)\n","TestId":"21847"},{"TestImplementationCost":"Low","TestPillar":"Devices","TestCategory":"Device","SkippedReason":null,"TestImpact":"Low","TestAppliesTo":null,"TestSfiPillar":"Protect identities and secrets","TestSkipped":"","TestMinimumLicense":"Intune","TestTags":null,"TestTitle":"Windows Cloud LAPS policy is created and assigned","TestRisk":"High","TestResult":"\nCloud LAPS policy is assigned and enforced.\n\n\n## Windows Cloud LAPS policy is created and assigned\n\n| Policy Name | Status | Assignment | Backup Directory | Automatic Account Management |\n| :---------- | :----- | :--------- | :--------------- | :--------------------------- |\n| [relaps](https://intune.microsoft.com/#view/Microsoft_Intune_Workflows/SecurityManagementMenu/~/accountprotection) | ✅ Assigned | **Included:** All Devices | ✅ Entra ID (AAD) | ❌ Not Configured |\n| [test](https://intune.microsoft.com/#view/Microsoft_Intune_Workflows/SecurityManagementMenu/~/accountprotection) | ✅ Assigned | **Included:** All Users | ✅ Active Directory | ✅ Enabled |\n\n\n\n","TestStatus":"Passed","TestDescription":"Without enforcing Local Administrator Password Solution (LAPS) policies, threat actors who gain access to endpoints can exploit static or weak local administrator passwords to escalate privileges, move laterally, and establish persistence. The attack chain typically begins with device compromise—via phishing, malware, or physical access—followed by attempts to harvest local admin credentials. Without LAPS, attackers can reuse compromised credentials across multiple devices, increasing the risk of privilege escalation and domain-wide compromise.\n\nEnforcing Windows LAPS on all corporate Windows devices ensures unique, regularly rotated local administrator passwords. This disrupts the attack chain at the credential access and lateral movement stages, significantly reducing the risk of widespread compromise.\n\n**Remediation action**\n\nUse Intune to enforce Windows LAPS policies that rotate strong and unique local admin passwords, and that back them up securely: \n- [Deploy Windows LAPS policy with Microsoft Intune](https://learn.microsoft.com/intune/intune-service/protect/windows-laps-policy?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci#create-a-laps-policy)\n\nFor more information, see: \n- [Windows LAPS policy settings reference](https://learn.microsoft.com/windows-server/identity/laps/laps-management-policy-settings?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci)\n- [Learn about Intune support for Windows LAPS](https://learn.microsoft.com/intune/intune-service/protect/windows-laps-overview?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci)\n","TestId":"24560"},{"TestImplementationCost":"High","TestPillar":"Identity","TestCategory":"Monitoring","SkippedReason":null,"TestImpact":"Low","TestAppliesTo":["Identity"],"TestSfiPillar":"Monitor and detect cyberthreats","TestSkipped":"","TestMinimumLicense":"P1","TestTags":["Identity"],"TestTitle":"All Microsoft Entra recommendations are addressed","TestRisk":"Medium","TestResult":"\nFound 11 unaddressed Entra recommendations.\n\n\n## Unaddressed Entra recommendations\n\n| Display Name | Status | Insights | Priority |\n| :--- | :--- | :--- | :--- |\n| Protect your tenant with Insider Risk condition in Conditional Access policy | active | You have 86 of 88 users that aren’t covered by the Insider Risk condition in a Conditional Access policy. | medium |\n| Protect all users with a user risk policy | active | You have 86 of 88 users that don’t have a user risk policy enabled. | high |\n| Protect all users with a sign-in risk policy | active | You have 86 of 88 users that don't have a sign-in risk policy turned on. | high |\n| Enable password hash sync if hybrid | active | You have disabled password hash sync. | medium |\n| Ensure all users can complete multifactor authentication | active | You have 59 of 88 users that aren’t registered with MFA. | high |\n| Enable policy to block legacy authentication | active | You have 3 of 88 users that don’t have legacy authentication blocked. | high |\n| Require multifactor authentication for administrative roles | active | You have 8 of 26 users with administrative roles that aren’t registered and protected with MFA. | high |\n| Renew expiring application credentials | active | Your tenant has applications with credentials that will expire soon. | high |\n| Remove unused credentials from applications | active | Your tenant has applications with credentials which have not been used in more than 30 days. | medium |\n| Remove unused applications | active | This recommendation will surface if your tenant has applications that have not been used for over 90 days. Applications that were created but never used, client applications which have not been issued a token or resource apps that have not been a target of a token request, will show under this recommendation. | medium |\n| Start your Defender for Identity deployment, installing Sensors on Domain Controllers and other eligible servers. | active | Installing Microsoft Defender for Identity sensors provides you with the ability to detect advanced threats in your entire identity infrastructure. Actionable security alerts are generated through the analysis of network traffic and security events. | low |\n\n\n","TestStatus":"Failed","TestDescription":"Microsoft Entra recommendations give organizations opportunities to implement best practices and optimize their security posture. Not acting on these items might result in an increased attack surface area, suboptimal operations, or poor user experience.\n\n**Remediation action**\n\n- [Address all active or postponed recommendations in the Microsoft Entra admin center](https://learn.microsoft.com/entra/identity/monitoring-health/overview-recommendations?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci#how-does-it-work)\n","TestId":"21866"},{"TestImpact":"Medium","TestRisk":"Low","TestSkipped":"","TestAppliesTo":null,"TestPillar":"Data","TestCategory":"Sensitivity Labels","TestDescription":"Labels must be published by using label policies before users can apply them to items, such as files, emails, and meetings. Label policies define which users receive which labels, set default labeling behavior, and other labeling requirements. Without published policies, sensitivity labels remain unavailable to users.\n\n**Remediation action**\n\n- [Create and configure sensitivity labels and their policies](https://learn.microsoft.com/purview/create-sensitivity-labels?tabs=classic-label-scheme&wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci#publish-sensitivity-labels-by-creating-a-label-policy)\n","TestTitle":"Published Label Policies","SkippedReason":null,"TestId":"35004","TestImplementationCost":"Low","TestMinimumLicense":["RMS_S_PREMIUM"],"TestSfiPillar":"Protect tenants and production systems","TestResult":"\n✅ At least one enabled label policy is published to users.\n\n### Label Policy Summary\n\n* Total Policies Configured: 6\n* Enabled Policies: 6\n* Disabled Policies: 0\n* Total Users/Groups with Label Access: All Users\n\n**Policies:**\n| Policy name | Enabled | Labels included | Published to |\n|:---|:---|:---|:---|\n| 35035-Test-Policy | True | 1 | Specific Users/Groups |\n| Test Policy | True | 1 | Specific Users/Groups |\n| true event | True | 1 | All Users/Groups |\n| userpolicy | True | 1 | Specific Users/Groups |\n| peyton | True | 1 | All Users/Groups |\n| test-policy-35012 | True | 1 | All Users/Groups |\n\n[Manage Label Policies in Microsoft Purview](https://purview.microsoft.com/informationprotection/labelpolicies)\n\n\n","TestStatus":"Passed","TestTags":null},{"TestImplementationCost":"Medium","TestPillar":"Identity","TestCategory":"Applications management","SkippedReason":null,"TestImpact":"Low","TestAppliesTo":["Identity"],"TestSfiPillar":"Protect identities and secrets","TestSkipped":"","TestMinimumLicense":"P1","TestTags":["Identity"],"TestTitle":"Applications that use Microsoft Entra for authentication and support provisioning are configured","TestRisk":"Medium","TestResult":"\nApplications that are configured for SSO and support provisioning are NOT configured for provisioning.\n\n\n## Applications that are NOT configured for provisioning\n\n\n| Application Name | Object ID | Application ID |\n| :--------------- | :-------- | :------------- |\n| [21869testapp](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/Overview/objectId/e69e29be-ba40-445a-9824-a3a45e0ae57a/appId/dd63d132-18fb-4f2e-aec4-82b97f30301f/preferredSingleSignOnMode/saml/servicePrincipalType/Application/fromNav/) | e69e29be-ba40-445a-9824-a3a45e0ae57a | dd63d132-18fb-4f2e-aec4-82b97f30301f |\n| [APP-2732_Genesys Cloud TCCC-G-TFS-Prod](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/Overview/objectId/ba63bb52-182c-4ec6-9cc8-ad2287cf51ed/appId/76249b01-8747-4db4-843f-6478d5b32b14/preferredSingleSignOnMode/saml/servicePrincipalType/Application/fromNav/) | ba63bb52-182c-4ec6-9cc8-ad2287cf51ed | 76249b01-8747-4db4-843f-6478d5b32b14 |\n| [AWS Single-Account Access](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/Overview/objectId/dc89bf5d-83e8-4419-9162-3b9280a85755/appId/091edd89-b342-4bb5-9144-82fe6c913987/preferredSingleSignOnMode/saml/servicePrincipalType/Application/fromNav/) | dc89bf5d-83e8-4419-9162-3b9280a85755 | 091edd89-b342-4bb5-9144-82fe6c913987 |\n| [claimtest](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/Overview/objectId/f7b07e81-79a0-4e51-b93a-169b8f2f6c4e/appId/f816d68b-aec7-4eab-9ebc-bd23b0d04e35/preferredSingleSignOnMode/saml/servicePrincipalType/Application/fromNav/) | f7b07e81-79a0-4e51-b93a-169b8f2f6c4e | f816d68b-aec7-4eab-9ebc-bd23b0d04e35 |\n| [Docusign](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/Overview/objectId/c6c64515-9c2c-4458-830d-fda30f7f55b5/appId/bc582926-d3ef-48e0-9a43-e813b898afb0/preferredSingleSignOnMode/saml/servicePrincipalType/Application/fromNav/) | c6c64515-9c2c-4458-830d-fda30f7f55b5 | bc582926-d3ef-48e0-9a43-e813b898afb0 |\n| [Dropbox Business](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/Overview/objectId/5eec0e98-b81a-422a-ab61-f8de2729330d/appId/f76d7d98-02ee-4e62-9345-36016a72e664/preferredSingleSignOnMode/saml/servicePrincipalType/Application/fromNav/) | 5eec0e98-b81a-422a-ab61-f8de2729330d | f76d7d98-02ee-4e62-9345-36016a72e664 |\n| [charlie AWS Account](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/Overview/objectId/39861745-eda1-4e3c-8358-d0ba931f12bb/appId/d3a04f85-a969-436b-bf4d-eae0a91efb4c/preferredSingleSignOnMode/saml/servicePrincipalType/Application/fromNav/) | 39861745-eda1-4e3c-8358-d0ba931f12bb | d3a04f85-a969-436b-bf4d-eae0a91efb4c |\n| [charlie- Genesys Cloud for Azure](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/Overview/objectId/84dc13ec-5754-4745-90f9-5cc92a5ded28/appId/9c599cd2-9fb0-4815-b65c-83be33f5df1b/preferredSingleSignOnMode/saml/servicePrincipalType/Application/fromNav/) | 84dc13ec-5754-4745-90f9-5cc92a5ded28 | 9c599cd2-9fb0-4815-b65c-83be33f5df1b |\n| [Salesforce](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/Overview/objectId/13720002-03b6-462f-ac2f-765f0f9b3f58/appId/1a2a1d4c-1d76-44ec-95f4-3ed5345423a9/preferredSingleSignOnMode/saml/servicePrincipalType/Application/fromNav/) | 13720002-03b6-462f-ac2f-765f0f9b3f58 | 1a2a1d4c-1d76-44ec-95f4-3ed5345423a9 |\n| [Saml test entity id](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/Overview/objectId/d589a2e6-4a78-4cdd-901b-f574dc7880db/appId/6590313e-1c00-4c07-be28-72858e837a52/preferredSingleSignOnMode/saml/servicePrincipalType/Application/fromNav/) | d589a2e6-4a78-4cdd-901b-f574dc7880db | 6590313e-1c00-4c07-be28-72858e837a52 |\n| [ServiceNow](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/Overview/objectId/9a8af246-0d94-42eb-aaaf-836a9f9a4974/appId/ecbbb1c8-ef06-48c4-9211-9ffbfbc24b94/preferredSingleSignOnMode/saml/servicePrincipalType/Application/fromNav/) | 9a8af246-0d94-42eb-aaaf-836a9f9a4974 | ecbbb1c8-ef06-48c4-9211-9ffbfbc24b94 |\n| [test](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/Overview/objectId/31e80a1b-3faa-4ce9-9794-2b77f61f20f7/appId/8ae2b566-71f5-467e-8960-cfe8da3a2cfa/preferredSingleSignOnMode/saml/servicePrincipalType/Application/fromNav/) | 31e80a1b-3faa-4ce9-9794-2b77f61f20f7 | 8ae2b566-71f5-467e-8960-cfe8da3a2cfa |\n\n\n\n","TestStatus":"Failed","TestDescription":"When applications that support both authentication and provisioning through Microsoft Entra aren't configured for automatic provisioning, organizations become vulnerable to identity lifecycle gaps that threat actors can exploit. Without automated provisioning, user accounts might persist in applications after employees leave the organization. This vulnerability creates dormant accounts that threat actors can discover through reconnaissance activities. These orphaned accounts often retain their original access permissions but lack active monitoring, making them attractive targets for initial access.\n\nThreat actors who gain access to these dormant accounts can use them to establish persistence in the target application, as the accounts appear legitimate and might not trigger security alerts. From these compromised application accounts, attackers can:\n\n- Attempt to escalate their privileges by exploring application-specific permissions\n- Access sensitive data stored within the application\n- Use the application as a pivot point to access other connected systems\n\nThe lack of centralized identity lifecycle management also makes it difficult for security teams to detect when an attacker is using these orphaned accounts, as the accounts might not be properly correlated with the organization's active user directory. \n\n**Remediation action**\n\n- [Configure application provisioning for missing applications](https://learn.microsoft.com/entra/identity/app-provisioning/configure-automatic-user-provisioning-portal?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci)\n","TestId":"21886"},{"TestImplementationCost":"","TestPillar":"Infrastructure","TestCategory":"Manage access and permissions","SkippedReason":null,"TestImpact":"","TestAppliesTo":null,"TestSfiPillar":"Protect tenants and isolate production systems","TestSkipped":"","TestMinimumLicense":"N/A","TestTags":null,"TestTitle":"Disabled accounts with read and write permissions on Azure resources should be removed","TestRisk":"High","TestResult":"Disabled accounts with read and write permissions on Azure resources should be removed\n\n| Subscription | Affected resource | Status | Azure portal |\n| :----------- | :---------------- | :----- | :----------- |\n| [Visual Studio Enterprise Subscription](https://portal.azure.com/#resource/subscriptions/54d3ea01-5a07-45d0-8d69-e5f5b0b20098) | [54d3ea01-5a07-45d0-8d69-e5f5b0b20098](https://portal.azure.com/#resource/subscriptions/54d3ea01-5a07-45d0-8d69-e5f5b0b20098) | ✅ | [View recommendation](https://portal.azure.com/#blade/Microsoft_Azure_Security/RecommendationsBlade/assessmentKey/1ff0b4c9-ed56-4de6-be9c-d7ab39645926/resourceId/%2fsubscriptions%2f54d3ea01-5a07-45d0-8d69-e5f5b0b20098) |\n","TestStatus":"Passed","TestDescription":"It's important to remove disabled accounts that have read and write permissions on Azure resources.
These accounts, although disabled from signing in on Active Directory, can still be targeted by attackers.
If exploited, these accounts could provide unauthorized access to your data, potentially leading to data breaches.
Therefore, to maintain a secure environment, we recommend removing these accounts from Azure resources.
\n\n**Remediation action**\n\nReview the list of accounts that are disabled from signing in on the Accounts section. Select an account to view its role definitions and locate the source scope. If you accept the risk for specific account, use the exempt capability to exclude it from evaluation.
  1. Go to the Azure portal.
  2. Open Access control (IAM) at a scope, such as management group, subscription, resource group, or resource, where the guest user has a role assignment.
  3. Click the Role assignments tab to view all the role assignments.
  4. In the list of role assignments, add a checkmark next to the disabled user with the role assignment you want to remove.
  5. Click Remove. In the remove role assignment message that appears, click Yes.
","TestId":"1ff0b4c9-ed56-4de6-be9c-d7ab39645926"},{"TestImplementationCost":"Low","TestPillar":"Identity","TestCategory":"Credential management","SkippedReason":null,"TestImpact":"Low","TestAppliesTo":["Identity"],"TestSfiPillar":"Protect identities and secrets","TestSkipped":"","TestMinimumLicense":"P1","TestTags":["Identity"],"TestTitle":"Password expiration is disabled","TestRisk":"Medium","TestResult":"\nPassword expiration is properly disabled across all domains and users.\n\n","TestStatus":"Passed","TestDescription":"When password expiration policies remain enabled, threat actors can exploit the predictable password rotation patterns that users typically follow when forced to change passwords regularly. Users frequently create weaker passwords by making minimal modifications to existing ones, such as incrementing numbers or adding sequential characters. Threat actors can easily anticipate and exploit these types of changes through credential stuffing attacks or targeted password spraying campaigns. These predictable patterns enable threat actors to establish persistence through:\n\n- Compromised credentials\n- Escalated privileges by targeting administrative accounts with weak rotated passwords\n- Maintaining long-term access by predicting future password variations\n\nResearch shows that users create weaker, more predictable passwords when they are forced to expire. These predictable passwords are easier for experienced attackers to crack, as they often make simple modifications to existing passwords rather than creating entirely new, strong passwords. Additionally, when users are required to frequently change passwords, they might resort to insecure practices such as writing down passwords or storing them in easily accessible locations, creating more attack vectors for threat actors to exploit during physical reconnaissance or social engineering campaigns. \n\n**Remediation action**\n\n- [Set the password expiration policy for your organization](https://learn.microsoft.com/microsoft-365/admin/manage/set-password-expiration-policy?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci).\n - Sign in to the [Microsoft 365 admin center](https://admin.microsoft.com/). Go to **Settings** > **Org Settings** >** Security & Privacy** > **Password expiration policy**. Ensure the **Set passwords to never expire** setting is checked.\n- [Disable password expiration using Microsoft Graph](https://learn.microsoft.com/graph/api/domain-update?view=graph-rest-1.0&preserve-view=true&wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci).\n- [Set individual user passwords to never expire using Microsoft Graph PowerShell](https://learn.microsoft.com/microsoft-365/admin/add-users/set-password-to-never-expire?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci)\n - `Update-MgUser -UserId -PasswordPolicies DisablePasswordExpiration`\n","TestId":"21811"},{"TestImplementationCost":"Low","TestPillar":"Identity","TestCategory":"Monitoring","SkippedReason":"UnderConstruction","TestImpact":"Low","TestAppliesTo":["Identity"],"TestSfiPillar":"Monitor and detect cyberthreats","TestSkipped":"UnderConstruction","TestMinimumLicense":null,"TestTags":["Identity"],"TestTitle":"Tenant creation events are triaged","TestRisk":"Medium","TestResult":"\nPlanned for future release.\n\n","TestStatus":"Planned","TestDescription":"Tenant creation events should be monitored and triaged to detect unauthorized tenant creation. Users with sufficient permissions can create new tenants, which could be used to establish shadow environments outside your organization's security monitoring. Routing audit logs to a SIEM and configuring alerts for tenant creation events enables security teams to quickly investigate and respond to potentially malicious activity.\n\n**Remediation action**\n\n- [Review and restrict permissions to create tenants](https://learn.microsoft.com/entra/identity/role-based-access-control/permissions-reference?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci)\n- [Stream audit logs to an event hub for SIEM integration](https://learn.microsoft.com/entra/identity/monitoring-health/howto-stream-logs-to-event-hub?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci)\n- [Configure monitoring and alerting for audit events](https://learn.microsoft.com/entra/identity/monitoring-health/overview-monitoring-health?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci)\n","TestId":"21789"},{"TestImpact":"Medium","TestRisk":"Medium","TestSkipped":"","TestAppliesTo":null,"TestPillar":"Data","TestCategory":"Information Protection","TestDescription":"When users aren't required to provide a justification for changing a label, they can silently replace a label with one that has a lower sensitivity. For example, replace the \"Confidential\" label that applies additional protection settings, with \"General\". This action creates security and compliance risk. Requiring a justification reason makes this risk more obvious to users, and forces them to provide a reason as a visible audit trail.\n\nCompromised accounts or departing employees could downgrade labels to enable data exfiltration. Requiring justification is a lightweight control that increases accountability with low impact on user workflows.\n\n**Remediation action**\n\n- [Publish sensitivity labels by creating a label policy](https://learn.microsoft.com/purview/create-sensitivity-labels?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci#publish-sensitivity-labels-by-creating-a-label-policy)\n- [What label policies can do](https://learn.microsoft.com/purview/sensitivity-labels?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci#what-label-policies-can-do)\n- [Review labeling activities in activity explorer](https://learn.microsoft.com/purview/data-classification-activity-explorer-available-events?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci#protection-removed)\n","TestTitle":"Downgrade Justification Required for Sensitivity Labels","SkippedReason":null,"TestId":"35018","TestImplementationCost":"Low","TestMinimumLicense":["RMS_S_PREMIUM"],"TestSfiPillar":"Protect tenants and production systems","TestResult":"\n✅ Downgrade justification is enforced in at least one enabled sensitivity label policy.\n\n\n\n### Downgrade Justification Configuration\n| Policy name | Downgrade justification | Scope | Labels | Workloads |\n| :--- | :--- | :--- | :--- | :--- |\n| [35035-Test-Policy](https://purview.microsoft.com/informationprotection/labelpolicies) | ✅ | Scoped | 1 | M365 Groups |\n| [Test Policy](https://purview.microsoft.com/informationprotection/labelpolicies) | ✅ | Scoped | 1 | Exchange |\n| [true event](https://purview.microsoft.com/informationprotection/labelpolicies) | ✅ | Global | 1 | Exchange |\n| [userpolicy](https://purview.microsoft.com/informationprotection/labelpolicies) | ✅ | Scoped | 1 | Exchange |\n| [peyton](https://purview.microsoft.com/informationprotection/labelpolicies) | ✅ | Global | 1 | Exchange |\n| [test-policy-35012](https://purview.microsoft.com/informationprotection/labelpolicies) | ❌ | Global | 1 | Exchange |\n\n### Summary\n| Metric | Count |\n| :--- | :--- |\n| Total enabled label policies | 6 |\n| Policies requiring downgrade justification | 5 |\n| Policies NOT requiring downgrade justification | 1 |\n| Percentage with downgrade justification | 83.33% |\n\n","TestStatus":"Passed","TestTags":null},{"TestImplementationCost":"Medium","TestPillar":"Identity","TestCategory":"Application management","SkippedReason":null,"TestImpact":"Low","TestAppliesTo":["Identity"],"TestSfiPillar":"Protect engineering systems","TestSkipped":"","TestMinimumLicense":"P2","TestTags":["Identity"],"TestTitle":"Global Administrator role activation triggers an approval workflow","TestRisk":"High","TestResult":"\n✅ **Pass**: Approval required with 2 primary approver(s) configured.\n\n\n## Global Administrator role activation and approval workflow\n\n\n| Approval Required | Primary Approvers | Escalation Approvers |\n| :---------------- | :---------------- | :------------------- |\n| Yes | Jordan Smith, Ash Williams | |\n\n\n\n","TestStatus":"Passed","TestDescription":"Without approval workflows, threat actors who compromise Global Administrator credentials through phishing, credential stuffing, or other authentication bypass techniques can immediately activate the most privileged role in a tenant without any other verification or oversight. Privileged Identity Management (PIM) allows eligible role activations to become active within seconds, so compromised credentials can allow near-instant privilege escalation. Once activated, threat actors can use the Global Administrator role to use the following attack paths to gain persistent access to the tenant:\n- Create new privileged accounts\n- Modify Conditional Access policies to exclude those new accounts\n- Establish alternate authentication methods such as certificate-based authentication or application registrations with high privileges\n\nThe Global Administrator role provides access to administrative features in Microsoft Entra ID and services that use Microsoft Entra identities, including Microsoft Defender XDR, Microsoft Purview, Exchange Online, and SharePoint Online. Without approval gates, threat actors can rapidly escalate to complete tenant takeover, exfiltrating sensitive data, compromising all user accounts, and establishing long-term backdoors through service principals or federation modifications that persist even after the initial compromise is detected. \n\n**Remediation action**\n\n- [Configure role settings to require approval for Global Administrator activation](https://learn.microsoft.com/entra/id-governance/privileged-identity-management/pim-how-to-change-default-settings?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci)\n- [Set up approval workflow for privileged roles](https://learn.microsoft.com/entra/id-governance/privileged-identity-management/pim-approval-workflow?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci)\n","TestId":"21817"},{"TestImplementationCost":"Medium","TestPillar":"Identity","TestCategory":"Access control","SkippedReason":null,"TestImpact":"Low","TestAppliesTo":null,"TestSfiPillar":"Protect identities and secrets","TestSkipped":"","TestMinimumLicense":"Free","TestTags":null,"TestTitle":"Block legacy Azure AD PowerShell module","TestRisk":"Medium","TestResult":"\nSummary\n\n- [Azure AD PowerShell](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/Overview/objectId/39921e28-0140-4bfc-ad89-26a3294f6ca9/appId/1b730954-1685-4b74-9bfd-dac224a7b894)\n- Sign in disabled: Yes\n\nAzure AD PowerShell is blocked in the tenant by turning off user sign in to the Azure Active Directory PowerShell Enterprise Application.\n\n","TestStatus":"Passed","TestDescription":"Threat actors frequently target legacy management interfaces such as the Azure AD PowerShell module (AzureAD and AzureADPreview), which don't support modern authentication, Conditional Access enforcement, or advanced audit logging. Continued use of these modules exposes the environment to risks including weak authentication, bypass of security controls, and incomplete visibility into administrative actions. Attackers can exploit these weaknesses to gain unauthorized access, escalate privileges, and perform malicious changes. \n\nBlock the Azure AD PowerShell module and enforce the use of Microsoft Graph PowerShell or Microsoft Entra PowerShell to ensure that only secure, supported, and auditable management channels are available, which closes critical gaps in the attack chain. \n\n**Remediation action**\n\n- [Disable user sign-in for application](https://learn.microsoft.com/entra/identity/enterprise-apps/disable-user-sign-in-portal?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci)\n","TestId":"21844"},{"TestImplementationCost":"Medium","TestPillar":"Identity","TestCategory":"Access control","SkippedReason":null,"TestImpact":"Low","TestAppliesTo":["Identity"],"TestSfiPillar":"Protect identities and secrets","TestSkipped":"","TestMinimumLicense":"P1","TestTags":["Identity"],"TestTitle":"Secure the MFA registration (My Security Info) page","TestRisk":"High","TestResult":"\nSecurity information registration is protected by Conditional Access policies.\n## Conditional Access Policies targeting security information registration\n\n\n| Policy Name | User Actions Targeted | Grant Controls Applied |\n| :---------- | :-------------------- | :--------------------- |\n| [Security regisrtation info](https://entra.microsoft.com/#view/Microsoft_AAD_ConditionalAccess/PolicyBlade/policyId/508ae024-d4c4-42bf-a8c9-40257c214c10) | urn:user:registersecurityinfo | |\n\n\n\n","TestStatus":"Passed","TestDescription":"Without Conditional Access policies protecting security information registration, threat actors can exploit unprotected registration flows to compromise authentication methods. When users register multifactor authentication and self-service password reset methods without proper controls, threat actors can intercept these registration sessions through adversary-in-the-middle attacks or exploit unmanaged devices accessing registration from untrusted locations. Once threat actors gain access to an unprotected registration flow, they can register their own authentication methods, effectively hijacking the target's authentication profile. The threat actors can bypass security controls and potentially escalate privileges throughout the environment because they can maintain persistent access by controlling the MFA methods. The compromised authentication methods then become the foundation for lateral movement as threat actors can authenticate as the legitimate user across multiple services and applications.\n\n**Remediation action**\n\n- [Deploy a Conditional Access policy for security info registration](https://learn.microsoft.com/entra/identity/conditional-access/policy-all-users-security-info-registration?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci)\n- [Configure known network locations](https://learn.microsoft.com/entra/identity/conditional-access/concept-assignment-network?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci)\n- [Enable combined security info registration](https://learn.microsoft.com/entra/identity/authentication/howto-registration-mfa-sspr-combined?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci)\n","TestId":"21806"},{"TestImplementationCost":"Low","TestPillar":"Identity","TestCategory":"Devices","SkippedReason":"This test is not applicable to the current environment.","TestImpact":"Low","TestAppliesTo":null,"TestSfiPillar":"Protect tenants and isolate production systems","TestSkipped":"NotApplicable","TestMinimumLicense":"P1","TestTags":null,"TestTitle":"Manage the local administrators on Microsoft Entra joined devices","TestRisk":"High","TestResult":"\nSkipped. This test is not applicable to the current environment.\n\n","TestStatus":"Skipped","TestDescription":"When local administrators on Microsoft Entra joined devices aren't properly managed, threat actors with compromised credentials can execute device takeover attacks by removing organizational administrators and disabling the device's connection to Microsoft Entra. This lack of control results in complete loss of organizational control, creating orphaned assets that can't be managed or recovered.\n\n**Remediation action**\n\n- [Manage the local administrators on Microsoft Entra joined devices](https://learn.microsoft.com/entra/identity/devices/assign-local-admin?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci#manage-the-microsoft-entra-joined-device-local-administrator-role)\n","TestId":21955},{"TestImplementationCost":"","TestPillar":"Infrastructure","TestCategory":"Apply system updates","SkippedReason":"This test is not applicable to the current environment.","TestImpact":"","TestAppliesTo":null,"TestSfiPillar":"Protect tenants and isolate production systems","TestSkipped":"NotApplicable","TestMinimumLicense":"N/A","TestTags":null,"TestTitle":"System updates should be installed on your machines (powered by Azure Update Manager)","TestRisk":"High","TestResult":"NotSupported, AssessmentModeNotSetToAuto\n\n| Subscription | Resource group | Resource type | Affected resource | Status | Azure portal |\n| :----------- | :------------- | :------------ | :---------------- | :----- | :----------- |\n| [Visual Studio Enterprise Subscription](https://portal.azure.com/#resource/subscriptions/54d3ea01-5a07-45d0-8d69-e5f5b0b20098) | indiavm_group | virtualmachines | [india-2](https://portal.azure.com/#resource/subscriptions/54d3ea01-5a07-45d0-8d69-e5f5b0b20098/resourcegroups/indiavm_group/providers/microsoft.compute/virtualmachines/india-2) | N/A | [View recommendation](https://portal.azure.com/#blade/Microsoft_Azure_Security/RecommendationsBlade/assessmentKey/e1145ab1-eb4f-43d8-911b-36ddf771d13f/resourceId/%2fsubscriptions%2f54d3ea01-5a07-45d0-8d69-e5f5b0b20098%2fresourcegroups%2findiavm_group%2fproviders%2fmicrosoft.compute%2fvirtualmachines%2findia-2) |\n| [Visual Studio Enterprise Subscription](https://portal.azure.com/#resource/subscriptions/54d3ea01-5a07-45d0-8d69-e5f5b0b20098) | indiavm_group | virtualmachines | [indiavm](https://portal.azure.com/#resource/subscriptions/54d3ea01-5a07-45d0-8d69-e5f5b0b20098/resourcegroups/indiavm_group/providers/microsoft.compute/virtualmachines/indiavm) | N/A | [View recommendation](https://portal.azure.com/#blade/Microsoft_Azure_Security/RecommendationsBlade/assessmentKey/e1145ab1-eb4f-43d8-911b-36ddf771d13f/resourceId/%2fsubscriptions%2f54d3ea01-5a07-45d0-8d69-e5f5b0b20098%2fresourcegroups%2findiavm_group%2fproviders%2fmicrosoft.compute%2fvirtualmachines%2findiavm) |\n","TestStatus":"Skipped","TestDescription":"It's important to keep your machines updated by installing any missing security and critical OS updates.
These updates often contain crucial patches for security vulnerabilities, which, if left unpatched, can be exploited by threat actors.
Therefore, to secure your machines and prevent potential breaches,follow the remediation steps and install all outstanding patches provided by Azure Update Manager.
\n\n**Remediation action**\n\nTo install missing system updates on a selected machine: 1. From \"Affected resources\", select a virtual machine. 2. Select the \"Fix\" button. This will redirect you to Azure Update Manager. 3. Follow the instructions on Azure Update Manager portal to complete the process.","TestId":"e1145ab1-eb4f-43d8-911b-36ddf771d13f"},{"TestImpact":"High","TestRisk":"Low","TestSkipped":"","TestAppliesTo":null,"TestPillar":"Data","TestCategory":"Sensitivity Labels","TestDescription":"When co-authoring isn't enabled for documents protected by sensitivity labels that apply encryption, only one person can edit the file at a time when they use Office desktop apps. As a result, this can slow down teams, which makes collaboration difficult and can delay project completion. This limitation is especially challenging for groups working on sensitive projects that require encryption for privacy but also need to work together efficiently.\n\nTurning on co-authoring for files encrypted with sensitivity labels lets several authorized users edit the file at the same time in Office desktop apps. Unless you can ensure that all users edit these files by using Office for the web, this change removes the slowdown of requiring checkout and allows teams to efficiently collaborate without sacrificing security. The co-authoring setting might also be a requirement for other labeling features.\n\n**Remediation action**\n\n- [Enable co-authoring for files encrypted with sensitivity labels](https://learn.microsoft.com/purview/sensitivity-labels-coauthoring?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci)\n","TestTitle":"Co-Authoring Enabled for Encrypted Documents","SkippedReason":null,"TestId":"35009","TestImplementationCost":"Low","TestMinimumLicense":["RMS_S_PREMIUM2"],"TestSfiPillar":"Protect tenants and production systems","TestResult":"\n✅ Co-authoring is enabled for encrypted documents with sensitivity labels.\n\n\n\n## Configuration Details\n\n| Setting | Status |\n| :------ | :----- |\n| EnableLabelCoauth | ✅ Enabled |\n\n\n","TestStatus":"Passed","TestTags":null},{"TestImplementationCost":"","TestPillar":"Infrastructure","TestCategory":"Implement security best practices","SkippedReason":"This test is not applicable to the current environment.","TestImpact":"","TestAppliesTo":null,"TestSfiPillar":"Protect tenants and isolate production systems","TestSkipped":"NotApplicable","TestMinimumLicense":"N/A","TestTags":null,"TestTitle":"Non-internet-facing virtual machines should be protected with network security groups","TestRisk":"Low","TestResult":"InternetFacingVms\n\n| Subscription | Resource group | Resource type | Affected resource | Status | Azure portal |\n| :----------- | :------------- | :------------ | :---------------- | :----- | :----------- |\n| [Visual Studio Enterprise Subscription](https://portal.azure.com/#resource/subscriptions/54d3ea01-5a07-45d0-8d69-e5f5b0b20098) | indiavm_group | virtualmachines | [india-2](https://portal.azure.com/#resource/subscriptions/54d3ea01-5a07-45d0-8d69-e5f5b0b20098/resourceGroups/indiavm_group/providers/Microsoft.Compute/virtualMachines/india-2) | N/A | [View recommendation](https://portal.azure.com/#blade/Microsoft_Azure_Security/RecommendationsBlade/assessmentKey/a9341235-9389-42f0-a0bf-9bfb57960d44/resourceId/%2fsubscriptions%2f54d3ea01-5a07-45d0-8d69-e5f5b0b20098%2fresourceGroups%2findiavm_group%2fproviders%2fMicrosoft.Compute%2fvirtualMachines%2findia-2) |\n| [Visual Studio Enterprise Subscription](https://portal.azure.com/#resource/subscriptions/54d3ea01-5a07-45d0-8d69-e5f5b0b20098) | indiavm_group | virtualmachines | [indiavm](https://portal.azure.com/#resource/subscriptions/54d3ea01-5a07-45d0-8d69-e5f5b0b20098/resourceGroups/indiavm_group/providers/Microsoft.Compute/virtualMachines/indiavm) | N/A | [View recommendation](https://portal.azure.com/#blade/Microsoft_Azure_Security/RecommendationsBlade/assessmentKey/a9341235-9389-42f0-a0bf-9bfb57960d44/resourceId/%2fsubscriptions%2f54d3ea01-5a07-45d0-8d69-e5f5b0b20098%2fresourceGroups%2findiavm_group%2fproviders%2fMicrosoft.Compute%2fvirtualMachines%2findiavm) |\n","TestStatus":"Skipped","TestDescription":"Protect your non-internet-facing virtual machine from potential threats by restricting access to it with a network security group (NSG). NSGs contain a list of Access Control List (ACL) rules that allow or deny network traffic to your VM from other instances, whether or not they're on the same subnet.
Note that to keep your machine as secure as possible, the VM's access to the internet must be restricted and an NSG should be enabled on the subnet.\n\n**Remediation action**\n\nTo protect a virtual machine with a network security group:
1. Select a VM from the list below, or select \"Take action\" if you've arrived from a recommendation for a specific VM.
2. Assign the relevant NSG to the NIC or subnet for the VM you're protecting:
  a. To assign the NSG to the VM's subnet (recommended):
    i. In the Networking page, select the 'Virtual network/subnet'.
    ii. Open the \"Subnets\" menu.
    iii. Select the subnet where your VM is deployed.
    iv. Select the network security group to assign to the subnet and select \"Save\".
  b. To assign the NSG to the NIC:
    i. In the Networking page, select the network interface that's associated with the selected VM.
    ii. In the Network interfaces page, select the 'Network security group' menu item.
    iii. Select 'Edit' at the top of the page.
    iv. Follow the on-screen instructions and select the network security group to assign to this NIC.
Learn more.","TestId":"a9341235-9389-42f0-a0bf-9bfb57960d44"},{"TestImpact":"High","TestRisk":"High","TestSkipped":"","TestAppliesTo":null,"TestPillar":"Data","TestCategory":"Sensitivity Labels Configuration","TestDescription":"Without encryption, sensitivity labels denote an item's sensitivity level without preventing unauthorized access, unless supplemented by another protection mechanism. Sensitivity labels that are configured to apply encryption from the Azure Rights Management service enforce access control and usage rights. This protection persists regardless of where the content is stored or shared. For example, users can still share a document labeled as \"Confidential\", but if that label applies encryption, unauthorized people won't be able to open it.\n\nOrganizations using labels without encryption gain visibility of the sensitivity level but the labels themselves lack technical enforcement. Labels that apply encryption ensure only authorized users can decrypt content and use it with any restrictions that are specified for that user. For example, read-only, or prevent copying. This protection helps prevent data exfiltration even if files are leaked or improperly shared. At least one sensitivity label should be configured to apply encryption for high-value data that requires protection beyond identifying the sensitivity level.\n\n**Remediation action**\n\n- [Restrict access to content by using encryption in sensitivity labels](https://learn.microsoft.com/purview/encryption-sensitivity-labels?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci)\n","TestTitle":"Encryption-Enabled Labels","SkippedReason":null,"TestId":"35013","TestImplementationCost":"Medium","TestMinimumLicense":["RMS_S_PREMIUM"],"TestSfiPillar":"Protect tenants and production systems","TestResult":"\n✅ At least one encryption-enabled sensitivity label is configured.\n\n\n## [Encryption Label Details](https://purview.microsoft.com/informationprotection/informationprotectionlabels/sensitivitylabels)\n\n| Label name | Encryption type | Default permissions identities | Co-Authoring blocked |\n| :--------- | :-------------- | :----------------------------- | :------------------: |\n| Confidential – RMS | User-Defined | Not specified | No |\n| test35036 | Standard RMS | demouser3791943@contoso.com, demouser3792567@contoso.com, demouser3792993@contoso.com | No |\n| test-dke | Double Key Encryption (DKE) | demouser3792993@contoso.com, demouser4181693@contoso.com, demouser4208366@contoso.com, demouser4208785@contoso.com, sessionenforced@contoso.com, ... | Yes |\n\n**Summary:**\n* Total Encryption-Enabled Labels: 3\n* Standard RMS: 1\n* User-Defined: 1\n* Double Key Encryption (DKE): 1\n\n\n","TestStatus":"Passed","TestTags":null},{"TestImpact":"Low","TestRisk":"High","TestSkipped":"","TestAppliesTo":null,"TestPillar":"Data","TestCategory":"Information Protection","TestDescription":"When auto-labeling policies are left in simulation mode, you're not realizing the protection from labeling that data. As a result, users and services can't take additional protective measures to safeguard the identified sensitive data. For example, users won't see in their Office apps that a file is labeled Highly Confidential. Data loss prevention rules might use sensitivity labels to prevent sharing with external users, and other risky actions. Labeled data also provides an additional layer of protection when you use Microsoft 365 Copilot.\n\nTo ensure sensitive information is automatically labeled, turn on at least one auto-labeling policy. Turning on auto-labeling policies after simulation testing puts protective measures into effect and starts reducing risk.\n\n**Remediation action**\n\n- [How to configure auto-labeling policies for SharePoint, OneDrive, and Exchange](https://learn.microsoft.com/purview/apply-sensitivity-label-automatically?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci#how-to-configure-auto-labeling-policies-for-sharepoint-onedrive-and-exchange)\n","TestTitle":"Auto-labeling enforcement mode enabled","SkippedReason":null,"TestId":"35020","TestImplementationCost":"Low","TestMinimumLicense":["EXCHANGE_S_ENTERPRISE"],"TestSfiPillar":"Protect tenants and production systems","TestResult":"\n❌ No auto-labeling policies are in enforcement mode. All policies are either disabled or in simulation mode.\n\n\n\n### Summary:\n\n- **Total Policies in Enforcement Mode:** 0\n- **Total Policies in Simulation Mode:** 2\n- **Total Policies Disabled:** 0\n- **Workloads Covered by Enforcement Policies:**\n - **Exchange/Outlook:** No\n - **SharePoint:** No\n - **OneDrive:** No\n - **Teams:** No\n - **Power BI:** No\n\n\n","TestStatus":"Failed","TestTags":null},{"TestImplementationCost":"High","TestPillar":"Identity","TestCategory":"Application management","SkippedReason":null,"TestImpact":"Medium","TestAppliesTo":["Identity"],"TestSfiPillar":"Protect tenants and isolate production systems","TestSkipped":"","TestMinimumLicense":"Free","TestTags":["Identity"],"TestTitle":"Outbound cross-tenant access settings are configured","TestRisk":"High","TestResult":"\nTenant has a default cross-tenant access setting outbound policy with unrestricted access.\n## [Outbound access settings - Default settings](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/OutboundAccessSettings.ReactView/isDefault~/true/name//id/)\n### B2B Collaboration\nUsers and groups\n- Access status: allowed\n- Applies to: All users\n\nExternal applications\n- Access status: allowed\n- Applies to: Selected external applications (1 applications)\n\n### B2B Direct Connect\nUsers and groups\n- Access status: allowed\n- Applies to: All users\n\nExternal applications\n- Access status: allowed\n- Applies to: All external applications\n\n\n","TestStatus":"Failed","TestDescription":"Allowing unrestricted external collaboration with unverified organizations can increase the risk surface area of the tenant because it allows guest accounts that might not have proper security controls. Threat actors can attempt to gain access by compromising identities in these loosely governed external tenants. Once granted guest access, they can then use legitimate collaboration pathways to infiltrate resources in your tenant and attempt to gain sensitive information. Threat actors can also exploit misconfigured permissions to escalate privileges and try different types of attacks.\n\nWithout vetting the security of organizations you collaborate with, malicious external accounts can persist undetected, exfiltrate confidential data, and inject malicious payloads. This type of exposure can weaken organizational control and enable cross-tenant attacks that bypass traditional perimeter defenses and undermine both data integrity and operational resilience. Cross-tenant settings for outbound access in Microsoft Entra provide the ability to block collaboration with unknown organizations by default, reducing the attack surface.\n\n**Remediation action**\n\n- [Cross-tenant access overview](https://learn.microsoft.com/entra/external-id/cross-tenant-access-overview?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci)\n- [Configure cross-tenant access settings](https://learn.microsoft.com/entra/external-id/cross-tenant-access-settings-b2b-collaboration?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci#configure-default-settings)\n- [Modify outbound access settings](https://learn.microsoft.com/entra/external-id/cross-tenant-access-settings-b2b-collaboration?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci)\n","TestId":"21790"},{"TestImplementationCost":"Low","TestPillar":"Identity","TestCategory":"Privileged access","SkippedReason":null,"TestImpact":"Low","TestAppliesTo":null,"TestSfiPillar":"Protect engineering systems","TestSkipped":"","TestMinimumLicense":"P1","TestTags":null,"TestTitle":"Maximum number of Global Administrators doesn't exceed eight users","TestRisk":"Low","TestResult":"\nMaximum number of Global Administrators exceeds eight users/service principals.\n\n\n## Global Administrators\n\n### Total number of Global Administrators: 25\n\n| Display Name | Object Type | User Principal Name |\n| :----------- | :---------- | :------------------ |\n| [Jules Bailey](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/AdministrativeRole/userId/0145d508-50fd-4f86-a47a-bf1c043c8358) | User | jules@contoso.com |\n| [Jamie Rodriguez](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/AdministrativeRole/userId/0b37813c-ae19-4399-982f-16587f17f9c0) | User | jamie@contoso.com |\n| [Ellis Cooper](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/AdministrativeRole/userId/1433571b-3d7c-4a56-a9cc-67580848bc73) | User | ellis@contoso.com |\n| [Cameron Anderson](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/AdministrativeRole/userId/1ce4078f-f795-4baf-aa55-1fdfcc2ebfe6) | User | cameron@contoso.com |\n| [Taylor Brown](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/AdministrativeRole/userId/2072badc-3cf0-4e84-b4c2-f9c065c46165) | User | taylor@contoso.com |\n| [Dakota Lee](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/AdministrativeRole/userId/210d3e96-015f-462d-b6d6-81e6023263df) | User | guest-user_external.com#EXT#@contoso.com |\n| [Custom-App-Test](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/ApplicationMenuBlade/~/Overview/appId/ddb4f0e6-8018-4359-96c1-7473704bde43) | Service Principal | N/A |\n| [Dakota Lee Test](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/AdministrativeRole/userId/43482f27-d1af-420f-84ba-e9148a700f45) | User | dakota-test@contoso.com |\n| [Ash Williams](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/AdministrativeRole/userId/513f3db2-044c-41be-af14-431bf88a2b3e) | User | ash@contoso.com |\n| [Sage Bennett](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/AdministrativeRole/userId/518ce209-faf4-4717-add9-7129a669fa11) | User | sage@contoso.com |\n| [Morgan Wilson](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/AdministrativeRole/userId/5655cf54-34bc-4f36-bb74-44da35547975) | User | morgan@contoso.com |\n| [Charlie Lewis](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/AdministrativeRole/userId/5b0ec3ff-cea1-4eb9-8530-f2a66e5bec0a) | User | charlie@contoso.com |\n| [Phoenix Gray](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/AdministrativeRole/userId/7094fb23-003a-4f81-9796-5daeaa603003) | User | phoenix@contoso.com |\n| [Peyton Clark](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/AdministrativeRole/userId/7e92f268-bb12-469a-a869-210d596d4c1f) | User | peyton@contoso.com |\n| [Finley Robinson](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/AdministrativeRole/userId/990fd38a-c516-4e3f-82e4-d458a1ab0f91) | User | finley.robinson@contoso.com |\n| [Avery Brooks](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/AdministrativeRole/userId/a85798bd-652b-4eb9-ba90-3ee882df0179) | User | avery.brooks@contoso.com |\n| [Reese Harris](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/AdministrativeRole/userId/babe04c9-8340-4329-a727-a8cee0cd2b1a) | User | reese@contoso.com |\n| [Jordan Smith](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/AdministrativeRole/userId/bfaeba1e-1357-47de-9557-529caa103d5d) | User | jordan@contoso.com |\n| [Hayden Scott](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/AdministrativeRole/userId/c0b65b13-37b1-4081-bcfc-14844159b4a5) | User | hayden@contoso.com |\n| [contoso-tenant-devops-7576c63d-bc90-4ae4-9f1c-0d959fb520db](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/ApplicationMenuBlade/~/Overview/appId/e876f7cb-13f3-48a4-8329-66d7b1fa33fb) | Service Principal | N/A |\n| [Quinn Garcia](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/AdministrativeRole/userId/ceef37b7-c865-48fb-80c9-4def11201854) | User | quinn@contoso.com |\n| [Mailbox Migration Account](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/ApplicationMenuBlade/~/Overview/appId/b650c3c1-3395-40bb-8471-2a6a8b76d8a9) | Service Principal | N/A |\n| [Drew Mitchell](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/AdministrativeRole/userId/df02402a-e291-42cc-b449-79366daa2a40) | User | drew@contoso.com |\n| [Alex Johnson](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/AdministrativeRole/userId/e436ca15-3a39-4dcc-819e-7dbb246cd46b) | User | alex@contoso.onmicrosoft.com |\n| [Avery Thomas](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/AdministrativeRole/userId/f431700c-6d81-45b8-8f8d-581a8aa7cda6) | User | avery@contoso.com |\n\n\n\n","TestStatus":"Failed","TestDescription":"An excessive number of Global Administrator accounts creates an expanded attack surface that threat actors can exploit through various initial access vectors. Each extra privileged account represents a potential entry point for threat actors. An excess of Global Administrator accounts undermines the principle of least privilege. Microsoft recommends that organizations have no more than eight Global Administrators.\n\n**Remediation action**\n\n- [Follow best practices for Microsoft Entra roles](https://learn.microsoft.com/entra/identity/role-based-access-control/best-practices?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci)\n","TestId":"21812"},{"TestImplementationCost":"Low","TestPillar":"Devices","TestCategory":"Tenant","SkippedReason":null,"TestImpact":"Medium","TestAppliesTo":null,"TestSfiPillar":"Protect tenants and isolate production systems","TestSkipped":"","TestMinimumLicense":"Intune","TestTags":null,"TestTitle":"Compliance policy assignment for Android Enterprise Fully managed device is configured and assigned","TestRisk":"High","TestResult":"\nAt least one compliance policy for Android Enterprise Fully managed devices exists and is assigned.\n\n\n## Compliance policy assignment for Android Enterprise Fully managed device is configured and assigned\n\n| Policy Name | Status | Assignment |\n| :---------- | :----- | :--------- |\n| [My android enterprise policy](https://intune.microsoft.com/#view/Microsoft_Intune_DeviceSettings/DevicesComplianceMenu/~/policies) | ✅ Assigned | **Included:** All Users, **Excluded:** testPIM |\n\n\n","TestStatus":"Passed","TestDescription":"If compliance policies aren't assigned to fully managed Android Enterprise devices in Intune, threat actors can exploit noncompliant endpoints to gain unauthorized access to corporate resources, bypass security controls, and persist in the environment. Without enforced compliance, devices can lack critical security configurations such as passcode requirements, data storage encryption, and OS version controls. These gaps increase the risk of data leakage, privilege escalation, and lateral movement. Inconsistent device compliance weakens the organization’s security posture and makes it harder to detect and remediate threats before significant damage occurs.\n\nEnforcing compliance policies ensures Android Enterprise devices meet core security requirements and supports Zero Trust by validating device health and reducing exposure to misconfigured or unmanaged endpoints.\n\n**Remediation action**\n\nCreate and assign Intune compliance policies to fully managed and corporate-owned Android Enterprise devices to enforce organizational standards for secure access and management: \n- [Create a compliance policy in Microsoft Intune](https://learn.microsoft.com/intune/intune-service/protect/create-compliance-policy?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci#create-the-policy)\n- [Review the Android Enterprise compliance settings you can manage with Intune](https://learn.microsoft.com/intune/intune-service/protect/compliance-policy-create-android-for-work?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci)\n","TestId":"24545"},{"TestImpact":"High","TestRisk":"High","TestSkipped":"","TestAppliesTo":null,"TestPillar":"Data","TestCategory":"Information Protection","TestDescription":"The policy setting **Require users to apply a label** ensures a sensitivity label must be applied before users can save files and send emails or meeting invites, create new groups or sites, and use Power BI content. This setting also prevents users from completely removing a sensitivity label. Unlabeled items create security and compliance risks. For example, threat actors can exfiltrate sensitive data that could be prevented by protection solutions that trigger based on label detection.\n\n**Remediation action**\n\n- [Publish sensitivity labels by creating a label policy](https://learn.microsoft.com/purview/create-sensitivity-labels?tabs=modern-label-scheme&wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci#publish-sensitivity-labels-by-creating-a-label-policy)\n- [Require users to apply a label to their email and documents](https://learn.microsoft.com/purview/sensitivity-labels-office-apps?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci#require-users-to-apply-a-label-to-their-email-and-documents)\n","TestTitle":"Mandatory labeling enabled for sensitivity labels","SkippedReason":null,"TestId":"35016","TestImplementationCost":"Medium","TestMinimumLicense":["RMS_S_PREMIUM"],"TestSfiPillar":"Protect tenants and production systems","TestResult":"\n✅ Mandatory labeling is configured and enforced through at least one active sensitivity label policy across one or more workloads (Outlook, Teams/OneDrive, SharePoint/Microsoft 365 Groups, or Power BI).\n\n\n\n### [Enabled label policies](https://purview.microsoft.com/informationprotection/labelpolicies)\n| Policy name | Email | Files/Collab | Sites/Groups | Power BI | Email override | Scope | Labels |\n| :--- | :--- | :--- | :--- | :--- | :--- | :--- | :--- |\n| 35035-Test-Policy | ✅ | ❌ | ❌ | ❌ | No | User/Group-scoped | 1 |\n| Test Policy | ❌ | ✅ | ❌ | ✅ | Yes | User/Group-scoped | 1 |\n| true event | ❌ | ❌ | ❌ | ❌ | Yes | Global | 1 |\n| userpolicy | ❌ | ❌ | ❌ | ❌ | Yes | User/Group-scoped | 1 |\n| peyton | ✅ | ✅ | ❌ | ✅ | No | Global | 1 |\n| test-policy-35012 | ❌ | ❌ | ❌ | ❌ | Yes | Global | 1 |\n\n\n### Summary\n| Metric | Count |\n| :--- | :--- |\n| Total enabled label policies | 6 |\n| Total enabled label policies with mandatory labeling | 3 |\n| Email mandatory labeling | 2 |\n| File/collaboration mandatory labeling | 2 |\n| Site/group mandatory labeling | 0 |\n| Power BI mandatory labeling | 2 |\n\n","TestStatus":"Passed","TestTags":null},{"TestImpact":"High","TestRisk":"High","TestSkipped":"","TestAppliesTo":null,"TestPillar":"Data","TestCategory":"Rights Management Service (RMS)","TestDescription":"Internal RMS licensing allows users and services in the organization to license protected content for internal distribution and sharing. It's enabled automatically when Azure RMS is activated. If disabled, users can't collaborate on encrypted emails and files internally, and legal holds, eDiscovery, and data recovery operations can't access encrypted content.\n\n**Remediation action**\n\n- [Set up Message Encryption](https://learn.microsoft.com/purview/set-up-new-message-encryption-capabilities?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci)\n","TestTitle":"Internal RMS Licensing Enabled","SkippedReason":null,"TestId":"35025","TestImplementationCost":"Low","TestMinimumLicense":["RMS_S_PREMIUM"],"TestSfiPillar":"Protect tenants and production systems","TestResult":"\n✅ Internal RMS licensing is enabled, allowing internal users to license and share protected content within the organization.\n\n**[Internal RMS Licensing Status](https://purview.microsoft.com/settings/encryption)**\n| Setting | Status |\n| :--- | :--- |\n| InternalLicensingEnabled | True |\n| ExternalLicensingEnabled | True |\n| AzureRMSLicensingEnabled | True |\n| LicensingLocation | https://f34ade14-8c5d-483e-b19e-d6ae7663a26f.rms.ap.aadrm.com/_wmcs/licensing |\n\n**Summary:**\n* Internal Licensing Configuration: ✅ Enabled\n* Licensing Endpoints: ✅ Configured\n\n\n","TestStatus":"Passed","TestTags":null},{"TestImplementationCost":"Low","TestPillar":"Identity","TestCategory":"Access control","SkippedReason":null,"TestImpact":"Low","TestAppliesTo":["Identity"],"TestSfiPillar":"Protect tenants and isolate production systems","TestSkipped":"","TestMinimumLicense":"Free","TestTags":["Identity"],"TestTitle":"App Instance Property Lock is configured for all multitenant applications","TestRisk":"High","TestResult":"\nFound multi-tenant apps without app instance property lock configured.\n\n\n## Multi-tenant applications and their App Instance Property Lock setting\n\n\n| Application | Application ID | App Instance Property Lock configured |\n| :---------- | :------------- | :------------------------------------ |\n| [AWS Account](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/ApplicationMenuBlade/~/Authentication/appId/2e311a1d-f5c0-41c6-b866-77af3289871e/isMSAApp~/false) | 2e311a1d-f5c0-41c6-b866-77af3289871e | False |\n| [Adatum Demo App](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/ApplicationMenuBlade/~/Authentication/appId/d2934d2a-3fbc-44a1-bda0-13e8d8a73b15/isMSAApp~/false) | d2934d2a-3fbc-44a1-bda0-13e8d8a73b15 | False |\n| [EAM Provider](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/ApplicationMenuBlade/~/Authentication/appId/f8642471-b7d7-4432-9527-776071e69b8b/isMSAApp~/false) | f8642471-b7d7-4432-9527-776071e69b8b | True |\n| [ExtProperties](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/ApplicationMenuBlade/~/Authentication/appId/61a54643-d4b6-471d-bd7c-a55586155dfc/isMSAApp~/false) | 61a54643-d4b6-471d-bd7c-a55586155dfc | False |\n| [Graph Filter](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/ApplicationMenuBlade/~/Authentication/appId/c94b2f6c-f4c2-4ab3-8d1a-6971b2c7e975/isMSAApp~/false) | c94b2f6c-f4c2-4ab3-8d1a-6971b2c7e975 | False |\n| [My Properties Bag](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/ApplicationMenuBlade/~/Authentication/appId/303b4699-5b62-451c-b951-7e10b01d9b6d/isMSAApp~/false) | 303b4699-5b62-451c-b951-7e10b01d9b6d | False |\n| [Tenant Extension Properties App](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/ApplicationMenuBlade/~/Authentication/appId/7db77c2b-30c1-4379-838f-8767c1e0d619/isMSAApp~/false) | 7db77c2b-30c1-4379-838f-8767c1e0d619 | False |\n| [Tenant Extension Properties App](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/ApplicationMenuBlade/~/Authentication/appId/271b9db4-6e96-430c-808f-973a776adeaf/isMSAApp~/false) | 271b9db4-6e96-430c-808f-973a776adeaf | False |\n| [Zero Trust Assessment](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/ApplicationMenuBlade/~/Authentication/appId/e7dfcbb6-fe86-44a2-b512-8d361dcc3d30/isMSAApp~/false) | e7dfcbb6-fe86-44a2-b512-8d361dcc3d30 | True |\n| [da-typespec-todo-aad](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/ApplicationMenuBlade/~/Authentication/appId/9358444a-41ec-4a93-915a-4970b3f33738/isMSAApp~/false) | 9358444a-41ec-4a93-915a-4970b3f33738 | False |\n| [graph-developer-proxy-samples](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/ApplicationMenuBlade/~/Authentication/appId/3658d9e9-dc87-4345-b59b-184febcf6781/isMSAApp~/false) | 3658d9e9-dc87-4345-b59b-184febcf6781 | False |\n| [idpowerelectron](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/ApplicationMenuBlade/~/Authentication/appId/909fff82-5b0a-4ce5-b66d-db58ee1a925d/isMSAApp~/false) | 909fff82-5b0a-4ce5-b66d-db58ee1a925d | True |\n| [test-mta](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/ApplicationMenuBlade/~/Authentication/appId/5ebc726d-e583-4822-b111-95ee05503c7e/isMSAApp~/false) | 5ebc726d-e583-4822-b111-95ee05503c7e | True |\n| [test1](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/ApplicationMenuBlade/~/Authentication/appId/8d0c8cec-8d54-414b-abfd-7418b8d0bfa0/isMSAApp~/false) | 8d0c8cec-8d54-414b-abfd-7418b8d0bfa0 | True |\n\n\n\n","TestStatus":"Failed","TestDescription":"App instance property lock prevents changes to sensitive properties of a multitenant application after the application is provisioned in another tenant. Without a lock, critical properties such as application credentials can be maliciously or unintentionally modified, causing disruptions, increased risk, unauthorized access, or privilege escalations.\n\n**Remediation action**\nEnable the app instance property lock for all multitenant applications and specify the properties to lock.\n- [Configure an app instance lock](https://learn.microsoft.com/entra/identity-platform/howto-configure-app-instance-property-locks?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci#configure-an-app-instance-lock)\n","TestId":"21777"},{"TestImplementationCost":"Medium","TestPillar":"Identity","TestCategory":"Application management","SkippedReason":null,"TestImpact":"Low","TestAppliesTo":null,"TestSfiPillar":"Protect engineering systems","TestSkipped":"","TestMinimumLicense":"P1","TestTags":null,"TestTitle":"Workload Identities are not assigned privileged roles","TestRisk":"High","TestResult":"\n**Found workload identities assigned to privileged roles.**\n| Service Principal Name | Privileged Role | Assignment Type |\n| :--- | :--- | :--- |\n| [Custom-App-Test](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/Overview/objectId/38415a71-b77b-44d5-a276-539faabe0de7/appId/ddb4f0e6-8018-4359-96c1-7473704bde43/preferredSingleSignOnMode~/null/servicePrincipalType/Application/fromNav/) | Global Administrator | Permanent |\n| [contoso-tenant-devops-7576c63d-bc90-4ae4-9f1c-0d959fb520db](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/Overview/objectId/c5632968-35cd-445d-926e-16e0afc9160e/appId/e876f7cb-13f3-48a4-8329-66d7b1fa33fb/preferredSingleSignOnMode~/null/servicePrincipalType/Application/fromNav/) | Global Administrator | Permanent |\n| [Mailbox Migration Account](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/Overview/objectId/d22f071d-e8d3-41fc-a516-b29753cdd1f6/appId/b650c3c1-3395-40bb-8471-2a6a8b76d8a9/preferredSingleSignOnMode~/null/servicePrincipalType/Application/fromNav/) | Application Administrator | Permanent |\n| [Mailbox Migration Account](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/Overview/objectId/d22f071d-e8d3-41fc-a516-b29753cdd1f6/appId/b650c3c1-3395-40bb-8471-2a6a8b76d8a9/preferredSingleSignOnMode~/null/servicePrincipalType/Application/fromNav/) | Global Administrator | Permanent |\n\n\n**Recommendation:** Review and remove privileged role assignments from workload identities unless absolutely necessary. Use least-privilege principles and consider alternative approaches like managed identities with specific API permissions instead of directory roles.\n\n\n","TestStatus":"Failed","TestDescription":"If administrators assign privileged roles to workload identities, such as service principals or managed identities, the tenant can be exposed to significant risk if those identities are compromised. Threat actors who gain access to a privileged workload identity can perform reconnaissance to enumerate resources, escalate privileges, and manipulate or exfiltrate sensitive data. The attack chain typically begins with credential theft or abuse of a vulnerable application. Next step is privilege escalation through the assigned role, lateral movement across cloud resources, and finally persistence via other role assignments or credential updates. Workload identities are often used in automation and might not be monitored as closely as user accounts. Compromise can then go undetected, allowing threat actors to maintain access and control over critical resources. Workload identities aren't subject to user-centric protections like MFA, making least-privilege assignment and regular review essential. \n\n**Remediation action**\n- [Review and remove privileged roles assignments](https://learn.microsoft.com/entra/id-governance/privileged-identity-management/pim-resource-roles-assign-roles?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci#update-or-remove-an-existing-role-assignment).\n- [Follow the best practices for workload identities](https://learn.microsoft.com/entra/workload-id/workload-identities-overview?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci#key-scenarios).\n- [Learn about privileged roles and permissions in Microsoft Entra ID](https://learn.microsoft.com/entra/identity/role-based-access-control/privileged-roles-permissions?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci)\n","TestId":21836},{"TestImplementationCost":"","TestPillar":"Infrastructure","TestCategory":"Implement security best practices","SkippedReason":null,"TestImpact":"","TestAppliesTo":null,"TestSfiPillar":"Protect tenants and isolate production systems","TestSkipped":"","TestMinimumLicense":"N/A","TestTags":null,"TestTitle":"A maximum of 3 owners should be designated for subscriptions","TestRisk":"High","TestResult":"A maximum of 3 owners should be designated for subscriptions\n\n| Subscription | Affected resource | Status | Azure portal |\n| :----------- | :---------------- | :----- | :----------- |\n| [Visual Studio Enterprise Subscription](https://portal.azure.com/#resource/subscriptions/54d3ea01-5a07-45d0-8d69-e5f5b0b20098) | [54d3ea01-5a07-45d0-8d69-e5f5b0b20098](https://portal.azure.com/#resource/subscriptions/54d3ea01-5a07-45d0-8d69-e5f5b0b20098) | ❌ | [View recommendation](https://portal.azure.com/#blade/Microsoft_Azure_Security/RecommendationsBlade/assessmentKey/6f90a6d6-d4d6-0794-0ec1-98fa77878c2e/resourceId/%2fsubscriptions%2f54d3ea01-5a07-45d0-8d69-e5f5b0b20098) |\n","TestStatus":"Failed","TestDescription":"To reduce the potential for breaches by compromised owner accounts, we recommend limiting the number of owner accounts to a maximum of 3\n\n**Remediation action**\n\nTo remove owner permissions from user accounts on your subscription:
Click a subscription from the list of subscriptions below or click 'Take action' if you are coming from a specific subscription.
The Access control (IAM) page opens.
1. Click the Role assignments tab and set the 'Role' filter to 'Owner'.
2. Select the owners you want to remove.
3. Click Remove.","TestId":"6f90a6d6-d4d6-0794-0ec1-98fa77878c2e"},{"TestImplementationCost":"Medium","TestPillar":"Identity","TestCategory":"Monitoring","SkippedReason":null,"TestImpact":"Low","TestAppliesTo":null,"TestSfiPillar":"Monitor and detect cyberthreats","TestSkipped":"","TestMinimumLicense":null,"TestTags":null,"TestTitle":"Diagnostic settings are configured for all Microsoft Entra logs","TestRisk":"High","TestResult":"\n❌ Some Entra Logs are not configured with Diagnostic settings.\n\n\n\n## [Microsoft Entra Log Archiving](https://portal.azure.com/#view/Microsoft_AAD_IAM/DiagnosticSettingsMenuBlade)\n\n| Log name | Diagnostic settings |\n| :--- | :--- |\n| ADFSSignInLogs | none |\n| AuditLogs | none |\n| EnrichedOffice365AuditLogs | none |\n| ManagedIdentitySignInLogs | none |\n| MicrosoftGraphActivityLogs | none |\n| NetworkAccessTrafficLogs | none |\n| NonInteractiveUserSignInLogs | none |\n| ProvisioningLogs | none |\n| RemoteNetworkHealthLogs | none |\n| RiskyServicePrincipals | none |\n| RiskyUsers | none |\n| ServicePrincipalRiskEvents | none |\n| ServicePrincipalSignInLogs | none |\n| SignInLogs | none |\n| UserRiskEvents | none |\n\n\n\n","TestStatus":"Failed","TestDescription":"The activity logs and reports in Microsoft Entra can help detect unauthorized access attempts or identify when tenant configuration changes. When logs are archived or integrated with Security Information and Event Management (SIEM) tools, security teams can implement powerful monitoring and detection security controls, proactive threat hunting, and incident response processes. The logs and monitoring features can be used to assess tenant health and provide evidence for compliance and audits.\n\nIf logs aren't regularly archived or sent to a SIEM tool for querying, it's challenging to investigate sign-in issues. The absence of historical logs means that security teams might miss patterns of failed sign-in attempts, unusual activity, and other indicators of compromise. This lack of visibility can prevent the timely detection of breaches, allowing attackers to maintain undetected access for extended periods.\n\n**Remediation action**\n\n- [Configure Microsoft Entra diagnostic settings](https://learn.microsoft.com/entra/identity/monitoring-health/howto-configure-diagnostic-settings?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci)\n- [Integrate Microsoft Entra logs with Azure Monitor logs](https://learn.microsoft.com/entra/identity/monitoring-health/howto-integrate-activity-logs-with-azure-monitor-logs?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci)\n- [Stream Microsoft Entra logs to an event hub](https://learn.microsoft.com/entra/identity/monitoring-health/howto-stream-logs-to-event-hub?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci)\n","TestId":"21860"},{"TestImplementationCost":"High","TestPillar":"Identity","TestCategory":"Application management","SkippedReason":null,"TestImpact":"Low","TestAppliesTo":["Identity"],"TestSfiPillar":"Protect engineering systems","TestSkipped":"","TestMinimumLicense":"P1","TestTags":["Identity"],"TestTitle":"Highly privileged roles are only activated in a PAW/SAW device","TestRisk":"High","TestResult":"\nNo Conditional Access policies found that restrict privileged roles to PAW device.\n\n**❌ Found 0 policy(s) with compliant device control targeting all privileged roles**\n\n\n**❌ Found 0 policy(s) with PAW/SAW device filter targeting all privileged roles**\n\n\n","TestStatus":"Failed","TestDescription":"If privileged role activations aren't restricted to dedicated Privileged Access Workstations (PAWs), threat actors can exploit compromised endpoint devices to perform privileged escalation attacks from unmanaged or noncompliant workstations. Standard productivity workstations often contain attack vectors such as unrestricted web browsing, email clients vulnerable to phishing, and locally installed applications with potential vulnerabilities. When administrators activated privileged roles from these workstations, threat actors who gain initial access through malware, browser exploits, or social engineering can then use the locally cached privileged credentials or hijack existing authenticated sessions to escalate their privileges. Privileged role activations grant extensive administrative rights across Microsoft Entra ID and connected services, so attackers can create new administrative accounts, modify security policies, access sensitive data across all organizational resources, and deploy malware or backdoors throughout the environment to establish persistent access. This lateral movement from a compromised endpoint to privileged cloud resources represents a critical attack path that bypasses many traditional security controls. The privileged access appears legitimate when originating from an authenticated administrator's session.\n\nIf this check passes, your tenant has a Conditional Access policy that restricts privileged role access to PAW devices, but it isn't the only control required to fully enable a PAW solution. You also need to configure an Intune device configuration and compliance policy and a device filter.\n\n**Remediation action**\n\n- [Deploy a privileged access workstation solution](https://learn.microsoft.com/security/privileged-access-workstations/privileged-access-deployment?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci)\n - Provides guidance for configuring the Conditional Access and Intune device configuration and compliance policies.\n- [Configure device filters in Conditional Access to restrict privileged access](https://learn.microsoft.com/entra/identity/conditional-access/concept-condition-filters-for-devices?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci)\n","TestId":"21830"},{"TestImplementationCost":"Low","TestPillar":"Devices","TestCategory":"Tenant","SkippedReason":null,"TestImpact":"Low","TestAppliesTo":null,"TestSfiPillar":"Protect tenants and isolate production systems","TestSkipped":"","TestMinimumLicense":"Intune","TestTags":null,"TestTitle":"Device Clean-up Rule is Created","TestRisk":"Low","TestResult":"\nNo device clean-up rule exists.\n\n\n\n","TestStatus":"Failed","TestDescription":"If device cleanup rules aren't configured in Intune, stale or inactive devices can remain visible in the tenant indefinitely. This leads to cluttered device lists, inaccurate reporting, and reduced visibility into the active device landscape. Unused devices might retain access credentials or tokens, increasing the risk of unauthorized access or misinformed policy decisions. \n\nDevice cleanup rules automatically hide inactive devices from admin views and reports, improving tenant hygiene and reducing administrative burden. This supports Zero Trust by maintaining an accurate and trustworthy device inventory while preserving historical data for audit or investigation.\n\n**Remediation action**\n\nConfigure Intune device cleanup rules to automatically hide inactive devices from the tenant: \n- [Create a device cleanup rule](https://learn.microsoft.com/intune/intune-service/fundamentals/device-cleanup-rules?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci#how-to-create-a-device-cleanup-rule)\n\nFor more information, see: \n- [Using Intune device cleanup rules](https://techcommunity.microsoft.com/blog/devicemanagementmicrosoft/using-intune-device-cleanup-rules-updated-version/3760854) *on the Microsoft Tech Community blog*\n","TestId":"24802"},{"TestImpact":"Low","TestRisk":"High","TestSkipped":"","TestAppliesTo":null,"TestPillar":"Data","TestCategory":"Information Protection","TestDescription":"When auto-labeling for SharePoint and OneDrive isn't set up, files uploaded without sensitivity labels might not be visible to Data Loss Protection (DLP) policies that rely on labels. As a result, those files can move through the environment with fewer safeguards, which can raise the risk of inappropriate sharing or access.\n \nFor example, enabling at least one auto-labeling policy in enforcement mode for SharePoint and OneDrive helps classify sensitive files when users create or edit them. Auto-labeling classification supports downstream protections, such as DLP policies, so they can respond based on the file’s sensitivity and help reduce data exposure risk.\n\n**Remediation action**\n\n- [Apply sensitivity labels automatically for SharePoint and OneDrive](https://learn.microsoft.com/purview/apply-sensitivity-label-automatically?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci)\n","TestTitle":"Auto-Labeling Policies Enabled for SharePoint and OneDrive","SkippedReason":null,"TestId":"35021","TestImplementationCost":"Medium","TestMinimumLicense":["EXCHANGE_S_ENTERPRISE"],"TestSfiPillar":"Protect tenants and production systems","TestResult":"\n❌ 2 auto-labeling policies target SharePoint/OneDrive, but none are enabled and in enforcement mode.\n\n### [Auto-Labeling Policies for SharePoint/OneDrive](https://purview.microsoft.com/informationprotection/autolabeling)\n\n| Policy Name | Description | Enabled | Mode | Workload | Created | Last Modified |\n| :--- | :--- | :---: | :--- | :--- | :--- | :--- |\n| Japan Financial Data | | ✅ | TestWithoutNotifications | Exchange, SharePoint, OneDriveForBusiness, Applications, Azure, AWS | 2026-02-05 | 2026-02-05 |\n| U.S. Patriot Act Enhanced | | ✅ | TestWithoutNotifications | Exchange, SharePoint, OneDriveForBusiness, Applications, Azure, AWS | 2026-02-05 | 2026-02-06 |\n\n### Summary\n\n* **Total Policies Targeting SharePoint/OneDrive:** 2\n* **Policies in Enforcement Mode:** 0\n* **Policies in Simulation Mode:** 2\n* **Policies Disabled:** 0\n* **SharePoint Coverage:** [No]\n* **OneDrive Coverage:** [No]\n\n### Recommendation\n\nEnable at least one auto-labeling policy in enforcement mode for SharePoint and/or OneDrive to automatically classify sensitive files. Visit the [Auto-labeling policies portal](https://purview.microsoft.com/informationprotection/autolabeling) to create or configure policies.\n\n\n","TestStatus":"Failed","TestTags":null},{"TestImplementationCost":"Low","TestPillar":"Devices","TestCategory":"Tenant","SkippedReason":null,"TestImpact":"Medium","TestAppliesTo":null,"TestSfiPillar":"Protect tenants and isolate production systems","TestSkipped":"","TestMinimumLicense":"Intune","TestTags":null,"TestTitle":"Compliance policies protect Windows devices","TestRisk":"High","TestResult":"\n❌ Test 24541 failed due to an unexpected error.\r\n - **Error Message**: Response status code does not indicate success: NotFound (Not Found)..\r\n```\r\n\nException : \n Type : Microsoft.Graph.PowerShell.Authentication.Helpers.HttpResponseException\n Response : StatusCode: 404, ReasonPhrase: 'Not Found', Version: 2.0, Content: System.Net.Http.DecompressionHandler+GZipDecompressedContent, Headers:\n {\n Cache-Control: no-cache\n Vary: Accept-Encoding\n Strict-Transport-Security: max-age=31536000\n request-id: f632d1e1-0368-48a8-8809-88eea06e56f8\n client-request-id: b25c394e-fc7e-4f7b-90f7-88dc2444fd83\n x-ms-ags-diagnostic: {\"ServerInfo\":{\"DataCenter\":\"Australia East\",\"Slice\":\"E\",\"Ring\":\"5\",\"ScaleUnit\":\"001\",\"RoleInstance\":\"SY1PEPF000060EA\"}}\n x-ms-resource-unit: 1\n Date: Mon, 18 May 2026 22:16:57 GMT\n Content-Type: application/json\n }\n TargetSite : \n Name : ThrowTerminatingError\n DeclaringType : [System.Management.Automation.MshCommandRuntime]\n MemberType : Method\n Module : System.Management.Automation.dll\n Message : Response status code does not indicate success: NotFound (Not Found).\n Source : System.Management.Automation\n HResult : -2146233088\n StackTrace : \n at System.Management.Automation.MshCommandRuntime.ThrowTerminatingError(ErrorRecord errorRecord)\nTargetObject : Method: GET, RequestUri: 'https://graph.microsoft.com/v1.0/groups/91732cd1-062d-41ab-991a-8e37e1ac1937?$select=displayName', Version: 2.0, Content: , Headers:\n {\n ConsistencyLevel: eventual\n User-Agent: Mozilla/5.0\n User-Agent: (Macintosh; Darwin 25.5.0 Darwin Kernel Version 25.5.0: Mon Apr 27 20:41:06 PDT 2026; root:xnu-12377.121.6~2/RELEASE_ARM64_T6030; en-AU)\n User-Agent: PowerShell/7.5.2\n User-Agent: Invoke-MgGraphRequest\n FeatureFlag: 00000003\n Cache-Control: no-store, no-cache\n Authorization: Bearer [REDACTED]\n SdkVersion: graph-powershell/2.35.1\n client-request-id: b25c394e-fc7e-4f7b-90f7-88dc2444fd83\n Accept-Encoding: gzip\n Accept-Encoding: deflate\n Accept-Encoding: br\n }\nCategoryInfo : InvalidOperation: (Method: GET, Reques…cept-Encoding: br\n }:HttpRequestMessage) [Invoke-ZtRetry], HttpResponseException\nFullyQualifiedErrorId : InvokeGraphHttpResponseException,Invoke-ZtRetry\nErrorDetails : GET https://graph.microsoft.com/v1.0/groups/91732cd1-062d-41ab-991a-8e37e1ac1937?$select=displayName\n HTTP/2.0 404 Not Found\n Cache-Control: no-cache\n Vary: Accept-Encoding\n Strict-Transport-Security: max-age=31536000\n request-id: f632d1e1-0368-48a8-8809-88eea06e56f8\n client-request-id: b25c394e-fc7e-4f7b-90f7-88dc2444fd83\n x-ms-ags-diagnostic: {\"ServerInfo\":{\"DataCenter\":\"Australia East\",\"Slice\":\"E\",\"Ring\":\"5\",\"ScaleUnit\":\"001\",\"RoleInstance\":\"SY1PEPF000060EA\"}}\n x-ms-resource-unit: 1\n Date: Mon, 18 May 2026 22:16:57 GMT\n Content-Type: application/json\n \n {\"error\":{\"code\":\"Request_ResourceNotFound\",\"message\":\"Resource '91732cd1-062d-41ab-991a-8e37e1ac1937' does not exist or one of its queried reference-property objects are not present.\",\"innerError\":{\"date\":\"2026-05-18T22:16:58\",\"request-id\":\"f632d1e1-0368-48a8-8809-88eea06e56f8\",\"client-request-id\":\"b25c394e-fc7e-4f7b-90f7-88dc2444fd83\"}}}\nInvocationInfo : \n MyCommand : Invoke-ZtRetry\n ScriptLineNumber : 118\n OffsetInLine : 13\n HistoryId : 1\n ScriptName : /Users/manson/GitHub/zerotrustassessment/src/powershell/private/core/Invoke-ZtGraphRequestCache.ps1\n Line : $results = Invoke-ZtRetry -ScriptBlock { Invoke-MgGraphRequest -Method $Method -Uri $Uri -Headers $Headers -OutputType $OutputType } # -Body $Body # Cannot use Body with GET in PS 5.1\n \n Statement : Invoke-ZtRetry -ScriptBlock { Invoke-MgGraphRequest -Method $Method -Uri $Uri -Headers $Headers -OutputType $OutputType }\n PositionMessage : At /Users/manson/GitHub/zerotrustassessment/src/powershell/private/core/Invoke-ZtGraphRequestCache.ps1:118 char:13\n + … $results = Invoke-ZtRetry -ScriptBlock { Invoke-MgGraphRequest -Meth …\n + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n PSScriptRoot : /Users/manson/GitHub/zerotrustassessment/src/powershell/private/core\n PSCommandPath : /Users/manson/GitHub/zerotrustassessment/src/powershell/private/core/Invoke-ZtGraphRequestCache.ps1\n InvocationName : Invoke-ZtRetry\n CommandOrigin : Internal\nScriptStackTrace : at , /Users/manson/GitHub/zerotrustassessment/src/powershell/private/core/Invoke-ZtGraphRequestCache.ps1: line 118\n at Invoke-ZtRetry, /Users/manson/GitHub/zerotrustassessment/src/powershell/private/core/Invoke-ZtRetry.ps1: line 51\n at Invoke-ZtGraphRequestCache, /Users/manson/GitHub/zerotrustassessment/src/powershell/private/core/Invoke-ZtGraphRequestCache.ps1: line 118\n at Invoke-ZtGraphRequest, /Users/manson/GitHub/zerotrustassessment/src/powershell/public/Invoke-ZtGraphRequest.ps1: line 226\n at Get-PolicyAssignmentTarget, /Users/manson/GitHub/zerotrustassessment/src/powershell/private/core/Get-PolicyAssignmentTarget.ps1: line 19\n at Test-Assessment-24541, /Users/manson/GitHub/zerotrustassessment/src/powershell/tests/Test-Assessment.24541.ps1: line 90\n at Invoke-ZtTest, /Users/manson/GitHub/zerotrustassessment/src/powershell/private/tests/Invoke-ZtTest.ps1: line 125\n at , /Users/manson/GitHub/zerotrustassessment/src/powershell/private/tests/Start-ZtTestExecution.ps1: line 106\n at , : line 62\n\n\r\n```\n\n","TestStatus":"Error","TestDescription":"If compliance policies for Windows devices aren't configured and assigned, threat actors can exploit unmanaged or noncompliant endpoints to gain unauthorized access to corporate resources, bypass security controls, and persist within the environment. Without enforced compliance, devices can lack critical security configurations like BitLocker encryption, password requirements, firewall settings, and OS version controls. These gaps increase the risk of data leakage, privilege escalation, and lateral movement. Inconsistent device compliance weakens the organization’s security posture and makes it harder to detect and remediate threats before significant damage occurs.\n\nEnforcing compliance policies ensures Windows devices meet core security requirements and supports Zero Trust by validating device health and reducing exposure to misconfigured endpoints.\n\n**Remediation action**\n\nCreate and assign Intune compliance policies to Windows devices to enforce organizational standards for secure access and management:\n- [Create and assign Intune compliance policies](https://learn.microsoft.com/intune/intune-service/protect/create-compliance-policy?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci#create-the-policy)\n- [Review the Windows compliance settings you can manage with Intune](https://learn.microsoft.com/intune/intune-service/protect/compliance-policy-create-windows?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci)\n","TestId":"24541"},{"TestImplementationCost":"High","TestPillar":"Identity","TestCategory":"Privileged access","SkippedReason":"UnderConstruction","TestImpact":"Low","TestAppliesTo":["Identity"],"TestSfiPillar":"Protect identities and secrets","TestSkipped":"UnderConstruction","TestMinimumLicense":null,"TestTags":["Identity"],"TestTitle":"Directory Sync account credentials haven't been rotated recently","TestRisk":"Low","TestResult":"\nPlanned for future release.\n","TestStatus":"Planned","TestDescription":"...\n\n**Remediation action**\n\n","TestId":"21833"},{"TestImpact":"Medium","TestRisk":"High","TestSkipped":"","TestAppliesTo":null,"TestPillar":"Data","TestCategory":"Data Security Posture Management","TestDescription":"Until organizations configure Communication Compliance policies to capture Copilot interactions, they can’t see when users expose sensitive data to AI services. They also can’t tell how people use Copilot with confidential information or spot possible policy violations. As a result, users may unknowingly share customer records, financial data, source code, or trade secrets with AI services.\n\nCommunication Compliance policies that focus on Copilot interactions give organizations clear oversight of AI use while respecting privacy controls. These policies show how users work with sensitive data in AI features and help ensure teams follow data governance and compliance requirements.\n\n**Remediation action**\n\n- [Create and manage Communication Compliance policies](https://learn.microsoft.com/purview/communication-compliance-policies?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci)\n","TestTitle":"Communication compliance monitoring is configured for Microsoft Copilot","SkippedReason":null,"TestId":"35039","TestImplementationCost":"Medium","TestMinimumLicense":["EXCHANGE_S_ENTERPRISE"],"TestSfiPillar":"Protect tenants and production systems","TestResult":"\nCommunication Compliance rules targeting Copilot content are properly configured and enabled.\n\n### Copilot-Targeting Rules\n\n| Rule Name | Associated Policy |\n| :------ | :---- |\n| Copilot Data Protection | Copilot Data Protection |\n| Custom Policy 35040 | Custom Policy 35040 |\n| Microsoft 365 Copilot interactions | Microsoft 365 Copilot interactions |\n| test1 | test1 |\n\n### Enabled Policies\n\n| Policy Name | Enabled | Review Mailbox |\n| :------ | :---- | :---- |\n| Copilot Data Protection | True | SupervisoryReview{3bbbbd4f-cc0a-45ff-b0f5-c6023124c881}@contoso.onmicrosoft.com |\n| Custom Policy 35040 | True | SupervisoryReview{8fb152db-0f94-45f9-b29c-8764f3a5ccef}@contoso.onmicrosoft.com |\n| Microsoft 365 Copilot interactions | True | SupervisoryReview{8ce4a232-c7cf-4712-aee9-f02c9a9cd3e8}@contoso.onmicrosoft.com |\n| test1 | True | SupervisoryReview{7a05811d-28e7-4163-a013-d57c554fca5f}@contoso.onmicrosoft.com |\n\n### Activity Evidence\n\nRecent Copilot Matches (30 days): 0\n\n**Summary:**\n\n Status: ✅ Pass\n\n Total Copilot Rules Found: 4\n\n Enabled Policies with Copilot Rules: 4\n\n**Portal Access:**\n\n [Microsoft Purview Communication Compliance > Policies](https://purview.microsoft.com/communicationcompliance/policies)\n\n\n","TestStatus":"Passed","TestTags":null},{"TestImplementationCost":"","TestPillar":"Infrastructure","TestCategory":"Manage access and permissions","SkippedReason":null,"TestImpact":"","TestAppliesTo":null,"TestSfiPillar":"Protect tenants and isolate production systems","TestSkipped":"","TestMinimumLicense":"N/A","TestTags":null,"TestTitle":"Guest accounts with write permissions on Azure resources should be removed","TestRisk":"High","TestResult":"Guest accounts with write permissions on Azure resources should be removed\n\n| Subscription | Affected resource | Status | Azure portal |\n| :----------- | :---------------- | :----- | :----------- |\n| [Visual Studio Enterprise Subscription](https://portal.azure.com/#resource/subscriptions/54d3ea01-5a07-45d0-8d69-e5f5b0b20098) | [54d3ea01-5a07-45d0-8d69-e5f5b0b20098](https://portal.azure.com/#resource/subscriptions/54d3ea01-5a07-45d0-8d69-e5f5b0b20098) | ✅ | [View recommendation](https://portal.azure.com/#blade/Microsoft_Azure_Security/RecommendationsBlade/assessmentKey/0354476c-a12a-4fcc-a79d-f0ab7ffffdbb/resourceId/%2fsubscriptions%2f54d3ea01-5a07-45d0-8d69-e5f5b0b20098) |\n","TestStatus":"Passed","TestDescription":"Accounts with write permissions that have been provisioned outside of the Azure Active Directory tenant (different domain names), should be removed from your Azure resources.
These guest accounts are not managed to the same standards as enterprise tenant identities.
This makes them potential targets for threat actors looking to find ways to access your data without being noticed.
By removing these accounts, you can reduce the risk of unauthorized data access and potential breaches..
\n\n**Remediation action**\n\nReview the list of guest accounts that require access removal on the Accounts section. Select an account to view its role definitions and locate source scope. If you accept the risk for a specific account, use the exempt capability to exclude it from evaluation.
  1. Go to the Azure portal.
  2. Open Access control (IAM) at a scope, such as management group, subscription, resource group, or resource, where the guest user has a role assignment.
  3. Click the Role assignments tab to view all the role assignments.
  4. In the list of role assignments, add a checkmark next to the guest user with the role assignment you want to remove.
  5. Click Remove. In the remove role assignment message that appears, click Yes.
","TestId":"0354476c-a12a-4fcc-a79d-f0ab7ffffdbb"},{"TestImplementationCost":"Medium","TestPillar":"Identity","TestCategory":"Credential management","SkippedReason":"UnderConstruction","TestImpact":"Medium","TestAppliesTo":["Identity"],"TestSfiPillar":"Protect identities and secrets","TestSkipped":"UnderConstruction","TestMinimumLicense":"P1","TestTags":["Identity"],"TestTitle":"Self-Service Password Reset does not use Q & A","TestRisk":"Medium","TestResult":"\nPlanned for future release.\n\n","TestStatus":"Planned","TestDescription":"Allowing security questions as a self-service password reset (SSPR) method weakens the password reset process because answers are frequently guessable, reused across sites, or discoverable through open-source intelligence (OSINT). Threat actors enumerate or phish users, derive likely responses (family names, schools, and locations), and then trigger password reset flows to bypass stronger methods by exploiting the weaker knowledge-based gate. After they successfully reset a password on an account that isn't protected by multifactor authentication they can: gain valid primary credentials, establish session tokens, and laterally expand by registering more durable authentication methods, add forwarding rules, or exfiltrate sensitive data.\n\nEliminating this method removes a weak link in the password reset process. Some organizations might have specific business reasons for leaving security questions enabled, but this isn't recommended.\n\n**Remediation action**\n\n- [Disable security questions in SSPR policy](https://learn.microsoft.com/entra/identity/authentication/concept-authentication-security-questions?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci)\n- [Select authentication methods and registration options](https://learn.microsoft.com/entra/identity/authentication/tutorial-enable-sspr?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci#select-authentication-methods-and-registration-options)\n","TestId":"22072"},{"TestImplementationCost":"Low","TestPillar":"Devices","TestCategory":"Device","SkippedReason":null,"TestImpact":"Medium","TestAppliesTo":null,"TestSfiPillar":"Protect networks","TestSkipped":"","TestMinimumLicense":"Intune","TestTags":null,"TestTitle":"Windows Firewall Policy is Created and Assigned","TestRisk":"High","TestResult":"\nAt least one Windows Firewall policy is created and assigned to a group.\n\n\n## Windows Firewall Configuration Policies\n\n| Policy Name | Status | Assignment Target |\n| :---------- | :----- | :---------------- |\n| [WF_Policy](https://intune.microsoft.com/#view/Microsoft_Intune_Workflows/SecurityManagementMenu/~/firewall) | ✅ Assigned | **Included:** WFgroup, My Test Device Group |\n| [WF_Policy2](https://intune.microsoft.com/#view/Microsoft_Intune_Workflows/SecurityManagementMenu/~/firewall) | ❌ Not assigned | None |\n| [WF_Policy3](https://intune.microsoft.com/#view/Microsoft_Intune_Workflows/SecurityManagementMenu/~/firewall) | ✅ Assigned | **Included:** All Devices, **Excluded:** My Test Device Group, WFgroup |\n\n\n\n","TestStatus":"Passed","TestDescription":"If policies for Windows Firewall aren't configured and assigned, threat actors can exploit unprotected endpoints to gain unauthorized access, move laterally, and escalate privileges within the environment. Without enforced firewall rules, attackers can bypass network segmentation, exfiltrate data, or deploy malware, increasing the risk of widespread compromise.\n\nEnforcing Windows Firewall policies ensures consistent application of inbound and outbound traffic controls, reducing exposure to unauthorized access and supporting Zero Trust through network segmentation and device-level protection.\n\n**Remediation action**\n\nConfigure and assign firewall policies for Windows in Intune to block unauthorized traffic and enforce consistent network protections across all managed devices:\n\n- [Configure firewall policies for Windows devices](https://learn.microsoft.com/intune/intune-service/protect/endpoint-security-firewall-policy?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci). Intune uses two complementary profiles to manage firewall settings:\n - **Windows Firewall** - Use this profile to configure overall firewall behavior based on network type.\n - **Windows Firewall rules** - Use this profile to define traffic rules for apps, ports, or IPs, tailored to specific groups or workloads. This Intune profile also supports use of [reusable settings groups](https://learn.microsoft.com/intune/intune-service/protect/endpoint-security-firewall-policy?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci#add-reusable-settings-groups-to-profiles-for-firewall-rules) to help simplify management of common settings you use for different profile instances.\n- [Assign policies in Intune](https://learn.microsoft.com/intune/intune-service/configuration/device-profile-assign?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci#assign-a-policy-to-users-or-groups)\n\nFor more information, see: \n- [Available Windows Firewall settings](https://learn.microsoft.com/intune/intune-service/protect/endpoint-security-firewall-profile-settings?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci#windows-firewall-profile)\n","TestId":"24540"},{"TestImpact":"Medium","TestRisk":"Medium","TestSkipped":"","TestAppliesTo":null,"TestPillar":"Data","TestCategory":"Data Loss Prevention (DLP)","TestDescription":"Adaptive Protection ensures that data loss prevention (DLP) policies are tailored to each user's risk profile, rather than applying the same rules to everyone. Without Adaptive Protection, organizations miss the chance to prevent insider threats because they can't respond to behavioral indicators like unusual data access or risky activities.\n\nBy integrating Insider Risk Management with DLP, Adaptive Protection uses machine learning to identify users as high, moderate, or low risk. This lets Adaptive Protection automatically apply stricter DLP controls to those at higher risk, while allowing more flexibility for others, an approach that helps protect sensitive data and supports operational efficiency.\n\n**Remediation action**\n\n- [Help dynamically mitigate risks with Adaptive Protection](https://learn.microsoft.com/purview/insider-risk-management-adaptive-protection?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci)\n","TestTitle":"Adaptive Protection in DLP Policies","SkippedReason":null,"TestId":"35032","TestImplementationCost":"Low","TestMinimumLicense":["EXCHANGE_S_ENTERPRISE"],"TestSfiPillar":"Protect tenants and production systems","TestResult":"\n✅ Adaptive Protection is configured in DLP policies, enabling risk-based, behavior-driven data protection through insider risk integration.\n\n\n### Adaptive Protection Summary\n\n| Metric | Count |\n| :----- | :---- |\n| Total DLP Rules | 8 |\n| Rules with Adaptive Protection | 1 |\n| Policies with Adaptive Protection | 1 |\n| Rules with Elevated Risk Level | 1 |\n| Rules with Moderate Risk Level | 0 |\n| Rules with Minor Risk Level | 0 |\n\n\n### DLP Rules with Adaptive Protection\n\n| Rule Name | Parent Policy | Enabled | Risk Levels |\n| :-------- | :------------ | :------ | :---------- |\n| Block elevated-risk financial data transfers | Adaptive Protection - Elevated Risk | ✅ Yes | Elevated |\n\n\n[View DLP Policies in Microsoft Purview Portal](https://purview.microsoft.com/datalossprevention/policies)\n\n\n","TestStatus":"Passed","TestTags":null},{"TestImplementationCost":"Medium","TestPillar":"Identity","TestCategory":"Monitoring","SkippedReason":null,"TestImpact":"Medium","TestAppliesTo":["Identity"],"TestSfiPillar":"Monitor and detect cyberthreats","TestSkipped":"","TestMinimumLicense":"P1","TestTags":["Application"],"TestTitle":"High priority Entra recommendations are addressed","TestRisk":"High","TestResult":"\nFound 6 unaddressed high priority Entra recommendations.\n\n\n## Unaddressed high priority Entra recommendations\n\n| Display Name | Status | Insights |\n| :--- | :--- | :--- |\n| Protect all users with a user risk policy | active | You have 86 of 88 users that don’t have a user risk policy enabled. |\n| Protect all users with a sign-in risk policy | active | You have 86 of 88 users that don't have a sign-in risk policy turned on. |\n| Ensure all users can complete multifactor authentication | active | You have 59 of 88 users that aren’t registered with MFA. |\n| Enable policy to block legacy authentication | active | You have 3 of 88 users that don’t have legacy authentication blocked. |\n| Require multifactor authentication for administrative roles | active | You have 8 of 26 users with administrative roles that aren’t registered and protected with MFA. |\n| Renew expiring application credentials | active | Your tenant has applications with credentials that will expire soon. |\n\n\n","TestStatus":"Failed","TestDescription":"Leaving high-priority Microsoft Entra recommendations unaddressed can create a gap in an organization’s security posture, offering threat actors opportunities to exploit known weaknesses. Not acting on these items might result in an increased attack surface area, suboptimal operations, or poor user experience. \n\n**Remediation action**\n\n- [Address all high priority recommendations in the Microsoft Entra admin center](https://learn.microsoft.com/entra/identity/monitoring-health/overview-recommendations?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci#how-does-it-work)\n","TestId":"22124"},{"TestImplementationCost":"Low","TestPillar":"Identity","TestCategory":"Access control","SkippedReason":"UnderConstruction","TestImpact":"Low","TestAppliesTo":["Identity"],"TestSfiPillar":"Protect identities and secrets","TestSkipped":"UnderConstruction","TestMinimumLicense":"P1","TestTags":["Identity"],"TestTitle":"Require password reset notifications for administrator roles","TestRisk":"High","TestResult":"\nPlanned for future release.\n\n","TestStatus":"Planned","TestDescription":"Configuring password reset notifications for administrator roles in Microsoft Entra ID enhances security by notifying privileged administrators when another administrator resets their password. This visibility helps detect unauthorized or suspicious activity that could indicate credential compromise or insider threats. Without these notifications, malicious actors could exploit elevated privileges to establish persistence, escalate access, or extract sensitive data. Proactive notifications support quick action, preserve privileged access integrity, and strengthen the overall security posture. \n\n**Remediation action**\n\n- [Notify all admins when other admins reset their passwords](https://learn.microsoft.com/entra/identity/authentication/concept-sspr-howitworks?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci#notify-all-admins-when-other-admins-reset-their-passwords)\n","TestId":"21891"},{"TestImplementationCost":"Medium","TestPillar":"Identity","TestCategory":"Access control","SkippedReason":null,"TestImpact":"Medium","TestAppliesTo":null,"TestSfiPillar":"Protect identities and secrets","TestSkipped":"","TestMinimumLicense":"P1","TestTags":null,"TestTitle":"Reduce the user-visible password surface area","TestRisk":"High","TestResult":"\nYour organization has implemented multiple passwordless authentication methods reducing password exposure.\n## Passwordless authentication methods\n\n| Method | State | Include targets | Authentication mode | Status |\n| :----- | :---- | :-------------- | :------------------ | :----- |\n| FIDO2 Security Keys | ✅ Enabled | All users | N/A | ✅ Pass |\n| Microsoft Authenticator | ✅ Enabled | All users | ✅ any | ✅ Pass |\n\n","TestStatus":"Passed","TestDescription":"Organizations with extensive user-facing password surfaces expose multiple entry points for threat actors to launch credential-based attacks. Frequent user interactions with password prompts across applications, devices, and workflows increase the risk of exploitation. Threat actors often begin with credential stuffing—using compromised credentials from data breaches—followed by password spraying to test common passwords across multiple accounts. Once initial access is gained, they conduct credential discovery by examining browser password stores, cached credentials in memory, and credential managers to harvest additional authentication materials. These stolen credentials enable lateral movement, allowing attackers to access more systems and applications, often escalating privileges by targeting administrative accounts that still rely on password authentication. In the persistence phase, attackers may create backdoor accounts with password-based access or weaken defenses by altering password policies. To evade detection, they leverage legitimate authentication channels, blending in with normal user activity while maintaining persistent access to organizational resources. \n\n**Remediation action**\n\n * [Enable passwordless authentication methods](https://learn.microsoft.com/en-us/entra/identity/authentication/how-to-plan-prerequisites-phishing-resistant-passwordless-authentication)\n\n * [Deploy FIDO2 security keys](https://learn.microsoft.com/en-us/entra/identity/authentication/how-to-enable-passkey-fido2)\n\n","TestId":"21889"},{"TestImplementationCost":"Medium","TestPillar":"Identity","TestCategory":"Access control","SkippedReason":"UnderConstruction","TestImpact":"Low","TestAppliesTo":["Identity"],"TestSfiPillar":"Protect identities and secrets","TestSkipped":"UnderConstruction","TestMinimumLicense":null,"TestTags":["Identity"],"TestTitle":"Privileged roles have access reviews","TestRisk":"Medium","TestResult":"\nPlanned for future release.\n","TestStatus":"Planned","TestDescription":"...\n\n**Remediation action**\n\n","TestId":"21855"},{"TestImplementationCost":"Low","TestPillar":"Identity","TestCategory":"Credential management","SkippedReason":null,"TestImpact":"Low","TestAppliesTo":null,"TestSfiPillar":"Protect identities and secrets","TestSkipped":"","TestMinimumLicense":"P1","TestTags":null,"TestTitle":"Enable custom banned passwords","TestRisk":"Medium","TestResult":"\nCustom banned passwords are properly configured with organization-specific terms to prevent predictable password patterns.\n\n\n## Password protection settings\n\n| Enforce custom list | Custom banned password list | Number of terms |\n| :------------------ | :-------------------------- | :-------------- |\n| [Yes](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/AuthenticationMethodsMenuBlade/~/PasswordProtection/fromNav/) | test | 1 |\n\n\n\n","TestStatus":"Passed","TestDescription":"Organizations that don't populate and enforce the custom banned password list expose themselves to a systematic attack chain where threat actors exploit predictable organizational password patterns. These threat actors typically start with reconnaissance phases, where they gather open-source intelligence (OSINT) from websites, social media, and public records to identify likely password components. With this knowledge, they launch password spray attacks that test organization-specific password variations across multiple user accounts, staying under lockout thresholds to avoid detection. Without the protection the custom banned password list offers, employees often add familiar organizational terms to their passwords, like locations, product names, and industry terms, creating consistent attack vectors. \n\nThe custom banned password list helps organizations plug this critical gap to prevent easily guessed passwords that could lead to initial access and subsequent lateral movement within the environment.\n\n**Remediation action**\n\n- [Learn how to enable custom banned password protection and add organizational terms](https://learn.microsoft.com/entra/identity/authentication/tutorial-configure-custom-password-protection?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci)\n","TestId":"21848"},{"TestImplementationCost":"Medium","TestPillar":"Identity","TestCategory":"External collaboration","SkippedReason":null,"TestImpact":"Medium","TestAppliesTo":null,"TestSfiPillar":"Protect tenants and isolate production systems","TestSkipped":"","TestMinimumLicense":["P2","Governance"],"TestTags":null,"TestTitle":"All entitlement management assignment policies that apply to external users require connected organizations","TestRisk":"Medium","TestResult":"\nAssignment policies without connected organization restrictions were found.\n## Evaluated assignment policies\n| Access package | Assignment policy | Target scope | Status |\n| :--- | :--- | :--- | :--- |\n| [PS-GraphCmdLetScriptTest4](https://entra.microsoft.com/#view/Microsoft_AAD_ERM/DashboardBlade/~/elmEntitlement/menuId/) | 21929Test | allExternalUsers | ❌ Fail |\n| [PS-GraphCmdLetScriptTest4](https://entra.microsoft.com/#view/Microsoft_AAD_ERM/DashboardBlade/~/elmEntitlement/menuId/) | External | allConfiguredConnectedOrganizationUsers | ⚠️ Investigate |\n| [Get user info demo](https://entra.microsoft.com/#view/Microsoft_AAD_ERM/DashboardBlade/~/elmEntitlement/menuId/) | Initial Policy | specificConnectedOrganizationUsers | ✅ Pass |\n| [UserInfo](https://entra.microsoft.com/#view/Microsoft_AAD_ERM/DashboardBlade/~/elmEntitlement/menuId/) | Initial Policy | allConfiguredConnectedOrganizationUsers | ⚠️ Investigate |\n\n\n","TestStatus":"Failed","TestDescription":"Access packages configured to allow \"All users\" instead of specific connected organizations expose your organization to uncontrolled external access. Threat actors can exploit this by requesting access through compromised external accounts from unauthorized organizations, bypassing the principle of least privilege. This enables initial access, reconnaissance, privilege escalation, and lateral movement within your environment. \n\n**Remediation action**\n\n- [Define trusted organizations as connected organizations](https://learn.microsoft.com/entra/id-governance/entitlement-management-organization?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci#view-the-list-of-connected-organizations)\n- [Configure access packages to only allow specific connected organizations](https://learn.microsoft.com/entra/id-governance/entitlement-management-access-package-create?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci#allow-users-not-in-your-directory-to-request-the-access-package)\n","TestId":"21875"},{"TestImplementationCost":"High","TestPillar":"Identity","TestCategory":"Access control","SkippedReason":null,"TestImpact":"High","TestAppliesTo":null,"TestSfiPillar":"Protect identities and secrets","TestSkipped":"","TestMinimumLicense":"P1","TestTags":null,"TestTitle":"All sign-in activity comes from managed devices","TestRisk":"High","TestResult":"\n❌ Not all sign-in activity comes from managed devices.\n\n### Managed device conditional access policy summary\n\nThe table below lists all Conditional Access policies that require a compliant device or a hybrid joined device.\n| Name | All users | All apps | Compliant device | Hybrid joined device | Policy state | Status |\n| :--- | :---: | :---: | :---: | :---: | :--- | :--- |\n| [\\[ellis\\] - CA policy for Compliant devices](https://entra.microsoft.com/#view/Microsoft_AAD_ConditionalAccess/PolicyBlade/policyId/dfde11d6-2433-45dc-86dc-f191dcac3bd9) | 🔴 | 🔴 | 🟢 | 🔴 | 🔴 Disabled | ❌ Fail |\n| [\\[ellis\\] - Require app protection policy](https://entra.microsoft.com/#view/Microsoft_AAD_ConditionalAccess/PolicyBlade/policyId/6909c0fb-c830-42b6-a438-c41d4010518f) | 🔴 | 🔴 | 🟢 | 🔴 | 🟢 Enabled | ❌ Fail |\n| [ALEX - MFA for risky sign-ins](https://entra.microsoft.com/#view/Microsoft_AAD_ConditionalAccess/PolicyBlade/policyId/5167662e-2022-45a5-825c-4514e5a0cfd4) | 🔴 | 🟢 | 🟢 | 🟢 | 🔴 Disabled | ❌ Fail |\n| [All sign-in activity comes from managed devices](https://entra.microsoft.com/#view/Microsoft_AAD_ConditionalAccess/PolicyBlade/policyId/7701ec7b-8983-4dd2-ae60-27cb0b2d3c6d) | 🟢 | 🟢 | 🟢 | 🟢 | 🟡 Report-only | ❌ Fail |\n| [Device compliance #1](https://entra.microsoft.com/#view/Microsoft_AAD_ConditionalAccess/PolicyBlade/policyId/2965e1d4-6146-41a5-abae-5219abf7d68f) | 🔴 | 🟢 | 🟢 | 🟢 | 🔴 Disabled | ❌ Fail |\n| [Device compliancy](https://entra.microsoft.com/#view/Microsoft_AAD_ConditionalAccess/PolicyBlade/policyId/206c9071-89d7-4b57-adaf-87f78a4bd7f5) | 🔴 | 🟢 | 🟢 | 🟢 | 🔴 Disabled | ❌ Fail |\n| [Require compliant or hybrid Azure AD joined device for admins](https://entra.microsoft.com/#view/Microsoft_AAD_ConditionalAccess/PolicyBlade/policyId/5ee30a46-6df0-48ff-b60b-45073b7e4e3e) | 🔴 | 🟢 | 🟢 | 🟢 | 🔴 Disabled | ❌ Fail |\n| [Require compliant or hybrid Azure AD joined device or multifactor authentication for all users](https://entra.microsoft.com/#view/Microsoft_AAD_ConditionalAccess/PolicyBlade/policyId/05439c0a-90b2-45e9-92cc-0e13ddc3b9c3) | 🔴 | 🟢 | 🟢 | 🟢 | 🔴 Disabled | ❌ Fail |\n| [Require compliant or hybrid Azure AD joined device or multifactor authentication for all users](https://entra.microsoft.com/#view/Microsoft_AAD_ConditionalAccess/PolicyBlade/policyId/ee4fdb05-5aec-4616-b2da-6d16a2cb2a54) | 🔴 | 🟢 | 🟢 | 🟢 | 🔴 Disabled | ❌ Fail |\n| [Securing security info registration](https://entra.microsoft.com/#view/Microsoft_AAD_ConditionalAccess/PolicyBlade/policyId/28ba1d93-c70c-4c7f-93e4-852705472e3d) | 🟢 | 🔴 | 🟢 | 🟢 | 🔴 Disabled | ❌ Fail |\n\n\n","TestStatus":"Failed","TestDescription":"Requiring sign-ins from managed devices ensures that users access organizational resources only from devices that meet your security and compliance requirements. Unmanaged devices lack organizational security controls and endpoint protection, creating potential entry points for attackers. Using Conditional Access to require compliant or Microsoft Entra hybrid joined devices helps protect against credential theft and unauthorized access from untrusted endpoints.\n\n**Remediation action**\n\n- [Require compliant or hybrid joined devices with Conditional Access](https://learn.microsoft.com/entra/identity/conditional-access/policy-all-users-device-compliance?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci)\n- [Configure device compliance policies in Microsoft Intune](https://learn.microsoft.com/mem/intune/protect/device-compliance-get-started?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci)\n","TestId":"21892"},{"TestImplementationCost":"Medium","TestPillar":"Identity","TestCategory":"Application management","SkippedReason":null,"TestImpact":"Low","TestAppliesTo":["Identity"],"TestSfiPillar":"Protect networks","TestSkipped":"","TestMinimumLicense":"P1","TestTags":["Identity"],"TestTitle":"Tenant restrictions v2 are configured","TestRisk":"High","TestResult":"\nTenant Restrictions v2 policy is properly configured.\n\n\n## Tenant restriction settings\n\n\n| Policy Configured | External users and groups | External applications |\n| :---------------- | :------------------------ | :-------------------- |\n| [Yes](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/TenantRestrictions.ReactView/isDefault~/true/name//id/) | All external users and groups | All external applications |\n\n\n\n","TestStatus":"Passed","TestDescription":"Tenant Restrictions v2 (TRv2) allows organizations to enforce policies that restrict access to specified Microsoft Entra tenants, preventing unauthorized exfiltration of corporate data to external tenants using local accounts. Without TRv2, threat actors can exploit this vulnerability, which leads to potential data exfiltration and compliance violations, followed by credential harvesting if those external tenants have weaker controls. Once credentials are obtained, threat actors can gain initial access to these external tenants. TRv2 provides the mechanism to prevent users from authenticating to unauthorized tenants. Otherwise, threat actors can move laterally, escalate privileges, and potentially exfiltrate sensitive data, all while appearing as legitimate user activity that bypasses traditional data loss prevention controls focused on internal tenant monitoring.\n\nImplementing TRv2 enforces policies that restrict access to specified tenants, mitigating these risks by ensuring that authentication and data access are confined to authorized tenants only. \n\nIf this check passes, your tenant has a TRv2 policy configured but more steps are required to validate the scenario end-to-end.\n\n**Remediation action**\n- [Set up Tenant Restrictions v2](https://learn.microsoft.com/entra/external-id/tenant-restrictions-v2?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci)\n","TestId":"21793"},{"TestImplementationCost":"Medium","TestPillar":"Identity","TestCategory":"External collaboration","SkippedReason":"UnderConstruction","TestImpact":"Medium","TestAppliesTo":["Identity"],"TestSfiPillar":"Protect tenants and isolate production systems","TestSkipped":"UnderConstruction","TestMinimumLicense":"Free","TestTags":["Application"],"TestTitle":"All guests user strong authentication methods","TestRisk":"Medium","TestResult":"\nPlanned for future release.\n\n","TestStatus":"Planned","TestDescription":"External user accounts are often used to provide access to business partners who belong to organizations that have a business relationship with your organization. If these accounts are compromised in their organization, attackers can use the valid credentials to gain initial access to your environment, often bypassing traditional defenses due to their legitimacy.\n\nAttackers might gain access with external user accounts, if multifactor authentication (MFA) isn't universally enforced or if there are exceptions in place. They might also gain access by exploiting the vulnerabilities of weaker MFA methods like SMS and phone calls using social engineering techniques, such as SIM swapping or phishing, to intercept the authentication codes.\n\nOnce an attacker gains access to an account without MFA or a session with weak MFA methods, they might attempt to manipulate MFA settings (for example, registering attacker controlled methods) to establish persistence to plan and execute further attacks based on the privileges of the compromised accounts.\n\n**Remediation action**\n\n- [Deploy a Conditional Access policy to enforce authentication strength for guests](https://learn.microsoft.com/entra/identity/conditional-access/policy-guests-mfa-strength?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci).\n- For organizations with a closer business relationship and vetting on their MFA practices, consider deploying cross-tenant access settings to accept the MFA claim.\n - [Configure B2B collaboration cross-tenant access settings](https://learn.microsoft.com/entra/external-id/cross-tenant-access-settings-b2b-collaboration?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci#to-change-inbound-trust-settings-for-mfa-and-device-claims)\n","TestId":"21851"},{"TestImplementationCost":"Medium","TestPillar":"Devices","TestCategory":"Tenant","SkippedReason":null,"TestImpact":"Medium","TestAppliesTo":null,"TestSfiPillar":"Protect tenants and isolate production systems","TestSkipped":"","TestMinimumLicense":"Intune","TestTags":null,"TestTitle":"Windows Security Baseline is Configured and Assigned","TestRisk":"High","TestResult":"\nNo security baselines are configured or assigned to Windows devices in Intune.\n\n\n\n","TestStatus":"Failed","TestDescription":"Without properly configured and assigned Intune security baselines for Windows, devices remain vulnerable to a wide array of attack vectors that threat actors exploit to gain persistence and escalate privileges. Adversaries leverage default Windows configurations that lack hardened security settings to perform lateral movement using techniques like credential dumping, privilege escalation via unpatched vulnerabilities, and exploitation of weak authentication mechanisms. In the absence of enforced security baselines, threat actors can bypass critical security controls, maintain persistence through registry modifications, and exfiltrate sensitive data through unmonitored channels. Failing to implement a defense-in-depth strategy makes devices easier to exploit as attackers progress through the attack chain—from initial access to data exfiltration—ultimately compromising the organization’s security posture and increasing the risk of compliance violations.\n\nApplying security baselines ensures Windows devices are configured with hardened settings, reducing attack surface, enforcing defense-in-depth, and supporting Zero Trust by standardizing security controls across the environment.\n\n**Remediation action**\n\nConfigure and assign Intune security baselines to Windows devices to enforce standardized security settings and monitor compliance:\n- [Deploy security baselines to help secure Windows devices](https://learn.microsoft.com/intune/intune-service/protect/security-baselines-configure?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci#create-a-profile-for-a-security-baseline)\n- [Monitor security baseline compliance](https://learn.microsoft.com/intune/intune-service/protect/security-baselines-monitor?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci)\n","TestId":"24573"},{"TestImplementationCost":"Low","TestPillar":"Identity","TestCategory":"Monitoring","SkippedReason":"UnderConstruction","TestImpact":"High","TestAppliesTo":["Identity"],"TestSfiPillar":"Monitor and detect cyberthreats","TestSkipped":"UnderConstruction","TestMinimumLicense":"P1","TestTags":["Identity"],"TestTitle":"No legacy authentication sign-in activity","TestRisk":"Medium","TestResult":"\nPlanned for future release.\n\n","TestStatus":"Planned","TestDescription":"Legacy authentication protocols such as basic authentication for SMTP and IMAP don't support modern security features like multifactor authentication (MFA), which is crucial for protecting against unauthorized access. This lack of protection makes accounts using these protocols vulnerable to password-based attacks, and provides attackers with a means to gain initial access using stolen or guessed credentials.\n\nWhen an attacker successfully gains unauthorized access to credentials, they can use them to access linked services, using the weak authentication method as an entry point. Attackers who gain access through legacy authentication might make changes to Microsoft Exchange, such as configuring mail forwarding rules or changing other settings, allowing them to maintain continued access to sensitive communications.\n\nLegacy authentication also provides attackers with a consistent method to reenter a system using compromised credentials without triggering security alerts or requiring reauthentication.\n\nFrom there, attackers can use legacy protocols to access other systems that are accessible via the compromised account, facilitating lateral movement. Attackers using legacy protocols can blend in with legitimate user activities, making it difficult for security teams to distinguish between normal usage and malicious behavior.\n\n**Remediation action**\n\n- [Exchange protocols can be deactivated in Exchange](https://learn.microsoft.com/exchange/clients-and-mobile-in-exchange-online/disable-basic-authentication-in-exchange-online?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci)\n- [Legacy authentication protocols can be blocked with Conditional Access](https://learn.microsoft.com/entra/identity/conditional-access/policy-block-legacy-authentication?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci)\n- [Sign-ins using legacy authentication workbook to help determine whether it's safe to turn off legacy authentication](https://learn.microsoft.com/entra/identity/monitoring-health/workbook-legacy-authentication?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci)\n","TestId":"21795"},{"TestImplementationCost":"Low","TestPillar":"Identity","TestCategory":"Access control","SkippedReason":null,"TestImpact":"Medium","TestAppliesTo":null,"TestSfiPillar":"Protect identities and secrets","TestSkipped":"","TestMinimumLicense":"P1","TestTags":null,"TestTitle":"Privileged users have short-lived sign-in sessions","TestRisk":"Medium","TestResult":"\n## Privileged User Sign-In Sessions\n\n**Total Privileged Roles Found:** 34\n\n**CA Policies Targeting Roles:** 8\n\n**Recommended Sign In Session Hours:** 4\n\n**Policies with Compliant Frequency (≤4 hours):** 1\n\n### Conditional Access Policies by Privileged Role\n\n#### Global Administrator\n\n**Status:** ❌ No CA policies assigned\n\n*No Conditional Access policies target this privileged role.*\n\n#### User Administrator\n\n**Status:** ❌ No CA policies assigned\n\n*No Conditional Access policies target this privileged role.*\n\n#### Helpdesk Administrator\n\n**Status:** ✅ Covered\n\n| Policy Name | Sign-In Frequency | Compliant |\n| :--- | :--- | :--- |\n| [j-test admin](https://entra.microsoft.com/#view/Microsoft_AAD_ConditionalAccess/PolicyBlade/policyId/6c0ef46a-3b58-43a9-b451-7464a16d91d7) | 1 hours | ✅ |\n\n#### Partner Tier1 Support\n\n**Status:** ❌ No CA policies assigned\n\n*No Conditional Access policies target this privileged role.*\n\n#### Partner Tier2 Support\n\n**Status:** ❌ No CA policies assigned\n\n*No Conditional Access policies target this privileged role.*\n\n#### Directory Writers\n\n**Status:** ❌ No CA policies assigned\n\n*No Conditional Access policies target this privileged role.*\n\n#### Application Administrator\n\n**Status:** ✅ Covered\n\n| Policy Name | Sign-In Frequency | Compliant |\n| :--- | :--- | :--- |\n| [j-test admin](https://entra.microsoft.com/#view/Microsoft_AAD_ConditionalAccess/PolicyBlade/policyId/6c0ef46a-3b58-43a9-b451-7464a16d91d7) | 1 hours | ✅ |\n\n#### Application Developer\n\n**Status:** ❌ No CA policies assigned\n\n*No Conditional Access policies target this privileged role.*\n\n#### Security Reader\n\n**Status:** ❌ No CA policies assigned\n\n*No Conditional Access policies target this privileged role.*\n\n#### Security Administrator\n\n**Status:** ✅ Covered\n\n| Policy Name | Sign-In Frequency | Compliant |\n| :--- | :--- | :--- |\n| [j-test admin](https://entra.microsoft.com/#view/Microsoft_AAD_ConditionalAccess/PolicyBlade/policyId/6c0ef46a-3b58-43a9-b451-7464a16d91d7) | 1 hours | ✅ |\n\n#### Privileged Role Administrator\n\n**Status:** ✅ Covered\n\n| Policy Name | Sign-In Frequency | Compliant |\n| :--- | :--- | :--- |\n| [j-test admin](https://entra.microsoft.com/#view/Microsoft_AAD_ConditionalAccess/PolicyBlade/policyId/6c0ef46a-3b58-43a9-b451-7464a16d91d7) | 1 hours | ✅ |\n\n#### Intune Administrator\n\n**Status:** ❌ No CA policies assigned\n\n*No Conditional Access policies target this privileged role.*\n\n#### Cloud Application Administrator\n\n**Status:** ✅ Covered\n\n| Policy Name | Sign-In Frequency | Compliant |\n| :--- | :--- | :--- |\n| [j-test admin](https://entra.microsoft.com/#view/Microsoft_AAD_ConditionalAccess/PolicyBlade/policyId/6c0ef46a-3b58-43a9-b451-7464a16d91d7) | 1 hours | ✅ |\n\n#### Conditional Access Administrator\n\n**Status:** ✅ Covered\n\n| Policy Name | Sign-In Frequency | Compliant |\n| :--- | :--- | :--- |\n| [j-test admin](https://entra.microsoft.com/#view/Microsoft_AAD_ConditionalAccess/PolicyBlade/policyId/6c0ef46a-3b58-43a9-b451-7464a16d91d7) | 1 hours | ✅ |\n\n#### Cloud Device Administrator\n\n**Status:** ❌ No CA policies assigned\n\n*No Conditional Access policies target this privileged role.*\n\n#### Authentication Administrator\n\n**Status:** ✅ Covered\n\n| Policy Name | Sign-In Frequency | Compliant |\n| :--- | :--- | :--- |\n| [j-test admin](https://entra.microsoft.com/#view/Microsoft_AAD_ConditionalAccess/PolicyBlade/policyId/6c0ef46a-3b58-43a9-b451-7464a16d91d7) | 1 hours | ✅ |\n\n#### Privileged Authentication Administrator\n\n**Status:** ✅ Covered\n\n| Policy Name | Sign-In Frequency | Compliant |\n| :--- | :--- | :--- |\n| [j-test admin](https://entra.microsoft.com/#view/Microsoft_AAD_ConditionalAccess/PolicyBlade/policyId/6c0ef46a-3b58-43a9-b451-7464a16d91d7) | 1 hours | ✅ |\n\n#### B2C IEF Keyset Administrator\n\n**Status:** ❌ No CA policies assigned\n\n*No Conditional Access policies target this privileged role.*\n\n#### External Identity Provider Administrator\n\n**Status:** ❌ No CA policies assigned\n\n*No Conditional Access policies target this privileged role.*\n\n#### Security Operator\n\n**Status:** ❌ No CA policies assigned\n\n*No Conditional Access policies target this privileged role.*\n\n#### Global Reader\n\n**Status:** ❌ No CA policies assigned\n\n*No Conditional Access policies target this privileged role.*\n\n#### Password Administrator\n\n**Status:** ✅ Covered\n\n| Policy Name | Sign-In Frequency | Compliant |\n| :--- | :--- | :--- |\n| [j-test admin](https://entra.microsoft.com/#view/Microsoft_AAD_ConditionalAccess/PolicyBlade/policyId/6c0ef46a-3b58-43a9-b451-7464a16d91d7) | 1 hours | ✅ |\n\n#### Hybrid Identity Administrator\n\n**Status:** ❌ No CA policies assigned\n\n*No Conditional Access policies target this privileged role.*\n\n#### Domain Name Administrator\n\n**Status:** ❌ No CA policies assigned\n\n*No Conditional Access policies target this privileged role.*\n\n#### AI Administrator\n\n**Status:** ❌ No CA policies assigned\n\n*No Conditional Access policies target this privileged role.*\n\n#### AI Reader\n\n**Status:** ❌ No CA policies assigned\n\n*No Conditional Access policies target this privileged role.*\n\n#### Identity Governance Administrator\n\n**Status:** ❌ No CA policies assigned\n\n*No Conditional Access policies target this privileged role.*\n\n#### Authentication Extensibility Administrator\n\n**Status:** ❌ No CA policies assigned\n\n*No Conditional Access policies target this privileged role.*\n\n#### Lifecycle Workflows Administrator\n\n**Status:** ❌ No CA policies assigned\n\n*No Conditional Access policies target this privileged role.*\n\n#### Attribute Provisioning Reader\n\n**Status:** ❌ No CA policies assigned\n\n*No Conditional Access policies target this privileged role.*\n\n#### Attribute Provisioning Administrator\n\n**Status:** ❌ No CA policies assigned\n\n*No Conditional Access policies target this privileged role.*\n\n#### Authentication Extensibility Password Administrator\n\n**Status:** ❌ No CA policies assigned\n\n*No Conditional Access policies target this privileged role.*\n\n#### Agent ID Administrator\n\n**Status:** ❌ No CA policies assigned\n\n*No Conditional Access policies target this privileged role.*\n\n#### ExamStudyTest\n\n**Status:** ❌ No CA policies assigned\n\n*No Conditional Access policies target this privileged role.*\n\n❌ **Not all privileged roles are covered by compliant sign-in frequency controls.**\n\n**Recommendation:** Configure Conditional Access policies to enforce sign-in frequency of 4 hours or less for ALL privileged roles.\n\n\n","TestStatus":"Failed","TestDescription":"When privileged users are allowed to maintain long-lived sign-in sessions without periodic reauthentication, threat actors can gain extended windows of opportunity to exploit compromised credentials or hijack active sessions. Once a privileged account is compromised through techniques like credential theft, phishing, or session fixation, extended session timeouts allow threat actors to maintain persistence within the environment for prolonged periods. With long-lived sessions, threat actors can perform lateral movement across systems, escalate privileges further, and access sensitive resources without triggering another authentication challenge. The extended session duration also increases the window for session hijacking attacks, where threat actors can steal session tokens and impersonate the privileged user. Once a threat actor is established in a privileged session, they can:\n\n- Create backdoor accounts\n- Modify security policies\n- Access sensitive data\n- Establish more persistence mechanisms\n\nThe lack of periodic reauthentication requirements means that even if the original compromise is detected, the threat actor might continue operating undetected using the hijacked privileged session until the session naturally expires or the user manually signs out.\n\n**Remediation action**\n\n- [Learn about Conditional Access adaptive session lifetime policies](https://learn.microsoft.com/entra/identity/conditional-access/concept-session-lifetime?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci)\n- [Configure sign-in frequency for privileged users with Conditional Access policies ](https://learn.microsoft.com/entra/identity/conditional-access/howto-conditional-access-session-lifetime?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci)\n","TestId":21825},{"TestImpact":"Low","TestRisk":"Low","TestSkipped":"","TestAppliesTo":null,"TestPillar":"Data","TestCategory":"Information Protection","TestDescription":"When an organization doesn’t use custom branding templates, people outside the company who receive encrypted messages could see a generic Microsoft‑branded portal. Because the portal doesn’t reflect the organization’s identity, recipients can be less confident about where the message came from.\n\nCustom branding templates let organizations add their logo, colors, disclaimers, and contact details to the portal. These elements help the portal look familiar to recipients and can support trust when they view and interact with encrypted messages.\n\n**Remediation action**\n\n- [Add your organization's brand to your encrypted messages](https://learn.microsoft.com/purview/add-your-organization-brand-to-encrypted-messages?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci)\n","TestTitle":"OME Custom Branding Templates","SkippedReason":null,"TestId":"35027","TestImplementationCost":"Low","TestMinimumLicense":["RMS_S_PREMIUM"],"TestSfiPillar":"Protect tenants and production systems","TestResult":"\n❌ OME custom branding is not configured; the encryption portal uses generic Microsoft branding.\n\n**Summary:**\n\n- Total OME Configurations: 1\n- Configured with Custom Branding: 0\n\n**Configuration Details:**\n\n| Configuration identity | Email text | Logo configured | Background color | Portal text | Introduction text | Disclaimer text |\n|:-----------------------|:-----------|:----------------|:-----------------|:------------|:------------------|:----------------|\n| OME Configuration | ❌ None | ❌ No | ❌ None | ❌ None | ❌ None | ❌ None |\n\n","TestStatus":"Failed","TestTags":null},{"TestImplementationCost":"Medium","TestPillar":"Identity","TestCategory":"Application management","SkippedReason":null,"TestImpact":"Medium","TestAppliesTo":["Identity"],"TestSfiPillar":"Protect identities and secrets","TestSkipped":"","TestMinimumLicense":"Free","TestTags":["Application"],"TestTitle":"Applications don't have certificates with expiration longer than 180 days","TestRisk":"High","TestResult":"\nFound 3 applications and 7 service principals with certificates longer than 180 days\n\n\n## Applications with long-lived credentials\n\n| Application | Certificate expiry |\n| :--- | :--- |\n| [Automation](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/ApplicationMenuBlade/~/Credentials/appId/dc7d83b5-d38b-4488-8952-7abf02e71590) | 2125-03-03 |\n| [Custom-App-Test](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/ApplicationMenuBlade/~/Credentials/appId/ddb4f0e6-8018-4359-96c1-7473704bde43) | 2028-11-05 |\n| [ZeroTrustTest](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/ApplicationMenuBlade/~/Credentials/appId/3835a2fc-573d-4c4b-a4a3-993a1a156607) | 2028-10-04 |\n\n\n## Service principals with long-lived credentials\n\n| Service principal | App owner tenant | Certificate expiry |\n| :--- | :--- | :--- |\n| [21869testapp](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/SignOn/objectId/e69e29be-ba40-445a-9824-a3a45e0ae57a/appId/dd63d132-18fb-4f2e-aec4-82b97f30301f/preferredSingleSignOnMode/saml/servicePrincipalType/Application/fromNav/) | | 2028-10-27 |\n| [APP-2732_Genesys Cloud TCCC-G-TFS-Prod](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/SignOn/objectId/ba63bb52-182c-4ec6-9cc8-ad2287cf51ed/appId/76249b01-8747-4db4-843f-6478d5b32b14/preferredSingleSignOnMode/saml/servicePrincipalType/Application/fromNav/) | | 2028-07-30 |\n| [Azure AD SAML Toolkit](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/SignOn/objectId/4317fd0a-dcee-45bf-8e94-9a66638b11e0/appId/6f5ed68c-9fad-4d78-bf88-2b16bbe16338/preferredSingleSignOnMode/saml/servicePrincipalType/Application/fromNav/) | | 2028-10-11 |\n| [charlie AWS Account](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/SignOn/objectId/39861745-eda1-4e3c-8358-d0ba931f12bb/appId/d3a04f85-a969-436b-bf4d-eae0a91efb4c/preferredSingleSignOnMode/saml/servicePrincipalType/Application/fromNav/) | | 2028-01-07 |\n| [charlie- Genesys Cloud for Azure](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/SignOn/objectId/84dc13ec-5754-4745-90f9-5cc92a5ded28/appId/9c599cd2-9fb0-4815-b65c-83be33f5df1b/preferredSingleSignOnMode/saml/servicePrincipalType/Application/fromNav/) | | 2028-07-30 |\n| [SumoLogic](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/SignOn/objectId/144df581-a0c9-4280-9739-0c3612ab9ccf/appId/1b6c36b2-f2b1-43d3-b74f-8d52c44fc9c1/preferredSingleSignOnMode/saml/servicePrincipalType/Application/fromNav/) | | 2027-02-15 |\n| [claimtest](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/SignOn/objectId/f7b07e81-79a0-4e51-b93a-169b8f2f6c4e/appId/f816d68b-aec7-4eab-9ebc-bd23b0d04e35/preferredSingleSignOnMode/saml/servicePrincipalType/Application/fromNav/) | | 2028-02-26 |\n\n\n","TestStatus":"Failed","TestDescription":"Certificates, if not securely stored, can be extracted and exploited by attackers, leading to unauthorized access. Long-lived certificates are more likely to be exposed over time. Credentials, when exposed, provide attackers with the ability to blend their activities with legitimate operations, making it easier to bypass security controls. If an attacker compromises an application's certificate, they can escalate their privileges within the system, leading to broader access and control, depending on the privileges of the application.\n\n**Remediation action**\n\n- [Define certificate based application configuration](https://devblogs.microsoft.com/identity/app-management-policy/)\n- [Define trusted certificate authorities for apps and service principals in the tenant](https://learn.microsoft.com/graph/api/resources/certificatebasedapplicationconfiguration?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci)\n- [Define application management policies](https://learn.microsoft.com/graph/api/resources/applicationauthenticationmethodpolicy?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci)\n- [Enforce secret and certificate standards](https://learn.microsoft.com/entra/identity/enterprise-apps/tutorial-enforce-secret-standards?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci)\n- [Create a least-privileged custom role to rotate application credentials](https://learn.microsoft.com/entra/identity/role-based-access-control/custom-create?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci)\n","TestId":"21773"},{"TestImpact":"Medium","TestRisk":"Medium","TestSkipped":"","TestAppliesTo":null,"TestPillar":"Data","TestCategory":"Microsoft Purview Message Encryption","TestDescription":"The SimplifiedClientAccessEnabled setting controls whether the Protect button appears in Outlook on the web. This button lets users quickly add encryption to their emails. If the setting is not turned on, users cannot use the Protect button and must find other ways to encrypt their messages.\n\nTo enable this setting, AzureRMSLicensingEnabled must also be active. Azure Rights Management encryption service provides the encryption technology needed for the Protect button to work.\n\n**Remediation action**\n\n- [Manage the display of the Encrypt button in Outlook on the web](https://learn.microsoft.com/purview/manage-office-365-message-encryption?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci#manage-the-display-of-the-encrypt-button-in-outlook-on-the-web)\n","TestTitle":"Office 365 Message Encryption (OME) - SimplifiedClientAccessEnabled","SkippedReason":null,"TestId":"35026","TestImplementationCost":"Low","TestMinimumLicense":["RMS_S_PREMIUM"],"TestSfiPillar":"Protect tenants and production systems","TestResult":"\n✅ SimplifiedClientAccessEnabled is true (Protect button enabled) and AzureRMSLicensingEnabled is true (encryption foundation active).\n\n\n### OME SimplifiedClientAccess Status\n\n| Setting | Value |\n| :------ | :---- |\n| SimplifiedClientAccessEnabled | True |\n| AzureRMSLicensingEnabled | True |\n| InternalLicensingEnabled | True |\n\n\n**Summary:**\n\n* Protect Button Status: ✅ Enabled\n\n\n","TestStatus":"Passed","TestTags":null},{"TestImplementationCost":"Low","TestPillar":"Identity","TestCategory":"Access control","SkippedReason":null,"TestImpact":"Medium","TestAppliesTo":["Identity"],"TestSfiPillar":"Protect identities and secrets","TestSkipped":"","TestMinimumLicense":"P1","TestTags":["User","Credential"],"TestTitle":"Block legacy authentication policies are configured","TestRisk":"Medium","TestResult":"\nConditional Access to block legacy Authentication are configured and enabled.\n\n - [Block legacy authentication](https://entra.microsoft.com/#view/Microsoft_AAD_ConditionalAccess/PolicyBlade/policyId/4086128c-3850-48ac-8962-e19a956828bd) (Report-only)\n - [Block legacy authentication - Testing](https://entra.microsoft.com/#view/Microsoft_AAD_ConditionalAccess/PolicyBlade/policyId/bedecc1e-85c9-4d54-b885-cefe6bcc8763) (Report-only)\n - [Block access except Compliant Network](https://entra.microsoft.com/#view/Microsoft_AAD_ConditionalAccess/PolicyBlade/policyId/9ee6df4b-165d-4f86-a176-0ddcc4ad886c)\n\n\n","TestStatus":"Passed","TestDescription":"Legacy authentication protocols such as basic authentication for SMTP and IMAP don't support modern security features like multifactor authentication (MFA), which is crucial for protecting against unauthorized access. This lack of protection makes accounts using these protocols vulnerable to password-based attacks, and provides attackers with a means to gain initial access using stolen or guessed credentials.\n\nWhen an attacker successfully gains unauthorized access to credentials, they can use them to access linked services, using the weak authentication method as an entry point. Attackers who gain access through legacy authentication might make changes to Microsoft Exchange, such as configuring mail forwarding rules or changing other settings, allowing them to maintain continued access to sensitive communications.\n\nLegacy authentication also provides attackers with a consistent method to reenter a system using compromised credentials without triggering security alerts or requiring reauthentication.\n\nFrom there, attackers can use legacy protocols to access other systems that are accessible via the compromised account, facilitating lateral movement. Attackers using legacy protocols can blend in with legitimate user activities, making it difficult for security teams to distinguish between normal usage and malicious behavior.\n\n**Remediation action**\n\n- [Deploy a Conditional Access policy to Block legacy authentication](https://learn.microsoft.com/entra/identity/conditional-access/policy-block-legacy-authentication?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci)\n","TestId":"21796"},{"TestImplementationCost":"Medium","TestPillar":"Identity","TestCategory":"Application management","SkippedReason":null,"TestImpact":"Medium","TestAppliesTo":null,"TestSfiPillar":"Protect engineering systems","TestSkipped":"","TestMinimumLicense":"P1","TestTags":null,"TestTitle":"Enterprise applications must require explicit assignment or scoped provisioning","TestRisk":"Medium","TestResult":"\nFound enterprise applications that lack both assignment requirements and provisioning scoping.\n## Applications without provisioning jobs (1)\n\n| Display name | Reason |\n| :----------- | :----- |\n| [21869testapp](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/Overview/objectId/e69e29be-ba40-445a-9824-a3a45e0ae57a/appId/dd63d132-18fb-4f2e-aec4-82b97f30301f) | No provisioning jobs configured |\n\n\n\n","TestStatus":"Failed","TestDescription":"When enterprise applications lack both explicit assignment requirements AND scoped provisioning controls, threat actors can exploit this dual weakness to gain unauthorized access to sensitive applications and data. The highest risk occurs when applications are configured with the default setting: \"Assignment required\" is set to \"No\" *and* provisioning isn't required or scoped. This dangerous combination allows threat actors who compromise any user account within the tenant to immediately access applications with broad user bases, expanding their attack surface and potential for lateral movement within the organization.\n\nWhile an application with open assignment but proper provisioning scoping (such as department-based filters or group membership requirements) maintains security controls through the provisioning layer, applications lacking both controls create unrestricted access pathways that threat actors can exploit. When applications provision accounts for all users without assignment restrictions, threat actors can abuse compromised accounts to conduct reconnaissance activities, enumerate sensitive data across multiple systems, or use the applications as staging points for further attacks against connected resources. This unrestricted access model is dangerous for applications that have elevated permissions or are connected to critical business systems. Threat actors can use any compromised user account to access sensitive information, modify data, or perform unauthorized actions that the application's permissions allow. The absence of both assignment controls and provisioning scoping also prevents organizations from implementing proper access governance. Without proper governance, it's difficult to track who has access to which applications, when access was granted, and whether access should be revoked based on role changes or employment status. Furthermore, applications with broad provisioning scopes can create cascading security risks where a single compromised account provides access to an entire ecosystem of connected applications and services.\n\n**Remediation action**\n- Evaluate business requirements to determine appropriate access control method. [Restrict a Microsoft Entra app to a set of users](https://learn.microsoft.com/entra/identity-platform/howto-restrict-your-app-to-a-set-of-users?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci).\n- Configure enterprise applications to require assignment for sensitive applications. [Learn about the \"Assignment required\" enterprise application property](https://learn.microsoft.com/entra/identity/enterprise-apps/application-properties?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci#assignment-required).\n- Implement scoped provisioning based on groups, departments, or attributes. [Create scoping filters](https://learn.microsoft.com/entra/identity/app-provisioning/define-conditional-rules-for-provisioning-user-accounts?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci#create-scoping-filters).\n","TestId":"21869"},{"TestImplementationCost":"Medium","TestPillar":"Identity","TestCategory":"Access control; Credential management","SkippedReason":null,"TestImpact":"Low","TestAppliesTo":null,"TestSfiPillar":"Protect identities and secrets","TestSkipped":"","TestMinimumLicense":"P1","TestTags":null,"TestTitle":"All user sign in activity uses phishing-resistant authentication methods","TestRisk":"Medium","TestResult":"\n❌ Not all users are protected by Conditional Access policies requiring phishing-resistant authentication methods.\n\n**Reason**: Found policies with user exclusions that create coverage gaps\n## Conditional Access Policies with Phishing-Resistant Authentication (Issues Found)\n\n| Policy | Authentication strength | Included Users | Excluded Users |\n| :---------- | :---------------------- | :------------- | :------------- |\n| [Security regisrtation info](https://entra.microsoft.com/#view/Microsoft_AAD_ConditionalAccess/PolicyBlade/policyId/508ae024-d4c4-42bf-a8c9-40257c214c10) | [Multifactor authentication](https://entra.microsoft.com/#view/Microsoft_AAD_ConditionalAccess/ConditionalAccessBlade/~/AuthStrengths/menuId//fromNav/Identity) | All Users | ⚠️ 3 users |\n\n\n\n","TestStatus":"Failed","TestDescription":"Phishing-resistant authentication methods like passkeys and FIDO2 security keys provide the strongest protection against credential theft and sophisticated phishing attacks. Traditional MFA methods remain vulnerable to adversary-in-the-middle attacks and social engineering. Enforcing phishing-resistant methods for all users through Conditional Access policies helps prevent unauthorized access even when attackers attempt to intercept authentication flows.\n\n**Remediation action**\n\n- [Configure Conditional Access for all users with MFA strength](https://learn.microsoft.com/entra/identity/conditional-access/policy-all-users-mfa-strength?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci)\n- [Deploy phishing-resistant passwordless authentication](https://learn.microsoft.com/entra/identity/authentication/how-to-deploy-phishing-resistant-passwordless-authentication?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci)\n","TestId":"21784"},{"TestImplementationCost":"High","TestPillar":null,"TestCategory":"Application management","SkippedReason":"UnderConstruction","TestImpact":"Low","TestAppliesTo":["Identity"],"TestSfiPillar":"","TestSkipped":"UnderConstruction","TestMinimumLicense":null,"TestTags":["Identity"],"TestTitle":"Line-of-business and partner apps use MSAL","TestRisk":"Medium","TestResult":"\nPlanned for future release.\n","TestStatus":"Planned","TestDescription":"...\n\n**Remediation action**\n\n","TestId":"21778"},{"TestImplementationCost":"Low","TestPillar":"Devices","TestCategory":"Device","SkippedReason":null,"TestImpact":"Medium","TestAppliesTo":null,"TestSfiPillar":"Protect tenants and isolate production systems","TestSkipped":"","TestMinimumLicense":"Intune","TestTags":null,"TestTitle":"macOS update policy is configured and assigned","TestRisk":"High","TestResult":"\nAt least one macOS update policy is assigned to a group.\n\n\n## macOS Update Policies\n\n| Policy Name | Status | Assignment Target |\n| :---------- | :----- | :---------------- |\n| [macOS_Update_1](https://intune.microsoft.com/#view/Microsoft_Intune_DeviceSettings/DevicesMenu/~/iOSiPadOSUpdate) | ✅ Assigned | **Included:** All Devices, **Excluded:** WFgroup |\n| [alex_macOS_SoftwareUpdate](https://intune.microsoft.com/#view/Microsoft_Intune_DeviceSettings/DevicesMenu/~/configuration) | ✅ Assigned | **Included:** All Devices, **Excluded:** WFgroup |\n| [alex_macOS_SoftwareUpdateEnforceLatest](https://intune.microsoft.com/#view/Microsoft_Intune_DeviceSettings/DevicesMenu/~/configuration) | ❌ Not assigned | None |\n\n\n\n","TestStatus":"Passed","TestDescription":"If macOS update policies aren’t properly configured and assigned, threat actors can exploit unpatched vulnerabilities in macOS devices within the organization. Without enforced update policies, devices remain on outdated software versions, increasing the attack surface for privilege escalation, remote code execution, or persistence techniques. Threat actors can leverage these weaknesses to gain initial access, escalate privileges, and move laterally within the environment. If policies exist but aren’t assigned to device groups, endpoints remain unprotected, and compliance gaps go undetected. This can result in widespread compromise, data exfiltration, and operational disruption.\n\nEnforcing macOS update policies ensures devices receive timely patches, reducing the risk of exploitation and supporting Zero Trust by maintaining a secure, compliant device fleet.\n\n**Remediation action**\n\nConfigure and assign macOS update policies in Intune to enforce timely patching and reduce risk from unpatched vulnerabilities: \n- [Manage macOS software updates in Intune](https://learn.microsoft.com/intune/intune-service/protect/software-updates-macos?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci)\n","TestId":"24690"},{"TestImplementationCost":"Low","TestPillar":"Identity","TestCategory":"Credential management","SkippedReason":null,"TestImpact":"Low","TestAppliesTo":null,"TestSfiPillar":"Protect identities and secrets","TestSkipped":"","TestMinimumLicense":"P1","TestTags":null,"TestTitle":"Microsoft Authenticator app report suspicious activity setting is enabled","TestRisk":"Medium","TestResult":"\nAuthenticator app report suspicious activity is [not enabled](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/AuthenticationMethodsMenuBlade/~/AuthMethodsSettings).\n\n","TestStatus":"Failed","TestDescription":"Threat actors increasingly rely on prompt bombing and real-time phishing proxies to coerce or trick users into approving fraudulent multifactor authentication (MFA) challenges. Without the Microsoft Authenticator app's **Report suspicious activity** capability enabled, an attacker can iterate until a fatigued user accepts. This type of attack can lead to privilege escalation, persistence, lateral movement into sensitive workloads, data exfiltration, or destructive actions.\n\nWhen reporting is enabled for all users, any unexpected push or phone prompt can be actively flagged, immediately elevating the user to high user risk and generating a high-fidelity user risk detection (userReportedSuspiciousActivity) that risk-based Conditional Access policies or other response automation can use to block or require secure remediation. \n\n**Remediation action**\n\n- [Enable the report suspicious activity setting in the Microsoft Authenticator app](https://learn.microsoft.com/entra/identity/authentication/howto-mfa-mfasettings?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci#report-suspicious-activity)\n","TestId":"21841"},{"TestImpact":"High","TestRisk":"Medium","TestSkipped":"","TestAppliesTo":null,"TestPillar":"Data","TestCategory":"Label Policy Configuration","TestDescription":"When users attach sensitive documents to emails, the email should inherit the highest sensitivity label from attachments to maintain consistent protection. Without this setting enabled, users might send unlabeled emails that contain sensitive attachments, creating a mismatch between the email's sensitivity and its actual content.\n\nEmail label inheritance automatically applies the attachment's highest priority label to the email message, ensuring protection levels match and prevent accidental data exposure.\n\n**Remediation action**\n\n- [Publish sensitivity labels](https://learn.microsoft.com/purview/create-sensitivity-labels?tabs=modern-label-scheme&wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci#publish-sensitivity-labels-by-creating-a-label-policy) to [Configure label inheritance from email attachments](https://learn.microsoft.com/purview/sensitivity-labels-office-apps?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci#configure-label-inheritance-from-email-attachments).\n","TestTitle":"Email label inheritance from attachments configured","SkippedReason":null,"TestId":"35014","TestImplementationCost":"Low","TestMinimumLicense":["RMS_S_PREMIUM"],"TestSfiPillar":"Protect tenants and production systems","TestResult":"\n❌ Email label inheritance is not configured. No label policies have the `attachmentaction` setting enabled, or no labels are scoped to both files and emails to participate in inheritance.\n\n\n### [Dual-scoped labels (ready for inheritance)](https://purview.microsoft.com/informationprotection/informationprotectionlabels/sensitivitylabels)\n\n| Label name | Content type | Priority |\n| :--------- | :----------- | :------- |\n| alex-test-label-1-display | Files & Emails | 0 |\n| 35010Test | Files & Emails | 1 |\n| peyton | Files & Emails | 3 |\n| test-35012-1 | Files & Emails | 4 |\n| test35036 | Files & Emails | 6 |\n| 35014-parker | Files & Emails | 8 |\n\n**Summary:**\n\n- Policies with attachmentaction enabled: 0\n- Labels with Files & Emails scope: 6\n- Inheritance setting found: False\n\n\n","TestStatus":"Failed","TestTags":null},{"TestImplementationCost":"Medium","TestPillar":"Identity","TestCategory":"Access control","SkippedReason":"UnderConstruction","TestImpact":"Medium","TestAppliesTo":["Identity"],"TestSfiPillar":"Protect identities and secrets","TestSkipped":"UnderConstruction","TestMinimumLicense":null,"TestTags":["Identity"],"TestTitle":"Guest access is restricted","TestRisk":"Medium","TestResult":"\nPlanned for future release.\n","TestStatus":"Planned","TestDescription":"...\n\n**Remediation action**\n\n","TestId":"21821"},{"TestImplementationCost":"Low","TestPillar":"Identity","TestCategory":"Credential management","SkippedReason":null,"TestImpact":"Low","TestAppliesTo":["Identity"],"TestSfiPillar":"Protect identities and secrets","TestSkipped":"","TestMinimumLicense":"P1","TestTags":["Identity"],"TestTitle":"Temporary access pass restricted to one-time use","TestRisk":"Low","TestResult":"\nTemporary Access Pass is configured for one-time use only.\n\n\n## Temporary Access Pass Configuration\n\n| Setting | Value | Status |\n| :------ | :---- | :----- |\n| [One-time use restriction](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/AuthenticationMethodsMenuBlade/~/AdminAuthMethods/fromNav/) | Enabled | ✅ Pass |\n\n\n","TestStatus":"Passed","TestDescription":"When Temporary Access Pass (TAP) is configured to allow multiple uses, threat actors who compromise the credential can reuse it repeatedly during its validity period, extending their unauthorized access window beyond the intended single bootstrapping event. This situation creates an extended opportunity for threat actors to establish persistence by registering additional strong authentication methods under the compromised account during the credential lifetime. A reusable TAP that falls into the wrong hands lets threat actors conduct reconnaissance activities across multiple sessions, gradually mapping the environment and identifying high-value targets while maintaining legitimate-looking access patterns. The compromised TAP can also serve as a reliable backdoor mechanism, allowing threat actors to maintain access even if other compromised credentials are detected and revoked, since the TAP appears as a legitimate administrative tool in security logs.\n\n**Remediation action**\n\n- [Configure Temporary Access Pass for one-time use in authentication methods policy](https://learn.microsoft.com/entra/identity/authentication/howto-authentication-temporary-access-pass?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci#enable-the-temporary-access-pass-policy)\n","TestId":"21846"},{"TestImplementationCost":"Medium","TestPillar":"Identity","TestCategory":"Credential management","SkippedReason":null,"TestImpact":"Medium","TestAppliesTo":null,"TestSfiPillar":"Protect identities and secrets","TestSkipped":"","TestMinimumLicense":"P1","TestTags":null,"TestTitle":"Migrate from legacy MFA and SSPR policies","TestRisk":"High","TestResult":"\nCombined registration is enabled.\n\n\n\n","TestStatus":"Passed","TestDescription":"Legacy multifactor authentication (MFA) and self-service password reset (SSPR) policies in Microsoft Entra ID manage authentication methods separately, leading to fragmented configurations and suboptimal user experience. Moreover, managing these policies independently increases administrative overhead and the risk of misconfiguration. \n\nMigrating to the combined Authentication Methods policy consolidates the management of MFA, SSPR, and passwordless authentication methods into a single policy framework. This unification allows for more granular control, enabling administrators to target specific authentication methods to user groups and enforce consistent security measures across the organization. Additionally, the unified policy supports modern authentication methods, such as FIDO2 security keys and Windows Hello for Business, enhancing the organization's security posture.\n\nMicrosoft announced the deprecation of legacy MFA and SSPR policies, with a retirement date set for September 30, 2025. Organizations are advised to complete the migration to the Authentication Methods policy before this date to avoid potential disruptions and to benefit from the enhanced security and management capabilities of the unified policy.\n\n**Remediation action**\n\n- [Enable combined security information registration](https://learn.microsoft.com/entra/identity/authentication/howto-registration-mfa-sspr-combined?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci)\n- [How to migrate MFA and SSPR policy settings to the Authentication methods policy for Microsoft Entra ID](https://learn.microsoft.com/entra/identity/authentication/how-to-authentication-methods-manage?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci)\n","TestId":"21803"},{"TestImplementationCost":"Low","TestPillar":"Devices","TestCategory":"Data","SkippedReason":null,"TestImpact":"Low","TestAppliesTo":null,"TestSfiPillar":"Protect tenants and isolate production systems","TestSkipped":"","TestMinimumLicense":"Intune","TestTags":null,"TestTitle":"Corporate Wi-Fi Network on macOS Devices is Securely Managed ","TestRisk":"High","TestResult":"\nNo Enterprise Wi-Fi profile for macOS exists or none are assigned.\n\n\n\n","TestStatus":"Failed","TestDescription":"If Wi-Fi profiles aren't properly configured and assigned, macOS devices can fail to connect to secure networks or connect insecurely, exposing corporate data to interception or unauthorized access. Without centralized management, devices rely on manual configuration, increasing the risk of misconfiguration, weak authentication, and connection to rogue networks. These gaps can lead to data interception, unauthorized network access, and compliance violations.\n\nCentrally managing Wi-Fi profiles for macOS devices in Intune ensures secure and consistent connectivity to enterprise networks. This enforces authentication and encryption standards, simplifies onboarding, and supports Zero Trust by reducing exposure to untrusted networks.\n\n**Remediation action**\n\nUse Intune to configure and assign secure Wi-Fi profiles for macOS devices to enforce authentication and encryption standards:\n\n- [Configure Wi-Fi settings for macOS devices in Intune](https://learn.microsoft.com/intune/intune-service/configuration/wi-fi-settings-configure?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci#create-the-profile)\n\nFor more information, see:\n\n- [Review the available Wi-Fi settings for macOS devices in Microsoft Intune](https://learn.microsoft.com/intune/intune-service/configuration/wi-fi-settings-macos?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci)\n","TestId":"24870"},{"TestImplementationCost":"Low","TestPillar":"Identity","TestCategory":"Devices","SkippedReason":null,"TestImpact":"Low","TestAppliesTo":null,"TestSfiPillar":"Protect tenants and isolate production systems","TestSkipped":"","TestMinimumLicense":"Free","TestTags":null,"TestTitle":"Restrict nonadministrator users from recovering the BitLocker keys for their owned devices","TestRisk":"High","TestResult":"\n[Non-administrator users are restricted from recovering BitLocker keys for their owned devices](https://entra.microsoft.com/#view/Microsoft_AAD_Devices/DevicesMenuBlade/~/DeviceSettings/menuId/Overview)\n\n","TestStatus":"Passed","TestDescription":"When non-administrator users can access their own BitLocker keys, threat actors who compromise user credentials gain direct access to encryption keys without requiring privilege escalation. Once attackers obtain BitLocker keys, they can decrypt sensitive data stored on the device, including cached credentials, local databases, and confidential files.\n\nWithout proper restrictions, a single compromised user account provides immediate access to all encrypted data on that device, negating the primary security benefit of disk encryption and creating a pathway for lateral movement. \n\n**Remediation action**\n\n- [Restrict non-admin users from recovering the BitLocker key(s) for their owned devices](https://learn.microsoft.com/entra/identity/devices/manage-device-identities?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci#configure-device-settings)\n","TestId":"21954"},{"TestImplementationCost":"Medium","TestPillar":"Identity","TestCategory":"Access control","SkippedReason":"UnderConstruction","TestImpact":"Low","TestAppliesTo":["Identity"],"TestSfiPillar":"Protect identities and secrets","TestSkipped":"UnderConstruction","TestMinimumLicense":null,"TestTags":["Identity"],"TestTitle":"No nested groups in PIM for groups","TestRisk":"Medium","TestResult":"\nPlanned for future release.\n","TestStatus":"Planned","TestDescription":"...\n\n**Remediation action**\n\n","TestId":"21882"},{"TestImpact":"Medium","TestRisk":"High","TestSkipped":"","TestAppliesTo":null,"TestPillar":"Data","TestCategory":"Data Security Posture Management","TestDescription":"Until organizations use Insider Risk Management with Adaptive Protection, they could fail to detect insider threats, risky behaviors such as misuse of legitimate access to exfiltrate data, or unsafe AI scenarios where users expose sensitive data to large language models or unauthorized cloud AI services.\n\nInsider Risk Management works with Data Loss Prevention (DLP) to combine user behavior signals with content-based rules, helping teams detect risks early and respond before sensitive data is exposed or compromised.\n\n**Remediation action**\n\n- [Create and configure Insider Risk Management policies](https://learn.microsoft.com/purview/insider-risk-management-policies?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci)\n- [Help dynamically mitigate risks with Adaptive Protection](https://learn.microsoft.com/purview/insider-risk-management-adaptive-protection?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci)\n","TestTitle":"Insider Risk Management Policies Enabled for Risky AI Usage","SkippedReason":null,"TestId":"35038","TestImplementationCost":"Medium","TestMinimumLicense":["EXCHANGE_S_ENTERPRISE"],"TestSfiPillar":"Protect tenants and production systems","TestResult":"\n❌ No Insider Risk Management Policies are enabled with Adaptive Protection, creating a critical gap in insider threat detection and risky AI usage prevention.\n## Summary\n\n- **Total IRM Policies:** 2\n- **Enabled Policies with Adaptive Protection:** 0\n## [IRM Policies](https://purview.microsoft.com/insiderriskmgmt/policiespage)\n\n| Policy Name | Enabled | Adaptive Protection (OptInDrpForDlp) | Created Date |\n|:---|:---|:---|:---|\n| Data leaks quick policy - 1/13/2026 | ✅ Enabled | ❌ Disabled | 2026-01-13 |\n| IRM_Tenant_Setting_0817c655-a853-4d8f-9723-3a333b5b9235 | ✅ Enabled | ❌ Disabled | 2026-01-09 |\n\n\n","TestStatus":"Failed","TestTags":null},{"TestImplementationCost":"Medium","TestPillar":"Identity","TestCategory":"Access control","SkippedReason":"UnderConstruction","TestImpact":"Low","TestAppliesTo":["Identity"],"TestSfiPillar":"Protect identities and secrets","TestSkipped":"UnderConstruction","TestMinimumLicense":null,"TestTags":["Identity"],"TestTitle":"Azure subscriptions used by Identity Governance are secured consistently with Identity Governance roles","TestRisk":"High","TestResult":"\nPlanned for future release.\n","TestStatus":"Planned","TestDescription":"...\n\n**Remediation action**\n\n","TestId":"21881"},{"TestImplementationCost":"Low","TestPillar":"Identity","TestCategory":"Access control","SkippedReason":"UnderConstruction","TestImpact":"Low","TestAppliesTo":["Identity"],"TestSfiPillar":"Protect identities and secrets","TestSkipped":"UnderConstruction","TestMinimumLicense":null,"TestTags":["Identity"],"TestTitle":"Directory sync account is locked down to specific named location","TestRisk":"Low","TestResult":"\nPlanned for future release.\n","TestStatus":"Planned","TestDescription":"...\n\n**Remediation action**\n\n","TestId":"21834"},{"TestImpact":"Medium","TestRisk":"High","TestSkipped":"","TestAppliesTo":null,"TestPillar":"Data","TestCategory":"Advanced Classification","TestDescription":"Exact data match (EDM) is an advanced sensitive information type that detects organization-specific data by matching exact values against an uploaded reference database. Unlike pattern-based sensitive information types (SITs) that detect common formats, EDM identifies things like customer lists, employee IDs, or proprietary codes unique to your organization. Without EDM, auto-labeling policies and DLP rules can't detect this proprietary data, leaving it at risk of exposure.\n\n**Remediation action**\n\n- [Learn about exact data match based sensitive information types](https://learn.microsoft.com/purview/sit-learn-about-exact-data-match-based-sits?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci)\n- [Get started with exact data match based sensitive information types](https://learn.microsoft.com/purview/sit-get-started-exact-data-match-based-sits-overview?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci)\n","TestTitle":"Exact Data Match (EDM) Configurations","SkippedReason":null,"TestId":"35034","TestImplementationCost":"Medium","TestMinimumLicense":["EXCHANGE_S_ENTERPRISE"],"TestSfiPillar":"Protect tenants and production systems","TestResult":"\n✅ Exact Data Match (EDM) schemas are configured, enabling detection of organization-specific sensitive data patterns.\n\n\n## [Exact Data Match Schemas](https://purview.microsoft.com/informationprotection/dataclassification/exactdatamatch)\n\n| Schema name | Description | Version | Created date | Modified date |\n| :---------- | :---------- | :------ | :----------- | :------------ |\n| test | test edm | 1 | 01/28/2026 20:41:04 | 01/28/2026 20:41:04 |\n| test35034 | testing | 2 | 01/28/2026 20:40:03 | 01/28/2026 20:43:26 |\n\n**Summary:**\n* Total EDM Schemas: 2\n\n\n","TestStatus":"Passed","TestTags":null},{"TestImplementationCost":"","TestPillar":"Infrastructure","TestCategory":"Remediate vulnerabilities","SkippedReason":"This test is not applicable to the current environment.","TestImpact":"","TestAppliesTo":null,"TestSfiPillar":"Protect tenants and isolate production systems","TestSkipped":"NotApplicable","TestMinimumLicense":"N/A","TestTags":null,"TestTitle":"Machines should have vulnerability findings resolved","TestRisk":"Low","TestResult":"Vulnerability assessment scanner is not deployed on the machine, Unsupported OS\n\n| Subscription | Resource group | Resource type | Affected resource | Status | Azure portal |\n| :----------- | :------------- | :------------ | :---------------- | :----- | :----------- |\n| [Visual Studio Enterprise Subscription](https://portal.azure.com/#resource/subscriptions/54d3ea01-5a07-45d0-8d69-e5f5b0b20098) | indiavm_group | virtualmachines | [india-2](https://portal.azure.com/#resource/subscriptions/54d3ea01-5a07-45d0-8d69-e5f5b0b20098/resourceGroups/INDIAVM_GROUP/providers/Microsoft.Compute/virtualMachines/india-2) | N/A | [View recommendation](https://portal.azure.com/#blade/Microsoft_Azure_Security/RecommendationsBlade/assessmentKey/1195afff-c881-495e-9bc5-1486211ae03f/resourceId/%2fsubscriptions%2f54d3ea01-5a07-45d0-8d69-e5f5b0b20098%2fresourceGroups%2fINDIAVM_GROUP%2fproviders%2fMicrosoft.Compute%2fvirtualMachines%2findia-2) |\n| [Visual Studio Enterprise Subscription](https://portal.azure.com/#resource/subscriptions/54d3ea01-5a07-45d0-8d69-e5f5b0b20098) | indiavm_group | virtualmachines | [indiavm](https://portal.azure.com/#resource/subscriptions/54d3ea01-5a07-45d0-8d69-e5f5b0b20098/resourceGroups/INDIAVM_GROUP/providers/Microsoft.Compute/virtualMachines/indiavm) | N/A | [View recommendation](https://portal.azure.com/#blade/Microsoft_Azure_Security/RecommendationsBlade/assessmentKey/1195afff-c881-495e-9bc5-1486211ae03f/resourceId/%2fsubscriptions%2f54d3ea01-5a07-45d0-8d69-e5f5b0b20098%2fresourceGroups%2fINDIAVM_GROUP%2fproviders%2fMicrosoft.Compute%2fvirtualMachines%2findiavm) |\n","TestStatus":"Skipped","TestDescription":"Resolving vulnerability findings on virtual machines is a recommended step in maintaining a secure environment.
\nThese findings, identified by vulnerability assessment solutions, highlight potential weaknesses that could be exploited by malicious actors.
\nIf these vulnerabilities are not addressed, they could lead to unauthorized access, data breaches, or even system failure.
\nTherefore, it is important to resolve these findings promptly to ensure the security and integrity of the virtual machines.
\n\n**Remediation action**\n\nReview and remediate vulnerabilities discovered by the vulnerability assessment solutions.","TestId":"1195afff-c881-495e-9bc5-1486211ae03f"},{"TestImplementationCost":"Medium","TestPillar":"Identity","TestCategory":"External collaboration","SkippedReason":null,"TestImpact":"Medium","TestAppliesTo":null,"TestSfiPillar":"Protect identities and secrets","TestSkipped":"","TestMinimumLicense":"P2","TestTags":null,"TestTitle":"All entitlement management assignment policies that apply to external users require approval","TestRisk":"Medium","TestResult":"\nNo access package assignment policies found that apply to external users.\n\n","TestStatus":"Passed","TestDescription":"Access package assignment policies that allow external users to request access should require approval. Without an approval gate, external users can self-provision access to organizational resources without oversight. Requiring approval ensures that a designated approver reviews each request, providing an opportunity to validate the requestor's identity and business justification before granting access.\n\n**Remediation action**\n\n- [Configure approval for access package assignment policies](https://learn.microsoft.com/entra/id-governance/entitlement-management-access-package-approval-policy?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci)\n- [Review access package policies for external users](https://learn.microsoft.com/entra/id-governance/entitlement-management-access-package-request-policy?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci)\n","TestId":"21879"},{"TestImplementationCost":"Low","TestPillar":"Identity","TestCategory":"Credential management","SkippedReason":null,"TestImpact":"Low","TestAppliesTo":null,"TestSfiPillar":"Protect identities and secrets","TestSkipped":"","TestMinimumLicense":"P1","TestTags":null,"TestTitle":"Smart lockout threshold set to 10 or less","TestRisk":"Medium","TestResult":"\nSmart lockout threshold is configured above 10.\n## Smart lockout configuration\n\n| Setting | Value |\n| :---- | :---- |\n| [Lockout threshold](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/AuthenticationMethodsMenuBlade/~/PasswordProtection/fromNav/) | 11 attempts|\n\n\n","TestStatus":"Failed","TestDescription":"When the smart lockout threshold is set to more than 10, threat actors can exploit the configuration to conduct reconnaissance, identify valid user accounts without triggering lockout protections, and establish initial access without detection. Once attackers gain initial access, they can move laterally through the environment by using the compromised account to access resources and escalate privileges.\n\nSmart lockout helps lock out bad actors who try to guess your users' passwords or use brute force methods to get in. Smart lockout recognizes sign-ins that come from valid users and treats them differently than ones of attackers and other unknown sources. A threshold of more than 10 provides insufficient protection against automated password spray attacks, making it easier for threat actors to compromise accounts while evading detection mechanisms. \n\n**Remediation action**\n\n- [Set Microsoft Entra smart lockout threshold to 10 or less](https://learn.microsoft.com/entra/identity/authentication/howto-password-smart-lockout?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci).\n","TestId":"21850"},{"TestImplementationCost":"Low","TestPillar":"Identity","TestCategory":"Credential management","SkippedReason":"UnderConstruction","TestImpact":"Low","TestAppliesTo":["Identity"],"TestSfiPillar":"Protect identities and secrets","TestSkipped":"UnderConstruction","TestMinimumLicense":"P1","TestTags":["Identity"],"TestTitle":"Enable SSPR","TestRisk":"Low","TestResult":"\nPlanned for future release.\n\n","TestStatus":"Planned","TestDescription":"Without Self-Service Password Reset (SSPR) enabled, users with password-related issues must contact help desk support, which can cause in operational delays and lost productivity. There are also potential security vulnerabilities during the extended timeframe required for administrative password resets. These delays not only reduce employee efficiency (especially in time-sensitive roles), but also increase support costs and strain IT resources. During these periods, threat actors might exploit locked accounts through social engineering attacks targeting help desk personnel. Threat actors can potentially convince support staff to reset passwords for accounts they don't legitimately control, enabling initial access to user credentials.\n\nWhen users are unable to reset their own passwords through secure, automated processes, they frequently resort to insecure workarounds. Examples include sharing accounts with colleagues, using weak passwords that are easier to remember, or writing down passwords in discoverable locations, all of which expand the attack surface for credential harvesting techniques. The lack of SSPR forces users to maintain static passwords for longer periods between administrative resets. This type of password policy increases the likelihood that compromised credentials from previous breaches or password spray attacks remain valid and usable by threat actors. The absence of user-controlled password reset capabilities also delays the response time for users to secure their accounts when they suspect compromise. This delay allows threat actors extended persistence within compromised accounts to perform reconnaissance, establish other access methods, or exfiltrate sensitive data before the account is eventually reset through administrative channels \n\n**Remediation action**\n\n- [Enable Self-Service Password Reset](https://learn.microsoft.com/entra/identity/authentication/tutorial-enable-sspr?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci)\n","TestId":"21870"},{"TestImplementationCost":"Medium","TestPillar":"Identity","TestCategory":"External collaboration","SkippedReason":null,"TestImpact":"Medium","TestAppliesTo":["Identity"],"TestSfiPillar":"Protect tenants and isolate production systems","TestSkipped":"","TestMinimumLicense":"Free","TestTags":["Identity"],"TestTitle":"Allow/Deny lists of domains to restrict external collaboration are configured","TestRisk":"Medium","TestResult":"\nAllow/Deny lists of domains to restrict external collaboration are not configured.\n\n","TestStatus":"Failed","TestDescription":"Limiting guest access to a known and approved list of tenants helps to prevent threat actors from exploiting unrestricted guest access to establish initial access through compromised external accounts or by creating accounts in untrusted tenants. Threat actors who gain access through an unrestricted domain can discover internal resources, users, and applications to perform additional attacks. \n\nOrganizations should take inventory and configure an allowlist or blocklist to control B2B collaboration invitations from specific organizations. Without these controls, threat actors might use social engineering techniques to obtain invitations from legitimate internal users. \n\n**Remediation action**\n\n- Learn how to [set up a list of approved domains](https://learn.microsoft.com/entra/external-id/allow-deny-list?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci#add-an-allowlist).\n","TestId":"21874"},{"TestImplementationCost":"High","TestPillar":"Identity","TestCategory":"Access control","SkippedReason":"UnderConstruction","TestImpact":"High","TestAppliesTo":["Identity"],"TestSfiPillar":"Protect identities and secrets","TestSkipped":"UnderConstruction","TestMinimumLicense":null,"TestTags":["Identity"],"TestTitle":"All app assignment and group membership is governed","TestRisk":"Medium","TestResult":"\nPlanned for future release.\n","TestStatus":"Planned","TestDescription":"...\n\n**Remediation action**\n\n","TestId":"21897"},{"TestImplementationCost":"Low","TestPillar":"Devices","TestCategory":"Device","SkippedReason":null,"TestImpact":"Low","TestAppliesTo":null,"TestSfiPillar":"Protect identities and secrets","TestSkipped":"","TestMinimumLicense":"Intune","TestTags":null,"TestTitle":"Windows BitLocker policy is configured and assigned","TestRisk":"High","TestResult":"\nNo Windows BitLocker policy is configured or assigned.\n\n\n\n","TestStatus":"Failed","TestDescription":"Without a properly configured and assigned BitLocker policy in Intune, threat actors can exploit unencrypted Windows devices to gain unauthorized access to sensitive corporate data. Devices that lack enforced encryption are vulnerable to physical attacks, like disk removal or booting from external media, allowing attackers to bypass operating system security controls. These attacks can result in data exfiltration, credential theft, and further lateral movement within the environment.\n\nEnforcing BitLocker across managed Windows devices is critical for compliance with data protection regulations and for reducing the risk of data breaches.\n\n**Remediation action**\n\nUse Intune to enforce BitLocker encryption and monitor compliance across all managed Windows devices: \n- [Create a BitLocker policy for Windows devices in Intune](https://learn.microsoft.com/intune/intune-service/protect/encrypt-devices?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci#create-and-deploy-policy)\n- [Assign policies in Intune](https://learn.microsoft.com/intune/intune-service/configuration/device-profile-assign?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci#assign-a-policy-to-users-or-groups)\n- [Monitor device encryption with Intune](https://learn.microsoft.com/intune/intune-service/protect/encryption-monitor?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci)\n","TestId":"24550"},{"TestImplementationCost":"Medium","TestPillar":"Identity","TestCategory":"Access control","SkippedReason":null,"TestImpact":"Low","TestAppliesTo":null,"TestSfiPillar":"Protect identities and secrets","TestSkipped":"","TestMinimumLicense":"P1","TestTags":null,"TestTitle":"Privileged Microsoft Entra built-in roles are targeted with Conditional Access policies to enforce phishing-resistant methods","TestRisk":"High","TestResult":"\nSome privileged built-in roles don't have Conditional Access policies to enforce phishing-resistant authentication.\n\n\n\n## Conditional Access policies with phishing resistant authentication policies \n\nFound 4 phishing resistant Conditional Access policies.\n\n - [MFA CA Policy](https://entra.microsoft.com/#view/Microsoft_AAD_ConditionalAccess/PolicyBlade/policyId/e589544c-0c92-432e-86ae-4e4ef103eac8)\n - [Guest-Meferna-Woodgrove-PhishingResistantAuthStrength](https://entra.microsoft.com/#view/Microsoft_AAD_ConditionalAccess/PolicyBlade/policyId/0f0a0c1c-41b0-4c18-ae20-d02492d03737)\n - [NewphishingCA](https://entra.microsoft.com/#view/Microsoft_AAD_ConditionalAccess/PolicyBlade/policyId/3fe49849-5ab6-4717-a22d-aa42536eb560) (Disabled)\n - [test_21783](https://entra.microsoft.com/#view/Microsoft_AAD_ConditionalAccess/PolicyBlade/policyId/4028bb9f-c5f8-4035-9522-f0e3bdbacbcb)\n\n\n## Privileged roles\n\nFound 2 of 33 privileged built-in roles protected by phishing resistant authentication.\n\n| Role name | Phishing resistance enforced |\n| :--- | :---: |\n| Hybrid Identity Administrator | ✅ |\n| Security Administrator | ✅ |\n| Agent ID Administrator | ❌ |\n| AI Administrator | ❌ |\n| AI Reader | ❌ |\n| Application Administrator | ❌ |\n| Application Developer | ❌ |\n| Attribute Provisioning Administrator | ❌ |\n| Attribute Provisioning Reader | ❌ |\n| Authentication Administrator | ❌ |\n| Authentication Extensibility Administrator | ❌ |\n| Authentication Extensibility Password Administrator | ❌ |\n| B2C IEF Keyset Administrator | ❌ |\n| Cloud Application Administrator | ❌ |\n| Cloud Device Administrator | ❌ |\n| Conditional Access Administrator | ❌ |\n| Directory Writers | ❌ |\n| Domain Name Administrator | ❌ |\n| External Identity Provider Administrator | ❌ |\n| Global Administrator | ❌ |\n| Global Reader | ❌ |\n| Helpdesk Administrator | ❌ |\n| Identity Governance Administrator | ❌ |\n| Intune Administrator | ❌ |\n| Lifecycle Workflows Administrator | ❌ |\n| Partner Tier1 Support | ❌ |\n| Partner Tier2 Support | ❌ |\n| Password Administrator | ❌ |\n| Privileged Authentication Administrator | ❌ |\n| Privileged Role Administrator | ❌ |\n| Security Operator | ❌ |\n| Security Reader | ❌ |\n| User Administrator | ❌ |\n## Authentication strength policies\n\nFound 2 custom phishing resistant authentication strength policies.\n\n - [ACSC Maturity Level 3](https://entra.microsoft.com/#view/Microsoft_AAD_ConditionalAccess/ConditionalAccessBlade/~/AuthStrengths/fromNav/)\n - [Phishing-resistant MFA](https://entra.microsoft.com/#view/Microsoft_AAD_ConditionalAccess/ConditionalAccessBlade/~/AuthStrengths/fromNav/)\n\n\n","TestStatus":"Failed","TestDescription":"Without phishing-resistant authentication methods, privileged users are more vulnerable to phishing attacks. These types of attacks trick users into revealing their credentials to grant unauthorized access to attackers. If non-phishing-resistant authentication methods are used, attackers might intercept credentials and tokens, through methods like adversary-in-the-middle attacks, undermining the security of the privileged account.\n\nOnce a privileged account or session is compromised due to weak authentication methods, attackers might manipulate the account to maintain long-term access, create other backdoors, or modify user permissions. Attackers can also use the compromised privileged account to escalate their access even further, potentially gaining control over more sensitive systems.\n\n**Remediation action**\n\n- [Get started with a phishing-resistant passwordless authentication deployment](https://learn.microsoft.com/entra/identity/authentication/how-to-plan-prerequisites-phishing-resistant-passwordless-authentication?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci)\n- [Ensure that privileged accounts register and use phishing resistant methods](https://learn.microsoft.com/entra/identity/authentication/concept-authentication-strengths?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci#authentication-strengths)\n- [Deploy a Conditional Access policy to target privileged accounts and require phishing resistant credentials](https://learn.microsoft.com/entra/identity/conditional-access/policy-admin-phish-resistant-mfa?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci)\n- [Monitor authentication method activity](https://learn.microsoft.com/entra/identity/monitoring-health/concept-usage-insights-report?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci#authentication-methods-activity)\n","TestId":"21783"},{"TestImpact":"Low","TestRisk":"High","TestSkipped":"NotConnectedToService","TestAppliesTo":null,"TestPillar":"Data","TestCategory":"SharePoint Online","TestDescription":"When sensitivity label integration is disabled (the default) in SharePoint, files in SharePoint and OneDrive can't be labeled or display existing labels, and can't benefit from the additional protection of sensitivity labels that apply encryption. This protection gap leaves sensitive files unclassified and vulnerable to unauthorized access and external sharing.\n\nEnabling sensitivity labels in SharePoint allows users to apply labels by using Office for the web and SharePoint. It's also a requirement for default labeling for these locations, and for auto-labeling policies that can classify files automatically. Sensitivity labels for these files can also strengthen security for Microsoft 365 Copilot, and be used with data loss prevention policies and other Microsoft Purview solutions.\n\n**Remediation action**\n\n- [Enable sensitivity labels for files in SharePoint and OneDrive](https://learn.microsoft.com/purview/sensitivity-labels-sharepoint-onedrive-files?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci)\n","TestTitle":"Sensitivity labels are enabled for SharePoint and OneDrive","SkippedReason":"This test requires connection to the service(s) \"SharePointOnline\" currently disconnected. Please use _Connect-ZtAssessment_ to connect.","TestId":"35005","TestImplementationCost":"Low","TestMinimumLicense":["RMS_S_PREMIUM"],"TestSfiPillar":"Protect tenants and production systems","TestResult":"\nSkipped. This test requires connection to the service(s) \"SharePointOnline\" currently disconnected. Please use _Connect-ZtAssessment_ to connect.\n\n","TestStatus":"Skipped","TestTags":null},{"TestImplementationCost":"Low","TestPillar":"Identity","TestCategory":"Access control","SkippedReason":null,"TestImpact":"Low","TestAppliesTo":["Identity"],"TestSfiPillar":"Protect identities and secrets","TestSkipped":"","TestMinimumLicense":"P1","TestTags":["Identity"],"TestTitle":"Authentication transfer is blocked","TestRisk":"High","TestResult":"\nAuthentication transfer is blocked by Conditional Access Policy(s).\n## Conditional Access Policies targeting Authentication Transfer\n\n\n| Policy Name | Policy ID | State | Created | Modified |\n| :---------- | :-------- | :---- | :------ | :------- |\n| [Block Device Code](https://entra.microsoft.com/#view/Microsoft_AAD_ConditionalAccess/PolicyBlade/policyId/db2153a1-40a2-457f-917c-c280b204b5cd) | db2153a1-40a2-457f-917c-c280b204b5cd | enabled | 02/28/2024 00:22:50 | 2026-07-01 |\n\n\n\n","TestStatus":"Passed","TestDescription":"Blocking authentication transfer in Microsoft Entra ID is a critical security control. It helps protect against token theft and replay attacks by preventing the use of device tokens to silently authenticate on other devices or browsers. When authentication transfer is enabled, a threat actor who gains access to one device can access resources to nonapproved devices, bypassing standard authentication and device compliance checks. When administrators block this flow, organizations can ensure that each authentication request must originate from the original device, maintaining the integrity of the device compliance and user session context.\n\n**Remediation action**\n\n- [Deploy a Conditional Access policy to block authentication transfer](https://learn.microsoft.com/entra/identity/conditional-access/policy-block-authentication-flows?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci#authentication-transfer-policies)\n","TestId":"21828"},{"TestImplementationCost":"Low","TestPillar":"Identity","TestCategory":"Credential management","SkippedReason":null,"TestImpact":"Low","TestAppliesTo":null,"TestSfiPillar":"Protect identities and secrets","TestSkipped":"","TestMinimumLicense":"Free","TestTags":null,"TestTitle":"Security key attestation is enforced","TestRisk":"High","TestResult":"\nSecurity key attestation is not enforced, allowing unverified or potentially compromised security keys to be registered.\n## [Security key attestation policy details](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ConfigureAuthMethodsBlade/authMethod~/%7B%22%40odata.type%22%3A%22%23microsoft.graph.fido2AuthenticationMethodConfiguration%22%2C%22id%22%3A%22Fido2%22%2C%22state%22%3A%22enabled%22%2C%22isSelfServiceRegistrationAllowed%22%3Atrue%2C%22isAttestationEnforced%22%3Afalse%2C%22excludeTargets%22%3A%5B%7B%22id%22%3A%2243b7bc87-77eb-4263-abad-e3c2478f0a35%22%2C%22targetType%22%3A%22group%22%2C%22displayName%22%3A%22eam-block-user%22%7D%5D%2C%22keyRestrictions%22%3A%7B%22isEnforced%22%3Afalse%2C%22enforcementType%22%3A%22allow%22%2C%22aaGuids%22%3A%5B%22de1e552d-db1d-4423-a619-566b625cdc84%22%2C%2290a3ccdf-635c-4729-a248-9b709135078f%22%2C%2277010bd7-212a-4fc9-b236-d2ca5e9d4084%22%2C%22b6ede29c-3772-412c-8a78-539c1f4c62d2%22%2C%22ee041bce-25e5-4cdb-8f86-897fd6418464%22%2C%2273bb0cd4-e502-49b8-9c6f-b59445bf720b%22%5D%7D%2C%22includeTargets%40odata.context%22%3A%22https%3A%2F%2Fgraph.microsoft.com%2Fbeta%2F%24metadata%23policies%2FauthenticationMethodsPolicy%2FauthenticationMethodConfigurations('Fido2')%2Fmicrosoft.graph.fido2AuthenticationMethodConfiguration%2FincludeTargets%22%2C%22includeTargets%22%3A%5B%7B%22targetType%22%3A%22group%22%2C%22id%22%3A%22all_users%22%2C%22isRegistrationRequired%22%3Afalse%7D%5D%2C%22enabled%22%3Atrue%2C%22target%22%3A%22All%20users%2C%20excluding%201%20group%22%2C%22isAllUsers%22%3Atrue%2C%22voiceDisabled%22%3Afalse%7D/canModify~/true/voiceDisabled~/false/userMemberIds~/%5B%5D/userId/1ce4078f-f795-4baf-aa55-1fdfcc2ebfe6/isCiamTenant~/false/isCiamTrialTenant~/false)\n- **Enforce attestation** : False ❌\n- **Key restriction policy** :\n - **Enforce key restrictions** : False\n - **Restrict specific keys** : Allow\n - **AAGUID** :\n - de1e552d-db1d-4423-a619-566b625cdc84\n - 90a3ccdf-635c-4729-a248-9b709135078f\n - 77010bd7-212a-4fc9-b236-d2ca5e9d4084\n - b6ede29c-3772-412c-8a78-539c1f4c62d2\n - ee041bce-25e5-4cdb-8f86-897fd6418464\n - 73bb0cd4-e502-49b8-9c6f-b59445bf720b\n\n\n","TestStatus":"Failed","TestDescription":"When security key attestation isn't enforced, threat actors can exploit weak or compromised authentication hardware to establish persistent presence within organizational environments. Without attestation validation, malicious actors can register unauthorized or counterfeit FIDO2 security keys that bypass hardware-backed security controls, enabling them to perform credential stuffing attacks using fabricated authenticators that mimic legitimate security keys. This initial access lets threat actors escalate privileges by using the trusted nature of hardware authentication methods, then move laterally through the environment by registering more compromised security keys on high-privilege accounts. The lack of attestation enforcement creates a pathway for threat actors to establish command and control through persistent hardware-based authentication methods, ultimately leading to data exfiltration or system compromise while maintaining the appearance of legitimate hardware-secured authentication throughout the attack chain. \n\n**Remediation action**\n\n- [Enable attestation enforcement through the Authentication methods policy configuration](https://learn.microsoft.com/entra/identity/authentication/how-to-enable-passkey-fido2?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci#enable-passkey-fido2-authentication-method).\n- [Configure approved list of security keys by Authenticator Attestation Globally Unique Identifier (AAGUID)](https://learn.microsoft.com/entra/identity/authentication/concept-fido2-hardware-vendor?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci).\n","TestId":"21840"},{"TestImplementationCost":"Medium","TestPillar":"Devices","TestCategory":"Device","SkippedReason":null,"TestImpact":"Medium","TestAppliesTo":null,"TestSfiPillar":"Protect tenants and isolate production systems","TestSkipped":"","TestMinimumLicense":"Intune","TestTags":null,"TestTitle":"Windows Update policies are enforced to reduce risk from unpatched vulnerabilities","TestRisk":"High","TestResult":"\nWindows Update policy is assigned and enforced.\n\n\n| Policy Name | Status | Assignment |\n| :---------- | :------------- | :--------- |\n| [PROD](https://intune.microsoft.com/#view/Microsoft_Intune_DeviceSettings/DevicesWindowsMenu/~/windows10Update) | ✅ Assigned | **Included:** All Devices, **Excluded:** WFgroup |\n\n\n\n","TestStatus":"Passed","TestDescription":"If Windows Update policies aren't enforced across all corporate Windows devices, threat actors can exploit unpatched vulnerabilities to gain unauthorized access, escalate privileges, and move laterally within the environment. The attack chain often begins with device compromise via phishing, malware, or exploitation of known vulnerabilities, and is followed by attempts to bypass security controls. Without enforced update policies, attackers leverage outdated software to persist in the environment, increasing the risk of privilege escalation and domain-wide compromise.\n\nEnforcing Windows Update policies ensures timely patching of security flaws, disrupting attacker persistence, and reducing the risk of widespread compromise.\n\n**Remediation action**\n\nStart with [Manage Windows software updates in Intune](https://learn.microsoft.com/intune/device-updates/windows/configure?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci) to understand the available Windows Update policy types and how to configure them.\n\nIntune includes the following Windows update policy type: \n- [Windows quality updates policy](https://learn.microsoft.com/intune/device-updates/windows/quality-updates?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci) - *to install the regular monthly updates for Windows.*\n- [Expedite updates policy](https://learn.microsoft.com/intune/device-updates/windows/expedite-updates?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci) - *to quickly install critical security patches.*\n- [Feature updates policy](https://learn.microsoft.com/intune/device-updates/windows/feature-updates?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci)\n- [Update rings policy](https://learn.microsoft.com/intune/device-updates/windows/update-rings?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci) - *to manage how and when devices install feature and quality updates.*\n- [Windows driver updates](https://learn.microsoft.com/intune/device-updates/windows/driver-updates?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci) - *to update hardware components.*\n","TestId":"24553"},{"TestImplementationCost":"High","TestPillar":"Identity","TestCategory":"Access control","SkippedReason":"UnderConstruction","TestImpact":"Medium","TestAppliesTo":["Identity"],"TestSfiPillar":"Protect identities and secrets","TestSkipped":"UnderConstruction","TestMinimumLicense":null,"TestTags":["Identity"],"TestTitle":"All supported access lifecycle resources are managed with entitlement management packages","TestRisk":"Medium","TestResult":"\nPlanned for future release.\n","TestStatus":"Planned","TestDescription":"...\n\n**Remediation action**\n\n","TestId":"21898"},{"TestImplementationCost":"High","TestPillar":"Identity","TestCategory":"Access control","SkippedReason":"UnderConstruction","TestImpact":"Low","TestAppliesTo":["Identity"],"TestSfiPillar":"Protect identities and secrets","TestSkipped":"UnderConstruction","TestMinimumLicense":null,"TestTags":["Identity"],"TestTitle":"All risk detections are triaged","TestRisk":"High","TestResult":"\nPlanned for future release.\n","TestStatus":"Planned","TestDescription":"...\n\n**Remediation action**\n\n","TestId":"21864"},{"TestImplementationCost":"Low","TestPillar":"Devices","TestCategory":"Tenant","SkippedReason":null,"TestImpact":"Medium","TestAppliesTo":null,"TestSfiPillar":"Protect tenants and isolate production systems","TestSkipped":"","TestMinimumLicense":"Intune","TestTags":null,"TestTitle":"macOS Compliance Policy is Created and Assigned","TestRisk":"High","TestResult":"\nNo compliance policy for macOS exists or none are assigned.\n\n\n## macOS Compliance Policies\n\n| Policy Name | Status | Assignment Target |\n| :---------- | :----- | :---------------- |\n| [My macOS policy](https://intune.microsoft.com/#view/Microsoft_Intune_DeviceSettings/DevicesMenu/~/compliance) | ❌ Not assigned | None |\n\n\n\n","TestStatus":"Failed","TestDescription":"If compliance policies for macOS devices aren't configured and assigned, threat actors can exploit unmanaged or noncompliant endpoints to gain unauthorized access to corporate resources, bypass security controls, and persist within the environment. Without enforced compliance, macOS devices can lack critical security configurations like data storage encryption, password requirements, and OS version controls. These gaps increase the risk of data leakage, privilege escalation, and lateral movement. Inconsistent device compliance weakens the organization’s security posture and makes it harder to detect and remediate threats before significant damage occurs.\n\nEnforcing compliance policies ensures macOS devices meet core security requirements and supports Zero Trust by validating device health and reducing exposure to misconfigured endpoints.\n\n**Remediation actions**\n\nCreate and assign Intune compliance policies to macOS devices to enforce organizational standards for secure access and management: \n- [Create and assign Intune compliance policies](https://learn.microsoft.com/intune/intune-service/protect/create-compliance-policy?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci#create-the-policy)\n- [Review the macOS compliance settings you can manage with Intune](https://learn.microsoft.com/intune/intune-service/protect/compliance-policy-create-mac-os?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci)\n","TestId":"24542"},{"TestImplementationCost":"Medium","TestPillar":"Identity","TestCategory":"Application management","SkippedReason":null,"TestImpact":"Low","TestAppliesTo":null,"TestSfiPillar":"Monitor and detect cyberthreats","TestSkipped":"","TestMinimumLicense":"P1","TestTags":null,"TestTitle":"Enterprise applications with high privilege Microsoft Graph API permissions have owners","TestRisk":"High","TestResult":"\nNot all enterprise applications with high privilege permissions have owners\n\n## Applications lacking sufficient owners\n\n| App name | Multi-tenant | Permission | Classification | Owner count |\n| :-------- | :------------ | :---------- | :------------- | :----------- |\n| [idPowerToys - CI](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/Overview/objectId/b66231c2-9568-46f1-b61e-c5f8fd9edee4/appId/50827722-4f53-48ba-ae58-db63bb53626b) | True | Agreement.Read.All, CrossTenantInformation.ReadBasic.All, Directory.Read.All, offline_access, openid, Policy.Read.All, profile, User.Read | High | 0 |\n| [idPowerToys - Release](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/Overview/objectId/4654e05d-9f59-4925-807c-8eb2306e1cb1/appId/904e4864-f3c3-4d2f-ace2-c37a4ed55145) | True | Agreement.Read.All, CrossTenantInformation.ReadBasic.All, Directory.Read.All, offline_access, openid, Policy.Read.All, profile, User.Read | High | 0 |\n| [Azure AD Assessment](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/Overview/objectId/6c74be7f-bcc9-4541-bfe1-f113b90b0497/appId/68bc31c0-f891-4f4c-9309-c6104f7be41b) | False | Application.Read.All, AuditLog.Read.All, Directory.Read.All, Group.Read.All, offline_access, openid, Organization.Read.All, Policy.Read.All, profile, Reports.Read.All, RoleManagement.Read.Directory, SecurityEvents.Read.All, User.Read.All, UserAuthenticationMethod.Read.All | High | 0 |\n| [idPowerToys for Desktop](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/Overview/objectId/24cc58d8-2844-4974-b7cd-21c8a470e6bb/appId/520aa3af-bd78-4631-8f87-d48d356940ed) | True | Agreement.Read.All, CrossTenantInformation.ReadBasic.All, Directory.Read.All, offline_access, openid, Policy.Read.All, profile | High | 0 |\n| [entraChatAppMultiTenant](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/Overview/objectId/855a57ff-88a6-4ad0-85d7-4f46d742730e/appId/5e00b345-a805-42a0-9caa-7d6cb761c668) | True | APIConnectors.Read.All, Application.ReadWrite.All, AuditLog.Read.All, Directory.ReadWrite.All, EventListener.ReadWrite.All, Group.Read.All, IdentityUserFlow.Read.All, offline_access, openid, Policy.Read.All, Policy.ReadWrite.AuthenticationFlows, Policy.ReadWrite.AuthenticationMethod, Policy.ReadWrite.ConditionalAccess, Policy.ReadWrite.TrustFramework, profile, TrustFrameworkKeySet.Read.All, User.Read | High | 0 |\n| [Intune Documentation](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/Overview/objectId/97b66fb0-f682-41e0-9aef-47f170c2abae/appId/56066daa-baba-438f-89d0-7ea3be2e2222) | True | DeviceManagementApps.Read.All, DeviceManagementConfiguration.Read.All, DeviceManagementManagedDevices.Read.All, DeviceManagementRBAC.Read.All, DeviceManagementServiceConfig.Read.All, Group.Read.All, offline_access, openid, profile, User.Read | High | 0 |\n| [Automation](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/Overview/objectId/f79df990-9ad2-4142-b5fd-8945ff334da3/appId/dc7d83b5-d38b-4488-8952-7abf02e71590) | False | Directory.ReadWrite.All, User.Read | High | 1 |\n| [M365PronounKit](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/Overview/objectId/6bf7c616-88e8-4f7c-bdad-452e561fa777/appId/eea28244-3eec-4820-beae-d4a2c0bcc235) | False | User.ReadWrite.All | High | 0 |\n| [test public client](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/Overview/objectId/5e80ea33-31fa-49fd-9a94-61894bd1a6c9/appId/79a0c604-f215-4c52-8fbe-641d08aa7937) | False | User.Read.All | High | 0 |\n| [InfinityDemo](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/Overview/objectId/bac0ba57-1876-448e-96bf-6f0481c99fda/appId/fef811e1-2354-43b0-961b-248fe15e737d) | False | Directory.Read.All, User.Read | High | 0 |\n| [Lokka](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/Overview/objectId/1abc3899-a5df-40ab-8aa7-95d31edd4c01/appId/f581405a-9e57-4e81-91f1-40cd62f7595e) | False | DeviceManagementConfiguration.ReadWrite.All, Directory.ReadWrite.All, DirectoryRecommendations.Read.All, IdentityRiskEvent.Read.All, Mail.Read, Mail.Send, Policy.Read.All, Policy.ReadWrite.Authorization, Policy.ReadWrite.ConditionalAccess, PrivilegedAccess.Read.AzureAD, PrivilegedAccess.Read.AzureADGroup, Reports.Read.All, User.Read.All, UserAuthenticationMethod.Read.All | High | 0 |\n| [Maester DevOps Account - GitHub - Secret (demo)](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/Overview/objectId/e31cd01e-afaf-4cc3-8d15-d3f9f7eb61e8/appId/d0dc5f0a-bf75-41a4-9272-d5ec2345c963) | False | DeviceManagementConfiguration.Read.All, DeviceManagementManagedDevices.Read.All, Directory.Read.All, DirectoryRecommendations.Read.All, IdentityRiskEvent.Read.All, Mail.Send, Policy.Read.All, Policy.Read.ConditionalAccess, PrivilegedAccess.Read.AzureAD, Reports.Read.All, RoleEligibilitySchedule.Read.Directory, RoleManagement.Read.All, SecurityIdentitiesHealth.Read.All, SecurityIdentitiesSensors.Read.All, SharePointTenantSettings.Read.All, UserAuthenticationMethod.Read.All | High | 0 |\n| [MyTestForBlock](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/Overview/objectId/e9fca357-cccd-4ec4-840f-7482f6f02818/appId/14a3ba45-3246-4fbe-8c3b-c3922e68232b) | False | User.Read.All | High | 0 |\n| [PnPPowerShell](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/Overview/objectId/6d2e8d37-82b8-41e7-aa95-443a7401e8b8/appId/1d93462e-0f39-4e4c-898a-b6b1df5fa997) | False | Sites.FullControl.All, TermStore.Read.All, User.Read, User.Read.All, User.ReadWrite.All | High | 0 |\n| [Postman](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/Overview/objectId/aa64efdb-2d05-4c81-a9e5-80294bf0afac/appId/7fb37b38-ce4f-4675-9263-0cd3404b4925) | False | Directory.ReadWrite.All, Mail.ReadWrite, Policy.Read.All, User.Read | High | 0 |\n| [SharePoint Version App](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/Overview/objectId/666a58ef-c3e5-4efc-828a-2ab3c0120677/appId/2bb68591-782c-4c64-9415-bdf9414ae400) | False | Sites.Read.All, User.Read | High | 0 |\n| [Trello](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/Overview/objectId/3d6c91cf-d48f-4272-ac4c-9f989bbec779/appId/d77611ee-5051-4383-9af3-5ba3627306a7) | False | Application.Read.All | High | 0 |\n| [testuserread](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/Overview/objectId/89bd9c7a-0c81-4a0a-9153-ff7cd0b81352/appId/9fe2675c-7fc5-4895-8470-eed989ea0d63) | False | GroupMember.Read.All, User.Read.All | High | 0 |\n| [My Doc Gen](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/Overview/objectId/a445d652-f72d-4a88-9493-79d3c3c23d1b/appId/e580347d-d0aa-4aa1-9113-5daa0bb1c805) | False | Agreement.Read.All, CrossTenantInformation.ReadBasic.All, Directory.Read.All, offline_access, openid, Policy.Read.All, profile, User.Read | High | 0 |\n| [MyZt](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/Overview/objectId/716038b1-2811-40fc-8622-93e093890af0/appId/eee51d92-0bb5-4467-be6a-8f24ef677e4d) | False | Agreement.Read.All, CrossTenantInformation.ReadBasic.All, DeviceManagementApps.Read.All, DeviceManagementConfiguration.Read.All, DeviceManagementRBAC.Read.All, DeviceManagementServiceConfig.Read.All, Directory.Read.All, offline_access, openid, Policy.Read.All, PrivilegedEligibilitySchedule.Read.AzureADGroup, profile, RoleAssignmentSchedule.Read.Directory, RoleEligibilitySchedule.Read.Directory, User.Read | High | 0 |\n| [MyZtA\\[\\[](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/Overview/objectId/d2a2a09d-7562-45fc-a950-36fedfb790f8/appId/d159fcf5-a613-435b-8195-8add3cdf4bff) | False | Agreement.Read.All, CrossTenantInformation.ReadBasic.All, DeviceManagementApps.Read.All, DeviceManagementConfiguration.Read.All, DeviceManagementRBAC.Read.All, DeviceManagementServiceConfig.Read.All, Directory.Read.All, Policy.Read.All, PrivilegedEligibilitySchedule.Read.AzureADGroup, RoleAssignmentSchedule.Read.Directory, RoleEligibilitySchedule.Read.Directory, User.Read | High | 0 |\n| [Maester DevOps Account](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/Overview/objectId/d54232da-de3b-4874-aef2-5203dbd7342a/appId/d99dd249-6ab3-4e92-be40-81af11658359) | False | Directory.Read.All, DirectoryRecommendations.Read.All, IdentityRiskEvent.Read.All, Mail.Send, Policy.Read.All, PrivilegedAccess.Read.AzureAD, Reports.Read.All, User.Read | High | 0 |\n| [Graph PS - Zero Trust Workshop](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/Overview/objectId/f6e8dfdd-4c84-441f-ae6e-f2f51fd20699/appId/a9632ced-c276-4c2b-9288-3a34b755eaa9) | False | AuditLog.Read.All, CrossTenantInformation.ReadBasic.All, Directory.Read.All, DirectoryRecommendations.Read.All, IdentityRiskEvent.Read.All, offline_access, openid, Policy.Read.All, Policy.Read.ConditionalAccess, PrivilegedAccess.Read.AzureAD, profile, Reports.Read.All, RoleEligibilitySchedule.Read.Directory, RoleEligibilitySchedule.ReadWrite.Directory, RoleManagement.Read.All, UserAuthenticationMethod.Read.All | High | 0 |\n| [Maester DevOps Account - GitHub](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/Overview/objectId/ce3af345-b0e0-4b15-808c-937d825bcf03/appId/f050a85f-390b-4d43-85a0-2196b706bfd6) | False | DeviceManagementConfiguration.Read.All, DeviceManagementManagedDevices.Read.All, Directory.Read.All, DirectoryRecommendations.Read.All, IdentityRiskEvent.Read.All, Mail.Send, Policy.Read.All, Policy.Read.ConditionalAccess, PrivilegedAccess.Read.AzureAD, Reports.Read.All, RoleEligibilitySchedule.Read.Directory, RoleManagement.Read.All, SharePointTenantSettings.Read.All, UserAuthenticationMethod.Read.All | High | 0 |\n| [Maester DevOps Account - New GitHub Action](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/Overview/objectId/7c1885fd-fdf8-413a-86a6-f8867914272f/appId/143cb1b1-81af-4999-a292-a8c537601119) | False | DeviceManagementConfiguration.Read.All, DeviceManagementManagedDevices.Read.All, Directory.Read.All, DirectoryRecommendations.Read.All, IdentityRiskEvent.Read.All, Policy.Read.All, Policy.Read.ConditionalAccess, PrivilegedAccess.Read.AzureAD, Reports.Read.All, RoleEligibilitySchedule.Read.Directory, RoleEligibilitySchedule.ReadWrite.Directory, RoleManagement.Read.All, SharePointTenantSettings.Read.All, User.Read, UserAuthenticationMethod.Read.All | High | 0 |\n| [Maester Automation App](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/Overview/objectId/e3972142-1d36-4e7d-a777-ecd64619fcab/appId/55635484-743e-42e2-a78e-6bc15050ebde) | False | DeviceManagementConfiguration.Read.All, DeviceManagementManagedDevices.Read.All, Directory.Read.All, DirectoryRecommendations.Read.All, IdentityRiskEvent.Read.All, Mail.Send, Policy.Read.All, Policy.Read.ConditionalAccess, PrivilegedAccess.Read.AzureAD, Reports.Read.All, RoleEligibilitySchedule.Read.Directory, RoleEligibilitySchedule.ReadWrite.Directory, RoleManagement.Read.All, SharePointTenantSettings.Read.All, User.Read, UserAuthenticationMethod.Read.All | High | 0 |\n| [contoso-tenant-devops-7576c63d-bc90-4ae4-9f1c-0d959fb520db](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/Overview/objectId/c5632968-35cd-445d-926e-16e0afc9160e/appId/e876f7cb-13f3-48a4-8329-66d7b1fa33fb) | False | Directory.ReadWrite.All, Policy.ReadWrite.Authorization, Policy.ReadWrite.DeviceConfiguration | High | 0 |\n| [contoso-Maester-54d3ea01-5a07-45d0-8d69-e5f5b0b20098](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/Overview/objectId/4faa0456-5ecb-49f3-bb9a-2dbe516e939a/appId/a8c184ae-8ddf-41f3-8881-c090b43c385f) | False | Directory.Read.All, DirectoryRecommendations.Read.All, Mail.Send, Policy.Read.All, Reports.Read.All | High | 0 |\n| [contoso-maester-demo-39ecb2b6-d900-496e-886f-d112cca4f1a9](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/Overview/objectId/cc578aea-b1bd-434d-86d2-8a22c5728ded/appId/efec213e-0a85-4d7a-938f-3d97edd4ade0) | False | DeviceManagementConfiguration.Read.All, DeviceManagementManagedDevices.Read.All, Directory.Read.All, DirectoryRecommendations.Read.All, IdentityRiskEvent.Read.All, Policy.Read.All, Policy.Read.ConditionalAccess, PrivilegedAccess.Read.AzureAD, Reports.Read.All, ReportSettings.Read.All, RoleEligibilitySchedule.Read.Directory, RoleManagement.Read.All, SecurityIdentitiesHealth.Read.All, SecurityIdentitiesSensors.Read.All, SharePointTenantSettings.Read.All, ThreatHunting.Read.All, UserAuthenticationMethod.Read.All | High | 0 |\n| [Agent Identity Blueprint Example 4208296](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/Overview/objectId/c845b130-ce1b-4124-96ca-465df0eaa10f/appId/d0e3212f-58a2-4511-8b56-bd57b023106d) | False | AgentIdUser.ReadWrite.IdentityParentedBy, Calendars.Read, Mail.Read, User.Read | High | 0 |\n| [Agent Identity Blueprint Example 4209295](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/Overview/objectId/20aaa39b-821d-40a5-8d8a-eff27f86bb4a/appId/f522f080-5192-4665-87a4-e1211b7adca6) | False | AgentIdUser.ReadWrite.IdentityParentedBy, Files.Read, User.Read | High | 0 |\n| [testSP](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/Overview/objectId/2361fd8a-fe89-4d07-9199-c117feb52b5e/appId/e47d8f25-5327-40f8-99fe-d832b99d938d) | False | AuditLog.Read.All, CrossTenantInformation.ReadBasic.All, DeviceManagementConfiguration.Read.All, DeviceManagementManagedDevices.Read.All, DeviceManagementRBAC.Read.All, DeviceManagementServiceConfig.Read.All, Directory.Read.All, DirectoryRecommendations.Read.All, EntitlementManagement.Read.All, IdentityRiskEvent.Read.All, IdentityRiskyUser.Read.All, InformationProtectionPolicy.Read.All, LifecycleWorkflows-Reports.Read.All, NetworkAccess-Reports.Read.All, NetworkAccessPolicy.Read.All, Policy.Read.ConditionalAccess, Policy.Read.PermissionGrant, PrivilegedAccess.Read.AzureAD, RoleManagement.Read.All, UserAuthenticationMethod.Read.All | High | 0 |\n| [idPowerToys](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/Overview/objectId/ad36b6e2-273d-4652-a505-8481f096e513/appId/6ce0484b-2ae6-4458-b2b9-b3369f42fd6f) | True | Agreement.Read.All, CrossTenantInformation.ReadBasic.All, Directory.Read.All, offline_access, openid, Policy.Read.All, profile, User.Read | High | 0 |\n| [Zero Trust Assessment](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/Overview/objectId/3dde25cc-223f-4a16-8e8f-6695940b9680/appId/e7dfcbb6-fe86-44a2-b512-8d361dcc3d30) | True | Agreement.Read.All, CrossTenantInformation.ReadBasic.All, DeviceManagementApps.Read.All, DeviceManagementConfiguration.Read.All, DeviceManagementRBAC.Read.All, DeviceManagementServiceConfig.Read.All, Directory.Read.All, offline_access, openid, Policy.Read.All, PrivilegedEligibilitySchedule.Read.AzureADGroup, profile, RoleAssignmentSchedule.Read.Directory, RoleEligibilitySchedule.Read.Directory, User.Read | High | 0 |\n| [ZT-PermissionTest](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/Overview/objectId/b264ce7f-a584-49bf-8dd4-d2a3971e97b9/appId/be667b5a-b863-4698-9f60-868ef968b857) | False | AuditLog.Read.All, CrossTenantInformation.ReadBasic.All, DeviceManagementApps.Read.All, DeviceManagementConfiguration.Read.All, DeviceManagementManagedDevices.Read.All, DeviceManagementRBAC.Read.All, DeviceManagementServiceConfig.Read.All, Directory.Read.All, DirectoryRecommendations.Read.All, EntitlementManagement.Read.All, IdentityRiskEvent.Read.All, IdentityRiskyServicePrincipal.Read.All, IdentityRiskyUser.Read.All, NetworkAccess.Read.All, offline_access, openid, Policy.Read.All, Policy.Read.ConditionalAccess, Policy.Read.PermissionGrant, PrivilegedAccess.Read.AzureAD, profile, Reports.Read.All, RoleManagement.Read.All, User.Read, UserAuthenticationMethod.Read.All | High | 0 |\n| [ZeroTrustTest](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/Overview/objectId/d07c6af4-09f7-403f-bdeb-fb6be0d5e9fe/appId/3835a2fc-573d-4c4b-a4a3-993a1a156607) | False | AuditLog.Read.All, Content.DelegatedWriter, Content.SuperUser, CrossTenantInformation.ReadBasic.All, CustomSecAttributeAssignment.Read.All, DeviceManagementApps.Read.All, DeviceManagementConfiguration.Read.All, DeviceManagementManagedDevices.Read.All, DeviceManagementRBAC.Read.All, DeviceManagementServiceConfig.Read.All, Directory.Read.All, DirectoryRecommendations.Read.All, EntitlementManagement.Read.All, IdentityRiskEvent.Read.All, IdentityRiskyServicePrincipal.Read.All, IdentityRiskyUser.Read.All, NetworkAccess.Read.All, offline_access, openid, Policy.Read.All, Policy.Read.ConditionalAccess, Policy.Read.PermissionGrant, PrivilegedAccess.Read.AzureAD, profile, Reports.Read.All, RoleManagement.Read.All, User.Read, UserAuthenticationMethod.Read.All | High | 0 |\n| [test](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/Overview/objectId/35cbeecb-be21-4596-9869-0157d84f2d67/appId/c823a25d-fe94-494c-91f6-c7d51bf2df82) | False | Sites.FullControl.All, User.Read | High | 0 |\n| [Custom-App-Test](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/Overview/objectId/38415a71-b77b-44d5-a276-539faabe0de7/appId/ddb4f0e6-8018-4359-96c1-7473704bde43) | False | Application.Read.All, AuditLog.Read.All, CrossTenantInformation.ReadBasic.All, CustomSecAttributeAssignment.Read.All, DeviceManagementConfiguration.Read.All, DeviceManagementManagedDevices.Read.All, DeviceManagementRBAC.Read.All, DeviceManagementServiceConfig.Read.All, Directory.Read.All, DirectoryRecommendations.Read.All, EntitlementManagement.Read.All, IdentityRiskEvent.Read.All, IdentityRiskyServicePrincipal.Read.All, IdentityRiskyUser.Read.All, Policy.Read.All, Policy.Read.ConditionalAccess, Policy.Read.PermissionGrant, PrivilegedAccess.Read.AzureAD, RoleManagement.Read.All, User.Read, UserAuthenticationMethod.Read.All | High | 0 |\n| [Maester DevOps Account](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/Overview/objectId/7c32eaee-ff26-4435-be3d-b4ced08f9edc/appId/303774c1-3c6f-4dfd-8505-f24e82f9212a) | False | Directory.Read.All, DirectoryRecommendations.Read.All, IdentityRiskEvent.Read.All, Policy.Read.All, Policy.Read.ConditionalAccess, PrivilegedAccess.Read.AzureAD, Reports.Read.All, RoleEligibilitySchedule.Read.Directory, RoleEligibilitySchedule.ReadWrite.Directory, RoleManagement.Read.All, SharePointTenantSettings.Read.All, User.Read, UserAuthenticationMethod.Read.All | High | 0 |\n| [entra-docs-email github DO NOT DELETE](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/Overview/objectId/7a94aec7-a5e3-48dd-b20f-3db74d689434/appId/ae06b71a-a0aa-4211-b846-fd74f25ccd45) | False | Mail.Send, User.Read | High | 0 |\n| [Maester DevOps Account - manson/maester-demo](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/Overview/objectId/fdce906b-d2f6-4738-8c76-e4559b9e17e8/appId/91c84d77-3dce-4fb0-b0de-474a8606c812) | False | DeviceManagementConfiguration.Read.All, DeviceManagementManagedDevices.Read.All, Directory.Read.All, DirectoryRecommendations.Read.All, IdentityRiskEvent.Read.All, Policy.Read.All, Policy.Read.ConditionalAccess, PrivilegedAccess.Read.AzureAD, Reports.Read.All, ReportSettings.Read.All, RoleEligibilitySchedule.Read.Directory, RoleManagement.Read.All, SecurityIdentitiesHealth.Read.All, SecurityIdentitiesSensors.Read.All, SharePointTenantSettings.Read.All, ThreatHunting.Read.All, UserAuthenticationMethod.Read.All | High | 0 |\n| [GitHub Actions App for Microsoft Info script](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/Overview/objectId/852b4218-67d2-4046-a9a6-f8b47430ccdf/appId/38535360-9f3e-4b1e-a41e-b4af46afcb0c) | False | Application.Read.All | High | 0 |\n| [GraphPermissionApp](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/Overview/objectId/a15dc834-08ce-4fd8-85de-3729fff8e34f/appId/d36fe320-bc28-40c8-a141-a512d65d112c) | False | Application.Read.All, User.Read | High | 0 |\n| [Graph Explorer](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/Overview/objectId/8f8f300a-870a-46ff-bdab-934e1436920d/appId/d3ce4cf8-6810-442d-b42e-375e14710095) | True | Directory.AccessAsUser.All, User.Read | High | 0 |\n| [Azure AD Assessment (Test)](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/Overview/objectId/d4cf4286-0fbe-424d-b4f2-65aa2c568631/appId/c62a9fcb-53bf-446e-8063-ea6e2bfcc023) | False | AuditLog.Read.All, Directory.AccessAsUser.All, Directory.ReadWrite.All, Group.ReadWrite.All, IdentityProvider.ReadWrite.All, offline_access, openid, Policy.ReadWrite.TrustFramework, PrivilegedAccess.ReadWrite.AzureAD, PrivilegedAccess.ReadWrite.AzureResources, profile, TrustFrameworkKeySet.ReadWrite.All, User.Invite.All | High | 0 |\n| [Reset Viral Users Redemption Status](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/Overview/objectId/3a8785da-9965-473f-a97c-25fefdc39fee/appId/cc7b0696-1956-408b-876a-ad6bf2b9890b) | False | Directory.ReadWrite.All, offline_access, openid, profile, User.Invite.All, User.Read, User.ReadWrite.All | High | 0 |\n| [Windows Virtual Desktop AME](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/Overview/objectId/8369f33c-da25-4a8a-866d-b0145e29ef29/appId/5a0aa725-4958-4b0c-80a9-34562e23f3b7) | True | Directory.Read.All, User.Read.All | High | 0 |\n| [Microsoft Sample Data Packs](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/Overview/objectId/63e1f0d4-bc2c-497a-bfe2-9eb4c8c2600e/appId/a1cffbc6-1cb3-44e4-a1d2-cee9cce700f1) | False | Application.ReadWrite.OwnedBy, Calendars.ReadWrite, Calendars.ReadWrite.All, Contacts.ReadWrite, Directory.ReadWrite.All, Files.ReadWrite, Files.ReadWrite.All, Group.ReadWrite.All, Mail.ReadWrite, Mail.Send, MailboxSettings.ReadWrite, Sites.FullControl.All, Sites.Manage.All, Sites.ReadWrite.All, User.ReadWrite, User.ReadWrite.All | High | 0 |\n| [Modern Workplace Concierge](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/Overview/objectId/ad1c51e8-f8a8-4bf2-ac09-a3a20cba5fa5/appId/c65c4011-1b90-4ec9-b5e9-1ee17786ad84) | True | Application.Read.All, DeviceManagementApps.ReadWrite.All, DeviceManagementConfiguration.ReadWrite.All, DeviceManagementRBAC.ReadWrite.All, DeviceManagementServiceConfig.ReadWrite.All, Group.ReadWrite.All, openid, Policy.Read.All, Policy.ReadWrite.ConditionalAccess, profile, RoleManagement.Read.Directory, User.Read, User.ReadBasic.All | High | 0 |\n\n\n","TestStatus":"Failed","TestDescription":"Without owners, enterprise applications become orphaned assets that threat actors can exploit through credential harvesting and privilege escalation techniques. These applications often retain elevated permissions and access to sensitive resources while lacking proper oversight and security governance. The elevation of privilege to owners can raise a security concern, depending on the application's permissions. More critically, applications without an owner can create uncertainty in security monitoring where threat actors can establish persistence by using existing application permissions to access data or create backdoor accounts without triggering ownership-based detection mechanisms.\n\nWhen applications lack owners, security teams can't effectively conduct application lifecycle management. This gap leaves applications with potentially excessive permissions, outdated configurations, or compromised credentials that threat actors can discover through enumeration techniques and exploit to move laterally within the environment. The absence of ownership also prevents proper access reviews and permission audits, allowing threat actors to maintain long-term access through applications that should be decommissioned or had their permissions reduced. Not maintaining a clean application portfolio can provide persistent access vectors that can be used for data exfiltration or further compromise of the environment.\n\n**Remediation action**\n\n- [Assign owners to applications](https://learn.microsoft.com/entra/identity/enterprise-apps/assign-app-owners?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci)\n","TestId":"21867"},{"TestImplementationCost":"Medium","TestPillar":"Devices","TestCategory":"Device","SkippedReason":null,"TestImpact":"Medium","TestAppliesTo":null,"TestSfiPillar":"Protect identities and secrets","TestSkipped":"","TestMinimumLicense":"Intune","TestTags":null,"TestTitle":"Windows Hello for Business Policy is Configured and Assigned","TestRisk":"High","TestResult":"\nWindows Hello for Business policy is not assigned or not enforced.\n\n\n## Windows Hello for Business Policy is Configured and Assigned\n\nWindows Hello For Business ([Tenant Wide Setting](https://intune.microsoft.com/#view/Microsoft_Intune_DeviceSettings/DevicesEnrollmentMenu/~/windowsEnrollment) ): ❓ Not Configured.\n\n| Policy Name | Status | Assignment |\n| :---------- | :----- | :--------- |\n| [Windows Hello for Business](https://intune.microsoft.com/#view/Microsoft_Intune_DeviceSettings/DevicesMenu/~/configuration) | ❌ Not assigned | None |\n\n\n\n","TestStatus":"Failed","TestDescription":"If policies for Windows Hello for Business (WHfB) aren't configured and assigned to all users and devices, threat actors can exploit weak authentication mechanisms—like passwords—to gain unauthorized access. This can lead to credential theft, privilege escalation, and lateral movement within the environment. Without strong, policy-driven authentication like WHfB, attackers can compromise devices and accounts, increasing the risk of widespread impact.\n\nEnforcing WHfB disrupts this attack chain by requiring strong, multifactor authentication, which helps reduce the risk of credential-based attacks and unauthorized access.\n\n**Remediation action**\n\nDeploy Windows Hello for Business in Intune to enforce strong, multifactor authentication: \n- [Configure a tenant-wide Windows Hello for Business policy](https://learn.microsoft.com/intune/intune-service/protect/windows-hello?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci#create-a-windows-hello-for-business-policy-for-device-enrollment) that applies at the time a device enrolls with Intune.\n- After enrollment, [configure Account protection profiles](https://learn.microsoft.com/intune/intune-service/protect/endpoint-security-account-protection-policy?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci#account-protection-profiles) and [assign](https://learn.microsoft.com/intune/intune-service/configuration/device-profile-assign?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci#assign-a-policy-to-users-or-groups) different configurations for Windows Hello for Business to different groups of users and devices.\n","TestId":"24551"},{"TestImplementationCost":"","TestPillar":"Infrastructure","TestCategory":"Implement security best practices","SkippedReason":null,"TestImpact":"","TestAppliesTo":null,"TestSfiPillar":"Protect tenants and isolate production systems","TestSkipped":"","TestMinimumLicense":"N/A","TestTags":null,"TestTitle":"There should be more than one owner assigned to subscriptions","TestRisk":"High","TestResult":"There should be more than one owner assigned to subscriptions\n\n| Subscription | Affected resource | Status | Azure portal |\n| :----------- | :---------------- | :----- | :----------- |\n| [Visual Studio Enterprise Subscription](https://portal.azure.com/#resource/subscriptions/54d3ea01-5a07-45d0-8d69-e5f5b0b20098) | [54d3ea01-5a07-45d0-8d69-e5f5b0b20098](https://portal.azure.com/#resource/subscriptions/54d3ea01-5a07-45d0-8d69-e5f5b0b20098) | ✅ | [View recommendation](https://portal.azure.com/#blade/Microsoft_Azure_Security/RecommendationsBlade/assessmentKey/2c79b4af-f830-b61e-92b9-63dfa30f16e4/resourceId/%2fsubscriptions%2f54d3ea01-5a07-45d0-8d69-e5f5b0b20098) |\n","TestStatus":"Passed","TestDescription":"Designate more than one subscription owner in order to have administrator access redundancy.\n\n**Remediation action**\n\nTo add another account with owner permissions to your subscription:
Click a subscription from the list of subscriptions below or click 'Take action' if you are coming from a specific subscription.
The Access control (IAM) page opens.
1. Click 'Add' to open the Add role assignment pane.
If you don't have permissions to assign roles, the Add role assignment option will be disabled
1. In the 'Role' drop-down list, select the Owner role.
2. In the Select list, select a user.
3. Select 'Save'.","TestId":"2c79b4af-f830-b61e-92b9-63dfa30f16e4"},{"TestImplementationCost":"Low","TestPillar":"Identity","TestCategory":"External collaboration","SkippedReason":null,"TestImpact":"Medium","TestAppliesTo":null,"TestSfiPillar":"Protect tenants and isolate production systems","TestSkipped":"","TestMinimumLicense":"P1","TestTags":null,"TestTitle":"Guests don't have long lived sign-in sessions","TestRisk":"Medium","TestResult":"\nGuests do have long lived sign-in sessions.\n\n\n## Sign-in frequency policies\n\n| Policy name | Sign-in frequency | Status |\n| :---------- | :---------------- | :----- |\n| [MT-Test-MtCaMfaForGuest](https://entra.microsoft.com/#view/Microsoft_AAD_ConditionalAccess/PolicyBlade/policyId/a16cd40e-1fa7-4151-82f0-baca22b68ede) | Not configured | ❌ |\n\n\n\n","TestStatus":"Failed","TestDescription":"Guest accounts with extended sign-in sessions increase the risk surface area that threat actors can exploit. When guest sessions persist beyond necessary timeframes, threat actors often attempt to gain initial access through credential stuffing, password spraying, or social engineering attacks. Once they gain access, they can maintain unauthorized access for extended periods without reauthentication challenges. These compromised and extended sessions:\n\n- Allow unauthorized access to Microsoft Entra artifacts, enabling threat actors to identify sensitive resources and map organizational structures.\n- Allow threat actors to persist within the network by using legitimate authentication tokens, making detection more challenging as the activity appears as typical user behavior.\n- Provides threat actors with a longer window of time to escalate privileges through techniques like accessing shared resources, discovering more credentials, or exploiting trust relationships between systems.\n\nWithout proper session controls, threat actors can achieve lateral movement across the organization's infrastructure, accessing critical data and systems that extend far beyond the original guest account's intended scope of access. \n\n**Remediation action**\n- [Configure adaptive session lifetime policies](https://learn.microsoft.com/entra/identity/conditional-access/howto-conditional-access-session-lifetime?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci) so sign-in frequency policies have shorter live sign-in sessions.\n","TestId":"21824"},{"TestImplementationCost":"Medium","TestPillar":"Identity","TestCategory":"Privileged access","SkippedReason":null,"TestImpact":"Low","TestAppliesTo":["Identity"],"TestSfiPillar":"Protect identities and secrets","TestSkipped":"","TestMinimumLicense":"P1","TestTags":["Credential"],"TestTitle":"Privileged accounts have phishing-resistant methods registered","TestRisk":"High","TestResult":"\nFound privileged users that have not yet registered phishing resistant authentication methods\n\n## Privileged users\n\nFound privileged users that have not registered phishing resistant authentication methods.\n\nUser | Role Name | Phishing resistant method registered |\n| :--- | :--- | :---: |\n|[Hayden Scott Test](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/UserAuthMethods/userId/6f467d0a-25ec-435c-8fb9-9d53eb21e02f/hidePreviewBanner~/true)| SharePoint Administrator | ❌ |\n|[Hayden Scott Test](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/UserAuthMethods/userId/6f467d0a-25ec-435c-8fb9-9d53eb21e02f/hidePreviewBanner~/true)| Global Reader | ❌ |\n|[Hayden Scott Test](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/UserAuthMethods/userId/6f467d0a-25ec-435c-8fb9-9d53eb21e02f/hidePreviewBanner~/true)| Exchange Administrator | ❌ |\n|[Alex Johnson](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/UserAuthMethods/userId/e436ca15-3a39-4dcc-819e-7dbb246cd46b/hidePreviewBanner~/true)| Global Administrator | ❌ |\n|[Alex Johnson](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/UserAuthMethods/userId/e436ca15-3a39-4dcc-819e-7dbb246cd46b/hidePreviewBanner~/true)| Billing Administrator | ❌ |\n|[Alex Johnson](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/UserAuthMethods/userId/e436ca15-3a39-4dcc-819e-7dbb246cd46b/hidePreviewBanner~/true)| Application Administrator | ❌ |\n|[Hayden Scott](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/UserAuthMethods/userId/0d6cfd05-fc46-440b-b605-66dd26dcd7d2/hidePreviewBanner~/true)| Global Reader | ❌ |\n|[Hayden Scott](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/UserAuthMethods/userId/c0b65b13-37b1-4081-bcfc-14844159b4a5/hidePreviewBanner~/true)| Global Administrator | ❌ |\n|[Hayden Scott](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/UserAuthMethods/userId/c0b65b13-37b1-4081-bcfc-14844159b4a5/hidePreviewBanner~/true)| Compliance Administrator | ❌ |\n|[Jordan Smith](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/UserAuthMethods/userId/bfaeba1e-1357-47de-9557-529caa103d5d/hidePreviewBanner~/true)| Application Administrator | ❌ |\n|[Jordan Smith](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/UserAuthMethods/userId/bfaeba1e-1357-47de-9557-529caa103d5d/hidePreviewBanner~/true)| AI Administrator | ❌ |\n|[Jordan Smith](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/UserAuthMethods/userId/bfaeba1e-1357-47de-9557-529caa103d5d/hidePreviewBanner~/true)| Exchange Administrator | ❌ |\n|[Jordan Smith](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/UserAuthMethods/userId/bfaeba1e-1357-47de-9557-529caa103d5d/hidePreviewBanner~/true)| Global Administrator | ❌ |\n|[Taylor Brown](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/UserAuthMethods/userId/2072badc-3cf0-4e84-b4c2-f9c065c46165/hidePreviewBanner~/true)| Global Administrator | ❌ |\n|[Casey Davis](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/UserAuthMethods/userId/58d9ed99-93ca-4674-8c5f-ec770f5ba17d/hidePreviewBanner~/true)| Global Reader | ❌ |\n|[ash-williams-test](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/UserAuthMethods/userId/c5c8ba63-4620-4e91-ac40-b66bebe07a0d/hidePreviewBanner~/true)| Global Reader | ❌ |\n|[ash-williams-test](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/UserAuthMethods/userId/c5c8ba63-4620-4e91-ac40-b66bebe07a0d/hidePreviewBanner~/true)| SharePoint Administrator | ❌ |\n|[ash-williams-test](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/UserAuthMethods/userId/c5c8ba63-4620-4e91-ac40-b66bebe07a0d/hidePreviewBanner~/true)| Exchange Administrator | ❌ |\n|[Morgan Wilson](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/UserAuthMethods/userId/5655cf54-34bc-4f36-bb74-44da35547975/hidePreviewBanner~/true)| Global Administrator | ❌ |\n|[Riley Martinez](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/UserAuthMethods/userId/653c7fdd-1b41-4229-992a-69cc35aad4f7/hidePreviewBanner~/true)| Application Administrator | ❌ |\n|[Cameron Anderson](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/UserAuthMethods/userId/1ce4078f-f795-4baf-aa55-1fdfcc2ebfe6/hidePreviewBanner~/true)| Global Reader | ❌ |\n|[Cameron Anderson](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/UserAuthMethods/userId/1ce4078f-f795-4baf-aa55-1fdfcc2ebfe6/hidePreviewBanner~/true)| Compliance Administrator | ❌ |\n|[Cameron Anderson](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/UserAuthMethods/userId/1ce4078f-f795-4baf-aa55-1fdfcc2ebfe6/hidePreviewBanner~/true)| Global Administrator | ❌ |\n|[Cameron Anderson](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/UserAuthMethods/userId/1ce4078f-f795-4baf-aa55-1fdfcc2ebfe6/hidePreviewBanner~/true)| Azure AD Joined Device Local Administrator | ❌ |\n|[Cameron Anderson](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/UserAuthMethods/userId/1ce4078f-f795-4baf-aa55-1fdfcc2ebfe6/hidePreviewBanner~/true)| Purview Workload Content Administrator | ❌ |\n|[Cameron Anderson](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/UserAuthMethods/userId/1ce4078f-f795-4baf-aa55-1fdfcc2ebfe6/hidePreviewBanner~/true)| Security Administrator | ❌ |\n|[Avery Thomas](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/UserAuthMethods/userId/f431700c-6d81-45b8-8f8d-581a8aa7cda6/hidePreviewBanner~/true)| Global Administrator | ❌ |\n|[Jamie Rodriguez](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/UserAuthMethods/userId/0b37813c-ae19-4399-982f-16587f17f9c0/hidePreviewBanner~/true)| Global Administrator | ❌ |\n|[Dakota Lee](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/UserAuthMethods/userId/e4bc6f4a-124f-469b-8951-3d5c34fb9741/hidePreviewBanner~/true)| User Administrator | ❌ |\n|[Skylar White](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/UserAuthMethods/userId/2a054082-8f05-4e05-8fce-4e35c3bb40cc/hidePreviewBanner~/true)| Application Administrator | ❌ |\n|[Jules Bailey](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/UserAuthMethods/userId/0145d508-50fd-4f86-a47a-bf1c043c8358/hidePreviewBanner~/true)| Global Administrator | ❌ |\n|[peyton-test](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/UserAuthMethods/userId/e0952dcb-8d63-496d-8661-05c86c1a51f0/hidePreviewBanner~/true)| Exchange Administrator | ❌ |\n|[peyton-test](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/UserAuthMethods/userId/e0952dcb-8d63-496d-8661-05c86c1a51f0/hidePreviewBanner~/true)| Global Reader | ❌ |\n|[peyton-test](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/UserAuthMethods/userId/e0952dcb-8d63-496d-8661-05c86c1a51f0/hidePreviewBanner~/true)| SharePoint Administrator | ❌ |\n|[Peyton Clark](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/UserAuthMethods/userId/7e92f268-bb12-469a-a869-210d596d4c1f/hidePreviewBanner~/true)| Global Reader | ❌ |\n|[Peyton Clark](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/UserAuthMethods/userId/7e92f268-bb12-469a-a869-210d596d4c1f/hidePreviewBanner~/true)| Global Administrator | ❌ |\n|[Charlie Lewis](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/UserAuthMethods/userId/5b0ec3ff-cea1-4eb9-8530-f2a66e5bec0a/hidePreviewBanner~/true)| Global Administrator | ❌ |\n|[Finley Robinson](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/UserAuthMethods/userId/990fd38a-c516-4e3f-82e4-d458a1ab0f91/hidePreviewBanner~/true)| Global Administrator | ❌ |\n|[Finley Robinson](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/UserAuthMethods/userId/990fd38a-c516-4e3f-82e4-d458a1ab0f91/hidePreviewBanner~/true)| Global Reader | ❌ |\n|[finley-test](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/UserAuthMethods/userId/d71ccc09-c0a3-4604-9d02-49f7a3715f49/hidePreviewBanner~/true)| Exchange Administrator | ❌ |\n|[finley-test](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/UserAuthMethods/userId/d71ccc09-c0a3-4604-9d02-49f7a3715f49/hidePreviewBanner~/true)| SharePoint Administrator | ❌ |\n|[finley-test](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/UserAuthMethods/userId/d71ccc09-c0a3-4604-9d02-49f7a3715f49/hidePreviewBanner~/true)| Global Reader | ❌ |\n|[Sam Parker](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/UserAuthMethods/userId/96d29f01-873c-46a3-b542-f7ee192cc675/hidePreviewBanner~/true)| Application Administrator | ❌ |\n|[On-Premises Directory Synchronization Service Account](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/UserAuthMethods/userId/33956e9a-cb54-42e9-94e8-d8f6ba05a55f/hidePreviewBanner~/true)| Directory Synchronization Accounts | ❌ |\n|[parker-test](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/UserAuthMethods/userId/c1bdb03c-0079-40b1-96a8-3595de3b94a2/hidePreviewBanner~/true)| Global Reader | ❌ |\n|[Ellis Cooper](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/UserAuthMethods/userId/1433571b-3d7c-4a56-a9cc-67580848bc73/hidePreviewBanner~/true)| Global Administrator | ❌ |\n|[Sage Bennett](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/UserAuthMethods/userId/518ce209-faf4-4717-add9-7129a669fa11/hidePreviewBanner~/true)| Agent ID Administrator | ❌ |\n|[Sage Bennett](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/UserAuthMethods/userId/518ce209-faf4-4717-add9-7129a669fa11/hidePreviewBanner~/true)| Global Secure Access Log Reader | ❌ |\n|[Sage Bennett](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/UserAuthMethods/userId/518ce209-faf4-4717-add9-7129a669fa11/hidePreviewBanner~/true)| Agent Registry Administrator | ❌ |\n|[Sage Bennett](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/UserAuthMethods/userId/518ce209-faf4-4717-add9-7129a669fa11/hidePreviewBanner~/true)| Privileged Role Administrator | ❌ |\n|[Sage Bennett](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/UserAuthMethods/userId/518ce209-faf4-4717-add9-7129a669fa11/hidePreviewBanner~/true)| Attribute Log Administrator | ❌ |\n|[Sage Bennett](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/UserAuthMethods/userId/518ce209-faf4-4717-add9-7129a669fa11/hidePreviewBanner~/true)| Attribute Definition Administrator | ❌ |\n|[Sage Bennett](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/UserAuthMethods/userId/518ce209-faf4-4717-add9-7129a669fa11/hidePreviewBanner~/true)| Attribute Assignment Administrator | ❌ |\n|[Sage Bennett](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/UserAuthMethods/userId/518ce209-faf4-4717-add9-7129a669fa11/hidePreviewBanner~/true)| Global Administrator | ❌ |\n|[Sage Bennett](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/UserAuthMethods/userId/518ce209-faf4-4717-add9-7129a669fa11/hidePreviewBanner~/true)| Global Reader | ❌ |\n|[Dakota Lee](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/UserAuthMethods/userId/210d3e96-015f-462d-b6d6-81e6023263df/hidePreviewBanner~/true)| Compliance Administrator | ❌ |\n|[Dakota Lee](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/UserAuthMethods/userId/210d3e96-015f-462d-b6d6-81e6023263df/hidePreviewBanner~/true)| Global Administrator | ❌ |\n|[Dakota Lee Test](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/UserAuthMethods/userId/43482f27-d1af-420f-84ba-e9148a700f45/hidePreviewBanner~/true)| Compliance Administrator | ❌ |\n|[Dakota Lee Test](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/UserAuthMethods/userId/43482f27-d1af-420f-84ba-e9148a700f45/hidePreviewBanner~/true)| Global Administrator | ❌ |\n|[Phoenix Gray](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/UserAuthMethods/userId/7094fb23-003a-4f81-9796-5daeaa603003/hidePreviewBanner~/true)| Global Administrator | ❌ |\n|[Rowan Foster](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/UserAuthMethods/userId/7804b01c-1223-4045-a393-43171298fa6b/hidePreviewBanner~/true)| Yammer Administrator | ❌ |\n|[Avery Brooks](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/UserAuthMethods/userId/a85798bd-652b-4eb9-ba90-3ee882df0179/hidePreviewBanner~/true)| Global Administrator | ❌ |\n|[Alex Wilber](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/UserAuthMethods/userId/f10bc459-0bcf-49d0-8f86-4553b8f015b8/hidePreviewBanner~/true)| Billing Administrator | ✅ |\n|[Quinn Garcia](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/UserAuthMethods/userId/ceef37b7-c865-48fb-80c9-4def11201854/hidePreviewBanner~/true)| Global Administrator | ✅ |\n|[Reese Harris](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/UserAuthMethods/userId/babe04c9-8340-4329-a727-a8cee0cd2b1a/hidePreviewBanner~/true)| Global Administrator | ✅ |\n|[Ash Williams](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/UserAuthMethods/userId/513f3db2-044c-41be-af14-431bf88a2b3e/hidePreviewBanner~/true)| Global Administrator | ✅ |\n|[Ash Williams](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/UserAuthMethods/userId/513f3db2-044c-41be-af14-431bf88a2b3e/hidePreviewBanner~/true)| Attribute Definition Administrator | ✅ |\n|[Ash Williams](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/UserAuthMethods/userId/513f3db2-044c-41be-af14-431bf88a2b3e/hidePreviewBanner~/true)| Attribute Assignment Administrator | ✅ |\n|[Drew Mitchell](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/UserAuthMethods/userId/df02402a-e291-42cc-b449-79366daa2a40/hidePreviewBanner~/true)| Azure Information Protection Administrator | ✅ |\n|[Drew Mitchell](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/UserAuthMethods/userId/df02402a-e291-42cc-b449-79366daa2a40/hidePreviewBanner~/true)| Compliance Administrator | ✅ |\n|[Drew Mitchell](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/UserAuthMethods/userId/df02402a-e291-42cc-b449-79366daa2a40/hidePreviewBanner~/true)| Global Administrator | ✅ |\n|[Drew Mitchell](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/UserAuthMethods/userId/df02402a-e291-42cc-b449-79366daa2a40/hidePreviewBanner~/true)| Application Administrator | ✅ |\n|[Drew Mitchell](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/UserAuthMethods/userId/df02402a-e291-42cc-b449-79366daa2a40/hidePreviewBanner~/true)| Purview Workload Content Administrator | ✅ |\n|[Drew Mitchell](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/UserAuthMethods/userId/df02402a-e291-42cc-b449-79366daa2a40/hidePreviewBanner~/true)| Global Reader | ✅ |\n\n\n","TestStatus":"Failed","TestDescription":"Without phishing-resistant authentication methods, privileged users are more vulnerable to phishing attacks. These types of attacks trick users into revealing their credentials to grant unauthorized access to attackers. If non-phishing-resistant authentication methods are used, attackers might intercept credentials and tokens, through methods like adversary-in-the-middle attacks, undermining the security of the privileged account.\n\nOnce a privileged account or session is compromised due to weak authentication methods, attackers might manipulate the account to maintain long-term access, create other backdoors, or modify user permissions. Attackers can also use the compromised privileged account to escalate their access even further, potentially gaining control over more sensitive systems.\n\n**Remediation action**\n\n- [Get started with a phishing-resistant passwordless authentication deployment](https://learn.microsoft.com/entra/identity/authentication/how-to-plan-prerequisites-phishing-resistant-passwordless-authentication?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci)\n- [Ensure that privileged accounts register and use phishing resistant methods](https://learn.microsoft.com/entra/identity/authentication/concept-authentication-strengths?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci#authentication-strengths)\n- [Deploy a Conditional Access policy to target privileged accounts and require phishing resistant credentials](https://learn.microsoft.com/entra/identity/conditional-access/policy-admin-phish-resistant-mfa?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci)\n- [Monitor authentication method activity](https://learn.microsoft.com/entra/identity/monitoring-health/concept-usage-insights-report?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci#authentication-methods-activity)\n","TestId":"21782"},{"TestImplementationCost":"Medium","TestPillar":"Devices","TestCategory":"Tenant","SkippedReason":null,"TestImpact":"Medium","TestAppliesTo":null,"TestSfiPillar":"Protect tenants and isolate production systems","TestSkipped":"","TestMinimumLicense":"Intune","TestTags":null,"TestTitle":"macOS - Platform SSO is configured and assigned","TestRisk":"Medium","TestResult":"\nmacOS SSO policies are configured and assigned in Intune.\n\n\n## macOS SSO Policies\n\n| Policy Name | Status | Assignment Target |\n| :---------- | :----- | :---------------- |\n| [Platform SSO](https://intune.microsoft.com/#view/Microsoft_Intune_DeviceSettings/DevicesMenu/~/configuration) | ✅ Assigned | **Included:** All Users |\n\n\n\n","TestStatus":"Passed","TestDescription":"If Platform SSO policies aren't enforced on macOS devices, endpoints might rely on insecure or inconsistent authentication mechanisms, allowing attackers to bypass Conditional Access and compliance policies. This opens the door to lateral movement across cloud services and on-premises resources, especially when federated identities are used. Threat actors can persist by leveraging stolen tokens or cached credentials and exfiltrate sensitive data through unmanaged apps or browser sessions. The absence of SSO enforcement also undermines app protection policies and device posture assessments, making it difficult to detect and contain breaches. Ultimately, failure to configure and assign macOS Platform SSO policies compromises identity security and weakens the organization's Zero Trust posture.\n\nEnforcing Platform SSO policies on macOS devices ensures consistent, secure authentication across apps and services. This strengthens identity protection, supports Conditional Access enforcement, and aligns with Zero Trust by reducing reliance on local credentials and improving posture assessments.\n\n**Remediation action**\n\nUse Intune to configure and assign Platform SSO policies for macOS devices to enforce secure authentication and strengthen identity protection, see:\n\n- [Configure Platform SSO for macOS in Intune](https://learn.microsoft.com/intune/intune-service/configuration/platform-sso-macos?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci) – *Step-by-step guidance for enabling Platform SSO on macOS devices.*\n- [Single sign-on (SSO) overview and options for Apple devices in Microsoft Intune](https://learn.microsoft.com/intune/intune-service/configuration/use-enterprise-sso-plug-in-ios-ipados-macos?pivots=macos&wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci) – *Overview of SSO options available for Apple platforms.*\n","TestId":"24568"},{"TestImplementationCost":"Medium","TestPillar":"Identity","TestCategory":"Access control","SkippedReason":"UnderConstruction","TestImpact":"Medium","TestAppliesTo":["Identity"],"TestSfiPillar":"Protect identities and secrets","TestSkipped":"UnderConstruction","TestMinimumLicense":"P2","TestTags":["Identity"],"TestTitle":"Enable Microsoft Entra ID Protection policy to enforce multifactor authentication registration","TestRisk":"Low","TestResult":"\nPlanned for future release.\n\n","TestStatus":"Planned","TestDescription":"Require multifactor authentication (MFA) registration for all users. Based on studies, your account is more than 99% less likely to be compromised if you're using MFA. Even if you don't require MFA all the time, this policy ensures your users are ready when it's needed.\n\n**Remediation action**\n\n- [Configure the multifactor authentication registration policy](https://learn.microsoft.com/entra/id-protection/howto-identity-protection-configure-mfa-policy?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci)\n","TestId":"21893"},{"TestImplementationCost":"","TestPillar":"Infrastructure","TestCategory":"Restrict unauthorized network access","SkippedReason":null,"TestImpact":"","TestAppliesTo":null,"TestSfiPillar":"Protect tenants and isolate production systems","TestSkipped":"","TestMinimumLicense":"N/A","TestTags":null,"TestTitle":"IP forwarding on your virtual machine should be disabled","TestRisk":"Medium","TestResult":"IP forwarding on your virtual machine should be disabled\n\n| Subscription | Resource group | Resource type | Affected resource | Status | Azure portal |\n| :----------- | :------------- | :------------ | :---------------- | :----- | :----------- |\n| [Visual Studio Enterprise Subscription](https://portal.azure.com/#resource/subscriptions/54d3ea01-5a07-45d0-8d69-e5f5b0b20098) | indiavm_group | virtualmachines | [india-2](https://portal.azure.com/#resource/subscriptions/54d3ea01-5a07-45d0-8d69-e5f5b0b20098/resourceGroups/INDIAVM_GROUP/providers/Microsoft.Compute/virtualMachines/india-2) | ✅ | [View recommendation](https://portal.azure.com/#blade/Microsoft_Azure_Security/RecommendationsBlade/assessmentKey/c3b51c94-588b-426b-a892-24696f9e54cc/resourceId/%2fsubscriptions%2f54d3ea01-5a07-45d0-8d69-e5f5b0b20098%2fresourceGroups%2fINDIAVM_GROUP%2fproviders%2fMicrosoft.Compute%2fvirtualMachines%2findia-2) |\n| [Visual Studio Enterprise Subscription](https://portal.azure.com/#resource/subscriptions/54d3ea01-5a07-45d0-8d69-e5f5b0b20098) | indiavm_group | virtualmachines | [indiavm](https://portal.azure.com/#resource/subscriptions/54d3ea01-5a07-45d0-8d69-e5f5b0b20098/resourceGroups/INDIAVM_GROUP/providers/Microsoft.Compute/virtualMachines/indiavm) | ✅ | [View recommendation](https://portal.azure.com/#blade/Microsoft_Azure_Security/RecommendationsBlade/assessmentKey/c3b51c94-588b-426b-a892-24696f9e54cc/resourceId/%2fsubscriptions%2f54d3ea01-5a07-45d0-8d69-e5f5b0b20098%2fresourceGroups%2fINDIAVM_GROUP%2fproviders%2fMicrosoft.Compute%2fvirtualMachines%2findiavm) |\n","TestStatus":"Passed","TestDescription":"Defender for Cloud has discovered that IP forwarding is enabled on some of your virtual machines. Enabling IP forwarding on a virtual machine's NIC allows the machine to receive traffic addressed to other destinations. IP forwarding is rarely required (e.g., when using the VM as a network virtual appliance), and therefore, this should be reviewed by the network security team.\n\n**Remediation action**\n\nWe recommend you edit the IP configurations of the NICs belonging to some of your virtual machines.
To disable IP forwarding:
1. Select a VM from the list below, or click 'Take action' if you've arrived from a specific VM's recommendation blade.
2. In the 'Networking' blade, click on the NIC link ('Network Interface' in the top left).
3. In the 'IP configurations' blade, set the 'IP forwarding' field to 'Disabled'.
4. Click 'Save'.","TestId":"c3b51c94-588b-426b-a892-24696f9e54cc"},{"TestImplementationCost":"Low","TestPillar":"Identity","TestCategory":"Access control","SkippedReason":"UnderConstruction","TestImpact":"Low","TestAppliesTo":["Identity"],"TestSfiPillar":"Protect identities and secrets","TestSkipped":"UnderConstruction","TestMinimumLicense":null,"TestTags":["Identity"],"TestTitle":"No Active low priority Entra recommendations found","TestRisk":"Low","TestResult":"\nPlanned for future release.\n","TestStatus":"Planned","TestDescription":"...\n\n**Remediation action**\n\n","TestId":"21984"},{"TestImplementationCost":"","TestPillar":"Infrastructure","TestCategory":"Remediate vulnerabilities","SkippedReason":null,"TestImpact":"","TestAppliesTo":null,"TestSfiPillar":"Protect tenants and isolate production systems","TestSkipped":"","TestMinimumLicense":"N/A","TestTags":null,"TestTitle":"Machines should have a vulnerability assessment solution","TestRisk":"Medium","TestResult":"Machines should have a vulnerability assessment solution\n\n| Subscription | Resource group | Resource type | Affected resource | Status | Azure portal |\n| :----------- | :------------- | :------------ | :---------------- | :----- | :----------- |\n| [Visual Studio Enterprise Subscription](https://portal.azure.com/#resource/subscriptions/54d3ea01-5a07-45d0-8d69-e5f5b0b20098) | indiavm_group | virtualmachines | [india-2](https://portal.azure.com/#resource/subscriptions/54d3ea01-5a07-45d0-8d69-e5f5b0b20098/resourceGroups/INDIAVM_GROUP/providers/Microsoft.Compute/virtualMachines/india-2) | ❌ | [View recommendation](https://portal.azure.com/#blade/Microsoft_Azure_Security/RecommendationsBlade/assessmentKey/ffff0522-1e88-47fc-8382-2a80ba848f5d/resourceId/%2fsubscriptions%2f54d3ea01-5a07-45d0-8d69-e5f5b0b20098%2fresourceGroups%2fINDIAVM_GROUP%2fproviders%2fMicrosoft.Compute%2fvirtualMachines%2findia-2) |\n| [Visual Studio Enterprise Subscription](https://portal.azure.com/#resource/subscriptions/54d3ea01-5a07-45d0-8d69-e5f5b0b20098) | indiavm_group | virtualmachines | [indiavm](https://portal.azure.com/#resource/subscriptions/54d3ea01-5a07-45d0-8d69-e5f5b0b20098/resourceGroups/INDIAVM_GROUP/providers/Microsoft.Compute/virtualMachines/indiavm) | N/A | [View recommendation](https://portal.azure.com/#blade/Microsoft_Azure_Security/RecommendationsBlade/assessmentKey/ffff0522-1e88-47fc-8382-2a80ba848f5d/resourceId/%2fsubscriptions%2f54d3ea01-5a07-45d0-8d69-e5f5b0b20098%2fresourceGroups%2fINDIAVM_GROUP%2fproviders%2fMicrosoft.Compute%2fvirtualMachines%2findiavm) |\n","TestStatus":"Failed","TestDescription":"Defender for Cloud regularly checks your connected machines to ensure they're running vulnerability assessment tools. Use this recommendation to deploy a vulnerability assessment solution.\n\n**Remediation action**\n\nTo deploy a vulnerability assessment solution, in the \"Unhealthy resources\" tab, select the resources, then select \"Remediate\". Read the remediation details in the confirmation box, insert the relevant parameters if required and approve the remediation. Note: It can take several hours after remediation completes to see the resources in the 'Healthy resources' tab","TestId":"ffff0522-1e88-47fc-8382-2a80ba848f5d"},{"TestImplementationCost":"Medium","TestPillar":"Identity","TestCategory":"Credential management","SkippedReason":"UnderConstruction","TestImpact":"Medium","TestAppliesTo":["Identity"],"TestSfiPillar":"Protect identities and secrets","TestSkipped":"UnderConstruction","TestMinimumLicense":"P1","TestTags":["Identity"],"TestTitle":"Turn off Seamless SSO if there are is no usage","TestRisk":"Medium","TestResult":"\nPlanned for future release.\n\n","TestStatus":"Planned","TestDescription":"Microsoft Entra seamless single sign-on (Seamless SSO) is a legacy authentication feature designed to provide passwordless access for domain-joined devices that are not hybrid Microsoft Entra ID joined. Seamless SSO relies on Kerberos authentication and is primarily beneficial for older operating systems like Windows 7 and Windows 8.1, which do not support Primary Refresh Tokens (PRT). If these legacy systems are no longer present in the environment, continuing to use Seamless SSO introduces unnecessary complexity and potential security exposure. Threat actors could exploit misconfigured or stale Kerberos tickets, or compromise the `AZUREADSSOACC` computer account in Active Directory, which holds the Kerberos decryption key used by Microsoft Entra ID. Once compromised, attackers could impersonate users, bypass modern authentication controls, and gain unauthorized access to cloud resources. Disabling Seamless SSO in environments where it is no longer needed reduces the attack surface and enforces the use of modern, token-based authentication mechanisms that offer stronger protections. \n\n**Remediation action**\n\n- [Review how Seamless SSO works](https://learn.microsoft.com/entra/identity/hybrid/connect/how-to-connect-sso-how-it-works?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci)\n- [Disable Seamless SSO](https://learn.microsoft.com/entra/identity/hybrid/connect/how-to-connect-sso-faq?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci#how-can-i-disable-seamless-sso-)\n- [Clean up stale devices in Microsoft Entra ID](https://learn.microsoft.com/entra/identity/devices/manage-stale-devices?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci)\n","TestId":"21985"},{"TestImpact":"Medium","TestRisk":"Medium","TestSkipped":"","TestAppliesTo":null,"TestPillar":"Data","TestCategory":"Information Protection","TestDescription":"Without mail flow rules, organizations depend on users to manually apply sensitivity labels or encrypt messages. This approach can lead to inconsistencies and errors, which may result in sensitive emails being sent without proper protection and increase the risk of unauthorized access and data exfiltration.\n\nMail flow rules help automatically add encryption and set permissions for emails that meet certain conditions, such as:\n- Mail sent to people outside the company \n- Mail that contains sensitive information \n- Mail that must follow department-based requirements \nThis ensures that important messages are protected without relying on users to manually secure them.\n\n**Remediation action**\n\n- [Set up Message Encryption and mail flow rules to use Microsoft Purview Message Encryption](https://learn.microsoft.com/purview/set-up-new-message-encryption-capabilities?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci#next-steps-define-mail-flow-rules-to-use-microsoft-purview-message-encryption)\n","TestTitle":"Mail flow rules with rights protection","SkippedReason":null,"TestId":"35029","TestImplementationCost":"Medium","TestMinimumLicense":["RMS_S_PREMIUM2"],"TestSfiPillar":"Protect tenants and production systems","TestResult":"\n✅ Mail flow rules with rights protection are configured, automatically protecting sensitive emails through encryption and restriction policies.\n\n### [Protection rules configuration](https://admin.exchange.microsoft.com/#/transportrules)\n\n| Rule name | State | Priority | OME | RMS template | Classification | Last modified |\n| :--- | :--- | :--- | :--- | :--- | :--- | :--- |\n| [powershell_test](https://admin.exchange.microsoft.com/#/transportrules) | ✅ Enabled | 0 | No | Encrypt | N/A | 2026-02-09 |\n| [Encrypt mail for sky@contoso.com](https://admin.exchange.microsoft.com/#/transportrules) | ✅ Enabled | 1 | No | Encrypt | N/A | 2026-02-09 |\n\n### Rules by action type\n\n| Action type | Count |\n| :--- | :--- |\n| OME encryption rules | 0 |\n| RMS template application | 2 |\n| Classification rules | 0 |\n\n### Summary\n\n| Metric | Count |\n| :--- | :--- |\n| Total protection rules | 2 |\n| Enabled rules | 2 |\n| Disabled rules | 0 |\n| External email protection | ✅ Yes |\n\n","TestStatus":"Passed","TestTags":null},{"TestImplementationCost":"Low","TestPillar":"Identity","TestCategory":"Devices","SkippedReason":null,"TestImpact":"Medium","TestAppliesTo":null,"TestSfiPillar":"Protect engineering systems","TestSkipped":"","TestMinimumLicense":"Free","TestTags":null,"TestTitle":"Limit the maximum number of devices per user to 10","TestRisk":"High","TestResult":"\n[Maximum number of devices per user](https://entra.microsoft.com/#view/Microsoft_AAD_Devices/DevicesMenuBlade/~/DeviceSettings/menuId/Overview) is set to 10\n\n","TestStatus":"Passed","TestDescription":"Controlling device proliferation is important. Set a reasonable limit on the number of devices each user can register in your Microsoft Entra ID tenant. Limiting device registration maintains security while allowing business flexibility. Microsoft Entra ID lets users register up to 50 devices by default. Reducing this number to 10 minimizes the attack surface and simplifies device management.\n\n**Remediation action**\n\n- Learn how to [limit the maximum number of devices per user](https://learn.microsoft.com/entra/identity/devices/manage-device-identities?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci#configure-device-settings).\n","TestId":"21837"},{"TestImplementationCost":"Medium","TestPillar":"Identity","TestCategory":"Access control","SkippedReason":null,"TestImpact":"Medium","TestAppliesTo":["Identity"],"TestSfiPillar":"Accelerate response and remediation","TestSkipped":"","TestMinimumLicense":"P2","TestTags":["Identity"],"TestTitle":"Block high risk sign-ins","TestRisk":"High","TestResult":"\nSome high-risk sign-in attempts are not adequately mitigated by Conditional Access policies.\n\n","TestStatus":"Failed","TestDescription":"When high-risk sign-ins are not properly restricted through Conditional Access policies, organizations expose themselves to security vulnerabilities. Threat actors can exploit these gaps for initial access through compromised credentials, credential stuffing attacks, or anomalous sign-in patterns that Microsoft Entra ID Protection identifies as risky behaviors. Without appropriate restrictions, threat actors who successfully authenticate during high-risk scenarios can perform privilege escalation by misusing the authenticated session to access sensitive resources, modify security configurations, or conduct reconnaissance activities within the environment. Once threat actors establish access through uncontrolled high-risk sign-ins, they can achieve persistence by creating additional accounts, installing backdoors, or modifying authentication policies to maintain long-term access to the organization's resources. The unrestricted access enables threat actors to conduct lateral movement across systems and applications using the authenticated session, potentially accessing sensitive data stores, administrative interfaces, or critical business applications. Finally, threat actors achieve impact through data exfiltration, or compromise business-critical systems while maintaining plausible deniability by exploiting the fact that their risky authentication was not properly challenged or blocked.\n\n**Remediation action**\n\n- [Deploy a Conditional Access policy to require MFA for elevated sign-in risk](https://learn.microsoft.com/entra/identity/conditional-access/policy-risk-based-sign-in?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci)\n","TestId":"21799"},{"TestImplementationCost":"High","TestPillar":"Identity","TestCategory":"Monitoring","SkippedReason":"This test is for tenants that are licensed for Entra Workload ID. See [Entra Workload ID licensing](https://learn.microsoft.com/entra/workload-id/workload-identities-faqs)","TestImpact":"Low","TestAppliesTo":null,"TestSfiPillar":"Monitor and detect cyberthreats","TestSkipped":"NotLicensedEntraWorkloadID","TestMinimumLicense":"P2","TestTags":null,"TestTitle":"All risky workload identities are triaged","TestRisk":"High","TestResult":"\nSkipped. This test is for tenants that are licensed for Entra Workload ID. See [Entra Workload ID licensing](https://learn.microsoft.com/entra/workload-id/workload-identities-faqs)\n\n","TestStatus":"Skipped","TestDescription":"Compromised workload identities (service principals and applications) allow threat actors to gain persistent access without user interaction or multifactor authentication. Microsoft Entra ID Protection monitors these identities for suspicious activities like leaked credentials, anomalous API traffic, and malicious applications. Unaddressed risky workload identities enable privilege escalation, lateral movement, data exfiltration, and persistent backdoors that bypass traditional security controls. Organizations must systematically investigate and remediate these risks to prevent unauthorized access. \n\n**Remediation action**\n\n- [Investigate and remediate risky workload identities](https://learn.microsoft.com/entra/id-protection/concept-workload-identity-risk?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci#investigate-risky-workload-identities)\n- [Apply Conditional Access policies for workload identities](https://learn.microsoft.com/entra/identity/conditional-access/workload-identity?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci)\n","TestId":21862},{"TestImplementationCost":"Low","TestPillar":"Devices","TestCategory":"Device","SkippedReason":null,"TestImpact":"Low","TestAppliesTo":null,"TestSfiPillar":"Protect identities and secrets","TestSkipped":"","TestMinimumLicense":"Intune","TestTags":null,"TestTitle":"Intune Local Users and Groups policy is created and assigned","TestRisk":"High","TestResult":"\nNo Local Users and Groups policy is configured or assigned.\n\n\n\n","TestStatus":"Failed","TestDescription":"Without a properly configured and assigned Local Users and Groups policy in Intune, threat actors can exploit unmanaged or misconfigured local accounts on Windows devices. This can lead to unauthorized privilege escalation, persistence, and lateral movement within the environment. If local administrator accounts aren't controlled, attackers can create hidden accounts or elevate privileges, bypassing compliance and security controls. This gap increases the risk of data exfiltration, ransomware deployment, and regulatory noncompliance.\n\nEnsuring that Local Users and Groups policies are enforced on managed Windows devices, by using account protection profiles, is critical to maintaining a secure and compliant device fleet.\n\n\n**Remediation action**\n\nConfigure and deploy a **Local user group membership** profile from Intune account protection policy to restrict and manage local account usage on Windows devices: \n- Create an [Account protection policy for endpoint security in Intune](https://learn.microsoft.com/intune/intune-service/protect/endpoint-security-account-protection-policy?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci#account-protection-profiles)\n- [Assign policies in Intune](https://learn.microsoft.com/intune/intune-service/configuration/device-profile-assign?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci#assign-a-policy-to-users-or-groups)\n","TestId":"24564"},{"TestImplementationCost":"Low","TestPillar":"Identity","TestCategory":"Access control","SkippedReason":null,"TestImpact":"Low","TestAppliesTo":null,"TestSfiPillar":"Protect identities and secrets","TestSkipped":"","TestMinimumLicense":"P1","TestTags":null,"TestTitle":"Microsoft Authenticator app shows sign-in context","TestRisk":"Medium","TestResult":"\nMicrosoft Authenticator shows application name and geographic location in push notifications.\n\n\n## Microsoft Authenticator settings\n\n\nFeature Settings:\n\n✅ **Application Name**\n- Status: Enabled\n- Include Target: All users\n- Exclude Target: No exclusions\n\n✅ **Geographic Location**\n- Status: Enabled\n- Include Target: All users\n- Exclude Target: No exclusions\n\n\n","TestStatus":"Passed","TestDescription":"Without sign-in context, threat actors can exploit authentication fatigue by flooding users with push notifications, increasing the chance that a user accidentally approves a malicious request. When users get generic push notifications without the application name or geographic location, they don't have the information they need to make informed approval decisions. This lack of context makes users vulnerable to social engineering attacks, especially when threat actors time their requests during periods of legitimate user activity. This vulnerability is especially dangerous when threat actors gain initial access through credential harvesting or password spraying attacks and then try to establish persistence by approving multifactor authentication (MFA) requests from unexpected applications or locations. Without contextual information, users can't detect unusual sign-in attempts, allowing threat actors to maintain access and escalate privileges by moving laterally through systems after bypassing the initial authentication barrier. Without application and location context, security teams also lose valuable telemetry for detecting suspicious authentication patterns that can indicate ongoing compromise or reconnaissance activities. \n\n**Remediation action**\nGive users the context they need to make informed approval decisions. Configure Microsoft Authenticator notifications by setting the Authentication methods policy to include the application name and geographic location. \n- [Use additional context in Authenticator notifications - Authentication methods policy](https://learn.microsoft.com/entra/identity/authentication/how-to-mfa-additional-context?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci)\n","TestId":"21802"},{"TestImplementationCost":"Medium","TestPillar":"Identity","TestCategory":"Application management","SkippedReason":null,"TestImpact":"Low","TestAppliesTo":["Identity"],"TestSfiPillar":"Protect identities and secrets","TestSkipped":"","TestMinimumLicense":"Free","TestTags":["Identity"],"TestTitle":"Service principals don't have certificates or credentials associated with them","TestRisk":"Medium","TestResult":"\nFound Service Principals with credentials configured in the tenant, which represents a security risk.\n\n\n## Service Principals with credentials configured in the tenant\n\n\n| Service Principal Name | Credentials Type | Credentials Expiration Date | Expiry Status |\n| :--------------------- | :--------------- | :-------------------------- | :------------ |\n| [21869testapp](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/Overview/objectId/e69e29be-ba40-445a-9824-a3a45e0ae57a/appId/dd63d132-18fb-4f2e-aec4-82b97f30301f) | Password Credentials | 2028-10-27 | ✅ Current |\n| [APP-2732_Genesys Cloud TCCC-G-TFS-Prod](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/Overview/objectId/ba63bb52-182c-4ec6-9cc8-ad2287cf51ed/appId/76249b01-8747-4db4-843f-6478d5b32b14) | Password Credentials | 2028-07-30 | ✅ Current |\n| [AWS Single-Account Access](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/Overview/objectId/dc89bf5d-83e8-4419-9162-3b9280a85755/appId/091edd89-b342-4bb5-9144-82fe6c913987) | Password Credentials | 2025-10-26 | ❗ Expired |\n| [Automation](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/Overview/objectId/f79df990-9ad2-4142-b5fd-8945ff334da3/appId/dc7d83b5-d38b-4488-8952-7abf02e71590) | Password Credentials | 2027-03-03 | ✅ Current |\n| [Azure AD SAML Toolkit](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/Overview/objectId/4317fd0a-dcee-45bf-8e94-9a66638b11e0/appId/6f5ed68c-9fad-4d78-bf88-2b16bbe16338) | Password Credentials | 2028-10-11 | ✅ Current |\n| [Dropbox Business](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/Overview/objectId/5eec0e98-b81a-422a-ab61-f8de2729330d/appId/f76d7d98-02ee-4e62-9345-36016a72e664) | Password Credentials | 2024-02-17 | ❗ Expired |\n| [charlie AWS Account](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/Overview/objectId/39861745-eda1-4e3c-8358-d0ba931f12bb/appId/d3a04f85-a969-436b-bf4d-eae0a91efb4c) | Password Credentials | 2028-01-07 | ✅ Current |\n| [charlie- Genesys Cloud for Azure](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/Overview/objectId/84dc13ec-5754-4745-90f9-5cc92a5ded28/appId/9c599cd2-9fb0-4815-b65c-83be33f5df1b) | Password Credentials | 2028-07-30 | ✅ Current |\n| [P2P Server](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/Overview/objectId/05c98ca9-d208-4d3e-ad24-911bfc3d028c/appId/2af9f5c5-0ffc-4d1c-ba2e-72cf6382df06) | Password Credentials | 2024-06-11 | ❗ Expired |\n| [Salesforce](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/Overview/objectId/13720002-03b6-462f-ac2f-765f0f9b3f58/appId/1a2a1d4c-1d76-44ec-95f4-3ed5345423a9) | Password Credentials | 2025-10-02 | ❗ Expired |\n| [Saml test entity id](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/Overview/objectId/d589a2e6-4a78-4cdd-901b-f574dc7880db/appId/6590313e-1c00-4c07-be28-72858e837a52) | Password Credentials | 2025-11-17 | ❗ Expired |\n| [ServiceNow](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/Overview/objectId/9a8af246-0d94-42eb-aaaf-836a9f9a4974/appId/ecbbb1c8-ef06-48c4-9211-9ffbfbc24b94) | Password Credentials | 2024-02-15 | ❗ Expired |\n| [SumoLogic](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/Overview/objectId/144df581-a0c9-4280-9739-0c3612ab9ccf/appId/1b6c36b2-f2b1-43d3-b74f-8d52c44fc9c1) | Password Credentials | 2027-02-15 | ✅ Current |\n| [claimtest](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/Overview/objectId/f7b07e81-79a0-4e51-b93a-169b8f2f6c4e/appId/f816d68b-aec7-4eab-9ebc-bd23b0d04e35) | Password Credentials | 2028-02-26 | ✅ Current |\n| [test](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/Overview/objectId/31e80a1b-3faa-4ce9-9794-2b77f61f20f7/appId/8ae2b566-71f5-467e-8960-cfe8da3a2cfa) | Password Credentials | 2025-10-10 | ❗ Expired |\n| [21869testapp](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/Overview/objectId/e69e29be-ba40-445a-9824-a3a45e0ae57a/appId/dd63d132-18fb-4f2e-aec4-82b97f30301f) | Key Credentials | 2028-10-27 | ✅ Current |\n| [APP-2732_Genesys Cloud TCCC-G-TFS-Prod](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/Overview/objectId/ba63bb52-182c-4ec6-9cc8-ad2287cf51ed/appId/76249b01-8747-4db4-843f-6478d5b32b14) | Key Credentials | 2028-07-30 | ✅ Current |\n| [AWS Single-Account Access](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/Overview/objectId/dc89bf5d-83e8-4419-9162-3b9280a85755/appId/091edd89-b342-4bb5-9144-82fe6c913987) | Key Credentials | 2025-10-26 | ❗ Expired |\n| [Azure AD SAML Toolkit](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/Overview/objectId/4317fd0a-dcee-45bf-8e94-9a66638b11e0/appId/6f5ed68c-9fad-4d78-bf88-2b16bbe16338) | Key Credentials | 2028-10-11 | ✅ Current |\n| [Dropbox Business](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/Overview/objectId/5eec0e98-b81a-422a-ab61-f8de2729330d/appId/f76d7d98-02ee-4e62-9345-36016a72e664) | Key Credentials | 2024-02-17 | ❗ Expired |\n| [charlie AWS Account](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/Overview/objectId/39861745-eda1-4e3c-8358-d0ba931f12bb/appId/d3a04f85-a969-436b-bf4d-eae0a91efb4c) | Key Credentials | 2028-01-07 | ✅ Current |\n| [charlie- Genesys Cloud for Azure](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/Overview/objectId/84dc13ec-5754-4745-90f9-5cc92a5ded28/appId/9c599cd2-9fb0-4815-b65c-83be33f5df1b) | Key Credentials | 2028-07-30 | ✅ Current |\n| [P2P Server](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/Overview/objectId/05c98ca9-d208-4d3e-ad24-911bfc3d028c/appId/2af9f5c5-0ffc-4d1c-ba2e-72cf6382df06) | Key Credentials | 2024-06-11 | ❗ Expired |\n| [Salesforce](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/Overview/objectId/13720002-03b6-462f-ac2f-765f0f9b3f58/appId/1a2a1d4c-1d76-44ec-95f4-3ed5345423a9) | Key Credentials | 2025-10-02 | ❗ Expired |\n| [Saml test entity id](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/Overview/objectId/d589a2e6-4a78-4cdd-901b-f574dc7880db/appId/6590313e-1c00-4c07-be28-72858e837a52) | Key Credentials | 2025-11-17 | ❗ Expired |\n| [ServiceNow](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/Overview/objectId/9a8af246-0d94-42eb-aaaf-836a9f9a4974/appId/ecbbb1c8-ef06-48c4-9211-9ffbfbc24b94) | Key Credentials | 2024-02-15 | ❗ Expired |\n| [SumoLogic](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/Overview/objectId/144df581-a0c9-4280-9739-0c3612ab9ccf/appId/1b6c36b2-f2b1-43d3-b74f-8d52c44fc9c1) | Key Credentials | 2027-02-15 | ✅ Current |\n| [claimtest](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/Overview/objectId/f7b07e81-79a0-4e51-b93a-169b8f2f6c4e/appId/f816d68b-aec7-4eab-9ebc-bd23b0d04e35) | Key Credentials | 2028-02-26 | ✅ Current |\n| [test](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/Overview/objectId/31e80a1b-3faa-4ce9-9794-2b77f61f20f7/appId/8ae2b566-71f5-467e-8960-cfe8da3a2cfa) | Key Credentials | 2025-10-10 | ❗ Expired |\n\n\n\n","TestStatus":"Investigate","TestDescription":"Service principals without proper authentication credentials (certificates or client secrets) create security vulnerabilities that allow threat actors to impersonate these identities. This can lead to unauthorized access, lateral movement within your environment, privilege escalation, and persistent access that's difficult to detect and remediate. \n\n**Remediation action**\n\n- For your organization's service principals: [Add certificates or client secrets to the app registration](https://learn.microsoft.com/entra/identity-platform/how-to-add-credentials?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci)\n- For external service principals: Review and remove any unnecessary credentials to reduce security risk\n","TestId":"21896"},{"TestImplementationCost":"Medium","TestPillar":"Identity","TestCategory":"Privileged access","SkippedReason":null,"TestImpact":"Medium","TestAppliesTo":["Identity"],"TestSfiPillar":"Protect tenants and isolate production systems","TestSkipped":"","TestMinimumLicense":"Free","TestTags":["Identity"],"TestTitle":"Permissions to create new tenants is limited to the Tenant Creator role","TestRisk":"High","TestResult":"\nNon-privileged users are restricted from creating tenants.\n\n\n\n","TestStatus":"Passed","TestDescription":"A threat actor or a well-intentioned but uninformed employee can create a new Microsoft Entra tenant if there are no restrictions in place. By default, the user who creates a tenant is automatically assigned the Global Administrator role. Without proper controls, this action fractures the identity perimeter by creating a tenant outside the organization's governance and visibility. It introduces risk though a shadow identity platform that can be exploited for token issuance, brand impersonation, consent phishing, or persistent staging infrastructure. Since the rogue tenant might not be tethered to the enterprise’s administrative or monitoring planes, traditional defenses are blind to its creation, activity, and potential misuse.\n\n**Remediation action**\n\nEnable the **Restrict non-admin users from creating tenants** setting. For users that need the ability to create tenants, assign them the Tenant Creator role. You can also review tenant creation events in the Microsoft Entra audit logs.\n\n- [Restrict member users' default permissions](https://learn.microsoft.com/entra/fundamentals/users-default-permissions?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci#restrict-member-users-default-permissions)\n- [Assign the Tenant Creator role](https://learn.microsoft.com/entra/identity/role-based-access-control/permissions-reference?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci#tenant-creator)\n- [Review tenant creation events](https://learn.microsoft.com/entra/identity/monitoring-health/reference-audit-activities?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci#core-directory). Look for OperationName==\"Create Company\", Category == \"DirectoryManagement\".\n","TestId":"21787"},{"TestImplementationCost":"Medium","TestPillar":"Identity","TestCategory":"Identity governance","SkippedReason":null,"TestImpact":"Medium","TestAppliesTo":null,"TestSfiPillar":"Protect tenants and isolate production systems","TestSkipped":"","TestMinimumLicense":["P2","Governance"],"TestTags":null,"TestTitle":"All entitlement management packages that apply to guests have expirations or access reviews configured in their assignment policies","TestRisk":"Medium","TestResult":"\nAccess package assignment policies without expiration and without access reviews were found for external users.\n\n## [Access package assignment policies for external users](https://entra.microsoft.com/#view/Microsoft_AAD_ERM/DashboardBlade/~/elmEntitlement)\n\n| Access package | Assignment policy | Expiry configured | Access review configured | Status |\n| :------------- | :---------------- | :------------------ | :--------------------- | :----- |\n| PS-GraphCmdLetScriptTest4 | External | No | No | ❌ Non-compliant |\n| Get user info demo | Initial Policy | Yes | No | ✅ Compliant |\n| PS-GraphCmdLetScriptTest4 | 21929Test | No | Yes | ✅ Compliant |\n| UserInfo | Initial Policy | Yes | No | ✅ Compliant |\n\n\n","TestStatus":"Failed","TestDescription":"Access packages for guest users without expiration dates or access reviews allow indefinite access to organizational resources. Compromised or stale guest accounts enable threat actors to maintain persistent, undetected access for lateral movement, privilege escalation, and data exfiltration. Without periodic validation, organizations cannot identify when business relationships change or when guest access is no longer needed. \n\n**Remediation action**\n\n- [Configure lifecycle settings](https://learn.microsoft.com/entra/id-governance/entitlement-management-access-package-lifecycle-policy?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci)\n- [Configure access reviews](https://learn.microsoft.com/entra/id-governance/entitlement-management-access-reviews-create?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci)\n","TestId":"21929"},{"TestImplementationCost":"Medium","TestPillar":"Identity","TestCategory":"Monitoring","SkippedReason":"UnderConstruction","TestImpact":"Medium","TestAppliesTo":["Identity"],"TestSfiPillar":"Monitor and detect cyberthreats","TestSkipped":"UnderConstruction","TestMinimumLicense":"P1","TestTags":["Identity"],"TestTitle":"All user sign-in activity uses strong authentication methods","TestRisk":"Medium","TestResult":"\nPlanned for future release.\n\n","TestStatus":"Planned","TestDescription":"Attackers might gain access if multifactor authentication (MFA) isn't universally enforced or if there are exceptions in place. Attackers might gain access by exploiting vulnerabilities of weaker MFA methods like SMS and phone calls through social engineering techniques. These techniques might include SIM swapping or phishing, to intercept authentication codes.\n\nAttackers might use these accounts as entry points into the tenant. By using intercepted user sessions, attackers can disguise their activities as legitimate user actions, evade detection, and continue their attack without raising suspicion. From there, they might attempt to manipulate MFA settings to establish persistence, plan, and execute further attacks based on the privileges of compromised accounts.\n\n**Remediation action**\n\n- [Deploy multifactor authentication](https://learn.microsoft.com/entra/identity/authentication/howto-mfa-getstarted?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci)\n- [Get started with a phishing-resistant passwordless authentication deployment](https://learn.microsoft.com/entra/identity/authentication/how-to-plan-prerequisites-phishing-resistant-passwordless-authentication?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci)\n- [Deploy a Conditional Access policy to require phishing-resistant MFA for all users](https://learn.microsoft.com/entra/identity/conditional-access/policy-all-users-mfa-strength?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci)\n- [Review authentication methods activity](https://learn.microsoft.com/entra/identity/monitoring-health/concept-usage-insights-report?tabs=microsoft-entra-admin-center&wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci#authentication-methods-activity)\n","TestId":"21800"},{"TestImplementationCost":"Low","TestPillar":"Devices","TestCategory":"Device","SkippedReason":null,"TestImpact":"Low","TestAppliesTo":null,"TestSfiPillar":"Protect networks","TestSkipped":"","TestMinimumLicense":"Intune","TestTags":null,"TestTitle":"A Microsoft Defender Antivirus policy is created and assigned in Intune for macOS","TestRisk":"High","TestResult":"\nDefender Antivirus policies are configured and assigned in Intune for macOS.\n\n\n## A Microsoft Defender Antivirus policy is created and assigned in Intune for macOS\n\n| Policy Name | Status | Assignment |\n| :---------- | :----- | :--------- |\n| [macOS Defender Antivirus Policy](https://intune.microsoft.com/#view/Microsoft_Intune_Workflows/SecurityManagementMenu/~/antivirus) | ✅ Assigned | **Included:** antivirustest |\n\n\n\n","TestStatus":"Passed","TestDescription":"If Microsoft Defender Antivirus policies aren't properly configured and assigned to macOS devices in Intune, attackers can exploit unprotected endpoints to execute malware, disable antivirus protections, and persist in the environment. Without enforced policies, devices run outdated definitions, lack real-time protection, or have misconfigured scan schedules, increasing the risk of undetected threats and privilege escalation. This enables lateral movement across the network, credential harvesting, and data exfiltration. The absence of antivirus enforcement undermines device compliance, increases exposure of endpoints to zero-day threats, and can result in regulatory noncompliance. Attackers use these gaps to maintain persistence and evade detection, especially in environments without centralized policy enforcement.\n\nEnforcing Defender Antivirus policies ensures that macOS devices are consistently protected against malware, supports real-time threat detection, and aligns with Zero Trust by maintaining a secure and compliant endpoint posture.\n\n**Remediation action**\n\nUse Intune to configure and assign Microsoft Defender Antivirus policies for macOS devices to enforce real-time protection, maintain up-to-date definitions, and reduce exposure to malware: \n- [Configure Intune policies to manage Microsoft Defender Antivirus](https://learn.microsoft.com/intune/intune-service/protect/endpoint-security-antivirus-policy?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci#macos)\n- [Assign policies in Intune](https://learn.microsoft.com/intune/intune-service/configuration/device-profile-assign?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci#assign-a-policy-to-users-or-groups)\n","TestId":"24784"},{"TestImplementationCost":"Low","TestPillar":"Devices","TestCategory":"Tenant","SkippedReason":null,"TestImpact":"Low","TestAppliesTo":null,"TestSfiPillar":"Protect tenants and isolate production systems","TestSkipped":"","TestMinimumLicense":"Intune","TestTags":null,"TestTitle":"Intune Endpoint Analytics policy is created and assigned","TestRisk":"Low","TestResult":"\nEndpoint analytics policy is not created or not assigned.\n\nNo Endpoint Analytics policies found in this tenant.\n\n\n","TestStatus":"Failed","TestDescription":"If endpoint analytics isn't enabled, threat actors can exploit gaps in device health, performance, and security posture. Without the visibility endpoint analytics brings, it can be difficult for an organization to detect indicators such as anomalous device behavior, delayed patching, or configuration drift. These gaps allow attackers to establish persistence, escalate privileges, and move laterally across the environment. An absence of analytics data can impede rapid detection and response, allowing attackers to exploit unmonitored endpoints for command and control, data exfiltration, or further compromise.\n\nEnabling endpoint analytics provides visibility into device health and behavior, helping organizations detect risks, respond quickly to threats, and maintain a strong Zero Trust posture.\n\n**Remediation action**\n\nEnroll Windows devices into endpoint analytics in Intune to monitor device health and identify risks: \n- [Configure endpoint analytics](https://learn.microsoft.com/intune/endpoint-analytics/configure?pivots=intune&wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci)\n\nFor more information, see:\n- [What is endpoint analytics?](https://learn.microsoft.com/intune/endpoint-analytics/index?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci)\n","TestId":"24576"},{"TestImplementationCost":"Low","TestPillar":"Devices","TestCategory":"Tenant","SkippedReason":null,"TestImpact":"Low","TestAppliesTo":null,"TestSfiPillar":"Protect tenants and isolate production systems","TestSkipped":"","TestMinimumLicense":"Intune","TestTags":null,"TestTitle":"Intune Terms and Conditions Policy is configured and assigned","TestRisk":"Medium","TestResult":"\nNo Terms and Conditions policy exists or none are assigned.\n\n\n\n","TestStatus":"Failed","TestDescription":"If Terms and Conditions policies aren't configured and assigned in Intune, users can access corporate resources without agreeing to required legal, security, or usage terms. This omission exposes the organization to compliance risks, legal liabilities, and potential misuse of resources.\n\nEnforcing Terms and Conditions ensures users acknowledge and accept company policies before accessing sensitive data or systems, supporting regulatory compliance and responsible resource use.\n\n**Remediation action**\n\nCreate and assign Terms and Conditions policies in Intune to require user acceptance before granting access to corporate resources: \n- [Create terms and conditions policy](https://learn.microsoft.com/intune/intune-service/enrollment/terms-and-conditions-create?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci)\n","TestId":"24794"},{"TestImplementationCost":"Medium","TestPillar":"Devices","TestCategory":"Device","SkippedReason":null,"TestImpact":"Medium","TestAppliesTo":null,"TestSfiPillar":"Protect networks","TestSkipped":"","TestMinimumLicense":"Intune","TestTags":null,"TestTitle":"Attack Surface Reduction rules are applied to Windows devices to prevent exploitation of vulnerable system components","TestRisk":"High","TestResult":"\nNo Attack Surface Reduction policies found for Windows devices in Intune.\n\n**Required ASR Rules:**\n- Block execution of potentially obfuscated scripts\n- Block Win32 API calls from Office macros\n\n\n","TestStatus":"Failed","TestDescription":"If Intune profiles for Attack Surface Reduction (ASR) rules aren't properly configured and assigned to Windows devices, threat actors can exploit unprotected endpoints to execute obfuscated scripts and invoke Win32 API calls from Office macros. These techniques are commonly used in phishing campaigns and malware delivery, allowing attackers to bypass traditional antivirus defenses and gain initial access. Once inside, attackers escalate privileges, establish persistence, and move laterally across the network. Without ASR enforcement, devices remain vulnerable to script-based attacks and macro abuse, undermining the effectiveness of Microsoft Defender and exposing sensitive data to exfiltration. This gap in endpoint protection increases the likelihood of successful compromise and reduces the organization’s ability to contain and respond to threats.\n\nEnforcing ASR rules helps block common attack techniques such as script-based execution and macro abuse, reducing the risk of initial compromise and supporting Zero Trust by hardening endpoint defenses.\n\n**Remediation action**\n\nUse Intune to deploy **Attack Surface Reduction Rules** profiles for Windows devices to block high-risk behaviors and strengthen endpoint protection:\n- [Configure Intune profiles for Attack Surface Reduction Rules](https://learn.microsoft.com/intune/intune-service/protect/endpoint-security-asr-policy?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci#devices-managed-by-intune)\n- [Assign policies in Intune](https://learn.microsoft.com/intune/intune-service/configuration/device-profile-assign?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci#assign-a-policy-to-users-or-groups)\n\nFor more information, see: \n- [Attack surface reduction rules reference](https://learn.microsoft.com/defender-endpoint/attack-surface-reduction-rules-reference?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci) in the Microsoft Defender documentation.\n","TestId":"24574"},{"TestImplementationCost":"Low","TestPillar":"Devices","TestCategory":"Device","SkippedReason":null,"TestImpact":"High","TestAppliesTo":null,"TestSfiPillar":"Protect networks","TestSkipped":"","TestMinimumLicense":"Intune","TestTags":null,"TestTitle":"macOS - Firewall policy is created and assigned","TestRisk":"Medium","TestResult":"\nNo assigned macOS firewall policy was found in Intune.\n\n\n\n","TestStatus":"Failed","TestDescription":"Without a centrally managed firewall policy, macOS devices might rely on default or user-modified settings, which often fail to meet corporate security standards. This exposes devices to unsolicited inbound connections, enabling threat actors to exploit vulnerabilities, establish outbound command-and-control (C2) traffic for data exfiltration, and move laterally within the network—significantly escalating the scope and impact of a breach.\n\nEnforcing macOS Firewall policies ensures consistent control over inbound and outbound traffic, reducing exposure to unauthorized access and supporting Zero Trust through device-level protection and network segmentation.\n\n**Remediation action**\n\nConfigure and assign **macOS Firewall** profiles in Intune to block unauthorized traffic and enforce consistent network protections across all managed macOS devices:\n\n- [Configure the built-in firewall on macOS devices](https://learn.microsoft.com/intune/intune-service/protect/endpoint-security-firewall-policy?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci)\n- [Assign policies in Intune](https://learn.microsoft.com/intune/intune-service/configuration/device-profile-assign?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci#assign-a-policy-to-users-or-groups)\n\nFor more information, see: \n- [Available macOS firewall settings](https://learn.microsoft.com/intune/intune-service/protect/endpoint-security-firewall-profile-settings?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci#macos-firewall-profile)\n","TestId":"24552"},{"TestImplementationCost":"","TestPillar":"Infrastructure","TestCategory":"Secure management ports","SkippedReason":"This test is not applicable to the current environment.","TestImpact":"","TestAppliesTo":null,"TestSfiPillar":"Protect tenants and isolate production systems","TestSkipped":"NotApplicable","TestMinimumLicense":"N/A","TestTags":null,"TestTitle":"Management ports of virtual machines should be protected with just-in-time network access control","TestRisk":"High","TestResult":"ServersStandardTierOnly\n\n| Subscription | Resource group | Resource type | Affected resource | Status | Azure portal |\n| :----------- | :------------- | :------------ | :---------------- | :----- | :----------- |\n| [Visual Studio Enterprise Subscription](https://portal.azure.com/#resource/subscriptions/54d3ea01-5a07-45d0-8d69-e5f5b0b20098) | indiavm_group | virtualmachines | [india-2](https://portal.azure.com/#resource/subscriptions/54d3ea01-5a07-45d0-8d69-e5f5b0b20098/resourceGroups/indiavm_group/providers/Microsoft.Compute/virtualMachines/india-2) | N/A | [View recommendation](https://portal.azure.com/#blade/Microsoft_Azure_Security/RecommendationsBlade/assessmentKey/805651bc-6ecd-4c73-9b55-97a19d0582d0/resourceId/%2fsubscriptions%2f54d3ea01-5a07-45d0-8d69-e5f5b0b20098%2fresourceGroups%2findiavm_group%2fproviders%2fMicrosoft.Compute%2fvirtualMachines%2findia-2) |\n| [Visual Studio Enterprise Subscription](https://portal.azure.com/#resource/subscriptions/54d3ea01-5a07-45d0-8d69-e5f5b0b20098) | indiavm_group | virtualmachines | [indiavm](https://portal.azure.com/#resource/subscriptions/54d3ea01-5a07-45d0-8d69-e5f5b0b20098/resourceGroups/indiavm_group/providers/Microsoft.Compute/virtualMachines/indiavm) | N/A | [View recommendation](https://portal.azure.com/#blade/Microsoft_Azure_Security/RecommendationsBlade/assessmentKey/805651bc-6ecd-4c73-9b55-97a19d0582d0/resourceId/%2fsubscriptions%2f54d3ea01-5a07-45d0-8d69-e5f5b0b20098%2fresourceGroups%2findiavm_group%2fproviders%2fMicrosoft.Compute%2fvirtualMachines%2findiavm) |\n","TestStatus":"Skipped","TestDescription":"Defender for Cloud has identified some overly-permissive inbound rules for management ports in your Network Security Group. Enable just-in-time access control to protect your VM from internet-based brute-force attacks. Learn more in Understanding just-in-time (JIT) VM access.\n\n**Remediation action**\n\nTo enable just-in-time VM access:
  • Select one or more VMs from the list below and select \"Remediate\", or select \"Take action\" if you've arrived from a recommendation for a specific VM.
  • On the \"JIT VM access configuration\" page, define the ports for which the just-in-time VM access will be applicable.
    • To add additional ports, select the \"Add\" button on the top left, or select an existing port and edit it.
    • On the \"Add port configuration\" pane, enter the required parameters.
  • Select \"Save\".
","TestId":"805651bc-6ecd-4c73-9b55-97a19d0582d0"},{"TestImplementationCost":"Low","TestPillar":"Identity","TestCategory":"External collaboration","SkippedReason":null,"TestImpact":"Medium","TestAppliesTo":["Identity"],"TestSfiPillar":"Protect tenants and isolate production systems","TestSkipped":"","TestMinimumLicense":"Free","TestTags":["ExternalCollaboration"],"TestTitle":"Guest can’t invite other guests","TestRisk":"Medium","TestResult":"\nTenant restricts who can invite guests.\n\n**Guest invite settings**\n\n * Guest invite restrictions → Member users and users assigned to specific admin roles can invite guest users including guests with member permissions\n\n","TestStatus":"Passed","TestDescription":"External user accounts are often used to provide access to business partners who belong to organizations that have a business relationship with your enterprise. If these accounts are compromised in their organization, attackers can use the valid credentials to gain initial access to your environment, often bypassing traditional defenses due to their legitimacy. \n\nAllowing external users to onboard other external users increases the risk of unauthorized access. If an attacker compromises an external user's account, they can use it to create more external accounts, multiplying their access points and making it harder to detect the intrusion.\n\n**Remediation action**\n\n- [Restrict who can invite guests to only users assigned to specific admin roles](https://learn.microsoft.com/entra/external-id/external-collaboration-settings-configure?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci#to-configure-guest-invite-settings)\n","TestId":"21791"},{"TestImpact":"Medium","TestRisk":"High","TestSkipped":"","TestAppliesTo":null,"TestPillar":"Data","TestCategory":"Advanced Classification","TestDescription":"Named entity sensitive information types (SITs) are prebuilt Microsoft classifiers that detect common sensitive entities like people's names, physical addresses, and medical terminology. They extend data protection beyond pattern matching into context aware classification, and can be used in auto-labeling policies and DLP rules without any custom development.\n\n**Remediation action**\n\n- [Learn about named entities](https://learn.microsoft.com/purview/sit-named-entities-learn?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci)\n- [Use named entities in your data loss prevention policies](https://learn.microsoft.com/purview/sit-named-entities-use?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci)\n","TestTitle":"Named Entity SITs Usage in Auto-Labeling and DLP Policies","SkippedReason":null,"TestId":"35035","TestImplementationCost":"Low","TestMinimumLicense":["EXCHANGE_S_ENTERPRISE"],"TestSfiPillar":"Protect tenants and production systems","TestResult":"\n✅ At least one auto-labeling or DLP policy rule uses a Named Entity SIT (such as 'All Full Names', 'All Physical Addresses', 'All Medical Terms and Conditions', or similar pre-built classifiers).\n\n\n\n### [Rules using named entity SITs](https://purview.microsoft.com/informationprotection/dataclassification/multicloudsensitiveinfotypes)\n| Rule name | Policy name | Named Entity SITs | Count | Workload | Type |\n| :--- | :--- | :--- | :--- | :--- | :--- |\n| U.S. Patriot Act Enhanced-ODB | [U.S. Patriot Act Enhanced](https://purview.microsoft.com/informationprotection/autolabeling) | U.S. Physical Addresses, All Full Names | 2 | Exchange, SharePoint, OneDriveForBusiness, PowerBI, Applications, Azure, AWS | Auto-Labeling |\n\n\n### Summary\n| Metric | Count |\n| :--- | :--- |\n| Named entity SITs in catalog | 60 |\n| Total auto-labeling rules | 2 |\n| Total DLP rules | 8 |\n| Auto-labeling rules using named entity SITs | 1 |\n| DLP rules using named entity SITs | 0 |\n\n","TestStatus":"Passed","TestTags":null},{"TestImplementationCost":"Low","TestPillar":"Identity","TestCategory":"Application management","SkippedReason":null,"TestImpact":"Low","TestAppliesTo":["Identity"],"TestSfiPillar":"Protect networks","TestSkipped":"","TestMinimumLicense":"P1","TestTags":["Identity"],"TestTitle":"Trusted network locations are configured to increase quality of risk detections","TestRisk":"Medium","TestResult":"\n✅ **Pass**: Trusted named locations are configured in Microsoft Entra ID to support location-based security controls.\n\n\n## All named locations\n\n5 [named locations](https://entra.microsoft.com/#view/Microsoft_AAD_ConditionalAccess/ConditionalAccessBlade/~/NamedLocations/menuId//fromNav/) found.\n\n| Name | Location type | Trusted | Creation date | Modified date |\n| :--- | :------------ | :------ | :------------ | :------------ |\n| Melbourne Branch | IP-based | Yes | Unknown | Unknown |\n| Boston Head Office | IP-based | Yes | Unknown | Unknown |\n| Untrusted Locations | Country-based | No | Unknown | Unknown |\n| Corporate IPs | IP-based | Yes | Unknown | Unknown |\n| Manson home | IP-based | Yes | 04/16/2025 04:55:11 | 04/16/2025 04:55:11 |\n\n\n\n","TestStatus":"Passed","TestDescription":"Without named locations configured in Microsoft Entra ID, threat actors can exploit the absence of location intelligence to conduct attacks without triggering location-based risk detections or security controls. When organizations fail to define named locations for trusted networks, branch offices, and known geographic regions, Microsoft Entra ID Protection can't assess location-based risk signals. Not having these policies in place can lead to increased false positives that create alert fatigue and potentially mask genuine threats. This configuration gap prevents the system from distinguishing between legitimate and illegitimate locations. For example, legitimate sign-ins from corporate networks and suspicious authentication attempts from high-risk locations (anonymous proxy networks, Tor exit nodes, or regions where the organization has no business presence). Threat actors can use this uncertainty to conduct credential stuffing attacks, password spray campaigns, and initial access attempts from malicious infrastructure without triggering location-based detections that would normally flag such activity as suspicious. Organizations can also lose the ability to implement adaptive security policies that could automatically apply stricter authentication requirements or block access entirely from untrusted geographic regions. Threat actors can maintain persistence and conduct lateral movement from any global location without encountering location-based security barriers, which should serve as an extra layer of defense against unauthorized access attempts.\n\n**Remediation action**\n\n- [Configure named locations to define trusted IP ranges and geographic regions for enhanced location-based risk detection and Conditional Access policy enforcement](https://learn.microsoft.com/entra/identity/conditional-access/concept-assignment-network?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci)\n","TestId":"21865"},{"TestImplementationCost":"Medium","TestPillar":"Identity","TestCategory":"External collaboration","SkippedReason":null,"TestImpact":"Low","TestAppliesTo":null,"TestSfiPillar":"Protect tenants and isolate production systems","TestSkipped":"","TestMinimumLicense":"Free","TestTags":null,"TestTitle":"Inactive guest identities are disabled or removed from the tenant","TestRisk":"Medium","TestResult":"\n❌ Found 3 inactive guest user(s) with no sign-in activity in the last 90 days:\n\n\n## Inactive guest accounts in the tenant\n\n\n| Display name | User principal name | Last sign-in date | Created date |\n| :----------- | :------------------ | :---------------- | :----------- |\n| [Ash Williams](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/overview/userId/a0883b7a-c6a8-440f-84f0-d6e1b79aaf4c/hidePreviewBanner~/true) | manson_manson.net#EXT#@contoso.onmicrosoft.com | 2025-08-10 | 2021-04-11 |\n| [Riley Martinez](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/overview/userId/653c7fdd-1b41-4229-992a-69cc35aad4f7/hidePreviewBanner~/true) | riley@contoso.onmicrosoft.com | | 2021-06-02 |\n| [Shonali Balakrishna](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/overview/userId/305bbf73-eee4-4e0c-9c7d-627e00ed3665/hidePreviewBanner~/true) | guest-user_external.com#EXT#@contoso.com | 2025-05-05 | 2025-03-25 |\n\n\n\n","TestStatus":"Failed","TestDescription":"When guest identities remain active but unused for extended periods, threat actors can exploit these dormant accounts as entry vectors into the organization. Inactive guest accounts represent a significant attack surface because they often maintain persistent access permissions to resources, applications, and data while remaining unmonitored by security teams. Threat actors frequently target these accounts through credential stuffing, password spraying, or by compromising the guest's home organization to gain lateral access. Once an inactive guest account is compromised, attackers can utilize existing access grants to:\n- Move laterally within the tenant\n- Escalate privileges through group memberships or application permissions\n- Establish persistence through techniques like creating more service principals or modifying existing permissions\n\nThe prolonged dormancy of these accounts provides attackers with extended dwell time to conduct reconnaissance, exfiltrate sensitive data, and establish backdoors without detection, as organizations typically focus monitoring efforts on active internal users rather than external guest accounts.\n\n**Remediation action**\n- [Monitor and clean up stale guest accounts](https://learn.microsoft.com/entra/identity/users/clean-up-stale-guest-accounts?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci)\n","TestId":"21858"},{"TestImpact":"Low","TestRisk":"Medium","TestSkipped":"NotConnectedToService","TestAppliesTo":null,"TestPillar":"Data","TestCategory":"Advanced Label Features","TestDescription":"The super user feature of the Azure Rights Management service grants designated accounts the ability to decrypt content your organization has encrypted by using this service, regardless of the original permissions assigned. Super users might be necessary for eDiscovery, data recovery, compliance investigations, and content migration. The super user feature ensures that authorized people and services can always read and inspect the data that the Azure Rights Management service encrypts for your organization.\n\nWhen you use a group to designate super user accounts, membership of that group must be carefully controlled and limited, for example, to service accounts used by compliance tools or eDiscovery platforms. Unless you have a feature or business need that requires the feature to be enabled all the time, Microsoft recommends keeping the feature disabled by default, and enabling it only when needed. When you use a group to designate super user accounts, use Microsoft Entra Privileged Identity Management (PIM) to reduce risk by enabling just‑in‑time access when required and minimizing permanent privilege.\n\n**Remediation action**\n\n- [Configure Azure Rights Management super users for discovery services or data recovery](https://learn.microsoft.com/purview/encryption-super-users?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci#security-best-practices-for-the-super-user-feature)\n","TestTitle":"Super user membership is configured for Microsoft Purview Information Protection","SkippedReason":"This test requires connection to the service(s) \"AipService\" currently disconnected. Please use _Connect-ZtAssessment_ to connect.","TestId":"35011","TestImplementationCost":"Medium","TestMinimumLicense":["RMS_S_PREMIUM2"],"TestSfiPillar":"Protect tenants and production systems","TestResult":"\nSkipped. This test requires connection to the service(s) \"AipService\" currently disconnected. Please use _Connect-ZtAssessment_ to connect.\n\n","TestStatus":"Skipped","TestTags":null},{"TestImpact":"Medium","TestRisk":"Medium","TestSkipped":"","TestAppliesTo":null,"TestPillar":"Data","TestCategory":"Data Security Posture Management","TestDescription":"Browser Data Loss Prevention (DLP) for cloud apps in Microsoft Edge for Business prevents users from uploading, downloading, copying, or pasting sensitive data to and from unmanaged cloud AI services (ChatGPT, Google Gemini, Claude, etc.) directly through the browser. Without Browser DLP policies for AI apps configured, users can access consumer AI services through Edge for Business and exfiltrate sensitive organizational data by uploading files or pasting confidential information, circumventing cloud-based DLP controls.\n\nBrowser DLP acts as the final enforcement point at the browser level, blocking data transfers to AI services even if data governance policies allow access to the service itself. Organizations using Microsoft 365 Copilot or allowing employee access to generative AI tools must enable Browser DLP policies targeting unmanaged AI apps to prevent uncontrolled data exposure. Browser DLP for AI apps requires PAYG billing activation, Intune-managed devices, and Edge for Business deployment to function.\n\n**Remediation action**\n\n**To enable Browser DLP for AI Apps (Minimal Setup):**\n\n1. **Activate PAYG Billing** (One-time setup)\n - Navigate to [Purview Settings > Account](https://purview.microsoft.com/settings/account)\n - Enable \"Purview Pay-as-You-Go billing\"\n - Activate trial or start paid subscription\n - This is the only hard requirement\n\n2. **Create Browser DLP Policy** (via Purview UI)\n - Navigate to [Microsoft Purview portal](https://purview.microsoft.com)\n - Data Loss Prevention > Policies > + Create policy\n - Choose \"Custom\" policy template\n - Name: \"Browser DLP - AI Apps\" (or similar)\n - Add locations: Select \"Edge for Business\"\n - Add cloud apps: Select \"All unmanaged AI apps\" OR add specific apps manually\n - Configure scope: All users or specific groups\n - Create rule:\n - Name: \"Block Sensitive Data to Unmanaged AI Apps\"\n - Condition: Content contains [pick sensitive info types: credit card, SSN, bank account, etc.]\n - Action: \"Restrict browser activities\" > Block file uploads and text sharing to unmanaged apps\n - Incident reports: Enable alerts for rule matches\n - Policy mode: Start with \"Simulate\" (TestWithoutNotifications) for testing\n - Enable policy\n\n3. **Deployment Requirements**\n - Managed devices: Intune enrollment required (Windows 10/11)\n - Browser: Edge for Business v144+\n - Microsoft Edge management automatically syncs policy\n\n4. **Validation**\n - Navigate to Activity Explorer in Purview\n - Filter: Enforcement Plane = \"Browser\"\n - Monitor for browser DLP activities\n - Review [Microsoft Defender](https://security.microsoft.com) for related alerts\n\n**Optional Enhancement: Add Collection Policies** (Data classification layer)\n- If you want more granular data classification, create collection policies targeting AI apps\n- Collection policies define what data to monitor (optional for basic protection)\n- Link collection policies to Browser DLP rules (if UI supports linking)\n\n**Via PowerShell (After PAYG activation):**\n```powershell\nConnect-ExchangeOnline\nConnect-IPPSSession\n\n# List browser DLP policies\nGet-DlpCompliancePolicy | Where-Object { $_.EnforcementPlanes -contains \"Browser\" } | Select-Object Name, Enabled, Mode\n\n# Enable specific policy\nSet-DlpCompliancePolicy -Identity -Enabled $true\n\n# List rules for browser policy\nGet-DlpCompliancePolicy | Where-Object { $_.EnforcementPlanes -contains \"Browser\" } | ForEach-Object { Get-DlpComplianceRule -Policy $_.Identity }\n```\n\n**For more information:**\n- [Learn about Browser DLP for Cloud Apps](https://learn.microsoft.com/en-us/purview/dlp-browser-dlp-learn)\n- [Create policy for browser cloud app protection](https://learn.microsoft.com/en-us/purview/dlp-create-policy-prevent-cloud-sharing-from-edge-biz)\n- [Create policy for AI app protection](https://learn.microsoft.com/en-us/purview/dlp-create-policy-block-to-ai-via-edge)\n- [Billing and PAYG activation](https://learn.microsoft.com/en-us/purview/purview-billing-models)\n","TestTitle":"Browser data loss prevention is enabled for AI apps via Edge for Business","SkippedReason":null,"TestId":"35041","TestImplementationCost":"High","TestMinimumLicense":["RMS_S_PREMIUM2"],"TestSfiPillar":"Protect tenants and production systems","TestResult":"\n✅ Browser Data Loss Prevention for AI Apps is configured and enabled via at least one active DLP policy with Browser enforcement, preventing sensitive data from being uploaded to or copied from unmanaged AI services through Edge for Business.\n\n\n**Browser DLP Configuration Summary:**\n\n* Browser DLP Policies Found: 1\n* Browser DLP Policies Enabled: 1\n* Enabled Policies with Rules: 1\n* Browser DLP Rules: 1\n\n## [Discovered Policies](https://purview.microsoft.com/datalossprevention/policies)\n\n| Policy name | Enabled | Mode | Enforcement planes | Policy category | Created by | Creation time (UTC) | Rules count |\n|:---|:---|:---|:---|:---|:---|:---|:---|\n| Browser DLP Test | True | TestWithoutNotifications | Browser | ApplicableToAI | Dakota Lee Test | 2026-02-13T07:18:47Z | 1 |\n\n","TestStatus":"Passed","TestTags":null},{"TestImplementationCost":"Low","TestPillar":"Devices","TestCategory":"Device","SkippedReason":null,"TestImpact":"Medium","TestAppliesTo":null,"TestSfiPillar":"Protect identities and secrets","TestSkipped":"","TestMinimumLicense":"Intune","TestTags":null,"TestTitle":"Intune macOS FileVault policy is created and Assigned","TestRisk":"High","TestResult":"\nNo relevant macOS FileVault encryption policies are configured or assigned.\n\n\n## Intune macOS FileVault policy is created and Assigned\n\n\n\n| Policy Name | Status | Assignment |\n| :---------- | :----- | :--------- |\n\n\n\n","TestStatus":"Failed","TestDescription":"Without properly configured and assigned FileVault encryption policies in Intune, threat actors can exploit physical access to unmanaged or misconfigured macOS devices to extract sensitive corporate data. Unencrypted devices allow attackers to bypass operating system-level security by booting from external media or removing the storage drive. These attacks can expose credentials, certificates, and cached authentication tokens, enabling privilege escalation and lateral movement. Additionally, unencrypted devices undermine compliance with data protection regulations and increase the risk of reputational damage and financial penalties in the event of a breach.\n\nEnforcing FileVault encryption protects data at rest on macOS devices, even if lost or stolen. It disrupts credential harvesting and lateral movement, supports regulatory compliance, and aligns with Zero Trust principles of device trust.\n\n**Remediation action**\n\nUse Intune to enforce FileVault encryption and monitor compliance on all managed macOS devices: \n- [Create a FileVault disk encryption policy for macOS in Intune](https://learn.microsoft.com/intune/intune-service/protect/encrypt-devices-filevault?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci#create-endpoint-security-policy-for-filevault)\n- [Assign policies in Intune](https://learn.microsoft.com/intune/intune-service/configuration/device-profile-assign?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci#assign-a-policy-to-users-or-groups)\n- [Monitor device encryption with Intune](https://learn.microsoft.com/intune/intune-service/protect/encryption-monitor?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci)\n","TestId":"24569"},{"TestImpact":"High","TestRisk":"Medium","TestSkipped":"","TestAppliesTo":null,"TestPillar":"Data","TestCategory":"sensitivity-labels","TestDescription":"Publishing too many labels globally creates confusion and decision paralysis for users, reducing adoption and increasing misclassification. When users face more than 25 labels, they struggle to identify the appropriate classification, leading to incorrect labels or avoiding the feature entirely.\n\nMicrosoft recommends no more than 25 labels in global policies, ideally organized as five main labels with up to five sublabels each. Use scoped policies to publish specialized labels only to specific users, groups, or departments, keeping the global label set focused on common scenarios.\n\n**Remediation action**\n\n- [Sensitivity label limitations per tenant](https://learn.microsoft.com/purview/sensitivity-labels?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci#sensitivity-label-limitations-per-tenant)\n- [Create and publish sensitivity labels](https://learn.microsoft.com/microsoft-365/compliance/create-sensitivity-labels?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci)\n","TestTitle":"Global Scope Label Count","SkippedReason":null,"TestId":"35015","TestImplementationCost":"Medium","TestMinimumLicense":["RMS_S_PREMIUM"],"TestSfiPillar":"Protect tenants and production systems","TestResult":"\n✅ 3 sensitivity labels are published in globally-scoped policies, within the recommended limit of 25.\n\n### [Global Label Policies](https://purview.microsoft.com/informationprotection/labelpolicies)\n\n| Policy Name | Global Workloads | Labels Published | Sample Labels |\n| :--- | :--- | :---: | :--- |\n| [true event](https://purview.microsoft.com/informationprotection/labelpolicies) | Exchange | 1 | Confidential – RMS |\n| [peyton](https://purview.microsoft.com/informationprotection/labelpolicies) | Exchange | 1 | peyton |\n| [test-policy-35012](https://purview.microsoft.com/informationprotection/labelpolicies) | Exchange | 1 | test-35012-1 |\n\n### Summary\n\n* **Total Unique Labels Published Globally:** 3\n* **Recommended Maximum:** 25\n* **Status:** Pass\n\n*Note: Labels appearing in multiple global policies are counted once (deduplicated).*\n\n\n","TestStatus":"Passed","TestTags":null},{"TestImplementationCost":"High","TestPillar":"Identity","TestCategory":"Access control","SkippedReason":null,"TestImpact":"Medium","TestAppliesTo":null,"TestSfiPillar":"Protect identities and secrets","TestSkipped":"","TestMinimumLicense":"Free","TestTags":null,"TestTitle":"Guest access is limited to approved tenants","TestRisk":"Medium","TestResult":"\nGuest access is not limited to approved tenants.\n\n\n## [Collaboration restrictions](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/CompanyRelationshipsMenuBlade/~/Settings/menuId/)\n\nThe tenant is configured to: **Allow invitations to be sent to any domain (most inclusive)** ❌\n\n","TestStatus":"Failed","TestDescription":"Without limiting guest access to approved tenants, threat actors can exploit unrestricted guest access to establish initial access through compromised external accounts or by creating accounts in untrusted tenants. Organizations can configure an allowlist or blocklist to control B2B collaboration invitations from specific organizations, and without these controls, threat actors can leverage social engineering techniques to obtain invitations from legitimate internal users. Once threat actors gain guest access through unrestricted domains, they can perform discovery activities to enumerate internal resources, users, and applications that guest accounts can access. The compromised guest account then serves as a persistent foothold, allowing threat actors to execute collection activities against accessible SharePoint sites, Teams channels, and other resources granted to guest users. From this position, threat actors can attempt lateral movement by exploiting trust relationships between the compromised tenant and partner organizations, or by leveraging guest permissions to access sensitive data that can be used for further credential compromise or business email compromise attacks.\n\n**Remediation action**\n\n- [Configure Domain-Based Allow or Deny Lists](https://learn.microsoft.com/en-us/entra/external-id/allow-deny-list)\n\n","TestId":"21822"},{"TestImplementationCost":"High","TestPillar":"Identity","TestCategory":"Access control","SkippedReason":"UnderConstruction","TestImpact":"Low","TestAppliesTo":["Identity"],"TestSfiPillar":"Protect identities and secrets","TestSkipped":"UnderConstruction","TestMinimumLicense":null,"TestTags":["Identity"],"TestTitle":"Block legacy Microsoft Online PowerShell module","TestRisk":"Low","TestResult":"\nPlanned for future release.\n","TestStatus":"Planned","TestDescription":"...\n\n**Remediation action**\n\n","TestId":"21843"},{"TestImplementationCost":"Medium","TestPillar":"Identity","TestCategory":"Credential management","SkippedReason":null,"TestImpact":"Medium","TestAppliesTo":["Identity"],"TestSfiPillar":"Protect identities and secrets","TestSkipped":"","TestMinimumLicense":"P1","TestTags":["Credential"],"TestTitle":"Users have strong authentication methods configured ","TestRisk":"Medium","TestResult":"\nFound users that have not yet registered phishing resistant authentication methods\n\n## Users strong authentication methods\n\nFound users that have not registered phishing resistant authentication methods.\n\nUser | Last sign in | Phishing resistant method registered |\n| :--- | :--- | :---: |\n|[Hayden Scott Test](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/UserAuthMethods/userId/6f467d0a-25ec-435c-8fb9-9d53eb21e02f/hidePreviewBanner~/true)| 2026-03-03 | ❌ |\n|[Alex Johnson](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/UserAuthMethods/userId/e436ca15-3a39-4dcc-819e-7dbb246cd46b/hidePreviewBanner~/true)| Unknown | ❌ |\n|[Hayden Scott](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/UserAuthMethods/userId/0d6cfd05-fc46-440b-b605-66dd26dcd7d2/hidePreviewBanner~/true)| 01/28/2026 12:30:09 | ❌ |\n|[Hayden Scott](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/UserAuthMethods/userId/c0b65b13-37b1-4081-bcfc-14844159b4a5/hidePreviewBanner~/true)| 05/18/2026 07:31:59 | ❌ |\n|[Agent User Example 3791943](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/UserAuthMethods/userId/76112b45-5214-4fa5-8054-30bafc588e5e/hidePreviewBanner~/true)| Unknown | ❌ |\n|[Agent User Example 3792567](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/UserAuthMethods/userId/7ecf3e6f-2343-455e-8d4f-73d661ac3ae3/hidePreviewBanner~/true)| Unknown | ❌ |\n|[Agent User Example 3792993](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/UserAuthMethods/userId/b5d9a21a-3d15-474b-abd0-21c8d3c65589/hidePreviewBanner~/true)| Unknown | ❌ |\n|[Agent User Example 4181693](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/UserAuthMethods/userId/d83e2c6c-7e80-4343-b8ec-7fc49b1b100d/hidePreviewBanner~/true)| Unknown | ❌ |\n|[Agent User Example 4208366](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/UserAuthMethods/userId/d0ce1a0b-90a1-4493-92ca-58abbe556065/hidePreviewBanner~/true)| Unknown | ❌ |\n|[Agent User Example 4208785](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/UserAuthMethods/userId/e3916bda-a99d-47c6-8a28-4f89540c32b8/hidePreviewBanner~/true)| Unknown | ❌ |\n|[Agent User Example 4209371](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/UserAuthMethods/userId/f863e6af-79b3-46e4-82a6-dc47ee626346/hidePreviewBanner~/true)| Unknown | ❌ |\n|[Jordan Smith](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/UserAuthMethods/userId/bfaeba1e-1357-47de-9557-529caa103d5d/hidePreviewBanner~/true)| 05/18/2026 12:58:28 | ❌ |\n|[Taylor Brown](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/UserAuthMethods/userId/2072badc-3cf0-4e84-b4c2-f9c065c46165/hidePreviewBanner~/true)| Unknown | ❌ |\n|[Casey Davis](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/UserAuthMethods/userId/58d9ed99-93ca-4674-8c5f-ec770f5ba17d/hidePreviewBanner~/true)| Unknown | ❌ |\n|[antivirustest](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/UserAuthMethods/userId/1d131633-dd0e-4438-8ceb-df7577d2e0fd/hidePreviewBanner~/true)| Unknown | ❌ |\n|[ash-williams-test](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/UserAuthMethods/userId/c5c8ba63-4620-4e91-ac40-b66bebe07a0d/hidePreviewBanner~/true)| 2026-03-03 | ❌ |\n|[Morgan Wilson](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/UserAuthMethods/userId/5655cf54-34bc-4f36-bb74-44da35547975/hidePreviewBanner~/true)| Unknown | ❌ |\n|[Riley Martinez](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/UserAuthMethods/userId/653c7fdd-1b41-4229-992a-69cc35aad4f7/hidePreviewBanner~/true)| Unknown | ❌ |\n|[Cameron Anderson](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/UserAuthMethods/userId/1ce4078f-f795-4baf-aa55-1fdfcc2ebfe6/hidePreviewBanner~/true)| 05/18/2026 07:26:20 | ❌ |\n|[Avery Thomas](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/UserAuthMethods/userId/f431700c-6d81-45b8-8f8d-581a8aa7cda6/hidePreviewBanner~/true)| 01/20/2024 08:00:27 | ❌ |\n|[Daniel Nguyen](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/UserAuthMethods/userId/ddfb9311-801e-4a84-9466-a18086768b73/hidePreviewBanner~/true)| Unknown | ❌ |\n|[David Kim](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/UserAuthMethods/userId/1b156c3d-79c5-44d2-a88c-23f69216777f/hidePreviewBanner~/true)| Unknown | ❌ |\n|[Emma Johnson](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/UserAuthMethods/userId/e498eab5-b6b5-493f-8353-b8c350083791/hidePreviewBanner~/true)| Unknown | ❌ |\n|[Faiza Malkia](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/UserAuthMethods/userId/36bf7e02-3abc-46aa-895f-cf95227377fd/hidePreviewBanner~/true)| Unknown | ❌ |\n|[Jamie Rodriguez](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/UserAuthMethods/userId/0b37813c-ae19-4399-982f-16587f17f9c0/hidePreviewBanner~/true)| 05/18/2026 07:34:56 | ❌ |\n|[Dakota Lee](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/UserAuthMethods/userId/e4bc6f4a-124f-469b-8951-3d5c34fb9741/hidePreviewBanner~/true)| 11/15/2023 18:36:22 | ❌ |\n|[Hamisi Khari](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/UserAuthMethods/userId/494995bf-5510-450c-a317-6d24f63cd15b/hidePreviewBanner~/true)| Unknown | ❌ |\n|[Henrietta Mueller](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/UserAuthMethods/userId/eb6a4040-3ff6-4911-a80d-68c701384c38/hidePreviewBanner~/true)| Unknown | ❌ |\n|[HR Agent](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/UserAuthMethods/userId/143c26fd-d308-4cb4-9c80-b54e66d6192c/hidePreviewBanner~/true)| Unknown | ❌ |\n|[Skylar White](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/UserAuthMethods/userId/2a054082-8f05-4e05-8fce-4e35c3bb40cc/hidePreviewBanner~/true)| 2023-12-12 | ❌ |\n|[Jules Bailey](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/UserAuthMethods/userId/0145d508-50fd-4f86-a47a-bf1c043c8358/hidePreviewBanner~/true)| Unknown | ❌ |\n|[James Thompson](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/UserAuthMethods/userId/ba635de8-4625-42eb-a59a-87f507ad9a9e/hidePreviewBanner~/true)| Unknown | ❌ |\n|[Jane Doe](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/UserAuthMethods/userId/57c41b80-a96a-4c06-8ab9-9539818a637f/hidePreviewBanner~/true)| Unknown | ❌ |\n|[Jessica Taylor](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/UserAuthMethods/userId/983164a3-87fa-4071-aa67-ff1530092df1/hidePreviewBanner~/true)| Unknown | ❌ |\n|[Johanna Lorenz](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/UserAuthMethods/userId/8994aee7-8c36-4e04-9116-8f21d8acdeb7/hidePreviewBanner~/true)| Unknown | ❌ |\n|[John Doe Test 1](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/UserAuthMethods/userId/69a2da18-6395-4a90-bde8-72e8aaa6c775/hidePreviewBanner~/true)| Unknown | ❌ |\n|[John Doe Test 1](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/UserAuthMethods/userId/fcebe3cc-ca26-49c6-9bb1-c9eafb243634/hidePreviewBanner~/true)| Unknown | ❌ |\n|[John1 Doe](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/UserAuthMethods/userId/77d4be98-c05d-4478-be25-3ee710b5247e/hidePreviewBanner~/true)| 2024-04-11 | ❌ |\n|[Joni Sherman](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/UserAuthMethods/userId/2da436f2-952a-47de-9dfe-84bd2f0d93e9/hidePreviewBanner~/true)| Unknown | ❌ |\n|[peyton-test](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/UserAuthMethods/userId/e0952dcb-8d63-496d-8661-05c86c1a51f0/hidePreviewBanner~/true)| 2026-03-03 | ❌ |\n|[Peyton Clark](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/UserAuthMethods/userId/7e92f268-bb12-469a-a869-210d596d4c1f/hidePreviewBanner~/true)| 03/17/2026 03:14:18 | ❌ |\n|[Lee Gu](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/UserAuthMethods/userId/0a9e313b-8777-4741-ba14-0f2724179117/hidePreviewBanner~/true)| Unknown | ❌ |\n|[Lidia Holloway](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/UserAuthMethods/userId/9188d3d3-386c-4145-a811-0d777a288e11/hidePreviewBanner~/true)| Unknown | ❌ |\n|[Lynne Robbins](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/UserAuthMethods/userId/8e5f7749-d5e7-46fc-8eb7-3b8ab7e20ae5/hidePreviewBanner~/true)| Unknown | ❌ |\n|[Charlie Lewis](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/UserAuthMethods/userId/5b0ec3ff-cea1-4eb9-8530-f2a66e5bec0a/hidePreviewBanner~/true)| 07/30/2025 03:28:21 | ❌ |\n|[Finley Robinson](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/UserAuthMethods/userId/990fd38a-c516-4e3f-82e4-d458a1ab0f91/hidePreviewBanner~/true)| 05/18/2026 08:23:54 | ❌ |\n|[finley-test](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/UserAuthMethods/userId/d71ccc09-c0a3-4604-9d02-49f7a3715f49/hidePreviewBanner~/true)| 2026-03-03 | ❌ |\n|[Sam Parker](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/UserAuthMethods/userId/96d29f01-873c-46a3-b542-f7ee192cc675/hidePreviewBanner~/true)| 06/28/2025 12:47:54 | ❌ |\n|[Ash Williams](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/UserAuthMethods/userId/a0883b7a-c6a8-440f-84f0-d6e1b79aaf4c/hidePreviewBanner~/true)| 2025-10-08 | ❌ |\n|[Michael Wong](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/UserAuthMethods/userId/63e4e634-15e4-4a85-bc9c-532855574377/hidePreviewBanner~/true)| Unknown | ❌ |\n|[Miriam Graham](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/UserAuthMethods/userId/f5745554-1894-4fb0-9560-65d6fc489724/hidePreviewBanner~/true)| Unknown | ❌ |\n|[Nestor Wilke](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/UserAuthMethods/userId/24b9254d-1bc5-435c-ad3d-7dbee86f8b9a/hidePreviewBanner~/true)| Unknown | ❌ |\n|[New User](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/UserAuthMethods/userId/6eef8ea0-1263-4973-9b0b-1e7aed0d21cd/hidePreviewBanner~/true)| Unknown | ❌ |\n|[No Location](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/UserAuthMethods/userId/696743fa-055b-42fb-aac4-ab451a4617d6/hidePreviewBanner~/true)| Unknown | ❌ |\n|[NoMail Enabled](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/UserAuthMethods/userId/a740d122-ee21-4354-9423-adccf8b6b233/hidePreviewBanner~/true)| Unknown | ❌ |\n|[Olivia Patel](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/UserAuthMethods/userId/03a5c332-4d75-47fd-b211-838e8cd0ee1b/hidePreviewBanner~/true)| Unknown | ❌ |\n|[On-Premises Directory Synchronization Service Account](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/UserAuthMethods/userId/33956e9a-cb54-42e9-94e8-d8f6ba05a55f/hidePreviewBanner~/true)| 06/17/2024 04:12:01 | ❌ |\n|[Patti Fernandez](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/UserAuthMethods/userId/3bae3a95-7605-4271-8418-e35733991834/hidePreviewBanner~/true)| Unknown | ❌ |\n|[Pradeep Gupta](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/UserAuthMethods/userId/ac712f60-0052-4911-8c5d-146cf9d4dc59/hidePreviewBanner~/true)| Unknown | ❌ |\n|[parker-test](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/UserAuthMethods/userId/c1bdb03c-0079-40b1-96a8-3595de3b94a2/hidePreviewBanner~/true)| 2026-09-03 | ❌ |\n|[Ellis Cooper](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/UserAuthMethods/userId/1433571b-3d7c-4a56-a9cc-67580848bc73/hidePreviewBanner~/true)| 09/23/2025 23:03:25 | ❌ |\n|[Rhea Stone](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/UserAuthMethods/userId/ac49a6e5-09c1-404b-915e-0d28574b3d72/hidePreviewBanner~/true)| Unknown | ❌ |\n|[Richard Wilkings](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/UserAuthMethods/userId/c27e2b23-c322-4a79-8c6f-9dba8fd9f4e2/hidePreviewBanner~/true)| Unknown | ❌ |\n|[Roi Fraguela](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/UserAuthMethods/userId/e0a814e5-5169-4af2-bb19-63930b42ac41/hidePreviewBanner~/true)| Unknown | ❌ |\n|[Ryan Chen](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/UserAuthMethods/userId/9605b9f8-9823-4c33-8018-57ad32d9fcb9/hidePreviewBanner~/true)| Unknown | ❌ |\n|[Sage Bennett](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/UserAuthMethods/userId/518ce209-faf4-4717-add9-7129a669fa11/hidePreviewBanner~/true)| 05/18/2026 07:55:35 | ❌ |\n|[Sandy](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/UserAuthMethods/userId/d5e32d0c-3f3c-43ef-abe1-75890a73f40c/hidePreviewBanner~/true)| Unknown | ❌ |\n|[Sarah Mehrotra](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/UserAuthMethods/userId/2d79a82a-ae19-461a-a0aa-807045ec3c4e/hidePreviewBanner~/true)| 05/18/2026 08:02:51 | ❌ |\n|[Sarah Mitchell](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/UserAuthMethods/userId/0ca3a9f0-7e3c-44c5-9638-250be0d94621/hidePreviewBanner~/true)| Unknown | ❌ |\n|[Shonali Balakrishna](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/UserAuthMethods/userId/305bbf73-eee4-4e0c-9c7d-627e00ed3665/hidePreviewBanner~/true)| 2025-05-05 | ❌ |\n|[Simon Burn](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/UserAuthMethods/userId/c3aab1a2-0733-438d-bc14-90dc8f6d876d/hidePreviewBanner~/true)| Unknown | ❌ |\n|[Sophia Rodriguez](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/UserAuthMethods/userId/d5d9f31f-c8d7-4b6c-bfca-b25b1cd4c1f1/hidePreviewBanner~/true)| Unknown | ❌ |\n|[Tegra Núnez](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/UserAuthMethods/userId/25e54254-3719-4c07-a880-3aee6bc60876/hidePreviewBanner~/true)| Unknown | ❌ |\n|[Tracy yu](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/UserAuthMethods/userId/80153e0b-dcce-42de-9df6-59a3fc89479b/hidePreviewBanner~/true)| Unknown | ❌ |\n|[Dakota Lee](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/UserAuthMethods/userId/210d3e96-015f-462d-b6d6-81e6023263df/hidePreviewBanner~/true)| 2026-01-05 | ❌ |\n|[Dakota Lee Test](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/UserAuthMethods/userId/43482f27-d1af-420f-84ba-e9148a700f45/hidePreviewBanner~/true)| 05/18/2026 08:24:19 | ❌ |\n|[Phoenix Gray](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/UserAuthMethods/userId/7094fb23-003a-4f81-9796-5daeaa603003/hidePreviewBanner~/true)| 2025-04-02 | ❌ |\n|[Rowan Foster](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/UserAuthMethods/userId/7804b01c-1223-4045-a393-43171298fa6b/hidePreviewBanner~/true)| Unknown | ❌ |\n|[usernonick](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/UserAuthMethods/userId/b531f68f-8d01-467b-9db6-a57438b0e8af/hidePreviewBanner~/true)| Unknown | ❌ |\n|[Avery Brooks](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/UserAuthMethods/userId/a85798bd-652b-4eb9-ba90-3ee882df0179/hidePreviewBanner~/true)| 02/19/2026 11:02:30 | ❌ |\n|[Wilna Rossouw](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/UserAuthMethods/userId/62cd4528-8e5d-4789-84f6-8b33d0af5ca7/hidePreviewBanner~/true)| Unknown | ❌ |\n|[Yakup Meredow](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/UserAuthMethods/userId/767bcbda-28a0-4e5f-841d-e918c5a1c229/hidePreviewBanner~/true)| Unknown | ❌ |\n|[Alex Wilber](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/UserAuthMethods/userId/f10bc459-0bcf-49d0-8f86-4553b8f015b8/hidePreviewBanner~/true)| 2026-03-05 | ✅ |\n|[Diego Siciliani](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/UserAuthMethods/userId/cdfa577c-972f-4399-98aa-1ec4be7fa6d1/hidePreviewBanner~/true)| 06/28/2025 23:31:12 | ✅ |\n|[Quinn Garcia](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/UserAuthMethods/userId/ceef37b7-c865-48fb-80c9-4def11201854/hidePreviewBanner~/true)| 2025-06-12 | ✅ |\n|[Reese Harris](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/UserAuthMethods/userId/babe04c9-8340-4329-a727-a8cee0cd2b1a/hidePreviewBanner~/true)| 04/20/2026 01:11:33 | ✅ |\n|[Ash Williams](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/UserAuthMethods/userId/513f3db2-044c-41be-af14-431bf88a2b3e/hidePreviewBanner~/true)| 05/18/2026 08:56:31 | ✅ |\n|[Drew Mitchell](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/UserAuthMethods/userId/df02402a-e291-42cc-b449-79366daa2a40/hidePreviewBanner~/true)| 05/16/2026 06:01:47 | ✅ |\n\n\n","TestStatus":"Failed","TestDescription":"Attackers might gain access if multifactor authentication (MFA) isn't universally enforced or if there are exceptions in place. Attackers might gain access by exploiting vulnerabilities of weaker MFA methods like SMS and phone calls through social engineering techniques. These techniques might include SIM swapping or phishing, to intercept authentication codes.\n\nAttackers might use these accounts as entry points into the tenant. By using intercepted user sessions, attackers can disguise their activities as legitimate user actions, evade detection, and continue their attack without raising suspicion. From there, they might attempt to manipulate MFA settings to establish persistence, plan, and execute further attacks based on the privileges of compromised accounts.\n\n**Remediation action**\n\n- [Deploy multifactor authentication](https://learn.microsoft.com/entra/identity/authentication/howto-mfa-getstarted?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci)\n- [Get started with a phishing-resistant passwordless authentication deployment](https://learn.microsoft.com/entra/identity/authentication/how-to-plan-prerequisites-phishing-resistant-passwordless-authentication?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci)\n- [Deploy a Conditional Access policy to require phishing-resistant MFA for all users](https://learn.microsoft.com/entra/identity/conditional-access/policy-all-users-mfa-strength?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci)\n- [Review authentication methods activity](https://learn.microsoft.com/entra/identity/monitoring-health/concept-usage-insights-report?tabs=microsoft-entra-admin-center&wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci#authentication-methods-activity)\n","TestId":"21801"},{"TestImplementationCost":"High","TestPillar":"Identity","TestCategory":"Application management","SkippedReason":null,"TestImpact":"Low","TestAppliesTo":["Identity"],"TestSfiPillar":"Protect engineering systems","TestSkipped":"","TestMinimumLicense":"P1","TestTags":["Identity"],"TestTitle":"App registrations use safe redirect URIs","TestRisk":"High","TestResult":"\nUnsafe redirect URIs found\n\n1️⃣ → Use of http(s) instead of https, 2️⃣ → Use of *.azurewebsites.net, 3️⃣ → Invalid URL, 4️⃣ → Domain not resolved\n\n| | Name | Unsafe redirect URIs |\n| :--- | :--- | :--- |\n| | [Azure AD SAML Toolkit](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/SignOn/objectId/4317fd0a-dcee-45bf-8e94-9a66638b11e0/appId/6f5ed68c-9fad-4d78-bf88-2b16bbe16338/preferredSingleSignOnMode/saml/servicePrincipalType/Application/fromNav/) | `2️⃣ https://samltoolkit.azurewebsites.net/SAML/Consume` | |\n| | [My nice app](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/SignOn/objectId/d41cfc13-11d1-4f93-835a-88e729725564/appId/2946f286-2b59-4f29-876c-0ed8bbe1c482/preferredSingleSignOnMode/saml/servicePrincipalType/Application/fromNav/) | `2️⃣ https://mysalmon.azurewebsites.net/login.saml` | |\n| | [MyVisualStudioMcpClient](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/SignOn/objectId/cae606b7-4a44-4d07-a7a5-a6fb285e41f1/appId/84ad8697-445d-4b26-affd-1b1459e97aae/preferredSingleSignOnMode/saml/servicePrincipalType/Application/fromNav/) | `1️⃣ http://127.0.0.1:33418` | |\n| | [MyVscode](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/SignOn/objectId/dfc83a5d-36e5-4506-ae9d-6ad5bb403377/appId/92abdce1-3952-4a8b-8720-e59257edd421/preferredSingleSignOnMode/saml/servicePrincipalType/Application/fromNav/) | `1️⃣ http://127.0.0.1:33418` | |\n| | [saml test app](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/SignOn/objectId/daa6074c-db6f-4bdc-a41b-bc0052c536a5/appId/c266d677-a5f8-47bc-9f0a-1b6fbe0bddad/preferredSingleSignOnMode/saml/servicePrincipalType/Application/fromNav/) | `2️⃣ https://appclaims.azurewebsites.net/signin-saml`, `2️⃣ https://appclaims.azurewebsites.net/signin-oidc` | |\n\n\n","TestStatus":"Failed","TestDescription":"OAuth applications configured with URLs that include wildcards, or URL shorteners increase the attack surface for threat actors. Insecure redirect URIs (reply URLs) might allow adversaries to manipulate authentication requests, hijack authorization codes, and intercept tokens by directing users to attacker-controlled endpoints. Wildcard entries expand the risk by permitting unintended domains to process authentication responses, while shortener URLs might facilitate phishing and token theft in uncontrolled environments. \n\nWithout strict validation of redirect URIs, attackers can bypass security controls, impersonate legitimate applications, and escalate their privileges. This misconfiguration enables persistence, unauthorized access, and lateral movement, as adversaries exploit weak OAuth enforcement to infiltrate protected resources undetected.\n\n**Remediation action**\n\n- [Check the redirect URIs for your application registrations.](https://learn.microsoft.com/entra/identity-platform/reply-url?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci) Make sure the redirect URIs don't have *.azurewebsites.net, wildcards, or URL shorteners.\n","TestId":"21885"},{"TestImplementationCost":"Medium","TestPillar":"Identity","TestCategory":"Access control","SkippedReason":"UnderConstruction","TestImpact":"Low","TestAppliesTo":["Identity"],"TestSfiPillar":"Protect identities and secrets","TestSkipped":"UnderConstruction","TestMinimumLicense":null,"TestTags":["Identity"],"TestTitle":"Guest identities are lifecycle managed with access reviews","TestRisk":"Medium","TestResult":"\nPlanned for future release.\n","TestStatus":"Planned","TestDescription":"...\n\n**Remediation action**\n\n","TestId":"21857"},{"TestImplementationCost":"Low","TestPillar":"Identity","TestCategory":"Privileged access","SkippedReason":"UnderConstruction","TestImpact":"Low","TestAppliesTo":["Identity"],"TestSfiPillar":"Protect tenants and isolate production systems","TestSkipped":"UnderConstruction","TestMinimumLicense":"P1","TestTags":["Identity"],"TestTitle":"Conditional Access protected actions are enabled","TestRisk":"Medium","TestResult":"\nPlanned for future release.\n\n","TestStatus":"Planned","TestDescription":"Threat actors who gain privileged access to a tenant can manipulate identity, access, and security configurations. This type of attack can result in environment-wide compromise and loss of control over organizational assets. Take action to protect high-impact management tasks associated with Conditional Access policies, cross-tenant access settings, hard deletions, and network locations that are critical to maintaining security.\n\nProtected actions let administrators secure these tasks with extra security controls, such as stronger authentication methods (passwordless MFA or phishing-resistant MFA), the use of Privileged Access Workstation (PAW) devices, or shorter session timeouts.\n\n**Remediation action**\n\n- [Add, test, or remove protected actions in Microsoft Entra ID](https://learn.microsoft.com/entra/identity/role-based-access-control/protected-actions-add?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci)\n","TestId":"21831"},{"TestImplementationCost":"Low","TestPillar":"Identity","TestCategory":"Access control","SkippedReason":"This test is for tenants that are licensed for Entra Workload ID. See [Entra Workload ID licensing](https://learn.microsoft.com/entra/workload-id/workload-identities-faqs)","TestImpact":"High","TestAppliesTo":null,"TestSfiPillar":"Accelerate response and remediation","TestSkipped":"NotLicensedEntraWorkloadID","TestMinimumLicense":"Workload","TestTags":null,"TestTitle":"Workload Identities are configured with risk-based policies","TestRisk":"Medium","TestResult":"\nSkipped. This test is for tenants that are licensed for Entra Workload ID. See [Entra Workload ID licensing](https://learn.microsoft.com/entra/workload-id/workload-identities-faqs)\n\n","TestStatus":"Skipped","TestDescription":"Set up risk-based Conditional Access policies for workload identities based on risk policy in Microsoft Entra ID to make sure only trusted and verified workloads use sensitive resources. Without these policies, threat actors can compromise workload identities with minimal detection and perform further attacks. Without conditional controls to detect anomalous activity and other risks, there's no check against malicious operations like token forgery, access to sensitive resources, and disruption of workloads. The lack of automated containment mechanisms increases dwell time and affects the confidentiality, integrity, and availability of critical services. \n\n**Remediation action**\nCreate a risk-based Conditional Access policy for workload identities.\n- [Create a risk-based Conditional Access policy](https://learn.microsoft.com/entra/identity/conditional-access/workload-identity?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci#create-a-risk-based-conditional-access-policy)\n","TestId":21883},{"TestImplementationCost":"Low","TestPillar":"Identity","TestCategory":"Credential management","SkippedReason":null,"TestImpact":"Low","TestAppliesTo":null,"TestSfiPillar":"Protect identities and secrets","TestSkipped":"","TestMinimumLicense":"Free","TestTags":null,"TestTitle":"Security key authentication method enabled","TestRisk":"High","TestResult":"\nSecurity key authentication method is enabled for your tenant, providing hardware-backed phishing-resistant authentication.\n\n\n## FIDO2 security key authentication settings\n\n✅ **FIDO2 authentication method**\n- Status: Enabled\n- Include targets: All users\n- Exclude targets: None\n\n\n\n","TestStatus":"Passed","TestDescription":"FIDO2 security keys provide hardware-backed, phishing-resistant authentication that protects against credential theft and unauthorized access. Security keys use cryptographic proof of identity bound to a specific device, making credentials impossible to replicate or phish. Enabling this authentication method allows users to register security keys for strong passwordless authentication.\n\n**Remediation action**\n\n- [Enable FIDO2 security key authentication method](https://learn.microsoft.com/entra/identity/authentication/how-to-enable-passkey-fido2?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci#enable-passkey-fido2-authentication-method)\n- [Manage authentication methods](https://learn.microsoft.com/entra/identity/authentication/concept-authentication-methods-manage?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci)\n","TestId":"21838"},{"TestImplementationCost":"","TestPillar":"Infrastructure","TestCategory":"Implement security best practices","SkippedReason":null,"TestImpact":"","TestAppliesTo":null,"TestSfiPillar":"Protect tenants and isolate production systems","TestSkipped":"","TestMinimumLicense":"N/A","TestTags":null,"TestTitle":"Subnets should be associated with a network security group","TestRisk":"Low","TestResult":"Subnets should be associated with a network security group\n\n| Subscription | Resource group | Resource type | Affected resource | Status | Azure portal |\n| :----------- | :------------- | :------------ | :---------------- | :----- | :----------- |\n| [Visual Studio Enterprise Subscription](https://portal.azure.com/#resource/subscriptions/54d3ea01-5a07-45d0-8d69-e5f5b0b20098) | indiavm_group | virtualnetworks | [default](https://portal.azure.com/#resource/subscriptions/54d3ea01-5a07-45d0-8d69-e5f5b0b20098/resourceGroups/indiavm_group/providers/Microsoft.Network/virtualNetworks/indiavm-vnet/subnets/default) | ❌ | [View recommendation](https://portal.azure.com/#blade/Microsoft_Azure_Security/RecommendationsBlade/assessmentKey/eade5b56-eefd-444f-95c8-23f29e5d93cb/resourceId/%2fsubscriptions%2f54d3ea01-5a07-45d0-8d69-e5f5b0b20098%2fresourceGroups%2findiavm_group%2fproviders%2fMicrosoft.Network%2fvirtualNetworks%2findiavm-vnet%2fsubnets%2fdefault) |\n| [Visual Studio Enterprise Subscription](https://portal.azure.com/#resource/subscriptions/54d3ea01-5a07-45d0-8d69-e5f5b0b20098) | charlie | virtualnetworks | [default](https://portal.azure.com/#resource/subscriptions/54d3ea01-5a07-45d0-8d69-e5f5b0b20098/resourceGroups/charlie/providers/Microsoft.Network/virtualNetworks/charlie-vnet/subnets/default) | ❌ | [View recommendation](https://portal.azure.com/#blade/Microsoft_Azure_Security/RecommendationsBlade/assessmentKey/eade5b56-eefd-444f-95c8-23f29e5d93cb/resourceId/%2fsubscriptions%2f54d3ea01-5a07-45d0-8d69-e5f5b0b20098%2fresourceGroups%2fcharlie%2fproviders%2fMicrosoft.Network%2fvirtualNetworks%2fcharlie-vnet%2fsubnets%2fdefault) |\n","TestStatus":"Failed","TestDescription":"Protect your subnet from potential threats by restricting access to it with a network security group (NSG). NSGs contain a list of Access Control List (ACL) rules that allow or deny network traffic to your subnet. When an NSG is associated with a subnet, the ACL rules apply to all the VM instances and integrated services in that subnet, but don't apply to internal traffic inside the subnet. To secure resources in the same subnet from one another, enable NSG directly on the resources as well.
Note that the following subnet types will be listed as not applicable: GatewaySubnet, AzureFirewallSubnet, AzureBastionSubnet.\n\n**Remediation action**\n\nTo enable Network Security Groups on your subnets:
1. Select a subnet to enable NSG on.
2. Click the 'Network security group' section.
3. Follow the steps and select an existing network security group to attach to this specific subnet.","TestId":"eade5b56-eefd-444f-95c8-23f29e5d93cb"},{"TestImplementationCost":"Medium","TestPillar":"Identity","TestCategory":"Privileged access","SkippedReason":null,"TestImpact":"Low","TestAppliesTo":null,"TestSfiPillar":"Protect identities and secrets","TestSkipped":"","TestMinimumLicense":"P2","TestTags":null,"TestTitle":"Activation alert for all privileged role assignments","TestRisk":"Low","TestResult":"\nActivation alerts are configured for privileged role assignments.\n\n","TestStatus":"Passed","TestDescription":"Without activation alerts for privileged role assignments, threat actors can escalate privileges undetected. This lack of visibility creates a blind spot where attackers can activate the most privileged role and perform malicious actions such as creating backdoor accounts, modifying security policies, or accessing sensitive data.\n\nMonitoring these activation alerts can help security teams distinguish between authorized and unauthorized privilege escalation activities. \n\n**Remediation action**\n\n- [Configure notifications for privileged roles](https://learn.microsoft.com/entra/id-governance/privileged-identity-management/pim-how-to-change-default-settings?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci#require-justification-on-active-assignment)\n","TestId":"21820"},{"TestImplementationCost":"","TestPillar":"Infrastructure","TestCategory":"Restrict unauthorized network access","SkippedReason":null,"TestImpact":"","TestAppliesTo":null,"TestSfiPillar":"Protect tenants and isolate production systems","TestSkipped":"","TestMinimumLicense":"N/A","TestTags":null,"TestTitle":"Internet-facing virtual machines should be protected with network security groups","TestRisk":"High","TestResult":"Internet-facing virtual machines should be protected with network security groups\n\n| Subscription | Resource group | Resource type | Affected resource | Status | Azure portal |\n| :----------- | :------------- | :------------ | :---------------- | :----- | :----------- |\n| [Visual Studio Enterprise Subscription](https://portal.azure.com/#resource/subscriptions/54d3ea01-5a07-45d0-8d69-e5f5b0b20098) | indiavm_group | virtualmachines | [india-2](https://portal.azure.com/#resource/subscriptions/54d3ea01-5a07-45d0-8d69-e5f5b0b20098/resourceGroups/INDIAVM_GROUP/providers/Microsoft.Compute/virtualMachines/india-2) | ✅ | [View recommendation](https://portal.azure.com/#blade/Microsoft_Azure_Security/RecommendationsBlade/assessmentKey/483f12ed-ae23-447e-a2de-a67a10db4353/resourceId/%2fsubscriptions%2f54d3ea01-5a07-45d0-8d69-e5f5b0b20098%2fresourceGroups%2fINDIAVM_GROUP%2fproviders%2fMicrosoft.Compute%2fvirtualMachines%2findia-2) |\n| [Visual Studio Enterprise Subscription](https://portal.azure.com/#resource/subscriptions/54d3ea01-5a07-45d0-8d69-e5f5b0b20098) | indiavm_group | virtualmachines | [indiavm](https://portal.azure.com/#resource/subscriptions/54d3ea01-5a07-45d0-8d69-e5f5b0b20098/resourceGroups/INDIAVM_GROUP/providers/Microsoft.Compute/virtualMachines/indiavm) | ✅ | [View recommendation](https://portal.azure.com/#blade/Microsoft_Azure_Security/RecommendationsBlade/assessmentKey/483f12ed-ae23-447e-a2de-a67a10db4353/resourceId/%2fsubscriptions%2f54d3ea01-5a07-45d0-8d69-e5f5b0b20098%2fresourceGroups%2fINDIAVM_GROUP%2fproviders%2fMicrosoft.Compute%2fvirtualMachines%2findiavm) |\n","TestStatus":"Passed","TestDescription":"Protect your VM from potential threats by restricting access to it with a network security group (NSG). NSGs contain a list of Access Control List (ACL) rules that allow or deny network traffic to your VM from other instances, in or outside the same subnet.
To keep your machine as secure as possible, the VM access to the internet must be restricted and an NSG should be enabled on the subnet.
VMs with 'High' severity are internet-facing VMs.\n\n**Remediation action**\n\nTo protect a virtual machine with a Network Security Group:
1. Select a VM from the list below, or click \"Take action\" if you've arrived from a recommendation for a specific VM.
2. Assign the relevant NSG to the NIC or subnet for the VM you're protecting:
  a. To assign the NSG to the VM's subnet (recommended):
    i. In the Networking page, select the 'Virtual network/subnet'.
    ii. Open the \"Subnets\" menu.
    iii. Select the subnet where your VM is deployed.
    iv. Select the Network Security Group to assign to the subnet and click \"Save\".
  b. To assign the NSG to the NIC:
    i. In the Networking page, select the network interface that's associated with the selected VM.
    ii. In the Network interfaces page, select the 'Network security group' menu item.
    iii. Click 'Edit' at the top of the page.
    iv. Follow the on-screen instructions and select the Network Security Group to assign to this NIC.
Learn more.","TestId":"483f12ed-ae23-447e-a2de-a67a10db4353"},{"TestImplementationCost":"Medium","TestPillar":"Devices","TestCategory":"Data","SkippedReason":null,"TestImpact":"Low","TestAppliesTo":null,"TestSfiPillar":"Protect networks","TestSkipped":"","TestMinimumLicense":"Intune","TestTags":null,"TestTitle":"Corporate Wi-Fi network on iOS devices is securely managed","TestRisk":"High","TestResult":"\nNo Enterprise Wi-Fi profile for iOS exists or none are assigned.\n\n\n## iOS WiFi Configuration Profiles\n\n| Policy Name | Wi-Fi Security Type | Status | Assignment |\n| :---------- | :----- | :--------- | :--------- |\n| [Wifi test WPAEnterprise](https://intune.microsoft.com/#view/Microsoft_Intune_DeviceSettings/DevicesIosMenu/~/configuration) | Enterprise | ❌ Not Assigned | None |\n\n\n\n","TestStatus":"Failed","TestDescription":"If Wi-Fi profiles aren't properly configured and assigned, users can connect insecurely or fail to connect to trusted networks, exposing corporate data to interception or unauthorized access. Without centralized management, devices rely on manual configuration, increasing the risk of misconfiguration, weak authentication, and connection to rogue networks.\n\nCentrally managing Wi-Fi profiles for iOS devices in Intune ensures secure and consistent connectivity to enterprise networks. This enforces authentication and encryption standards, simplifies onboarding, and supports Zero Trust by reducing exposure to untrusted networks.\n\n**Remediation action**\n\nUse Intune to configure and assign secure Wi-Fi profiles for iOS/iPadOS devices to enforce authentication and encryption standards:\n\n- [Deploy Wi-Fi profiles to devices in Microsoft Intune](https://learn.microsoft.com/intune/intune-service/configuration/wi-fi-settings-configure?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci#create-the-profile)\n\nFor more information, see: \n- [Review the available Wi-Fi settings for iOS and iPadOS devices in Microsoft Intune](https://learn.microsoft.com/intune/intune-service/configuration/wi-fi-settings-ios?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci)\n","TestId":"24839"},{"TestImpact":"Low","TestRisk":"Medium","TestSkipped":"NotConnectedToService","TestAppliesTo":null,"TestPillar":"Data","TestCategory":"SharePoint Online","TestDescription":"When PDF labeling is disabled (the default) in SharePoint, PDF files can't be labeled or display existing labels, which creates a protection gap. Unlike Office files, PDFs can circulate externally without visible classification markers, making it impossible for recipients to determine the handling requirements or for data loss prevention (DLP) policies to detect sensitive content.\n\nEnabling PDF labeling for SharePoint and OneDrive extends sensitivity label support to PDFs, allowing users to apply labels by using Office for the web and SharePoint, and supports other labeling methods such as auto-labeling policies to classify PDF content automatically.\n\n**Remediation action**\n\n- [Enable sensitivity labels for PDF files in SharePoint and OneDrive](https://learn.microsoft.com/purview/sensitivity-labels-sharepoint-onedrive-files?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci#adding-support-for-pdf)\n","TestTitle":"PDF labeling is enabled in SharePoint","SkippedReason":"This test requires connection to the service(s) \"SharePointOnline\" currently disconnected. Please use _Connect-ZtAssessment_ to connect.","TestId":"35006","TestImplementationCost":"Low","TestMinimumLicense":["RMS_S_PREMIUM"],"TestSfiPillar":"Protect tenants and production systems","TestResult":"\nSkipped. This test requires connection to the service(s) \"SharePointOnline\" currently disconnected. Please use _Connect-ZtAssessment_ to connect.\n\n","TestStatus":"Skipped","TestTags":null},{"TestImpact":"High","TestRisk":"Medium","TestSkipped":"","TestAppliesTo":null,"TestPillar":"Identity","TestCategory":"Access control","TestDescription":"Attackers might exploit valid but inactive applications that still have elevated privileges. These applications can be used to gain initial access without raising alarm because they’re legitimate applications. From there, attackers can use the application privileges to plan or execute other attacks. Attackers might also maintain access by manipulating the inactive application, such as by adding credentials. This persistence ensures that even if their primary access method is detected, they can regain access later.\n\n**Remediation action**\n\n- [Disable privileged service principals](https://learn.microsoft.com/graph/api/serviceprincipal-update?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci)\n- Investigate if the application has legitimate use cases\n- [If service principal doesn't have legitimate use cases, delete it](https://learn.microsoft.com/graph/api/serviceprincipal-delete?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci)\n","TestTitle":"Inactive applications don't have highly privileged permissions","SkippedReason":null,"TestId":"21770","TestImplementationCost":"Low","TestMinimumLicense":["AAD_PREMIUM"],"TestSfiPillar":"Protect engineering systems","TestResult":"\nInactive Application(s) with high privileges were found\n\n\n## Apps with privileged Graph permissions\n\n| | Name | Risk | Delegate Permission | Application Permission | App owner tenant | Last sign in|\n| :--- | :--- | :--- | :--- | :--- | :--- | :--- |\n| ❌ | [Windows Virtual Desktop AME](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/Overview/objectId/8369f33c-da25-4a8a-866d-b0145e29ef29/appId/5a0aa725-4958-4b0c-80a9-34562e23f3b7) | High | | User.Read.All, Directory.Read.All | MS Azure Cloud | Unknown | \n| ❌ | [Reset Viral Users Redemption Status](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/Overview/objectId/3a8785da-9965-473f-a97c-25fefdc39fee/appId/cc7b0696-1956-408b-876a-ad6bf2b9890b) | High | User.Read, User.Invite.All, User.ReadWrite.All, Directory.ReadWrite.All, offline_access, profile, openid | | Microsoft | Unknown | \n| ❌ | [Azure AD Assessment (Test)](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/Overview/objectId/d4cf4286-0fbe-424d-b4f2-65aa2c568631/appId/c62a9fcb-53bf-446e-8063-ea6e2bfcc023) | High | AuditLog.Read.All, Directory.AccessAsUser.All, Directory.ReadWrite.All, Group.ReadWrite.All, IdentityProvider.ReadWrite.All, Policy.ReadWrite.TrustFramework, PrivilegedAccess.ReadWrite.AzureAD, PrivilegedAccess.ReadWrite.AzureResources, TrustFrameworkKeySet.ReadWrite.All, User.Invite.All, offline_access, openid, profile | | Microsoft Accounts | Unknown | \n| ❌ | [Modern Workplace Concierge](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/Overview/objectId/ad1c51e8-f8a8-4bf2-ac09-a3a20cba5fa5/appId/c65c4011-1b90-4ec9-b5e9-1ee17786ad84) | High | openid, profile, RoleManagement.Read.Directory, Application.Read.All, User.ReadBasic.All, Group.ReadWrite.All, DeviceManagementRBAC.ReadWrite.All, Policy.ReadWrite.ConditionalAccess, Policy.Read.All, User.Read, DeviceManagementApps.ReadWrite.All, DeviceManagementConfiguration.ReadWrite.All, DeviceManagementServiceConfig.ReadWrite.All | | Nicolonsky Tech | Unknown | \n| ❌ | [Graph Explorer](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/Overview/objectId/8f8f300a-870a-46ff-bdab-934e1436920d/appId/d3ce4cf8-6810-442d-b42e-375e14710095) | High | User.Read, Directory.AccessAsUser.All | | graphExplorerMT | Unknown | \n| ❌ | [Microsoft Sample Data Packs](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/Overview/objectId/63e1f0d4-bc2c-497a-bfe2-9eb4c8c2600e/appId/a1cffbc6-1cb3-44e4-a1d2-cee9cce700f1) | High | Files.ReadWrite, User.ReadWrite | Contacts.ReadWrite, Sites.Manage.All, MailboxSettings.ReadWrite, Sites.ReadWrite.All, Calendars.ReadWrite, Sites.FullControl.All, Application.ReadWrite.OwnedBy, Calendars.ReadWrite.All, Mail.ReadWrite, User.ReadWrite.All, Directory.ReadWrite.All, Files.ReadWrite.All, Group.ReadWrite.All, Mail.Send | Microsoft | Unknown | \n| ✅ | [idPowerToys - CI](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/Overview/objectId/b66231c2-9568-46f1-b61e-c5f8fd9edee4/appId/50827722-4f53-48ba-ae58-db63bb53626b) | High | Agreement.Read.All, CrossTenantInformation.ReadBasic.All, Directory.Read.All, Policy.Read.All, User.Read, openid, profile, offline_access | | Manson | 2023-07-05 | \n| ✅ | [idPowerToys - Release](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/Overview/objectId/4654e05d-9f59-4925-807c-8eb2306e1cb1/appId/904e4864-f3c3-4d2f-ace2-c37a4ed55145) | High | Agreement.Read.All, CrossTenantInformation.ReadBasic.All, Directory.Read.All, Policy.Read.All, User.Read, openid, profile, offline_access | | Manson | 2023-10-24 | \n| ✅ | [Azure AD Assessment](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/Overview/objectId/6c74be7f-bcc9-4541-bfe1-f113b90b0497/appId/68bc31c0-f891-4f4c-9309-c6104f7be41b) | High | Organization.Read.All, RoleManagement.Read.Directory, Application.Read.All, User.Read.All, Group.Read.All, Policy.Read.All, Directory.Read.All, SecurityEvents.Read.All, UserAuthenticationMethod.Read.All, AuditLog.Read.All, Reports.Read.All, openid, offline_access, profile | | Microsoft | 2023-10-27 | \n| ✅ | [idPowerToys for Desktop](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/Overview/objectId/24cc58d8-2844-4974-b7cd-21c8a470e6bb/appId/520aa3af-bd78-4631-8f87-d48d356940ed) | High | Directory.Read.All, Policy.Read.All, Agreement.Read.All, CrossTenantInformation.ReadBasic.All, openid, profile, offline_access | | Manson | 2025-02-16 | \n| ✅ | [entraChatAppMultiTenant](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/Overview/objectId/855a57ff-88a6-4ad0-85d7-4f46d742730e/appId/5e00b345-a805-42a0-9caa-7d6cb761c668) | High | User.Read, openid, profile, offline_access, APIConnectors.Read.All, Application.ReadWrite.All, Policy.ReadWrite.AuthenticationFlows, Policy.Read.All, EventListener.ReadWrite.All, Policy.ReadWrite.AuthenticationMethod, Group.Read.All, AuditLog.Read.All, Policy.ReadWrite.ConditionalAccess, IdentityUserFlow.Read.All, Policy.ReadWrite.TrustFramework, TrustFrameworkKeySet.Read.All, Directory.ReadWrite.All | | JJ Industries | 2025-05-08 | \n| ✅ | [Intune Documentation](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/Overview/objectId/97b66fb0-f682-41e0-9aef-47f170c2abae/appId/56066daa-baba-438f-89d0-7ea3be2e2222) | High | User.Read, DeviceManagementConfiguration.Read.All, DeviceManagementApps.Read.All, DeviceManagementManagedDevices.Read.All, DeviceManagementRBAC.Read.All, DeviceManagementServiceConfig.Read.All, Group.Read.All, openid, profile, offline_access | | Ugur Koc Lab | 2025-09-01 | \n| ✅ | [Automation](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/Overview/objectId/f79df990-9ad2-4142-b5fd-8945ff334da3/appId/dc7d83b5-d38b-4488-8952-7abf02e71590) | High | User.Read | Directory.ReadWrite.All | Pora Inc. | 2025-09-09 | \n| ✅ | [M365PronounKit](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/Overview/objectId/6bf7c616-88e8-4f7c-bdad-452e561fa777/appId/eea28244-3eec-4820-beae-d4a2c0bcc235) | High | | User.ReadWrite.All | Pora | 2025-09-09 | \n| ✅ | [test public client](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/Overview/objectId/5e80ea33-31fa-49fd-9a94-61894bd1a6c9/appId/79a0c604-f215-4c52-8fbe-641d08aa7937) | High | | User.Read.All | Pora | 2025-09-09 | \n| ✅ | [InfinityDemo](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/Overview/objectId/bac0ba57-1876-448e-96bf-6f0481c99fda/appId/fef811e1-2354-43b0-961b-248fe15e737d) | High | User.Read, Directory.Read.All | | Pora | 2025-09-09 | \n| ✅ | [Lokka](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/Overview/objectId/1abc3899-a5df-40ab-8aa7-95d31edd4c01/appId/f581405a-9e57-4e81-91f1-40cd62f7595e) | High | | Mail.Send, DeviceManagementConfiguration.ReadWrite.All, DirectoryRecommendations.Read.All, Policy.ReadWrite.Authorization, PrivilegedAccess.Read.AzureAD, Reports.Read.All, IdentityRiskEvent.Read.All, Policy.Read.All, User.Read.All, PrivilegedAccess.Read.AzureADGroup, Mail.Read, Directory.ReadWrite.All, Policy.ReadWrite.ConditionalAccess, UserAuthenticationMethod.Read.All | Pora Inc. | 2025-09-09 | \n| ✅ | [Maester DevOps Account - GitHub - Secret (demo)](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/Overview/objectId/e31cd01e-afaf-4cc3-8d15-d3f9f7eb61e8/appId/d0dc5f0a-bf75-41a4-9272-d5ec2345c963) | High | | DirectoryRecommendations.Read.All, Reports.Read.All, PrivilegedAccess.Read.AzureAD, Directory.Read.All, IdentityRiskEvent.Read.All, Policy.Read.All, DeviceManagementManagedDevices.Read.All, RoleEligibilitySchedule.Read.Directory, RoleManagement.Read.All, SecurityIdentitiesSensors.Read.All, Policy.Read.ConditionalAccess, SecurityIdentitiesHealth.Read.All, DeviceManagementConfiguration.Read.All, SharePointTenantSettings.Read.All, UserAuthenticationMethod.Read.All, Mail.Send | Pora Inc. | 2025-09-09 | \n| ✅ | [MyTestForBlock](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/Overview/objectId/e9fca357-cccd-4ec4-840f-7482f6f02818/appId/14a3ba45-3246-4fbe-8c3b-c3922e68232b) | High | | User.Read.All | Pora | 2025-09-09 | \n| ✅ | [PnPPowerShell](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/Overview/objectId/6d2e8d37-82b8-41e7-aa95-443a7401e8b8/appId/1d93462e-0f39-4e4c-898a-b6b1df5fa997) | High | User.Read | User.ReadWrite.All, TermStore.Read.All, User.Read.All, Sites.FullControl.All | Pora | 2025-09-09 | \n| ✅ | [Postman](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/Overview/objectId/aa64efdb-2d05-4c81-a9e5-80294bf0afac/appId/7fb37b38-ce4f-4675-9263-0cd3404b4925) | High | Policy.Read.All, User.Read, Directory.ReadWrite.All, Mail.ReadWrite | Mail.ReadWrite, Directory.ReadWrite.All | Pora | 2025-09-09 | \n| ✅ | [SharePoint Version App](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/Overview/objectId/666a58ef-c3e5-4efc-828a-2ab3c0120677/appId/2bb68591-782c-4c64-9415-bdf9414ae400) | High | User.Read | Sites.Read.All, Sites.Read.All | Pora | 2025-09-09 | \n| ✅ | [Trello](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/Overview/objectId/3d6c91cf-d48f-4272-ac4c-9f989bbec779/appId/d77611ee-5051-4383-9af3-5ba3627306a7) | High | | Application.Read.All | Pora Inc. | 2025-09-09 | \n| ✅ | [testuserread](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/Overview/objectId/89bd9c7a-0c81-4a0a-9153-ff7cd0b81352/appId/9fe2675c-7fc5-4895-8470-eed989ea0d63) | High | | GroupMember.Read.All, User.Read.All | Pora | 2025-09-09 | \n| ✅ | [My Doc Gen](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/Overview/objectId/a445d652-f72d-4a88-9493-79d3c3c23d1b/appId/e580347d-d0aa-4aa1-9113-5daa0bb1c805) | High | User.Read, openid, profile, offline_access, Directory.Read.All, Policy.Read.All, Agreement.Read.All, CrossTenantInformation.ReadBasic.All | | Pora | 2025-09-09 | \n| ✅ | [MyZt](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/Overview/objectId/716038b1-2811-40fc-8622-93e093890af0/appId/eee51d92-0bb5-4467-be6a-8f24ef677e4d) | High | Agreement.Read.All, CrossTenantInformation.ReadBasic.All, Directory.Read.All, Policy.Read.All, User.Read, DeviceManagementServiceConfig.Read.All, DeviceManagementConfiguration.Read.All, DeviceManagementRBAC.Read.All, DeviceManagementApps.Read.All, RoleAssignmentSchedule.Read.Directory, RoleEligibilitySchedule.Read.Directory, PrivilegedEligibilitySchedule.Read.AzureADGroup, openid, profile, offline_access | | Pora | 2025-09-09 | \n| ✅ | [MyZtA\\[\\[](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/Overview/objectId/d2a2a09d-7562-45fc-a950-36fedfb790f8/appId/d159fcf5-a613-435b-8195-8add3cdf4bff) | High | RoleAssignmentSchedule.Read.Directory, RoleEligibilitySchedule.Read.Directory, Policy.Read.All, Agreement.Read.All, DeviceManagementConfiguration.Read.All, DeviceManagementApps.Read.All, DeviceManagementRBAC.Read.All, DeviceManagementServiceConfig.Read.All, User.Read, Directory.Read.All, PrivilegedEligibilitySchedule.Read.AzureADGroup, CrossTenantInformation.ReadBasic.All | | Pora | 2025-09-09 | \n| ✅ | [Maester DevOps Account](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/Overview/objectId/d54232da-de3b-4874-aef2-5203dbd7342a/appId/d99dd249-6ab3-4e92-be40-81af11658359) | High | User.Read | DirectoryRecommendations.Read.All, PrivilegedAccess.Read.AzureAD, Reports.Read.All, Mail.Send, Directory.Read.All, IdentityRiskEvent.Read.All, Policy.Read.All | Pora | 2025-09-09 | \n| ✅ | [Graph PS - Zero Trust Workshop](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/Overview/objectId/f6e8dfdd-4c84-441f-ae6e-f2f51fd20699/appId/a9632ced-c276-4c2b-9288-3a34b755eaa9) | High | AuditLog.Read.All, CrossTenantInformation.ReadBasic.All, Directory.Read.All, DirectoryRecommendations.Read.All, IdentityRiskEvent.Read.All, Policy.Read.All, Policy.Read.ConditionalAccess, PrivilegedAccess.Read.AzureAD, Reports.Read.All, RoleEligibilitySchedule.Read.Directory, RoleEligibilitySchedule.ReadWrite.Directory, RoleManagement.Read.All, UserAuthenticationMethod.Read.All, openid, profile, offline_access | | Pora | 2025-09-09 | \n| ✅ | [Maester DevOps Account - GitHub](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/Overview/objectId/ce3af345-b0e0-4b15-808c-937d825bcf03/appId/f050a85f-390b-4d43-85a0-2196b706bfd6) | High | | Policy.Read.ConditionalAccess, Directory.Read.All, IdentityRiskEvent.Read.All, Policy.Read.All, DirectoryRecommendations.Read.All, Reports.Read.All, PrivilegedAccess.Read.AzureAD, DeviceManagementConfiguration.Read.All, SharePointTenantSettings.Read.All, UserAuthenticationMethod.Read.All, Mail.Send, DeviceManagementManagedDevices.Read.All, RoleEligibilitySchedule.Read.Directory, RoleManagement.Read.All | Entra.Chat | 2025-09-09 | \n| ✅ | [Maester DevOps Account - New GitHub Action](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/Overview/objectId/7c1885fd-fdf8-413a-86a6-f8867914272f/appId/143cb1b1-81af-4999-a292-a8c537601119) | High | User.Read | Policy.Read.ConditionalAccess, Directory.Read.All, IdentityRiskEvent.Read.All, Policy.Read.All, DeviceManagementManagedDevices.Read.All, RoleEligibilitySchedule.Read.Directory, RoleEligibilitySchedule.ReadWrite.Directory, RoleManagement.Read.All, DeviceManagementConfiguration.Read.All, SharePointTenantSettings.Read.All, UserAuthenticationMethod.Read.All, DirectoryRecommendations.Read.All, Reports.Read.All, PrivilegedAccess.Read.AzureAD | Pora Inc. | 2025-09-09 | \n| ✅ | [Maester Automation App](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/Overview/objectId/e3972142-1d36-4e7d-a777-ecd64619fcab/appId/55635484-743e-42e2-a78e-6bc15050ebde) | High | User.Read | Policy.Read.ConditionalAccess, Mail.Send, Directory.Read.All, IdentityRiskEvent.Read.All, Policy.Read.All, DeviceManagementManagedDevices.Read.All, RoleEligibilitySchedule.Read.Directory, RoleEligibilitySchedule.ReadWrite.Directory, RoleManagement.Read.All, DeviceManagementConfiguration.Read.All, SharePointTenantSettings.Read.All, UserAuthenticationMethod.Read.All, DirectoryRecommendations.Read.All, Reports.Read.All, PrivilegedAccess.Read.AzureAD | Pora Inc. | 2025-09-09 | \n| ✅ | [contoso-tenant-devops-7576c63d-bc90-4ae4-9f1c-0d959fb520db](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/Overview/objectId/c5632968-35cd-445d-926e-16e0afc9160e/appId/e876f7cb-13f3-48a4-8329-66d7b1fa33fb) | High | | Directory.ReadWrite.All, Policy.ReadWrite.Authorization, Policy.ReadWrite.DeviceConfiguration | Pora Inc. | 2025-10-01 | \n| ✅ | [contoso-Maester-54d3ea01-5a07-45d0-8d69-e5f5b0b20098](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/Overview/objectId/4faa0456-5ecb-49f3-bb9a-2dbe516e939a/appId/a8c184ae-8ddf-41f3-8881-c090b43c385f) | High | | DirectoryRecommendations.Read.All, Reports.Read.All, Directory.Read.All, Policy.Read.All, Mail.Send | Pora | 2025-11-01 | \n| ✅ | [contoso-maester-demo-39ecb2b6-d900-496e-886f-d112cca4f1a9](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/Overview/objectId/cc578aea-b1bd-434d-86d2-8a22c5728ded/appId/efec213e-0a85-4d7a-938f-3d97edd4ade0) | High | | DirectoryRecommendations.Read.All, Reports.Read.All, ThreatHunting.Read.All, PrivilegedAccess.Read.AzureAD, ReportSettings.Read.All, Directory.Read.All, IdentityRiskEvent.Read.All, Policy.Read.All, Policy.Read.ConditionalAccess, DeviceManagementManagedDevices.Read.All, RoleEligibilitySchedule.Read.Directory, RoleManagement.Read.All, SecurityIdentitiesSensors.Read.All, DeviceManagementConfiguration.Read.All, SharePointTenantSettings.Read.All, UserAuthenticationMethod.Read.All, SecurityIdentitiesHealth.Read.All | Pora Inc. | 2025-11-01 | \n| ✅ | [MyVscode](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/Overview/objectId/dfc83a5d-36e5-4506-ae9d-6ad5bb403377/appId/92abdce1-3952-4a8b-8720-e59257edd421) | Unranked | MCP.AccessReview.Read.All, MCP.AdministrativeUnit.Read.All, MCP.Application.Read.All, MCP.AuditLog.Read.All, MCP.AuthenticationContext.Read.All, MCP.Device.Read.All, MCP.DirectoryRecommendations.Read.All, MCP.Domain.Read.All, MCP.EntitlementManagement.Read.All, MCP.GroupMember.Read.All, MCP.HealthMonitoringAlert.Read.All, MCP.IdentityRiskEvent.Read.All, MCP.IdentityRiskyServicePrincipal.Read.All, MCP.IdentityRiskyUser.Read.All, MCP.LicenseAssignment.Read.All, MCP.LifecycleWorkflows-CustomExt.Read.All, MCP.LifecycleWorkflows-Reports.Read.All, MCP.LifecycleWorkflows-Workflow.Read.All, MCP.LifecycleWorkflows-Workflow.ReadBasic.All, MCP.LifecycleWorkflows.Read.All, MCP.NetworkAccess-Reports.Read.All, MCP.NetworkAccess.Read.All, MCP.Organization.Read.All, MCP.Policy.Read.All, MCP.Policy.Read.ConditionalAccess, MCP.ProvisioningLog.Read.All, MCP.Reports.Read.All, MCP.RoleAssignmentSchedule.Read.Directory, MCP.RoleEligibilitySchedule.Read.Directory, MCP.RoleManagement.Read.Directory, MCP.Synchronization.Read.All, MCP.User.Read.All, MCP.UserAuthenticationMethod.Read.All | | Pora Inc. | 2025-11-15 | \n| ✅ | [Agent Identity Blueprint Example 4208296](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/Overview/objectId/c845b130-ce1b-4124-96ca-465df0eaa10f/appId/d0e3212f-58a2-4511-8b56-bd57b023106d) | High | User.Read, Mail.Read, Calendars.Read | AgentIdUser.ReadWrite.IdentityParentedBy | Pora Inc. | 2025-11-18 | \n| ✅ | [Agent Identity Blueprint Example 4209295](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/Overview/objectId/20aaa39b-821d-40a5-8d8a-eff27f86bb4a/appId/f522f080-5192-4665-87a4-e1211b7adca6) | High | User.Read, Files.Read | AgentIdUser.ReadWrite.IdentityParentedBy | Pora Inc. | 2025-11-18 | \n| ✅ | [testSP](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/Overview/objectId/2361fd8a-fe89-4d07-9199-c117feb52b5e/appId/e47d8f25-5327-40f8-99fe-d832b99d938d) | High | | CrossTenantInformation.ReadBasic.All, Policy.Read.ConditionalAccess, DeviceManagementRBAC.Read.All, Policy.Read.PermissionGrant, IdentityRiskyUser.Read.All, DeviceManagementServiceConfig.Read.All, DirectoryRecommendations.Read.All, PrivilegedAccess.Read.AzureAD, EntitlementManagement.Read.All, NetworkAccess-Reports.Read.All, Directory.Read.All, IdentityRiskEvent.Read.All, LifecycleWorkflows-Reports.Read.All, NetworkAccessPolicy.Read.All, DeviceManagementManagedDevices.Read.All, RoleManagement.Read.All, AuditLog.Read.All, DeviceManagementConfiguration.Read.All, InformationProtectionPolicy.Read.All, UserAuthenticationMethod.Read.All | Pora Inc. | 2025-11-27 | \n| ✅ | [idPowerToys](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/Overview/objectId/ad36b6e2-273d-4652-a505-8481f096e513/appId/6ce0484b-2ae6-4458-b2b9-b3369f42fd6f) | High | Agreement.Read.All, CrossTenantInformation.ReadBasic.All, Directory.Read.All, Policy.Read.All, User.Read, openid, profile, offline_access | | Manson | 2025-12-02 | \n| ✅ | [Zero Trust Assessment](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/Overview/objectId/3dde25cc-223f-4a16-8e8f-6695940b9680/appId/e7dfcbb6-fe86-44a2-b512-8d361dcc3d30) | High | Agreement.Read.All, CrossTenantInformation.ReadBasic.All, Directory.Read.All, Policy.Read.All, User.Read, DeviceManagementServiceConfig.Read.All, DeviceManagementConfiguration.Read.All, DeviceManagementRBAC.Read.All, DeviceManagementApps.Read.All, RoleAssignmentSchedule.Read.Directory, RoleEligibilitySchedule.Read.Directory, PrivilegedEligibilitySchedule.Read.AzureADGroup, openid, profile, offline_access | | Pora | 2026-03-07 | \n| ✅ | [ZT-PermissionTest](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/Overview/objectId/b264ce7f-a584-49bf-8dd4-d2a3971e97b9/appId/be667b5a-b863-4698-9f60-868ef968b857) | High | User.Read, AuditLog.Read.All, DeviceManagementConfiguration.Read.All, CrossTenantInformation.ReadBasic.All, Policy.Read.All, DeviceManagementApps.Read.All, Directory.Read.All, Reports.Read.All, DeviceManagementRBAC.Read.All, IdentityRiskyServicePrincipal.Read.All, DeviceManagementManagedDevices.Read.All, offline_access, DeviceManagementServiceConfig.Read.All, Policy.Read.ConditionalAccess, DirectoryRecommendations.Read.All, EntitlementManagement.Read.All, IdentityRiskEvent.Read.All, IdentityRiskyUser.Read.All, Policy.Read.PermissionGrant, NetworkAccess.Read.All, PrivilegedAccess.Read.AzureAD, RoleManagement.Read.All, UserAuthenticationMethod.Read.All, openid, profile | | Pora Inc. | 2026-03-13 | \n| ✅ | [ZeroTrustTest](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/Overview/objectId/d07c6af4-09f7-403f-bdeb-fb6be0d5e9fe/appId/3835a2fc-573d-4c4b-a4a3-993a1a156607) | High | User.Read, AuditLog.Read.All, DeviceManagementConfiguration.Read.All, CrossTenantInformation.ReadBasic.All, Policy.Read.All, CustomSecAttributeAssignment.Read.All, DirectoryRecommendations.Read.All, Policy.Read.ConditionalAccess, DeviceManagementApps.Read.All, DeviceManagementRBAC.Read.All, IdentityRiskyServicePrincipal.Read.All, DeviceManagementManagedDevices.Read.All, offline_access, DeviceManagementServiceConfig.Read.All, Reports.Read.All, Directory.Read.All, EntitlementManagement.Read.All, IdentityRiskEvent.Read.All, IdentityRiskyUser.Read.All, Policy.Read.PermissionGrant, NetworkAccess.Read.All, PrivilegedAccess.Read.AzureAD, RoleManagement.Read.All, UserAuthenticationMethod.Read.All, openid, profile | DeviceManagementManagedDevices.Read.All, RoleManagement.Read.All, IdentityRiskyUser.Read.All, Content.SuperUser, EntitlementManagement.Read.All, Content.DelegatedWriter, DeviceManagementServiceConfig.Read.All, DirectoryRecommendations.Read.All, PrivilegedAccess.Read.AzureAD, CrossTenantInformation.ReadBasic.All, CustomSecAttributeAssignment.Read.All, Policy.Read.ConditionalAccess, Directory.Read.All, IdentityRiskEvent.Read.All, DeviceManagementRBAC.Read.All, Policy.Read.PermissionGrant, AuditLog.Read.All, DeviceManagementConfiguration.Read.All, IdentityRiskyServicePrincipal.Read.All, UserAuthenticationMethod.Read.All | Pora Inc. | 2026-04-16 | \n| ✅ | [test](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/Overview/objectId/35cbeecb-be21-4596-9869-0157d84f2d67/appId/c823a25d-fe94-494c-91f6-c7d51bf2df82) | High | User.Read | Sites.FullControl.All | Pora | 2026-04-30 | \n| ✅ | [Custom-App-Test](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/Overview/objectId/38415a71-b77b-44d5-a276-539faabe0de7/appId/ddb4f0e6-8018-4359-96c1-7473704bde43) | High | User.Read | DeviceManagementServiceConfig.Read.All, DirectoryRecommendations.Read.All, PrivilegedAccess.Read.AzureAD, CrossTenantInformation.ReadBasic.All, CustomSecAttributeAssignment.Read.All, Policy.Read.ConditionalAccess, EntitlementManagement.Read.All, DeviceManagementManagedDevices.Read.All, RoleManagement.Read.All, Directory.Read.All, IdentityRiskEvent.Read.All, Policy.Read.All, DeviceManagementRBAC.Read.All, Policy.Read.PermissionGrant, AuditLog.Read.All, DeviceManagementConfiguration.Read.All, IdentityRiskyServicePrincipal.Read.All, UserAuthenticationMethod.Read.All, IdentityRiskyUser.Read.All, Application.Read.All | Pora Inc. | 2026-05-14 | \n| ✅ | [Maester DevOps Account](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/Overview/objectId/7c32eaee-ff26-4435-be3d-b4ced08f9edc/appId/303774c1-3c6f-4dfd-8505-f24e82f9212a) | High | User.Read | RoleEligibilitySchedule.Read.Directory, RoleEligibilitySchedule.ReadWrite.Directory, RoleManagement.Read.All, DirectoryRecommendations.Read.All, Reports.Read.All, PrivilegedAccess.Read.AzureAD, SharePointTenantSettings.Read.All, UserAuthenticationMethod.Read.All, Policy.Read.ConditionalAccess, Directory.Read.All, IdentityRiskEvent.Read.All, Policy.Read.All | Pora | 2026-05-17 | \n| ✅ | [entra-docs-email github DO NOT DELETE](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/Overview/objectId/7a94aec7-a5e3-48dd-b20f-3db74d689434/appId/ae06b71a-a0aa-4211-b846-fd74f25ccd45) | High | User.Read | Mail.Send | Pora Inc. | 2026-05-17 | \n| ✅ | [Maester DevOps Account - manson/maester-demo](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/Overview/objectId/fdce906b-d2f6-4738-8c76-e4559b9e17e8/appId/91c84d77-3dce-4fb0-b0de-474a8606c812) | High | | Policy.Read.ConditionalAccess, ReportSettings.Read.All, SecurityIdentitiesHealth.Read.All, DirectoryRecommendations.Read.All, Reports.Read.All, ThreatHunting.Read.All, PrivilegedAccess.Read.AzureAD, DeviceManagementConfiguration.Read.All, SharePointTenantSettings.Read.All, UserAuthenticationMethod.Read.All, DeviceManagementManagedDevices.Read.All, RoleEligibilitySchedule.Read.Directory, RoleManagement.Read.All, SecurityIdentitiesSensors.Read.All, Directory.Read.All, IdentityRiskEvent.Read.All, Policy.Read.All | Pora Inc. | 2026-05-17 | \n| ✅ | [GitHub Actions App for Microsoft Info script](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/Overview/objectId/852b4218-67d2-4046-a9a6-f8b47430ccdf/appId/38535360-9f3e-4b1e-a41e-b4af46afcb0c) | High | | Application.Read.All | Pora | 2026-05-18 | \n| ✅ | [GraphPermissionApp](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/Overview/objectId/a15dc834-08ce-4fd8-85de-3729fff8e34f/appId/d36fe320-bc28-40c8-a141-a512d65d112c) | High | User.Read | Application.Read.All | Pora Inc. | 2026-05-18 | \n| ✅ | [MessageCenterAccount github.com/manson/mc DO NOT DELETE](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/Overview/objectId/427b14ca-13b3-4911-b67e-9ff626614781/appId/778fad36-e4c1-4d40-a58e-9b5b64179d41) | Unranked | | ServiceMessage.Read.All | Entra.Chat | 2026-05-18 | \n| ✅ | [custommcp](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/Overview/objectId/fba0c411-7019-4c32-bec4-2f281824b698/appId/aca7e359-22cf-4d86-9338-6d6051245755) | Unranked | MCP.AccessReview.Read.All, MCP.AdministrativeUnit.Read.All, MCP.Application.Read.All, MCP.AuditLog.Read.All, MCP.AuthenticationContext.Read.All, MCP.Device.Read.All, MCP.DirectoryRecommendations.Read.All, MCP.Domain.Read.All, MCP.EntitlementManagement.Read.All, MCP.GroupMember.Read.All, MCP.HealthMonitoringAlert.Read.All, MCP.IdentityRiskEvent.Read.All, MCP.IdentityRiskyServicePrincipal.Read.All, MCP.IdentityRiskyUser.Read.All, MCP.LicenseAssignment.Read.All, MCP.LifecycleWorkflows-CustomExt.Read.All, MCP.LifecycleWorkflows-Reports.Read.All, MCP.LifecycleWorkflows-Workflow.Read.All, MCP.LifecycleWorkflows-Workflow.ReadBasic.All, MCP.LifecycleWorkflows.Read.All, MCP.NetworkAccess-Reports.Read.All, MCP.NetworkAccess.Read.All, MCP.Organization.Read.All, MCP.Policy.Read.All, MCP.Policy.Read.ConditionalAccess, MCP.ProvisioningLog.Read.All, MCP.Reports.Read.All, MCP.RoleAssignmentSchedule.Read.Directory, MCP.RoleEligibilitySchedule.Read.Directory, MCP.RoleManagement.Read.Directory, MCP.Synchronization.Read.All, MCP.UserAuthenticationMethod.Read.All | | Pora Inc. | Unknown | \n| ✅ | [ChatGPT](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/Overview/objectId/ede526ec-83dd-4e66-8ed0-98e05dca5454/appId/e0476654-c1d5-430b-ab80-70cbd947616a) | Unranked | MCP.AccessReview.Read.All, MCP.AdministrativeUnit.Read.All, MCP.Application.Read.All, MCP.AuditLog.Read.All, MCP.AuthenticationContext.Read.All, MCP.Device.Read.All, MCP.DirectoryRecommendations.Read.All, MCP.Domain.Read.All, MCP.EntitlementManagement.Read.All, MCP.GroupMember.Read.All, MCP.HealthMonitoringAlert.Read.All, MCP.IdentityRiskEvent.Read.All, MCP.IdentityRiskyServicePrincipal.Read.All, MCP.IdentityRiskyUser.Read.All, MCP.LicenseAssignment.Read.All, MCP.LifecycleWorkflows-CustomExt.Read.All, MCP.LifecycleWorkflows-Reports.Read.All, MCP.LifecycleWorkflows-Workflow.Read.All, MCP.LifecycleWorkflows-Workflow.ReadBasic.All, MCP.LifecycleWorkflows.Read.All, MCP.NetworkAccess-Reports.Read.All, MCP.NetworkAccess.Read.All, MCP.Organization.Read.All, MCP.Policy.Read.All, MCP.Policy.Read.ConditionalAccess, MCP.ProvisioningLog.Read.All, MCP.Reports.Read.All, MCP.RoleAssignmentSchedule.Read.Directory, MCP.RoleEligibilitySchedule.Read.Directory, MCP.RoleManagement.Read.Directory, MCP.Synchronization.Read.All, MCP.User.Read.All, MCP.UserAuthenticationMethod.Read.All | | OpenAI | Unknown | \n| ✅ | [TestMcPClient](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/Overview/objectId/cf30c6da-890f-4e66-b353-06adbae9933f/appId/55c372a3-9a33-42bb-ac50-7f49224fee47) | Unranked | MCP.AccessReview.Read.All, MCP.AdministrativeUnit.Read.All, MCP.Application.Read.All, MCP.AuditLog.Read.All, MCP.AuthenticationContext.Read.All, MCP.Device.Read.All, MCP.DirectoryRecommendations.Read.All, MCP.Domain.Read.All, MCP.EntitlementManagement.Read.All, MCP.GroupMember.Read.All, MCP.HealthMonitoringAlert.Read.All, MCP.IdentityRiskEvent.Read.All, MCP.IdentityRiskyServicePrincipal.Read.All, MCP.IdentityRiskyUser.Read.All, MCP.LicenseAssignment.Read.All, MCP.LifecycleWorkflows-CustomExt.Read.All, MCP.LifecycleWorkflows-Reports.Read.All, MCP.LifecycleWorkflows-Workflow.Read.All, MCP.LifecycleWorkflows-Workflow.ReadBasic.All, MCP.LifecycleWorkflows.Read.All, MCP.NetworkAccess-Reports.Read.All, MCP.NetworkAccess.Read.All, MCP.Organization.Read.All, MCP.Policy.Read.All, MCP.Policy.Read.ConditionalAccess, MCP.ProvisioningLog.Read.All, MCP.Reports.Read.All, MCP.RoleAssignmentSchedule.Read.Directory, MCP.RoleEligibilitySchedule.Read.Directory, MCP.RoleManagement.Read.Directory, MCP.Synchronization.Read.All, MCP.User.Read.All, MCP.UserAuthenticationMethod.Read.All | | Pora Inc. | Unknown | \n| ✅ | [MyTestMcPClient](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/Overview/objectId/84fbf039-0d23-41d0-b58b-f7a7b76a0486/appId/b6e43d0e-e33f-4223-bae4-144e5974ec3b) | Unranked | MCP.AccessReview.Read.All, MCP.AdministrativeUnit.Read.All, MCP.Application.Read.All, MCP.AuditLog.Read.All, MCP.AuthenticationContext.Read.All, MCP.Device.Read.All, MCP.DirectoryRecommendations.Read.All, MCP.Domain.Read.All, MCP.EntitlementManagement.Read.All, MCP.GroupMember.Read.All, MCP.HealthMonitoringAlert.Read.All, MCP.IdentityRiskEvent.Read.All, MCP.IdentityRiskyServicePrincipal.Read.All, MCP.IdentityRiskyUser.Read.All, MCP.LicenseAssignment.Read.All, MCP.LifecycleWorkflows-CustomExt.Read.All, MCP.LifecycleWorkflows-Reports.Read.All, MCP.LifecycleWorkflows-Workflow.Read.All, MCP.LifecycleWorkflows-Workflow.ReadBasic.All, MCP.LifecycleWorkflows.Read.All, MCP.NetworkAccess-Reports.Read.All, MCP.NetworkAccess.Read.All, MCP.Organization.Read.All, MCP.Policy.Read.All, MCP.Policy.Read.ConditionalAccess, MCP.ProvisioningLog.Read.All, MCP.Reports.Read.All, MCP.RoleAssignmentSchedule.Read.Directory, MCP.RoleEligibilitySchedule.Read.Directory, MCP.RoleManagement.Read.Directory, MCP.Synchronization.Read.All, MCP.User.Read.All, MCP.UserAuthenticationMethod.Read.All | | Pora Inc. | Unknown | \n| ✅ | [M365 MCP Client for Claude](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/Overview/objectId/73f345ba-56fb-4d92-b2f6-2fe168131092/appId/08ad6f98-a4f8-4635-bb8d-f1a3044760f0) | Unranked | MCP.AdministrativeUnit.Read.All, MCP.Application.Read.All, MCP.AuditLog.Read.All, MCP.AuthenticationContext.Read.All, MCP.Device.Read.All, MCP.DirectoryRecommendations.Read.All, MCP.Domain.Read.All, MCP.EntitlementManagement.Read.All, MCP.GroupMember.Read.All, MCP.HealthMonitoringAlert.Read.All, MCP.IdentityRiskEvent.Read.All, MCP.IdentityRiskyServicePrincipal.Read.All, MCP.IdentityRiskyUser.Read.All, MCP.LicenseAssignment.Read.All, MCP.LifecycleWorkflows-CustomExt.Read.All, MCP.LifecycleWorkflows-Reports.Read.All, MCP.LifecycleWorkflows-Workflow.Read.All, MCP.LifecycleWorkflows-Workflow.ReadBasic.All, MCP.LifecycleWorkflows.Read.All, MCP.NetworkAccess-Reports.Read.All, MCP.NetworkAccess.Read.All, MCP.Organization.Read.All, MCP.Policy.Read.All, MCP.Policy.Read.ConditionalAccess, MCP.ProvisioningLog.Read.All, MCP.Reports.Read.All, MCP.RoleAssignmentSchedule.Read.Directory, MCP.RoleEligibilitySchedule.Read.Directory, MCP.RoleManagement.Read.Directory, MCP.Synchronization.Read.All, MCP.User.Read.All, MCP.UserAuthenticationMethod.Read.All | | Anthropic | Unknown | \n| ✅ | [MyVisualStudioMcpClient](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/Overview/objectId/cae606b7-4a44-4d07-a7a5-a6fb285e41f1/appId/84ad8697-445d-4b26-affd-1b1459e97aae) | Unranked | MCP.AccessReview.Read.All, MCP.AdministrativeUnit.Read.All, MCP.Application.Read.All, MCP.AuditLog.Read.All, MCP.AuthenticationContext.Read.All, MCP.Device.Read.All, MCP.DirectoryRecommendations.Read.All, MCP.Domain.Read.All, MCP.EntitlementManagement.Read.All, MCP.GroupMember.Read.All, MCP.HealthMonitoringAlert.Read.All, MCP.IdentityRiskEvent.Read.All, MCP.IdentityRiskyServicePrincipal.Read.All, MCP.IdentityRiskyUser.Read.All, MCP.LicenseAssignment.Read.All, MCP.LifecycleWorkflows-CustomExt.Read.All, MCP.LifecycleWorkflows-Reports.Read.All, MCP.LifecycleWorkflows-Workflow.Read.All, MCP.LifecycleWorkflows-Workflow.ReadBasic.All, MCP.LifecycleWorkflows.Read.All, MCP.NetworkAccess-Reports.Read.All, MCP.NetworkAccess.Read.All, MCP.Organization.Read.All, MCP.Policy.Read.All, MCP.Policy.Read.ConditionalAccess, MCP.ProvisioningLog.Read.All, MCP.Reports.Read.All, MCP.RoleAssignmentSchedule.Read.Directory, MCP.RoleEligibilitySchedule.Read.Directory, MCP.RoleManagement.Read.Directory, MCP.Synchronization.Read.All, MCP.User.Read.All, MCP.UserAuthenticationMethod.Read.All | | Pora Inc. | Unknown | \n\n\n","TestStatus":"Failed","TestTags":null},{"TestImplementationCost":"Low","TestPillar":"Devices","TestCategory":"Tenant","SkippedReason":null,"TestImpact":"Medium","TestAppliesTo":null,"TestSfiPillar":"Protect tenants and isolate production systems","TestSkipped":"","TestMinimumLicense":"Intune","TestTags":null,"TestTitle":"Compliance policy assignment for iOS/iPadOS devices","TestRisk":"High","TestResult":"\nAt least one compliance policy for iOS/iPadOS exists and is assigned.\n\n\n## iOS/iPadOS Compliance Policies\n\n| Policy Name | Status | Assignment Target |\n| :---------- | :----- | :---------------- |\n| [My iOS policy](https://intune.microsoft.com/#view/Microsoft_Intune_DeviceSettings/DevicesMenu/~/compliance) | ✅ Assigned | **Included:** All Devices, All Users, **Excluded:** aad-conditional-access-excluded |\n\n\n\n","TestStatus":"Passed","TestDescription":"If compliance policies aren't assigned to iOS/iPadOS devices in Intune, threat actors can exploit noncompliant endpoints to gain unauthorized access to corporate resources, bypass security controls, and persist in the environment. Without enforced compliance, devices can lack critical security configurations like passcode requirements and OS version controls. These gaps increase the risk of data leakage, privilege escalation, and lateral movement. Inconsistent device compliance weakens the organization’s security posture and makes it harder to detect and remediate threats before significant damage occurs.\n\nEnforcing compliance policies ensures iOS/iPadOS devices meet core security requirements and supports Zero Trust by validating device health and reducing exposure to misconfigured or unmanaged endpoints.\n\n**Remediation action**\n\nCreate and assign Intune compliance policies to iOS/iPadOS devices to enforce organizational standards for secure access and management: \n- [Create a compliance policy in Microsoft Intune](https://learn.microsoft.com/intune/intune-service/protect/create-compliance-policy?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci#create-the-policy)\n- [Review the iOS/iPadOS compliance settings you can manage with Intune](https://learn.microsoft.com/intune/intune-service/protect/compliance-policy-create-ios?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci)\n","TestId":"24543"},{"TestImplementationCost":"Medium","TestPillar":"Devices","TestCategory":"Device","SkippedReason":null,"TestImpact":"Low","TestAppliesTo":null,"TestSfiPillar":"Protect networks","TestSkipped":"","TestMinimumLicense":"Intune","TestTags":null,"TestTitle":"A Windows Defender Antivirus policy is created and assigned","TestRisk":"High","TestResult":"\nNo relevant Windows Defender Antivirus policies are configured or assigned.\n\n\n\n","TestStatus":"Failed","TestDescription":"If policies for Microsoft Defender Antivirus aren't properly configured and assigned in Intune, threat actors can exploit unprotected endpoints to execute malware, disable antivirus protections, and persist within the environment. Without enforced antivirus policies, devices operate with outdated definitions, disabled real-time protection, or misconfigured scan schedules. These gaps allow attackers to bypass detection, escalate privileges, and move laterally across the network. The absence of antivirus enforcement undermines device compliance, increases exposure to zero-day threats, and can result in regulatory noncompliance. Attackers leverage these weaknesses to maintain persistence and evade detection, especially in environments lacking centralized policy enforcement.\n\nEnforcing Defender Antivirus policies ensures consistent protection against malware, supports real-time threat detection, and aligns with Zero Trust by maintaining a secure and compliant endpoint posture.\n\n**Remediation action**\n\nConfigure and assign Intune policies for Microsoft Defender Antivirus to enforce real-time protection, maintain up-to-date definitions, and reduce exposure to malware:\n\n- [Configure Intune policies to manage Microsoft Defender Antivirus](https://learn.microsoft.com/intune/intune-service/protect/endpoint-security-antivirus-policy?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci#windows)\n- [Assign policies in Intune](https://learn.microsoft.com/intune/intune-service/configuration/device-profile-assign?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci#assign-a-policy-to-users-or-groups)\n","TestId":"24575"},{"TestImplementationCost":"Low","TestPillar":"Identity","TestCategory":"Privileged access","SkippedReason":null,"TestImpact":"Medium","TestAppliesTo":["Identity"],"TestSfiPillar":"Protect identities and secrets","TestSkipped":"","TestMinimumLicense":"Free","TestTags":["PrivilegedIdentity"],"TestTitle":"Privileged accounts are cloud native identities","TestRisk":"Medium","TestResult":"\nThis tenant has 3 privileged users that are synced from on-premises.\n\n## Privileged roles\n\n| Role name | User | Source | Status |\n| :--- | :--- | :--- | :---: |\n| Agent ID Administrator | [Sage Bennett](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/AdministrativeRole/userId/518ce209-faf4-4717-add9-7129a669fa11) | Cloud native identity | ✅ |\n| AI Administrator | [Jordan Smith](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/AdministrativeRole/userId/bfaeba1e-1357-47de-9557-529caa103d5d) | Cloud native identity | ✅ |\n| Application Administrator | [Skylar White](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/AdministrativeRole/userId/2a054082-8f05-4e05-8fce-4e35c3bb40cc) | Cloud native identity | ✅ |\n| Application Administrator | [Riley Martinez](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/AdministrativeRole/userId/653c7fdd-1b41-4229-992a-69cc35aad4f7) | Cloud native identity | ✅ |\n| Application Administrator | [Sam Parker](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/AdministrativeRole/userId/96d29f01-873c-46a3-b542-f7ee192cc675) | Cloud native identity | ✅ |\n| Application Administrator | [Jordan Smith](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/AdministrativeRole/userId/bfaeba1e-1357-47de-9557-529caa103d5d) | Cloud native identity | ✅ |\n| Application Administrator | [Drew Mitchell](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/AdministrativeRole/userId/df02402a-e291-42cc-b449-79366daa2a40) | Cloud native identity | ✅ |\n| Application Administrator | [Alex Johnson](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/AdministrativeRole/userId/e436ca15-3a39-4dcc-819e-7dbb246cd46b) | Cloud native identity | ✅ |\n| Global Administrator | [Jules Bailey](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/AdministrativeRole/userId/0145d508-50fd-4f86-a47a-bf1c043c8358) | Synced from on-premises | ❌ |\n| Global Administrator | [Jamie Rodriguez](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/AdministrativeRole/userId/0b37813c-ae19-4399-982f-16587f17f9c0) | Cloud native identity | ✅ |\n| Global Administrator | [Ellis Cooper](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/AdministrativeRole/userId/1433571b-3d7c-4a56-a9cc-67580848bc73) | Cloud native identity | ✅ |\n| Global Administrator | [Cameron Anderson](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/AdministrativeRole/userId/1ce4078f-f795-4baf-aa55-1fdfcc2ebfe6) | Cloud native identity | ✅ |\n| Global Administrator | [Taylor Brown](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/AdministrativeRole/userId/2072badc-3cf0-4e84-b4c2-f9c065c46165) | Cloud native identity | ✅ |\n| Global Administrator | [Dakota Lee](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/AdministrativeRole/userId/210d3e96-015f-462d-b6d6-81e6023263df) | Cloud native identity | ✅ |\n| Global Administrator | [Dakota Lee Test](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/AdministrativeRole/userId/43482f27-d1af-420f-84ba-e9148a700f45) | Cloud native identity | ✅ |\n| Global Administrator | [Ash Williams](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/AdministrativeRole/userId/513f3db2-044c-41be-af14-431bf88a2b3e) | Cloud native identity | ✅ |\n| Global Administrator | [Sage Bennett](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/AdministrativeRole/userId/518ce209-faf4-4717-add9-7129a669fa11) | Cloud native identity | ✅ |\n| Global Administrator | [Morgan Wilson](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/AdministrativeRole/userId/5655cf54-34bc-4f36-bb74-44da35547975) | Synced from on-premises | ❌ |\n| Global Administrator | [Charlie Lewis](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/AdministrativeRole/userId/5b0ec3ff-cea1-4eb9-8530-f2a66e5bec0a) | Cloud native identity | ✅ |\n| Global Administrator | [Phoenix Gray](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/AdministrativeRole/userId/7094fb23-003a-4f81-9796-5daeaa603003) | Cloud native identity | ✅ |\n| Global Administrator | [Peyton Clark](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/AdministrativeRole/userId/7e92f268-bb12-469a-a869-210d596d4c1f) | Cloud native identity | ✅ |\n| Global Administrator | [Finley Robinson](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/AdministrativeRole/userId/990fd38a-c516-4e3f-82e4-d458a1ab0f91) | Cloud native identity | ✅ |\n| Global Administrator | [Avery Brooks](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/AdministrativeRole/userId/a85798bd-652b-4eb9-ba90-3ee882df0179) | Cloud native identity | ✅ |\n| Global Administrator | [Reese Harris](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/AdministrativeRole/userId/babe04c9-8340-4329-a727-a8cee0cd2b1a) | Cloud native identity | ✅ |\n| Global Administrator | [Jordan Smith](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/AdministrativeRole/userId/bfaeba1e-1357-47de-9557-529caa103d5d) | Cloud native identity | ✅ |\n| Global Administrator | [Hayden Scott](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/AdministrativeRole/userId/c0b65b13-37b1-4081-bcfc-14844159b4a5) | Cloud native identity | ✅ |\n| Global Administrator | [Quinn Garcia](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/AdministrativeRole/userId/ceef37b7-c865-48fb-80c9-4def11201854) | Cloud native identity | ✅ |\n| Global Administrator | [Drew Mitchell](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/AdministrativeRole/userId/df02402a-e291-42cc-b449-79366daa2a40) | Cloud native identity | ✅ |\n| Global Administrator | [Alex Johnson](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/AdministrativeRole/userId/e436ca15-3a39-4dcc-819e-7dbb246cd46b) | Cloud native identity | ✅ |\n| Global Administrator | [Avery Thomas](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/AdministrativeRole/userId/f431700c-6d81-45b8-8f8d-581a8aa7cda6) | Cloud native identity | ✅ |\n| Global Reader | [Hayden Scott](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/AdministrativeRole/userId/0d6cfd05-fc46-440b-b605-66dd26dcd7d2) | Cloud native identity | ✅ |\n| Global Reader | [Cameron Anderson](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/AdministrativeRole/userId/1ce4078f-f795-4baf-aa55-1fdfcc2ebfe6) | Cloud native identity | ✅ |\n| Global Reader | [Sage Bennett](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/AdministrativeRole/userId/518ce209-faf4-4717-add9-7129a669fa11) | Cloud native identity | ✅ |\n| Global Reader | [Casey Davis](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/AdministrativeRole/userId/58d9ed99-93ca-4674-8c5f-ec770f5ba17d) | Synced from on-premises | ❌ |\n| Global Reader | [Hayden Scott Test](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/AdministrativeRole/userId/6f467d0a-25ec-435c-8fb9-9d53eb21e02f) | Cloud native identity | ✅ |\n| Global Reader | [Peyton Clark](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/AdministrativeRole/userId/7e92f268-bb12-469a-a869-210d596d4c1f) | Cloud native identity | ✅ |\n| Global Reader | [Finley Robinson](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/AdministrativeRole/userId/990fd38a-c516-4e3f-82e4-d458a1ab0f91) | Cloud native identity | ✅ |\n| Global Reader | [parker-test](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/AdministrativeRole/userId/c1bdb03c-0079-40b1-96a8-3595de3b94a2) | Cloud native identity | ✅ |\n| Global Reader | [ash-williams-test](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/AdministrativeRole/userId/c5c8ba63-4620-4e91-ac40-b66bebe07a0d) | Cloud native identity | ✅ |\n| Global Reader | [finley-test](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/AdministrativeRole/userId/d71ccc09-c0a3-4604-9d02-49f7a3715f49) | Cloud native identity | ✅ |\n| Global Reader | [Drew Mitchell](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/AdministrativeRole/userId/df02402a-e291-42cc-b449-79366daa2a40) | Cloud native identity | ✅ |\n| Global Reader | [peyton-test](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/AdministrativeRole/userId/e0952dcb-8d63-496d-8661-05c86c1a51f0) | Cloud native identity | ✅ |\n| Privileged Role Administrator | [Sage Bennett](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/AdministrativeRole/userId/518ce209-faf4-4717-add9-7129a669fa11) | Cloud native identity | ✅ |\n| Security Administrator | [Cameron Anderson](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/AdministrativeRole/userId/1ce4078f-f795-4baf-aa55-1fdfcc2ebfe6) | Cloud native identity | ✅ |\n| User Administrator | [Dakota Lee](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/AdministrativeRole/userId/e4bc6f4a-124f-469b-8951-3d5c34fb9741) | Cloud native identity | ✅ |\n\n\n","TestStatus":"Failed","TestDescription":"If an on-premises account is compromised and is synchronized to Microsoft Entra, the attacker might gain access to the tenant as well. This risk increases because on-premises environments typically have more attack surfaces due to older infrastructure and limited security controls. Attackers might also target the infrastructure and tools used to enable connectivity between on-premises environments and Microsoft Entra. These targets might include tools like Microsoft Entra Connect or Active Directory Federation Services, where they could impersonate or otherwise manipulate other on-premises user accounts.\n\nIf privileged cloud accounts are synchronized with on-premises accounts, an attacker who acquires credentials for on-premises can use those same credentials to access cloud resources and move laterally to the cloud environment.\n\n**Remediation action**\n\n- [Protecting Microsoft 365 from on-premises attacks](https://learn.microsoft.com/entra/architecture/protect-m365-from-on-premises-attacks?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci#specific-security-recommendations)\n\nFor each role with high privileges (assigned permanently or eligible through Microsoft Entra Privileged Identity Management), you should do the following actions:\n\n- Review the users that have onPremisesImmutableId and onPremisesSyncEnabled set. See [Microsoft Graph API user resource type](https://learn.microsoft.com/graph/api/resources/user?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci).\n- Create cloud-only user accounts for those individuals and remove their hybrid identity from privileged roles.\n","TestId":"21814"},{"TestImpact":"Medium","TestRisk":"Medium","TestSkipped":"","TestAppliesTo":null,"TestPillar":"Data","TestCategory":"Information Protection","TestDescription":"Setting a default label ensures a base level of protection settings for all new and edited items that support sensitivity labels, and for new containers such as Teams. Users can manually override the label if necessary, and other labeling methods such as auto-labeling can replace the default label with a label that has a higher sensitivity level. Setting a default sensitivity label extends your labeling reach and reduces decision fatigue for users, ensuring content has at least a minimum level of protection.\n\nUnlabeled content might bypass data loss prevention (DLP) policies, and other protection solutions that rely on label detection. If appropriate, set a different default sensitivity label for unlabeled documents and Loop components and pages, emails and meeting invites, new containers, and also a default label for Power BI content.\n\n**Remediation action**\n\n- [Publish sensitivity labels by creating a label policy](https://learn.microsoft.com/purview/create-sensitivity-labels?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci#publish-sensitivity-labels-by-creating-a-label-policy)\n- [Default label policy for Fabric and Power BI](https://learn.microsoft.com/fabric/governance/sensitivity-label-default-label-policy?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci)\n","TestTitle":"Default label configured for sensitivity labels","SkippedReason":null,"TestId":"35017","TestImplementationCost":"Low","TestMinimumLicense":["RMS_S_PREMIUM"],"TestSfiPillar":"Protect tenants and production systems","TestResult":"\n✅ Default labels are configured for at least one workload (Outlook, Teams/OneDrive, SharePoint/Microsoft 365 Groups, or Power BI) in at least one active sensitivity label policy.\n\n\n\n### [Enabled label policies](https://purview.microsoft.com/informationprotection/labelpolicies)\n| Policy name | Documents/Emails | Outlook | Power BI | SharePoint/Groups | Scope | Labels |\n| :--- | :--- | :--- | :--- | :--- | :--- | :--- |\n| 35035-Test-Policy | ✅ | ✅ | ❌ | ❌ | User/Group-Scoped | 1 |\n| Test Policy | ✅ | ✅ | ✅ | ❌ | User/Group-Scoped | 1 |\n| true event | ❌ | ❌ | ❌ | ❌ | Global | 1 |\n| userpolicy | ❌ | ❌ | ❌ | ❌ | User/Group-Scoped | 1 |\n| peyton | ✅ | ✅ | ✅ | ❌ | Global | 1 |\n| test-policy-35012 | ❌ | ❌ | ❌ | ❌ | Global | 1 |\n\n\n### Summary\n| Metric | Count |\n| :--- | :--- |\n| Total enabled label policies | 6 |\n| Policies with default labels | 3 |\n| Documents/Emails default | 3 |\n| Outlook default | 3 |\n| Power BI default | 2 |\n| SharePoint/Groups default | 0 |\n\n","TestStatus":"Passed","TestTags":null},{"TestImplementationCost":"Medium","TestPillar":"Identity","TestCategory":"Privileged access","SkippedReason":"UnderConstruction","TestImpact":"Low","TestAppliesTo":["Identity"],"TestSfiPillar":"Protect identities and secrets","TestSkipped":"UnderConstruction","TestMinimumLicense":null,"TestTags":["Identity"],"TestTitle":"Privileged roles aren't assigned to stale identities","TestRisk":"Medium","TestResult":"\nPlanned for future release.\n\n","TestStatus":"Planned","TestDescription":"Privileged roles should not remain assigned to identities that show no recent sign-in activity. Stale accounts with administrative privileges are attractive targets for attackers because they can be compromised without triggering behavioral analytics alerts. Regularly reviewing and removing privileged role assignments from inactive identities reduces the risk of credential-based attacks and helps maintain least-privilege access.\n\n**Remediation action**\n\n- [Review privileged role assignments using access reviews](https://learn.microsoft.com/entra/id-governance/privileged-identity-management/pim-create-roles-and-resource-roles-review?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci)\n- [Remove privileged role assignments from inactive identities](https://learn.microsoft.com/entra/id-governance/privileged-identity-management/pim-resource-roles-assign-roles?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci#update-or-remove-an-existing-role-assignment)\n- [Configure automated access reviews for privileged roles](https://learn.microsoft.com/entra/id-governance/access-reviews-overview?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci)\n","TestId":"21854"},{"TestImplementationCost":"Medium","TestPillar":"Identity","TestCategory":"Access control","SkippedReason":null,"TestImpact":"Medium","TestAppliesTo":["Identity"],"TestSfiPillar":"Protect engineering systems","TestSkipped":"","TestMinimumLicense":"P1","TestTags":["Identity"],"TestTitle":"Resource-Specific Consent is restricted","TestRisk":"Medium","TestResult":"\nResource-Specific Consent is not restricted.\n\nThe current state is ManagedByMicrosoft.\n\n\n","TestStatus":"Failed","TestDescription":"Letting group owners consent to applications in Microsoft Entra ID creates a lateral escalation path that lets threat actors persist and steal data without admin credentials. If an attacker compromises a group owner account, they can register or use a malicious application and consent to high-privilege Graph API permissions scoped to the group. Attackers can potentially read all Teams messages, access SharePoint files, or manage group membership. This consent action creates a long-lived application identity with delegated or application permissions. The attacker maintains persistence with OAuth tokens, steals sensitive data from team channels and files, and impersonates users through messaging or email permissions. Without centralized enforcement of app consent policies, security teams lose visibility, and malicious applications spread under the radar, enabling multi-stage attacks across collaboration platforms.\n\n**Remediation action**\nConfigure preapproval of Resource-Specific Consent (RSC) permissions.\n- [Preapproval of RSC permissions](https://learn.microsoft.com/microsoftteams/platform/graph-api/rsc/preapproval-instruction-docs?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci)\n","TestId":"21810"},{"TestImplementationCost":"High","TestPillar":"Identity","TestCategory":"Application management","SkippedReason":null,"TestImpact":"Low","TestAppliesTo":null,"TestSfiPillar":"Protect engineering systems","TestSkipped":"","TestMinimumLicense":"P1","TestTags":null,"TestTitle":"Emergency access accounts are configured appropriately","TestRisk":"High","TestResult":"\nQuinn Garcia accounts appear to be configured as per Microsoft guidance based on cloud-only state, registered phishing-resistant credentials and Conditional Access policy exclusions.\n\n**Summary:**\n- Total permanent Global Administrators: 20\n- Cloud-only GAs with phishing-resistant auth: 5\n- Quinn Garcia accounts (excluded from all CA): 3\n- Enabled Conditional Access policies: 17\n\n## Quinn Garcia accounts\n\n| Display name | UPN | Synced from on-premises | Authentication methods |\n| :----------- | :-- | :---------------------- | :--------------------- |\n| Quinn Garcia | [quinn@contoso.com](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/overview/userId/ceef37b7-c865-48fb-80c9-4def11201854) | No | password, phone, softwareOath, fido2 |\n| Reese Harris | [reese@contoso.com](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/overview/userId/babe04c9-8340-4329-a727-a8cee0cd2b1a) | No | password, temporaryAccessPass, microsoftAuthenticator, fido2, fido2 |\n| Ash Williams | [ash@contoso.com](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/overview/userId/513f3db2-044c-41be-af14-431bf88a2b3e) | No | password, email, phone, softwareOath, microsoftAuthenticator, microsoftAuthenticator, fido2, fido2, fido2, fido2, fido2, fido2, fido2, windowsHelloForBusiness, windowsHelloForBusiness, windowsHelloForBusiness, windowsHelloForBusiness, windowsHelloForBusiness |\n\n## All permanent Global Administrators\n\n| Display name | UPN | Cloud only | Phishing resistant auth | All CA excluded | CA policies missing exclusion |\n| :----------- | :-- | :--------: | :---------------------: | :---------: | :---------------------------- |\n| Quinn Garcia | [quinn@contoso.com](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/overview/userId/ceef37b7-c865-48fb-80c9-4def11201854) | ✅ | ✅ | ✅ | None |\n| Ash Williams | [ash@contoso.com](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/overview/userId/513f3db2-044c-41be-af14-431bf88a2b3e) | ✅ | ✅ | ✅ | None |\n| Reese Harris | [reese@contoso.com](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/overview/userId/babe04c9-8340-4329-a727-a8cee0cd2b1a) | ✅ | ✅ | ✅ | None |\n| Hayden Scott | [hayden@contoso.com](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/overview/userId/c0b65b13-37b1-4081-bcfc-14844159b4a5) | ✅ | ✅ | ❌ | [MFA - All users](https://entra.microsoft.com/#view/Microsoft_AAD_ConditionalAccess/PolicyBlade/policyId/474ddef4-5620-4e7a-8976-6e9b095b2675), [testdevicereg21872](https://entra.microsoft.com/#view/Microsoft_AAD_ConditionalAccess/PolicyBlade/policyId/620a9c5c-09c4-4558-a0fe-7fc8b3540992), [Security regisrtation info](https://entra.microsoft.com/#view/Microsoft_AAD_ConditionalAccess/PolicyBlade/policyId/508ae024-d4c4-42bf-a8c9-40257c214c10) |\n| Drew Mitchell | [drew@contoso.com](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/overview/userId/df02402a-e291-42cc-b449-79366daa2a40) | ✅ | ✅ | ❌ | [MFA - All users](https://entra.microsoft.com/#view/Microsoft_AAD_ConditionalAccess/PolicyBlade/policyId/474ddef4-5620-4e7a-8976-6e9b095b2675), [j-test admin](https://entra.microsoft.com/#view/Microsoft_AAD_ConditionalAccess/PolicyBlade/policyId/6c0ef46a-3b58-43a9-b451-7464a16d91d7), [Block Device Code](https://entra.microsoft.com/#view/Microsoft_AAD_ConditionalAccess/PolicyBlade/policyId/db2153a1-40a2-457f-917c-c280b204b5cd), [testdevicereg21872](https://entra.microsoft.com/#view/Microsoft_AAD_ConditionalAccess/PolicyBlade/policyId/620a9c5c-09c4-4558-a0fe-7fc8b3540992), [Security regisrtation info](https://entra.microsoft.com/#view/Microsoft_AAD_ConditionalAccess/PolicyBlade/policyId/508ae024-d4c4-42bf-a8c9-40257c214c10) |\n| Avery Thomas | [avery@contoso.com](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/overview/userId/f431700c-6d81-45b8-8f8d-581a8aa7cda6) | ✅ | ❌ | ❌ | [MFA - All users](https://entra.microsoft.com/#view/Microsoft_AAD_ConditionalAccess/PolicyBlade/policyId/474ddef4-5620-4e7a-8976-6e9b095b2675), [Block Device Code](https://entra.microsoft.com/#view/Microsoft_AAD_ConditionalAccess/PolicyBlade/policyId/db2153a1-40a2-457f-917c-c280b204b5cd), [testdevicereg21872](https://entra.microsoft.com/#view/Microsoft_AAD_ConditionalAccess/PolicyBlade/policyId/620a9c5c-09c4-4558-a0fe-7fc8b3540992), [Security regisrtation info](https://entra.microsoft.com/#view/Microsoft_AAD_ConditionalAccess/PolicyBlade/policyId/508ae024-d4c4-42bf-a8c9-40257c214c10) |\n| Peyton Clark | [peyton@contoso.com](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/overview/userId/7e92f268-bb12-469a-a869-210d596d4c1f) | ✅ | ❌ | ❌ | [MFA - All users](https://entra.microsoft.com/#view/Microsoft_AAD_ConditionalAccess/PolicyBlade/policyId/474ddef4-5620-4e7a-8976-6e9b095b2675), [Block Device Code](https://entra.microsoft.com/#view/Microsoft_AAD_ConditionalAccess/PolicyBlade/policyId/db2153a1-40a2-457f-917c-c280b204b5cd), [testdevicereg21872](https://entra.microsoft.com/#view/Microsoft_AAD_ConditionalAccess/PolicyBlade/policyId/620a9c5c-09c4-4558-a0fe-7fc8b3540992), [Security regisrtation info](https://entra.microsoft.com/#view/Microsoft_AAD_ConditionalAccess/PolicyBlade/policyId/508ae024-d4c4-42bf-a8c9-40257c214c10) |\n| Avery Brooks | [avery.brooks@contoso.com](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/overview/userId/a85798bd-652b-4eb9-ba90-3ee882df0179) | ✅ | ❌ | ❌ | [MFA - All users](https://entra.microsoft.com/#view/Microsoft_AAD_ConditionalAccess/PolicyBlade/policyId/474ddef4-5620-4e7a-8976-6e9b095b2675), [Block Device Code](https://entra.microsoft.com/#view/Microsoft_AAD_ConditionalAccess/PolicyBlade/policyId/db2153a1-40a2-457f-917c-c280b204b5cd), [testdevicereg21872](https://entra.microsoft.com/#view/Microsoft_AAD_ConditionalAccess/PolicyBlade/policyId/620a9c5c-09c4-4558-a0fe-7fc8b3540992), [Security regisrtation info](https://entra.microsoft.com/#view/Microsoft_AAD_ConditionalAccess/PolicyBlade/policyId/508ae024-d4c4-42bf-a8c9-40257c214c10) |\n| Sage Bennett | [sage@contoso.com](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/overview/userId/518ce209-faf4-4717-add9-7129a669fa11) | ✅ | ❌ | ❌ | [Block Device Code](https://entra.microsoft.com/#view/Microsoft_AAD_ConditionalAccess/PolicyBlade/policyId/db2153a1-40a2-457f-917c-c280b204b5cd), [testdevicereg21872](https://entra.microsoft.com/#view/Microsoft_AAD_ConditionalAccess/PolicyBlade/policyId/620a9c5c-09c4-4558-a0fe-7fc8b3540992), [Security regisrtation info](https://entra.microsoft.com/#view/Microsoft_AAD_ConditionalAccess/PolicyBlade/policyId/508ae024-d4c4-42bf-a8c9-40257c214c10) |\n| Finley Robinson | [finley.robinson@contoso.com](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/overview/userId/990fd38a-c516-4e3f-82e4-d458a1ab0f91) | ✅ | ❌ | ❌ | [testdevicereg21872](https://entra.microsoft.com/#view/Microsoft_AAD_ConditionalAccess/PolicyBlade/policyId/620a9c5c-09c4-4558-a0fe-7fc8b3540992), [Security regisrtation info](https://entra.microsoft.com/#view/Microsoft_AAD_ConditionalAccess/PolicyBlade/policyId/508ae024-d4c4-42bf-a8c9-40257c214c10) |\n| Ellis Cooper | [ellis@contoso.com](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/overview/userId/1433571b-3d7c-4a56-a9cc-67580848bc73) | ✅ | ❌ | ❌ | [MFA - All users](https://entra.microsoft.com/#view/Microsoft_AAD_ConditionalAccess/PolicyBlade/policyId/474ddef4-5620-4e7a-8976-6e9b095b2675), [Block Device Code](https://entra.microsoft.com/#view/Microsoft_AAD_ConditionalAccess/PolicyBlade/policyId/db2153a1-40a2-457f-917c-c280b204b5cd), [testdevicereg21872](https://entra.microsoft.com/#view/Microsoft_AAD_ConditionalAccess/PolicyBlade/policyId/620a9c5c-09c4-4558-a0fe-7fc8b3540992), [\\[ellis\\] - Require app protection policy](https://entra.microsoft.com/#view/Microsoft_AAD_ConditionalAccess/PolicyBlade/policyId/6909c0fb-c830-42b6-a438-c41d4010518f), [Security regisrtation info](https://entra.microsoft.com/#view/Microsoft_AAD_ConditionalAccess/PolicyBlade/policyId/508ae024-d4c4-42bf-a8c9-40257c214c10) |\n| Cameron Anderson | [cameron@contoso.com](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/overview/userId/1ce4078f-f795-4baf-aa55-1fdfcc2ebfe6) | ✅ | ❌ | ❌ | [MFA - All users](https://entra.microsoft.com/#view/Microsoft_AAD_ConditionalAccess/PolicyBlade/policyId/474ddef4-5620-4e7a-8976-6e9b095b2675), [j-test admin](https://entra.microsoft.com/#view/Microsoft_AAD_ConditionalAccess/PolicyBlade/policyId/6c0ef46a-3b58-43a9-b451-7464a16d91d7), [Block Device Code](https://entra.microsoft.com/#view/Microsoft_AAD_ConditionalAccess/PolicyBlade/policyId/db2153a1-40a2-457f-917c-c280b204b5cd), [testdevicereg21872](https://entra.microsoft.com/#view/Microsoft_AAD_ConditionalAccess/PolicyBlade/policyId/620a9c5c-09c4-4558-a0fe-7fc8b3540992), [Security regisrtation info](https://entra.microsoft.com/#view/Microsoft_AAD_ConditionalAccess/PolicyBlade/policyId/508ae024-d4c4-42bf-a8c9-40257c214c10) |\n| Taylor Brown | [taylor@contoso.com](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/overview/userId/2072badc-3cf0-4e84-b4c2-f9c065c46165) | ✅ | ❌ | ❌ | [MFA - All users](https://entra.microsoft.com/#view/Microsoft_AAD_ConditionalAccess/PolicyBlade/policyId/474ddef4-5620-4e7a-8976-6e9b095b2675), [Block Device Code](https://entra.microsoft.com/#view/Microsoft_AAD_ConditionalAccess/PolicyBlade/policyId/db2153a1-40a2-457f-917c-c280b204b5cd), [testdevicereg21872](https://entra.microsoft.com/#view/Microsoft_AAD_ConditionalAccess/PolicyBlade/policyId/620a9c5c-09c4-4558-a0fe-7fc8b3540992), [Security regisrtation info](https://entra.microsoft.com/#view/Microsoft_AAD_ConditionalAccess/PolicyBlade/policyId/508ae024-d4c4-42bf-a8c9-40257c214c10) |\n| Dakota Lee | [guest-user_external.com#EXT#@contoso.com](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/overview/userId/210d3e96-015f-462d-b6d6-81e6023263df) | ✅ | ❌ | ❌ | [MFA - All users](https://entra.microsoft.com/#view/Microsoft_AAD_ConditionalAccess/PolicyBlade/policyId/474ddef4-5620-4e7a-8976-6e9b095b2675), [Block Device Code](https://entra.microsoft.com/#view/Microsoft_AAD_ConditionalAccess/PolicyBlade/policyId/db2153a1-40a2-457f-917c-c280b204b5cd), [testdevicereg21872](https://entra.microsoft.com/#view/Microsoft_AAD_ConditionalAccess/PolicyBlade/policyId/620a9c5c-09c4-4558-a0fe-7fc8b3540992), [Security regisrtation info](https://entra.microsoft.com/#view/Microsoft_AAD_ConditionalAccess/PolicyBlade/policyId/508ae024-d4c4-42bf-a8c9-40257c214c10) |\n| Dakota Lee Test | [dakota-test@contoso.com](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/overview/userId/43482f27-d1af-420f-84ba-e9148a700f45) | ✅ | ❌ | ❌ | [MFA - All users](https://entra.microsoft.com/#view/Microsoft_AAD_ConditionalAccess/PolicyBlade/policyId/474ddef4-5620-4e7a-8976-6e9b095b2675), [Block Device Code](https://entra.microsoft.com/#view/Microsoft_AAD_ConditionalAccess/PolicyBlade/policyId/db2153a1-40a2-457f-917c-c280b204b5cd), [testdevicereg21872](https://entra.microsoft.com/#view/Microsoft_AAD_ConditionalAccess/PolicyBlade/policyId/620a9c5c-09c4-4558-a0fe-7fc8b3540992), [Security regisrtation info](https://entra.microsoft.com/#view/Microsoft_AAD_ConditionalAccess/PolicyBlade/policyId/508ae024-d4c4-42bf-a8c9-40257c214c10) |\n| Charlie Lewis | [charlie@contoso.com](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/overview/userId/5b0ec3ff-cea1-4eb9-8530-f2a66e5bec0a) | ✅ | ❌ | ❌ | [MFA - All users](https://entra.microsoft.com/#view/Microsoft_AAD_ConditionalAccess/PolicyBlade/policyId/474ddef4-5620-4e7a-8976-6e9b095b2675), [Block Device Code](https://entra.microsoft.com/#view/Microsoft_AAD_ConditionalAccess/PolicyBlade/policyId/db2153a1-40a2-457f-917c-c280b204b5cd), [testdevicereg21872](https://entra.microsoft.com/#view/Microsoft_AAD_ConditionalAccess/PolicyBlade/policyId/620a9c5c-09c4-4558-a0fe-7fc8b3540992), [Security regisrtation info](https://entra.microsoft.com/#view/Microsoft_AAD_ConditionalAccess/PolicyBlade/policyId/508ae024-d4c4-42bf-a8c9-40257c214c10) |\n| Phoenix Gray | [phoenix@contoso.com](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/overview/userId/7094fb23-003a-4f81-9796-5daeaa603003) | ✅ | ❌ | ❌ | [MFA - All users](https://entra.microsoft.com/#view/Microsoft_AAD_ConditionalAccess/PolicyBlade/policyId/474ddef4-5620-4e7a-8976-6e9b095b2675), [Block Device Code](https://entra.microsoft.com/#view/Microsoft_AAD_ConditionalAccess/PolicyBlade/policyId/db2153a1-40a2-457f-917c-c280b204b5cd), [testdevicereg21872](https://entra.microsoft.com/#view/Microsoft_AAD_ConditionalAccess/PolicyBlade/policyId/620a9c5c-09c4-4558-a0fe-7fc8b3540992), [Security regisrtation info](https://entra.microsoft.com/#view/Microsoft_AAD_ConditionalAccess/PolicyBlade/policyId/508ae024-d4c4-42bf-a8c9-40257c214c10) |\n| Jordan Smith | [jordan@contoso.com](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/overview/userId/bfaeba1e-1357-47de-9557-529caa103d5d) | ✅ | ❌ | ❌ | [MFA - All users](https://entra.microsoft.com/#view/Microsoft_AAD_ConditionalAccess/PolicyBlade/policyId/474ddef4-5620-4e7a-8976-6e9b095b2675), [j-test admin](https://entra.microsoft.com/#view/Microsoft_AAD_ConditionalAccess/PolicyBlade/policyId/6c0ef46a-3b58-43a9-b451-7464a16d91d7), [Block Device Code](https://entra.microsoft.com/#view/Microsoft_AAD_ConditionalAccess/PolicyBlade/policyId/db2153a1-40a2-457f-917c-c280b204b5cd), [testdevicereg21872](https://entra.microsoft.com/#view/Microsoft_AAD_ConditionalAccess/PolicyBlade/policyId/620a9c5c-09c4-4558-a0fe-7fc8b3540992), [Security regisrtation info](https://entra.microsoft.com/#view/Microsoft_AAD_ConditionalAccess/PolicyBlade/policyId/508ae024-d4c4-42bf-a8c9-40257c214c10) |\n| Jamie Rodriguez | [jamie@contoso.com](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/overview/userId/0b37813c-ae19-4399-982f-16587f17f9c0) | ✅ | ❌ | ❌ | [MFA - All users](https://entra.microsoft.com/#view/Microsoft_AAD_ConditionalAccess/PolicyBlade/policyId/474ddef4-5620-4e7a-8976-6e9b095b2675), [Block Device Code](https://entra.microsoft.com/#view/Microsoft_AAD_ConditionalAccess/PolicyBlade/policyId/db2153a1-40a2-457f-917c-c280b204b5cd), [testdevicereg21872](https://entra.microsoft.com/#view/Microsoft_AAD_ConditionalAccess/PolicyBlade/policyId/620a9c5c-09c4-4558-a0fe-7fc8b3540992), [Security regisrtation info](https://entra.microsoft.com/#view/Microsoft_AAD_ConditionalAccess/PolicyBlade/policyId/508ae024-d4c4-42bf-a8c9-40257c214c10), [Block access except Compliant Network](https://entra.microsoft.com/#view/Microsoft_AAD_ConditionalAccess/PolicyBlade/policyId/9ee6df4b-165d-4f86-a176-0ddcc4ad886c) |\n| Jules Bailey | [jules@contoso.com](https://entra.microsoft.com/#view/Microsoft_AAD_UsersAndTenants/UserProfileMenuBlade/~/overview/userId/0145d508-50fd-4f86-a47a-bf1c043c8358) | ❌ | ❌ | ❌ | [MFA - All users](https://entra.microsoft.com/#view/Microsoft_AAD_ConditionalAccess/PolicyBlade/policyId/474ddef4-5620-4e7a-8976-6e9b095b2675), [Block Device Code](https://entra.microsoft.com/#view/Microsoft_AAD_ConditionalAccess/PolicyBlade/policyId/db2153a1-40a2-457f-917c-c280b204b5cd), [testdevicereg21872](https://entra.microsoft.com/#view/Microsoft_AAD_ConditionalAccess/PolicyBlade/policyId/620a9c5c-09c4-4558-a0fe-7fc8b3540992), [Security regisrtation info](https://entra.microsoft.com/#view/Microsoft_AAD_ConditionalAccess/PolicyBlade/policyId/508ae024-d4c4-42bf-a8c9-40257c214c10) |\n\n\n\n","TestStatus":"Passed","TestDescription":"Microsoft recommends that organizations have two cloud-only Quinn Garcia accounts permanently assigned the [Global Administrator](https://learn.microsoft.com/entra/identity/role-based-access-control/permissions-reference?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci#global-administrator) role. These accounts are highly privileged and aren't assigned to specific individuals. The accounts are limited to emergency or \"break glass\" scenarios where normal accounts can't be used or all other administrators are accidentally locked out.\n\n**Remediation action**\n\n- Create accounts following the [Quinn Garcia account recommendations](https://learn.microsoft.com/entra/identity/role-based-access-control/security-emergency-access?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci).\n","TestId":"21835"},{"TestImplementationCost":"Low","TestPillar":"Devices","TestCategory":"Device","SkippedReason":null,"TestImpact":"Medium","TestAppliesTo":null,"TestSfiPillar":"Protect tenants and isolate production systems","TestSkipped":"","TestMinimumLicense":"Intune","TestTags":null,"TestTitle":"An iOS update policy is created and assigned","TestRisk":"High","TestResult":"\nAn iOS update policy is configured and assigned.\n\n\n## iOS Update Policies\n\n| Policy Name | Status | Assignment Target |\n| :---------- | :----- | :---------------- |\n| [iOS_Update_1](https://intune.microsoft.com/#view/Microsoft_Intune_DeviceSettings/DevicesMenu/~/iOSiPadOSUpdate) | ❌ Not assigned | None |\n| [alex_ios_DDM_SoftwareUpdate](https://intune.microsoft.com/#view/Microsoft_Intune_DeviceSettings/DevicesMenu/~/configuration) | ✅ Assigned | **Included:** All Devices, **Excluded:** WFgroup |\n| [alex_ios_DDM_SoftwareUpdateEnforceLatest](https://intune.microsoft.com/#view/Microsoft_Intune_DeviceSettings/DevicesMenu/~/configuration) | ✅ Assigned | **Included:** All Devices, **Excluded:** WFgroup |\n| [alex_ios_policy1](https://intune.microsoft.com/#view/Microsoft_Intune_DeviceSettings/DevicesMenu/~/configuration) | ❌ Not assigned | None |\n| [alex_ios_policy2](https://intune.microsoft.com/#view/Microsoft_Intune_DeviceSettings/DevicesMenu/~/configuration) | ✅ Assigned | **Included:** All Users |\n\n\n\n","TestStatus":"Passed","TestDescription":"If iOS update policies aren’t configured and assigned, threat actors can exploit unpatched vulnerabilities in outdated operating systems on managed devices. The absence of enforced update policies allows attackers to use known exploits to gain initial access, escalate privileges, and move laterally within the environment. Without timely updates, devices remain susceptible to exploits that have already been addressed by Apple, enabling threat actors to bypass security controls, deploy malware, or exfiltrate sensitive data. This attack chain begins with device compromise through an unpatched vulnerability, followed by persistence and potential data breach that impacts both organizational security and compliance posture.\n\nEnforcing update policies disrupts this chain by ensuring devices are consistently protected against known threats.\n\n**Remediation action**\n\nConfigure and assign iOS/iPadOS update policies in Intune to enforce timely patching and reduce risk from unpatched vulnerabilities: \n- [Manage iOS/iPadOS software updates in Intune](https://learn.microsoft.com/intune/intune-service/protect/software-updates-guide-ios-ipados?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci)\n- [Assign policies in Intune](https://learn.microsoft.com/intune/intune-service/configuration/device-profile-assign?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci#assign-a-policy-to-users-or-groups)\n","TestId":"24554"},{"TestImplementationCost":"Low","TestPillar":"Identity","TestCategory":"Monitoring","SkippedReason":null,"TestImpact":"Low","TestAppliesTo":["Identity"],"TestSfiPillar":"Monitor and detect cyberthreats","TestSkipped":"","TestMinimumLicense":"P2","TestTags":["Identity"],"TestTitle":"Activation alert for highly privileged role assignments","TestRisk":"High","TestResult":"\nRole notifications are not properly configured.\n\nNote: To save time, this check stops when it finds the first role that does not have notifications. After fixing this role and all other roles, we recommend running the check again to verify.\n\n\n## Notifications for high privileged roles\n\n\n| Role Name | Notification Scenario | Notification Type | Default Recipients Enabled | Additional Recipients |\n| :-------- | :-------------------- | :---------------- | :------------------------- | :-------------------- |\n| AI Administrator | Send notifications when members are assigned as eligible to this role | Role assignment alert | True | |\n| AI Administrator | Send notifications when members are assigned as eligible to this role | Notification to the assigned user (assignee) | True | |\n| AI Administrator | Send notifications when members are assigned as eligible to this role | Request to approve a role assignment renewal/extension | True | |\n| AI Administrator | Send notifications when members are assigned as active to this role | Role assignment alert | True | |\n| AI Administrator | Send notifications when members are assigned as active to this role | Notification to the assigned user (assignee) | True | |\n| AI Administrator | Send notifications when members are assigned as active to this role | Request to approve a role assignment renewal/extension | True | |\n| AI Administrator | Send notifications when eligible members activate this role | Role activation alert | True | |\n| AI Administrator | Send notifications when eligible members activate this role | Notification to activated user (requestor) | True | |\n| AI Administrator | Send notifications when eligible members activate this role | Request to approve an activation | True | |\n| AI Reader | Send notifications when members are assigned as eligible to this role | Role assignment alert | True | |\n| AI Reader | Send notifications when members are assigned as eligible to this role | Notification to the assigned user (assignee) | True | |\n| AI Reader | Send notifications when members are assigned as eligible to this role | Request to approve a role assignment renewal/extension | True | |\n| AI Reader | Send notifications when members are assigned as active to this role | Role assignment alert | True | |\n| AI Reader | Send notifications when members are assigned as active to this role | Notification to the assigned user (assignee) | True | |\n| AI Reader | Send notifications when members are assigned as active to this role | Request to approve a role assignment renewal/extension | True | |\n| AI Reader | Send notifications when eligible members activate this role | Role activation alert | True | |\n| AI Reader | Send notifications when eligible members activate this role | Notification to activated user (requestor) | True | |\n| AI Reader | Send notifications when eligible members activate this role | Request to approve an activation | True | |\n| Agent ID Administrator | Send notifications when members are assigned as eligible to this role | Role assignment alert | True | |\n| Agent ID Administrator | Send notifications when members are assigned as eligible to this role | Notification to the assigned user (assignee) | True | |\n| Agent ID Administrator | Send notifications when members are assigned as eligible to this role | Request to approve a role assignment renewal/extension | True | |\n| Agent ID Administrator | Send notifications when members are assigned as active to this role | Role assignment alert | True | |\n| Agent ID Administrator | Send notifications when members are assigned as active to this role | Notification to the assigned user (assignee) | True | |\n| Agent ID Administrator | Send notifications when members are assigned as active to this role | Request to approve a role assignment renewal/extension | True | |\n| Agent ID Administrator | Send notifications when eligible members activate this role | Role activation alert | True | |\n| Agent ID Administrator | Send notifications when eligible members activate this role | Notification to activated user (requestor) | True | |\n| Agent ID Administrator | Send notifications when eligible members activate this role | Request to approve an activation | True | |\n| Application Administrator | Send notifications when members are assigned as eligible to this role | Role assignment alert | True | jordan@contoso.com |\n| Application Administrator | Send notifications when members are assigned as eligible to this role | Notification to the assigned user (assignee) | True | ash@contoso.com |\n| Application Administrator | Send notifications when members are assigned as eligible to this role | Request to approve a role assignment renewal/extension | True | |\n| Application Administrator | Send notifications when members are assigned as active to this role | Role assignment alert | True | |\n| Application Administrator | Send notifications when members are assigned as active to this role | Notification to the assigned user (assignee) | True | |\n| Application Administrator | Send notifications when members are assigned as active to this role | Request to approve a role assignment renewal/extension | True | |\n| Application Administrator | Send notifications when eligible members activate this role | Role activation alert | True | |\n| Application Administrator | Send notifications when eligible members activate this role | Notification to activated user (requestor) | True | |\n| Application Administrator | Send notifications when eligible members activate this role | Request to approve an activation | True | |\n| Application Developer | Send notifications when members are assigned as eligible to this role | Role assignment alert | True | jordan@contoso.com |\n| Application Developer | Send notifications when members are assigned as eligible to this role | Notification to the assigned user (assignee) | True | |\n| Application Developer | Send notifications when members are assigned as eligible to this role | Request to approve a role assignment renewal/extension | True | |\n| Application Developer | Send notifications when members are assigned as active to this role | Role assignment alert | True | |\n| Application Developer | Send notifications when members are assigned as active to this role | Notification to the assigned user (assignee) | True | |\n| Application Developer | Send notifications when members are assigned as active to this role | Request to approve a role assignment renewal/extension | True | |\n| Application Developer | Send notifications when eligible members activate this role | Role activation alert | True | |\n| Application Developer | Send notifications when eligible members activate this role | Notification to activated user (requestor) | True | |\n| Application Developer | Send notifications when eligible members activate this role | Request to approve an activation | True | |\n| Attribute Provisioning Administrator | Send notifications when members are assigned as eligible to this role | Role assignment alert | True | |\n| Attribute Provisioning Administrator | Send notifications when members are assigned as eligible to this role | Notification to the assigned user (assignee) | True | |\n| Attribute Provisioning Administrator | Send notifications when members are assigned as eligible to this role | Request to approve a role assignment renewal/extension | True | |\n| Attribute Provisioning Administrator | Send notifications when members are assigned as active to this role | Role assignment alert | True | |\n| Attribute Provisioning Administrator | Send notifications when members are assigned as active to this role | Notification to the assigned user (assignee) | True | |\n| Attribute Provisioning Administrator | Send notifications when members are assigned as active to this role | Request to approve a role assignment renewal/extension | True | |\n| Attribute Provisioning Administrator | Send notifications when eligible members activate this role | Role activation alert | True | |\n| Attribute Provisioning Administrator | Send notifications when eligible members activate this role | Notification to activated user (requestor) | True | |\n| Attribute Provisioning Administrator | Send notifications when eligible members activate this role | Request to approve an activation | True | |\n| Attribute Provisioning Reader | Send notifications when members are assigned as eligible to this role | Role assignment alert | True | |\n| Attribute Provisioning Reader | Send notifications when members are assigned as eligible to this role | Notification to the assigned user (assignee) | True | |\n| Attribute Provisioning Reader | Send notifications when members are assigned as eligible to this role | Request to approve a role assignment renewal/extension | True | |\n| Attribute Provisioning Reader | Send notifications when members are assigned as active to this role | Role assignment alert | True | |\n| Attribute Provisioning Reader | Send notifications when members are assigned as active to this role | Notification to the assigned user (assignee) | True | |\n| Attribute Provisioning Reader | Send notifications when members are assigned as active to this role | Request to approve a role assignment renewal/extension | True | |\n| Attribute Provisioning Reader | Send notifications when eligible members activate this role | Role activation alert | True | |\n| Attribute Provisioning Reader | Send notifications when eligible members activate this role | Notification to activated user (requestor) | True | |\n| Attribute Provisioning Reader | Send notifications when eligible members activate this role | Request to approve an activation | True | |\n| Authentication Administrator | Send notifications when members are assigned as eligible to this role | Role assignment alert | True | |\n| Authentication Administrator | Send notifications when members are assigned as eligible to this role | Notification to the assigned user (assignee) | True | |\n| Authentication Administrator | Send notifications when members are assigned as eligible to this role | Request to approve a role assignment renewal/extension | True | |\n| Authentication Administrator | Send notifications when members are assigned as active to this role | Role assignment alert | True | |\n| Authentication Administrator | Send notifications when members are assigned as active to this role | Notification to the assigned user (assignee) | True | |\n| Authentication Administrator | Send notifications when members are assigned as active to this role | Request to approve a role assignment renewal/extension | True | |\n| Authentication Administrator | Send notifications when eligible members activate this role | Role activation alert | True | |\n| Authentication Administrator | Send notifications when eligible members activate this role | Notification to activated user (requestor) | True | |\n| Authentication Administrator | Send notifications when eligible members activate this role | Request to approve an activation | True | |\n| Authentication Extensibility Administrator | Send notifications when members are assigned as eligible to this role | Role assignment alert | True | |\n| Authentication Extensibility Administrator | Send notifications when members are assigned as eligible to this role | Notification to the assigned user (assignee) | True | |\n| Authentication Extensibility Administrator | Send notifications when members are assigned as eligible to this role | Request to approve a role assignment renewal/extension | True | |\n| Authentication Extensibility Administrator | Send notifications when members are assigned as active to this role | Role assignment alert | True | |\n| Authentication Extensibility Administrator | Send notifications when members are assigned as active to this role | Notification to the assigned user (assignee) | True | |\n| Authentication Extensibility Administrator | Send notifications when members are assigned as active to this role | Request to approve a role assignment renewal/extension | True | |\n| Authentication Extensibility Administrator | Send notifications when eligible members activate this role | Role activation alert | True | |\n| Authentication Extensibility Administrator | Send notifications when eligible members activate this role | Notification to activated user (requestor) | True | |\n| Authentication Extensibility Administrator | Send notifications when eligible members activate this role | Request to approve an activation | True | |\n| Authentication Extensibility Password Administrator | Send notifications when members are assigned as eligible to this role | Role assignment alert | True | |\n| Authentication Extensibility Password Administrator | Send notifications when members are assigned as eligible to this role | Notification to the assigned user (assignee) | True | |\n| Authentication Extensibility Password Administrator | Send notifications when members are assigned as eligible to this role | Request to approve a role assignment renewal/extension | True | |\n| Authentication Extensibility Password Administrator | Send notifications when members are assigned as active to this role | Role assignment alert | True | |\n| Authentication Extensibility Password Administrator | Send notifications when members are assigned as active to this role | Notification to the assigned user (assignee) | True | |\n| Authentication Extensibility Password Administrator | Send notifications when members are assigned as active to this role | Request to approve a role assignment renewal/extension | True | |\n| Authentication Extensibility Password Administrator | Send notifications when eligible members activate this role | Role activation alert | True | |\n| Authentication Extensibility Password Administrator | Send notifications when eligible members activate this role | Notification to activated user (requestor) | True | |\n| Authentication Extensibility Password Administrator | Send notifications when eligible members activate this role | Request to approve an activation | True | |\n| B2C IEF Keyset Administrator | Send notifications when members are assigned as eligible to this role | Role assignment alert | True | |\n| B2C IEF Keyset Administrator | Send notifications when members are assigned as eligible to this role | Notification to the assigned user (assignee) | True | |\n| B2C IEF Keyset Administrator | Send notifications when members are assigned as eligible to this role | Request to approve a role assignment renewal/extension | True | |\n| B2C IEF Keyset Administrator | Send notifications when members are assigned as active to this role | Role assignment alert | True | |\n| B2C IEF Keyset Administrator | Send notifications when members are assigned as active to this role | Notification to the assigned user (assignee) | True | |\n| B2C IEF Keyset Administrator | Send notifications when members are assigned as active to this role | Request to approve a role assignment renewal/extension | True | |\n| B2C IEF Keyset Administrator | Send notifications when eligible members activate this role | Role activation alert | True | |\n| B2C IEF Keyset Administrator | Send notifications when eligible members activate this role | Notification to activated user (requestor) | True | |\n| B2C IEF Keyset Administrator | Send notifications when eligible members activate this role | Request to approve an activation | True | |\n| Cloud Application Administrator | Send notifications when members are assigned as eligible to this role | Role assignment alert | True | |\n| Cloud Application Administrator | Send notifications when members are assigned as eligible to this role | Notification to the assigned user (assignee) | True | |\n| Cloud Application Administrator | Send notifications when members are assigned as eligible to this role | Request to approve a role assignment renewal/extension | True | |\n| Cloud Application Administrator | Send notifications when members are assigned as active to this role | Role assignment alert | True | |\n| Cloud Application Administrator | Send notifications when members are assigned as active to this role | Notification to the assigned user (assignee) | True | |\n| Cloud Application Administrator | Send notifications when members are assigned as active to this role | Request to approve a role assignment renewal/extension | True | |\n| Cloud Application Administrator | Send notifications when eligible members activate this role | Role activation alert | True | |\n| Cloud Application Administrator | Send notifications when eligible members activate this role | Notification to activated user (requestor) | True | |\n| Cloud Application Administrator | Send notifications when eligible members activate this role | Request to approve an activation | True | |\n| Cloud Device Administrator | Send notifications when members are assigned as eligible to this role | Role assignment alert | True | |\n| Cloud Device Administrator | Send notifications when members are assigned as eligible to this role | Notification to the assigned user (assignee) | True | |\n| Cloud Device Administrator | Send notifications when members are assigned as eligible to this role | Request to approve a role assignment renewal/extension | True | |\n| Cloud Device Administrator | Send notifications when members are assigned as active to this role | Role assignment alert | True | |\n| Cloud Device Administrator | Send notifications when members are assigned as active to this role | Notification to the assigned user (assignee) | True | |\n| Cloud Device Administrator | Send notifications when members are assigned as active to this role | Request to approve a role assignment renewal/extension | True | |\n| Cloud Device Administrator | Send notifications when eligible members activate this role | Role activation alert | True | |\n| Cloud Device Administrator | Send notifications when eligible members activate this role | Notification to activated user (requestor) | True | |\n| Cloud Device Administrator | Send notifications when eligible members activate this role | Request to approve an activation | True | |\n| Conditional Access Administrator | Send notifications when members are assigned as eligible to this role | Role assignment alert | True | |\n| Conditional Access Administrator | Send notifications when members are assigned as eligible to this role | Notification to the assigned user (assignee) | True | |\n| Conditional Access Administrator | Send notifications when members are assigned as eligible to this role | Request to approve a role assignment renewal/extension | True | |\n| Conditional Access Administrator | Send notifications when members are assigned as active to this role | Role assignment alert | True | |\n| Conditional Access Administrator | Send notifications when members are assigned as active to this role | Notification to the assigned user (assignee) | True | |\n| Conditional Access Administrator | Send notifications when members are assigned as active to this role | Request to approve a role assignment renewal/extension | True | |\n| Conditional Access Administrator | Send notifications when eligible members activate this role | Role activation alert | True | |\n| Conditional Access Administrator | Send notifications when eligible members activate this role | Notification to activated user (requestor) | True | |\n| Conditional Access Administrator | Send notifications when eligible members activate this role | Request to approve an activation | True | |\n| Directory Writers | Send notifications when members are assigned as eligible to this role | Role assignment alert | True | |\n| Directory Writers | Send notifications when members are assigned as eligible to this role | Notification to the assigned user (assignee) | True | |\n| Directory Writers | Send notifications when members are assigned as eligible to this role | Request to approve a role assignment renewal/extension | True | |\n| Directory Writers | Send notifications when members are assigned as active to this role | Role assignment alert | True | |\n| Directory Writers | Send notifications when members are assigned as active to this role | Notification to the assigned user (assignee) | True | |\n| Directory Writers | Send notifications when members are assigned as active to this role | Request to approve a role assignment renewal/extension | True | |\n| Directory Writers | Send notifications when eligible members activate this role | Role activation alert | True | |\n| Directory Writers | Send notifications when eligible members activate this role | Notification to activated user (requestor) | True | |\n| Directory Writers | Send notifications when eligible members activate this role | Request to approve an activation | True | |\n| Domain Name Administrator | Send notifications when members are assigned as eligible to this role | Role assignment alert | True | |\n| Domain Name Administrator | Send notifications when members are assigned as eligible to this role | Notification to the assigned user (assignee) | True | |\n| Domain Name Administrator | Send notifications when members are assigned as eligible to this role | Request to approve a role assignment renewal/extension | True | |\n| Domain Name Administrator | Send notifications when members are assigned as active to this role | Role assignment alert | True | |\n| Domain Name Administrator | Send notifications when members are assigned as active to this role | Notification to the assigned user (assignee) | True | |\n| Domain Name Administrator | Send notifications when members are assigned as active to this role | Request to approve a role assignment renewal/extension | True | |\n| Domain Name Administrator | Send notifications when eligible members activate this role | Role activation alert | True | |\n| Domain Name Administrator | Send notifications when eligible members activate this role | Notification to activated user (requestor) | True | |\n| Domain Name Administrator | Send notifications when eligible members activate this role | Request to approve an activation | True | |\n| ExamStudyTest | Send notifications when members are assigned as eligible to this role | Role assignment alert | True | |\n| ExamStudyTest | Send notifications when members are assigned as eligible to this role | Notification to the assigned user (assignee) | True | |\n| ExamStudyTest | Send notifications when members are assigned as eligible to this role | Request to approve a role assignment renewal/extension | True | |\n| ExamStudyTest | Send notifications when members are assigned as active to this role | Role assignment alert | True | |\n| ExamStudyTest | Send notifications when members are assigned as active to this role | Notification to the assigned user (assignee) | True | |\n| ExamStudyTest | Send notifications when members are assigned as active to this role | Request to approve a role assignment renewal/extension | True | |\n| ExamStudyTest | Send notifications when eligible members activate this role | Role activation alert | True | |\n| ExamStudyTest | Send notifications when eligible members activate this role | Notification to activated user (requestor) | True | |\n| ExamStudyTest | Send notifications when eligible members activate this role | Request to approve an activation | True | |\n| External Identity Provider Administrator | Send notifications when members are assigned as eligible to this role | Role assignment alert | True | |\n| External Identity Provider Administrator | Send notifications when members are assigned as eligible to this role | Notification to the assigned user (assignee) | True | |\n| External Identity Provider Administrator | Send notifications when members are assigned as eligible to this role | Request to approve a role assignment renewal/extension | True | |\n| External Identity Provider Administrator | Send notifications when members are assigned as active to this role | Role assignment alert | True | |\n| External Identity Provider Administrator | Send notifications when members are assigned as active to this role | Notification to the assigned user (assignee) | True | |\n| External Identity Provider Administrator | Send notifications when members are assigned as active to this role | Request to approve a role assignment renewal/extension | True | |\n| External Identity Provider Administrator | Send notifications when eligible members activate this role | Role activation alert | True | |\n| External Identity Provider Administrator | Send notifications when eligible members activate this role | Notification to activated user (requestor) | True | |\n| External Identity Provider Administrator | Send notifications when eligible members activate this role | Request to approve an activation | True | |\n| Global Administrator | Send notifications when members are assigned as eligible to this role | Role assignment alert | False | |\n\n\n\n","TestStatus":"Failed","TestDescription":"Organizations without proper activation alerts for highly privileged roles lack visibility into when users access these critical permissions. Threat actors can exploit this monitoring gap to perform privilege escalation by activating highly privileged roles without detection, then establish persistence through admin account creation or security policy modifications. The absence of real-time alerts enables attackers to conduct lateral movement, modify audit configurations, and disable security controls without triggering immediate response procedures.\n\n**Remediation action**\n\n- [Configure Microsoft Entra role settings in Privileged Identity Management](https://learn.microsoft.com/entra/id-governance/privileged-identity-management/pim-how-to-change-default-settings?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci#require-justification-on-activation)\n","TestId":"21818"},{"TestImpact":"Low","TestRisk":"Low","TestSkipped":"NotConnectedToService","TestAppliesTo":null,"TestPillar":"Data","TestCategory":"SharePoint Online","TestDescription":"Information Rights Management (IRM) integration in SharePoint Online libraries is a legacy feature that has been replaced by Enhanced SharePoint Permissions (ESP). Any library using this legacy capability should be flagged to move to newer capabilities.\n\n**Remediation action**\n\nTo disable legacy IRM in SharePoint Online:\n1. Identify libraries currently using IRM protection (audit existing sites)\n2. Plan migration to modern sensitivity labels with encryption\n3. Connect to SharePoint Online: `Connect-SPOService -Url https://-admin.sharepoint.com`\n4. Disable legacy IRM: `Set-SPOTenant -IrmEnabled $false`\n5. Enable modern sensitivity labels: `Set-SPOTenant -EnableAIPIntegration $true`\n6. Configure and publish sensitivity labels with encryption to replace IRM policies\n\n- [Enable sensitivity labels for SharePoint and OneDrive](https://learn.microsoft.com/microsoft-365/compliance/sensitivity-labels-sharepoint-onedrive-files)\n- [SharePoint IRM and sensitivity labels (migration guidance)](https://learn.microsoft.com/microsoft-365/compliance/sensitivity-labels-sharepoint-onedrive-files#sharepoint-information-rights-management-irm-and-sensitivity-labels)\n- [Create and configure sensitivity labels with encryption](https://learn.microsoft.com/microsoft-365/compliance/encryption-sensitivity-labels)\n\n","TestTitle":"Information Rights Management is enabled in SharePoint Online","SkippedReason":"This test requires connection to the service(s) \"SharePointOnline\" currently disconnected. Please use _Connect-ZtAssessment_ to connect.","TestId":"35007","TestImplementationCost":"Low","TestMinimumLicense":["RMS_S_PREMIUM"],"TestSfiPillar":"","TestResult":"\nSkipped. This test requires connection to the service(s) \"SharePointOnline\" currently disconnected. Please use _Connect-ZtAssessment_ to connect.\n","TestStatus":"Skipped","TestTags":null},{"TestImplementationCost":"High","TestPillar":"Identity","TestCategory":"Monitoring","SkippedReason":null,"TestImpact":"Low","TestAppliesTo":["Identity"],"TestSfiPillar":"Monitor and detect cyberthreats","TestSkipped":"","TestMinimumLicense":"P2","TestTags":["Identity"],"TestTitle":"All high-risk sign-ins are triaged","TestRisk":"High","TestResult":"\nFound **9** untriaged high-risk sign ins.\n## Untriaged High-Risk Sign ins\n\n| Date | User Principal Name | Type | Risk Level |\n| :---- | :---- | :---- | :---- |\n| 04/19/2026 22:27:06 | finley.robinson@contoso.com | anonymizedIPAddress | High |\n| 04/21/2026 03:30:29 | finley.robinson@contoso.com | unfamiliarFeatures | High |\n| 05/06/2026 13:36:36 | finley.robinson@contoso.com | maliciousIPAddress | High |\n| 04/16/2026 20:18:45 | finley.robinson@contoso.com | unfamiliarFeatures | High |\n| 04/19/2026 21:50:48 | finley.robinson@contoso.com | unfamiliarFeatures | High |\n| 04/24/2026 15:18:48 | finley.robinson@contoso.com | unfamiliarFeatures | High |\n| 04/24/2026 19:17:28 | finley.robinson@contoso.com | anonymizedIPAddress | High |\n| 04/25/2026 13:32:56 | finley.robinson@contoso.com | maliciousIPAddress | High |\n| 05/05/2026 05:58:04 | finley.robinson@contoso.com | anonymizedIPAddress | High |\n\n\n","TestStatus":"Failed","TestDescription":"Risky sign-ins flagged by Microsoft Entra ID Protection indicate a high probability of unauthorized access attempts. Threat actors use these sign-ins to gain an initial foothold. If these sign-ins remain uninvestigated, adversaries can establish persistence by repeatedly authenticating under the guise of legitimate users. \n\nA lack of response lets attackers execute reconnaissance, attempt to escalate their access, and blend into normal patterns. When untriaged sign-ins continue to generate alerts and there's no intervention, security gaps widen, facilitating lateral movement and defense evasion, as adversaries recognize the absence of an active security response.\n\n**Remediation action**\n\n- [Investigate risky sign-ins](https://learn.microsoft.com/entra/id-protection/howto-identity-protection-investigate-risk?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci)\n- [Remediate risks and unblock users](https://learn.microsoft.com/entra/id-protection/howto-identity-protection-remediate-unblock?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci)\n","TestId":"21863"},{"TestImplementationCost":"Low","TestPillar":"Identity","TestCategory":"Application management","SkippedReason":null,"TestImpact":"Low","TestAppliesTo":["Identity"],"TestSfiPillar":"Protect engineering systems","TestSkipped":"","TestMinimumLicense":"P1","TestTags":["Application"],"TestTitle":"Inactive applications don’t have highly privileged Microsoft Entra built-in roles","TestRisk":"High","TestResult":"\nNo inactive applications with privileged Entra built-in roles\n\n\n## Apps with privileged Entra built-in roles\n\n| | Name | Role | Assignment | App owner tenant | Last sign in|\n| :--- | :--- | :--- | :--- | :--- | :--- |\n| ✅ | [Mailbox Migration Account](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/Overview/objectId/d22f071d-e8d3-41fc-a516-b29753cdd1f6/appId/b650c3c1-3395-40bb-8471-2a6a8b76d8a9) | Global Administrator, Application Administrator | Permanent | Pora Inc. | 2025-09-09 | \n| ✅ | [contoso-tenant-devops-7576c63d-bc90-4ae4-9f1c-0d959fb520db](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/Overview/objectId/c5632968-35cd-445d-926e-16e0afc9160e/appId/e876f7cb-13f3-48a4-8329-66d7b1fa33fb) | Global Administrator | Permanent | Pora Inc. | 2025-10-01 | \n| ✅ | [Custom-App-Test](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/Overview/objectId/38415a71-b77b-44d5-a276-539faabe0de7/appId/ddb4f0e6-8018-4359-96c1-7473704bde43) | Global Administrator | Permanent | Pora Inc. | 2026-05-14 | \n\n\n","TestStatus":"Passed","TestDescription":"Attackers might exploit valid but inactive applications that still have elevated privileges. These applications can be used to gain initial access without raising alarm because they're legitimate applications. From there, attackers can use the application privileges to plan or execute other attacks. Attackers might also maintain access by manipulating the inactive application, such as by adding credentials. This persistence ensures that even if their primary access method is detected, they can regain access later.\n\n**Remediation action**\n\n- [Disable inactive privileged service principals](https://learn.microsoft.com/graph/api/serviceprincipal-update?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci)\n- Investigate if the application has legitimate use cases. If so, [analyze if a OAuth2 permission is a better fit](https://learn.microsoft.com/entra/identity-platform/v2-app-types?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci)\n- [If service principal doesn't have legitimate use cases, delete it](https://learn.microsoft.com/graph/api/serviceprincipal-delete?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci)\n","TestId":"21771"},{"TestImplementationCost":"Medium","TestPillar":"Identity","TestCategory":"External collaboration","SkippedReason":"This test is for tenants that are licensed for Entra Workload ID. See [Entra Workload ID licensing](https://learn.microsoft.com/entra/workload-id/workload-identities-faqs)","TestImpact":"Low","TestAppliesTo":null,"TestSfiPillar":"Protect tenants and isolate production systems","TestSkipped":"NotLicensedEntraWorkloadID","TestMinimumLicense":"P1","TestTags":null,"TestTitle":"Conditional Access policies for workload identities based on known networks are configured","TestRisk":"High","TestResult":"\nSkipped. This test is for tenants that are licensed for Entra Workload ID. See [Entra Workload ID licensing](https://learn.microsoft.com/entra/workload-id/workload-identities-faqs)\n\n","TestStatus":"Skipped","TestDescription":"When workload identities operate without network-based Conditional Access restrictions, threat actors can compromise service principal credentials through various methods, such as exposed secrets in code repositories or intercepted authentication tokens. The threat actors can then use these credentials from any location globally. This unrestricted access enables threat actors to perform reconnaissance activities, enumerate resources, and map the tenant's infrastructure while appearing legitimate. Once the threat actor is established within the environment, they can move laterally between services, access sensitive data stores, and potentially escalate privileges by exploiting overly permissive service-to-service permissions. The lack of network restrictions makes it impossible to detect anomalous access patterns based on location. This gap allows threat actors to maintain persistent access and exfiltrate data over extended periods without triggering security alerts that would normally flag connections from unexpected networks or geographic locations. \n\n**Remediation action**\n\n- [Configure Conditional Access for workload identities](https://learn.microsoft.com/entra/identity/conditional-access/workload-identity?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci)\n- [Create named locations](https://learn.microsoft.com/entra/identity/conditional-access/concept-assignment-network?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci)\n- [Follow best practices for securing workload identities](https://learn.microsoft.com/entra/workload-id/workload-identities-overview?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci)\n","TestId":21884},{"TestImplementationCost":"Low","TestPillar":"Devices","TestCategory":"Device","SkippedReason":null,"TestImpact":"Low","TestAppliesTo":null,"TestSfiPillar":"Protect identities and secrets","TestSkipped":"","TestMinimumLicense":"Intune","TestTags":null,"TestTitle":"A macOS Cloud LAPS Policy is Created and Assigned","TestRisk":"High","TestResult":"\nNo macOS DEP tokens found in the tenant.\n\n\n\n","TestStatus":"Failed","TestDescription":"Without enforcing macOS LAPS policies during Automated Device Enrollment (ADE), threat actors can exploit static or reused local administrator passwords to escalate privileges, move laterally, and establish persistence. Devices provisioned without randomized credentials are vulnerable to credential harvesting and reuse across multiple endpoints, increasing the risk of domain-wide compromise.\n\nEnforcing macOS LAPS ensures that each device is provisioned with a unique, encrypted local administrator password managed by Intune. This disrupts the attack chain at the credential access and lateral movement stages, significantly reducing the risk of widespread compromise and aligning with Zero Trust principles of least privilege and credential hygiene.\n\n**Remediation action**\n\nUse Intune to configure macOS ADE profiles that provision a local admin account with a randomized and encrypted password, and that enables secure rotation: \n- [Configure macOS LAPS in Microsoft Intune](https://learn.microsoft.com/intune/intune-service/enrollment/macos-laps?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci)\n- [Rotate local admin password (macOS)](https://learn.microsoft.com/intune/intune-service/remote-actions/device-rotate-local-admin-password?pivots=macos&wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci)\n\nFor more information, see: \n- [macOS ADE setup guide](https://learn.microsoft.com/intune/intune-service/enrollment/device-enrollment-program-enroll-macos?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci)\n","TestId":"24561"},{"TestTitle":"Identity governance for agents — sponsors assigned, entitlement-management channel exists, and lifecycle automation in place","TestSkipped":"","TestResult":"\r\n❌ One or more agent identities or blueprints have no sponsor assigned, OR no access package in the tenant has an assignment policy targeting agent identities (`allowedTargetScope == 'allDirectoryAgentIdentities'`), OR no Lifecycle Workflow contains an enabled task whose `taskDefinitionId` matches one of the three documented agent-identity sponsor tasks. Failed: sponsorship.\n\n\r\n\r\n## [Agent identities and blueprints without an effective sponsor](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/AllAgents.MenuView/~/allAgentIds)\r\n\r\n| Object kind | Display name | Failure reason |\n| :--- | :--- | :--- |\n| agentIdentity | [abbe67-7752-abbe67-7752-AgentIdentity](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/Overview/objectId/50e8817d-82ee-4169-a062-01367cb53d3a/appId/8145218c-ec26-4e1a-8599-6f7138fdcd73) | no sponsors assigned |\n| agentIdentity | [AI-avo716-2028-ai-avo716-2028-project-ITHelpdesk-SuperAgent-AgentIdentity](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/Overview/objectId/b47723ce-a77e-41b3-8a7e-cb7dcc165dc1/appId/3f898c9a-6ac9-4e4c-8c70-f802adab1210) | no sponsors assigned |\n| agentIdentity | [ai-u16981-8299-demo-u16981-AgentIdentity](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/Overview/objectId/80fc5ea4-1fa9-4778-8fd7-229c09139943/appId/f47f4a4c-bf34-44ca-9e80-987e1c5691d1) | no sponsors assigned |\n| agentIdentity | [aif-mdcagentvxbnu-proj-mdcagentvxbnu-AgentIdentity](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/Overview/objectId/556d7d99-a132-47a1-b0ae-aeffd9d5d20a/appId/b2e712e0-86ca-4657-9dbf-f866ef56d0c1) | no sponsors assigned |\n| agentIdentity | [ais-489n-procurementagent-aifp-489n-procurementagent-AgentIdentity](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/Overview/objectId/76050bf8-3d31-45a8-8345-a6f49cdd0693/appId/6b9808b0-a9c3-4c9c-928c-96b96934f13d) | no sponsors assigned |\n| agentIdentity | [ais-489n-procurementagent-aifp-489n-procurementagent-procurement-v2-chat-agent-AgentIdentity](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/Overview/objectId/e1a053b6-2341-45a6-8cb7-7f92496d161e/appId/b735385b-45b0-401f-9e15-ce21e6e6d8a6) | no sponsors assigned |\n| agentIdentity | [ais-489n-procurementagent-aifp-489n-procurementagent-procurement-v2-orchestrator-agent-AgentIdentity](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/Overview/objectId/f540853a-3c29-4806-99b4-4e58ffe0a224/appId/90a877a9-c72a-4caf-952b-82740653f9e5) | no sponsors assigned |\n| agentIdentity | [ais-489n-procurementagent-aifp-489n-procurementagent-procurement-v2-policy-agent-AgentIdentity](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/Overview/objectId/8030f366-f586-4f0b-b9e7-95ab4adef7ba/appId/02db7443-38e2-44fd-9a5e-e8515fdc7865) | no sponsors assigned |\n| agentIdentity | [ais-489n-procurementagent-aifp-489n-procurementagent-procurement-v2-product-agent-AgentIdentity](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/Overview/objectId/7f1fc86b-a62f-4722-bade-9d007e30063b/appId/61876bac-5a5a-4637-8b11-bc43521bc8a0) | no sponsors assigned |\n| agentIdentity | [ais-procurementagent-aifp-procurementagent-naha84-test-AgentIdentity](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/Overview/objectId/690859f4-ed9b-4021-bf71-62e2a0c9e761/appId/02123a30-22c2-40c0-935d-f8aed0b2d35a) | no sponsors assigned |\n\n_**Note**: This table is truncated and showing the first 10 out of 136 total._\r\n\r\n\r\n## [Access packages and policies that grant access to agent identities](https://entra.microsoft.com/#view/Microsoft_AAD_ERM/DashboardBlade/~/AccessPackages)\r\n\r\n| Access package display name | Policy display name | Allowed target scope |\n| :--- | :--- | :--- |\n| Sponsor Intiated Agent Access | Initial Policy | allDirectoryAgentIdentities |\n\r\n\r\n\r\n## [Lifecycle Workflows containing agent-identity sponsor tasks](https://entra.microsoft.com/#view/Microsoft_AAD_LifecycleManagement/CommonMenuBlade/~/workflows)\r\n\r\n| Workflow display name | Workflow category | Workflow enabled | Matching task display name | Task enabled |\n| :--- | :--- | :--- | :--- | :--- |\n| [Offboard an employee from Woodgrove](https://entra.microsoft.com/#view/Microsoft_AAD_LifecycleManagement/DetailedWorkflowMenuBlade/~/overview/workflowId/dae45147-ec42-48ad-b1b3-9414b0b12848/workflowName/Offboard%20an%20employee%20from%20Woodgrove) | leaver | ✅ Yes | Transfer agent identity sponsorships to manager (Preview) | ✅ Yes |\n| [Mover - Transfer Agent Sponsorship](https://entra.microsoft.com/#view/Microsoft_AAD_LifecycleManagement/DetailedWorkflowMenuBlade/~/overview/workflowId/c2c06c52-b554-491d-afe0-d4559f38dc92/workflowName/Mover%20-%20Transfer%20Agent%20Sponsorship) | mover | ✅ Yes | Send email to manager about sponsorship changes | ✅ Yes |\n| [Mover - Transfer Agent Sponsorship](https://entra.microsoft.com/#view/Microsoft_AAD_LifecycleManagement/DetailedWorkflowMenuBlade/~/overview/workflowId/c2c06c52-b554-491d-afe0-d4559f38dc92/workflowName/Mover%20-%20Transfer%20Agent%20Sponsorship) | mover | ✅ Yes | Transfer agent sponsorships to manager | ✅ Yes |\n| [Sponsor change](https://entra.microsoft.com/#view/Microsoft_AAD_LifecycleManagement/DetailedWorkflowMenuBlade/~/overview/workflowId/609b0785-0251-4d6a-9403-b6f44e6ccd73/workflowName/Sponsor%20change) | mover | ✅ Yes | Send email to manager about sponsorship changes (Preview) | ✅ Yes |\n\r\n\r\n","TestSfiPillar":"Protect identities and secrets","TestStatus":"Failed","TestImpact":"Low","TestPillar":"AI","TestId":"61013","TestRisk":"Medium","TestDescription":"Microsoft Entra Agent ID requires every agent identity and every agent identity blueprint to have at least one sponsor — a human user (or supported group) who carries business accountability for the agent's lifecycle: deciding when the agent is no longer needed, requesting access packages on the agent's behalf, approving extensions when access expires, and authorising suspension during incidents. Sponsorship is the entry point for the rest of identity governance: lifecycle workflows route sponsor-leaving notifications to managers and cosponsors, access-package expiry escalations are sent to the sponsor, and entitlement-management approvers rely on the sponsor relationship to validate that an agent's continued access reflects current business need. An agent identity that exists in the tenant without a sponsor is governance-invisible. Sponsorship alone, however, is not enough: the workshop guidance also requires that agent permissions — group memberships, Microsoft Graph and other API permissions — flow through Microsoft Entra entitlement management rather than through direct grants. An access package is the unit of bundled grant; an assignment policy attached to that package decides who may request or be assigned the package, who must approve, how long the resulting assignment lasts, and how the assignment is reviewed for continued business need. When an organisation enables agent workloads but does not author at least one access package whose policy targets agent identities, every permission an agent receives must instead be granted directly — through `appRoleAssignment`, `oauth2PermissionGrant`, group `members/$ref`, or directory-role assignment — outside the entitlement-management control loop. Direct grants have no built-in expiration, no approver, no sponsor-driven extension notification, and no access-review schedule; once made, they persist until an administrator notices and removes them. A threat actor who later compromises the agent — through credential theft, blueprint compromise, or a malicious access-package request that no governance pipeline existed to intercept — operates against an identity whose permissions were never reviewed against current business need, the precise standing-privilege condition that lifecycle workflows, sponsor approvals, and time-bounded access packages are designed to prevent. This check verifies the two foundational conditions together: every agent identity and blueprint has at least one sponsor currently resolvable in the directory, and at least one access package in the tenant has an assignment policy whose `allowedTargetScope` is `allDirectoryAgentIdentities` — the Microsoft Graph value corresponding to the portal's *For users, service principals, and agent identities in your directory* → *All agents* selection.\r\n\r\n**Remediation action**\r\n\r\n- [Administrative relationships in Microsoft Entra Agent ID](https://learn.microsoft.com/en-us/entra/agent-id/identity-platform/agent-owners-sponsors-managers)\r\n- [Governing agent identities](https://learn.microsoft.com/en-us/entra/id-governance/agent-id-governance-overview)\r\n- [Agent identity sponsor tasks in Lifecycle Workflows (Preview)](https://learn.microsoft.com/en-us/entra/id-governance/agent-sponsor-tasks)\r\n- [Add sponsors to an agent identity](https://learn.microsoft.com/en-us/graph/api/agentidentity-post-sponsors?view=graph-rest-1.0)\r\n- [Manage agents in Microsoft Entra ID](https://learn.microsoft.com/en-us/entra/agent-id/manage-agent)\r\n- [Access packages for agent identities](https://learn.microsoft.com/en-us/entra/agent-id/agent-access-packages)\r\n- [Create an access package in entitlement management](https://learn.microsoft.com/en-us/entra/id-governance/entitlement-management-access-package-create)\r\n- [Create an assignment policy via Microsoft Graph](https://learn.microsoft.com/en-us/graph/api/entitlementmanagement-post-assignmentpolicies?view=graph-rest-beta)\r\n- [Delegation and roles in entitlement management](https://learn.microsoft.com/en-us/entra/id-governance/entitlement-management-delegate)\r\n- [Lifecycle Workflow built-in tasks](https://learn.microsoft.com/en-us/entra/id-governance/lifecycle-workflow-tasks)\r\n- [Create a workflow via Microsoft Graph](https://learn.microsoft.com/en-us/graph/api/identitygovernance-lifecycleworkflowscontainer-post-workflows?view=graph-rest-1.0)\r\n\r\n","TestTags":null,"TestMinimumLicense":["AAD_PREMIUM AND AGENT_365"],"SkippedReason":null,"TestAppliesTo":null,"TestImplementationCost":"Low","TestCategory":"AI Authentication & Access"},{"TestId":"25380","TestCategory":"Global Secure Access","TestImpact":"High","TestResult":"\r\n✅ Global Secure Access signaling for Conditional Access is enabled. Source IP restoration and compliant network checks are active.\n\n\n\n### [Global Secure Access Conditional Access settings](https://entra.microsoft.com/#view/Microsoft_Azure_Network_Access/Security.ReactView)\n| Property | Value |\n| :--- | :--- |\n| Signaling status | ✅ Enabled |\n\r\n\r\n","SkippedReason":null,"TestMinimumLicense":["AAD_PREMIUM","Entra_Premium_Internet_Access"],"TestAppliesTo":null,"TestTags":null,"TestSfiPillar":"Protect networks","TestImplementationCost":"Low","TestSkipped":"","TestPillar":"Network","TestTitle":"Global Secure Access signaling for Conditional Access is enabled","TestStatus":"Passed","TestDescription":"When Global Secure Access routes user traffic through Microsoft's Security Service Edge, it replaces the original source IP with the proxy egress IP. If you don't enable Global Secure Access signaling for Conditional Access, Microsoft Entra ID receives the proxy IP instead of the user's actual IP address. Conditional Access policies that rely on named locations or trusted IP ranges evaluate the proxy IP instead of the user's actual IP, reducing the effectiveness of location-based controls.\r\n\r\nIf you don't enable Global Secure Access signaling for Conditional Access:\r\n\r\n- Microsoft Entra ID Protection risk detections that depend on source IP, such as impossible travel and unfamiliar sign-in properties, are less reliable.\r\n- Sign-in logs record the proxy IP, which prevents security operations teams from correlating sign-in events to user locations during incident response.\r\n\r\n**Remediation action**\r\n\r\n- [Enable Global Secure Access signaling for Conditional Access](https://learn.microsoft.com/entra/global-secure-access/how-to-source-ip-restoration?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci#enable-global-secure-access-signaling-for-conditional-access).\r\n- [Enable compliant network check with Conditional Access](https://learn.microsoft.com/entra/global-secure-access/how-to-compliant-network?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci) to require users to connect through Global Secure Access.\r\n- [Understand how Universal Conditional Access works with Global Secure Access traffic profiles](https://learn.microsoft.com/entra/global-secure-access/concept-universal-conditional-access?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci).\r\n","TestRisk":"Medium"},{"TestTitle":"Sensitivity labels are enabled for SharePoint and OneDrive","TestSkipped":"NotConnectedToService","TestResult":"\r\nSkipped. This test requires connection to the service(s) \"SharePointOnline\" currently disconnected. Please use _Connect-ZtAssessment_ to connect.\r\n\r\n","TestSfiPillar":"Protect tenants and production systems","TestStatus":"Skipped","TestImpact":"Low","TestPillar":"AI","TestId":"35005","TestRisk":"High","TestDescription":"When sensitivity label integration is disabled (the default) in SharePoint, files in SharePoint and OneDrive can't be labeled or display existing labels, and can't benefit from the additional protection of sensitivity labels that apply encryption. This protection gap leaves sensitive files unclassified and vulnerable to unauthorized access and external sharing.\r\n\r\nEnabling sensitivity labels in SharePoint allows users to apply labels by using Office for the web and SharePoint. It's also a requirement for default labeling for these locations, and for auto-labeling policies that can classify files automatically. Sensitivity labels for these files can also strengthen security for Microsoft 365 Copilot, and be used with data loss prevention policies and other Microsoft Purview solutions.\r\n\r\n**Remediation action**\r\n\r\n- [Enable sensitivity labels for files in SharePoint and OneDrive](https://learn.microsoft.com/purview/sensitivity-labels-sharepoint-onedrive-files?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci)\r\n","TestTags":null,"TestMinimumLicense":["RMS_S_PREMIUM"],"SkippedReason":"This test requires connection to the service(s) \"SharePointOnline\" currently disconnected. Please use _Connect-ZtAssessment_ to connect.","TestAppliesTo":null,"TestImplementationCost":"Low","TestCategory":"SharePoint Online"},{"TestId":"25550","TestCategory":"Azure Network Security","TestImpact":"Low","TestResult":"\r\n❌ TLS inspection is not properly configured on Azure Firewall. Either the global certificate authority is missing, or no application rules have TLS inspection enabled.\n\n\r\n## Azure Firewall policies TLS inspection status\r\n\r\n| Subscription name | Azure Firewall policy name | Attached to Firewall | TLS inspection globally configured | Certificate authority name | Application rule with TLS inspection enabled |\r\n| :--- | :--- | :--- | :--- | :--- | :--- |\r\n| Woodgrove - GTP Demos (External/Sponsored) | [woodgrove-policy](https://portal.azure.com/#@/resource/subscriptions/ab48f397-fc82-4634-aa52-62dd91b3ebaa/resourceGroups/Woodgrove-RG/providers/Microsoft.Network/firewallPolicies/woodgrove-policy) | Yes | Yes | fw-cert-eodl1fmPodQrU | No |\n| Woodgrove - GTP Demos (External/Sponsored) | [woodgrove1-policy](https://portal.azure.com/#@/resource/subscriptions/ab48f397-fc82-4634-aa52-62dd91b3ebaa/resourceGroups/Woodgrove-RG/providers/Microsoft.Network/firewallPolicies/woodgrove1-policy) | Yes | Yes | fw-cert-7Ar5j8JJkPbB1 | No |\n| Woodgrove - GTP Demos (External/Sponsored) | [woodgrove2-policy](https://portal.azure.com/#@/resource/subscriptions/ab48f397-fc82-4634-aa52-62dd91b3ebaa/resourceGroups/Woodgrove-RG/providers/Microsoft.Network/firewallPolicies/woodgrove2-policy) | Yes | Yes | fw-cert-4FYAYX0P5xO3H | No |\n\r\n\r\n","SkippedReason":null,"TestMinimumLicense":"Azure_Firewall_Premium","TestAppliesTo":null,"TestTags":null,"TestSfiPillar":"Protect networks","TestImplementationCost":"Low","TestSkipped":"","TestPillar":"Network","TestTitle":"Inspection of Outbound TLS Traffic is Enabled on Azure Firewall","TestStatus":"Failed","TestDescription":"Azure Firewall Premium offers Transport Layer Security (TLS) inspection to decrypt and inspect outbound and east-west TLS traffic, and inbound TLS traffic when used with Azure Application Gateway. TLS inspection is critical for detecting advanced threats that use encrypted channels to evade traditional security controls.\r\n\r\nWhen TLS inspection is enabled, Azure Firewall uses a customer-provided CA certificate stored in Azure Key Vault to decrypt, inspect, and then re-encrypt traffic before forwarding it to its destination. This enables advanced security capabilities such as IDPS and URL filtering to analyze encrypted traffic and identify malicious activity that would otherwise remain hidden.\r\n\r\nThis check verifies that Azure Firewall Premium has TLS inspection enabled. Without TLS inspection, the firewall cannot inspect encrypted payloads, significantly limiting visibility into threats that leverage TLS to evade detection.\r\n\r\n**Remediation action**\r\n\r\n- [Azure Firewall Premium features implementation guide](https://learn.microsoft.com/en-us/azure/firewall/premium-features)\r\n- [Deploy and configure Enterprise CA certificates for Azure Firewall](https://learn.microsoft.com/en-us/azure/firewall/premium-deploy-certificates-enterprise-ca)\r\n- [Azure Firewall Premium certificates](https://learn.microsoft.com/en-us/azure/firewall/premium-certificates)\r\n\r\n","TestRisk":"High"},{"TestTitle":"Internet traffic is protected by web content filtering policies in Global Secure Access","TestSkipped":"","TestResult":"\r\n✅ Web content filtering policies are configured and enforced - either through security profiles assigned to Conditional Access policies or through the Baseline Profile which applies to all internet traffic.\n\n\r\n## [Web Content Filtering Policies](https://entra.microsoft.com/#view/Microsoft_Azure_Network_Access/WebFilteringPolicy.ReactView)\r\n\r\n| Policy Name | Action | Rules Count | Last Modified |\r\n| :---------- | :----- | ----------: | :------------ |\r\n| [Baseline Internet Access Block Rule](https://entra.microsoft.com/#view/Microsoft_Azure_Network_Access/EditFilteringPolicyMenuBlade.MenuView/~/Basics/policyId/0b76a267-f303-4623-b23f-27fc7bd82e16/title/Baseline%20Internet%20Access%20Block%20Rule/defaultMenuItemId/Basics) | allow | 0 | 2026-03-02 19:18 |\n| [Allow Ethical Hacking ](https://entra.microsoft.com/#view/Microsoft_Azure_Network_Access/EditFilteringPolicyMenuBlade.MenuView/~/Basics/policyId/5ad9c86c-f3f6-4da8-91dd-d2f4c3d85880/title/Allow%20Ethical%20Hacking%20/defaultMenuItemId/Basics) | allow | 1 | 2024-08-12 18:07 |\n| [Just in time access to Dropbox](https://entra.microsoft.com/#view/Microsoft_Azure_Network_Access/EditFilteringPolicyMenuBlade.MenuView/~/Basics/policyId/8aab9016-b865-47ca-a51e-e79718f318c7/title/Just%20in%20time%20access%20to%20Dropbox/defaultMenuItemId/Basics) | allow | 1 | 2024-08-12 18:07 |\n| [Allow LinkedIn](https://entra.microsoft.com/#view/Microsoft_Azure_Network_Access/EditFilteringPolicyMenuBlade.MenuView/~/Basics/policyId/d1456ea9-6a5f-4ebd-9bb9-a9686818b078/title/Allow%20LinkedIn/defaultMenuItemId/Basics) | allow | 1 | 2024-08-18 18:09 |\n| [Allow Dropbox](https://entra.microsoft.com/#view/Microsoft_Azure_Network_Access/EditFilteringPolicyMenuBlade.MenuView/~/Basics/policyId/6db122c6-0da0-4274-83dc-d137b4f125de/title/Allow%20Dropbox/defaultMenuItemId/Basics) | allow | 1 | 2024-10-18 22:36 |\n| [Allow Finance Sites](https://entra.microsoft.com/#view/Microsoft_Azure_Network_Access/EditFilteringPolicyMenuBlade.MenuView/~/Basics/policyId/f802e0a5-791c-4ec7-8e8b-ce040b69f11e/title/Allow%20Finance%20Sites/defaultMenuItemId/Basics) | allow | 1 | 2024-11-12 23:10 |\n| [Allow Fin team](https://entra.microsoft.com/#view/Microsoft_Azure_Network_Access/EditFilteringPolicyMenuBlade.MenuView/~/Basics/policyId/a8890d74-a95e-4ce8-9892-e8058256f5be/title/Allow%20Fin%20team/defaultMenuItemId/Basics) | allow | 1 | 2024-12-06 19:13 |\n| [Allow AI](https://entra.microsoft.com/#view/Microsoft_Azure_Network_Access/EditFilteringPolicyMenuBlade.MenuView/~/Basics/policyId/f81b4954-4d00-4e49-ae08-1f6c4036c4db/title/Allow%20AI/defaultMenuItemId/Basics) | allow | 3 | 2026-03-02 21:38 |\n| [Allow Gemini](https://entra.microsoft.com/#view/Microsoft_Azure_Network_Access/EditFilteringPolicyMenuBlade.MenuView/~/Basics/policyId/684724fb-cb6b-41d8-b91b-237ee7eaa249/title/Allow%20Gemini/defaultMenuItemId/Basics) | allow | 1 | 2026-03-02 21:56 |\n| [Allow ChatGPT](https://entra.microsoft.com/#view/Microsoft_Azure_Network_Access/EditFilteringPolicyMenuBlade.MenuView/~/Basics/policyId/a97224ed-831d-460a-baa3-d74b5a0ad119/title/Allow%20ChatGPT/defaultMenuItemId/Basics) | allow | 1 | 2025-07-17 22:29 |\n| [Allow Jasper](https://entra.microsoft.com/#view/Microsoft_Azure_Network_Access/EditFilteringPolicyMenuBlade.MenuView/~/Basics/policyId/17bdf204-eb5e-4b5f-a41f-17ae6f8f9b2f/title/Allow%20Jasper/defaultMenuItemId/Basics) | allow | 1 | 2025-03-26 16:03 |\n| [Allow Github](https://entra.microsoft.com/#view/Microsoft_Azure_Network_Access/EditFilteringPolicyMenuBlade.MenuView/~/Basics/policyId/da11bbe0-4c59-4880-b67f-e53cd8660ec2/title/Allow%20Github/defaultMenuItemId/Basics) | allow | 1 | 2025-03-26 16:04 |\n| [Block AI](https://entra.microsoft.com/#view/Microsoft_Azure_Network_Access/EditFilteringPolicyMenuBlade.MenuView/~/Basics/policyId/304802f3-b446-4ce0-88bf-7b3f1693bdd8/title/Block%20AI/defaultMenuItemId/Basics) | allow | 1 | 2025-11-07 09:46 |\n| [Windows](https://entra.microsoft.com/#view/Microsoft_Azure_Network_Access/EditFilteringPolicyMenuBlade.MenuView/~/Basics/policyId/83050ddf-4e6f-48d0-ad06-8c17ad051844/title/Windows/defaultMenuItemId/Basics) | allow | 2 | 2025-04-05 06:07 |\n| [Block_ratestream_connector_MCP_Server](https://entra.microsoft.com/#view/Microsoft_Azure_Network_Access/EditFilteringPolicyMenuBlade.MenuView/~/Basics/policyId/a2b11ce6-b1c1-4917-82e4-a10bd5915d78/title/Block_ratestream_connector_MCP_Server/defaultMenuItemId/Basics) | block | 1 | 2025-11-05 16:16 |\n| [Block Unsanctioned MCP by default](https://entra.microsoft.com/#view/Microsoft_Azure_Network_Access/EditFilteringPolicyMenuBlade.MenuView/~/Basics/policyId/992bba38-62a6-4c7b-aeac-4395dc5c6def/title/Block%20Unsanctioned%20MCP%20by%20default/defaultMenuItemId/Basics) | block | 2 | 2025-11-05 18:29 |\n| [Allow Sanctioned MCP](https://entra.microsoft.com/#view/Microsoft_Azure_Network_Access/EditFilteringPolicyMenuBlade.MenuView/~/Basics/policyId/d72fd352-d599-455e-b181-37accdccfbd9/title/Allow%20Sanctioned%20MCP/defaultMenuItemId/Basics) | allow | 1 | 2025-11-19 19:46 |\n| [Block DeepSeek](https://entra.microsoft.com/#view/Microsoft_Azure_Network_Access/EditFilteringPolicyMenuBlade.MenuView/~/Basics/policyId/91f1032e-6ff7-48b7-a0d3-e35b445de805/title/Block%20DeepSeek/defaultMenuItemId/Basics) | block | 1 | 2026-02-26 20:45 |\n| [Anonymous copilot block 2](https://entra.microsoft.com/#view/Microsoft_Azure_Network_Access/EditFilteringPolicyMenuBlade.MenuView/~/Basics/policyId/7bc5293a-577a-40aa-be89-cdc3659cbd6f/title/Anonymous%20copilot%20block%202/defaultMenuItemId/Basics) | block | 1 | 2026-04-27 18:18 |\n\r\n## [Security Profiles with Linked Policies](https://entra.microsoft.com/#view/Microsoft_Azure_Network_Access/FilteringPolicyProfiles.ReactView)\r\n\r\n| Profile Name | State | Priority | Filtering Policies Linked | CA Policies Assigned | Is Baseline |\r\n| :----------- | :---- | -------: | :----------------------- | -------------------: | :---------- |\r\n| [Allow AIs](https://entra.microsoft.com/#view/Microsoft_Azure_Network_Access/EditProfileMenuBlade.MenuView/~/basics/profileId/ebc6f65d-7315-4047-9954-24f2eba76608) | enabled | 100 | Allow AI | 0 | No |\n| [Allow Github](https://entra.microsoft.com/#view/Microsoft_Azure_Network_Access/EditProfileMenuBlade.MenuView/~/basics/profileId/df64716c-ee1d-4862-b438-792065711eae) | enabled | 101 | Allow Github | 0 | No |\n| [Windows ](https://entra.microsoft.com/#view/Microsoft_Azure_Network_Access/EditProfileMenuBlade.MenuView/~/basics/profileId/1b386420-7659-44f7-bada-c02239ab8196) | enabled | 102 | Windows | 0 | No |\n| [TLS Inspection Demo](https://entra.microsoft.com/#view/Microsoft_Azure_Network_Access/EditProfileMenuBlade.MenuView/~/basics/profileId/b73bf9ea-9aff-40dd-90ae-40371ebbddae) | enabled | 103 | None | 1 | No |\n| [Sales Department](https://entra.microsoft.com/#view/Microsoft_Azure_Network_Access/EditProfileMenuBlade.MenuView/~/basics/profileId/caa04776-90f6-4d14-8c4a-e665c75e0a08) | enabled | 105 | Allow Dropbox | 0 | No |\n| [ZAVA_AI-Profile](https://entra.microsoft.com/#view/Microsoft_Azure_Network_Access/EditProfileMenuBlade.MenuView/~/basics/profileId/84ae7f47-ef74-424e-a2d7-ee449f34bc2b) | enabled | 110 | Block Unsanctioned MCP by default | 0 | No |\n| [ZAVA_AI-Profile-Content](https://entra.microsoft.com/#view/Microsoft_Azure_Network_Access/EditProfileMenuBlade.MenuView/~/basics/profileId/23174a62-1011-46f3-8198-a00aff6a4223) | enabled | 111 | None | 0 | No |\n| [GSADemo](https://entra.microsoft.com/#view/Microsoft_Azure_Network_Access/EditProfileMenuBlade.MenuView/~/basics/profileId/4c1eb1da-94e7-489e-a9e8-0b5288c3b4ac) | enabled | 124 | None | 0 | No |\n| [Temporary access to Dropbox](https://entra.microsoft.com/#view/Microsoft_Azure_Network_Access/EditProfileMenuBlade.MenuView/~/basics/profileId/5e98d8a3-38d1-4219-8eec-105ff9a7669f) | enabled | 210 | Just in time access to Dropbox | 1 | No |\n| [Finance department](https://entra.microsoft.com/#view/Microsoft_Azure_Network_Access/EditProfileMenuBlade.MenuView/~/basics/profileId/3736d656-d307-4ece-82ad-b1cf0179abc6) | enabled | 300 | Allow Finance Sites, Allow ChatGPT | 0 | No |\n| [Block Risky AI App Access](https://entra.microsoft.com/#view/Microsoft_Azure_Network_Access/EditProfileMenuBlade.MenuView/~/basics/profileId/0014abeb-60c5-4f89-8f78-b764284bc4f1) | enabled | 399 | Block DeepSeek, Allow Gemini, Allow ChatGPT | 1 | No |\n| [Finance AI](https://entra.microsoft.com/#view/Microsoft_Azure_Network_Access/EditProfileMenuBlade.MenuView/~/basics/profileId/4905afb6-9b08-4f6a-8ac9-46264e9e9e00) | enabled | 400 | Allow Gemini, Allow ChatGPT | 1 | No |\n| [Marketing AI](https://entra.microsoft.com/#view/Microsoft_Azure_Network_Access/EditProfileMenuBlade.MenuView/~/basics/profileId/c64be0ca-af7b-47b5-af1c-797118d144d4) | enabled | 401 | Allow Gemini, Allow ChatGPT, Allow Jasper | 0 | No |\n| [Engineering AI](https://entra.microsoft.com/#view/Microsoft_Azure_Network_Access/EditProfileMenuBlade.MenuView/~/basics/profileId/a11dc579-649f-4a7b-bb02-86c3e5094f3e) | enabled | 402 | Allow Gemini, Allow Github | 0 | No |\n| [Security Profile for Fin dept](https://entra.microsoft.com/#view/Microsoft_Azure_Network_Access/EditProfileMenuBlade.MenuView/~/basics/profileId/f551c2ba-c726-41c4-9c03-8baa60f172b9) | enabled | 1000 | Allow Fin team | 0 | No |\n| [Baseline Profile](https://entra.microsoft.com/#view/Microsoft_Azure_Network_Access/EditProfileMenuBlade.MenuView/~/basics/profileId/2bb1e634-8de0-4fcf-b05d-b1254a0a40db) | enabled | 65000 | Allow Sanctioned MCP, Block Unsanctioned MCP by default, Windows, Allow LinkedIn, Allow AI | N/A | Yes |\n\r\n## [Conditional Access Policies Assigned to Security Profiles](https://entra.microsoft.com/#view/Microsoft_AAD_ConditionalAccess/ConditionalAccessBlade/~/Policies)\r\n\r\n| CA Policy Name | Security Profile |\r\n| :------------- | :--------------- |\r\n| [CA42 - TLS Inspection](https://entra.microsoft.com/#view/Microsoft_AAD_ConditionalAccess/PolicyBlade/policyId/bc649926-1ea9-43b8-b8da-4e74c73853b5) | TLS Inspection Demo |\n| [CA35 - Ondemand Dropbox Access](https://entra.microsoft.com/#view/Microsoft_AAD_ConditionalAccess/PolicyBlade/policyId/349bce8e-4b71-4c42-87c3-a7c7d8ea870e) | Temporary access to Dropbox |\n| [CA46 - Allow internet access to AI](https://entra.microsoft.com/#view/Microsoft_AAD_ConditionalAccess/PolicyBlade/policyId/138504ad-20fb-475f-b159-26d45d339dc3) | Block Risky AI App Access |\n| [CA34 - IA - Allow traffic to finance web sites](https://entra.microsoft.com/#view/Microsoft_AAD_ConditionalAccess/PolicyBlade/policyId/ac87d339-5f95-406b-b28b-7b9c0b99ce28) | Finance AI |\n\r\n\r\n","TestSfiPillar":"Protect networks","TestStatus":"Passed","TestImpact":"Low","TestPillar":"Network","TestId":"25410","TestRisk":"Medium","TestDescription":"Creating filtering policies without linking them to a security profile or the baseline profile leaves them unenforced. Policies must be associated with either the baseline profile (applies to all internet traffic) or a security profile (applies through Conditional Access) to take effect. Unlinked policies provide no protection and create false confidence in your security posture.\r\n\r\n**Remediation action**\r\n\r\n- [Create security profiles and link filtering policies](https://learn.microsoft.com/entra/global-secure-access/how-to-configure-web-content-filtering?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci#create-a-security-profile)\r\n","TestTags":null,"TestMinimumLicense":["Entra_Premium_Internet_Access"],"SkippedReason":null,"TestAppliesTo":null,"TestImplementationCost":"Medium","TestCategory":"Global Secure Access"},{"TestTitle":"Data loss prevention policies are enabled","TestSkipped":"NotConnectedToService","TestResult":"\r\nSkipped. This test requires connection to the service(s) \"SecurityCompliance\" currently disconnected. Please use _Connect-ZtAssessment_ to connect.\r\n\r\n","TestSfiPillar":"Protect tenants and production systems","TestStatus":"Skipped","TestImpact":"Medium","TestPillar":"AI","TestId":"35030","TestRisk":"High","TestDescription":"A DLP policy can help you identify, monitor, and automatically protect sensitive information in Enterprise applications & devices and Inline web traffic data. DLP policies act on a variety of locations, methods of data transmission, and types of user activities. By protecting sensitive information, DLP policies can help you prevent data leaks, ensure compliance with regulations, and maintain the confidentiality of your organization's data.\r\n\r\n**Remediation action**\r\n\r\n- [Create and configure DLP policies](https://learn.microsoft.com/purview/dlp-create-deploy-policy?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci)\r\n","TestTags":null,"TestMinimumLicense":["EXCHANGE_S_ENTERPRISE"],"SkippedReason":"This test requires connection to the service(s) \"SecurityCompliance\" currently disconnected. Please use _Connect-ZtAssessment_ to connect.","TestAppliesTo":null,"TestImplementationCost":"Medium","TestCategory":"Data Loss Prevention (DLP)"},{"TestId":26886,"TestCategory":"Azure Network Security","TestImpact":"Low","TestResult":"\r\nSkipped. This test is not applicable to the current environment.\r\n","SkippedReason":"This test is not applicable to the current environment.","TestMinimumLicense":["DDoS_Network_Protection","DDoS_IP_Protection"],"TestAppliesTo":null,"TestTags":null,"TestSfiPillar":"Protect networks","TestImplementationCost":"Low","TestSkipped":"NotApplicable","TestPillar":"Network","TestTitle":"Diagnostic logging is enabled for DDoS-protected public IPs","TestStatus":"Skipped","TestDescription":"When Azure DDoS Protection is enabled for public IP addresses, diagnostic logging provides critical visibility into attack patterns, mitigation actions, and traffic flow data. Without diagnostic logs enabled, security teams lack the observability needed to understand attack characteristics, validate mitigation effectiveness, and perform post-incident analysis. Azure DDoS Protection generates three categories of diagnostic logs: DDoSProtectionNotifications (alerts when attacks are detected and when mitigation starts/stops), DDoSMitigationFlowLogs (detailed flow-level information during active attack mitigation), and DDoSMitigationReports (comprehensive attack summaries with traffic statistics and mitigation actions). These logs are essential for security operations to detect ongoing attacks, investigate incidents, meet compliance requirements, and tune protection policies. The absence of logging prevents correlation of network events with other security telemetry, eliminating the ability to construct attack timelines during incident investigations. Furthermore, compliance frameworks such as PCI-DSS, HIPAA, and SOC 2 require organizations to maintain audit logs of network security events, and the lack of DDoS diagnostic logging creates audit failures.\r\n\r\n**Remediation action**\r\n\r\nConfigure diagnostic settings for DDoS-protected public IP addresses\r\n- [Configure Azure DDoS Protection diagnostic logging](https://learn.microsoft.com/en-us/azure/ddos-protection/diagnostic-logging)\r\n\r\nView and configure DDoS diagnostic logs in the Azure portal\r\n- [View and configure DDoS diagnostic logging](https://learn.microsoft.com/en-us/azure/ddos-protection/diagnostic-logging#configure-ddos-diagnostic-logs)\r\n\r\nCreate a Log Analytics workspace for storing DDoS Protection logs\r\n- [Create a Log Analytics workspace](https://learn.microsoft.com/en-us/azure/azure-monitor/logs/quick-create-workspace)\r\n\r\nMonitor and analyze DDoS attack telemetry\r\n- [Azure DDoS Protection monitoring and logging](https://learn.microsoft.com/en-us/azure/ddos-protection/ddos-protection-overview#monitoring-and-logging)\r\n\r\nView and analyze DDoS logs for incident investigation\r\n- [Tutorial: View and analyze DDoS logs](https://learn.microsoft.com/en-us/azure/ddos-protection/view-logs)\r\n\r\n","TestRisk":"Medium"},{"TestTitle":"Browser data loss prevention is enabled for AI apps via Edge for Business","TestSkipped":"NotConnectedToService","TestResult":"\r\nSkipped. This test requires connection to the service(s) \"SecurityCompliance\" currently disconnected. Please use _Connect-ZtAssessment_ to connect.\r\n\r\n","TestSfiPillar":"Protect tenants and production systems","TestStatus":"Skipped","TestImpact":"Medium","TestPillar":"AI","TestId":"35041","TestRisk":"Medium","TestDescription":"Microsoft Purview Data Loss Prevention (DLP) monitoring and protection are built right into the Microsoft Edge for Business browser. You don’t need to onboard the device into Microsoft Purview. This integration helps you stop users from sharing sensitive information to and from cloud apps using Edge for Business. With the rise of AI applications, this capability is crucial to help prevent users from sharing sensitive information with unmanaged AI apps through Edge for Business, which could lead to data leaks and compliance risks. By enabling browser DLP for AI apps via Edge for Business, you can extend your data protection policies to cover web-based interactions, ensuring that sensitive data is safeguarded even when accessed through the browser.\r\n\r\n\r\n**Remediation action**\r\n\r\n- [Help prevent sharing via Microsoft Edge for Business to unmanaged AI apps from managed devices](https://learn.microsoft.com/purview/dlp-create-policy-block-to-ai-via-edge?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci)\r\n","TestTags":null,"TestMinimumLicense":["RMS_S_PREMIUM2"],"SkippedReason":"This test requires connection to the service(s) \"SecurityCompliance\" currently disconnected. Please use _Connect-ZtAssessment_ to connect.","TestAppliesTo":null,"TestImplementationCost":"High","TestCategory":"Data Security Posture Management"},{"TestId":"25537","TestCategory":"Azure Network Security","TestImpact":"Low","TestResult":"\r\nThreat Intel is not enabled in **Alert and Deny** mode for all Firewall policies.\n\n\r\n## Firewall policies\r\n\r\n| Policy name | Subscription name | Threat Intel mode | Result |\r\n| :---------- | :---------------- | :---------------- | :----- |\r\n| [fwp-hub-eastus](https://portal.azure.com/#resource/subscriptions/3ee59f4f-e3f2-4ba5-bea7-f81409658ab8/resourceGroups/rg-hub-eastus/providers/Microsoft.Network/firewallPolicies/fwp-hub-eastus) | [Network Security](https://portal.azure.com/#resource/subscriptions/3ee59f4f-e3f2-4ba5-bea7-f81409658ab8) | Alert | ❌ |\n| [woodgrove-policy](https://portal.azure.com/#resource/subscriptions/ab48f397-fc82-4634-aa52-62dd91b3ebaa/resourceGroups/Woodgrove-RG/providers/Microsoft.Network/firewallPolicies/woodgrove-policy) | [Woodgrove - GTP Demos (External/Sponsored)](https://portal.azure.com/#resource/subscriptions/ab48f397-fc82-4634-aa52-62dd91b3ebaa) | Deny | ✅ |\n| [woodgrove1-policy](https://portal.azure.com/#resource/subscriptions/ab48f397-fc82-4634-aa52-62dd91b3ebaa/resourceGroups/Woodgrove-RG/providers/Microsoft.Network/firewallPolicies/woodgrove1-policy) | [Woodgrove - GTP Demos (External/Sponsored)](https://portal.azure.com/#resource/subscriptions/ab48f397-fc82-4634-aa52-62dd91b3ebaa) | Deny | ✅ |\n| [woodgrove2-policy](https://portal.azure.com/#resource/subscriptions/ab48f397-fc82-4634-aa52-62dd91b3ebaa/resourceGroups/Woodgrove-RG/providers/Microsoft.Network/firewallPolicies/woodgrove2-policy) | [Woodgrove - GTP Demos (External/Sponsored)](https://portal.azure.com/#resource/subscriptions/ab48f397-fc82-4634-aa52-62dd91b3ebaa) | Deny | ✅ |\n\r\n\r\n\r\n","SkippedReason":null,"TestMinimumLicense":["Azure_Firewall_Standard","Azure_Firewall_Premium"],"TestAppliesTo":null,"TestTags":null,"TestSfiPillar":"Protect networks","TestImplementationCost":"Low","TestSkipped":"","TestPillar":"Network","TestTitle":"Threat intelligence is Enabled in Deny Mode on Azure Firewall","TestStatus":"Failed","TestDescription":"Azure Firewall threat intelligence-based filtering alerts on and denies traffic to and from known malicious IP addresses, fully qualified domain names (FQDNs), and URLs sourced from the Microsoft Threat Intelligence feed. When you don't enable threat intelligence in `Alert and deny` mode, Azure Firewall doesn't actively block traffic to known malicious destinations.\r\n\r\nIf you don't enable threat intelligence in `Alert and deny` mode:\r\n\r\n- Threat actors can communicate with known malicious infrastructure, enabling data exfiltration and command-and-control communication without active blocking.\r\n- Organizations that use `Alert only` mode can see threat activity in logs but can't prevent connections to known bad destinations.\r\n- All firewall policy tiers remain exposed to threats that the Microsoft Threat Intelligence feed already identified.\r\n\r\n**Remediation action**\r\n\r\n- [Configure threat intelligence settings in Azure Firewall Manager](https://learn.microsoft.com/azure/firewall-manager/threat-intelligence-settings?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci) to set the threat intelligence mode to `Alert and deny` in the firewall policy.\r\n","TestRisk":"High"},{"TestId":"27016","TestCategory":"Azure Network Security","TestImpact":"Low","TestResult":"\r\n✅ All Application Gateway WAF policies attached to Application Gateways are enabled, running in Prevention mode, and have at least one rate limiting rule configured and enabled.\n\n\r\n## [Application Gateway WAF policies](https://portal.azure.com/#browse/Microsoft.Network%2FapplicationGatewayWebApplicationFirewallPolicies)\r\n\r\n| Policy name | Subscription name | Policy state | Mode | Rate limit rules count | Rule state | Status |\r\n| :---------- | :---------------- | :----------- | :--- | :--------------------- | :--------- | :----- |\r\n| [WAFAppGWcopilotPolicy](https://portal.azure.com/#resource/subscriptions/ab48f397-fc82-4634-aa52-62dd91b3ebaa/resourceGroups/Woodgrove-RG/providers/Microsoft.Network/applicationGatewayWebApplicationFirewallPolicies/WAFAppGWcopilotPolicy) | [Woodgrove - GTP Demos (External/Sponsored)](https://portal.azure.com/#resource/subscriptions/ab48f397-fc82-4634-aa52-62dd91b3ebaa) | ✅ Enabled | ✅ Prevention | ✅ 1 | ✅ Enabled | ✅ |\n\r\n\r\n","SkippedReason":null,"TestMinimumLicense":"Azure WAF","TestAppliesTo":null,"TestTags":null,"TestSfiPillar":"Protect networks","TestImplementationCost":"Medium","TestSkipped":"","TestPillar":"Network","TestTitle":"Rate Limiting is Enabled in Application Gateway WAF","TestStatus":"Passed","TestDescription":"Azure Application Gateway Web Application Firewall (WAF) supports rate limiting through custom rules that restrict the number of requests clients can make within a specified time window. Rate limiting is a critical defense mechanism that protects applications from abuse by throttling clients that exceed defined request thresholds. \r\n\r\nWithout rate limiting configured, threat actors can execute brute force attacks that attempt thousands of password combinations per minute against authentication endpoints, credential stuffing attacks that test stolen credentials at scale, API abuse that extracts large volumes of data or consumes expensive backend resources, and application-layer denial of service attacks that flood endpoints with requests to exhaust server capacity. \r\n\r\nRate limiting rules use the `RateLimitRule` rule type and allow administrators to define thresholds based on request count per minute, with the ability to group requests by client IP address (using `groupBy` with `ClientAddr` variable) to track and limit individual clients. When a client exceeds the configured threshold, the WAF can block subsequent requests, log the violation, or redirect to a custom page. Unlike managed rulesets that detect attack patterns, rate limiting provides a quantitative defense that limits the impact of any volumetric attack regardless of whether the individual requests appear malicious. By configuring rate limiting on Application Gateway WAF, organizations can ensure that no single client can monopolize application resources or execute high-volume automated attacks.\r\n\r\n\r\n**Remediation action**\r\n\r\n- [What is Azure Web Application Firewall on Azure Application Gateway?](https://learn.microsoft.com/en-us/azure/web-application-firewall/ag/ag-overview) - Overview of WAF capabilities on Application Gateway including custom rules\r\n- [Create and use Web Application Firewall v2 custom rules on Application Gateway](https://learn.microsoft.com/en-us/azure/web-application-firewall/ag/create-custom-waf-rules) - Step-by-step guidance on creating custom rules including rate limiting\r\n- [Web Application Firewall custom rules](https://learn.microsoft.com/en-us/azure/web-application-firewall/ag/custom-waf-rules-overview) - Detailed documentation of custom rule types including RateLimitRule\r\n- [Rate limiting in Application Gateway WAF](https://learn.microsoft.com/en-us/azure/web-application-firewall/ag/rate-limiting-overview) - Overview of rate limiting capabilities and configuration options\r\n\r\n\r\n","TestRisk":"High"},{"TestTitle":"TLS inspection is enabled and correctly configured for outbound traffic","TestSkipped":"","TestResult":"\r\n✅ TLS Inspection Policy is enabled and properly configured to inspect encrypted outbound traffic.\n\n\n## TLS Inspection Policies Linked to Baseline Profiles\n\n| Linked profile name | Linked profile priority | Linked policy name | Policy link state | Profile state |\n| :--- | :--- | :--- | :--- | :--- |\n| [Baseline Profile](https://entra.microsoft.com/#view/Microsoft_Azure_Network_Access/EditProfileMenuBlade.MenuView/~/basics/profileId/2bb1e634-8de0-4fcf-b05d-b1254a0a40db) | 65000 | [TLS Inspection Policy](https://entra.microsoft.com/#view/Microsoft_Azure_Network_Access/EditTlsInspectionPolicyMenuBlade.MenuView/~/basics/policyId/a76f418b-bb2f-4f75-ab80-ae2b3b3c1bea) | ✅ Enabled | ✅ Enabled |\n\r\n\r\n","TestSfiPillar":"Protect networks","TestStatus":"Passed","TestImpact":"Medium","TestPillar":"Network","TestId":"25411","TestRisk":"High","TestDescription":"TLS inspection decrypts and inspects HTTPS traffic, enabling visibility into encrypted sessions. Without it, many Microsoft Entra Internet Access features can't function, including URL filtering and advanced threat detection. Most internet traffic is encrypted, so TLS inspection is essential for applying security policies to most user activity.\r\n\r\n**Remediation action**\r\n\r\n- [Configure Transport Layer Security Inspection Policies](https://learn.microsoft.com/entra/global-secure-access/how-to-transport-layer-security?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci)\r\n","TestTags":null,"TestMinimumLicense":["Entra_Premium_Internet_Access"],"SkippedReason":null,"TestAppliesTo":null,"TestImplementationCost":"High","TestCategory":"Global Secure Access"},{"TestId":"26889","TestCategory":"Azure Network Security","TestImpact":"Low","TestResult":"\r\n✅ Diagnostic logging is enabled for Azure Front Door WAF with active log collection configured.\n\n\n## [Azure Front Door WAF diagnostic logging status](https://portal.azure.com/#view/HubsExtension/BrowseResource/resourceType/Microsoft.Cdn%2Fprofiles)\n\n| Subscription | Profile name | SKU | WAF policy | Diagnostic settings count | Destination configured | Enabled log categories | Status |\r\n| :--- | :--- | :--- | :--- | :--- | :--- | :--- | :--- |\r\n| [Woodgrove - GTP Demos (External/Sponsored)](https://portal.azure.com/#resource/subscriptions/ab48f397-fc82-4634-aa52-62dd91b3ebaa/overview) | [WAFAFDpremium](https://portal.azure.com/#resource/subscriptions/ab48f397-fc82-4634-aa52-62dd91b3ebaa/resourcegroups/woodgrove-rg/providers/microsoft.cdn/profiles/wafafdpremium/diagnostics) | Premium_AzureFrontDoor | AFDCopilotWAFPolicy | 1 | Yes | FrontDoorAccessLog, FrontDoorWebApplicationFirewallLog | ✅ Pass |\n\r\n**Summary:**\n\n- Total Azure Front Door profiles with WAF evaluated: 1\n- Profiles with diagnostic logging enabled: 1\n- Profiles without diagnostic logging: 0\n\r\n","SkippedReason":null,"TestMinimumLicense":["Azure_FrontDoor_Standard","Azure_FrontDoor_Premium"],"TestAppliesTo":null,"TestTags":null,"TestSfiPillar":"Monitor and detect cyberthreats","TestImplementationCost":"Low","TestSkipped":"","TestPillar":"Network","TestTitle":"Diagnostic logging is enabled in Azure Front Door WAF","TestStatus":"Passed","TestDescription":"Without diagnostic logging enabled for Azure Front Door WAF, security teams lose visibility into blocked attacks, rule matches, access patterns, and WAF events occurring at the network edge. Threat actors attempting to exploit web application vulnerabilities through SQL injection, cross-site scripting, or other OWASP Top 10 attacks would go undetected because no WAF logs are being captured or analyzed. The absence of logging prevents correlation of WAF events with other security telemetry, eliminating the ability to construct attack timelines during incident investigations. Furthermore, compliance frameworks such as PCI-DSS, HIPAA, and SOC 2 require organizations to maintain audit logs of web application security events, and the lack of WAF diagnostic logging creates audit failures. Azure Front Door WAF provides multiple log categories including Access Logs and WAF Logs, which must be routed to a destination such as Log Analytics, Storage Account, or Event Hub to enable security monitoring and forensic analysis.\r\n\r\n**Remediation action**\r\n\r\nConfigure diagnostic settings for Azure Front Door to enable WAF log collection\r\n- [Create diagnostic settings in Azure Monitor](https://learn.microsoft.com/en-us/azure/azure-monitor/essentials/create-diagnostic-settings)\r\n\r\nEnable WAF logging to capture firewall events and rule matches\r\n- [Azure Front Door WAF monitoring and logging](https://learn.microsoft.com/en-us/azure/web-application-firewall/afds/waf-front-door-monitor)\r\n\r\nCreate a Log Analytics workspace for storing and analyzing WAF logs\r\n- [Create a Log Analytics workspace](https://learn.microsoft.com/en-us/azure/azure-monitor/logs/quick-create-workspace)\r\n\r\nMonitor Azure Front Door using diagnostic logs and metrics\r\n- [Monitor metrics and logs in Azure Front Door](https://learn.microsoft.com/en-us/azure/frontdoor/front-door-diagnostics)\r\n\r\n","TestRisk":"High"},{"TestTitle":"Globally published sensitivity labels don't exceed the recommended maximum","TestSkipped":"NotConnectedToService","TestResult":"\r\nSkipped. This test requires connection to the service(s) \"SecurityCompliance\" currently disconnected. Please use _Connect-ZtAssessment_ to connect.\r\n\r\n","TestSfiPillar":"Protect tenants and production systems","TestStatus":"Skipped","TestImpact":"High","TestPillar":"AI","TestId":"35015","TestRisk":"Medium","TestDescription":"Publishing too many labels globally creates confusion and decision paralysis for users, reducing adoption and increasing misclassification. When users face more than 25 labels, they struggle to identify the appropriate classification, leading to incorrect labels or avoiding the feature entirely.\r\n\r\nMicrosoft recommends no more than 25 labels in global policies, ideally organized as five main labels with up to five sublabels each. Use scoped policies to publish specialized labels only to specific users, groups, or departments, keeping the global label set focused on common scenarios.\r\n\r\n**Remediation action**\r\n\r\n- [Sensitivity label limitations per tenant](https://learn.microsoft.com/purview/sensitivity-labels?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci#sensitivity-label-limitations-per-tenant)\r\n- [Create and publish sensitivity labels](https://learn.microsoft.com/microsoft-365/compliance/create-sensitivity-labels?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci)\r\n","TestTags":null,"TestMinimumLicense":["RMS_S_PREMIUM"],"SkippedReason":"This test requires connection to the service(s) \"SecurityCompliance\" currently disconnected. Please use _Connect-ZtAssessment_ to connect.","TestAppliesTo":null,"TestImplementationCost":"Medium","TestCategory":"sensitivity-labels"},{"TestTitle":"Sensitivity label policies are published to users","TestSkipped":"NotConnectedToService","TestResult":"\r\nSkipped. This test requires connection to the service(s) \"SecurityCompliance\" currently disconnected. Please use _Connect-ZtAssessment_ to connect.\r\n\r\n","TestSfiPillar":"Protect tenants and production systems","TestStatus":"Skipped","TestImpact":"Medium","TestPillar":"AI","TestId":"35004","TestRisk":"Low","TestDescription":"Labels must be published by using label policies before users can apply them to items, such as files, emails, and meetings. Label policies define which users receive which labels, set default labeling behavior, and other labeling requirements. Without published policies, sensitivity labels remain unavailable to users.\r\n\r\n**Remediation action**\r\n\r\n- [Create and configure sensitivity labels and their policies](https://learn.microsoft.com/purview/create-sensitivity-labels?tabs=classic-label-scheme&wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci#publish-sensitivity-labels-by-creating-a-label-policy)\r\n","TestTags":null,"TestMinimumLicense":["RMS_S_PREMIUM"],"SkippedReason":"This test requires connection to the service(s) \"SecurityCompliance\" currently disconnected. Please use _Connect-ZtAssessment_ to connect.","TestAppliesTo":null,"TestImplementationCost":"Low","TestCategory":"Sensitivity Labels"},{"TestId":"27002","TestCategory":"Global Secure Access","TestImpact":"High","TestResult":"\r\n✅ All TLS inspection certificates have more than 90 days until expiration.\n\n\r\n## [TLS Inspection Certificates](https://entra.microsoft.com/#view/Microsoft_Azure_Network_Access/TLSInspectionPolicy.ReactView)\r\n\r\n**Summary:**\r\n\r\n- Total active certificates: 1\r\n- Certificates expiring within 90 days: 0\r\n- Certificates already expired: 0\r\n\r\n**Certificate Details:**\r\n\r\n| Certificate name | Common name | Status | Expiration date | Days until expiration | Renewal required |\r\n| :--- | :--- | :--- | :--- | :--- | :--- |\r\n| WGTLSInspect | WG TLS Inspection | Enabled | 2027-07-01 | 388 | No |\n\r\n\r\n\r\n","SkippedReason":null,"TestMinimumLicense":"Entra_Premium_Internet_Access","TestAppliesTo":null,"TestTags":null,"TestSfiPillar":"Protect networks","TestImplementationCost":"Low","TestSkipped":"","TestPillar":"Network","TestTitle":"TLS inspection certificates have sufficient validity period to prevent service disruption","TestStatus":"Passed","TestDescription":"TLS inspection uses an intermediate certificate authority to dynamically create leaf certificates for decrypting and inspecting encrypted traffic. When this certificate expires, the service can't perform TLS termination. This expiration immediately disables all TLS inspection capabilities, including URL filtering, threat detection, and data loss prevention on HTTPS traffic. Threat actors know that security controls often lapse during certificate expiration and they time attacks to coincide with these gaps.\r\n\r\nIf a certificate expires:\r\n\r\n- The organization loses visibility into encrypted traffic.\r\n- Threat actors can bypass TLS inspection to deliver encrypted malware, access command-and-control communications, and exfiltrate data.\r\n\r\n**Remediation action**\r\n\r\n- Maintain a 90-day buffer before certificate expiration to provide time to complete the renewal process. Microsoft recommends that signed certificates remain valid for at least six months.\r\n- Follow the steps in [Configure Transport Layer Security inspection settings](https://learn.microsoft.com/entra/global-secure-access/how-to-transport-layer-security-settings?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci) to:\r\n - Create a new Certificate Signing Request (CSR) and upload a renewed certificate in the Microsoft Entra admin center.\r\n - Sign the CSR by using your organization's PKI infrastructure with a validity period of at least six months (Microsoft recommendation).\r\n- Use [Active Directory Certificate Services (ADCS)](https://learn.microsoft.com/entra/global-secure-access/scripts/powershell-active-directory-certificate-service?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci) or [OpenSSL](https://learn.microsoft.com/entra/global-secure-access/scripts/powershell-open-secure-sockets-layer?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci) to sign the CSR.\r\n","TestRisk":"High"},{"TestTitle":"Adaptive Protection is enabled in data loss prevention policies","TestSkipped":"NotConnectedToService","TestResult":"\r\nSkipped. This test requires connection to the service(s) \"SecurityCompliance\" currently disconnected. Please use _Connect-ZtAssessment_ to connect.\r\n\r\n","TestSfiPillar":"Protect tenants and production systems","TestStatus":"Skipped","TestImpact":"Medium","TestPillar":"AI","TestId":"35032","TestRisk":"Medium","TestDescription":"With Adaptive Protection, organizations can apply the right controls to the right users based on the risk of their behavior.\r\n\r\nAdaptive Protection in Microsoft Purview integrates Microsoft Purview Insider Risk Management machine learning with Microsoft Purview Data Loss Prevention (DLP). When insider risk identifies a user who is engaging in risky behavior, they're dynamically assigned to an inside risk level. Then Adaptive Protection can automatically create a DLP policy to help protect the organization against the risky behavior that's associated with that inside risk level. As users insider risk levels change in insider risk management, the DLP policies applied to users can adjust.\r\n\r\n**Remediation action**\r\n\r\n- [Help dynamically mitigate risks with Adaptive Protection](https://learn.microsoft.com/purview/insider-risk-management-adaptive-protection?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci)\r\n","TestTags":null,"TestMinimumLicense":["EXCHANGE_S_ENTERPRISE"],"SkippedReason":"This test requires connection to the service(s) \"SecurityCompliance\" currently disconnected. Please use _Connect-ZtAssessment_ to connect.","TestAppliesTo":null,"TestImplementationCost":"Low","TestCategory":"Data Loss Prevention (DLP)"},{"TestId":"26881","TestCategory":"Azure Network Security","TestImpact":"Low","TestResult":"\r\n✅ All Application Gateway WAF policies attached to Application Gateways are enabled, running in Prevention mode, and have a Default Ruleset (Microsoft_DefaultRuleSet or OWASP) assigned.\n\n\r\n## [Application Gateway WAF policies](https://portal.azure.com/#browse/Microsoft.Network%2FapplicationGatewayWebApplicationFirewallPolicies)\r\n\r\n| Policy name | Subscription name | Policy state | Mode | Default ruleset type | Ruleset version | Status |\r\n| :---------- | :---------------- | :----------- | :--- | :------------------- | :-------------- | :----- |\r\n| [WAFAppGWcopilotPolicy](https://portal.azure.com/#resource/subscriptions/ab48f397-fc82-4634-aa52-62dd91b3ebaa/resourceGroups/Woodgrove-RG/providers/Microsoft.Network/applicationGatewayWebApplicationFirewallPolicies/WAFAppGWcopilotPolicy) | [Woodgrove - GTP Demos (External/Sponsored)](https://portal.azure.com/#resource/subscriptions/ab48f397-fc82-4634-aa52-62dd91b3ebaa) | ✅ Enabled | ✅ Prevention | OWASP | 3.2 | ✅ |\n\r\n\r\n","SkippedReason":null,"TestMinimumLicense":"Azure WAF","TestAppliesTo":null,"TestTags":null,"TestSfiPillar":"Protect networks","TestImplementationCost":"Low","TestSkipped":"","TestPillar":"Network","TestTitle":"Default Ruleset is enabled in Application Gateway WAF","TestStatus":"Passed","TestDescription":"Azure Application Gateway Web Application Firewall (WAF) provides centralized protection for web applications through managed rulesets that contain pre-configured detection signatures for known attack patterns.\r\n\r\nThe Microsoft Default Ruleset and OWASP Core Rule Set are continuously updated managed rulesets that protect against the most common and dangerous web vulnerabilities without requiring security expertise to configure.\r\n\r\nWhen no managed ruleset is enabled, the WAF policy provides no protection against known attack patterns, effectively operating as a pass-through despite being deployed.\r\n\r\nThreat actors routinely scan for unprotected web applications and exploit well-documented vulnerabilities using automated toolkits; without managed rules, attackers can execute SQL injection to extract or modify database contents, perform cross-site scripting to hijack user sessions and steal credentials, exploit local file inclusion to read sensitive configuration files, and leverage command injection to gain shell access on backend servers.\r\n\r\nThese attack techniques have known signatures that managed rulesets detect and block, but an empty or disabled ruleset configuration means the WAF cannot recognize these patterns and will allow malicious requests to reach backend applications unimpeded.\r\n\r\n\r\n**Remediation action**\r\n\r\n- [What is Azure Web Application Firewall on Azure Application Gateway?](https://learn.microsoft.com/en-us/azure/web-application-firewall/ag/ag-overview) - Overview of WAF capabilities on Application Gateway including managed rulesets\r\n- [Web Application Firewall CRS rule groups and rules](https://learn.microsoft.com/en-us/azure/web-application-firewall/ag/application-gateway-crs-rulegroups-rules) - Detailed documentation of available rulesets and rule groups\r\n- [Create Web Application Firewall policies for Application Gateway](https://learn.microsoft.com/en-us/azure/web-application-firewall/ag/create-waf-policy-ag) - Step-by-step guidance on creating and configuring WAF policies with managed rulesets\r\n\r\n\r\n","TestRisk":"High"},{"TestTitle":"Conditional Access policies cover both agent identities and agent users","TestSkipped":"","TestResult":"\r\n❌ No enabled Conditional Access policy targets agent identities with the `block` control, OR no enabled Conditional Access policy targets agent users with the `block` control. Agent traffic for the uncovered principal type bypasses Conditional Access enforcement.\n\n\r\n\r\n### [Conditional Access policies covering agent principals](https://entra.microsoft.com/#view/Microsoft_AAD_ConditionalAccess/ConditionalAccessBlade/~/Policies)\r\n\r\n| Policy | Targeted Agent Identity types | State | Grant controls | Status |\r\n| :----- | :---------------------------- | :---- | :------------- | :----- |\r\n| [Allow only approved agents to access resources](https://entra.microsoft.com/#view/Microsoft_AAD_ConditionalAccess/PolicyBlade/policyId/8ba6907e-3f9d-4172-81a7-a13d1bd28355) | Some Agent Identities or Blueprints | 🟡 Report-only | block | ❌ Fail |\n| [AWSBedrockPolicy](https://entra.microsoft.com/#view/Microsoft_AAD_ConditionalAccess/PolicyBlade/policyId/9b4077ef-8320-40fb-87b5-42fa08c63d1d) | Some Agent Identities or Blueprints | 🟡 Report-only | block | ❌ Fail |\n| [Block Agent ID Blueprint_AgentResource](https://entra.microsoft.com/#view/Microsoft_AAD_ConditionalAccess/PolicyBlade/policyId/62c6b998-633c-411b-8e6b-1f33200aa5ae) | Some Agent Identities or Blueprints | 🟡 Report-only | block | ❌ Fail |\n| [Block AgentID BluePrint_ Allresources](https://entra.microsoft.com/#view/Microsoft_AAD_ConditionalAccess/PolicyBlade/policyId/6dfb1cd7-e656-481a-a9c6-7bff54c71193) | Some Agent Identities or Blueprints | 🟡 Report-only | block | ❌ Fail |\n| [Block all high risk agents from accessing all resources](https://entra.microsoft.com/#view/Microsoft_AAD_ConditionalAccess/PolicyBlade/policyId/5a430e91-92ef-4cea-af93-27c247c2be1f) | Some Agent Identities or Blueprints | 🟢 Enabled | block | ✅ Pass |\n\r\n","TestSfiPillar":"Protect identities and secrets","TestStatus":"Failed","TestImpact":"Low","TestPillar":"AI","TestId":"61009","TestRisk":"High","TestDescription":"When an organisation deploys AI agents, those agents acquire access tokens for organisational resources on every interaction — mail, files, line-of-business APIs, downstream agents — and they do it without an interactive user session and without the device, location, or MFA signals that classic Conditional Access uses to make trust decisions for human users. Microsoft Entra Agent ID introduces two distinct first-class identity types that initiate these token acquisitions: **agent identities** (instantiated agents, modelled as service principals, that perform agentic tasks against resources) and **agent users** (non-human user accounts that back agent experiences requiring a mailbox or Teams presence). Conditional Access treats them as separate principal types: a policy that targets agent identities does not evaluate on agent-user sign-ins, and the reverse is also true. A tenant that enables agent workloads without at least one Conditional Access policy enforcing — `block unless approved` — has no enforcement boundary on autonomous AI access at all: every token request from an agent identity or an agent user is allowed by default, exactly the failure mode adversaries exploit when they compromise a single agent or its backing user account and then pivot through the resources that account can reach. As of writing this spec, Agent Users controls do not allow exclusions. A policy that blocks all agent users represents a tenant-level baseline that disables agent users from functioning.\r\n\r\n**Remediation action**\r\n\r\n- [Conditional Access for Agent ID (Preview) — concept and configuration](https://learn.microsoft.com/entra/identity/conditional-access/agent-id)\r\n- [Identity Protection signals for agents (informs risk-based policies that complement the baseline)](https://learn.microsoft.com/entra/id-protection/concept-risky-agents)\r\n- [Filter for applications in Conditional Access (basis for custom-security-attribute-based agent and resource targeting)](https://learn.microsoft.com/entra/identity/conditional-access/concept-filter-for-applications)\r\n- [Custom security attributes in Microsoft Entra ID (referenced by attribute-based agent scoping)](https://learn.microsoft.com/entra/fundamentals/custom-security-attributes-add)\r\n\r\n","TestTags":null,"TestMinimumLicense":["AAD_PREMIUM AND AGENT_365","AAD_PREMIUM_P2 AND AGENT_365"],"SkippedReason":null,"TestAppliesTo":null,"TestImplementationCost":"Low","TestCategory":"AI Identity & Access"},{"TestTitle":"Default sensitivity labels are configured for SharePoint document libraries","TestSkipped":"NotConnectedToService","TestResult":"\r\nSkipped. This test requires connection to the service(s) \"SharePointOnline\" currently disconnected. Please use _Connect-ZtAssessment_ to connect.\r\n\r\n","TestSfiPillar":"Protect tenants and production systems","TestStatus":"Skipped","TestImpact":"Low","TestPillar":"AI","TestId":"35008","TestRisk":"Medium","TestDescription":"When you configure SharePoint with a default label for document libraries, any new files uploaded to that library, or existing files edited in the library will have that label applied if they don't already have a sensitivity label, or they have a sensitivity label but with lower priority. This location-based labeling offers a baseline level of protection and a form of automatic labeling without content inspection. When files aren't labeled, important files can bypass protection and remain vulnerable.\r\n\r\nThis configuration is most suitable for document libraries that contain files with the same level of sensitivity. It can be supplemented with auto-labeling policies that uses content inspection, and manual labeling with a higher priority sensitivity label if needed.\r\n\r\n**Remediation action**\r\n\r\n- [Configure a default sensitivity label for a SharePoint document library](https://learn.microsoft.com/purview/sensitivity-labels-sharepoint-default-label?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci)\r\n","TestTags":null,"TestMinimumLicense":["RMS_S_PREMIUM2"],"SkippedReason":"This test requires connection to the service(s) \"SharePointOnline\" currently disconnected. Please use _Connect-ZtAssessment_ to connect.","TestAppliesTo":null,"TestImplementationCost":"Low","TestCategory":"SharePoint Online"},{"TestTitle":"Application Proxy applications require pre-authentication to block anonymous access to on-premises resources","TestSkipped":"","TestResult":"\r\n❌ One or more Application Proxy applications are configured with passthrough authentication, allowing unauthenticated access to on-premises resources.\n\n\r\n\r\n## Application Proxy Pre-Authentication Configuration\r\n\r\n| Application name | Pre-Authentication type | Compliant |\r\n| :--------------- | :---------------------- | :-------- |\r\n| [Header App](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/AppProxy/objectId/7214f2e9-6d16-4704-998f-a0f9c696bea6/appId/57eeafa0-67d5-4a5a-a695-8ed3facf146c/preferredSingleSignOnMode~/null/servicePrincipalType/Application/fromNav/) | aadPreAuthentication | ✅ Yes |\n| [WG AADDS Sample App](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/AppProxy/objectId/1dd9f99a-e4ff-4c24-87bb-a17026a18389/appId/1ebdbe69-e42d-4fdf-afb0-fe765c0e49ce/preferredSingleSignOnMode~/null/servicePrincipalType/Application/fromNav/) | aadPreAuthentication | ✅ Yes |\n| [Sales Dashboard On-Prem](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/AppProxy/objectId/2f8fbb25-54c8-4528-b96c-67bac5bda7ba/appId/1361dcf7-882f-401a-8463-3473a9c608b3/preferredSingleSignOnMode~/null/servicePrincipalType/Application/fromNav/) | aadPreAuthentication | ✅ Yes |\n| [WIA Woodgrove Portal](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/AppProxy/objectId/4b356f52-2b8a-4590-b244-d0679aeee3c6/appId/b609618b-d156-4c07-a654-dfdc1bac05c5/preferredSingleSignOnMode~/null/servicePrincipalType/Application/fromNav/) | aadPreAuthentication | ✅ Yes |\n| [Splunk Enterprise](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/AppProxy/objectId/e4c1faa9-9ee5-49db-9e2a-ad820e61d63b/appId/f18cdcc1-8a40-4b3e-bb90-8504a491565c/preferredSingleSignOnMode~/null/servicePrincipalType/Application/fromNav/) | passthru | ❌ No |\n\r\n\r\n\r\n","TestSfiPillar":"Protect identities and secrets","TestStatus":"Failed","TestImpact":"Medium","TestPillar":"Network","TestId":"25401","TestRisk":"High","TestDescription":"Without Microsoft Entra preauthentication configured on Application Proxy applications, threat actors can directly reach the internal URL of published on-premises applications without first proving their identity. When you use passthrough authentication, Application Proxy forwards traffic without validating the requestor, and all authentication responsibility falls to the internal application.\r\n\r\nIf you don't configure preauthentication on Application Proxy applications:\r\n\r\n- Threat actors can access internal application endpoints without identity verification, enabling reconnaissance and exploitation of backend vulnerabilities.\r\n- Conditional Access policies can't be enforced, so you can't require multifactor authentication, evaluate sign-in risk, or apply location-based restrictions.\r\n- You can't integrate with Microsoft Defender for Cloud Apps for real-time session monitoring and control.\r\n\r\n**Remediation action**\r\n\r\n- [Configure Microsoft Entra preauthentication for Application Proxy applications](https://learn.microsoft.com/entra/identity/app-proxy/application-proxy-add-on-premises-application?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci#add-an-on-premises-app-to-microsoft-entra-id) by changing the Pre-Authentication method from **Passthrough** to **Microsoft Entra ID**.\r\n- [Use Microsoft Graph API to programmatically update Application Proxy settings](https://learn.microsoft.com/graph/application-proxy-configure-api?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci).\r\n","TestTags":null,"TestMinimumLicense":["AAD_PREMIUM","AAD_PREMIUM_P2"],"SkippedReason":null,"TestAppliesTo":null,"TestImplementationCost":"Medium","TestCategory":"Application Proxy"},{"TestTitle":"Users accessing external applications from corporate devices are blocked unless explicitly authorized by tenant restrictions policies","TestSkipped":"","TestResult":"\r\n❌ Universal Tenant Restrictions are not fully configured. Tenant restrictions v2 policy does not block all users and all applications by default. \n\n\r\n## [Universal Tenant Restrictions Configuration](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/TenantRestrictions.ReactView/isDefault~/true/name//id/)\r\n\r\n| Setting | Current Value | Expected Value | Status |\r\n| :------ | :------------ | :------------- | :----: |\r\n| Network Packet Tagging Status | enabled | enabled | ✅ |\n| Users & Groups Access Type | allowed | blocked | ❌ |\n| Users & Groups Target | AllUsers | AllUsers | ✅ |\n| Applications Access Type | allowed | blocked | ❌ |\n| Applications Target | AllApplications | AllApplications | ✅ |\r\n\r\n\r\n","TestSfiPillar":"Protect networks","TestStatus":"Failed","TestImpact":"Low","TestPillar":"Network","TestId":"25377","TestRisk":"High","TestDescription":"Without universal tenant restrictions configured, users on corporate devices and networks can authenticate to unauthorized external Microsoft Entra tenants and access cloud applications by using external identities. This vulnerability makes it possible for a threat actor to use compromised user credentials or established persistence on a corporate device to authenticate to a tenant they control. They can bypass traditional network security controls that can't inspect encrypted authentication traffic to Microsoft identity endpoints.\r\n\r\nOnce authenticated to an external tenant, a threat actor can access Microsoft Graph APIs and cloud services. This access enables data exfiltration through OneDrive, SharePoint, Teams, or any Microsoft Entra-integrated application in the external tenant. This attack path exploits the inherent trust that corporate networks and devices have with Microsoft identity services. Universal tenant restrictions address this vulnerability by injecting tenant identity headers into authentication plane traffic through Global Secure Access. Microsoft Entra ID uses these headers to enforce tenant restrictions v2 policies that block authentication attempts to unauthorized external tenants.\r\n\r\n**Remediation action**\r\n- [Set up tenant restrictions v2](https://learn.microsoft.com/entra/external-id/tenant-restrictions-v2?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci) policies to block all external tenants by default.\r\n- [Turn on universal tenant restrictions](https://learn.microsoft.com/entra/global-secure-access/how-to-universal-tenant-restrictions?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci) signaling in Global Secure Access.\r\n- [Deploy Global Secure Access client](https://learn.microsoft.com/entra/global-secure-access/concept-clients?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci) on devices.\r\n- [Enable the Microsoft traffic profile](https://learn.microsoft.com/entra/global-secure-access/how-to-manage-microsoft-profile?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci).\r\n","TestTags":null,"TestMinimumLicense":["Entra_Premium_Internet_Access"],"SkippedReason":null,"TestAppliesTo":null,"TestImplementationCost":"Medium","TestCategory":"Global Secure Access"},{"TestId":"26884","TestCategory":"Azure Network Security","TestImpact":"Low","TestResult":"\r\n✅ All Azure Front Door WAF policies attached to Azure Front Door are enabled, running in Prevention mode, and have the Bot Manager rule set (Microsoft_BotManagerRuleSet) with at least one rule enabled, providing protection against malicious bot traffic.\n\n\n## [Azure Front Door WAF bot protection status](https://portal.azure.com/#view/HubsExtension/BrowseResource/resourceType/Microsoft.Cdn%2Fprofiles)\n\n| Subscription | Profile name | SKU | WAF policy | WAF mode | Bot protection enabled | Enabled state | Rule set version | Rule set action | Domains protected | Status |\r\n| :--- | :--- | :--- | :--- | :--- | :--- | :--- | :--- | :--- | :--- | :--- |\r\n| [Woodgrove - GTP Demos (External/Sponsored)](https://portal.azure.com/#resource/subscriptions/ab48f397-fc82-4634-aa52-62dd91b3ebaa/overview) | [WAFAFDpremium](https://portal.azure.com/#resource/subscriptions/ab48f397-fc82-4634-aa52-62dd91b3ebaa/resourceGroups/Woodgrove-RG/providers/Microsoft.Cdn/profiles/WAFAFDpremium/securityPolicies) | Premium_AzureFrontDoor | [AFDCopilotWAFPolicy](https://portal.azure.com/#resource/subscriptions/ab48f397-fc82-4634-aa52-62dd91b3ebaa/resourcegroups/woodgrove-rg/providers/microsoft.network/frontdoorwebapplicationfirewallpolicies/afdcopilotwafpolicy/overview) | ✅ Prevention | Yes | ✅ Enabled | 1.1 | Per-rule defaults | 1 | ✅ Pass |\n\r\n\n### Standard SKU profiles (Skipped - bot protection not available)\n\n| Subscription | Profile name | SKU | Status |\r\n| :--- | :--- | :--- | :--- |\r\n| [Woodgrove - GTP Demos (External/Sponsored)](https://portal.azure.com/#resource/subscriptions/ab48f397-fc82-4634-aa52-62dd91b3ebaa/overview) | [WGFrontDoor-migrated](https://portal.azure.com/#resource/subscriptions/ab48f397-fc82-4634-aa52-62dd91b3ebaa/resourceGroups/Woodgrove-RG/providers/Microsoft.Cdn/profiles/WGFrontDoor-migrated/overview) | Standard_AzureFrontDoor | Skipped - Standard SKU |\n\r\n**Summary:**\n\n- Total Azure Front Door Premium profiles evaluated: 1\n- Profiles with bot protection enabled: 1\n- Profiles without bot protection: 0\n- Standard SKU profiles (skipped): 1\n\r\n","SkippedReason":null,"TestMinimumLicense":"Azure_Front_Door_Premium","TestAppliesTo":null,"TestTags":null,"TestSfiPillar":"Protect networks","TestImplementationCost":"Low","TestSkipped":"","TestPillar":"Network","TestTitle":"Bot protection rule set is enabled and assigned in Azure Front Door WAF","TestStatus":"Passed","TestDescription":"Azure Front Door is a global, scalable entry point that uses the Microsoft global edge network to deliver fast, secure, and highly scalable web applications. Web Application Firewall (WAF) integrated with Azure Front Door provides protection against common web exploits and vulnerabilities at the network edge. The Bot Manager rule set is a managed rule set available exclusively in Azure Front Door Premium SKU that provides protection against malicious bots while allowing legitimate bots such as search engine crawlers to access your applications. When bot protection is not enabled, threat actors can deploy automated attacks against web applications including credential stuffing attacks that test stolen username/password combinations at scale, web scraping that extracts sensitive data or intellectual property, inventory hoarding bots that deplete product availability, and application-layer DDoS attacks that exhaust backend resources. The Bot Manager rule set categorizes bots into good bots, bad bots, and unknown bots, allowing security teams to configure appropriate actions for each category. Bad bots can be blocked or challenged with CAPTCHA, while good bots like Googlebot and Bingbot are allowed through. Without bot protection, organizations lack visibility into bot traffic patterns and cannot distinguish between human users and automated clients, making it impossible to defend against sophisticated bot-driven attacks that bypass traditional rate limiting and IP-based controls.\r\n\r\n**Remediation action**\r\n\r\nUpgrade to Azure Front Door Premium if currently using Standard SKU to access bot protection features\r\n- [Azure Front Door tier comparison](https://learn.microsoft.com/en-us/azure/frontdoor/standard-premium/tier-comparison)\r\n\r\nCreate a WAF policy with Premium SKU if one does not exist\r\n- [Create a WAF policy for Azure Front Door using the Azure portal](https://learn.microsoft.com/en-us/azure/web-application-firewall/afds/waf-front-door-create-portal)\r\n\r\nEnable the Bot Manager rule set in the WAF policy\r\n- [Configure bot protection for Web Application Firewall](https://learn.microsoft.com/en-us/azure/web-application-firewall/afds/waf-front-door-policy-configure-bot-protection)\r\n\r\nAssociate the WAF policy with your Azure Front Door profile via security policies\r\n- [Add security policy in Azure Front Door](https://learn.microsoft.com/en-us/azure/frontdoor/how-to-configure-endpoints#add-security-policy)\r\n\r\nConfigure bot protection rules to customize actions for different bot categories\r\n- [Bot protection rule set on Azure Front Door](https://learn.microsoft.com/en-us/azure/web-application-firewall/afds/afds-overview#bot-protection-rule-set)\r\n\r\nMonitor bot traffic using Azure Front Door logs and metrics\r\n- [Monitor metrics and logs in Azure Front Door](https://learn.microsoft.com/en-us/azure/frontdoor/front-door-diagnostics)\r\n\r\n","TestRisk":"High"},{"TestId":"27000","TestCategory":"Global Secure Access","TestImpact":"Low","TestResult":"\r\n❌ One or more high-risk web content filtering categories (Criminal activity, Hacking, Illegal software) are not blocked. Configure web content filtering policies to block these Liability categories to protect against security risks and policy violations.\n\n\r\n## [Web Content Filtering – Category block status](https://entra.microsoft.com/#view/Microsoft_Azure_Network_Access/WebFilteringPolicy.ReactView)\r\n\r\n| Category | Enforced by | CA enforced | Status |\r\n| :------- | :---------- | :---------- | :----- |\r\n| Criminal activity | None | N/A | ❌ Not blocked |\n| Hacking | None | N/A | ❌ Not blocked |\n| Illegal software | None | N/A | ❌ Not blocked |\n\r\n\r\n**Summary:**\r\n- Total required categories: 3\r\n- Categories blocked: 0\r\n- Categories not blocked: 3\r\n\r\n","SkippedReason":null,"TestMinimumLicense":"Entra_Premium_Internet_Access","TestAppliesTo":null,"TestTags":null,"TestSfiPillar":"Protect networks","TestImplementationCost":"Low","TestSkipped":"","TestPillar":"Network","TestTitle":"Web content filtering blocks high-risk categories","TestStatus":"Failed","TestDescription":"When you don't block high-risk web content filtering categories like criminal activity, hacking, and illegal software, users who connect through Global Secure Access stay exposed to dangerous attack vectors and liability risks. These high-risk sites can distribute exploit code, malware-embedded software, and guidance on committing illegal acts that threat actors can use to compromise your environment.\r\n\r\nWithout this protection:\r\n\r\n- Users can access sites that provide tools, scripts, and tutorials for unauthorized access, enabling threat actors to escalate their capabilities within the network.\r\n- Pirated software and license key generators downloaded from illegal software sites frequently contain embedded malware that establishes persistence and enables lateral movement.\r\n- The organization faces both security vulnerabilities and legal liability from uncontrolled access to high-risk content categories.\r\n\r\n**Remediation action**\r\n\r\n- [Configure web content filtering](https://learn.microsoft.com/entra/global-secure-access/how-to-configure-web-content-filtering?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci) to block high-risk web content categories **Criminal activity**, **Hacking**, and **Illegal software**.\r\n- Review all available [Global Secure Access web content filtering categories](https://learn.microsoft.com/entra/global-secure-access/reference-web-content-filtering-categories?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci).\r\n- [Create security profiles](https://learn.microsoft.com/entra/global-secure-access/how-to-configure-web-content-filtering?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci#create-a-security-profile) to group filtering policies for Conditional Access enforcement.\r\n- [Enable the Internet Access traffic forwarding profile](https://learn.microsoft.com/entra/global-secure-access/how-to-manage-internet-access-profile?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci) to route traffic through Global Secure Access for web content filtering to apply.\r\n- [Link security profiles to Conditional Access](https://learn.microsoft.com/entra/global-secure-access/how-to-configure-web-content-filtering?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci#create-and-link-conditional-access-policy) to enforce web content filtering for targeted users and groups.\r\n","TestRisk":"High"},{"TestTitle":"Conditional Access policies enforce strong authentication for private apps","TestSkipped":"","TestResult":"\r\n⚠️ No Private Access applications are configured.\r\n\r\n## Portal Links\r\n\r\n- [Global Secure Access > Applications > Enterprise applications](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/EnterpriseApplicationListBladeV3/fromNav/globalSecureAccess/applicationType/GlobalSecureAccessApplication)\r\n- [Conditional Access > Policies](https://entra.microsoft.com/#view/Microsoft_AAD_ConditionalAccess/ConditionalAccessBlade/~/Overview/menuId//fromNav/Identity)\r\n- [Authentication methods > Authentication strengths](https://entra.microsoft.com/#view/Microsoft_AAD_ConditionalAccess/ConditionalAccessBlade/~/AuthStrengths)\r\n\r\n","TestSfiPillar":"Protect identities and secrets","TestStatus":"Failed","TestImpact":"Medium","TestPillar":"Network","TestId":"25396","TestRisk":"High","TestDescription":"When Conditional Access policies don't protect Private Access applications by requiring strong authentication, threat actors can use phishing attacks, credential stuffing, or password spraying to get user credentials and sign in to private applications with just a compromised password.\r\n\r\nWithout strong authentication:\r\n\r\n- Threat actors gain initial access to internal resources that should be protected by stronger controls.\r\n- If multifactor authentication is missing or phishable methods like SMS or voice are used, adversary-in-the-middle attacks can happen where threat actors intercept authentication tokens and session cookies.\r\n- Threat actors can move laterally from the initially compromised private application to other internal resources.\r\n\r\nMicrosoft recommends enforcing phishing-resistant authentication methods such as FIDO2 security keys, Windows Hello for Business, or certificate-based authentication for access to private applications, with multifactor authentication as the minimum acceptable baseline.\r\n\r\n**Remediation action**\r\n\r\n- [Configure Conditional Access policies to require phishing-resistant authentication](https://learn.microsoft.com/entra/identity/conditional-access/policy-all-users-mfa-strength?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci).\r\n","TestTags":null,"TestMinimumLicense":["Entra_Premium_Private_Access"],"SkippedReason":null,"TestAppliesTo":null,"TestImplementationCost":"Medium","TestCategory":"Global Secure Access"},{"TestTitle":"TLS inspection custom bypass rules do not duplicate system bypass destinations","TestSkipped":"","TestResult":"\r\n✅ All custom TLS inspection bypass rules target unique destinations not covered by the system bypass list.\n\n\r\n\r\n","TestSfiPillar":"Protect networks","TestStatus":"Passed","TestImpact":"Low","TestPillar":"Network","TestId":"27004","TestRisk":"Low","TestDescription":"Global Secure Access maintains a system bypass list of destinations that are automatically excluded from Transport Layer Security (TLS) inspection. These bypass destinations represent known incompatibilities such as certificate pinning, mutual TLS requirements, or other technical constraints. Custom bypass rules that duplicate destinations in the system bypass list are redundant and serve no functional purpose.\r\n\r\nRedundant rules consume policy capacity, create administrative overhead, and can cause confusion about which rules are necessary. TLS inspection supports up to 1,000 rules and 8,000 destinations per tenant. Maintaining a clean policy configuration with only necessary custom bypass rules improves manageability, simplifies security audits, and ensures that policy capacity is available for legitimate business requirements.\r\n\r\n**Remediation action**\r\n\r\n- Review and remove redundant custom TLS inspection bypass rules in the Microsoft Entra admin center. Navigate to **Global Secure Access** > **Secure** > **TLS inspection policies**.\r\n- Review [the destinations included in the system bypass list](https://learn.microsoft.com/entra/global-secure-access/faq-transport-layer-security?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci#what-destinations-are-included-in-the-system-bypass).\r\n","TestTags":null,"TestMinimumLicense":["Entra_Premium_Internet_Access"],"SkippedReason":null,"TestAppliesTo":null,"TestImplementationCost":"Low","TestCategory":"Global Secure Access"},{"TestTitle":"GSA Licenses are available in the tenant and assigned to users","TestSkipped":"","TestResult":"\r\n✅ GSA licenses are available and assigned to at least one user.\n\n\r\n## [Licenses](https://admin.microsoft.com/Adminportal/Home#/licenses)\r\n\r\n**GSA License Summary:**\r\n\r\n| SKU Name | Status | Available | Assigned |\r\n| :------- | :----- | --------: | -------: |\r\n| MICROSOFT_AGENT_365_TIER_3 | Enabled | 25 | 2 |\n| TEST_SPE_E7 | Enabled | 25 | 4 |\n| Microsoft_Entra_Suite | Enabled | 250 | 4 |\n\r\n\r\n**GSA Service Plans Detected:**\r\n\r\n| Service Plan | SKU |\r\n| :----------- | :-- |\r\n| Entra_Premium_Private_Access | MICROSOFT_AGENT_365_TIER_3 |\n| Entra_Premium_Internet_Access | MICROSOFT_AGENT_365_TIER_3 |\n| Entra_Premium_Private_Access | TEST_SPE_E7 |\n| Entra_Premium_Internet_Access | TEST_SPE_E7 |\n| Entra_Premium_Private_Access | Microsoft_Entra_Suite |\n| Entra_Premium_Internet_Access | Microsoft_Entra_Suite |\n\r\n\r\n**User Assignment Summary:**\r\n\r\n| Metric | Value |\r\n| :----- | ----: |\r\n| Users with GSA Internet Access | 8 |\n| Users with GSA Private Access | 8 |\n| Total users with any GSA license | 8 |\n\r\n\r\n**Users with GSA licenses:**\n\n| Display name | User principal name | Internet Access | Private Access |\n| :----------- | :------------------ | :-------------- | :------------- |\n| Katerina Govedarica | demouser1@contoso.com | ✅ | ✅ |\n| Daniela Hanzlova (OPS-I) | demouser2@contoso.com | ✅ | ✅ |\n| Isaac Fielder | demouser3@contoso.com | ✅ | ✅ |\n| Nabil Hafsah | demouser4@contoso.com | ✅ | ✅ |\n| Irene Kuusik | demouser5@contoso.com | ✅ | ✅ |\n| Jø Castellanos (OPS) | demouser6@contoso.com | ✅ | ✅ |\n| Triage Agent User | demouser7@contoso.com | ✅ | ✅ |\n| Thembisile Belisle (IDENTITY OPS) | demouser8@contoso.com | ✅ | ✅ |\n\r\n\r\n","TestSfiPillar":"Protect networks","TestStatus":"Passed","TestImpact":"Low","TestPillar":"Network","TestId":"25375","TestRisk":"High","TestDescription":"Global Secure Access requires specific Microsoft Entra licenses to function, including Microsoft Entra Internet Access and Microsoft Entra Private Access, both of which require Microsoft Entra ID P1 as a prerequisite. Without valid licenses provisioned in the tenant, administrators can't configure traffic forwarding profiles, security policies, or remote network connections. If you don't assign licenses to users, their traffic doesn't route through Global Secure Access, and remains unprotected by security controls.\r\n\r\nWithout this protection:\r\n\r\n- Threat actors can bypass web content filtering, threat protection, and Conditional Access policies.\r\n- Expired or suspended subscriptions can halt the Global Secure Access service, creating security gaps where previously protected traffic flows go unmonitored.\r\n\r\n**Remediation action**\r\n- Review Global Secure Access licensing requirements and purchase appropriate licenses. For more information, see [Licensing overview](https://learn.microsoft.com/entra/global-secure-access/overview-what-is-global-secure-access?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci#licensing-overview).\r\n- Assign licenses to users through the Microsoft Entra admin center. For more information, see [Assign licenses to users](https://learn.microsoft.com/entra/fundamentals/license-users-groups?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci).\r\n- Use group-based licensing for easier management at scale. For more information, see [Group-based licensing](https://learn.microsoft.com/entra/fundamentals/concept-group-based-licensing?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci).\r\n- Monitor license utilization through Microsoft 365 admin center. For more information, see [Microsoft 365 admin center](https://admin.microsoft.com/Adminportal/Home#/licenses).\r\n- Review Microsoft Entra Suite as an alternative that includes both Internet Access and Private Access. For more information, see [What's new in Microsoft Entra](https://learn.microsoft.com/entra/fundamentals/whats-new?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci#microsoft-entra-suite).\r\n","TestTags":null,"TestMinimumLicense":["Entra_Premium_Internet_Access","Entra_Premium_Private_Access"],"SkippedReason":null,"TestAppliesTo":null,"TestImplementationCost":"Low","TestCategory":"Global Secure Access"},{"TestTitle":"Global Secure Access client is deployed on all managed endpoints","TestSkipped":"","TestResult":"\r\n❌ Global Secure Access client deployment is insufficient or cannot be verified. Either deployment coverage is below 70%, no devices are detected, or services may not be in scope for this environment.\n\n\r\n## [Deployment Summary](https://entra.microsoft.com/#view/Microsoft_Azure_Network_Access/AdminDashboard.ReactView)\r\n\r\n| Metric | Value |\r\n| :----- | ----: |\r\n| Total GSA devices | 2 |\n| Active devices | 1 |\n| Inactive devices | 1 |\n| Total managed device count | 75 |\n| Deployment percentage | 2.7% |\n| Gap | 73 |\n| Evaluation period | 2026-06-01 to 2026-06-08 |\n\r\n\r\n\r\n","TestSfiPillar":"Protect networks","TestStatus":"Failed","TestImpact":"Low","TestPillar":"Network","TestId":"25372","TestRisk":"High","TestDescription":"Comprehensive deployment of the Global Secure Access client is foundational to achieving Zero Trust network security. If you don't deploy the Global Secure Access client to managed endpoints, those devices operate outside the organization's Security Service Edge controls. Threat actors can exploit unprotected endpoints to establish initial access, move laterally, or exfiltrate data without triggering network-level security policies.\r\n\r\nWithout the Global Secure Access client:\r\n\r\n- Devices can't benefit from compliant network checks in Conditional Access policies, source IP restoration, or tenant restrictions.\r\n- Credential theft and token replay attacks are more difficult to detect when traffic bypasses the security perimeter.\r\n- Managed endpoints can't access private applications through Microsoft Entra Private Access.\r\n\r\n**Remediation action**\r\n- Install the Global Secure Access client:\r\n - [Windows client](https://learn.microsoft.com/entra/global-secure-access/how-to-install-windows-client?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci)\r\n - [macOS client](https://learn.microsoft.com/entra/global-secure-access/how-to-install-macos-client?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci)\r\n - [iOS client](https://learn.microsoft.com/entra/global-secure-access/how-to-install-ios-client?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci)\r\n - [Android client](https://learn.microsoft.com/entra/global-secure-access/how-to-install-android-client?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci)\r\n- Monitor the Global Secure Access client health and connection status by using the [Global Secure Access dashboard](https://learn.microsoft.com/entra/global-secure-access/concept-traffic-dashboard?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci).\r\n","TestTags":null,"TestMinimumLicense":["Entra_Premium_Private_Access","Entra_Premium_Internet_Access"],"SkippedReason":null,"TestAppliesTo":null,"TestImplementationCost":"Medium","TestCategory":"Global Secure Access"},{"TestTitle":"Communication compliance monitoring is configured for Microsoft Copilot","TestSkipped":"NotConnectedToService","TestResult":"\r\nSkipped. This test requires connection to the service(s) \"SecurityCompliance\" currently disconnected. Please use _Connect-ZtAssessment_ to connect.\r\n\r\n","TestSfiPillar":"Protect tenants and production systems","TestStatus":"Skipped","TestImpact":"Medium","TestPillar":"AI","TestId":"35039","TestRisk":"High","TestDescription":"Until organizations configure Communication Compliance policies to capture Copilot interactions, they can’t see when users expose sensitive data to AI services. They also can’t tell how people use Copilot with confidential information or spot possible policy violations. As a result, users may unknowingly share customer records, financial data, source code, or trade secrets with AI services.\r\n\r\nCommunication Compliance policies that focus on Copilot interactions give organizations clear oversight of AI use while respecting privacy controls. These policies show how users work with sensitive data in AI features and help ensure teams follow data governance and compliance requirements.\r\n\r\n**Remediation action**\r\n\r\n- [Create and manage Communication Compliance policies](https://learn.microsoft.com/purview/communication-compliance-policies?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci)\r\n","TestTags":null,"TestMinimumLicense":["EXCHANGE_S_ENTERPRISE"],"SkippedReason":"This test requires connection to the service(s) \"SecurityCompliance\" currently disconnected. Please use _Connect-ZtAssessment_ to connect.","TestAppliesTo":null,"TestImplementationCost":"Medium","TestCategory":"Data Security Posture Management"},{"TestTitle":"AI administrative roles have assigned principals","TestSkipped":"","TestResult":"\r\n❌ One or more AI administrative roles in Microsoft Entra have no assigned principal (or only empty role-assignable groups).\n\n\n**AI administrative role evaluation summary:**\n\n* In-scope roles: 17\n* Evaluated (role definition present in tenant): 17\n* Not evaluated (role definition missing in this cloud/SKU): 0\n* Pass: 14\n* Investigate: 0\n* Fail: 3\n\r\n## AI administrative roles with no tenant-scoped assigned principal\r\n\r\n| Role | Tenant-scoped principals | Restricted-scope principals | Tier | Outcome |\r\n| :--- | :----------------------- | :-------------------------- | :--- | :------ |\r\n| [Agent ID Developer](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/RoleMenuBlade/~/AllAssignments/objectId/adb2368d-a9be-41b5-8667-d96778e081b0/roleName/Agent%20ID%20Developer/roleTemplateId/adb2368d-a9be-41b5-8667-d96778e081b0/adminUnitObjectId//customRole~/false/resourceScope/%2F) | 0 | 0 | Admin | ❌ Fail |\n| [Agent Registry Administrator](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/RoleMenuBlade/~/AllAssignments/objectId/6b942400-691f-4bf0-9d12-d8a254a2baf5/roleName/Agent%20Registry%20Administrator/roleTemplateId/6b942400-691f-4bf0-9d12-d8a254a2baf5/adminUnitObjectId//customRole~/false/resourceScope/%2F) | 0 | 0 | Admin | ❌ Fail |\n| [SharePoint Administrator](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/RoleMenuBlade/~/AllAssignments/objectId/f28a1f50-f6e7-4571-818b-6a12f2af6b6c/roleName/SharePoint%20Administrator/roleTemplateId/f28a1f50-f6e7-4571-818b-6a12f2af6b6c/adminUnitObjectId//customRole~/false/resourceScope/%2F) | 0 | 0 | Admin | ❌ Fail |\n\r\n\n\r\n","TestSfiPillar":"Protect identities and secrets","TestStatus":"Failed","TestImpact":"Low","TestPillar":"AI","TestId":"61006","TestRisk":"High","TestDescription":"The AI control plane in Microsoft Entra ID, Microsoft Purview, Microsoft Defender, Microsoft Intune, Microsoft Power Platform, Microsoft SharePoint, and Microsoft Global Secure Access — the administrative scopes that manage agent identities, Microsoft 365 Copilot admin settings, Conditional Access for AI, Copilot Studio environments, AI grounding sources, AI posture signals, and AI detection and response — must have named principals assigned to each role. When any of these roles has no assigned principals, no human operator is accountable for that slice of the AI surface: agent identities go un-reviewed, Copilot admin settings drift, AI-specific detections have no owner to tune, AI-network policies go un-adjusted, and AI-related escalations have no designated responder. Threat actors exploit this by targeting the AI control plane directly, relying on the gap between \"the role exists in the directory\" and \"someone is actually watching it\" — a gap that is invisible from a standard role-exposure audit but immediately consequential when an AI-related incident requires action. Confirming that every AI admin role has at least one assigned principal is the minimum organizational posture for AI administration: it does not prescribe who the principal is, how many there are, or how the assignment is made, but it guarantees that every AI admin scope has at least one accountable party.\r\n\r\n**Scope of this check.** This check evaluates **Microsoft Entra directory role** assignments only. AI administration can also be granted through portal-native role systems that are *not* Entra directory roles — for example Microsoft Purview role groups, Microsoft Defender XDR custom roles, Power Platform environment-scoped roles and Dataverse security roles, SharePoint site-level permissions, and Copilot Studio maker permissions. A role appearing as \"unassigned\" here means no Entra principal is assigned to the corresponding Entra role; a workload-native administrator may still exist outside Entra and is out of scope for this assessment.\r\n\r\n**Remediation action**\r\n\r\n- [Assign an Entra ID role via the admin center](https://learn.microsoft.com/entra/identity/role-based-access-control/manage-roles-portal)\r\n- [Create a PIM-eligible assignment for an Entra ID role](https://learn.microsoft.com/entra/id-governance/privileged-identity-management/pim-how-to-add-role-to-user)\r\n- [Assign Microsoft Purview roles and role groups](https://learn.microsoft.com/purview/purview-permissions)\r\n\r\n","TestTags":null,"TestMinimumLicense":["AAD_BASIC","AAD_PREMIUM"],"SkippedReason":null,"TestAppliesTo":null,"TestImplementationCost":"Low","TestCategory":"AI Authentication & Access"},{"TestTitle":"Microsoft Purview Information Protection data connector is enabled on the Microsoft Sentinel workspace","TestSkipped":"","TestResult":"\r\n✅ The Microsoft Purview Information Protection data connector is enabled on at least one Sentinel-onboarded workspace.\n\n\r\n\r\n## [Sentinel data connectors per workspace](https://portal.azure.com/#view/HubsExtension/BrowseResource/resourceType/microsoft.securityinsightsarg%2Fsentinel)\r\n\r\n| Subscription | Workspace | Content package | Status |\r\n| :----------- | :-------- | :-------------- | :----- |\r\n| [Woodgrove - GTP Demos (External/Sponsored)](https://portal.azure.com/#resource/subscriptions/ab48f397-fc82-4634-aa52-62dd91b3ebaa) | [desired-state-monitor](https://portal.azure.com/#view/Microsoft_Azure_Security_Insights/MainMenuBlade/~/DataConnectors/id/%2Fsubscriptions%2Fab48f397-fc82-4634-aa52-62dd91b3ebaa%2Fresourcegroups%2Fztenv01desiredstate%2Fproviders%2Fmicrosoft.securityinsightsarg%2Fsentinel%2Fdesired-state-monitor) | Not found | ❌ Fail |\n| [Woodgrove - GTP Demos (External/Sponsored)](https://portal.azure.com/#resource/subscriptions/ab48f397-fc82-4634-aa52-62dd91b3ebaa) | [SentinelGraphNOE](https://portal.azure.com/#view/Microsoft_Azure_Security_Insights/MainMenuBlade/~/DataConnectors/id/%2Fsubscriptions%2Fab48f397-fc82-4634-aa52-62dd91b3ebaa%2Fresourcegroups%2Fwoodgrove-rg%2Fproviders%2Fmicrosoft.securityinsightsarg%2Fsentinel%2FSentinelGraphNOE) | Not found | ❌ Fail |\n| [Woodgrove - GTP Demos (External/Sponsored)](https://portal.azure.com/#resource/subscriptions/ab48f397-fc82-4634-aa52-62dd91b3ebaa) | [SentinelGraphWU2](https://portal.azure.com/#view/Microsoft_Azure_Security_Insights/MainMenuBlade/~/DataConnectors/id/%2Fsubscriptions%2Fab48f397-fc82-4634-aa52-62dd91b3ebaa%2Fresourcegroups%2Fwoodgrove-rg%2Fproviders%2Fmicrosoft.securityinsightsarg%2Fsentinel%2FSentinelGraphWU2) | Not found | ❌ Fail |\n| [Woodgrove - GTP Demos (External/Sponsored)](https://portal.azure.com/#resource/subscriptions/ab48f397-fc82-4634-aa52-62dd91b3ebaa) | [SentinelGraphEUAP](https://portal.azure.com/#view/Microsoft_Azure_Security_Insights/MainMenuBlade/~/DataConnectors/id/%2Fsubscriptions%2Fab48f397-fc82-4634-aa52-62dd91b3ebaa%2Fresourcegroups%2Fwoodgrove-msg-rg%2Fproviders%2Fmicrosoft.securityinsightsarg%2Fsentinel%2FSentinelGraphEUAP) | Microsoft Purview Information Protection | ✅ Pass |\n| [Woodgrove - GTP Demos (External/Sponsored)](https://portal.azure.com/#resource/subscriptions/ab48f397-fc82-4634-aa52-62dd91b3ebaa) | [Woodgrove-LogAnalyiticsWorkspace](https://portal.azure.com/#view/Microsoft_Azure_Security_Insights/MainMenuBlade/~/DataConnectors/id/%2Fsubscriptions%2Fab48f397-fc82-4634-aa52-62dd91b3ebaa%2Fresourcegroups%2Fwoodgrove-rg%2Fproviders%2Fmicrosoft.securityinsightsarg%2Fsentinel%2FWoodgrove-LogAnalyiticsWorkspace) | Microsoft Purview Information Protection | ✅ Pass |\n\r\n","TestSfiPillar":"Monitor and detect cyberthreats","TestStatus":"Passed","TestImpact":"Low","TestPillar":"AI","TestId":"61018","TestRisk":"Medium","TestDescription":"The Purview Information Protection connector brings sensitivity label events from the Microsoft 365 audit log into Microsoft Sentinel. For AI workloads, this makes it possible to determine whether classified content was involved in a Copilot or agent interaction by correlating label events with session activity. Without this connector, that correlation cannot run.\r\n\r\nWhen the Purview Information Protection connector is not enabled, Sentinel has no record of sensitivity label events and cannot determine whether classified content was involved in a Copilot or agent interaction. Threat actors who direct Copilot toward highly classified documents through a compromised account can exploit this gap because the sensitivity dimension of the session is invisible to the SIEM — only the undifferentiated Copilot activity event reaches Sentinel. Without this connector, the organization cannot distinguish a session that processed public content from one that accessed Highly Confidential material, preventing any triage based on data classification.\r\n\r\n**Remediation action**\r\n\r\n- [Connect Microsoft Purview Information Protection to Microsoft Sentinel](https://learn.microsoft.com/azure/sentinel/connect-microsoft-purview)\r\n- [Sensitivity labels overview](https://learn.microsoft.com/purview/sensitivity-labels)\r\n\r\n","TestTags":null,"TestMinimumLicense":["MIP_S_CLP1"],"SkippedReason":null,"TestAppliesTo":null,"TestImplementationCost":"Low","TestCategory":"AI Threat Detection"},{"TestTitle":"Sensitivity labels are configured","TestSkipped":"NotConnectedToService","TestResult":"\r\nSkipped. This test requires connection to the service(s) \"SecurityCompliance\" currently disconnected. Please use _Connect-ZtAssessment_ to connect.\r\n\r\n","TestSfiPillar":"Protect tenants and production systems","TestStatus":"Skipped","TestImpact":"Low","TestPillar":"AI","TestId":"35003","TestRisk":"High","TestDescription":"Sensitivity labels are the foundation of Microsoft Purview Information Protection. They enable organizations to classify and protect sensitive data across Microsoft 365, on-premises locations, and non-Microsoft applications.\r\n\r\nWithout sensitivity labels, organizations lack a standardized way to protect their data, leaving it vulnerable to unauthorized access and sharing. A well-designed label taxonomy typically includes 3-7 top-level labels—too many labels overwhelm users and reduce effectiveness.\r\n\r\n**Remediation action**\r\n\r\n- [Get started with sensitivity labels](https://learn.microsoft.com/purview/get-started-with-sensitivity-labels?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci)\r\n- [Create and configure sensitivity labels and their policies](https://learn.microsoft.com/purview/create-sensitivity-labels?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci)\r\n","TestTags":null,"TestMinimumLicense":["RMS_S_PREMIUM"],"SkippedReason":"This test requires connection to the service(s) \"SecurityCompliance\" currently disconnected. Please use _Connect-ZtAssessment_ to connect.","TestAppliesTo":null,"TestImplementationCost":"Medium","TestCategory":"sensitivity-labels"},{"TestTitle":"Conditional Access policies use compliant network controls","TestSkipped":"","TestResult":"\r\n❌ **Fail**: Compliant network controls are not properly configured. No Conditional Access policies reference the compliant network location.\n\n\r\n### [Global Secure Access Signaling Status](https://entra.microsoft.com/#view/Microsoft_Azure_Network_Access/Security.ReactView)\r\n\r\n| Setting | Value |\r\n| :------ | :---- |\r\n| Signaling status | ✅ Enabled |\r\n### [Compliant Network Named Location](https://entra.microsoft.com/#view/Microsoft_AAD_ConditionalAccess/ConditionalAccessBlade/~/NamedLocations)\r\n\r\n| Property | Value |\r\n| :------- | :---- |\r\n| Display name | All Compliant Network locations |\r\n| Network type | allTenantCompliantNetworks |\r\n| Is trusted | ❌ False |\r\n| Location ID | 3d46dbda-8382-466a-856d-eb00cbc6b910 |\r\n### [Conditional Access Policies Using Compliant Network](https://entra.microsoft.com/#view/Microsoft_AAD_ConditionalAccess/ConditionalAccessBlade/~/Policies)\r\n\r\n❌ No enabled Conditional Access policies reference the compliant network location.\r\n\r\n**Summary:**\r\n\r\n- Global Secure Access signaling enabled: True\r\n- Compliant network location exists: True\r\n- Policies using standard pattern (block all except compliant): 0\r\n- Policies using alternative patterns: 0\r\n\r\n","TestSfiPillar":"Protect networks","TestStatus":"Failed","TestImpact":"Medium","TestPillar":"Network","TestId":"25379","TestRisk":"Medium","TestDescription":"Without compliant network controls in Conditional Access policies, organizations can't enforce that users connect to corporate resources through the Global Secure Access service. This limitation leaves authentication traffic vulnerable to interception and replay attacks from arbitrary network locations. \r\n\r\nA threat actor who obtains valid user credentials through phishing or credential theft can authenticate from any internet location, bypassing Global Secure Access network controls. Once authenticated, the threat actor can access Microsoft Entra ID-integrated applications and services, exfiltrate data, or establish persistence by creating additional credentials or modifying user permissions. \r\n\r\nThe compliant network check reduces this risk by requiring that authentication traffic originates from the Global Secure Access service, which tags authentication requests with tenant-specific network identity signals. This requirement enables Microsoft Entra ID Conditional Access to verify that users connect through the organization's secured network path before granting access.\r\n\r\n**Remediation action**\r\n- Enable Global Secure Access signaling for Conditional Access. For more information, see [Enable compliant network check with Conditional Access](https://learn.microsoft.com/entra/global-secure-access/how-to-compliant-network?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci#enable-global-secure-access-signaling-for-conditional-access).\r\n- Create a Conditional Access policy that requires compliant network for access. For more information, see [Protect your resources behind the compliant network](https://learn.microsoft.com/entra/global-secure-access/how-to-compliant-network?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci#protect-your-resources-behind-the-compliant-network).\r\n- Deploy Global Secure Access clients on devices. For more information, see [Global Secure Access clients overview](https://learn.microsoft.com/entra/global-secure-access/concept-clients?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci).\r\n- Understand compliant network enforcement. For more information, see [Compliant network check enforcement](https://learn.microsoft.com/entra/global-secure-access/how-to-compliant-network?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci#compliant-network-check-enforcement).\r\n","TestTags":null,"TestMinimumLicense":["AAD_PREMIUM","AAD_PREMIUM_P2"],"SkippedReason":null,"TestAppliesTo":null,"TestImplementationCost":"Medium","TestCategory":"Global Secure Access"},{"TestId":"25466","TestCategory":"Private Access","TestImpact":"Medium","TestResult":"\r\n❌ One or more Private Access connector groups have fewer than two active connectors, exposing private application access to a single point of failure.\n\n\r\n#### [Private Access Connector Groups](https://entra.microsoft.com/#view/Microsoft_Entra_GSA_Connect/Connectors.ReactView)\r\n\r\n| Connector group name | Region | Active connectors | Total connectors | Status |\r\n| :------------------- | :----- | ----------------: | ---------------: | :----- |\r\n| AADDSConnector | nam | 0 | 0 | ❌ Fail |\n| Asia | asia | 0 | 0 | ❌ Fail |\n| Contoso Connector | eur | 0 | 1 | ❌ Fail |\n| Default | nam | 1 | 1 | ❌ Fail |\n| NOAM - App Proxy Group | nam | 0 | 1 | ❌ Fail |\n| woodgrove.ms GSA | nam | 0 | 0 | ❌ Fail |\n| contoso | nam | 0 | 0 | ❌ Fail |\n\n\n#### Connector Details for Failing Groups\n\n**Connector Group: AADDSConnector** (Region: nam)\n\n_No connectors found in this group._\n\n**Connector Group: Asia** (Region: asia)\n\n_No connectors found in this group._\n\n**Connector Group: Contoso Connector** (Region: eur)\n\n| Group Name | Machine Name | External IP | Connector Status | Version |\n| :--------- | :----------- | :---------- | :--------------- | :------ |\n| Contoso Connector | Woodgrove-GSA01 | 203.0.113.10 | ❌ Inactive | 1.5.3925.0 |\n\n**Connector Group: Default** (Region: nam)\n\n| Group Name | Machine Name | External IP | Connector Status | Version |\n| :--------- | :----------- | :---------- | :--------------- | :------ |\n| Default | ForrestorDemo | 203.0.113.11 | ✅ Active | 1.5.3925.0 |\n\n**Connector Group: NOAM - App Proxy Group** (Region: nam)\n\n| Group Name | Machine Name | External IP | Connector Status | Version |\n| :--------- | :----------- | :---------- | :--------------- | :------ |\n| NOAM - App Proxy Group | AppProxy02.Woodgrove.net | 203.0.113.12 | ❌ Inactive | 1.5.4522.0 |\n\n**Connector Group: woodgrove.ms GSA** (Region: nam)\n\n_No connectors found in this group._\n\n**Connector Group: contoso** (Region: nam)\n\n_No connectors found in this group._\n\n\r\n\r\n","SkippedReason":null,"TestMinimumLicense":"Entra_Premium_Private_Access","TestAppliesTo":null,"TestTags":null,"TestSfiPillar":"Protect networks","TestImplementationCost":"Low","TestSkipped":"","TestPillar":"Network","TestTitle":"At least two Private Access connectors are active and healthy per connector group","TestStatus":"Failed","TestDescription":"Microsoft Entra Private Access uses private network connectors to broker connections from on-premises or cloud-hosted networks to the Global Secure Access service. Each connector group serves as the only access path for the private applications assigned to it. If you deploy only one connector in a group, any failure of that host immediately removes all private application access for users who rely on that group.\r\n\r\nWithout this protection:\r\n\r\n- A single connector failure causes a complete loss of private resource access for all users who rely on that connector group until you manually restore the connector.\r\n- A threat actor who terminates the connector Windows service or blocks its outbound Transport Layer Security (TLS) communication can silently deny access to private applications without triggering identity-layer alerts.\r\n- Automatic updates that target one connector at a time might cause downtime when only one connector exists in a group.\r\n- You can't apply Conditional Access policies when the connector is unreachable, and users are denied access rather than routed through an alternative enforcement point.\r\n\r\n**Remediation action**\r\n\r\n- [Install and register an additional private network connector](https://learn.microsoft.com/entra/global-secure-access/how-to-configure-connectors?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci) on a Windows Server in the affected region.\r\n- [Learn about connector group high-availability requirements](https://learn.microsoft.com/entra/global-secure-access/concept-connectors?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci#connector-groups) and best practices.\r\n- [Review sizing and resiliency guidance](https://learn.microsoft.com/entra/global-secure-access/concept-connectors?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci#specifications-and-sizing-requirements) for Microsoft Entra private network connectors, including the minimum two-connector recommendation.\r\n- [Review high-availability load-balancing best practices](https://learn.microsoft.com/entra/identity/app-proxy/application-proxy-high-availability-load-balancing?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci#best-practices-for-high-availability-of-connectors) applicable to Private Access connector groups.\r\n- [Troubleshoot inactive or malfunctioning private network connectors](https://learn.microsoft.com/entra/global-secure-access/troubleshoot-connectors?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci).\r\n","TestRisk":"High"},{"TestId":"25539","TestCategory":"Azure Network Security","TestImpact":"Low","TestResult":"\r\nIntrusion Detection System (IDPS) inspection is set to Deny for Azure Firewall policies.\n\n\r\n## Firewall policies\r\n\r\n| Policy name | Subscription name | Result |\r\n| :--- | :--- | :--- |\r\n| [woodgrove-policy](https://portal.azure.com/#resource/subscriptions/ab48f397-fc82-4634-aa52-62dd91b3ebaa/resourcegroups/Woodgrove-RG/providers/Microsoft.Network/firewallPolicies/woodgrove-policy) | [Woodgrove - GTP Demos (External/Sponsored)](https://portal.azure.com/#resource/subscriptions/ab48f397-fc82-4634-aa52-62dd91b3ebaa) | ✅ Alert and Deny |\n| [woodgrove1-policy](https://portal.azure.com/#resource/subscriptions/ab48f397-fc82-4634-aa52-62dd91b3ebaa/resourcegroups/Woodgrove-RG/providers/Microsoft.Network/firewallPolicies/woodgrove1-policy) | [Woodgrove - GTP Demos (External/Sponsored)](https://portal.azure.com/#resource/subscriptions/ab48f397-fc82-4634-aa52-62dd91b3ebaa) | ✅ Alert and Deny |\n| [woodgrove2-policy](https://portal.azure.com/#resource/subscriptions/ab48f397-fc82-4634-aa52-62dd91b3ebaa/resourcegroups/Woodgrove-RG/providers/Microsoft.Network/firewallPolicies/woodgrove2-policy) | [Woodgrove - GTP Demos (External/Sponsored)](https://portal.azure.com/#resource/subscriptions/ab48f397-fc82-4634-aa52-62dd91b3ebaa) | ✅ Alert and Deny |\n\r\n\r\n\r\n","SkippedReason":null,"TestMinimumLicense":"Azure_Firewall_Premium","TestAppliesTo":null,"TestTags":null,"TestSfiPillar":"Protect networks","TestImplementationCost":"Low","TestSkipped":"","TestPillar":"Network","TestTitle":"IDPS Inspection is Enabled in Deny Mode on Azure Firewall","TestStatus":"Passed","TestDescription":"Azure Firewall Premium provides signature-based intrusion detection and prevention (IDPS) that identifies attacks by detecting specific patterns in network traffic, such as byte sequences and known malicious instruction sequences used by malware. IDPS applies to inbound, east-west (spoke-to-spoke), and outbound traffic across Layers 3-7. When IDPS isn't configured in `Alert and deny` mode, Azure Firewall only logs detected threats without blocking them.\r\n\r\nWithout IDPS enabled in `Alert and deny` mode:\r\n\r\n- Threat actors can send traffic that matches known attack signatures without being blocked.\r\n- Organizations running IDPS in `Alert only` mode gain visibility into threats but can't prevent intrusion attempts from reaching their workloads.\r\n- Lateral movement and exfiltration traffic that matches known attack signatures passes through the firewall without active intervention.\r\n\r\n**Remediation action**\r\n\r\n- [Enable IDPS in Alert and Deny mode in Azure Firewall Premium](https://learn.microsoft.com/azure/firewall/premium-features?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci) by configuring the intrusion detection mode to `Alert and deny` in the firewall policy.\r\n","TestRisk":"High"},{"TestTitle":"Web content filtering with website categories is configured","TestSkipped":"","TestResult":"\r\n✅ Web content filtering with web category controls is configured and applied through either the Baseline Profile or a security profile linked to an active Conditional Access policy. \n\n\n## Filtering Policies with Web Category Rules\n\n| Profile type | Profile name | Policy name | Rule name | Web categories | State |\n| :--- | :--- | :--- | :--- | :--- | :--- |\n| Security Profile | [Allow AIs](https://entra.microsoft.com/#view/Microsoft_Azure_Network_Access/EditProfileMenuBlade.MenuView/~/basics/profileId/ebc6f65d-7315-4047-9954-24f2eba76608) | [Allow AI](https://entra.microsoft.com/#view/Microsoft_Azure_Network_Access/EditFilteringPolicyMenuBlade.MenuView/~/Basics/policyId/f81b4954-4d00-4e49-ae08-1f6c4036c4db/title/Allow%20AI/defaultMenuItemId/Basics) | Allow AI | Artificial Intelligence | ✅ Enabled |\n| Baseline Profile | [Baseline Profile](https://entra.microsoft.com/#view/Microsoft_Azure_Network_Access/EditProfileMenuBlade.MenuView/~/basics/profileId/2bb1e634-8de0-4fcf-b05d-b1254a0a40db) | [Allow AI](https://entra.microsoft.com/#view/Microsoft_Azure_Network_Access/EditFilteringPolicyMenuBlade.MenuView/~/Basics/policyId/f81b4954-4d00-4e49-ae08-1f6c4036c4db/title/Allow%20AI/defaultMenuItemId/Basics) | Allow AI | Artificial Intelligence | ✅ Enabled |\n| Security Profile | [Security Profile for Fin dept](https://entra.microsoft.com/#view/Microsoft_Azure_Network_Access/EditProfileMenuBlade.MenuView/~/basics/profileId/f551c2ba-c726-41c4-9c03-8baa60f172b9) | [Allow Fin team](https://entra.microsoft.com/#view/Microsoft_Azure_Network_Access/EditFilteringPolicyMenuBlade.MenuView/~/Basics/policyId/a8890d74-a95e-4ce8-9892-e8058256f5be/title/Allow%20Fin%20team/defaultMenuItemId/Basics) | Allow Fin team | Finance | ✅ Enabled |\n| Security Profile | [Finance department](https://entra.microsoft.com/#view/Microsoft_Azure_Network_Access/EditProfileMenuBlade.MenuView/~/basics/profileId/3736d656-d307-4ece-82ad-b1cf0179abc6) | [Allow Finance Sites](https://entra.microsoft.com/#view/Microsoft_Azure_Network_Access/EditFilteringPolicyMenuBlade.MenuView/~/Basics/policyId/f802e0a5-791c-4ec7-8e8b-ce040b69f11e/title/Allow%20Finance%20Sites/defaultMenuItemId/Basics) | Finance sites | Finance | ✅ Enabled |\n| Security Profile | [Windows ](https://entra.microsoft.com/#view/Microsoft_Azure_Network_Access/EditProfileMenuBlade.MenuView/~/basics/profileId/1b386420-7659-44f7-bada-c02239ab8196) | [Windows](https://entra.microsoft.com/#view/Microsoft_Azure_Network_Access/EditFilteringPolicyMenuBlade.MenuView/~/Basics/policyId/83050ddf-4e6f-48d0-ad06-8c17ad051844/title/Windows/defaultMenuItemId/Basics) | tech | Computers And Technology | ✅ Enabled |\n| Baseline Profile | [Baseline Profile](https://entra.microsoft.com/#view/Microsoft_Azure_Network_Access/EditProfileMenuBlade.MenuView/~/basics/profileId/2bb1e634-8de0-4fcf-b05d-b1254a0a40db) | [Windows](https://entra.microsoft.com/#view/Microsoft_Azure_Network_Access/EditFilteringPolicyMenuBlade.MenuView/~/Basics/policyId/83050ddf-4e6f-48d0-ad06-8c17ad051844/title/Windows/defaultMenuItemId/Basics) | tech | Computers And Technology | ✅ Enabled |\n\n### Portal links\n\n- [Web content filtering policies](https://entra.microsoft.com/#view/Microsoft_Azure_Network_Access/WebFilteringPolicy.ReactView)\n- [Security profiles](https://entra.microsoft.com/#view/Microsoft_Azure_Network_Access/FilteringPolicyProfiles.ReactView)\n\r\n\r\n","TestSfiPillar":"Protect networks","TestStatus":"Passed","TestImpact":"Medium","TestPillar":"Network","TestId":"25409","TestRisk":"Medium","TestDescription":"Category-based filtering provides broader protection than URL-specific rules. Blocking entire website categories like malware, phishing, hacking, and criminal activity prevents access to thousands of malicious sites at once. Filtering policies that only target specific URLs or domains require constant maintenance and leave gaps as threat actors register new malicious domains daily.\r\n\r\n**Remediation action**\r\n\r\n- [Review available web content filtering categories](https://learn.microsoft.com/entra/global-secure-access/reference-web-content-filtering-categories?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci)\r\n- [Configure category-based filtering rules](https://learn.microsoft.com/entra/global-secure-access/how-to-configure-web-content-filtering?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci)\r\n","TestTags":null,"TestMinimumLicense":["Entra_Premium_Internet_Access"],"SkippedReason":null,"TestAppliesTo":null,"TestImplementationCost":"Medium","TestCategory":"Global Secure Access"},{"TestTitle":"GSA Deployment logs are populated and reviewed","TestSkipped":"","TestResult":"\r\nGSA deployment logs are populated and recent deployments have succeeded.\n\n\r\n## [Deployment Logs](https://entra.microsoft.com/#view/Microsoft_Azure_Network_Access/DeploymentLogs.ReactView)\r\n\r\n**Deployment Summary (Last 30 Days):**\r\n\r\n| Metric | Value |\r\n| :--- | :--- |\r\n| Total Deployments | 11 |\r\n| Succeeded | 11 |\r\n| Failed | 0 |\r\n| In Progress | 0 |\r\n| Failure Rate | 0% |\r\n\r\n**Recent Deployments:**\r\n\r\nShowing 10 of 11 deployments. [View all deployments](https://entra.microsoft.com/#view/Microsoft_Azure_Network_Access/DeploymentLogs.ReactView)\n\n\r\n| Date | Operation | Change Type | Status | Initiated By | Error Message |\r\n| :--- | :--- | :--- | :--- | :--- | :--- |\r\n| 2026-06-03 10:29 | Update Security Provider Settings | SecurityProviderSettings | ✅ Succeeded | GSA Service account | N/A |\n| 2026-06-03 10:29 | Update Security Provider Settings | SecurityProviderSettings | ✅ Succeeded | GSA Service account | N/A |\n| 2026-06-03 10:29 | Update Security Provider Settings | SecurityProviderSettings | ✅ Succeeded | GSA Service account | N/A |\n| 2026-06-03 10:28 | Update Security Provider Settings | SecurityProviderSettings | ✅ Succeeded | AppID: 61e5de7f-3d54-447d-8db1-0859295e9c13 | N/A |\n| 2026-06-03 10:28 | Update Security Provider Settings | SecurityProviderSettings | ✅ Succeeded | AppID: 7bbb185e-9e4f-403d-ae87-facc397e6038 | N/A |\n| 2026-06-03 10:28 | Update Security Provider Settings | SecurityProviderSettings | ✅ Succeeded | AppID: 61e5de7f-3d54-447d-8db1-0859295e9c13 | N/A |\n| 2026-06-03 10:28 | Update Tls Settings | TlsSettings | ✅ Succeeded | AppID: 61e5de7f-3d54-447d-8db1-0859295e9c13 | N/A |\n| 2026-06-03 10:28 | Update Tls Settings | TlsSettings | ✅ Succeeded | AppID: 7bbb185e-9e4f-403d-ae87-facc397e6038 | N/A |\n| 2026-06-03 10:27 | Update Tls Settings | TlsSettings | ✅ Succeeded | AppID: 61e5de7f-3d54-447d-8db1-0859295e9c13 | N/A |\n| 2026-06-03 10:10 | Update Tls Settings | TlsSettings | ✅ Succeeded | GSA Service account | N/A |\n| ... | | | | | |\n\r\n\r\n\r\n","TestSfiPillar":"Monitor and detect cyberthreats","TestStatus":"Passed","TestImpact":"Low","TestPillar":"Network","TestId":"25422","TestRisk":"Medium","TestDescription":"Global Secure Access deployment logs track the status and progress of configuration changes across the global network. These changes include forwarding profile redistributions, remote network updates, filtering profile changes, and changes to Conditional Access settings. If deployment logs show failed deployments, threat actors can exploit inconsistent security configurations where some edge locations have outdated or misconfigured policies.\r\n\r\nIf you don't monitor deployment logs:\r\n\r\n- Failed deployments can leave security gaps such as outdated forwarding profiles that don't route traffic through security inspection, or filtering profiles that don't block malicious destinations.\r\n- Administrators might remain unaware of outdated configurations, believing that changes are applied uniformly.\r\n- Deployment failures that create exploitable gaps can go undetected.\r\n\r\n**Remediation action**\r\n\r\n- Follow the steps in [How to use the Global Secure Access deployment logs](https://learn.microsoft.com/entra/global-secure-access/how-to-view-deployment-logs?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci) to:\r\n - Access and review deployment logs in the Microsoft Entra admin center to identify failed deployments.\r\n - For failed deployments, examine the error message in the `status.message` field and retry the configuration change that triggered the failure.\r\n - Monitor deployment notifications that appear in the admin center when making configuration changes to catch failures in real-time.\r\n- If deployments consistently fail for remote networks, [review the underlying remote network configuration](https://learn.microsoft.com/entra/global-secure-access/how-to-manage-remote-networks?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci) for errors.\r\n- For forwarding profile deployment failures, [verify traffic forwarding configuration](https://learn.microsoft.com/entra/global-secure-access/concept-traffic-forwarding?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci).\r\n","TestTags":null,"TestMinimumLicense":["Entra_Premium_Internet_Access","Entra_Premium_Private_Access"],"SkippedReason":null,"TestAppliesTo":null,"TestImplementationCost":"Low","TestCategory":"Global Secure Access"},{"TestTitle":"Internet access forwarding profile is enabled","TestSkipped":"","TestResult":"\r\nInternet access forwarding profile is enabled with user assignments.\n\n\r\n## Internet access profile\r\n\r\n| Profile name | Profile state | Assignments | Assignment count |\r\n| :----------- | :------------ | :---------- | :---------- |\r\n| [Internet traffic forwarding profile](https://entra.microsoft.com/#view/Microsoft_Azure_Network_Access/ForwardingProfile.ReactView) | ✅ Enabled | [✅ All Users](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/Users/objectId/d5d94205-bbdd-4252-86e3-9adcfcb9b0cd/appId/00f3da2e-20a3-4b7d-91f6-3a612e58c44f/preferredSingleSignOnMode~/null/servicePrincipalType/Application/fromNav/) | All Users |\r\n\r\n","TestSfiPillar":"Protect networks","TestStatus":"Passed","TestImpact":"Medium","TestPillar":"Network","TestId":"25406","TestRisk":"High","TestDescription":"When the Internet Access forwarding profile isn't enabled, users can access internet resources without routing traffic through the Secure Web Gateway. This gap allows threat actors to bypass security controls that block threats, malicious content, and unsafe destinations.\r\n\r\nWithout this protection:\r\n\r\n- Organizations lose visibility into traffic patterns. They can't detect data exfiltration, connections to malicious domains, or unauthorized external access.\r\n- Threat actors can deliver malware, establish command and control connections, or exfiltrate data through unmonitored channels.\r\n- Threat actors can use compromised credentials or social engineering to gain initial access, download tools, establish persistence, or communicate with external infrastructure.\r\n- Threat actors can use compromised accounts to blend with typical user behavior and access external resources without triggering security alerts based on user context, device compliance, or location.\r\n\r\n**Remediation action**\r\n- Enable the Internet Access forwarding profile to route traffic through the Secure Web Gateway. For more information, see [How to manage the Internet Access traffic forwarding profile](https://learn.microsoft.com/entra/global-secure-access/how-to-manage-internet-access-profile?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci).\r\n- Assign users and groups to the Internet Access profile to limit traffic forwarding to specific users. For more information, see [Global Secure Access traffic forwarding profiles](https://learn.microsoft.com/entra/global-secure-access/concept-traffic-forwarding?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci).\r\n","TestTags":null,"TestMinimumLicense":["Entra_Premium_Internet_Access"],"SkippedReason":null,"TestAppliesTo":null,"TestImplementationCost":"Low","TestCategory":"Global Secure Access"},{"TestTitle":"Network traffic is routed through Global Secure Access for security policy enforcement","TestSkipped":"","TestResult":"\r\n✅ All traffic forwarding profiles are enabled. Network traffic is being captured and protected by Microsoft's Security Service Edge.\n\n\n## Traffic Forwarding Profiles\n\n[Open Traffic Forwarding Profiles in Entra Portal](https://entra.microsoft.com/#view/Microsoft_Azure_Network_Access/ForwardingProfile.ReactView)\n\n| Traffic Type | Name | State |\r\n| :----------- | :--- | :---- |\r\n| Microsoft 365 | Microsoft 365 traffic forwarding profile | ✅ enabled |\n| Private Access | Private access traffic forwarding profile | ✅ enabled |\n| Internet Access | Internet traffic forwarding profile | ✅ enabled |\r\n\r\n\r\n","TestSfiPillar":"Protect networks","TestStatus":"Passed","TestImpact":"Low","TestPillar":"Network","TestId":"25381","TestRisk":"High","TestDescription":"Traffic forwarding profiles are the foundational mechanism through which Global Secure Access captures and routes network traffic to Microsoft's Security Service Edge infrastructure. If you don't enable the appropriate traffic forwarding profiles, network traffic bypasses the Global Secure Access service entirely, and users don't get these network access protections.\r\n\r\nThere are three distinct profiles:\r\n\r\n- **Microsoft traffic profile**: Captures Microsoft Entra ID, Microsoft Graph, SharePoint Online, Exchange Online, and other Microsoft 365 workloads.\r\n- **Private access profile**: Captures traffic destined for internal corporate resources.\r\n- **Internet access profile**: Captures traffic to the public internet including non-Microsoft SaaS applications.\r\n\r\nIf you don't enable these profiles:\r\n\r\n- You can't enforce security policies, web content filtering, threat protection, or Universal Continuous Access Evaluation.\r\n- Threat actors who compromise user credentials can access corporate resources without the security controls that Global Secure Access would otherwise apply.\r\n\r\n**Remediation action**\r\n\r\n- Enable the Microsoft traffic forwarding profile. For more information, see [Manage the Microsoft traffic profile](https://learn.microsoft.com/entra/global-secure-access/how-to-manage-microsoft-profile?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci).\r\n- Enable the Private Access traffic forwarding profile. For more information, see [Manage the Private Access traffic forwarding profile](https://learn.microsoft.com/entra/global-secure-access/how-to-manage-private-access-profile?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci).\r\n- Enable the Internet Access traffic forwarding profile. For more information, see [Manage the Internet Access traffic forwarding profile](https://learn.microsoft.com/entra/global-secure-access/how-to-manage-internet-access-profile?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci).\r\n","TestTags":null,"TestMinimumLicense":["Entra_Premium_Private_Access","Entra_Premium_Internet_Access"],"SkippedReason":null,"TestAppliesTo":null,"TestImplementationCost":"Medium","TestCategory":"Global Secure Access"},{"TestTitle":"Application admin rights are constrained to specific Private Access apps, not tenant-wide","TestSkipped":"","TestResult":"\r\n\n## Summary\n\n| Metric | Count |\n| :--- | ---: |\n| Total Assignments | 3 |\n| Tenant-Wide Assignments | 2 |\n| Scoped Assignments | 1 |\n| Problematic Assignments | 0 |\n\n\n## Application Administrator Assignments:\n\n- Count: 3\n\n| DirectoryScopeId | Principal DisplayName | UPN | AccountEnabled | Type | User Type |\n| :--- | :--- | :--- | :---: | :--- | :--- |\n| / | Sarmis Celms | demouser9@contoso.com | True | user | Member |\n| / | Archie Bazarbaykyzy | demouser10@contoso.com | True | user | Member |\n| /0bf15e78-c570-40b0-82c2-9172d825b0cb | Violet Martinez | demouser11@contoso.com | True | user | Member |\n\n\n## ❌ Tenant-Wide Assignments\n\nThe following Application Administrator assignments have tenant-wide scope and should be constrained:\n\n| Principal | Type | User Type | Scope |\n| :--- | :--- | :--- | :--- |\n| demouser9@contoso.com | user | Member | Tenant-wide (/) |\n| demouser10@contoso.com | user | Member | Tenant-wide (/) |\n\n\n## ✅ Scoped Assignments\n\nThe following Application Administrator assignments are scoped to specific applications:\n\n| Principal | Type | Application | PA/QA App |\n| :--- | :--- | :--- | :---: |\n| demouser11@contoso.com | user | Unknown app | ❌ |\n\n\n## ⚠️ Warnings\n\n- 1 scoped assignment(s) could not be resolved to application objects; see details in 'Unresolved Scoped Assignments' below\n\n\n## ⚠️ Unresolved Scoped Assignments\n\nThe following scoped assignments reference application or service principal objects that could not be resolved:\n\n| Principal | Type | Scope Target Kind | DirectoryScopeId |\n| :--- | :--- | :--- | :--- |\n| demouser11@contoso.com | user | application | /0bf15e78-c570-40b0-82c2-9172d825b0cb |\n\n\n[View in Entra Portal: Roles and administrators](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/AllRolesBlade)\r\n\r\n","TestSfiPillar":"Protect identities and secrets","TestStatus":"Failed","TestImpact":"Low","TestPillar":"Network","TestId":"25384","TestRisk":"High","TestDescription":"An Application Administrator role scoped at the tenant level can manage every app registration and enterprise application. If a threat actor compromises an Application Administrator with tenant-wide scope, they can add credentials to any service principal, consent to malicious APIs, modify or create applications that enable data exfiltration, and disable or tamper with Private Access apps. Scoping the role to only required Private Access enterprise apps enforces least privilege and limits the blast radius.\r\n\r\nIf you don't scope Application Administrator assignments to specific apps:\r\n\r\n- A compromised Application Administrator can manage every app registration and enterprise application in your tenant.\r\n- Threat actors can add credentials to any service principal, enabling persistence and lateral movement.\r\n- There's no blast radius containment; a single compromised identity can affect all applications.\r\n\r\n**Remediation action**\r\n\r\n- [Assign Application Administrator roles scoped to specific app registrations](https://learn.microsoft.com/entra/identity/role-based-access-control/custom-enterprise-app-permissions?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci) instead of tenant-wide.\r\n- [Assign Microsoft Entra roles](https://learn.microsoft.com/entra/identity/role-based-access-control/manage-roles-portal?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci) with the least privilege necessary to perform required tasks.\r\n- [Use Privileged Identity Management to manage just-in-time role activation](https://learn.microsoft.com/entra/id-governance/privileged-identity-management/pim-configure?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci).\r\n- [Manage Microsoft Entra role assignments in the admin center](https://learn.microsoft.com/entra/identity/role-based-access-control/manage-roles-portal?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci).\r\n","TestTags":null,"TestMinimumLicense":["Entra_Premium_Private_Access","Entra_Premium_Internet_Access"],"SkippedReason":null,"TestAppliesTo":null,"TestImplementationCost":"Low","TestCategory":"Role management"},{"TestId":"25543","TestCategory":"Azure Network Security","TestImpact":"Low","TestResult":"\r\n✅ All Azure Front Door WAF policies are enabled in **Prevention** mode.\n\n\r\n\r\n## [Azure Front Door WAF policies](https://portal.azure.com/#view/Microsoft_Azure_HybridNetworking/FirewallManagerMenuBlade/~/wafMenuItem)\r\n\r\n| Policy name | Subscription name | Policy state | Mode | Status |\r\n| :---------- | :---------------- | :----------: | :--: | :----: |\r\n| [AFDCopilotWAFPolicy](https://portal.azure.com/#resource/subscriptions/ab48f397-fc82-4634-aa52-62dd91b3ebaa/resourcegroups/Woodgrove-RG/providers/Microsoft.Network/frontdoorwebapplicationfirewallpolicies/AFDCopilotWAFPolicy) | [Woodgrove - GTP Demos (External/Sponsored)](https://portal.azure.com/#resource/subscriptions/ab48f397-fc82-4634-aa52-62dd91b3ebaa) | ✅ Enabled | ✅ Prevention | ✅ |\r\n\r\n\r\n","SkippedReason":null,"TestMinimumLicense":["Azure WAF on Azure Front Door Premium SKU","Azure Standard SKU"],"TestAppliesTo":null,"TestTags":null,"TestSfiPillar":"Protect networks","TestImplementationCost":"Low","TestSkipped":"","TestPillar":"Network","TestTitle":"Azure Front Door WAF is Enabled in Prevention Mode","TestStatus":"Passed","TestDescription":"Azure Front Door Web Application Firewall (WAF) protects web applications from common exploits and vulnerabilities, including SQL injection, cross-site scripting, and other OWASP Top 10 threats. WAF operates in two modes: Detection and Prevention. Detection mode evaluates and logs requests that match WAF rules but doesn't block traffic, while Prevention mode actively blocks malicious requests before they reach the backend application. When WAF is in Detection mode, web applications remain exposed to exploitation even though threats are being identified.\r\n\r\nWithout WAF in Prevention mode:\r\n\r\n- Threat actors can exploit web application vulnerabilities because matched requests are only logged, not blocked.\r\n- Organizations lose active protection at the global edge that managed and custom WAF rules provide, which reduces WAF to an observation tool rather than a security control.\r\n\r\n**Remediation action**\r\n\r\n- [Configure WAF for Azure Front Door](https://learn.microsoft.com/azure/web-application-firewall/afds/afds-overview?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci) to switch the WAF policy from **Detection mode** to **Prevention mode**.\r\n- [Configure WAF policy settings for Azure Front Door](https://learn.microsoft.com/azure/web-application-firewall/afds/waf-front-door-policy-settings?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci#waf-mode) to enable **Prevention mode** in the policy settings.\r\n","TestRisk":"High"},{"TestTitle":"Communication compliance monitoring is configured for enterprise AI tools","TestSkipped":"NotConnectedToService","TestResult":"\r\nSkipped. This test requires connection to the service(s) \"SecurityCompliance\" currently disconnected. Please use _Connect-ZtAssessment_ to connect.\r\n\r\n","TestSfiPillar":"Protect tenants and production systems","TestStatus":"Skipped","TestImpact":"Medium","TestPillar":"AI","TestId":"35040","TestRisk":"High","TestDescription":"Collection Policies provide the data ingestion layer that supports monitoring of enterprise AI app activity. When these policies are in place, Communication Compliance can collect signals from AI app interactions and help organizations understand where data protection risks may exist across AI‑enabled workflows. This visibility helps teams apply data protection controls more consistently as AI use expands beyond Microsoft 365 Copilot.\r\n\t\t\r\nIn practice, users may accidentally share sensitive data with custom AI applications, Power Automate flows, AI Builder automations, or non‑Microsoft AI services that aren’t approved to handle confidential information. However, Communication Compliance policies that cover enterprise AI app interactions can help surface potential data exposure to these services and extend data protection practices to custom and third‑party AI solutions.\r\n\r\n**Remediation action**\r\n\r\n- [Create and Deploy collection policies](https://learn.microsoft.com/purview/collection-policies-create-deploy-policy?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci)\r\n- [Create and manage Communication Compliance policies](https://learn.microsoft.com/purview/communication-compliance-policies?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci)\r\n","TestTags":null,"TestMinimumLicense":["EXCHANGE_S_ENTERPRISE"],"SkippedReason":"This test requires connection to the service(s) \"SecurityCompliance\" currently disconnected. Please use _Connect-ZtAssessment_ to connect.","TestAppliesTo":null,"TestImplementationCost":"Medium","TestCategory":"Data Security Posture Management"},{"TestTitle":"Private Access connectors are active and healthy","TestSkipped":"","TestResult":"\r\nOne or more Private Network Access connectors are inactive or unhealthy.\n\n\r\n## Private Access connectors summary\r\n\r\n[Portal Link: Global Secure Access > Connect > Connectors](https://entra.microsoft.com/#view/Microsoft_Entra_GSA_Connect/Connectors.ReactView/fromNav/globalSecureAccess)\r\n\r\n- **Total Connectors:** 3\r\n- **Active Connectors:** 1\r\n- **Inactive Connectors:** 2\r\n\r\n## Private Access connectors status\r\n\r\n| Machine name | Status | External ip | Version |\r\n| :----------- | :------------ | :---------- | :------ |\r\n| AppProxy02.Woodgrove.net | ❌ Inactive | 203.0.113.12 | 1.5.4522.0 |\n| Woodgrove-GSA01 | ❌ Inactive | 203.0.113.10 | 1.5.3925.0 |\n| ForrestorDemo | ✅ Active | 203.0.113.11 | 1.5.3925.0 |\n\r\n\r\n","TestSfiPillar":"Protect networks","TestStatus":"Failed","TestImpact":"Medium","TestPillar":"Network","TestId":"25391","TestRisk":"Medium","TestDescription":"When Microsoft Entra private network connectors are inactive or unhealthy, organizations might resort to using less secure access methods. This condition creates opportunities where threat actors can target externally exposed services or use compromised credentials.\r\n\r\nWithout functional connectors:\r\n\r\n- Token-based authentication and authorization for all Microsoft Entra Private Access scenarios is eliminated.\r\n- Threat actors can bypass intended security boundaries to access resources beyond their authorization scope.\r\n- The service can't route requests properly, directly disrupting network access controls.\r\n\r\n**Remediation action**\r\n\r\n- [Configure connectors for high availability](https://learn.microsoft.com/entra/global-secure-access/how-to-configure-connectors?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci).\r\n- Monitor connector health in the Microsoft Entra admin center under Global Secure Access > Connect > Connectors.\r\n- [Troubleshoot connector installation and connectivity issues](https://learn.microsoft.com/entra/global-secure-access/troubleshoot-connectors?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci).\r\n","TestTags":null,"TestMinimumLicense":["Entra_Premium_Private_Access"],"SkippedReason":null,"TestAppliesTo":null,"TestImplementationCost":"Low","TestCategory":"Global Secure Access"},{"TestTitle":"DC Agent is deployed and enforcing strong authentication policies","TestSkipped":"","TestResult":"\r\n❌ Microsoft Entra Private Access Sensors for domain controllers is not deployed.\n\n\r\n\r\n","TestSfiPillar":"Protect networks","TestStatus":"Failed","TestImpact":"Medium","TestPillar":"Network","TestId":"25403","TestRisk":"High","TestDescription":"If you don't deploy Microsoft Entra Private Access sensors to domain controllers, threat actors can exploit Kerberos authentication requests from any device on the network, including unmanaged or compromised endpoints. They can use this vulnerability to get service tickets for on-premises resources without multifactor authentication or device compliance validation.\r\n\r\nIf you don't deploy Private Access sensors to domain controllers:\r\n\r\n- Threat actors can request Kerberos tickets for privileged resources such as file shares, database servers, and remote desktop services. This vulnerability enables lateral movement across the on-premises environment.\r\n- Conditional Access policies don't apply to Kerberos authentication, because it operates within a perimeter-based trust model where any authenticated user can request tickets regardless of authentication strength or device posture.\r\n- Compromised user credentials obtained through phishing or credential theft can be immediately used to access domain-authenticated resources without triggering multifactor authentication requirements.\r\n\r\n**Remediation action**\r\n\r\n- [Configure Microsoft Entra Private Access for Active Directory domain controllers](https://learn.microsoft.com/entra/global-secure-access/how-to-configure-domain-controllers?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci).\r\n","TestTags":null,"TestMinimumLicense":["Entra_Premium_Private_Access"],"SkippedReason":null,"TestAppliesTo":null,"TestImplementationCost":"Medium","TestCategory":"Global Secure Access"},{"TestTitle":"Quick Access is protected by Conditional Access policies","TestSkipped":"","TestResult":"\r\n⚠️ No Quick Access application is configured, review the documentation on how to enable Quick Access if needed.\n\n\r\n\r\n","TestSfiPillar":"Protect networks","TestStatus":"Investigate","TestImpact":"Medium","TestPillar":"Network","TestId":"25394","TestRisk":"High","TestDescription":"When you configure Quick Access in Microsoft Entra Private Access without Conditional Access policies, threat actors who compromise user credentials gain unrestricted access to private resources. The Quick Access application serves as a container for private resources including FQDNs and IP addresses.\r\n\r\nWithout policy enforcement:\r\n\r\n- Compromised accounts provide a direct pathway to internal systems.\r\n- Threat actors operating from unmanaged devices or anomalous locations can access private resources indistinguishably from authorized users.\r\n- Lateral movement across the internal network and data exfiltration from private applications become possible.\r\n- Multifactor authentication requirements and device health checks can't be enforced.\r\n\r\n**Remediation action**\r\n\r\n- [Apply Conditional Access Policies to Microsoft Entra Private Access Apps](https://learn.microsoft.com/entra/global-secure-access/how-to-target-resource-private-access-apps?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci).\r\n","TestTags":null,"TestMinimumLicense":["Entra_Premium_Private_Access"],"SkippedReason":null,"TestAppliesTo":null,"TestImplementationCost":"Low","TestCategory":"Global Secure Access"},{"TestId":"25533","TestCategory":"Azure Network Security","TestImpact":"Low","TestResult":"\r\n❌ DDoS Protection is not enabled for one or more Public IP addresses. This includes public IPs with DDoS protection explicitly disabled, and public IPs that inherit from a VNET that does not have a DDoS Protection Plan enabled.\n\n\r\n## [Public IP addresses DDoS protection status](https://portal.azure.com/#view/HubsExtension/BrowseResource/resourceType/Microsoft.Network%2FpublicIPAddresses)\r\n\r\n| Public IP name | DDoS protection mode | Resource type | Associated VNET | VNET DDoS protection | Status |\r\n| :--- | :--- | :--- | :--- | :--- | :---: |\r\n| [0764e398-4146-46c3-82af-b09f933d2e95](https://portal.azure.com/#resource/subscriptions/ee301620-7f47-414b-97b7-9d84046f4d38/resourceGroups/MC_rg-Zava-Resources-489n_aks-ZavaK8s-04ee6589_centralus/providers/Microsoft.Network/publicIPAddresses/0764e398-4146-46c3-82af-b09f933d2e95) | VirtualNetworkInherited | Load Balancer | N/A | ❌ Disabled | ❌ Fail |\n| [25e07f3c-f40e-42f7-b412-c858045356b7](https://portal.azure.com/#resource/subscriptions/ab48f397-fc82-4634-aa52-62dd91b3ebaa/resourceGroups/MC_woodgrove-MDC-RG_AKS-HELM_eastus/providers/Microsoft.Network/publicIPAddresses/25e07f3c-f40e-42f7-b412-c858045356b7) | VirtualNetworkInherited | Load Balancer | N/A | ❌ Disabled | ❌ Fail |\n| [53893aa7-96a7-4f1a-9361-cf50b9aaf903](https://portal.azure.com/#resource/subscriptions/ab48f397-fc82-4634-aa52-62dd91b3ebaa/resourceGroups/MC_aks-inventory-onboarded_woodgrove-aks-inventory-mdc_eastus/providers/Microsoft.Network/publicIPAddresses/53893aa7-96a7-4f1a-9361-cf50b9aaf903) | VirtualNetworkInherited | Load Balancer | N/A | ❌ Disabled | ❌ Fail |\n| [59da40d4-0a56-4bda-b371-10e0f0330084](https://portal.azure.com/#resource/subscriptions/ab48f397-fc82-4634-aa52-62dd91b3ebaa/resourceGroups/MC_woodgrove-MDC-RG_woodgrove-k8-MDC_eastus/providers/Microsoft.Network/publicIPAddresses/59da40d4-0a56-4bda-b371-10e0f0330084) | VirtualNetworkInherited | Load Balancer | N/A | ❌ Disabled | ❌ Fail |\n| [8e26b621-7582-4c44-a17f-e12900a243f9](https://portal.azure.com/#resource/subscriptions/ee301620-7f47-414b-97b7-9d84046f4d38/resourceGroups/MC_rg-Zava-Resources-yxhw_aks-ZavaK8s-yxhw-04ee6589_centralus/providers/Microsoft.Network/publicIPAddresses/8e26b621-7582-4c44-a17f-e12900a243f9) | VirtualNetworkInherited | Load Balancer | N/A | ❌ Disabled | ❌ Fail |\n| [aadds-dfc25f6c560b4eeaa2aee72234866e76-pip](https://portal.azure.com/#resource/subscriptions/ab48f397-fc82-4634-aa52-62dd91b3ebaa/resourceGroups/Woodgrove-AzureADDS/providers/Microsoft.Network/publicIPAddresses/aadds-dfc25f6c560b4eeaa2aee72234866e76-pip) | ❌ Disabled | N/A | N/A | N/A | ❌ Fail |\n| [aispm-win11pro-ip](https://portal.azure.com/#resource/subscriptions/ab48f397-fc82-4634-aa52-62dd91b3ebaa/resourceGroups/woodgrove-MDC-AI/providers/Microsoft.Network/publicIPAddresses/aispm-win11pro-ip) | VirtualNetworkInherited | Network Interface | aispm-win11pro-vnet | ❌ Disabled | ❌ Fail |\n| [ArcBox-Client-PIP](https://portal.azure.com/#resource/subscriptions/ab48f397-fc82-4634-aa52-62dd91b3ebaa/resourceGroups/woodgrove-mdc-arc/providers/Microsoft.Network/publicIPAddresses/ArcBox-Client-PIP) | ❌ Disabled | N/A | N/A | N/A | ❌ Fail |\n| [ArcBox-Client-PIP](https://portal.azure.com/#resource/subscriptions/ab48f397-fc82-4634-aa52-62dd91b3ebaa/resourceGroups/woodgrove-MDC-RG/providers/Microsoft.Network/publicIPAddresses/ArcBox-Client-PIP) | ❌ Disabled | N/A | N/A | N/A | ❌ Fail |\n| [dfe11441-44f9-436e-9963-210eb4c4afe9](https://portal.azure.com/#resource/subscriptions/855b095a-349d-42bf-b161-f93dc2438660/resourceGroups/MC_scp-agent-chat-demo_investigation-agent-aks_eastus2/providers/Microsoft.Network/publicIPAddresses/dfe11441-44f9-436e-9963-210eb4c4afe9) | VirtualNetworkInherited | Load Balancer | N/A | ❌ Disabled | ❌ Fail |\n| [fw-Woodgrove-vNet_Pip427](https://portal.azure.com/#resource/subscriptions/ab48f397-fc82-4634-aa52-62dd91b3ebaa/resourceGroups/Woodgrove-RG/providers/Microsoft.Network/publicIPAddresses/fw-Woodgrove-vNet_Pip427) | ❌ Disabled | N/A | N/A | N/A | ❌ Fail |\n| [fw-Woodgrove-vNet1_Pip1](https://portal.azure.com/#resource/subscriptions/ab48f397-fc82-4634-aa52-62dd91b3ebaa/resourceGroups/Woodgrove-RG/providers/Microsoft.Network/publicIPAddresses/fw-Woodgrove-vNet1_Pip1) | ❌ Disabled | N/A | N/A | N/A | ❌ Fail |\n| [fw-Woodgrove-vNet2_Pip1](https://portal.azure.com/#resource/subscriptions/ab48f397-fc82-4634-aa52-62dd91b3ebaa/resourceGroups/Woodgrove-RG/providers/Microsoft.Network/publicIPAddresses/fw-Woodgrove-vNet2_Pip1) | ❌ Disabled | N/A | N/A | N/A | ❌ Fail |\n| [iot-cyberx-hyperv-vm-ip](https://portal.azure.com/#resource/subscriptions/ab48f397-fc82-4634-aa52-62dd91b3ebaa/resourceGroups/woodgrove-iot-rg/providers/Microsoft.Network/publicIPAddresses/iot-cyberx-hyperv-vm-ip) | ❌ Disabled | N/A | N/A | N/A | ❌ Fail |\n| [kubernetes-a0d51c55fc4824c52ab1712ff972a13c](https://portal.azure.com/#resource/subscriptions/ab48f397-fc82-4634-aa52-62dd91b3ebaa/resourceGroups/mc_woodgrove-mdc-rg_woodgrove-k8-mdc_eastus/providers/Microsoft.Network/publicIPAddresses/kubernetes-a0d51c55fc4824c52ab1712ff972a13c) | VirtualNetworkInherited | Load Balancer | N/A | ❌ Disabled | ❌ Fail |\n| [kubernetes-a0fa6321661254f55bdc38cdb41c284f](https://portal.azure.com/#resource/subscriptions/ab48f397-fc82-4634-aa52-62dd91b3ebaa/resourceGroups/mc_woodgrove-mdc-rg_woodgrove-k8-mdc_eastus/providers/Microsoft.Network/publicIPAddresses/kubernetes-a0fa6321661254f55bdc38cdb41c284f) | VirtualNetworkInherited | Load Balancer | N/A | ❌ Disabled | ❌ Fail |\n| [kubernetes-a15ce95a194c94e50af58720b3ed00c2](https://portal.azure.com/#resource/subscriptions/ab48f397-fc82-4634-aa52-62dd91b3ebaa/resourceGroups/mc_woodgrove-mdc-rg_woodgrove-k8-mdc_eastus/providers/Microsoft.Network/publicIPAddresses/kubernetes-a15ce95a194c94e50af58720b3ed00c2) | VirtualNetworkInherited | Load Balancer | N/A | ❌ Disabled | ❌ Fail |\n| [kubernetes-a19ccc58d286a4cbca0eedd6ecb58b6d](https://portal.azure.com/#resource/subscriptions/ab48f397-fc82-4634-aa52-62dd91b3ebaa/resourceGroups/mc_woodgrove-mdc-rg_woodgrove-k8-mdc_eastus/providers/Microsoft.Network/publicIPAddresses/kubernetes-a19ccc58d286a4cbca0eedd6ecb58b6d) | VirtualNetworkInherited | Load Balancer | N/A | ❌ Disabled | ❌ Fail |\n| [kubernetes-a1a706f765005416e9882326faabe233](https://portal.azure.com/#resource/subscriptions/ab48f397-fc82-4634-aa52-62dd91b3ebaa/resourceGroups/mc_woodgrove-mdc-rg_woodgrove-k8-mdc_eastus/providers/Microsoft.Network/publicIPAddresses/kubernetes-a1a706f765005416e9882326faabe233) | VirtualNetworkInherited | Load Balancer | N/A | ❌ Disabled | ❌ Fail |\n| [kubernetes-a3140115c01c54ddb8ce32940ba6ecd8](https://portal.azure.com/#resource/subscriptions/ab48f397-fc82-4634-aa52-62dd91b3ebaa/resourceGroups/mc_woodgrove-mdc-rg_woodgrove-k8-mdc_eastus/providers/Microsoft.Network/publicIPAddresses/kubernetes-a3140115c01c54ddb8ce32940ba6ecd8) | VirtualNetworkInherited | Load Balancer | N/A | ❌ Disabled | ❌ Fail |\n| [kubernetes-a35357b3c81054c7a9886499a0dae0a1](https://portal.azure.com/#resource/subscriptions/ab48f397-fc82-4634-aa52-62dd91b3ebaa/resourceGroups/mc_woodgrove-mdc-rg_woodgrove-k8-mdc_eastus/providers/Microsoft.Network/publicIPAddresses/kubernetes-a35357b3c81054c7a9886499a0dae0a1) | VirtualNetworkInherited | Load Balancer | N/A | ❌ Disabled | ❌ Fail |\n| [kubernetes-a3d40b0a7614b4e0ea011fd31eeb30f5](https://portal.azure.com/#resource/subscriptions/ab48f397-fc82-4634-aa52-62dd91b3ebaa/resourceGroups/mc_woodgrove-mdc-rg_woodgrove-k8-mdc_eastus/providers/Microsoft.Network/publicIPAddresses/kubernetes-a3d40b0a7614b4e0ea011fd31eeb30f5) | VirtualNetworkInherited | Load Balancer | N/A | ❌ Disabled | ❌ Fail |\n| [kubernetes-a40d74ed494e041eda62421b5eae8772](https://portal.azure.com/#resource/subscriptions/ab48f397-fc82-4634-aa52-62dd91b3ebaa/resourceGroups/mc_woodgrove-mdc-rg_woodgrove-k8-mdc_eastus/providers/Microsoft.Network/publicIPAddresses/kubernetes-a40d74ed494e041eda62421b5eae8772) | VirtualNetworkInherited | Load Balancer | N/A | ❌ Disabled | ❌ Fail |\n| [kubernetes-a48abfac1872d41108a3ecaf866d8500](https://portal.azure.com/#resource/subscriptions/ab48f397-fc82-4634-aa52-62dd91b3ebaa/resourceGroups/mc_woodgrove-mdc-rg_aks-helm_eastus/providers/Microsoft.Network/publicIPAddresses/kubernetes-a48abfac1872d41108a3ecaf866d8500) | VirtualNetworkInherited | Load Balancer | N/A | ❌ Disabled | ❌ Fail |\n| [kubernetes-a58d1ee0c1d71450481d76ccaa61fa6d](https://portal.azure.com/#resource/subscriptions/ab48f397-fc82-4634-aa52-62dd91b3ebaa/resourceGroups/mc_woodgrove-mdc-rg_woodgrove-k8-mdc_eastus/providers/Microsoft.Network/publicIPAddresses/kubernetes-a58d1ee0c1d71450481d76ccaa61fa6d) | VirtualNetworkInherited | Load Balancer | N/A | ❌ Disabled | ❌ Fail |\n| [kubernetes-a591b3ebe662c4efda31aae40c30e7b9](https://portal.azure.com/#resource/subscriptions/ab48f397-fc82-4634-aa52-62dd91b3ebaa/resourceGroups/mc_woodgrove-mdc-rg_woodgrove-k8-mdc_eastus/providers/Microsoft.Network/publicIPAddresses/kubernetes-a591b3ebe662c4efda31aae40c30e7b9) | VirtualNetworkInherited | Load Balancer | N/A | ❌ Disabled | ❌ Fail |\n| [kubernetes-a688e3ac16fa642e98fd1605503968b5](https://portal.azure.com/#resource/subscriptions/ab48f397-fc82-4634-aa52-62dd91b3ebaa/resourceGroups/mc_woodgrove-mdc-rg_woodgrove-k8-mdc_eastus/providers/Microsoft.Network/publicIPAddresses/kubernetes-a688e3ac16fa642e98fd1605503968b5) | VirtualNetworkInherited | Load Balancer | N/A | ❌ Disabled | ❌ Fail |\n| [kubernetes-a6b30eda8a0d845dc9d1655879bb9868](https://portal.azure.com/#resource/subscriptions/ab48f397-fc82-4634-aa52-62dd91b3ebaa/resourceGroups/mc_woodgrove-mdc-rg_woodgrove-k8-mdc_eastus/providers/Microsoft.Network/publicIPAddresses/kubernetes-a6b30eda8a0d845dc9d1655879bb9868) | VirtualNetworkInherited | Load Balancer | N/A | ❌ Disabled | ❌ Fail |\n| [kubernetes-a7c74b2e7b3d546e89168ff4b95c2fb1](https://portal.azure.com/#resource/subscriptions/ab48f397-fc82-4634-aa52-62dd91b3ebaa/resourceGroups/mc_woodgrove-mdc-rg_woodgrove-k8-mdc_eastus/providers/Microsoft.Network/publicIPAddresses/kubernetes-a7c74b2e7b3d546e89168ff4b95c2fb1) | VirtualNetworkInherited | Load Balancer | N/A | ❌ Disabled | ❌ Fail |\n| [kubernetes-a822681d560284a2ea16557f11480ba2](https://portal.azure.com/#resource/subscriptions/ab48f397-fc82-4634-aa52-62dd91b3ebaa/resourceGroups/mc_woodgrove-mdc-rg_woodgrove-k8-mdc_eastus/providers/Microsoft.Network/publicIPAddresses/kubernetes-a822681d560284a2ea16557f11480ba2) | VirtualNetworkInherited | Load Balancer | N/A | ❌ Disabled | ❌ Fail |\n| [kubernetes-a833dc0b76fb44e2ea5e6f138747d2fe](https://portal.azure.com/#resource/subscriptions/ab48f397-fc82-4634-aa52-62dd91b3ebaa/resourceGroups/mc_woodgrove-mdc-rg_woodgrove-k8-mdc_eastus/providers/Microsoft.Network/publicIPAddresses/kubernetes-a833dc0b76fb44e2ea5e6f138747d2fe) | VirtualNetworkInherited | Load Balancer | N/A | ❌ Disabled | ❌ Fail |\n| [kubernetes-a8d7252f74891439688775b643123a0f](https://portal.azure.com/#resource/subscriptions/ab48f397-fc82-4634-aa52-62dd91b3ebaa/resourceGroups/mc_woodgrove-mdc-rg_woodgrove-k8-mdc_eastus/providers/Microsoft.Network/publicIPAddresses/kubernetes-a8d7252f74891439688775b643123a0f) | VirtualNetworkInherited | Load Balancer | N/A | ❌ Disabled | ❌ Fail |\n| [kubernetes-aa321844f7ea246b88b8d01981114630](https://portal.azure.com/#resource/subscriptions/ab48f397-fc82-4634-aa52-62dd91b3ebaa/resourceGroups/mc_woodgrove-mdc-rg_woodgrove-k8-mdc_eastus/providers/Microsoft.Network/publicIPAddresses/kubernetes-aa321844f7ea246b88b8d01981114630) | VirtualNetworkInherited | Load Balancer | N/A | ❌ Disabled | ❌ Fail |\n| [kubernetes-aa32f39fa84af499584d2ac168983a16](https://portal.azure.com/#resource/subscriptions/ab48f397-fc82-4634-aa52-62dd91b3ebaa/resourceGroups/mc_woodgrove-mdc-rg_woodgrove-k8-mdc_eastus/providers/Microsoft.Network/publicIPAddresses/kubernetes-aa32f39fa84af499584d2ac168983a16) | VirtualNetworkInherited | Load Balancer | N/A | ❌ Disabled | ❌ Fail |\n| [kubernetes-aa5679b6e676445f382eeadb46d3b083](https://portal.azure.com/#resource/subscriptions/ab48f397-fc82-4634-aa52-62dd91b3ebaa/resourceGroups/mc_woodgrove-mdc-rg_woodgrove-k8-mdc_eastus/providers/Microsoft.Network/publicIPAddresses/kubernetes-aa5679b6e676445f382eeadb46d3b083) | VirtualNetworkInherited | Load Balancer | N/A | ❌ Disabled | ❌ Fail |\n| [kubernetes-aa9c7f25336b8473a950ffb67299e868](https://portal.azure.com/#resource/subscriptions/ab48f397-fc82-4634-aa52-62dd91b3ebaa/resourceGroups/mc_woodgrove-mdc-rg_woodgrove-k8-mdc_eastus/providers/Microsoft.Network/publicIPAddresses/kubernetes-aa9c7f25336b8473a950ffb67299e868) | VirtualNetworkInherited | Load Balancer | N/A | ❌ Disabled | ❌ Fail |\n| [kubernetes-aafe74ce9c0374d08bcf23f5abc85059](https://portal.azure.com/#resource/subscriptions/ab48f397-fc82-4634-aa52-62dd91b3ebaa/resourceGroups/mc_woodgrove-mdc-rg_woodgrove-k8-mdc_eastus/providers/Microsoft.Network/publicIPAddresses/kubernetes-aafe74ce9c0374d08bcf23f5abc85059) | VirtualNetworkInherited | Load Balancer | N/A | ❌ Disabled | ❌ Fail |\n| [kubernetes-ab09f4b1e87814fc988c2503940f3460](https://portal.azure.com/#resource/subscriptions/ab48f397-fc82-4634-aa52-62dd91b3ebaa/resourceGroups/mc_woodgrove-mdc-rg_woodgrove-k8-mdc_eastus/providers/Microsoft.Network/publicIPAddresses/kubernetes-ab09f4b1e87814fc988c2503940f3460) | VirtualNetworkInherited | Load Balancer | N/A | ❌ Disabled | ❌ Fail |\n| [kubernetes-ab60d665eda524306bec191a9d532d0c](https://portal.azure.com/#resource/subscriptions/ab48f397-fc82-4634-aa52-62dd91b3ebaa/resourceGroups/mc_woodgrove-mdc-rg_woodgrove-k8-mdc_eastus/providers/Microsoft.Network/publicIPAddresses/kubernetes-ab60d665eda524306bec191a9d532d0c) | VirtualNetworkInherited | Load Balancer | N/A | ❌ Disabled | ❌ Fail |\n| [kubernetes-ab9ac9e224bfe41d795feb9ffc6ee65b](https://portal.azure.com/#resource/subscriptions/ab48f397-fc82-4634-aa52-62dd91b3ebaa/resourceGroups/mc_woodgrove-mdc-rg_woodgrove-k8-mdc_eastus/providers/Microsoft.Network/publicIPAddresses/kubernetes-ab9ac9e224bfe41d795feb9ffc6ee65b) | VirtualNetworkInherited | Load Balancer | N/A | ❌ Disabled | ❌ Fail |\n| [kubernetes-ac3e9ea10e6014fffaeb912909e13a6d](https://portal.azure.com/#resource/subscriptions/ab48f397-fc82-4634-aa52-62dd91b3ebaa/resourceGroups/mc_woodgrove-mdc-rg_woodgrove-k8-mdc_eastus/providers/Microsoft.Network/publicIPAddresses/kubernetes-ac3e9ea10e6014fffaeb912909e13a6d) | VirtualNetworkInherited | Load Balancer | N/A | ❌ Disabled | ❌ Fail |\n| [kubernetes-ac5fc07b415e64e9f90fe16be2523bb8](https://portal.azure.com/#resource/subscriptions/ab48f397-fc82-4634-aa52-62dd91b3ebaa/resourceGroups/mc_woodgrove-mdc-rg_woodgrove-k8-mdc_eastus/providers/Microsoft.Network/publicIPAddresses/kubernetes-ac5fc07b415e64e9f90fe16be2523bb8) | VirtualNetworkInherited | Load Balancer | N/A | ❌ Disabled | ❌ Fail |\n| [kubernetes-aca755ef9b0274523a18cc9f7467d066](https://portal.azure.com/#resource/subscriptions/ab48f397-fc82-4634-aa52-62dd91b3ebaa/resourceGroups/mc_woodgrove-mdc-rg_woodgrove-k8-mdc_eastus/providers/Microsoft.Network/publicIPAddresses/kubernetes-aca755ef9b0274523a18cc9f7467d066) | VirtualNetworkInherited | Load Balancer | N/A | ❌ Disabled | ❌ Fail |\n| [kubernetes-ad0534bb75ae6423a98d5128989cfc37](https://portal.azure.com/#resource/subscriptions/ab48f397-fc82-4634-aa52-62dd91b3ebaa/resourceGroups/mc_woodgrove-mdc-rg_woodgrove-k8-mdc_eastus/providers/Microsoft.Network/publicIPAddresses/kubernetes-ad0534bb75ae6423a98d5128989cfc37) | VirtualNetworkInherited | Load Balancer | N/A | ❌ Disabled | ❌ Fail |\n| [kubernetes-ad1a6e170b96a4570b64f89dc89c170a](https://portal.azure.com/#resource/subscriptions/ab48f397-fc82-4634-aa52-62dd91b3ebaa/resourceGroups/mc_aks-inventory-onboarded_woodgrove-aks-inventory-mdc_eastus/providers/Microsoft.Network/publicIPAddresses/kubernetes-ad1a6e170b96a4570b64f89dc89c170a) | VirtualNetworkInherited | Load Balancer | N/A | ❌ Disabled | ❌ Fail |\n| [kubernetes-ad69c5be68d874460936ead5790a6317](https://portal.azure.com/#resource/subscriptions/ab48f397-fc82-4634-aa52-62dd91b3ebaa/resourceGroups/mc_woodgrove-mdc-rg_aks-helm_eastus/providers/Microsoft.Network/publicIPAddresses/kubernetes-ad69c5be68d874460936ead5790a6317) | VirtualNetworkInherited | Load Balancer | N/A | ❌ Disabled | ❌ Fail |\n| [kubernetes-aef1fd73a285d42f1a2913c3826e8491](https://portal.azure.com/#resource/subscriptions/ab48f397-fc82-4634-aa52-62dd91b3ebaa/resourceGroups/mc_woodgrove-mdc-rg_woodgrove-k8-mdc_eastus/providers/Microsoft.Network/publicIPAddresses/kubernetes-aef1fd73a285d42f1a2913c3826e8491) | VirtualNetworkInherited | Load Balancer | N/A | ❌ Disabled | ❌ Fail |\n| [kubernetes-aef97c02920da4597a199145e4722685](https://portal.azure.com/#resource/subscriptions/ab48f397-fc82-4634-aa52-62dd91b3ebaa/resourceGroups/mc_woodgrove-mdc-rg_woodgrove-k8-mdc_eastus/providers/Microsoft.Network/publicIPAddresses/kubernetes-aef97c02920da4597a199145e4722685) | VirtualNetworkInherited | Load Balancer | N/A | ❌ Disabled | ❌ Fail |\n| [kubernetes-afa28311ed4aa40b19a6512d87f77844](https://portal.azure.com/#resource/subscriptions/ab48f397-fc82-4634-aa52-62dd91b3ebaa/resourceGroups/mc_woodgrove-mdc-rg_woodgrove-k8-mdc_eastus/providers/Microsoft.Network/publicIPAddresses/kubernetes-afa28311ed4aa40b19a6512d87f77844) | VirtualNetworkInherited | Load Balancer | N/A | ❌ Disabled | ❌ Fail |\n| [kubernetes-afddcb4d98e7443c18e2ee2841b3d3ee](https://portal.azure.com/#resource/subscriptions/ab48f397-fc82-4634-aa52-62dd91b3ebaa/resourceGroups/mc_woodgrove-mdc-rg_woodgrove-k8-mdc_eastus/providers/Microsoft.Network/publicIPAddresses/kubernetes-afddcb4d98e7443c18e2ee2841b3d3ee) | VirtualNetworkInherited | Load Balancer | N/A | ❌ Disabled | ❌ Fail |\n| [loadBalancer-publicip](https://portal.azure.com/#resource/subscriptions/ab48f397-fc82-4634-aa52-62dd91b3ebaa/resourceGroups/woodgrove-MDC-RG/providers/Microsoft.Network/publicIPAddresses/loadBalancer-publicip) | ❌ Disabled | N/A | N/A | N/A | ❌ Fail |\n| [msidemo-devpc-ip](https://portal.azure.com/#resource/subscriptions/ab48f397-fc82-4634-aa52-62dd91b3ebaa/resourceGroups/Woodgrove-RG/providers/Microsoft.Network/publicIPAddresses/msidemo-devpc-ip) | ❌ Disabled | N/A | N/A | N/A | ❌ Fail |\n| [PARKCITY-DC-PublicIP](https://portal.azure.com/#resource/subscriptions/ab48f397-fc82-4634-aa52-62dd91b3ebaa/resourceGroups/woodgrove-alpine/providers/Microsoft.Network/publicIPAddresses/PARKCITY-DC-PublicIP) | ❌ Disabled | N/A | N/A | N/A | ❌ Fail |\n| [PARKCITY-Jump-PublicIP](https://portal.azure.com/#resource/subscriptions/ab48f397-fc82-4634-aa52-62dd91b3ebaa/resourceGroups/woodgrove-alpine/providers/Microsoft.Network/publicIPAddresses/PARKCITY-Jump-PublicIP) | ❌ Disabled | N/A | N/A | N/A | ❌ Fail |\n| [PARKCITY-Win10B-PublicIP](https://portal.azure.com/#resource/subscriptions/ab48f397-fc82-4634-aa52-62dd91b3ebaa/resourceGroups/woodgrove-alpine/providers/Microsoft.Network/publicIPAddresses/PARKCITY-Win10B-PublicIP) | ❌ Disabled | N/A | N/A | N/A | ❌ Fail |\n| [PARKCITY-Win10D-PublicIP](https://portal.azure.com/#resource/subscriptions/ab48f397-fc82-4634-aa52-62dd91b3ebaa/resourceGroups/woodgrove-alpine/providers/Microsoft.Network/publicIPAddresses/PARKCITY-Win10D-PublicIP) | ❌ Disabled | N/A | N/A | N/A | ❌ Fail |\n| [PARKCITY-Win10G-PublicIP](https://portal.azure.com/#resource/subscriptions/ab48f397-fc82-4634-aa52-62dd91b3ebaa/resourceGroups/woodgrove-alpine/providers/Microsoft.Network/publicIPAddresses/PARKCITY-Win10G-PublicIP) | ❌ Disabled | N/A | N/A | N/A | ❌ Fail |\n| [PARKCITY-Win10R-PublicIP](https://portal.azure.com/#resource/subscriptions/ab48f397-fc82-4634-aa52-62dd91b3ebaa/resourceGroups/woodgrove-alpine/providers/Microsoft.Network/publicIPAddresses/PARKCITY-Win10R-PublicIP) | ❌ Disabled | N/A | N/A | N/A | ❌ Fail |\n| [PARKCITY-Win10S-PublicIP](https://portal.azure.com/#resource/subscriptions/ab48f397-fc82-4634-aa52-62dd91b3ebaa/resourceGroups/woodgrove-alpine/providers/Microsoft.Network/publicIPAddresses/PARKCITY-Win10S-PublicIP) | ❌ Disabled | N/A | N/A | N/A | ❌ Fail |\n| [PARKCITY-Win11H-PublicIP](https://portal.azure.com/#resource/subscriptions/ab48f397-fc82-4634-aa52-62dd91b3ebaa/resourceGroups/woodgrove-alpine/providers/Microsoft.Network/publicIPAddresses/PARKCITY-Win11H-PublicIP) | ❌ Disabled | N/A | N/A | N/A | ❌ Fail |\n| [PARKCITY-Win11T-PublicIP](https://portal.azure.com/#resource/subscriptions/ab48f397-fc82-4634-aa52-62dd91b3ebaa/resourceGroups/woodgrove-alpine/providers/Microsoft.Network/publicIPAddresses/PARKCITY-Win11T-PublicIP) | ❌ Disabled | N/A | N/A | N/A | ❌ Fail |\n| [PARKCITY-Win11U-PublicIP](https://portal.azure.com/#resource/subscriptions/ab48f397-fc82-4634-aa52-62dd91b3ebaa/resourceGroups/woodgrove-alpine/providers/Microsoft.Network/publicIPAddresses/PARKCITY-Win11U-PublicIP) | ❌ Disabled | N/A | N/A | N/A | ❌ Fail |\n| [pip-alpine-sap-northeurope-default](https://portal.azure.com/#resource/subscriptions/ab48f397-fc82-4634-aa52-62dd91b3ebaa/resourceGroups/woodgrove-alpine/providers/Microsoft.Network/publicIPAddresses/pip-alpine-sap-northeurope-default) | VirtualNetworkInherited | Network Interface | alpine-sap | ❌ Disabled | ❌ Fail |\n| [pip-bastion-hub-eastus](https://portal.azure.com/#resource/subscriptions/3ee59f4f-e3f2-4ba5-bea7-f81409658ab8/resourceGroups/rg-hub-eastus/providers/Microsoft.Network/publicIPAddresses/pip-bastion-hub-eastus) | VirtualNetworkInherited | Azure Bastion | N/A | ❌ Disabled | ❌ Fail |\n| [pip-fw-hub-eastus](https://portal.azure.com/#resource/subscriptions/3ee59f4f-e3f2-4ba5-bea7-f81409658ab8/resourceGroups/rg-hub-eastus/providers/Microsoft.Network/publicIPAddresses/pip-fw-hub-eastus) | VirtualNetworkInherited | Azure Firewall | N/A | ❌ Disabled | ❌ Fail |\n| [pip-fw-hub-mgmt-eastus](https://portal.azure.com/#resource/subscriptions/3ee59f4f-e3f2-4ba5-bea7-f81409658ab8/resourceGroups/rg-hub-eastus/providers/Microsoft.Network/publicIPAddresses/pip-fw-hub-mgmt-eastus) | VirtualNetworkInherited | Azure Firewall | N/A | ❌ Disabled | ❌ Fail |\n| [pip-parkcity-vnet-westus3-subnet](https://portal.azure.com/#resource/subscriptions/ab48f397-fc82-4634-aa52-62dd91b3ebaa/resourceGroups/woodgrove-alpine/providers/Microsoft.Network/publicIPAddresses/pip-parkcity-vnet-westus3-subnet) | VirtualNetworkInherited | Network Interface | PARKCITY-VNET | ❌ Disabled | ❌ Fail |\n| [pip-parkcity-vnet-westus3-subnet2](https://portal.azure.com/#resource/subscriptions/ab48f397-fc82-4634-aa52-62dd91b3ebaa/resourceGroups/woodgrove-alpine/providers/Microsoft.Network/publicIPAddresses/pip-parkcity-vnet-westus3-subnet2) | ❌ Disabled | N/A | N/A | N/A | ❌ Fail |\n| [Sap-Lin1-IP](https://portal.azure.com/#resource/subscriptions/ab48f397-fc82-4634-aa52-62dd91b3ebaa/resourceGroups/SAPCAL-P2008374138-279145257/providers/Microsoft.Network/publicIPAddresses/Sap-Lin1-IP) | ❌ Disabled | N/A | N/A | N/A | ❌ Fail |\n| [Sap-SAP2-IP](https://portal.azure.com/#resource/subscriptions/ab48f397-fc82-4634-aa52-62dd91b3ebaa/resourceGroups/SAPCAL-P2008374138-279145257/providers/Microsoft.Network/publicIPAddresses/Sap-SAP2-IP) | ❌ Disabled | N/A | N/A | N/A | ❌ Fail |\n| [SAPCALDefault-westeurope-ip](https://portal.azure.com/#resource/subscriptions/ab48f397-fc82-4634-aa52-62dd91b3ebaa/resourceGroups/SAPCAL-Network-westeurope/providers/Microsoft.Network/publicIPAddresses/SAPCALDefault-westeurope-ip) | ❌ Disabled | N/A | N/A | N/A | ❌ Fail |\n| [SAPECC751-Lin1-IP](https://portal.azure.com/#resource/subscriptions/ab48f397-fc82-4634-aa52-62dd91b3ebaa/resourceGroups/SAPCAL-P2008644020-290118933/providers/Microsoft.Network/publicIPAddresses/SAPECC751-Lin1-IP) | ❌ Disabled | N/A | N/A | N/A | ❌ Fail |\n| [SAPECC751-SAP2-IP](https://portal.azure.com/#resource/subscriptions/ab48f397-fc82-4634-aa52-62dd91b3ebaa/resourceGroups/SAPCAL-P2008644020-290118933/providers/Microsoft.Network/publicIPAddresses/SAPECC751-SAP2-IP) | ❌ Disabled | N/A | N/A | N/A | ❌ Fail |\n| [Sentinel-Logstash-ip](https://portal.azure.com/#resource/subscriptions/ab48f397-fc82-4634-aa52-62dd91b3ebaa/resourceGroups/Woodgrove-RG/providers/Microsoft.Network/publicIPAddresses/Sentinel-Logstash-ip) | ❌ Disabled | N/A | N/A | N/A | ❌ Fail |\n| [server01-publicIp](https://portal.azure.com/#resource/subscriptions/855b095a-349d-42bf-b161-f93dc2438660/resourceGroups/Azure-resources/providers/Microsoft.Network/publicIPAddresses/server01-publicIp) | ❌ Disabled | N/A | N/A | N/A | ❌ Fail |\n| [server02-publicIp](https://portal.azure.com/#resource/subscriptions/855b095a-349d-42bf-b161-f93dc2438660/resourceGroups/Azure-resources/providers/Microsoft.Network/publicIPAddresses/server02-publicIp) | ❌ Disabled | N/A | N/A | N/A | ❌ Fail |\n| [server03-publicIp](https://portal.azure.com/#resource/subscriptions/855b095a-349d-42bf-b161-f93dc2438660/resourceGroups/Azure-resources/providers/Microsoft.Network/publicIPAddresses/server03-publicIp) | ❌ Disabled | N/A | N/A | N/A | ❌ Fail |\n| [squid-proxy-ip](https://portal.azure.com/#resource/subscriptions/ab48f397-fc82-4634-aa52-62dd91b3ebaa/resourceGroups/woodgrove-alpine/providers/Microsoft.Network/publicIPAddresses/squid-proxy-ip) | ❌ Disabled | N/A | N/A | N/A | ❌ Fail |\n| [vm-zava-linux-01-pip](https://portal.azure.com/#resource/subscriptions/ee301620-7f47-414b-97b7-9d84046f4d38/resourceGroups/rg-Zava-Resources-yxhw/providers/Microsoft.Network/publicIPAddresses/vm-zava-linux-01-pip) | VirtualNetworkInherited | Network Interface | vnet-zava-cloud-and-ai | ❌ Disabled | ❌ Fail |\n| [vm-zava-linux-01-pip](https://portal.azure.com/#resource/subscriptions/ee301620-7f47-414b-97b7-9d84046f4d38/resourceGroups/rg-Zava-Resources-489n/providers/Microsoft.Network/publicIPAddresses/vm-zava-linux-01-pip) | VirtualNetworkInherited | Network Interface | vnet-zava-cloud-and-ai | ❌ Disabled | ❌ Fail |\n| [vm-zava-windows-01-pip](https://portal.azure.com/#resource/subscriptions/ee301620-7f47-414b-97b7-9d84046f4d38/resourceGroups/rg-Zava-Resources-489n/providers/Microsoft.Network/publicIPAddresses/vm-zava-windows-01-pip) | VirtualNetworkInherited | Network Interface | vnet-zava-cloud-and-ai | ❌ Disabled | ❌ Fail |\n| [vm-zava-windows-01-pip](https://portal.azure.com/#resource/subscriptions/ee301620-7f47-414b-97b7-9d84046f4d38/resourceGroups/rg-Zava-Resources-yxhw/providers/Microsoft.Network/publicIPAddresses/vm-zava-windows-01-pip) | VirtualNetworkInherited | Network Interface | vnet-zava-cloud-and-ai | ❌ Disabled | ❌ Fail |\n| [WAFcopilotPIP](https://portal.azure.com/#resource/subscriptions/ab48f397-fc82-4634-aa52-62dd91b3ebaa/resourceGroups/Woodgrove-RG/providers/Microsoft.Network/publicIPAddresses/WAFcopilotPIP) | ❌ Disabled | N/A | N/A | N/A | ❌ Fail |\n| [WG-AADJ11-ip](https://portal.azure.com/#resource/subscriptions/ab48f397-fc82-4634-aa52-62dd91b3ebaa/resourceGroups/Woodgrove-RG/providers/Microsoft.Network/publicIPAddresses/WG-AADJ11-ip) | ❌ Disabled | N/A | N/A | N/A | ❌ Fail |\n| [WG-IoT-Sensor-ip](https://portal.azure.com/#resource/subscriptions/ab48f397-fc82-4634-aa52-62dd91b3ebaa/resourceGroups/Woodgrove-RG/providers/Microsoft.Network/publicIPAddresses/WG-IoT-Sensor-ip) | ❌ Disabled | N/A | N/A | N/A | ❌ Fail |\n| [WG-W11-Admin](https://portal.azure.com/#resource/subscriptions/ab48f397-fc82-4634-aa52-62dd91b3ebaa/resourceGroups/Woodgrove-RG/providers/Microsoft.Network/publicIPAddresses/WG-W11-Admin) | VirtualNetworkInherited | Network Interface | Woodgrove-vNet | ❌ Disabled | ❌ Fail |\n| [Win11LAPS-ip](https://portal.azure.com/#resource/subscriptions/ab48f397-fc82-4634-aa52-62dd91b3ebaa/resourceGroups/Woodgrove-RG/providers/Microsoft.Network/publicIPAddresses/Win11LAPS-ip) | ❌ Disabled | N/A | N/A | N/A | ❌ Fail |\n| [Woodgrove-aaddsAdmin-ip](https://portal.azure.com/#resource/subscriptions/ab48f397-fc82-4634-aa52-62dd91b3ebaa/resourceGroups/Woodgrove-RG/providers/Microsoft.Network/publicIPAddresses/Woodgrove-aaddsAdmin-ip) | ❌ Disabled | N/A | N/A | N/A | ❌ Fail |\n| [Woodgrove-aaddsAppServer-ip](https://portal.azure.com/#resource/subscriptions/ab48f397-fc82-4634-aa52-62dd91b3ebaa/resourceGroups/Woodgrove-RG/providers/Microsoft.Network/publicIPAddresses/Woodgrove-aaddsAppServer-ip) | ❌ Disabled | N/A | N/A | N/A | ❌ Fail |\n| [Woodgrove-AppProxy01-PublicIP](https://portal.azure.com/#resource/subscriptions/ab48f397-fc82-4634-aa52-62dd91b3ebaa/resourceGroups/Woodgrove-RG/providers/Microsoft.Network/publicIPAddresses/Woodgrove-AppProxy01-PublicIP) | ❌ Disabled | N/A | N/A | N/A | ❌ Fail |\n| [Woodgrove-FW01-ip](https://portal.azure.com/#resource/subscriptions/ab48f397-fc82-4634-aa52-62dd91b3ebaa/resourceGroups/Woodgrove-RG/providers/Microsoft.Network/publicIPAddresses/Woodgrove-FW01-ip) | ❌ Disabled | N/A | N/A | N/A | ❌ Fail |\n| [Woodgrove-FW02-ip](https://portal.azure.com/#resource/subscriptions/ab48f397-fc82-4634-aa52-62dd91b3ebaa/resourceGroups/Woodgrove-RG/providers/Microsoft.Network/publicIPAddresses/Woodgrove-FW02-ip) | ❌ Disabled | N/A | N/A | N/A | ❌ Fail |\n| [Woodgrove-FW03-ip](https://portal.azure.com/#resource/subscriptions/ab48f397-fc82-4634-aa52-62dd91b3ebaa/resourceGroups/Woodgrove-RG/providers/Microsoft.Network/publicIPAddresses/Woodgrove-FW03-ip) | ❌ Disabled | N/A | N/A | N/A | ❌ Fail |\n| [Woodgrove-FW04-ip](https://portal.azure.com/#resource/subscriptions/ab48f397-fc82-4634-aa52-62dd91b3ebaa/resourceGroups/Woodgrove-RG/providers/Microsoft.Network/publicIPAddresses/Woodgrove-FW04-ip) | ❌ Disabled | N/A | N/A | N/A | ❌ Fail |\n| [Woodgrove-FW05-ip](https://portal.azure.com/#resource/subscriptions/ab48f397-fc82-4634-aa52-62dd91b3ebaa/resourceGroups/Woodgrove-RG/providers/Microsoft.Network/publicIPAddresses/Woodgrove-FW05-ip) | ❌ Disabled | N/A | N/A | N/A | ❌ Fail |\n| [Woodgrove-FW06-ip](https://portal.azure.com/#resource/subscriptions/ab48f397-fc82-4634-aa52-62dd91b3ebaa/resourceGroups/Woodgrove-RG/providers/Microsoft.Network/publicIPAddresses/Woodgrove-FW06-ip) | ❌ Disabled | N/A | N/A | N/A | ❌ Fail |\n| [woodgrove-linux-pip](https://portal.azure.com/#resource/subscriptions/ab48f397-fc82-4634-aa52-62dd91b3ebaa/resourceGroups/woodgrove-MDC-RG/providers/Microsoft.Network/publicIPAddresses/woodgrove-linux-pip) | VirtualNetworkInherited | Network Interface | mdc-vNet | ❌ Disabled | ❌ Fail |\n| [Woodgrove-NPS-PubIP1](https://portal.azure.com/#resource/subscriptions/ab48f397-fc82-4634-aa52-62dd91b3ebaa/resourceGroups/Woodgrove-RG/providers/Microsoft.Network/publicIPAddresses/Woodgrove-NPS-PubIP1) | ❌ Disabled | N/A | N/A | N/A | ❌ Fail |\n| [Woodgrove-NPS01-ip](https://portal.azure.com/#resource/subscriptions/ab48f397-fc82-4634-aa52-62dd91b3ebaa/resourceGroups/Woodgrove-RG/providers/Microsoft.Network/publicIPAddresses/Woodgrove-NPS01-ip) | ❌ Disabled | N/A | N/A | N/A | ❌ Fail |\n| [Woodgrove-SCCM-ip](https://portal.azure.com/#resource/subscriptions/ab48f397-fc82-4634-aa52-62dd91b3ebaa/resourceGroups/Woodgrove-RG/providers/Microsoft.Network/publicIPAddresses/Woodgrove-SCCM-ip) | ❌ Disabled | N/A | N/A | N/A | ❌ Fail |\n| [woodgrove-sql-publicip-cuyfscoptzaku](https://portal.azure.com/#resource/subscriptions/ab48f397-fc82-4634-aa52-62dd91b3ebaa/resourceGroups/woodgrove-MDC-RG/providers/Microsoft.Network/publicIPAddresses/woodgrove-sql-publicip-cuyfscoptzaku) | ❌ Disabled | N/A | N/A | N/A | ❌ Fail |\n| [woodgrove-sqlvm1-publicip-5vjudoyk7ueta](https://portal.azure.com/#resource/subscriptions/ab48f397-fc82-4634-aa52-62dd91b3ebaa/resourceGroups/woodgrove-MDC-RG/providers/Microsoft.Network/publicIPAddresses/woodgrove-sqlvm1-publicip-5vjudoyk7ueta) | ❌ Disabled | N/A | N/A | N/A | ❌ Fail |\n| [woodgrove-srv-0-pip](https://portal.azure.com/#resource/subscriptions/ab48f397-fc82-4634-aa52-62dd91b3ebaa/resourceGroups/woodgrove-MDC-RG/providers/Microsoft.Network/publicIPAddresses/woodgrove-srv-0-pip) | VirtualNetworkInherited | Network Interface | mdc-vNet | ❌ Disabled | ❌ Fail |\n| [woodgrove-srv-1-pip](https://portal.azure.com/#resource/subscriptions/ab48f397-fc82-4634-aa52-62dd91b3ebaa/resourceGroups/woodgrove-MDC-RG/providers/Microsoft.Network/publicIPAddresses/woodgrove-srv-1-pip) | VirtualNetworkInherited | Network Interface | mdc-vNet | ❌ Disabled | ❌ Fail |\n| [woodgrove-srv-2-pip](https://portal.azure.com/#resource/subscriptions/ab48f397-fc82-4634-aa52-62dd91b3ebaa/resourceGroups/woodgrove-MDC-RG/providers/Microsoft.Network/publicIPAddresses/woodgrove-srv-2-pip) | VirtualNetworkInherited | Network Interface | mdc-vNet | ❌ Disabled | ❌ Fail |\n| [woodgrove-srv1-pip](https://portal.azure.com/#resource/subscriptions/ab48f397-fc82-4634-aa52-62dd91b3ebaa/resourceGroups/woodgrove-MDC-RG/providers/Microsoft.Network/publicIPAddresses/woodgrove-srv1-pip) | VirtualNetworkInherited | Network Interface | mdc-vNet | ❌ Disabled | ❌ Fail |\n| [Woodgrove-Subnet-publicIpAddress](https://portal.azure.com/#resource/subscriptions/ab48f397-fc82-4634-aa52-62dd91b3ebaa/resourceGroups/Woodgrove-RG/providers/Microsoft.Network/publicIPAddresses/Woodgrove-Subnet-publicIpAddress) | VirtualNetworkInherited | Network Interface | Woodgrove-vNet | ❌ Disabled | ❌ Fail |\n| [woodgrove-tunnel-ip](https://portal.azure.com/#resource/subscriptions/ab48f397-fc82-4634-aa52-62dd91b3ebaa/resourceGroups/Woodgrove-RG/providers/Microsoft.Network/publicIPAddresses/woodgrove-tunnel-ip) | VirtualNetworkInherited | Network Interface | Woodgrove-vNet | ❌ Disabled | ❌ Fail |\n| [woodgrove-ubuntu-ip](https://portal.azure.com/#resource/subscriptions/ab48f397-fc82-4634-aa52-62dd91b3ebaa/resourceGroups/Woodgrove-RG/providers/Microsoft.Network/publicIPAddresses/woodgrove-ubuntu-ip) | ❌ Disabled | N/A | N/A | N/A | ❌ Fail |\n| [Woodgrove-vNet-ip](https://portal.azure.com/#resource/subscriptions/ab48f397-fc82-4634-aa52-62dd91b3ebaa/resourceGroups/Woodgrove-RG/providers/Microsoft.Network/publicIPAddresses/Woodgrove-vNet-ip) | ❌ Disabled | N/A | N/A | N/A | ❌ Fail |\n| [woodgrove-windows-srv0-pip](https://portal.azure.com/#resource/subscriptions/ab48f397-fc82-4634-aa52-62dd91b3ebaa/resourceGroups/woodgrove-MDC-RG/providers/Microsoft.Network/publicIPAddresses/woodgrove-windows-srv0-pip) | VirtualNetworkInherited | Network Interface | mdc-vNet | ❌ Disabled | ❌ Fail |\n| [woodgrove-windows-srv1-pip](https://portal.azure.com/#resource/subscriptions/ab48f397-fc82-4634-aa52-62dd91b3ebaa/resourceGroups/woodgrove-MDC-RG/providers/Microsoft.Network/publicIPAddresses/woodgrove-windows-srv1-pip) | VirtualNetworkInherited | Network Interface | mdc-vNet | ❌ Disabled | ❌ Fail |\n| [woodgrove-windows-srv2-pip](https://portal.azure.com/#resource/subscriptions/ab48f397-fc82-4634-aa52-62dd91b3ebaa/resourceGroups/woodgrove-MDC-RG/providers/Microsoft.Network/publicIPAddresses/woodgrove-windows-srv2-pip) | VirtualNetworkInherited | Network Interface | mdc-vNet | ❌ Disabled | ❌ Fail |\n| [pip-vgw-hub-vpn-eastus-001](https://portal.azure.com/#resource/subscriptions/3ee59f4f-e3f2-4ba5-bea7-f81409658ab8/resourceGroups/rg-hub-eastus/providers/Microsoft.Network/publicIPAddresses/pip-vgw-hub-vpn-eastus-001) | VirtualNetworkInherited | Virtual Network Gateway | vnet-hub-eastus | ✅ Enabled | ✅ Pass |\n| [pip-vgw-hub-vpn-eastus-002](https://portal.azure.com/#resource/subscriptions/3ee59f4f-e3f2-4ba5-bea7-f81409658ab8/resourceGroups/rg-hub-eastus/providers/Microsoft.Network/publicIPAddresses/pip-vgw-hub-vpn-eastus-002) | VirtualNetworkInherited | Virtual Network Gateway | vnet-hub-eastus | ✅ Enabled | ✅ Pass |\n\r\n\r\n","SkippedReason":null,"TestMinimumLicense":["DDoS_Network_Protection","DDoS_IP_Protection"],"TestAppliesTo":null,"TestTags":null,"TestSfiPillar":"Protect networks","TestImplementationCost":"Low","TestSkipped":"","TestPillar":"Network","TestTitle":"DDoS Protection is enabled for all Public IP Addresses in VNETs","TestStatus":"Failed","TestDescription":"DDoS attacks remain a major security and availability risk for customers with cloud-hosted applications. These attacks aim to overwhelm an application's compute, network, or memory resources, rendering it inaccessible to legitimate users. Any public-facing endpoint exposed to the internet can be a potential target for a DDoS attack. Azure DDoS Protection provides always-on monitoring and automatic mitigation against DDoS attacks targeting public-facing workloads.\r\n\r\nWithout Azure DDoS Protection (Network Protection or IP Protection), public IP addresses for services such as Application Gateways, Load Balancers, Azure Firewalls, Azure Bastion, Virtual Network Gateways, or virtual machines remain exposed to DDoS attacks that can overwhelm network bandwidth, exhaust system resources, and cause complete service unavailability. These attacks can disrupt access for legitimate users, degrade performance, and create cascading outages across dependent services.\r\n\r\nAzure DDoS Protection can be enabled in two ways:\r\n\r\n- DDoS IP Protection — Protection is explicitly enabled on individual public IP addresses by setting ddosSettings.protectionMode to Enabled.\r\n- DDoS Network Protection — Protection is enabled at the VNET level through a DDoS Protection Plan. Public IP addresses associated with resources in that VNET inherit the protection when ddosSettings.protectionMode is set to VirtualNetworkInherited. However, a public IP address with VirtualNetworkInherited is not protected unless the VNET actually has a DDoS Protection Plan associated and enableDdosProtection set to true.\r\nThis check verifies that every public IP address is actually covered by DDoS protection, either through DDoS IP Protection enabled directly on the public IP, or through DDoS Network Protection enabled on the VNET that the public IP's associated resource resides in. If this check does not pass, your workloads remain significantly more vulnerable to downtime, customer impact, and operational disruption during an attack.\r\n\r\n**Remediation action**\r\n\r\nTo enable DDoS Protection for public IP addresses, refer to the following Microsoft Learn documentation:\r\n\r\n- [Azure DDoS Protection overview](https://learn.microsoft.com/en-us/azure/ddos-protection/ddos-protection-overview)\r\n- [Quickstart: Create and configure Azure DDoS Network Protection using Azure portal](https://learn.microsoft.com/en-us/azure/ddos-protection/manage-ddos-protection)\r\n- [Quickstart: Create and configure Azure DDoS IP Protection using Azure portal](https://learn.microsoft.com/en-us/azure/ddos-protection/manage-ddos-ip-protection-portal)\r\n- [Azure DDoS Protection SKU comparison](https://learn.microsoft.com/en-us/azure/ddos-protection/ddos-protection-sku-comparison)\r\n\r\n","TestRisk":"High"},{"TestTitle":"On-demand scans are configured for sensitive information discovery","TestSkipped":"NotConnectedToService","TestResult":"\r\nSkipped. This test requires connection to the service(s) \"SecurityCompliance\" currently disconnected. Please use _Connect-ZtAssessment_ to connect.\r\n\r\n","TestSfiPillar":"Protect tenants and production systems","TestStatus":"Skipped","TestImpact":"Low","TestPillar":"AI","TestId":"35022","TestRisk":"Medium","TestDescription":"Items in SharePoint, OneDrive and on Devices are evaluated and classified when they're edited or touched. If they aren't edited and they are in scope of a Microsoft Purview policy, they remain unclassified and invisible to Microsoft Purview policies. On-demand scans let you manually trigger evaluation of items across specified SharePoint, OneDrive, or Devices locations to discover and classify historical content. This can provide you with a more complete view of your information protection posture.\r\n\r\n**Remediation action**\r\n\r\n- [On-demand classification in Microsoft Purview](https://learn.microsoft.com/purview/on-demand-classification?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci)\r\n","TestTags":null,"TestMinimumLicense":["EXCHANGE_S_ENTERPRISE"],"SkippedReason":"This test requires connection to the service(s) \"SecurityCompliance\" currently disconnected. Please use _Connect-ZtAssessment_ to connect.","TestAppliesTo":null,"TestImplementationCost":"Medium","TestCategory":"Information Protection"},{"TestTitle":"Auto-labeling policies are in enforcement mode","TestSkipped":"NotConnectedToService","TestResult":"\r\nSkipped. This test requires connection to the service(s) \"SecurityCompliance\" currently disconnected. Please use _Connect-ZtAssessment_ to connect.\r\n\r\n","TestSfiPillar":"Protect tenants and production systems","TestStatus":"Skipped","TestImpact":"Low","TestPillar":"AI","TestId":"35020","TestRisk":"High","TestDescription":"When auto-labeling policies are left in simulation mode, you're not realizing the protection from labeling that data. As a result, users and services can't take additional protective measures to safeguard the identified sensitive data. For example, users won't see in their Office apps that a file is labeled Highly Confidential. Data loss prevention rules might use sensitivity labels to prevent sharing with external users, and other risky actions. Labeled data also provides an additional layer of protection when you use Microsoft 365 Copilot.\r\n\r\nTo ensure sensitive information is automatically labeled, turn on at least one auto-labeling policy. Turning on auto-labeling policies after simulation testing puts protective measures into effect and starts reducing risk.\r\n\r\n**Remediation action**\r\n\r\n- [How to configure auto-labeling policies for SharePoint, OneDrive, and Exchange](https://learn.microsoft.com/purview/apply-sensitivity-label-automatically?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci#how-to-configure-auto-labeling-policies-for-sharepoint-onedrive-and-exchange)\r\n","TestTags":null,"TestMinimumLicense":["EXCHANGE_S_ENTERPRISE"],"SkippedReason":"This test requires connection to the service(s) \"SecurityCompliance\" currently disconnected. Please use _Connect-ZtAssessment_ to connect.","TestAppliesTo":null,"TestImplementationCost":"Low","TestCategory":"Information Protection"},{"TestTitle":"Auto-labeling policies are configured for all Microsoft 365 workloads","TestSkipped":"NotConnectedToService","TestResult":"\r\nSkipped. This test requires connection to the service(s) \"SecurityCompliance\" currently disconnected. Please use _Connect-ZtAssessment_ to connect.\r\n\r\n","TestSfiPillar":"Protect tenants and production systems","TestStatus":"Skipped","TestImpact":"Low","TestPillar":"AI","TestId":"35019","TestRisk":"High","TestDescription":"Auto-labeling greatly extends your labeling reach, by automatically labeling items based on content inspection. When you rely on just manual labeling, users might not always recognize what counts as sensitive data or might forget to label information during their daily tasks. Default labels offer a baseline of protection but don't take into consideration content that requires a higher level of protection. This leads to gaps in classification, allowing sensitive content to move through Microsoft 365 applications without proper labels or protection.\r\n\r\nYou can configure auto-labeling settings for labels that trigger when users open files in their Office apps, and auto-labeling policies that require no user interactions. Setting up at least one auto-labeling policy to detect sensitive content automatically labels this content, no matter what actions people take. In turn, this labeled content can be used with other Microsoft Purview solutions to increase your security, such as data loss prevention (DLP) rules and access restrictions.\r\n\r\n**Remediation action**\r\n\r\n- [Automatically apply a sensitivity label to Microsoft 365 data](https://learn.microsoft.com/purview/apply-sensitivity-label-automatically?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci)\r\n","TestTags":null,"TestMinimumLicense":["EXCHANGE_S_ENTERPRISE"],"SkippedReason":"This test requires connection to the service(s) \"SecurityCompliance\" currently disconnected. Please use _Connect-ZtAssessment_ to connect.","TestAppliesTo":null,"TestImplementationCost":"Medium","TestCategory":"Information Protection"},{"TestId":"25413","TestCategory":"Global Secure Access","TestImpact":"Medium","TestResult":"\r\n❌ File policies are either not configured or not linked to an active filtering profile, leaving file transfers unmonitored and exposing the organization to data exfiltration risk.\n\n\r\n## [File Policy Configuration](https://entra.microsoft.com/#view/Microsoft_Azure_Network_Access/SecurityFiltering.ReactView)\r\n\r\n| File Policy Name | Default Action |\r\n| :--------------- | :------------- |\r\n| [File policy](https://entra.microsoft.com/#view/Microsoft_Azure_Network_Access/EditFilePolicyMenuBlade.MenuView/~/basics/policyId/48697ad5-b760-4b38-8837-f8bf86748be1) | allow |\n\r\n## [Filtering Profile Linkage](https://entra.microsoft.com/#view/Microsoft_Azure_Network_Access/SecurityProfiles.ReactView)\r\n\r\n| Linked Profile Name | Profile State | Policy Link State |\r\n| :------------------ | :------------ | :---------------- |\r\n| [ZAVA_AI-Profile](https://entra.microsoft.com/#view/Microsoft_Azure_Network_Access/EditProfileMenuBlade.MenuView/~/basics/profileId/84ae7f47-ef74-424e-a2d7-ee449f34bc2b) | enabled | enabled |\n\r\n\r\n","SkippedReason":null,"TestMinimumLicense":"Entra_Premium_Internet_Access","TestAppliesTo":null,"TestTags":null,"TestSfiPillar":"Protect networks","TestImplementationCost":"High","TestSkipped":"","TestPillar":"Network","TestTitle":"File transfer policies are configured to prevent data exfiltration","TestStatus":"Failed","TestDescription":"Without network content filtering policies configured in Global Secure Access, threat actors can exfiltrate data to unsanctioned destinations through browsers, applications, and APIs. File sharing services, cloud storage providers, and peer-to-peer transfer sites remain unrestricted when you don't implement network content filtering policies.\r\n\r\nWithout this protection:\r\n\r\n- Threat actors can upload files containing intellectual property, credentials, or customer data to external services without detection.\r\n- Unmanaged cloud applications and generative AI tools become exfiltration channels for sensitive information.\r\n- The network layer lacks real-time data protection enforcement, allowing threat actors to bypass endpoint-based controls.\r\n- Threat actors can disguise malicious payloads or sensitive data within common file formats and transfer them across the network perimeter undetected.\r\n\r\n**Remediation action**\r\n\r\n- [Configure Global Secure Access web content filtering](https://learn.microsoft.com/entra/global-secure-access/how-to-configure-web-content-filtering?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci), including file policies to monitor and control file transfers.\r\n- [Enable and manage the Microsoft traffic forwarding profile](https://learn.microsoft.com/entra/global-secure-access/how-to-manage-microsoft-profile?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci) that group filtering policies for enforcement through Conditional Access.\r\n- [Link security profiles to Conditional Access policies](https://learn.microsoft.com/entra/identity/conditional-access/concept-conditional-access-session?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci) for user-aware and context-aware enforcement of network security policies.\r\n- [Install the Global Secure Access client](https://learn.microsoft.com/entra/global-secure-access/how-to-install-windows-client?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci) on end-user devices to enable traffic acquisition and policy enforcement.\r\n","TestRisk":"High"},{"TestTitle":"TLS inspection failure rate remains below 1% to ensure consistent traffic visibility","TestSkipped":"","TestResult":"\r\n✅ No TLS-intercepted traffic was found in the last 7 days. TLS inspection policies exist but no traffic was intercepted during the evaluation period.\n\n\r\n## [TLS inspection health summary](https://entra.microsoft.com/#view/Microsoft_Azure_Network_Access/TLSInspectionPolicy.ReactView)\r\n\r\n| Metric | Value |\r\n| :--- | :--- |\r\n| Evaluation period | Last 7 days |\r\n| Log Analytics workspace | [woodgrove-loganalyiticsworkspace](https://portal.azure.com/#resource/subscriptions/ab48f397-fc82-4634-aa52-62dd91b3ebaa/resourcegroups/woodgrove-rg/providers/microsoft.operationalinsights/workspaces/woodgrove-loganalyiticsworkspace/overview) |\r\n| Total intercepted transactions | 0 |\r\n| Successful inspections | 0 |\r\n| Failed inspections | 0 |\r\n| Failure rate | 0% |\r\n| Status | Pass |\r\n\r\n\r\n","TestSfiPillar":"Protect networks","TestStatus":"Passed","TestImpact":"Medium","TestPillar":"Network","TestId":"27003","TestRisk":"High","TestDescription":"By using Transport Layer Security (TLS) inspection, Global Secure Access can decrypt encrypted HTTPS traffic and check it for threats, malicious content, and policy violations. If TLS inspection fails for a connection, that traffic bypasses security controls. Inspection failures can let potential malware delivery, command-and-control communications, or data exfiltration go undetected.\r\n\r\nFailure rates above 1% point to systemic problems. These problems include certificate trust issues on endpoints, incompatible applications that use certificate pinning without proper bypass rules, or certificate authority configuration errors. Threat actors can also intentionally create connections that cause TLS inspection failures.\r\n\r\n**Remediation action**\r\n\r\n- [Configure diagnostic settings to export traffic logs](https://learn.microsoft.com/entra/global-secure-access/how-to-view-traffic-logs?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci#configure-diagnostic-settings-to-export-logs) to a Log Analytics workspace. Use these logs to monitor TLS inspection success rates and investigate the root causes of failures.\r\n- Follow the steps in [Troubleshoot Global Secure Access Transport Layer Security inspection errors](https://learn.microsoft.com/entra/global-secure-access/troubleshoot-transport-layer-security?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci) to resolve common inspection failures.\r\n- For destinations with certificate pinning, [add TLS bypass rules](https://learn.microsoft.com/entra/global-secure-access/how-to-transport-layer-security?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci) to reduce failure rates while keeping inspection for other traffic.\r\n","TestTags":null,"TestMinimumLicense":["Entra_Premium_Internet_Access"],"SkippedReason":null,"TestAppliesTo":null,"TestImplementationCost":"Medium","TestCategory":"Global Secure Access"},{"TestTitle":"Super user membership is configured for Microsoft Purview Information Protection","TestSkipped":"","TestResult":"\r\n❌ Super user feature is disabled with no members configured, OR feature is enabled with no members.\n\n## Azure Information Protection Super User Configuration\n\n**Super User Feature:** Disabled\n\n**Super Users Configured:** 0\n\n**Note:** Super user configuration is not available through the Azure portal and must be managed via PowerShell using the AipService module.\n\r\n\r\n","TestSfiPillar":"Protect tenants and production systems","TestStatus":"Failed","TestImpact":"Low","TestPillar":"AI","TestId":"35011","TestRisk":"Medium","TestDescription":"The super user feature of the Azure Rights Management service grants designated accounts the ability to decrypt content your organization has encrypted by using this service, regardless of the original permissions assigned. Super users might be necessary for eDiscovery, data recovery, compliance investigations, and content migration. The super user feature ensures that authorized people and services can always read and inspect the data that the Azure Rights Management service encrypts for your organization.\r\n\r\nWhen you use a group to designate super user accounts, membership of that group must be carefully controlled and limited, for example, to service accounts used by compliance tools or eDiscovery platforms. Unless you have a feature or business need that requires the feature to be enabled all the time, Microsoft recommends keeping the feature disabled by default, and enabling it only when needed. When you use a group to designate super user accounts, use Microsoft Entra Privileged Identity Management (PIM) to reduce risk by enabling just‑in‑time access when required and minimizing permanent privilege.\r\n\r\n**Remediation action**\r\n\r\n- [Configure Azure Rights Management super users for discovery services or data recovery](https://learn.microsoft.com/purview/encryption-super-users?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci#security-best-practices-for-the-super-user-feature)\r\n","TestTags":null,"TestMinimumLicense":["RMS_S_PREMIUM2"],"SkippedReason":null,"TestAppliesTo":null,"TestImplementationCost":"Medium","TestCategory":"Advanced Label Features"},{"TestId":"26887","TestCategory":"Azure Network Security","TestImpact":"Low","TestResult":"\r\n✅ Diagnostic logging is enabled for Azure Firewall with active log collection configured.\n\n\n## [Azure Firewall diagnostic logging status](https://portal.azure.com/#browse/Microsoft.Network%2FazureFirewalls)\n\n| Subscription | Firewall name | Location | Diagnostic settings count | Destination configured | Enabled log categories | Status |\r\n| :--- | :--- | :--- | :--- | :--- | :--- | :--- |\r\n| [Network Security](https://portal.azure.com/#resource/subscriptions/3ee59f4f-e3f2-4ba5-bea7-f81409658ab8/overview) | [fw-hub-eastus](https://portal.azure.com/#resource/subscriptions/3ee59f4f-e3f2-4ba5-bea7-f81409658ab8/resourceGroups/rg-hub-eastus/providers/Microsoft.Network/azureFirewalls/fw-hub-eastus/diagnostics) | eastus | 1 | Yes | allLogs | ✅ Pass |\n| [Woodgrove - GTP Demos (External/Sponsored)](https://portal.azure.com/#resource/subscriptions/ab48f397-fc82-4634-aa52-62dd91b3ebaa/overview) | [fw-Woodgrove-vNet](https://portal.azure.com/#resource/subscriptions/ab48f397-fc82-4634-aa52-62dd91b3ebaa/resourceGroups/Woodgrove-RG/providers/Microsoft.Network/azureFirewalls/fw-Woodgrove-vNet/diagnostics) | westus2 | 2 | Yes | AZFWNetworkRule, AZFWApplicationRule, AZFWNatRule, AZFWThreatIntel, AZFWIdpsSignature, AZFWDnsQuery, AZFWFqdnResolveFailure, AZFWFatFlow, AZFWFlowTrace, AZFWApplicationRuleAggregation, AZFWNetworkRuleAggregation, AZFWNatRuleAggregation, AzureFirewallApplicationRule, AzureFirewallNetworkRule, AzureFirewallDnsProxy | ✅ Pass |\n| [Woodgrove - GTP Demos (External/Sponsored)](https://portal.azure.com/#resource/subscriptions/ab48f397-fc82-4634-aa52-62dd91b3ebaa/overview) | [fw-Woodgrove-vNet1](https://portal.azure.com/#resource/subscriptions/ab48f397-fc82-4634-aa52-62dd91b3ebaa/resourceGroups/Woodgrove-RG/providers/Microsoft.Network/azureFirewalls/fw-Woodgrove-vNet1/diagnostics) | westus2 | 2 | Yes | AZFWNetworkRule, AZFWApplicationRule, AZFWNatRule, AZFWThreatIntel, AZFWIdpsSignature, AZFWDnsQuery, AZFWFqdnResolveFailure, AZFWFatFlow, AZFWFlowTrace, AZFWApplicationRuleAggregation, AZFWNetworkRuleAggregation, AZFWNatRuleAggregation, AzureFirewallApplicationRule, AzureFirewallNetworkRule, AzureFirewallDnsProxy | ✅ Pass |\n| [Woodgrove - GTP Demos (External/Sponsored)](https://portal.azure.com/#resource/subscriptions/ab48f397-fc82-4634-aa52-62dd91b3ebaa/overview) | [fw-Woodgrove-vNet2](https://portal.azure.com/#resource/subscriptions/ab48f397-fc82-4634-aa52-62dd91b3ebaa/resourceGroups/Woodgrove-RG/providers/Microsoft.Network/azureFirewalls/fw-Woodgrove-vNet2/diagnostics) | westus2 | 2 | Yes | AZFWNetworkRule, AZFWApplicationRule, AZFWNatRule, AZFWThreatIntel, AZFWIdpsSignature, AZFWDnsQuery, AZFWFqdnResolveFailure, AZFWFatFlow, AZFWFlowTrace, AZFWApplicationRuleAggregation, AZFWNetworkRuleAggregation, AZFWNatRuleAggregation, AzureFirewallApplicationRule, AzureFirewallNetworkRule, AzureFirewallDnsProxy | ✅ Pass |\n\r\n**Summary:**\n\n- Total Azure Firewalls evaluated: 4\n- Firewalls with diagnostic logging enabled: 4\n- Firewalls without diagnostic logging: 0\n\r\n","SkippedReason":null,"TestMinimumLicense":["Azure_Firewall_Standard","Azure_Firewall_Premium"],"TestAppliesTo":null,"TestTags":null,"TestSfiPillar":"Monitor and detect cyberthreats","TestImplementationCost":"Low","TestSkipped":"","TestPillar":"Network","TestTitle":"Diagnostic logging is enabled in Azure Firewall","TestStatus":"Passed","TestDescription":"Azure Firewall processes all inbound and outbound network traffic for protected workloads, making it a critical control point for network security monitoring. When diagnostic logging is not enabled, security operations teams lose visibility into traffic patterns, denied connection attempts, threat intelligence matches, and IDPS signature detections. A threat actor who gains initial access to an environment can move laterally through the network without detection because no firewall logs are being captured or analyzed. The absence of logging prevents correlation of network events with other security telemetry, eliminating the ability to construct attack timelines during incident investigations. Furthermore, compliance frameworks such as PCI-DSS, HIPAA, and SOC 2 require organizations to maintain audit logs of network security events, and the lack of firewall diagnostic logging creates audit failures. Azure Firewall provides multiple log categories including application rule logs, network rule logs, NAT rule logs, threat intelligence logs, IDPS signature logs, and DNS proxy logs, all of which must be routed to a destination such as Log Analytics, Storage Account, or Event Hub to enable security monitoring and forensic analysis.\r\n\r\n**Remediation action**\r\n\r\nCreate a Log Analytics workspace for storing Azure Firewall logs\r\n- [Create a Log Analytics workspace](https://learn.microsoft.com/en-us/azure/azure-monitor/logs/quick-create-workspace)\r\n\r\nConfigure diagnostic settings for Azure Firewall to enable log collection\r\n- [Create diagnostic settings in Azure Monitor](https://learn.microsoft.com/en-us/azure/azure-monitor/essentials/create-diagnostic-settings)\r\n\r\nEnable structured logs (resource-specific mode) for improved query performance and cost optimization\r\n- [Azure Firewall structured logs](https://learn.microsoft.com/en-us/azure/firewall/monitor-firewall#structured-azure-firewall-logs)\r\n\r\nUse Azure Firewall Workbook for visualizing and analyzing firewall logs\r\n- [Azure Firewall Workbook](https://learn.microsoft.com/en-us/azure/firewall/firewall-workbook)\r\n\r\nMonitor Azure Firewall metrics and logs for security operations\r\n- [Monitor Azure Firewall](https://learn.microsoft.com/en-us/azure/firewall/monitor-firewall)\r\n\r\n","TestRisk":"High"},{"TestId":"27020","TestCategory":"Azure Network Security","TestImpact":"Medium","TestResult":"\r\n❌ One or more Azure Front Door WAF policies attached to Azure Front Door are either disabled, not in Prevention mode, or do not have CAPTCHA challenge rules configured and enabled, leaving applications without interactive human verification against sophisticated automated bots at the global edge.\n\n\n## [Azure Front Door WAF policies](https://portal.azure.com/#browse/Microsoft.Network%2FfrontdoorWebApplicationFirewallPolicies)\n\n| Policy name | Subscription name | Enabled state | WAF mode | CAPTCHA challenge rules count | Rule state | CAPTCHA expiration (mins) | Status |\r\n| :--- | :--- | :--- | :--- | :--- | :--- | :--- | :--- |\r\n| [AFDCopilotWAFPolicy](https://portal.azure.com/#resource/subscriptions/ab48f397-fc82-4634-aa52-62dd91b3ebaa/resourceGroups/Woodgrove-RG/providers/Microsoft.Network/frontdoorWebApplicationFirewallPolicies/AFDCopilotWAFPolicy) | [Woodgrove - GTP Demos (External/Sponsored)](https://portal.azure.com/#resource/subscriptions/ab48f397-fc82-4634-aa52-62dd91b3ebaa/overview) | ✅ Enabled | ✅ Prevention | ❌ 0 | N/A | 30 | ❌ Fail |\n\r\n\r\n","SkippedReason":null,"TestMinimumLicense":"Azure WAF","TestAppliesTo":null,"TestTags":null,"TestSfiPillar":"Protect networks","TestImplementationCost":"Low","TestSkipped":"","TestPillar":"Network","TestTitle":"CAPTCHA challenge is enabled in Azure Front Door WAF","TestStatus":"Failed","TestDescription":"Azure Front Door Web Application Firewall (WAF) supports CAPTCHA challenge as a defense mechanism against sophisticated bots and automated tools across the global edge network. CAPTCHA challenge works by presenting users with a visual or audio puzzle that requires human cognitive ability to solve, proving that the request originates from a real human rather than an automated bot or script. When a request triggers a CAPTCHA challenge, the WAF responds with a challenge page containing the CAPTCHA puzzle that the user must solve to obtain a valid challenge cookie. If the user successfully completes the CAPTCHA, subsequent requests proceed normally until the cookie expires. Bots and automated tools that cannot solve the CAPTCHA puzzle are blocked from accessing protected resources at the edge before traffic reaches origin servers. CAPTCHA challenge is more effective than JavaScript challenge against advanced bots that use headless browsers with full JavaScript support, as it requires human-level cognition to pass. The `captchaExpirationInMinutes` setting in the policy controls how long the CAPTCHA cookie remains valid before the user must complete another challenge. CAPTCHA challenge provides the strongest level of interactive verification available in Azure Front Door WAF—it confirms human presence through an interactive puzzle rather than only verifying browser capability like JavaScript challenge. By configuring custom rules with CAPTCHA challenge action on Azure Front Door WAF, organizations can protect highly sensitive endpoints like login pages, registration forms, password reset flows, and payment pages from automated abuse while ensuring that only verified humans can access these resources across globally distributed edge locations.\r\n\r\n**Remediation action**\r\n\r\n- [Azure Web Application Firewall on Azure Front Door](https://learn.microsoft.com/en-us/azure/web-application-firewall/afds/afds-overview)\r\n- [Web Application Firewall custom rules for Azure Front Door](https://learn.microsoft.com/en-us/azure/web-application-firewall/afds/waf-front-door-custom-rules)\r\n- [Tutorial: Create a Web Application Firewall policy on Azure Front Door](https://learn.microsoft.com/en-us/azure/web-application-firewall/afds/waf-front-door-create-portal)\r\n- [Configure CAPTCHA challenge for Azure Front Door WAF](https://learn.microsoft.com/en-us/azure/web-application-firewall/afds/waf-front-door-tuning#captcha-challenge)\r\n\r\n","TestRisk":"Medium"},{"TestId":"26885","TestCategory":"Azure Network Security","TestImpact":"Low","TestResult":"\r\n❌ Metrics are not enabled for one or more DDoS-protected public IP addresses.\n\n\n## [DDoS-protected Public IP metrics status](https://portal.azure.com/#view/HubsExtension/BrowseResource/resourceType/Microsoft.Network%2FpublicIPAddresses)\n\n| Public IP name | Resource Group | Subscription | IP address | Protection type | Associated resource | Associated VNET | Metrics enabled | Log Analytics workspace | Status |\r\n| :--- | :--- | :--- | :--- | :--- | :--- | :--- | :--- | :--- | :--- |\r\n| [pip-bastion-hub-eastus](https://portal.azure.com/#resource/subscriptions/3ee59f4f-e3f2-4ba5-bea7-f81409658ab8/resourceGroups/rg-hub-eastus/providers/Microsoft.Network/publicIPAddresses/pip-bastion-hub-eastus/diagnostics) | rg-hub-eastus | Network Security | 203.0.113.13 | Network Protection | Azure Bastion | vnet-hub-eastus | ❌ No | N/A | ❌ Fail |\n| [pip-fw-hub-eastus](https://portal.azure.com/#resource/subscriptions/3ee59f4f-e3f2-4ba5-bea7-f81409658ab8/resourceGroups/rg-hub-eastus/providers/Microsoft.Network/publicIPAddresses/pip-fw-hub-eastus/diagnostics) | rg-hub-eastus | Network Security | 203.0.113.14 | Network Protection | Azure Firewall | vnet-hub-eastus | ❌ No | N/A | ❌ Fail |\n| [pip-vgw-hub-vpn-eastus-001](https://portal.azure.com/#resource/subscriptions/3ee59f4f-e3f2-4ba5-bea7-f81409658ab8/resourceGroups/rg-hub-eastus/providers/Microsoft.Network/publicIPAddresses/pip-vgw-hub-vpn-eastus-001/diagnostics) | rg-hub-eastus | Network Security | 203.0.113.15 | Network Protection | Virtual Network Gateway | vnet-hub-eastus | ❌ No | N/A | ❌ Fail |\n| [pip-vgw-hub-vpn-eastus-002](https://portal.azure.com/#resource/subscriptions/3ee59f4f-e3f2-4ba5-bea7-f81409658ab8/resourceGroups/rg-hub-eastus/providers/Microsoft.Network/publicIPAddresses/pip-vgw-hub-vpn-eastus-002/diagnostics) | rg-hub-eastus | Network Security | 203.0.113.16 | Network Protection | Virtual Network Gateway | vnet-hub-eastus | ❌ No | N/A | ❌ Fail |\n\r\n**Summary:**\n\n- Total DDoS-protected Public IPs evaluated: 4\n- Public IPs with metrics enabled: 0\n- Public IPs missing metrics: 4\n\r\n","SkippedReason":null,"TestMinimumLicense":["DDoS_Network_Protection","DDoS_IP_Protection"],"TestAppliesTo":null,"TestTags":null,"TestSfiPillar":"Monitor and detect cyberthreats","TestImplementationCost":"Low","TestSkipped":"","TestPillar":"Network","TestTitle":"Metrics are enabled for DDoS-protected public IPs","TestStatus":"Failed","TestDescription":"When Azure DDoS Protection is enabled for public IP addresses, enabling metrics provides essential real-time visibility into attack activity, mitigation effectiveness, and traffic patterns. Without metrics enabled on DDoS-protected public IPs, security teams lack the telemetry needed to detect ongoing attacks, validate that mitigation policies are working, and perform capacity planning. Azure DDoS Protection emits metrics such as \"Under DDoS attack or not\", inbound packets and bytes processed, packets and bytes dropped during mitigation, and TCP/UDP/SYN flood counters. These metrics are foundational for alerting, dashboards, and post-incident analysis. The absence of metrics prevents correlation of DDoS events with application performance issues and eliminates the ability to analyze attack patterns for proactive defense improvements. This check identifies all public IP addresses that are actually DDoS-protected — either through DDoS IP Protection enabled directly on the public IP, or through DDoS Network Protection inherited from a VNET that has a DDoS Protection Plan associated — and verifies that diagnostic settings are configured to capture metrics for security monitoring.\r\n\r\n**Remediation action**\r\n\r\nEnable metrics in diagnostic settings for DDoS-protected public IP addresses\r\n- [Azure DDoS Protection metrics and alerts](https://learn.microsoft.com/en-us/azure/ddos-protection/ddos-diagnostic-logs)\r\n\r\nConfigure diagnostic settings for Azure resources\r\n- [Configure diagnostic settings for Azure resources](https://learn.microsoft.com/en-us/azure/azure-monitor/essentials/diagnostic-settings)\r\n\r\nReview DDoS Protection capabilities and overview\r\n- [Azure DDoS Protection overview](https://learn.microsoft.com/en-us/azure/ddos-protection/ddos-protection-overview)\r\n\r\nEnable DDoS Network Protection on virtual networks\r\n- [Quickstart: Create and configure Azure DDoS Network Protection using Azure portal](https://learn.microsoft.com/en-us/azure/ddos-protection/manage-ddos-protection)\r\n\r\n","TestRisk":"Medium"},{"TestTitle":"Email label policies inherit sensitivity from attachments","TestSkipped":"NotConnectedToService","TestResult":"\r\nSkipped. This test requires connection to the service(s) \"SecurityCompliance\" currently disconnected. Please use _Connect-ZtAssessment_ to connect.\r\n\r\n","TestSfiPillar":"Protect tenants and production systems","TestStatus":"Skipped","TestImpact":"High","TestPillar":"AI","TestId":"35014","TestRisk":"Medium","TestDescription":"When users attach sensitive documents to emails, the email should inherit the highest sensitivity label from attachments to maintain consistent protection. Without this setting enabled, users might send unlabeled emails that contain sensitive attachments, creating a mismatch between the email's sensitivity and its actual content.\r\n\r\nEmail label inheritance automatically applies the attachment's highest priority label to the email message, ensuring protection levels match and prevent accidental data exposure.\r\n\r\n**Remediation action**\r\n\r\n- [Publish sensitivity labels](https://learn.microsoft.com/purview/create-sensitivity-labels?tabs=modern-label-scheme&wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci#publish-sensitivity-labels-by-creating-a-label-policy) to [Configure label inheritance from email attachments](https://learn.microsoft.com/purview/sensitivity-labels-office-apps?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci#configure-label-inheritance-from-email-attachments).\r\n","TestTags":null,"TestMinimumLicense":["RMS_S_PREMIUM"],"SkippedReason":"This test requires connection to the service(s) \"SecurityCompliance\" currently disconnected. Please use _Connect-ZtAssessment_ to connect.","TestAppliesTo":null,"TestImplementationCost":"Low","TestCategory":"Label Policy Configuration"},{"TestTitle":"OCR is enabled for sensitive information detection","TestSkipped":"NotConnectedToService","TestResult":"\r\nSkipped. This test requires connection to the service(s) \"SecurityCompliance\" currently disconnected. Please use _Connect-ZtAssessment_ to connect.\r\n\r\n","TestSfiPillar":"Protect tenants and production systems","TestStatus":"Skipped","TestImpact":"Low","TestPillar":"AI","TestId":"35023","TestRisk":"Medium","TestDescription":"OCR (optical character recognition) extends sensitive information type and trainable classifier detection to images across Exchange, SharePoint, OneDrive, Teams, and endpoint devices. Without OCR, DLP policies, and auto-labeling policies can't scan image-based content, scanned documents, screenshots, and invoices, leaving sensitive data in images unprotected. OCR requires Azure pay-as-you-go billing for Microsoft Syntex, and is configured at the tenant level.\r\n\r\n**Remediation action**\r\n\r\n- [Learn about and configure optical character recognition in Microsoft Purview](https://learn.microsoft.com/purview/ocr-learn-about?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci)\r\n","TestTags":null,"TestMinimumLicense":["EXCHANGE_S_ENTERPRISE"],"SkippedReason":"This test requires connection to the service(s) \"SecurityCompliance\" currently disconnected. Please use _Connect-ZtAssessment_ to connect.","TestAppliesTo":null,"TestImplementationCost":"Medium","TestCategory":"Information Protection"},{"TestTitle":"Network access is validated in real-time through Universal Continuous Access Evaluation","TestSkipped":"","TestResult":"\r\n✅ Universal CAE is enabled for Global Secure Access.\n\n\n## [Global Secure Access Status](https://entra.microsoft.com/#view/Microsoft_Azure_Network_Access/Welcome.ReactView)\n\n**Signaling Status**: ✅ Enabled\n\n## [Active Traffic Profiles](https://entra.microsoft.com/#view/Microsoft_Azure_Network_Access/TrafficForwarding.ReactView)\n\n| Name | State | Traffic Type |\n| :--- | :--- | :--- |\n| Internet traffic forwarding profile | Enabled | internet |\n| Microsoft 365 traffic forwarding profile | Enabled | m365 |\n| Private access traffic forwarding profile | Enabled | private |\n\n## [Policies disabling Continuous Access Evaluation](https://entra.microsoft.com/#view/Microsoft_AAD_ConditionalAccess/ConditionalAccessBlade/~/Policies)\n\nNo Conditional Access policies disabling Continuous Access Evaluation were found.\n\n\r\n\r\n","TestSfiPillar":"Protect networks","TestStatus":"Passed","TestImpact":"Low","TestPillar":"Network","TestId":"25371","TestRisk":"High","TestDescription":"Universal Continuous Access Evaluation (Universal CAE) validates network access tokens every time a connection is established through Global Secure Access tunnels. Without Universal CAE, tokens remain valid for 60 to 90 minutes regardless of changes to user state.\r\n\r\nWithout this protection:\r\n\r\n- A threat actor who obtains a token through theft or replay can continue accessing all Global Secure Access-protected resources even after the user's account is disabled or password is reset.\r\n- Critical events like session revocation or high user risk detection don't prompt immediate reauthentication.\r\n- Departing employees or malicious insiders maintain network-level access to private corporate resources for up to 90 minutes after remediation action is taken.\r\n- Token replay attacks from different IP addresses aren't blocked without Strict Enforcement mode.\r\n\r\n**Remediation action**\r\n- Review the [Universal CAE](https://learn.microsoft.com/entra/global-secure-access/concept-universal-continuous-access-evaluation?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci) capabilities for Global Secure Access.\r\n- Remove or modify Conditional Access policies that disable CAE for Global Secure Access workloads. For more information, see [Continuous access evaluation](https://learn.microsoft.com/entra/identity/conditional-access/concept-continuous-access-evaluation?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci).\r\n- Configure Universal CAE to use Strict Enforcement mode for enhanced token replay protection. For more information, see [Universal Continuous Access Evaluation](https://learn.microsoft.com/entra/global-secure-access/concept-universal-continuous-access-evaluation?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci#strict-enforcement-mode).\r\n","TestTags":null,"TestMinimumLicense":["Entra_Premium_Private_Access","Entra_Premium_Internet_Access"],"SkippedReason":null,"TestAppliesTo":null,"TestImplementationCost":"Low","TestCategory":"Global Secure Access"},{"TestId":"26883","TestCategory":"Azure Network Security","TestImpact":"Low","TestResult":"\r\n✅ All Azure Front Door WAF policies attached to Azure Front Door are enabled, running in Prevention mode, and have the Default Ruleset (Microsoft_DefaultRuleSet) with at least one rule enabled.\n\n\r\n\r\n## [Azure Front Door WAF Policies](https://portal.azure.com/#browse/Microsoft.Network%2FfrontdoorWebApplicationFirewallPolicies)\r\n\r\n| Policy name | Subscription name | Attached to AFD | Enabled state | WAF mode | Default ruleset type | Ruleset version | Status |\r\n| :---------- | :---------------- | :-------------: | :-----------: | :------: | :------------------- | :-------------- | :----: |\r\n| [AFDCopilotWAFPolicy](https://portal.azure.com/#resource/subscriptions/ab48f397-fc82-4634-aa52-62dd91b3ebaa/resourceGroups/Woodgrove-RG/providers/Microsoft.Network/frontdoorWebApplicationFirewallPolicies/AFDCopilotWAFPolicy) | [Woodgrove - GTP Demos (External/Sponsored)](https://portal.azure.com/#resource/subscriptions/ab48f397-fc82-4634-aa52-62dd91b3ebaa) | Yes | ✅ Enabled | ✅ Prevention | Microsoft_DefaultRuleSet | 2.1 | ✅ Pass |\n\r\n**Summary:**\n\n- Total Azure Front Door WAF policies evaluated: 1\n- Policies passing all criteria: 1\n- Policies failing one or more criteria: 0\n\r\n","SkippedReason":null,"TestMinimumLicense":"Azure WAF","TestAppliesTo":null,"TestTags":null,"TestSfiPillar":"Protect networks","TestImplementationCost":"Low","TestSkipped":"","TestPillar":"Network","TestTitle":"Default rule set is assigned in Azure Front Door WAF","TestStatus":"Passed","TestDescription":"Azure Front Door Web Application Firewall (WAF) provides centralized, edge-based protection for globally distributed web applications through managed rulesets that contain pre-configured detection signatures for known attack patterns. The Microsoft Default Ruleset is a continuously updated managed ruleset that protects against the most common and dangerous web vulnerabilities without requiring security expertise to configure. When no managed ruleset is enabled, the WAF policy provides no protection against known attack patterns, effectively operating as a pass-through despite being deployed at the edge. Threat actors routinely scan for unprotected web applications and exploit well-documented vulnerabilities using automated toolkits; without managed rules, attackers can execute SQL injection to extract or modify database contents, perform cross-site scripting to hijack user sessions and steal credentials, exploit local file inclusion to read sensitive configuration files, and leverage command injection to gain shell access on backend servers. These attack techniques have known signatures that managed rulesets detect and block at the edge before malicious traffic reaches origin servers, but an empty or disabled ruleset configuration means the WAF cannot recognize these patterns and will allow malicious requests to pass through to the application.\r\n\r\n**Remediation action**\r\n\r\nOverview of WAF capabilities on Azure Front Door including managed rulesets\r\n- [Azure Web Application Firewall on Azure Front Door](https://learn.microsoft.com/en-us/azure/web-application-firewall/afds/afds-overview)\r\n\r\nDetailed documentation of Default Rule Set groups and rules for Azure Front Door\r\n- [Web Application Firewall DRS rule groups and rules](https://learn.microsoft.com/en-us/azure/web-application-firewall/afds/waf-front-door-drs)\r\n\r\nStep-by-step guidance on creating and configuring WAF policies with managed rulesets\r\n- [Tutorial: Create a Web Application Firewall policy on Azure Front Door](https://learn.microsoft.com/en-us/azure/web-application-firewall/afds/waf-front-door-create-portal)\r\n\r\n","TestRisk":"High"},{"TestTitle":"A default sensitivity label is configured in label policies","TestSkipped":"NotConnectedToService","TestResult":"\r\nSkipped. This test requires connection to the service(s) \"SecurityCompliance\" currently disconnected. Please use _Connect-ZtAssessment_ to connect.\r\n\r\n","TestSfiPillar":"Protect tenants and production systems","TestStatus":"Skipped","TestImpact":"Medium","TestPillar":"AI","TestId":"35017","TestRisk":"Medium","TestDescription":"Setting a default label ensures a base level of protection settings for all new and edited items that support sensitivity labels, and for new containers such as Teams. Users can manually override the label if necessary, and other labeling methods such as auto-labeling can replace the default label with a label that has a higher sensitivity level. Setting a default sensitivity label extends your labeling reach and reduces decision fatigue for users, ensuring content has at least a minimum level of protection.\r\n\r\nUnlabeled content might bypass data loss prevention (DLP) policies, and other protection solutions that rely on label detection. If appropriate, set a different default sensitivity label for unlabeled documents and Loop components and pages, emails and meeting invites, new containers, and also a default label for Power BI content.\r\n\r\n**Remediation action**\r\n\r\n- [Publish sensitivity labels by creating a label policy](https://learn.microsoft.com/purview/create-sensitivity-labels?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci#publish-sensitivity-labels-by-creating-a-label-policy)\r\n- [Default label policy for Fabric and Power BI](https://learn.microsoft.com/fabric/governance/sensitivity-label-default-label-policy?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci)\r\n","TestTags":null,"TestMinimumLicense":["RMS_S_PREMIUM"],"SkippedReason":"This test requires connection to the service(s) \"SecurityCompliance\" currently disconnected. Please use _Connect-ZtAssessment_ to connect.","TestAppliesTo":null,"TestImplementationCost":"Low","TestCategory":"Information Protection"},{"TestId":"27018","TestCategory":"Azure Network Security","TestImpact":"Low","TestResult":"\r\n❌ One or more Azure Front Door WAF policies attached to Azure Front Door are either disabled, not in Prevention mode, or do not have rate limiting rules configured and enabled, leaving applications vulnerable to brute force and volumetric attacks at the global edge.\n\n\n## [Azure Front Door WAF policies](https://portal.azure.com/#browse/Microsoft.Network%2FfrontdoorWebApplicationFirewallPolicies)\n\n| Policy name | Subscription name | Rule state | Enabled state | WAF mode | Rate limit rules count | Status |\r\n| :--- | :--- | :--- | :--- | :--- | :--- | :--- |\r\n| [AFDCopilotWAFPolicy](https://portal.azure.com/#resource/subscriptions/ab48f397-fc82-4634-aa52-62dd91b3ebaa/resourceGroups/Woodgrove-RG/providers/Microsoft.Network/frontdoorWebApplicationFirewallPolicies/AFDCopilotWAFPolicy) | [Woodgrove - GTP Demos (External/Sponsored)](https://portal.azure.com/#resource/subscriptions/ab48f397-fc82-4634-aa52-62dd91b3ebaa/overview) | N/A | ✅ Enabled | ✅ Prevention | ❌ 0 | ❌ Fail |\n\r\n\r\n","SkippedReason":null,"TestMinimumLicense":"Azure_WAF","TestAppliesTo":null,"TestTags":null,"TestSfiPillar":"Protect networks","TestImplementationCost":"Medium","TestSkipped":"","TestPillar":"Network","TestTitle":"Rate Limiting is Enabled in Azure Front Door WAF","TestStatus":"Failed","TestDescription":"Azure Front Door Web Application Firewall (WAF) supports rate limiting through custom rules that restrict the number of requests clients can make within a specified time window across the global edge network. Rate limiting is a critical defense mechanism that protects applications from abuse by throttling clients that exceed defined request thresholds before traffic reaches origin servers.\r\n\r\nWithout rate limiting configured, threat actors can execute brute force attacks, credential stuffing attacks, API abuse, and application-layer denial of service attacks that flood endpoints with requests to exhaust server capacity.\r\n\r\nRate limiting rules use the `RateLimitRule` rule type and allow administrators to define thresholds based on request count per minute, with the ability to group requests by client IP address. When a client exceeds the configured threshold, the WAF can block subsequent requests, log the violation, issue a CAPTCHA challenge, or redirect to a custom page.\r\n\r\nThis check identifies Azure Front Door WAF policies that are attached to an Azure Front Door and verifies that at least one rate limiting rule is configured and enabled.\r\n\r\n**Remediation action**\r\n\r\n- [Azure Web Application Firewall on Azure Front Door](https://learn.microsoft.com/en-us/azure/web-application-firewall/afds/afds-overview)\r\n- [Web Application Firewall custom rules for Azure Front Door](https://learn.microsoft.com/en-us/azure/web-application-firewall/afds/waf-front-door-custom-rules)\r\n- [Rate limiting for Azure Front Door WAF](https://learn.microsoft.com/en-us/azure/web-application-firewall/afds/waf-front-door-rate-limit)\r\n- [Tutorial: Create a Web Application Firewall policy on Azure Front Door](https://learn.microsoft.com/en-us/azure/web-application-firewall/afds/waf-front-door-create-portal)\r\n\r\n","TestRisk":"High"},{"TestTitle":"Private Access Connectors are running the latest version","TestSkipped":"","TestResult":"\r\n❌ At least one private network connector is not running the latest version (1.5.4594.0).\n\n\n## Connector version assessment\n\n**Latest available version**: 1.5.4594.0\n\n**Total connectors**: 3\n**Up to date**: 0\n**Outdated**: 3\n\n### ❌ Outdated connectors\r\n\r\n| ID | Machine Name | Current Version |\r\n| :-- | :----------- | :-------------- |\r\n| 69c257b2-2fcd-4da1-b933-38d396c9ec2d | AppProxy02.Woodgrove.net | 1.5.4522.0 |\n| bffdc3f4-1bd5-4821-b230-1fb8f3fa0b45 | ForrestorDemo | 1.5.3925.0 |\n| d940fd07-6a1e-4047-8164-72cba3ab1097 | Woodgrove-GSA01 | 1.5.3925.0 |\n\r\n\r\n\r\n","TestSfiPillar":"Protect networks","TestStatus":"Failed","TestImpact":"Low","TestPillar":"Network","TestId":"25392","TestRisk":"Medium","TestDescription":"The private network connector is a key component of Microsoft Entra Private Access and Application Proxy. To maintain security, stability, and performance, all connector machines must run the latest software version.\r\n\r\nIf your connectors don't run the latest version:\r\n\r\n- They might be missing critical security patches, which leaves connectors vulnerable to known exploits.\r\n- You don't get the latest performance improvements and bug fixes, which can affect reliability.\r\n- Compatibility problems might arise with the Global Secure Access service as it evolves.\r\n\r\n**Remediation action**\r\n\r\n- [Configure private network connectors for Microsoft Entra Private Access and Microsoft Entra application proxy](https://learn.microsoft.com/entra/global-secure-access/how-to-configure-connectors?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci).\r\n- Verify that all your connectors are up to date and install the latest [connector updates](https://learn.microsoft.com/entra/global-secure-access/concept-connectors?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci#connector-updates).\r\n","TestTags":null,"TestMinimumLicense":["Entra_Premium_Private_Access"],"SkippedReason":null,"TestAppliesTo":null,"TestImplementationCost":"Low","TestCategory":"Private Access"},{"TestTitle":"Auto-labeling policies are enabled for SharePoint and OneDrive","TestSkipped":"NotConnectedToService","TestResult":"\r\nSkipped. This test requires connection to the service(s) \"SecurityCompliance\" currently disconnected. Please use _Connect-ZtAssessment_ to connect.\r\n\r\n","TestSfiPillar":"Protect tenants and production systems","TestStatus":"Skipped","TestImpact":"Low","TestPillar":"AI","TestId":"35021","TestRisk":"High","TestDescription":"When auto-labeling for SharePoint and OneDrive isn't set up, files uploaded without sensitivity labels might not be visible to Data Loss Protection (DLP) policies that rely on labels. As a result, those files can move through the environment with fewer safeguards, which can raise the risk of inappropriate sharing or access.\r\n \r\nFor example, enabling at least one auto-labeling policy in enforcement mode for SharePoint and OneDrive helps classify sensitive files when users create or edit them. Auto-labeling classification supports downstream protections, such as DLP policies, so they can respond based on the file’s sensitivity and help reduce data exposure risk.\r\n\r\n**Remediation action**\r\n\r\n- [Apply sensitivity labels automatically for SharePoint and OneDrive](https://learn.microsoft.com/purview/apply-sensitivity-label-automatically?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci)\r\n","TestTags":null,"TestMinimumLicense":["EXCHANGE_S_ENTERPRISE"],"SkippedReason":"This test requires connection to the service(s) \"SecurityCompliance\" currently disconnected. Please use _Connect-ZtAssessment_ to connect.","TestAppliesTo":null,"TestImplementationCost":"Medium","TestCategory":"Information Protection"},{"TestTitle":"Information Rights Management is enabled in SharePoint Online","TestSkipped":"NotConnectedToService","TestResult":"\r\nSkipped. This test requires connection to the service(s) \"SharePointOnline\" currently disconnected. Please use _Connect-ZtAssessment_ to connect.\r\n","TestSfiPillar":"","TestStatus":"Skipped","TestImpact":"Low","TestPillar":"AI","TestId":"35007","TestRisk":"Low","TestDescription":"Information Rights Management (IRM) integration in SharePoint Online libraries is a legacy feature that has been replaced by Enhanced SharePoint Permissions (ESP). Any library using this legacy capability should be flagged to move to newer capabilities.\r\n\r\n**Remediation action**\r\n\r\nTo disable legacy IRM in SharePoint Online:\r\n1. Identify libraries currently using IRM protection (audit existing sites)\r\n2. Plan migration to modern sensitivity labels with encryption\r\n3. Connect to SharePoint Online: `Connect-SPOService -Url https://-admin.sharepoint.com`\r\n4. Disable legacy IRM: `Set-SPOTenant -IrmEnabled $false`\r\n5. Enable modern sensitivity labels: `Set-SPOTenant -EnableAIPIntegration $true`\r\n6. Configure and publish sensitivity labels with encryption to replace IRM policies\r\n\r\n- [Enable sensitivity labels for SharePoint and OneDrive](https://learn.microsoft.com/microsoft-365/compliance/sensitivity-labels-sharepoint-onedrive-files)\r\n- [SharePoint IRM and sensitivity labels (migration guidance)](https://learn.microsoft.com/microsoft-365/compliance/sensitivity-labels-sharepoint-onedrive-files#sharepoint-information-rights-management-irm-and-sensitivity-labels)\r\n- [Create and configure sensitivity labels with encryption](https://learn.microsoft.com/microsoft-365/compliance/encryption-sensitivity-labels)\r\n\r\n","TestTags":null,"TestMinimumLicense":["RMS_S_PREMIUM"],"SkippedReason":"This test requires connection to the service(s) \"SharePointOnline\" currently disconnected. Please use _Connect-ZtAssessment_ to connect.","TestAppliesTo":null,"TestImplementationCost":"Low","TestCategory":"SharePoint Online"},{"TestTitle":"Exact Data Match is configured for sensitive information detection","TestSkipped":"NotConnectedToService","TestResult":"\r\nSkipped. This test requires connection to the service(s) \"SecurityCompliance\" currently disconnected. Please use _Connect-ZtAssessment_ to connect.\r\n\r\n","TestSfiPillar":"Protect tenants and production systems","TestStatus":"Skipped","TestImpact":"Medium","TestPillar":"AI","TestId":"35034","TestRisk":"High","TestDescription":"Exact data match (EDM) is an advanced sensitive information type that detects organization-specific data by matching exact values against an uploaded reference database. Unlike pattern-based sensitive information types (SITs) that detect common formats, EDM identifies things like customer lists, employee IDs, or proprietary codes unique to your organization. By configuring EDM-based SITs, you can significantly enhance the accuracy of sensitive information detection in Microsoft Purview, ensuring that critical data is properly identified and protected.\r\n\r\n**Remediation action**\r\n\r\n- [Learn about exact data match based sensitive information types](https://learn.microsoft.com/purview/sit-learn-about-exact-data-match-based-sits?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci)\r\n- [Get started with exact data match based sensitive information types](https://learn.microsoft.com/purview/sit-get-started-exact-data-match-based-sits-overview?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci)\r\n","TestTags":null,"TestMinimumLicense":["EXCHANGE_S_ENTERPRISE"],"SkippedReason":"This test requires connection to the service(s) \"SecurityCompliance\" currently disconnected. Please use _Connect-ZtAssessment_ to connect.","TestAppliesTo":null,"TestImplementationCost":"Medium","TestCategory":"Advanced Classification"},{"TestId":"27019","TestCategory":"Azure Network Security","TestImpact":"Low","TestResult":"\r\n❌ One or more Azure Front Door WAF policies attached to Azure Front Door are disabled, running in Detection mode, have no JavaScript challenge rules configured, or have JavaScript challenge rules configured but all set to Disabled state, leaving applications without browser verification against automated bots at the global edge.\n\n\n## [Azure Front Door WAF policies](https://portal.azure.com/#browse/Microsoft.Network%2FfrontdoorWebApplicationFirewallPolicies)\n\n| Policy name | Subscription name | Enabled state | WAF mode | JS challenge rules count | Rule state | Cookie expiration (mins) | Status |\r\n| :--- | :--- | :--- | :--- | :--- | :--- | :--- | :--- |\r\n| [AFDCopilotWAFPolicy](https://portal.azure.com/#resource/subscriptions/ab48f397-fc82-4634-aa52-62dd91b3ebaa/resourceGroups/Woodgrove-RG/providers/Microsoft.Network/frontdoorWebApplicationFirewallPolicies/AFDCopilotWAFPolicy) | [Woodgrove - GTP Demos (External/Sponsored)](https://portal.azure.com/#resource/subscriptions/ab48f397-fc82-4634-aa52-62dd91b3ebaa/overview) | ✅ Enabled | ✅ Prevention | ❌ 0 | N/A | 30 | ❌ Fail |\n\r\n\r\n","SkippedReason":null,"TestMinimumLicense":"Azure WAF","TestAppliesTo":null,"TestTags":null,"TestSfiPillar":"Protect networks","TestImplementationCost":"Low","TestSkipped":"","TestPillar":"Network","TestTitle":"JavaScript Challenge is Enabled in Azure Front Door WAF","TestStatus":"Failed","TestDescription":"Azure Front Door Web Application Firewall (WAF) supports JavaScript challenge as a defense mechanism against automated bots and headless browsers across the global edge network. JavaScript challenge works by serving a small JavaScript snippet that must be executed by the client browser to prove that the request originates from a real browser capable of running JavaScript, rather than a simple HTTP client or bot.\r\n\r\nWhen a request triggers a JavaScript challenge, the WAF responds with a challenge page containing JavaScript code that the browser must execute to obtain a valid challenge cookie. Bots and automated tools that cannot execute JavaScript fail this challenge and are blocked from accessing protected resources.\r\n\r\nThe `javascriptChallengeExpirationInMinutes` setting controls how long the challenge cookie remains valid before the client must complete another challenge. JavaScript challenge provides a middle ground between allowing all traffic and blocking suspected bots outright.\r\n\r\nThis check identifies Azure Front Door WAF policies that are attached to an Azure Front Door and verifies that at least one custom rule with JavaScript challenge action is configured and enabled.\r\n\r\n**Remediation action**\r\n\r\n- [Azure Web Application Firewall on Azure Front Door](https://learn.microsoft.com/en-us/azure/web-application-firewall/afds/afds-overview)\r\n- [Web Application Firewall custom rules for Azure Front Door](https://learn.microsoft.com/en-us/azure/web-application-firewall/afds/waf-front-door-custom-rules)\r\n- [Configure JavaScript challenge for Azure Front Door WAF](https://learn.microsoft.com/en-us/azure/web-application-firewall/afds/waf-front-door-tuning#javascript-challenge)\r\n- [Tutorial: Create a Web Application Firewall policy on Azure Front Door](https://learn.microsoft.com/en-us/azure/web-application-firewall/afds/waf-front-door-create-portal)\r\n\r\n","TestRisk":"Medium"},{"TestId":"25400","TestCategory":"Private Access","TestImpact":"Low","TestResult":"\r\n❌ No Private Access applications are configured. DNS resolution cannot be established without application segments.\n\n\r\n\r\n","SkippedReason":null,"TestMinimumLicense":["AAD_PREMIUM","Entra_Premium_Private_Access"],"TestAppliesTo":null,"TestTags":null,"TestSfiPillar":"Protect networks","TestImplementationCost":"Low","TestSkipped":"","TestPillar":"Network","TestTitle":"Is port 53 published or private DNS configured for Private Access applications","TestStatus":"Failed","TestDescription":"When you enable the Private Access profile in Global Secure Access but don't publish port 53 (UDP/TCP) in application segments or configure private DNS suffixes, the Global Secure Access client can't route DNS queries for internal domain names through the tunnel. As a result, DNS queries for internal FQDNs go to the local resolver on the device, which has no knowledge of internal zones.\r\n\r\nWithout this configuration:\r\n\r\n- FQDN-based application segments fail to match traffic because the client can't resolve internal host names to IP addresses.\r\n- Threat actors operating on the same local network as the remote user can observe unencrypted DNS queries, map internal resource names, and identify targets for later stages of an attack.\r\n- The client might fall back to direct connections that bypass Conditional Access and security profile enforcement applied through Global Secure Access.\r\n\r\n**Remediation action**\r\n\r\n- [Configure private DNS suffixes for Quick Access or per-app access](https://learn.microsoft.com/entra/global-secure-access/how-to-configure-quick-access?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci) so DNS queries for internal domains go through Global Secure Access.\r\n- [Configure per-app access with application segments](https://learn.microsoft.com/entra/global-secure-access/how-to-configure-per-app-access?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci) that include port 53 (UDP/TCP) to an internal DNS server.\r\n- [Learn about Microsoft Entra Private Access](https://learn.microsoft.com/entra/global-secure-access/concept-private-access?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci) in Global Secure Access.\r\n","TestRisk":"Low"},{"TestTitle":"Require users to use Microsoft Entra ID auth to interact with agents","TestSkipped":"","TestResult":"\r\n❌ Unable to evaluate agent identity sign-in evidence because sign-in log data could not be retrieved.\n\n**Error:** `GET https://graph.microsoft.com/beta/auditLogs/signIns?$filter=createdDateTime+ge+2026-05-09T20%3a22%3a52Z+and+signInEventTypes%2fany(t%3at+eq+%27interactiveUser%27)&$select=id%2ccreatedDateTime%2cuserPrincipalName%2cappId%2cresourceId%2cresourceDisplayName%2csignInEventTypes&$skiptoken=9efb9b3116bee40382784841a87a38ff8c758de3afc7ce235eddc66715edb4c5\r\nHTTP/1.1 400 Bad Request\r\nTransfer-Encoding: chunked\r\nVary: Accept-Encoding\r\nStrict-Transport-Security: max-age=31536000\r\nrequest-id: f368c91d-39e4-44ec-a283-f49915059cae\r\nclient-request-id: 064481f4-50c5-4ca5-add1-a2e61aa62be9\r\nx-ms-ags-diagnostic: {\"ServerInfo\":{\"DataCenter\":\"West Europe\",\"Slice\":\"E\",\"Ring\":\"5\",\"ScaleUnit\":\"005\",\"RoleInstance\":\"AM4PEPF00027D01\"}}\r\nDate: Mon, 08 Jun 2026 20:31:29 GMT\r\nContent-Type: application/json\r\n\r\n{\"error\":{\"code\":\"UnknownError\",\"message\":\"Skip token is null. It may have a typo or it has expired.\",\"innerError\":{\"date\":\"2026-06-08T20:31:29\",\"request-id\":\"f368c91d-39e4-44ec-a283-f49915059cae\",\"client-request-id\":\"064481f4-50c5-4ca5-add1-a2e61aa62be9\"}}}`\n\n\r\n","TestSfiPillar":"Protect identities and secrets","TestStatus":"Failed","TestImpact":"Medium","TestPillar":"AI","TestId":"61011","TestRisk":"High","TestDescription":"An agent endpoint that does not require Microsoft Entra user authentication is an unauthenticated reachable surface inside the tenant's AI estate. A threat actor that locates such an endpoint — through reconnaissance of public agent URLs, leaked Copilot Studio links, or enumeration of Foundry project endpoints — can interact with the agent without presenting any identity, then ride the agent's own grants to reach grounding data, connected tools, and downstream APIs the agent is authorized to call. Because the call never reaches Microsoft Entra, no Conditional Access policy evaluates it, no sign-in risk score is computed, no audit record ties the action to a real user, and no later investigation can attribute the resulting data access. The runtime behaviour that enforces Entra user authentication lives inside each agent's host (Copilot Studio, Microsoft 365 Copilot, Microsoft Foundry, custom code, third-party platforms) and is therefore not directly observable from the directory; what *is* observable is the trail left in the Microsoft Entra sign-in logs whenever an agent and its callers do go through Entra. This check inspects the last 30 days of sign-in activity for each agent identity and classifies the agent by the strongest evidence found: a non-interactive agent sign-in whose subject is a real user (the agent calling downstream resources on behalf of a signed-in user) is the strongest positive signal; an interactive user sign-in to the agent's blueprint is a good positive signal that proves users do reach the agent through Entra; absence of either across the lookback window means the platform has no evidence the agent enforces Entra user authentication and a control owner must verify the agent's host configuration directly.\r\n\r\n**Remediation action**\r\n\r\n- [Authenticate users in interactive agents](https://learn.microsoft.com/en-us/entra/agent-id/identity-platform/interactive-agent-authenticate-user)\r\n- [Request delegated user authorization for interactive agents](https://learn.microsoft.com/en-us/entra/agent-id/identity-platform/interactive-agent-request-user-authorization)\r\n- [Agent users in Microsoft Entra Agent ID](https://learn.microsoft.com/en-us/entra/agent-id/identity-platform/agent-users)\r\n- [Microsoft Entra Agent ID overview](https://learn.microsoft.com/en-us/entra/agent-id/what-is-microsoft-entra-agent-id)\r\n- [Sign-in logs in Microsoft Entra ID](https://learn.microsoft.com/en-us/entra/identity/monitoring-health/concept-sign-ins)\r\n\r\n","TestTags":null,"TestMinimumLicense":["AAD_PREMIUM"],"SkippedReason":null,"TestAppliesTo":null,"TestImplementationCost":"Medium","TestCategory":"AI Authentication & Access"},{"TestTitle":"Trainable classifiers are used in data loss prevention and auto-labeling policies","TestSkipped":"NotConnectedToService","TestResult":"\r\nSkipped. This test requires connection to the service(s) \"SecurityCompliance\" currently disconnected. Please use _Connect-ZtAssessment_ to connect.\r\n\r\n","TestSfiPillar":"Protect tenants and production systems","TestStatus":"Skipped","TestImpact":"Medium","TestPillar":"AI","TestId":"35036","TestRisk":"Medium","TestDescription":"Trainable classifiers are machine learning-based classifiers that recognize content by meaning and context rather than fixed patterns. Unlike sensitive information types that match predefined formats, trainable classifiers can identify unstructured content like strategic plans, financial reports, or HR documents. Using trainable classifiers in auto-labeling policies, and data loss prevention (DLP) rules, extends protection to sensitive business content that pattern-based rules can't reliably capture.\r\n\r\n**Remediation action**\r\n\r\n- [Learn about trainable classifiers](https://learn.microsoft.com/purview/classifier-learn-about?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci)\r\n- [Get started with trainable classifiers](https://learn.microsoft.com/purview/trainable-classifiers-get-started-with?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci)\r\n","TestTags":null,"TestMinimumLicense":["EXCHANGE_S_ENTERPRISE"],"SkippedReason":"This test requires connection to the service(s) \"SecurityCompliance\" currently disconnected. Please use _Connect-ZtAssessment_ to connect.","TestAppliesTo":null,"TestImplementationCost":"High","TestCategory":"Advanced Classification"},{"TestTitle":"Microsoft 365 audit logging is enabled","TestSkipped":"NotConnectedToService","TestResult":"\r\nSkipped. This test requires connection to the service(s) \"ExchangeOnline\" currently disconnected. Please use _Connect-ZtAssessment_ to connect.\r\n\r\n","TestSfiPillar":"Protect tenants and production systems","TestStatus":"Skipped","TestImpact":"Low","TestPillar":"AI","TestId":"35037","TestRisk":"High","TestDescription":"Audit logging in Microsoft 365 records which users and admins accessed sensitive data, when policy violations occurred, and what administrative actions they took across Microsoft 365. When audit logs are available, security teams can investigate incidents, perform electronic discovery for investigations and legal cases, detect insider threats, and demonstrate controls to auditors and regulators by using Microsoft Purview auditing solutions.\r\n\r\nAudit logging is on by default for Microsoft 365 organizations, but you can turn it off. If you turn off audit logging, threat actors can often operate undetected, and incident response becomes impossible due to lack of evidence. Organizations that don't enable audit logging also risk noncompliance with regulatory requirements that mandate activity logging for sensitive operations.\r\n\r\n**Remediation action**\r\n\r\n- [Turn auditing on or off](https://learn.microsoft.com/purview/audit-log-enable-disable?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci)\r\n","TestTags":null,"TestMinimumLicense":["RMS_S_PREMIUM"],"SkippedReason":"This test requires connection to the service(s) \"ExchangeOnline\" currently disconnected. Please use _Connect-ZtAssessment_ to connect.","TestAppliesTo":null,"TestImplementationCost":"Low","TestCategory":"Data Security Posture Management"},{"TestTitle":"Insider Risk Management policies are enabled for risky AI usage","TestSkipped":"NotConnectedToService","TestResult":"\r\nSkipped. This test requires connection to the service(s) \"SecurityCompliance\" currently disconnected. Please use _Connect-ZtAssessment_ to connect.\r\n\r\n","TestSfiPillar":"Protect tenants and production systems","TestStatus":"Skipped","TestImpact":"Medium","TestPillar":"AI","TestId":"35038","TestRisk":"High","TestDescription":"Until organizations use Insider Risk Management with Adaptive Protection, they could fail to detect insider threats, risky behaviors such as misuse of legitimate access to exfiltrate data, or unsafe AI scenarios where users expose sensitive data to large language models or unauthorized cloud AI services.\r\n\r\nInsider Risk Management works with Data Loss Prevention (DLP) to combine user behavior signals with content-based rules, helping teams detect risks early and respond before sensitive data is exposed or compromised.\r\n\r\n**Remediation action**\r\n\r\n- [Create and configure Insider Risk Management policies](https://learn.microsoft.com/purview/insider-risk-management-policies?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci)\r\n- [Help dynamically mitigate risks with Adaptive Protection](https://learn.microsoft.com/purview/insider-risk-management-adaptive-protection?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci)\r\n","TestTags":null,"TestMinimumLicense":["EXCHANGE_S_ENTERPRISE"],"SkippedReason":"This test requires connection to the service(s) \"SecurityCompliance\" currently disconnected. Please use _Connect-ZtAssessment_ to connect.","TestAppliesTo":null,"TestImplementationCost":"Medium","TestCategory":"Data Security Posture Management"},{"TestId":"27015","TestCategory":"Azure Network Security","TestImpact":"Low","TestResult":"\r\n❌ One or more Application Gateway WAF policies attached to Application Gateways are disabled, running in Detection mode, do not have the HTTP DDoS Protection ruleset configured, or have all HTTP DDoS Protection rules disabled, leaving applications vulnerable to volumetric HTTP-based attacks.\n\n\r\n## [Application Gateway WAF policies](https://portal.azure.com/#browse/Microsoft.Network%2FapplicationGatewayWebApplicationFirewallPolicies)\r\n\r\n| Policy name | Subscription name | Policy state | Mode | HTTP DDoS ruleset | Ruleset version | Status |\r\n| :---------- | :---------------- | :----------- | :--- | :---------------- | :-------------- | :----- |\r\n| [WAFAppGWcopilotPolicy](https://portal.azure.com/#resource/subscriptions/ab48f397-fc82-4634-aa52-62dd91b3ebaa/resourceGroups/Woodgrove-RG/providers/Microsoft.Network/applicationGatewayWebApplicationFirewallPolicies/WAFAppGWcopilotPolicy) | [Woodgrove - GTP Demos (External/Sponsored)](https://portal.azure.com/#resource/subscriptions/ab48f397-fc82-4634-aa52-62dd91b3ebaa) | ✅ Enabled | ✅ Prevention | ❌ Not Configured | N/A | ❌ |\n\r\n\r\n","SkippedReason":null,"TestMinimumLicense":"Azure WAF","TestAppliesTo":null,"TestTags":null,"TestSfiPillar":"Protect networks","TestImplementationCost":"Low","TestSkipped":"","TestPillar":"Network","TestTitle":"HTTP DDoS Protection Ruleset is Enabled in Application Gateway WAF","TestStatus":"Failed","TestDescription":"Azure Application Gateway Web Application Firewall (WAF) provides HTTP DDoS protection through the Microsoft HTTP DDoS Ruleset (Microsoft_HTTPDDoSRuleSet), which detects and mitigates volumetric HTTP-based attacks at the application layer. Unlike network-layer DDoS attacks that target bandwidth and infrastructure, HTTP-based DDoS attacks exploit the application layer by sending seemingly legitimate HTTP requests at extremely high volumes to exhaust server resources, database connections, and application threads. \r\n\r\nWithout HTTP DDoS protection enabled, threat actors can execute HTTP flood attacks that overwhelm backend servers with GET or POST requests at rates far exceeding normal traffic patterns, slowloris attacks that hold connections open by sending partial HTTP requests to exhaust connection pools, and high-frequency request patterns designed to trigger resource-intensive operations like complex database queries or file processing. \r\n\r\nThe HTTP DDoS ruleset contains rule groups like ExcessiveRequests with rules 500100 and 500110 that detect abnormal request rates based on configurable sensitivity levels (High, Medium, Low) and can block, log, or redirect malicious traffic. These rules identify clients making excessive requests within short time windows and can automatically block them before they impact application performance. By enabling this ruleset on Application Gateway WAF policies, malicious HTTP traffic is identified and blocked at the gateway before reaching backend application servers, preserving application availability and protecting infrastructure from resource exhaustion attacks.\r\n\r\n**Remediation action**\r\n\r\n- [What is Azure Web Application Firewall on Azure Application Gateway?](https://learn.microsoft.com/en-us/azure/web-application-firewall/ag/ag-overview) - Overview of WAF capabilities on Application Gateway including DDoS protection rulesets\r\n- [Web Application Firewall CRS rule groups and rules](https://learn.microsoft.com/en-us/azure/web-application-firewall/ag/application-gateway-crs-rulegroups-rules) - Documentation of available managed rulesets including HTTP DDoS rules\r\n- [Create Web Application Firewall policies for Application Gateway](https://learn.microsoft.com/en-us/azure/web-application-firewall/ag/create-waf-policy-ag) - Step-by-step guidance on creating and configuring WAF policies with managed rulesets\r\n- [Azure DDoS Protection overview](https://learn.microsoft.com/en-us/azure/ddos-protection/ddos-protection-overview) - Overview of Azure DDoS Protection capabilities including application-layer protection\r\n\r\n","TestRisk":"High"},{"TestTitle":"Global Secure Access web content filtering is enabled and configured","TestSkipped":"","TestResult":"\r\n✅ Web Content Filtering policy is enabled. \n\n### Applied web content filtering policies\n\n| Linked profile name | Linked profile priority | Linked policy name | Policy state | Profile state | Policy action | CA policy name | CA policy state |\n|---------------------|-------------------------|--------------------|--------------|---------------|---------------|----------------|-----------------|\n| [Baseline Profile](https://entra.microsoft.com/#view/Microsoft_Azure_Network_Access/EditProfileMenuBlade.MenuView/~/basics/profileId/2bb1e634-8de0-4fcf-b05d-b1254a0a40db) | 65000 | [Allow AI](https://entra.microsoft.com/#view/Microsoft_Azure_Network_Access/WebFilteringPolicy.ReactView) | enabled | enabled | allow | Not applicable | Not applicable |\n| [Block Risky AI App Access](https://entra.microsoft.com/#view/Microsoft_Azure_Network_Access/EditProfileMenuBlade.MenuView/~/basics/profileId/0014abeb-60c5-4f89-8f78-b764284bc4f1) | 399 | [Allow ChatGPT](https://entra.microsoft.com/#view/Microsoft_Azure_Network_Access/WebFilteringPolicy.ReactView) | enabled | enabled | allow | [CA46 - Allow internet access to AI](https://entra.microsoft.com/#view/Microsoft_AAD_ConditionalAccess/PolicyBlade/policyId/138504ad-20fb-475f-b159-26d45d339dc3) | enabled |\n| [Finance AI](https://entra.microsoft.com/#view/Microsoft_Azure_Network_Access/EditProfileMenuBlade.MenuView/~/basics/profileId/4905afb6-9b08-4f6a-8ac9-46264e9e9e00) | 400 | [Allow ChatGPT](https://entra.microsoft.com/#view/Microsoft_Azure_Network_Access/WebFilteringPolicy.ReactView) | enabled | enabled | allow | [CA34 - IA - Allow traffic to finance web sites](https://entra.microsoft.com/#view/Microsoft_AAD_ConditionalAccess/PolicyBlade/policyId/ac87d339-5f95-406b-b28b-7b9c0b99ce28) | enabled |\n| [Block Risky AI App Access](https://entra.microsoft.com/#view/Microsoft_Azure_Network_Access/EditProfileMenuBlade.MenuView/~/basics/profileId/0014abeb-60c5-4f89-8f78-b764284bc4f1) | 399 | [Allow Gemini](https://entra.microsoft.com/#view/Microsoft_Azure_Network_Access/WebFilteringPolicy.ReactView) | enabled | enabled | allow | [CA46 - Allow internet access to AI](https://entra.microsoft.com/#view/Microsoft_AAD_ConditionalAccess/PolicyBlade/policyId/138504ad-20fb-475f-b159-26d45d339dc3) | enabled |\n| [Finance AI](https://entra.microsoft.com/#view/Microsoft_Azure_Network_Access/EditProfileMenuBlade.MenuView/~/basics/profileId/4905afb6-9b08-4f6a-8ac9-46264e9e9e00) | 400 | [Allow Gemini](https://entra.microsoft.com/#view/Microsoft_Azure_Network_Access/WebFilteringPolicy.ReactView) | enabled | enabled | allow | [CA34 - IA - Allow traffic to finance web sites](https://entra.microsoft.com/#view/Microsoft_AAD_ConditionalAccess/PolicyBlade/policyId/ac87d339-5f95-406b-b28b-7b9c0b99ce28) | enabled |\n| [Baseline Profile](https://entra.microsoft.com/#view/Microsoft_Azure_Network_Access/EditProfileMenuBlade.MenuView/~/basics/profileId/2bb1e634-8de0-4fcf-b05d-b1254a0a40db) | 65000 | [Allow LinkedIn](https://entra.microsoft.com/#view/Microsoft_Azure_Network_Access/WebFilteringPolicy.ReactView) | enabled | enabled | allow | Not applicable | Not applicable |\n| [Baseline Profile](https://entra.microsoft.com/#view/Microsoft_Azure_Network_Access/EditProfileMenuBlade.MenuView/~/basics/profileId/2bb1e634-8de0-4fcf-b05d-b1254a0a40db) | 65000 | [Allow Sanctioned MCP](https://entra.microsoft.com/#view/Microsoft_Azure_Network_Access/WebFilteringPolicy.ReactView) | enabled | enabled | allow | Not applicable | Not applicable |\n| [Block Risky AI App Access](https://entra.microsoft.com/#view/Microsoft_Azure_Network_Access/EditProfileMenuBlade.MenuView/~/basics/profileId/0014abeb-60c5-4f89-8f78-b764284bc4f1) | 399 | [Block DeepSeek](https://entra.microsoft.com/#view/Microsoft_Azure_Network_Access/WebFilteringPolicy.ReactView) | enabled | enabled | block | [CA46 - Allow internet access to AI](https://entra.microsoft.com/#view/Microsoft_AAD_ConditionalAccess/PolicyBlade/policyId/138504ad-20fb-475f-b159-26d45d339dc3) | enabled |\n| [Baseline Profile](https://entra.microsoft.com/#view/Microsoft_Azure_Network_Access/EditProfileMenuBlade.MenuView/~/basics/profileId/2bb1e634-8de0-4fcf-b05d-b1254a0a40db) | 65000 | [Block Unsanctioned MCP by default](https://entra.microsoft.com/#view/Microsoft_Azure_Network_Access/WebFilteringPolicy.ReactView) | enabled | enabled | block | Not applicable | Not applicable |\n| [Temporary access to Dropbox](https://entra.microsoft.com/#view/Microsoft_Azure_Network_Access/EditProfileMenuBlade.MenuView/~/basics/profileId/5e98d8a3-38d1-4219-8eec-105ff9a7669f) | 210 | [Just in time access to Dropbox](https://entra.microsoft.com/#view/Microsoft_Azure_Network_Access/WebFilteringPolicy.ReactView) | enabled | enabled | allow | [CA35 - Ondemand Dropbox Access](https://entra.microsoft.com/#view/Microsoft_AAD_ConditionalAccess/PolicyBlade/policyId/349bce8e-4b71-4c42-87c3-a7c7d8ea870e) | enabled |\n| [Baseline Profile](https://entra.microsoft.com/#view/Microsoft_Azure_Network_Access/EditProfileMenuBlade.MenuView/~/basics/profileId/2bb1e634-8de0-4fcf-b05d-b1254a0a40db) | 65000 | [Windows](https://entra.microsoft.com/#view/Microsoft_Azure_Network_Access/WebFilteringPolicy.ReactView) | enabled | enabled | allow | Not applicable | Not applicable |\n\r\n\r\n","TestSfiPillar":"Protect networks","TestStatus":"Passed","TestImpact":"Medium","TestPillar":"Network","TestId":"25408","TestRisk":"Medium","TestDescription":"Web content filtering policies are the foundation of internet access control in Global Secure Access. Without any configured policies, users have unrestricted access to all internet destinations, exposing the organization to malware, phishing sites, and inappropriate content. Create filtering policies to block dangerous website categories and establish baseline internet access controls.\r\n\r\n**Remediation action**\r\n\r\n- [Configure web content filtering policies](https://learn.microsoft.com/entra/global-secure-access/how-to-configure-web-content-filtering?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci)\r\n","TestTags":null,"TestMinimumLicense":["Entra_Premium_Internet_Access"],"SkippedReason":null,"TestAppliesTo":null,"TestImplementationCost":"Medium","TestCategory":"Global Secure Access"},{"TestId":"25541","TestCategory":"Azure Network Security","TestImpact":"Low","TestResult":"\r\n✅ All Application Gateway WAF policies are enabled in **Prevention** mode.\n\n\r\n\r\n## [Application Gateway WAF policies](https://portal.azure.com/#view/Microsoft_Azure_HybridNetworking/FirewallManagerMenuBlade/~/wafMenuItem)\r\n\r\n| Policy name | Subscription name | Policy state | Mode | Status |\r\n| :---------- | :---------------- | :----------: | :--: | :----: |\r\n| [WAFAppGWcopilotPolicy](https://portal.azure.com/#resource/subscriptions/ab48f397-fc82-4634-aa52-62dd91b3ebaa/resourceGroups/Woodgrove-RG/providers/Microsoft.Network/applicationGatewayWebApplicationFirewallPolicies/WAFAppGWcopilotPolicy) | [Woodgrove - GTP Demos (External/Sponsored)](https://portal.azure.com/#resource/subscriptions/ab48f397-fc82-4634-aa52-62dd91b3ebaa) | ✅ Enabled | ✅ Prevention | ✅ |\n\r\n\r\n\r\n","SkippedReason":null,"TestMinimumLicense":["Azure WAF","Azure Application Gateway Standard SKU"],"TestAppliesTo":null,"TestTags":null,"TestSfiPillar":"Protect networks","TestImplementationCost":"Low","TestSkipped":"","TestPillar":"Network","TestTitle":"Application Gateway WAF is Enabled in Prevention mode","TestStatus":"Passed","TestDescription":"Azure Application Gateway Web Application Firewall (WAF) protects web applications from common exploits and vulnerabilities, including SQL injection, cross-site scripting, and other OWASP Top 10 threats. WAF operates in two modes: Detection and Prevention. Detection mode logs matched requests but doesn't block traffic, while Prevention mode actively blocks malicious requests before they reach the backend application. When WAF is in Detection mode, web applications remain exposed to exploitation even though threats are being identified.\r\n\r\nWithout WAF in Prevention mode:\r\n\r\n- Threat actors can exploit web application vulnerabilities such as SQL injection and cross-site scripting, because matched requests are only logged, not blocked.\r\n- Organizations lose the active protection that managed and custom WAF rules provide, which reduces WAF to an observability tool rather than a security control.\r\n\r\n**Remediation action**\r\n\r\n- [Configure WAF on Azure Application Gateway](https://learn.microsoft.com/azure/web-application-firewall/ag/ag-overview?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci#waf-modes) to switch the WAF policy from **Detection mode** to **Prevention mode**.\r\n- [Create and manage WAF policies for Application Gateway](https://learn.microsoft.com/azure/web-application-firewall/ag/create-waf-policy-ag?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci) to apply Prevention mode settings across all Application Gateway instances.\r\n","TestRisk":"High"},{"TestId":"26882","TestCategory":"Azure Network Security","TestImpact":"Low","TestResult":"\r\n✅ All Application Gateway WAF policies attached to Application Gateways are enabled, running in Prevention mode, and have the Bot Manager ruleset (Microsoft_BotManagerRuleSet) assigned.\n\n\r\n## [Application Gateway WAF policies](https://portal.azure.com/#browse/Microsoft.Network%2FapplicationGatewayWebApplicationFirewallPolicies)\r\n\r\n| Policy name | Subscription name | Policy state | WAF mode | Bot Manager ruleset version | Status |\r\n| :---------- | :---------------- | :----------- | :------- | :-------------------------- | :----- |\r\n| [WAFAppGWcopilotPolicy](https://portal.azure.com/#resource/subscriptions/ab48f397-fc82-4634-aa52-62dd91b3ebaa/resourceGroups/Woodgrove-RG/providers/Microsoft.Network/applicationGatewayWebApplicationFirewallPolicies/WAFAppGWcopilotPolicy) | [Woodgrove - GTP Demos (External/Sponsored)](https://portal.azure.com/#resource/subscriptions/ab48f397-fc82-4634-aa52-62dd91b3ebaa) | ✅ Enabled | ✅ Prevention | 1.0 | ✅ |\n\r\n\r\n","SkippedReason":null,"TestMinimumLicense":"Azure WAF","TestAppliesTo":null,"TestTags":null,"TestSfiPillar":"Protect networks","TestImplementationCost":"Low","TestSkipped":"","TestPillar":"Network","TestTitle":"Bot protection ruleset is enabled and assigned in Application Gateway WAF","TestStatus":"Passed","TestDescription":"Azure Application Gateway Web Application Firewall (WAF) provides bot protection through the Microsoft Bot Manager ruleset, which identifies and categorizes automated traffic based on behavioral patterns, known bot signatures, and IP reputation. Without bot protection enabled, threat actors leverage automated tools to perform large-scale attacks that would be impractical manually: credential stuffing attacks that test stolen username and password combinations across login endpoints at thousands of attempts per minute, content scraping that extracts proprietary data and pricing information for competitive exploitation, inventory hoarding bots that deplete product availability for legitimate customers, and application-layer denial of service attacks that overwhelm backend resources. These automated attacks often originate from distributed botnets that rotate IP addresses to evade simple rate limiting, making signature-based bot detection essential. The Bot Manager ruleset classifies bots into categories including known good bots (search engines), known bad bots (scrapers, spammers), and unknown bots, allowing granular policy enforcement. Without this classification, malicious bot traffic blends with legitimate requests, consuming application resources and enabling fraud that damages revenue and customer trust.\r\n\r\n**Remediation action**\r\n\r\n- [What is Azure Web Application Firewall on Azure Application Gateway?](https://learn.microsoft.com/en-us/azure/web-application-firewall/ag/ag-overview) - Overview of WAF capabilities on Application Gateway including bot protection\r\n- [Configure bot protection for Web Application Firewall on Azure Application Gateway](https://learn.microsoft.com/en-us/azure/web-application-firewall/ag/bot-protection) - Step-by-step guidance on enabling and configuring bot protection\r\n- [Web Application Firewall bot protection overview](https://learn.microsoft.com/en-us/azure/web-application-firewall/ag/bot-protection-overview) - Detailed documentation of bot categories and detection capabilities\r\n\r\n","TestRisk":"High"},{"TestTitle":"Microsoft 365 traffic is actively flowing through Global Secure Access","TestSkipped":"","TestResult":"\r\n⚠️ Microsoft 365 traffic is flowing through Global Secure Access, but some concerns were detected.\n\n\n## Summary\n\n| Metric | Value |\n| :--- | ---: |\n| Profile Enabled | ✅ Yes |\n| M365 Transactions (7 days) | 1,541 |\n| M365 Blocked Transactions | 0 |\n| Active Devices | 1 |\n| Total Devices | 2 |\n\n\n## Traffic Forwarding Profile\n\n| Property | Value |\n| :--- | :--- |\n| Profile Name | Microsoft 365 traffic forwarding profile |\n| State | enabled |\n| Traffic Type | m365 |\n\n\n## Transaction Summary\n\n| Traffic Type | Total Count | Blocked Count |\n| :--- | ---: | ---: |\n| internet | 7,084 | 0 |\n| microsoft365 | 1,541 | 0 |\n\n*Evaluation Period: 2026-06-01 to 2026-06-08*\n\n\n## Device Usage\n\n| Metric | Count |\n| :--- | ---: |\n| Total Devices | 2 |\n| Active Devices | 1 |\n| Inactive Devices | 1 |\n\n\n## ⚠️ Warnings\n\n- Low active device count (1) - verify client deployment across endpoints\n\n\n[View in Entra Portal: Traffic forwarding](https://entra.microsoft.com/#view/Microsoft_Azure_Network_Access/ForwardingProfile.ReactView)\r\n\r\n","TestSfiPillar":"Protect networks","TestStatus":"Passed","TestImpact":"Low","TestPillar":"Network","TestId":"25376","TestRisk":"High","TestDescription":"When Microsoft 365 traffic bypasses Global Secure Access, organizations lose visibility and control over their most critical productivity workloads. Threat actors who exploit unmonitored Microsoft 365 connections can exfiltrate sensitive data through SharePoint, OneDrive, or Exchange without triggering security policies or generating actionable telemetry. Token theft and replay attacks become more difficult to detect when traffic doesn't flow through the Security Service Edge because source IP correlation with sign-in logs and Conditional Access evaluation can't be applied consistently.\r\n\r\nOrganizations with significant bypassed traffic, whether due to incomplete client deployment, misconfigured forwarding profiles, or users on unmanaged devices, create blind spots where adversary-in-the-middle attacks, credential harvesting, and unauthorized data transfers can proceed undetected. Traffic that bypasses Global Secure Access also can't benefit from compliant network checks in Conditional Access policies, tenant restrictions, or source IP restoration, leaving significant security controls ineffective.\r\n\r\n**Remediation action**\r\n- Enable and configure the Microsoft traffic profile. For more information, see [Enable Microsoft traffic profile](https://learn.microsoft.com/entra/global-secure-access/how-to-manage-microsoft-profile?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci).\r\n- Deploy the Global Secure Access client to all managed devices. For more information, see [Deploy Global Secure Access client](https://learn.microsoft.com/entra/global-secure-access/how-to-install-windows-client?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci).\r\n- Review and configure traffic forwarding rules appropriately. For more information, see [Review traffic forwarding rules](https://learn.microsoft.com/entra/global-secure-access/concept-microsoft-traffic-profile?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci).\r\n","TestTags":null,"TestMinimumLicense":["Entra_Premium_Private_Access","Entra_Premium_Internet_Access"],"SkippedReason":null,"TestAppliesTo":null,"TestImplementationCost":"Medium","TestCategory":"Network security"},{"TestTitle":"Source IP restoration is enabled","TestSkipped":"","TestResult":"\r\n✅ Global Secure Access signaling is enabled.\r\n\r\n","TestSfiPillar":"Protect networks","TestStatus":"Passed","TestImpact":"Low","TestPillar":"Network","TestId":"25370","TestRisk":"Medium","TestDescription":"\r\nWhen organizations deploy Global Secure Access as their cloud-based network proxy, Microsoft's Secure Service Edge infrastructure routes user traffic. If you don't enable source IP restoration, all authentication requests come from the proxy's IP address instead of the user's actual public egress IP.\r\n\r\nWithout this protection:\r\n\r\n- Threat actors who compromise user credentials can authenticate from any location while bypassing IP-based Conditional Access controls and named location policies.\r\n- Microsoft Entra ID Protection risk detections lose visibility into the original user IP address, which degrades the accuracy of risk scoring algorithms.\r\n- Sign-in logs and audit trails no longer show the true source of authentication attempts, which makes incident investigation and forensic analysis more difficult.\r\n\r\n**Remediation action**\r\n\r\n- Enable Global Secure Access signaling in Conditional Access. For more information, see [Source IP restoration](https://learn.microsoft.com/entra/global-secure-access/how-to-source-ip-restoration?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci).\r\n","TestTags":null,"TestMinimumLicense":["Entra_Premium_Private_Access","Entra_Premium_Internet_Access"],"SkippedReason":null,"TestAppliesTo":null,"TestImplementationCost":"Low","TestCategory":"Network"},{"TestTitle":"All Private Access applications have assigned users or groups","TestSkipped":"","TestResult":"\r\n⚠️ No Private Access application is configured in the tenant, please review the documentation on how to enable Private Access applications.\r\n\r\n","TestSfiPillar":"Protect networks","TestStatus":"Investigate","TestImpact":"Medium","TestPillar":"Network","TestId":"25481","TestRisk":"High","TestDescription":"When Microsoft Entra Private Access applications lack user or group assignments, users can't establish tunnels through the application to reach the configured fully qualified domain names (FQDNs) and IP addresses. This restriction prevents access to protected internal resources. Without assignments, organizations can't enforce Conditional Access policies because these policies require explicit user-to-application relationships to evaluate risk signals, device compliance, and authentication strength requirements.\r\n\r\nWithout user assignments on Private Access applications:\r\n\r\n- Organizations lose the ability to enforce least privilege access controls where users get access only to the specific resources they need.\r\n- Organizations can't apply risk-based access policies that block or challenge authentication based on sign-in risk, user risk, or device compliance.\r\n- Identity protection signals that detect credential compromise, impossible travel, or anonymous IP addresses can't protect private resources.\r\n\r\n**Remediation action**\r\n\r\n- [Assign users and groups to Private Access applications](https://learn.microsoft.com/entra/global-secure-access/how-to-configure-per-app-access?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci#assign-users-and-groups) to enable Zero Trust access controls and Conditional Access enforcement.\r\n","TestTags":null,"TestMinimumLicense":["Entra_Premium_Private_Access"],"SkippedReason":null,"TestAppliesTo":null,"TestImplementationCost":"Low","TestCategory":"Global Secure Access"},{"TestId":"61002","TestCategory":"AI Threat Detection","TestImpact":"Low","TestResult":"\r\n✅ Microsoft Sentinel is onboarded on at least one Log Analytics workspace.\n\n\r\n\r\n### [Workspaces and their Sentinel onboarding state](https://portal.azure.com/#view/HubsExtension/BrowseResource/resourceType/Microsoft.OperationalInsights%2Fworkspaces)\r\n\r\n| Subscription | Workspace | Resource group | Sentinel onboarded |\r\n| :----------- | :-------- | :------------- | :----------------- |\r\n| Woodgrove - GTP Demos (External/Sponsored) | [D4SQL-ab48f397fc824634aa5262dd91b3ebaa-eastus](https://portal.azure.com/#resource/subscriptions/ab48f397-fc82-4634-aa52-62dd91b3ebaa/resourceGroups/DefaultResourceGroup-EUS/providers/Microsoft.OperationalInsights/workspaces/D4SQL-ab48f397fc824634aa5262dd91b3ebaa-eastus/overview) | defaultresourcegroup-eus | ❌ No |\n| Woodgrove - GTP Demos (External/Sponsored) | [D4SQL-ab48f397fc824634aa5262dd91b3ebaa-westus2](https://portal.azure.com/#resource/subscriptions/ab48f397-fc82-4634-aa52-62dd91b3ebaa/resourceGroups/DefaultResourceGroup-WUS2/providers/Microsoft.OperationalInsights/workspaces/D4SQL-ab48f397fc824634aa5262dd91b3ebaa-westus2/overview) | defaultresourcegroup-wus2 | ❌ No |\n| Woodgrove - GTP Demos (External/Sponsored) | [Default-ab48f397-fc82-4634-aa52-62dd91b3ebaa-eastus](https://portal.azure.com/#resource/subscriptions/ab48f397-fc82-4634-aa52-62dd91b3ebaa/resourceGroups/woodgrove-MDC-RG/providers/Microsoft.OperationalInsights/workspaces/Default-ab48f397-fc82-4634-aa52-62dd91b3ebaa-eastus/overview) | woodgrove-mdc-rg | ❌ No |\n| Woodgrove - GTP Demos (External/Sponsored) | [DefaultWorkspace-ab48f397-fc82-4634-aa52-62dd91b3ebaa-CCAN](https://portal.azure.com/#resource/subscriptions/ab48f397-fc82-4634-aa52-62dd91b3ebaa/resourceGroups/DefaultResourceGroup-CCAN/providers/Microsoft.OperationalInsights/workspaces/DefaultWorkspace-ab48f397-fc82-4634-aa52-62dd91b3ebaa-CCAN/overview) | defaultresourcegroup-ccan | ❌ No |\n| Woodgrove - GTP Demos (External/Sponsored) | [DefaultWorkspace-ab48f397-fc82-4634-aa52-62dd91b3ebaa-CUS](https://portal.azure.com/#resource/subscriptions/ab48f397-fc82-4634-aa52-62dd91b3ebaa/resourceGroups/DefaultResourceGroup-CUS/providers/Microsoft.OperationalInsights/workspaces/DefaultWorkspace-ab48f397-fc82-4634-aa52-62dd91b3ebaa-CUS/overview) | defaultresourcegroup-cus | ❌ No |\n| Woodgrove - GTP Demos (External/Sponsored) | [DefaultWorkspace-ab48f397-fc82-4634-aa52-62dd91b3ebaa-EUS](https://portal.azure.com/#resource/subscriptions/ab48f397-fc82-4634-aa52-62dd91b3ebaa/resourceGroups/DefaultResourceGroup-EUS/providers/Microsoft.OperationalInsights/workspaces/DefaultWorkspace-ab48f397-fc82-4634-aa52-62dd91b3ebaa-EUS/overview) | defaultresourcegroup-eus | ❌ No |\n| Woodgrove - GTP Demos (External/Sponsored) | [DefaultWorkspace-ab48f397-fc82-4634-aa52-62dd91b3ebaa-SCUS](https://portal.azure.com/#resource/subscriptions/ab48f397-fc82-4634-aa52-62dd91b3ebaa/resourceGroups/DefaultResourceGroup-SCUS/providers/Microsoft.OperationalInsights/workspaces/DefaultWorkspace-ab48f397-fc82-4634-aa52-62dd91b3ebaa-SCUS/overview) | defaultresourcegroup-scus | ❌ No |\n| Woodgrove - GTP Demos (External/Sponsored) | [DefaultWorkspace-ab48f397-fc82-4634-aa52-62dd91b3ebaa-WEU](https://portal.azure.com/#resource/subscriptions/ab48f397-fc82-4634-aa52-62dd91b3ebaa/resourceGroups/DefaultResourceGroup-WEU/providers/Microsoft.OperationalInsights/workspaces/DefaultWorkspace-ab48f397-fc82-4634-aa52-62dd91b3ebaa-WEU/overview) | defaultresourcegroup-weu | ❌ No |\n| Woodgrove - GTP Demos (External/Sponsored) | [DefaultWorkspace-ab48f397-fc82-4634-aa52-62dd91b3ebaa-WUS2](https://portal.azure.com/#resource/subscriptions/ab48f397-fc82-4634-aa52-62dd91b3ebaa/resourceGroups/DefaultResourceGroup-WUS2/providers/Microsoft.OperationalInsights/workspaces/DefaultWorkspace-ab48f397-fc82-4634-aa52-62dd91b3ebaa-WUS2/overview) | defaultresourcegroup-wus2 | ❌ No |\n| Cloud Security | [DefaultWorkspace-ee301620-7f47-414b-97b7-9d84046f4d38-CUS](https://portal.azure.com/#resource/subscriptions/ee301620-7f47-414b-97b7-9d84046f4d38/resourceGroups/DefaultResourceGroup-CUS/providers/Microsoft.OperationalInsights/workspaces/DefaultWorkspace-ee301620-7f47-414b-97b7-9d84046f4d38-CUS/overview) | defaultresourcegroup-cus | ❌ No |\n| Woodgrove - GTP Demos (External/Sponsored) | [SentinelGraphEUAP](https://portal.azure.com/#resource/subscriptions/ab48f397-fc82-4634-aa52-62dd91b3ebaa/resourceGroups/Woodgrove-MSG-RG/providers/Microsoft.OperationalInsights/workspaces/SentinelGraphEUAP/overview) | woodgrove-msg-rg | ✅ Yes |\n| Woodgrove - GTP Demos (External/Sponsored) | [SentinelGraphNOE](https://portal.azure.com/#resource/subscriptions/ab48f397-fc82-4634-aa52-62dd91b3ebaa/resourceGroups/Woodgrove-RG/providers/Microsoft.OperationalInsights/workspaces/SentinelGraphNOE/overview) | woodgrove-rg | ✅ Yes |\n| Woodgrove - GTP Demos (External/Sponsored) | [SentinelGraphWU2](https://portal.azure.com/#resource/subscriptions/ab48f397-fc82-4634-aa52-62dd91b3ebaa/resourceGroups/Woodgrove-RG/providers/Microsoft.OperationalInsights/workspaces/SentinelGraphWU2/overview) | woodgrove-rg | ✅ Yes |\n| Woodgrove - GTP Demos (External/Sponsored) | [Woodgrove-LogAnalyiticsWorkspace](https://portal.azure.com/#resource/subscriptions/ab48f397-fc82-4634-aa52-62dd91b3ebaa/resourceGroups/Woodgrove-RG/providers/Microsoft.OperationalInsights/workspaces/Woodgrove-LogAnalyiticsWorkspace/overview) | woodgrove-rg | ✅ Yes |\n| Woodgrove - GTP Demos (External/Sponsored) | [desired-state-monitor](https://portal.azure.com/#resource/subscriptions/ab48f397-fc82-4634-aa52-62dd91b3ebaa/resourceGroups/ZTEnv01DesiredState/providers/Microsoft.OperationalInsights/workspaces/desired-state-monitor/overview) | ztenv01desiredstate | ✅ Yes |\n| Woodgrove - SANDBOXv2 | [kpa588-3556-resource-logs](https://portal.azure.com/#resource/subscriptions/855b095a-349d-42bf-b161-f93dc2438660/resourceGroups/Hyena_demo/providers/Microsoft.OperationalInsights/workspaces/kpa588-3556-resource-logs/overview) | hyena_demo | ❌ No |\n| Cloud Security | [law-489n-procurementagent](https://portal.azure.com/#resource/subscriptions/ee301620-7f47-414b-97b7-9d84046f4d38/resourceGroups/rg-Zava-Foundry-489n/providers/Microsoft.OperationalInsights/workspaces/law-489n-procurementagent/overview) | rg-zava-foundry-489n | ❌ No |\n| Woodgrove - GTP Demos (External/Sponsored) | [law-management-eastus](https://portal.azure.com/#resource/subscriptions/ab48f397-fc82-4634-aa52-62dd91b3ebaa/resourceGroups/rg-management-eastus/providers/Microsoft.OperationalInsights/workspaces/law-management-eastus/overview) | rg-management-eastus | ❌ No |\n| Cloud Security | [law-yxhw-procurementagent](https://portal.azure.com/#resource/subscriptions/ee301620-7f47-414b-97b7-9d84046f4d38/resourceGroups/rg-Zava-Foundry-yxhw/providers/Microsoft.OperationalInsights/workspaces/law-yxhw-procurementagent/overview) | rg-zava-foundry-yxhw | ❌ No |\n| Cloud Security | [law-zava-0c87ac883406](https://portal.azure.com/#resource/subscriptions/ee301620-7f47-414b-97b7-9d84046f4d38/resourceGroups/rg-Zava-Resources-489n/providers/Microsoft.OperationalInsights/workspaces/law-zava-0c87ac883406/overview) | rg-zava-resources-489n | ❌ No |\n| Cloud Security | [law-zava-5d2db0938aec](https://portal.azure.com/#resource/subscriptions/ee301620-7f47-414b-97b7-9d84046f4d38/resourceGroups/rg-Zava-Resources-yxhw/providers/Microsoft.OperationalInsights/workspaces/law-zava-5d2db0938aec/overview) | rg-zava-resources-yxhw | ❌ No |\n| Cloud Security | [law-zava-mdc-04ee6589](https://portal.azure.com/#resource/subscriptions/ee301620-7f47-414b-97b7-9d84046f4d38/resourceGroups/rg-Zava-Resources-489n/providers/Microsoft.OperationalInsights/workspaces/law-zava-mdc-04ee6589/overview) | rg-zava-resources-489n | ❌ No |\n| Cloud Security | [law-zava-mdc-04ee6589](https://portal.azure.com/#resource/subscriptions/ee301620-7f47-414b-97b7-9d84046f4d38/resourceGroups/rg-Zava-Resources-yxhw/providers/Microsoft.OperationalInsights/workspaces/law-zava-mdc-04ee6589/overview) | rg-zava-resources-yxhw | ❌ No |\n| Woodgrove - GTP Demos (External/Sponsored) | [logs-wgyubipreregapp](https://portal.azure.com/#resource/subscriptions/ab48f397-fc82-4634-aa52-62dd91b3ebaa/resourceGroups/WoodgroveYubicoPOC/providers/Microsoft.OperationalInsights/workspaces/logs-wgyubipreregapp/overview) | woodgroveyubicopoc | ❌ No |\n| Woodgrove - SANDBOXv2 | [managed-appinsighthyenasdemo-ws](https://portal.azure.com/#resource/subscriptions/855b095a-349d-42bf-b161-f93dc2438660/resourceGroups/ai_appinsighthyenasdemo_c3de7b19-8320-45a0-a2ed-ffef43d84dee_managed/providers/microsoft.operationalinsights/workspaces/managed-appinsighthyenasdemo-ws/overview) | ai_appinsighthyenasdemo_c3de7b19-8320-45a0-a2ed-ffef43d84dee_managed | ❌ No |\n| External ID | [managed-contoso-online-ws](https://portal.azure.com/#resource/subscriptions/ffd46609-01a4-4bda-8a65-7472c5d141b4/resourceGroups/ai_zava-private-online_07df1fba-2e18-4285-b43c-1eb0e08931e1_managed/providers/microsoft.operationalinsights/workspaces/managed-contoso-online-ws/overview) | ai_zava-private-online_07df1fba-2e18-4285-b43c-1eb0e08931e1_managed | ❌ No |\n| Woodgrove - SANDBOXv2 | [multi-agent-sandbox-logs-dev](https://portal.azure.com/#resource/subscriptions/855b095a-349d-42bf-b161-f93dc2438660/resourceGroups/scp-agent-chat-demo/providers/Microsoft.OperationalInsights/workspaces/multi-agent-sandbox-logs-dev/overview) | scp-agent-chat-demo | ❌ No |\n| Woodgrove - GTP Demos (External/Sponsored) | [woodgrove-la-mdc-arc](https://portal.azure.com/#resource/subscriptions/ab48f397-fc82-4634-aa52-62dd91b3ebaa/resourceGroups/woodgrove-mdc-arc/providers/Microsoft.OperationalInsights/workspaces/woodgrove-la-mdc-arc/overview) | woodgrove-mdc-arc | ❌ No |\n\r\n\r\n**Summary:**\r\n\r\n- Total workspaces: 28\r\n- Workspaces with Sentinel onboarded: 5\r\n- Workspaces skipped (insufficient permissions): 0\r\n","SkippedReason":null,"TestMinimumLicense":"Microsoft_Sentinel","TestAppliesTo":null,"TestTags":null,"TestSfiPillar":"Monitor and detect cyberthreats","TestImplementationCost":"Medium","TestSkipped":"","TestPillar":"AI","TestTitle":"Microsoft Sentinel is onboarded on at least one Log Analytics workspace","TestStatus":"Passed","TestDescription":"Microsoft Sentinel is a cloud-native SIEM that correlates security signals from across your environment into incidents your SOC can act on. AI workloads generate events across identity, cloud posture, and threat protection simultaneously — a central workspace is the only place those signals can be assembled into a coherent incident. This check verifies Sentinel is onboarded to at least one Log Analytics workspace, which every other AI threat detection control in this pillar depends on.\r\n\r\nWhen Microsoft Sentinel is not onboarded to a Log Analytics workspace, security signals from AI workloads land in isolated product portals with no central point of correlation. Threat actors who compromise an agent identity can exploit this fragmentation because each product sees only its own slice of the attack — an anomalous Entra sign-in, a bulk Graph API call, and a Defender for AI Services alert each get triaged in isolation with no shared context. Without Sentinel, the organization cannot assemble the cross-product pattern that would reveal the full attack chain and trigger an automated response.\r\n\r\n**Remediation action**\r\n\r\n- [What is Microsoft Sentinel?](https://learn.microsoft.com/azure/sentinel/overview)\r\n- [Quickstart: Onboard Microsoft Sentinel](https://learn.microsoft.com/azure/sentinel/quickstart-onboard)\r\n- [Design your Microsoft Sentinel workspace architecture](https://learn.microsoft.com/azure/sentinel/design-your-workspace-architecture)\r\n- [Sentinel onboarding states — Create (REST API)](https://learn.microsoft.com/rest/api/securityinsights/sentinel-onboarding-states/create)\r\n\r\n","TestRisk":"High"},{"TestTitle":"Agent identities and blueprint principals have assigned technical owners and no disabled agents remain in the directory","TestSkipped":"","TestResult":"\r\n❌ One or more agent identities or blueprint principals have no assigned owner, or one or more disabled agent identities or blueprint principals exist in the directory.\n\n\n**Agent identity inventory:**\n\n* [Agent identities](https://entra.microsoft.com/?feature.msaljs=true#view/Microsoft_AAD_RegisteredApps/AllAgents.MenuView/~/allAgentIds): 431\n* [Blueprint principals](https://entra.microsoft.com/?feature.msaljs=true#view/Microsoft_AAD_RegisteredApps/AllAgents.MenuView/~/allAgentBlueprints): 63\n* Ownerless objects: 410\n* Disabled objects: 19\n\r\n\r\n## Agent identities and blueprint principals without an assigned owner\r\n\r\n| Object type | Display name | Account enabled |\r\n| :---------- | :----------- | :-------------- |\r\n| `agentIdentity` | [\\[Actor\\]-AgentID](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/AgentIdentity.MenuView/~/overview/objectId/def723dc-01f5-4cec-aaa3-9694bacb5a0e/menuId/overview) | ❌ Disabled |\n| `agentIdentity` | [Access Review Agent](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/AgentIdentity.MenuView/~/overview/objectId/9984e720-5b95-4822-95a0-1c688cd25ec3/menuId/overview) | ✅ Enabled |\n| `agentIdentity` | [Access Review Agent V2 (Security Copilot)](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/AgentIdentity.MenuView/~/overview/objectId/f4b5c7bc-c23c-4e42-b0ef-ba1ec64bea58/menuId/overview) | ✅ Enabled |\n| `agentIdentity` | [Access Review Agent V2 (Security Copilot)](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/AgentIdentity.MenuView/~/overview/objectId/dd5517fc-fa00-4ec9-83b3-cb93b40395f2/menuId/overview) | ✅ Enabled |\n| `agentIdentity` | [Account Management Agent](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/AgentIdentity.MenuView/~/overview/objectId/f3d7fba1-9f55-4cee-b839-fcfbf4b8c15d/menuId/overview) | ✅ Enabled |\n| `agentIdentity` | [Accounts Payable Agent](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/AgentIdentity.MenuView/~/overview/objectId/164ed609-79a3-4657-b6db-fa5d7f12acfb/menuId/overview) | ✅ Enabled |\n| `agentIdentity` | [Agent (Microsoft Copilot Studio)](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/AgentIdentity.MenuView/~/overview/objectId/be09c56b-7c39-443b-a135-2b145f3f0bd9/menuId/overview) | ✅ Enabled |\n| `agentIdentity` | [Agent (Microsoft Copilot Studio)](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/AgentIdentity.MenuView/~/overview/objectId/3e5445eb-dcb4-4dee-b05d-78861f0d34f7/menuId/overview) | ✅ Enabled |\n| `agentIdentity` | [Agent (Microsoft Copilot Studio)](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/AgentIdentity.MenuView/~/overview/objectId/a86bdabb-decf-41af-80b8-1eb433de26ec/menuId/overview) | ✅ Enabled |\n| `agentIdentity` | [Agent (Microsoft Copilot Studio)](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/AgentIdentity.MenuView/~/overview/objectId/a9360e7b-e3de-4269-9833-c763299d2caa/menuId/overview) | ✅ Enabled |\n| `agentIdentity` | [Agent (Microsoft Copilot Studio)](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/AgentIdentity.MenuView/~/overview/objectId/d72c00b5-2ad2-4da2-996c-26d26ef40baa/menuId/overview) | ✅ Enabled |\n| `agentIdentity` | [Agent (Microsoft Copilot Studio)](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/AgentIdentity.MenuView/~/overview/objectId/b1216bba-c257-4595-88d3-6719bcbcf009/menuId/overview) | ✅ Enabled |\n| `agentIdentity` | [Agent (Microsoft Copilot Studio)](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/AgentIdentity.MenuView/~/overview/objectId/4e05cc82-f443-4673-ba55-9e4eecbf8b73/menuId/overview) | ✅ Enabled |\n| `agentIdentity` | [Agent (Microsoft Copilot Studio)](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/AgentIdentity.MenuView/~/overview/objectId/ebce48f6-2acc-4779-922c-1b95a74803a7/menuId/overview) | ✅ Enabled |\n| `agentIdentity` | [Agent (Microsoft Copilot Studio)](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/AgentIdentity.MenuView/~/overview/objectId/5708d637-0041-43b9-8daf-96241d8ada2c/menuId/overview) | ✅ Enabled |\n| `agentIdentity` | [Agent (Microsoft Copilot Studio)](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/AgentIdentity.MenuView/~/overview/objectId/b701f2e6-c9c9-431c-b110-3cc407bfac56/menuId/overview) | ✅ Enabled |\n| `agentIdentity` | [Agent (Microsoft Copilot Studio)](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/AgentIdentity.MenuView/~/overview/objectId/b02f7fef-5051-4ed0-923e-0a37ec8869a2/menuId/overview) | ✅ Enabled |\n| `agentIdentity` | [Agent (Microsoft Copilot Studio)](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/AgentIdentity.MenuView/~/overview/objectId/f3864bdd-dad9-483d-b2b8-03a2360cbf78/menuId/overview) | ✅ Enabled |\n| `agentIdentity` | [Agent (Microsoft Copilot Studio)](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/AgentIdentity.MenuView/~/overview/objectId/30e69f5b-b69f-44f0-b4a4-3b4ba4880604/menuId/overview) | ✅ Enabled |\n| `agentIdentity` | [Agent (Microsoft Copilot Studio)](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/AgentIdentity.MenuView/~/overview/objectId/63bb200d-6e7a-4940-acd5-7a2b295ca210/menuId/overview) | ✅ Enabled |\n| `agentIdentity` | [Agent (Microsoft Copilot Studio)](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/AgentIdentity.MenuView/~/overview/objectId/1aa4bf63-9522-43d0-9b30-c01da7e2c213/menuId/overview) | ✅ Enabled |\n| `agentIdentity` | [Agent (Microsoft Copilot Studio)](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/AgentIdentity.MenuView/~/overview/objectId/994d3d2e-1319-4af4-8fb7-9968019163fd/menuId/overview) | ✅ Enabled |\n| `agentIdentity` | [Agent (Microsoft Copilot Studio)](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/AgentIdentity.MenuView/~/overview/objectId/c4885904-6043-47ef-8cd1-ccbef529bd37/menuId/overview) | ✅ Enabled |\n| `agentIdentity` | [Agent (Microsoft Copilot Studio)](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/AgentIdentity.MenuView/~/overview/objectId/96810283-7562-4a12-97c5-46296409370b/menuId/overview) | ✅ Enabled |\n| `agentIdentity` | [Agent (Microsoft Copilot Studio)](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/AgentIdentity.MenuView/~/overview/objectId/15babb6a-2496-4ebf-853c-c59690506f1e/menuId/overview) | ✅ Enabled |\n| `agentIdentity` | [Agent (Microsoft Copilot Studio)](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/AgentIdentity.MenuView/~/overview/objectId/587a3b3f-7ead-4556-bd36-e0ce88eab2d2/menuId/overview) | ✅ Enabled |\n| `agentIdentity` | [Agent (Microsoft Copilot Studio)](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/AgentIdentity.MenuView/~/overview/objectId/24ce9be5-a954-4f74-82ff-ac334ff3d276/menuId/overview) | ✅ Enabled |\n| `agentIdentity` | [Agent (Microsoft Copilot Studio)](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/AgentIdentity.MenuView/~/overview/objectId/16591a98-ed91-45b7-b3ca-2f3a6d05916e/menuId/overview) | ✅ Enabled |\n| `agentIdentity` | [Agent (Microsoft Copilot Studio)](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/AgentIdentity.MenuView/~/overview/objectId/29e7b171-558c-4116-b492-43a6cd2ff8f7/menuId/overview) | ✅ Enabled |\n| `agentIdentity` | [Agent (Microsoft Copilot Studio)](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/AgentIdentity.MenuView/~/overview/objectId/33cacd91-01f8-4fc4-8208-710ff342e319/menuId/overview) | ✅ Enabled |\n| `agentIdentity` | [Agent (Microsoft Copilot Studio)](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/AgentIdentity.MenuView/~/overview/objectId/c2fadda1-c424-4cf9-ac72-f3058a285278/menuId/overview) | ✅ Enabled |\n| `agentIdentity` | [Agent 1 (Microsoft Copilot Studio)](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/AgentIdentity.MenuView/~/overview/objectId/563d685b-03f8-4db9-85b1-41877e022a01/menuId/overview) | ✅ Enabled |\n| `agentIdentity` | [Agent 1 (Microsoft Copilot Studio)](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/AgentIdentity.MenuView/~/overview/objectId/eac0012d-1b62-4af1-92f4-64a84e8f7b1b/menuId/overview) | ✅ Enabled |\n| `agentIdentity` | [Agent 1 (Microsoft Copilot Studio)](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/AgentIdentity.MenuView/~/overview/objectId/d445a4d8-fc51-41cd-888e-6d5ff5542065/menuId/overview) | ✅ Enabled |\n| `agentIdentity` | [Agent 1 (Microsoft Copilot Studio)](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/AgentIdentity.MenuView/~/overview/objectId/647b6278-181a-47e0-80e4-6dda528fdd95/menuId/overview) | ✅ Enabled |\n| `agentIdentity` | [Agent 10 (Microsoft Copilot Studio)](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/AgentIdentity.MenuView/~/overview/objectId/e1d6a13a-4237-41a5-9e18-9948fe8a5c30/menuId/overview) | ✅ Enabled |\n| `agentIdentity` | [Agent 2 (Microsoft Copilot Studio)](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/AgentIdentity.MenuView/~/overview/objectId/d391f23c-2745-4e79-8131-201d448d9395/menuId/overview) | ✅ Enabled |\n| `agentIdentity` | [Agent 2 (Microsoft Copilot Studio)](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/AgentIdentity.MenuView/~/overview/objectId/80e34cba-10db-46bb-9c55-3136648d0e78/menuId/overview) | ✅ Enabled |\n| `agentIdentity` | [Agent 2 (Microsoft Copilot Studio)](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/AgentIdentity.MenuView/~/overview/objectId/136f701b-7a21-4ef9-961e-68721dd80d5c/menuId/overview) | ✅ Enabled |\n| `agentIdentity` | [Agent 3 (Microsoft Copilot Studio)](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/AgentIdentity.MenuView/~/overview/objectId/351df030-23cb-4fb0-b307-7bffaf673372/menuId/overview) | ✅ Enabled |\n| `agentIdentity` | [Agent 4 (Microsoft Copilot Studio)](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/AgentIdentity.MenuView/~/overview/objectId/df23d3dd-2873-456a-9049-eb7b74df882c/menuId/overview) | ✅ Enabled |\n| `agentIdentity` | [Agent 5 (Microsoft Copilot Studio)](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/AgentIdentity.MenuView/~/overview/objectId/3e927c64-36aa-4b91-974a-54d63dab893b/menuId/overview) | ✅ Enabled |\n| `agentIdentity` | [Agent 6 (Microsoft Copilot Studio)](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/AgentIdentity.MenuView/~/overview/objectId/f0bc5aa8-9f9b-47f9-add0-ab64576f9789/menuId/overview) | ✅ Enabled |\n| `agentIdentity` | [Agent 6 (Microsoft Copilot Studio)](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/AgentIdentity.MenuView/~/overview/objectId/a30695df-8362-40d8-ba28-2deb829dd8fb/menuId/overview) | ✅ Enabled |\n| `agentIdentity` | [Agent 7 (Microsoft Copilot Studio)](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/AgentIdentity.MenuView/~/overview/objectId/c4859a46-d4ed-44bf-97fb-39bd94bd08a9/menuId/overview) | ✅ Enabled |\n| `agentIdentity` | [Agent 7 (Microsoft Copilot Studio)](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/AgentIdentity.MenuView/~/overview/objectId/23c2e9f1-4ddf-47c9-81ad-7bdc47749abc/menuId/overview) | ✅ Enabled |\n| `agentIdentity` | [Agent 7 (Microsoft Copilot Studio)](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/AgentIdentity.MenuView/~/overview/objectId/9eb2bbff-c9c0-4009-84d9-2536f8c888eb/menuId/overview) | ✅ Enabled |\n| `agentIdentity` | [Agent 7 (Microsoft Copilot Studio)](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/AgentIdentity.MenuView/~/overview/objectId/20ec23e7-a3d1-4cc6-87ae-fa2293444dcb/menuId/overview) | ✅ Enabled |\n| `agentIdentity` | [Agent 7 (Microsoft Copilot Studio)](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/AgentIdentity.MenuView/~/overview/objectId/da7f77ef-8c1d-43a5-b7c3-a82aab28acc7/menuId/overview) | ✅ Enabled |\n| `agentIdentity` | [Agent 8 (Microsoft Copilot Studio)](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/AgentIdentity.MenuView/~/overview/objectId/7f1d46e2-1a5b-4932-a5cb-2a41a7b0de25/menuId/overview) | ✅ Enabled |\n| `agentIdentity` | [Agent 8 (Microsoft Copilot Studio)](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/AgentIdentity.MenuView/~/overview/objectId/2780eb01-1ca2-4bbf-8a8f-b30f2491bfb8/menuId/overview) | ✅ Enabled |\n| `agentIdentity` | [Agent 9 (Microsoft Copilot Studio)](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/AgentIdentity.MenuView/~/overview/objectId/04d628d1-ae2f-4c82-9343-4220552a1332/menuId/overview) | ✅ Enabled |\n| `agentIdentity` | [Agent 9 (Microsoft Copilot Studio)](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/AgentIdentity.MenuView/~/overview/objectId/2516b6ce-c48e-4ac4-aa0d-0112f8cf9371/menuId/overview) | ✅ Enabled |\n| `agentIdentity` | [Agent 9 (Microsoft Copilot Studio)](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/AgentIdentity.MenuView/~/overview/objectId/56d211ec-d865-4212-82ea-28815b6219ab/menuId/overview) | ✅ Enabled |\n| `agentIdentity` | [Agent MK (Microsoft Copilot Studio)](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/AgentIdentity.MenuView/~/overview/objectId/275234a9-e9e5-45ea-aadb-55aba3fc8970/menuId/overview) | ✅ Enabled |\n| `agentIdentity` | [Agent Starter (Microsoft Copilot Studio)](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/AgentIdentity.MenuView/~/overview/objectId/e0d330b2-1fc9-4b99-97fe-9e4e130bd11f/menuId/overview) | ✅ Enabled |\n| `agentIdentity` | [Agent365 CUA Automation (Microsoft Copilot Studio)](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/AgentIdentity.MenuView/~/overview/objectId/0cbea866-5299-4509-b777-e08944d900c2/menuId/overview) | ✅ Enabled |\n| `agentIdentity` | [ai-u16981-8299-demo-u16981-AgentIdentity](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/AgentIdentity.MenuView/~/overview/objectId/80fc5ea4-1fa9-4778-8fd7-229c09139943/menuId/overview) | ✅ Enabled |\n| `agentIdentity` | [Alert Triage Agent in Data Loss Prevention (Security Copilot)](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/AgentIdentity.MenuView/~/overview/objectId/2b06898c-6375-477d-ae92-2580bd19657b/menuId/overview) | ✅ Enabled |\n| `agentIdentity` | [Alert Triage Agent in Insider Risk Management (Security Copilot)](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/AgentIdentity.MenuView/~/overview/objectId/5f1e50f9-5078-46a5-aac2-faa45019d9ab/menuId/overview) | ✅ Enabled |\n| `agentIdentity` | [Anomaly Detection Agent](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/AgentIdentity.MenuView/~/overview/objectId/8f1481d6-9f2e-4e4f-8066-494762a8e6d8/menuId/overview) | ✅ Enabled |\n| `agentIdentity` | [API Gateway Monitor](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/AgentIdentity.MenuView/~/overview/objectId/33e7f440-ea68-4fc1-9227-a98a5f9465e3/menuId/overview) | ✅ Enabled |\n| `agentIdentity` | [Application Lifecycle Agent (Security Copilot)](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/AgentIdentity.MenuView/~/overview/objectId/5dafdd16-9f83-40dd-a132-858d33995df8/menuId/overview) | ✅ Enabled |\n| `agentIdentity` | [Application Lifecycle Agent (Security Copilot)](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/AgentIdentity.MenuView/~/overview/objectId/e4985953-f2c0-4a31-944b-57653c648a14/menuId/overview) | ✅ Enabled |\n| `agentIdentity` | [Asset Tracking Agent](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/AgentIdentity.MenuView/~/overview/objectId/11a398ba-e430-47b5-93e3-fc9f29f7c0ee/menuId/overview) | ✅ Enabled |\n| `agentIdentity` | [Audit Trail Agent](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/AgentIdentity.MenuView/~/overview/objectId/0b5f8462-fb27-4667-b3a5-c8dce7b362ef/menuId/overview) | ✅ Enabled |\n| `agentIdentity` | [Backup & Recovery Agent](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/AgentIdentity.MenuView/~/overview/objectId/2ced2dba-1fe3-442d-9546-b5bbc4cc6a57/menuId/overview) | ✅ Enabled |\n| `agentIdentity` | [BertAgent (Microsoft Copilot Studio)](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/AgentIdentity.MenuView/~/overview/objectId/0496d66a-6beb-4f7a-abd9-29ce01b13738/menuId/overview) | ✅ Enabled |\n| `agentIdentity` | [Billing Support Agent](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/AgentIdentity.MenuView/~/overview/objectId/4bd278e8-13ac-4166-b055-5709e28a7b84/menuId/overview) | ✅ Enabled |\n| `agentIdentity` | [Blue Agent (Microsoft Copilot Studio)](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/AgentIdentity.MenuView/~/overview/objectId/ca4e7269-07ab-4cdc-b104-d0da3feb1631/menuId/overview) | ✅ Enabled |\n| `agentIdentity` | [Budget Tracking Agent](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/AgentIdentity.MenuView/~/overview/objectId/7167d9a5-8128-4cee-be88-8e4a37a2cb6a/menuId/overview) | ✅ Enabled |\n| `agentIdentity` | [Business Intelligence Agent](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/AgentIdentity.MenuView/~/overview/objectId/0483a1ef-3cfd-4d66-8353-640870b81a4d/menuId/overview) | ✅ Enabled |\n| `agentIdentity` | [Campaign Analytics Agent](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/AgentIdentity.MenuView/~/overview/objectId/1f5ce6dd-2a0a-4a90-81ec-be115bfc48b0/menuId/overview) | ✅ Enabled |\n| `agentIdentity` | [Capacity Forecaster](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/AgentIdentity.MenuView/~/overview/objectId/2efdb8fb-cda9-437b-a5b4-276d6b32889e/menuId/overview) | ✅ Enabled |\n| `agentIdentity` | [Capacity Planning Agent](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/AgentIdentity.MenuView/~/overview/objectId/e2cd2006-6dc2-4ec5-b79b-4100788b4928/menuId/overview) | ✅ Enabled |\n| `agentIdentity` | [Case Enrichment Onboarding Agent (Microsoft Copilot Studio)](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/AgentIdentity.MenuView/~/overview/objectId/319ff146-3d6c-486a-9c1c-097d036f0834/menuId/overview) | ✅ Enabled |\n| `agentIdentity` | [Case Management Agent (Microsoft Copilot Studio)](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/AgentIdentity.MenuView/~/overview/objectId/78c3ff34-0e73-40cc-844e-2e2d85d2f042/menuId/overview) | ✅ Enabled |\n| `agentIdentity` | [Certificate Manager](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/AgentIdentity.MenuView/~/overview/objectId/1f7d32f7-ea52-4319-a0be-5e20b0b5f203/menuId/overview) | ✅ Enabled |\n| `agentIdentity` | [Chain Management Assistant (Microsoft Copilot Studio)](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/AgentIdentity.MenuView/~/overview/objectId/cb1244a1-b8eb-4d0e-b2ea-1fdce167d847/menuId/overview) | ✅ Enabled |\n| `agentIdentity` | [Chain-Detection-Pattern-Demo (Microsoft Copilot Studio)](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/AgentIdentity.MenuView/~/overview/objectId/df591cfd-d0ac-4208-bff3-a4e546d39324/menuId/overview) | ✅ Enabled |\n| `agentIdentity` | [Change Management Agent](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/AgentIdentity.MenuView/~/overview/objectId/6e563769-b2ff-4920-b0a4-0feb1cfd8b1c/menuId/overview) | ✅ Enabled |\n| `agentIdentity` | [Change Review Agent V2 (Multi-Turn) (Security Copilot)](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/AgentIdentity.MenuView/~/overview/objectId/985eff71-484a-4d24-bbf5-3e91cfdfa2e6/menuId/overview) | ✅ Enabled |\n| `agentIdentity` | [Change Review Agent V2 (Multi-Turn) (Security Copilot)](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/AgentIdentity.MenuView/~/overview/objectId/d0095fe8-508e-436e-8519-f9db3620869c/menuId/overview) | ✅ Enabled |\n| `agentIdentity` | [Change Review Agent V2 (Multi-Turn) (Security Copilot)](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/AgentIdentity.MenuView/~/overview/objectId/c564e42e-556f-4a74-88d2-f9a020d8e17a/menuId/overview) | ✅ Enabled |\n| `agentIdentity` | [Change Review Multi-Turn Agent V3 (DOTNET Orchestrator) (Security Copilot)](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/AgentIdentity.MenuView/~/overview/objectId/cd14feb7-b02e-488c-b07c-b96185e9458f/menuId/overview) | ✅ Enabled |\n| `agentIdentity` | [Claims Processing Agent](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/AgentIdentity.MenuView/~/overview/objectId/c8c772ea-14f3-4f93-9a14-07875ae2598a/menuId/overview) | ✅ Enabled |\n| `agentIdentity` | [Clinical Trial Monitor](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/AgentIdentity.MenuView/~/overview/objectId/378b8413-a5ff-4929-8599-33a994f0544c/menuId/overview) | ✅ Enabled |\n| `agentIdentity` | [Compliance Auditor](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/AgentIdentity.MenuView/~/overview/objectId/9a91047f-31b8-495e-bd89-205cb1a97b3a/menuId/overview) | ✅ Enabled |\n| `agentIdentity` | [computer agent (Microsoft Copilot Studio)](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/AgentIdentity.MenuView/~/overview/objectId/f604a1fc-eee5-4351-944a-0a1da8619a10/menuId/overview) | ✅ Enabled |\n| `agentIdentity` | [Conditional Access Optimization Agent (Security Copilot)](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/AgentIdentity.MenuView/~/overview/objectId/dd504728-c284-4f03-a28b-b762e899a010/menuId/overview) | ✅ Enabled |\n| `agentIdentity` | [Configuration Manager](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/AgentIdentity.MenuView/~/overview/objectId/0718c676-4e9d-492d-91a2-adfbe48081a5/menuId/overview) | ✅ Enabled |\n| `agentIdentity` | [Content Moderation Agent](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/AgentIdentity.MenuView/~/overview/objectId/eda16e8e-9028-48b0-b2c8-c92ec198ffb4/menuId/overview) | ✅ Enabled |\n| `agentIdentity` | [Contract Management Agent](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/AgentIdentity.MenuView/~/overview/objectId/d7c9ccf2-eea3-448b-8d42-c6ac6cb40488/menuId/overview) | ✅ Enabled |\n| `agentIdentity` | [Copilot in Dynamics 365 Sales (Microsoft Copilot Studio)](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/AgentIdentity.MenuView/~/overview/objectId/189c8eda-8d10-4284-9883-e212204e47fb/menuId/overview) | ✅ Enabled |\n| `agentIdentity` | [Cost Optimization Agent](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/AgentIdentity.MenuView/~/overview/objectId/48c7fbe4-3206-4351-8118-6b17bf690d32/menuId/overview) | ✅ Enabled |\n| `agentIdentity` | [Customer Feedback Agent](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/AgentIdentity.MenuView/~/overview/objectId/60eca29b-4df1-437a-9ed7-eb8b891fc50a/menuId/overview) | ✅ Enabled |\n| `agentIdentity` | [Customer Feedback Summarizer Agent](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/AgentIdentity.MenuView/~/overview/objectId/4d2bdd35-4dba-4652-b8d0-fda5ca7530d7/menuId/overview) | ✅ Enabled |\n| `agentIdentity` | [Customer Feedback Summarizer Agent](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/AgentIdentity.MenuView/~/overview/objectId/11701c78-bbb6-42ec-8801-e98d67b85e96/menuId/overview) | ✅ Enabled |\n| `agentIdentity` | [Customer Service Copilot Bot (Microsoft Copilot Studio)](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/AgentIdentity.MenuView/~/overview/objectId/171420f9-3766-4ad9-9f35-0d24940a5cc2/menuId/overview) | ✅ Enabled |\n| `agentIdentity` | [Customer Service Onboarding Agent (Microsoft Copilot Studio)](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/AgentIdentity.MenuView/~/overview/objectId/a653e9d7-7196-4585-aa8c-a47d7da20f4a/menuId/overview) | ✅ Enabled |\n| `agentIdentity` | [Customer Service Operations Agent (Microsoft Copilot Studio)](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/AgentIdentity.MenuView/~/overview/objectId/1b859e2a-08d5-40a0-bb8e-c088e7fa54a7/menuId/overview) | ✅ Enabled |\n| `agentIdentity` | [Customer Success Agent](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/AgentIdentity.MenuView/~/overview/objectId/806eb9af-b7e4-4104-9a30-a8667f1ad0a1/menuId/overview) | ✅ Enabled |\n| `agentIdentity` | [Customer Support Agent](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/AgentIdentity.MenuView/~/overview/objectId/80bb48a2-f618-4f82-89b4-80962a116560/menuId/overview) | ✅ Enabled |\n| `agentIdentity` | [CustomerServiceKnowledgeHarvest (Microsoft Copilot Studio)](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/AgentIdentity.MenuView/~/overview/objectId/2855d738-4932-4ded-866f-be33a5586c82/menuId/overview) | ✅ Enabled |\n| `agentIdentity` | [CustomerServiceKnowledgeHarvestDedupe (Microsoft Copilot Studio)](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/AgentIdentity.MenuView/~/overview/objectId/ab417c40-65bc-4515-bee8-a0e9976c9138/menuId/overview) | ✅ Enabled |\n| `agentIdentity` | [CustomerServiceKnowledgeHarvestDedupe (Microsoft Copilot Studio)](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/AgentIdentity.MenuView/~/overview/objectId/7747b701-3030-43bf-a402-0a81319c452a/menuId/overview) | ✅ Enabled |\n| `agentIdentity` | [CVE Criticality Explainer (Microsoft Copilot Studio)](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/AgentIdentity.MenuView/~/overview/objectId/57e9f605-6a22-4e56-a59f-d16b02dac03c/menuId/overview) | ✅ Enabled |\n| `agentIdentity` | [CVE Identifier Extractor (Microsoft Copilot Studio)](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/AgentIdentity.MenuView/~/overview/objectId/5f3f7f64-6c2b-40ee-9991-b39777b2b197/menuId/overview) | ✅ Enabled |\n| `agentIdentity` | [CVE Info Finder (Microsoft Copilot Studio)](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/AgentIdentity.MenuView/~/overview/objectId/1d1e5955-4713-4990-a0ce-5728067d41d5/menuId/overview) | ✅ Enabled |\n| `agentIdentity` | [CVE Lookup Assistant (Microsoft Copilot Studio)](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/AgentIdentity.MenuView/~/overview/objectId/c2bcd7e4-853b-46ff-85d0-40e6a873a870/menuId/overview) | ✅ Enabled |\n| `agentIdentity` | [CVE-Agent-analysis (Microsoft Copilot Studio)](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/AgentIdentity.MenuView/~/overview/objectId/68630068-93e0-4051-9525-ecb0cf84bb35/menuId/overview) | ✅ Enabled |\n| `agentIdentity` | [Cyber Threat News Summarizer (Microsoft Copilot Studio)](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/AgentIdentity.MenuView/~/overview/objectId/c1c93418-e0ee-4192-9445-2db7b09f75b2/menuId/overview) | ✅ Enabled |\n| `agentIdentity` | [D365 Contact Center Admin AI Agent (Microsoft Copilot Studio)](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/AgentIdentity.MenuView/~/overview/objectId/8f8765a4-0f41-4f1b-bebf-96b64eec24fd/menuId/overview) | ✅ Enabled |\n| `agentIdentity` | [D365 Contact Center Admin AI Agent (Microsoft Copilot Studio)](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/AgentIdentity.MenuView/~/overview/objectId/607d8abf-ebcd-485d-bde0-342dfe33bc55/menuId/overview) | ✅ Enabled |\n| `agentIdentity` | [D365 Sales - Configuration Agent (Microsoft Copilot Studio)](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/AgentIdentity.MenuView/~/overview/objectId/528c4eb6-345b-4da6-95b4-cfd74a59b30d/menuId/overview) | ✅ Enabled |\n| `agentIdentity` | [D365 Sales - Data Enrichment (Microsoft Copilot Studio)](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/AgentIdentity.MenuView/~/overview/objectId/39f792f1-43c8-4fe5-9aa5-41d3dc04b209/menuId/overview) | ✅ Enabled |\n| `agentIdentity` | [D365 Sales Agent - Company Resolver (Microsoft Copilot Studio)](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/AgentIdentity.MenuView/~/overview/objectId/ab6f05fc-5a38-4b53-b313-b908647bac1a/menuId/overview) | ✅ Enabled |\n| `agentIdentity` | [D365 Sales Agent - Competitor (Microsoft Copilot Studio)](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/AgentIdentity.MenuView/~/overview/objectId/7b8fd82e-3457-493f-9890-bc453482055f/menuId/overview) | ✅ Enabled |\n| `agentIdentity` | [D365 Sales Agent - Custom Research (Microsoft Copilot Studio)](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/AgentIdentity.MenuView/~/overview/objectId/8b336570-d5db-45fd-9743-d55653d4d621/menuId/overview) | ✅ Enabled |\n| `agentIdentity` | [D365 Sales Agent - Email Validation (Microsoft Copilot Studio)](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/AgentIdentity.MenuView/~/overview/objectId/8d792a37-7e6f-48ab-8741-bd83f30235fa/menuId/overview) | ✅ Enabled |\n| `agentIdentity` | [D365 Sales Agent - Engage Autonomous (Microsoft Copilot Studio)](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/AgentIdentity.MenuView/~/overview/objectId/be372604-9bca-4c55-8cda-b22cf890b024/menuId/overview) | ✅ Enabled |\n| `agentIdentity` | [D365 Sales Agent - Outreach (Microsoft Copilot Studio)](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/AgentIdentity.MenuView/~/overview/objectId/27204523-2867-4386-a3d5-3d4e79d55b5d/menuId/overview) | ✅ Enabled |\n| `agentIdentity` | [D365 Sales Agent - Readiness (Microsoft Copilot Studio)](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/AgentIdentity.MenuView/~/overview/objectId/a03bcf12-55c0-4553-84ab-36b4c8e3c45d/menuId/overview) | ✅ Enabled |\n| `agentIdentity` | [D365 Sales Agent - Research (Microsoft Copilot Studio)](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/AgentIdentity.MenuView/~/overview/objectId/08a05e33-1e60-4fb7-aad0-d7b8db41b985/menuId/overview) | ✅ Enabled |\n| `agentIdentity` | [D365 Sales Agent - Stakeholder Research (Microsoft Copilot Studio)](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/AgentIdentity.MenuView/~/overview/objectId/d199051e-8f3a-4e39-a19b-ef1b27a78cb8/menuId/overview) | ✅ Enabled |\n| `agentIdentity` | [D365 Sales Agent - Summary Synthesizer (Microsoft Copilot Studio)](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/AgentIdentity.MenuView/~/overview/objectId/3ccc73cc-920d-4df9-a5ba-6e3f04c5cea0/menuId/overview) | ✅ Enabled |\n| `agentIdentity` | [D365 Sales Agent - TCP Prefill Agent (Microsoft Copilot Studio)](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/AgentIdentity.MenuView/~/overview/objectId/0611ad97-df20-40db-b955-e3d493972295/menuId/overview) | ✅ Enabled |\n| `agentIdentity` | [Daily Assistant (Microsoft Copilot Studio)](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/AgentIdentity.MenuView/~/overview/objectId/68e7dbe2-3b9a-46d6-b402-a8b547c72b3a/menuId/overview) | ✅ Enabled |\n| `agentIdentity` | [Daily CISA RSS Feed Notifier (Microsoft Copilot Studio)](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/AgentIdentity.MenuView/~/overview/objectId/80d461cc-bee4-485d-9307-a9a9f14e88b8/menuId/overview) | ✅ Enabled |\n| `agentIdentity` | [Data Catalog Agent](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/AgentIdentity.MenuView/~/overview/objectId/3c8ae8f5-268b-47eb-a398-be05ca02d253/menuId/overview) | ✅ Enabled |\n| `agentIdentity` | [Data Loss Prevention Agent](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/AgentIdentity.MenuView/~/overview/objectId/1233d0f0-4eb0-4313-a31f-c72368aab487/menuId/overview) | ✅ Enabled |\n| `agentIdentity` | [Data Pipeline Agent](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/AgentIdentity.MenuView/~/overview/objectId/2b2a2c9a-d4d3-485e-a294-6331ce55ea10/menuId/overview) | ✅ Enabled |\n| `agentIdentity` | [Data Quality Agent](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/AgentIdentity.MenuView/~/overview/objectId/ae9502ad-8d31-4ffd-867a-70f4a3e3e2b9/menuId/overview) | ✅ Enabled |\n| `agentIdentity` | [Data Security Triage Agent in IRM (Purview) (Security Copilot)](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/AgentIdentity.MenuView/~/overview/objectId/2b51398c-fefd-404e-a44a-7fde5c9eb153/menuId/overview) | ✅ Enabled |\n| `agentIdentity` | [Deployment Orchestrator](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/AgentIdentity.MenuView/~/overview/objectId/1af00a77-af6c-4098-85e4-b4958a0ecf57/menuId/overview) | ✅ Enabled |\n| `agentIdentity` | [Disaster Recovery Agent](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/AgentIdentity.MenuView/~/overview/objectId/0bac1c63-54d9-47a0-9c2a-852a5678bfb7/menuId/overview) | ✅ Enabled |\n| `agentIdentity` | [Document Processing Agent](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/AgentIdentity.MenuView/~/overview/objectId/29b3adac-8c70-488c-bafb-fa8920b0b965/menuId/overview) | ✅ Enabled |\n| `agentIdentity` | [Email Routing Agent](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/AgentIdentity.MenuView/~/overview/objectId/1917c358-18c6-4298-9091-f80d56b57975/menuId/overview) | ✅ Enabled |\n| `agentIdentity` | [Employee Onboarding Agent](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/AgentIdentity.MenuView/~/overview/objectId/37f5e621-8f7e-43c8-9b90-25b5d7af5327/menuId/overview) | ✅ Enabled |\n| `agentIdentity` | [Escalation Manager](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/AgentIdentity.MenuView/~/overview/objectId/40a3258c-5e4d-4351-ba1d-01b06c899363/menuId/overview) | ✅ Enabled |\n| `agentIdentity` | [ETL Processor](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/AgentIdentity.MenuView/~/overview/objectId/152b8a0d-3cb0-4917-b522-314a8b563f82/menuId/overview) | ✅ Enabled |\n| `agentIdentity` | [Expense Reconciliation Agent](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/AgentIdentity.MenuView/~/overview/objectId/774ba315-9e31-4a38-a2d8-a2706eca6984/menuId/overview) | ✅ Enabled |\n| `agentIdentity` | [Facility Management Agent](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/AgentIdentity.MenuView/~/overview/objectId/7eb78670-e285-4bfd-b4bb-370bf1a5379b/menuId/overview) | ✅ Enabled |\n| `agentIdentity` | [Field Service Agent](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/AgentIdentity.MenuView/~/overview/objectId/b2120562-7622-4abf-93de-85cf564c2d15/menuId/overview) | ✅ Enabled |\n| `agentIdentity` | [Finance Advisor Agent](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/AgentIdentity.MenuView/~/overview/objectId/9097e2cf-2244-4202-a460-288133300e4c/menuId/overview) | ✅ Enabled |\n| `agentIdentity` | [Fleet Management Agent](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/AgentIdentity.MenuView/~/overview/objectId/f597c12e-fdca-4064-964d-7a35037512db/menuId/overview) | ✅ Enabled |\n| `agentIdentity` | [Foo (Microsoft Copilot Studio)](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/AgentIdentity.MenuView/~/overview/objectId/50d0ee65-6ea3-4659-a1a7-495541c0b81a/menuId/overview) | ✅ Enabled |\n| `agentIdentity` | [Forecast Analytics Agent](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/AgentIdentity.MenuView/~/overview/objectId/21278a72-66a0-4377-89a9-d2ffbc847d94/menuId/overview) | ✅ Enabled |\n| `agentIdentity` | [Fraud Detection Agent](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/AgentIdentity.MenuView/~/overview/objectId/fddfb10c-9f29-4944-b66b-39b97a637919/menuId/overview) | ✅ Enabled |\n| `agentIdentity` | [GraphTest (Microsoft Copilot Studio)](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/AgentIdentity.MenuView/~/overview/objectId/a81c3b63-9b32-48f5-9beb-fd8cfd1d72df/menuId/overview) | ✅ Enabled |\n| `agentIdentity` | [HagaiTest (Microsoft Copilot Studio)](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/AgentIdentity.MenuView/~/overview/objectId/9852b57e-1a69-4523-b80c-99ae62aae4f1/menuId/overview) | ✅ Enabled |\n| `agentIdentity` | [Health Check Agent](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/AgentIdentity.MenuView/~/overview/objectId/4149fda2-f886-42e8-bfc9-45412c1f9b80/menuId/overview) | ✅ Enabled |\n| `agentIdentity` | [HR Benefits Agent](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/AgentIdentity.MenuView/~/overview/objectId/1c0271dd-89da-4c0c-9faa-6ebbdd8b1352/menuId/overview) | ✅ Enabled |\n| `agentIdentity` | [Identity Governance Agent](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/AgentIdentity.MenuView/~/overview/objectId/734c11f8-33b8-4332-b7e9-6d428c349f82/menuId/overview) | ✅ Enabled |\n| `agentIdentity` | [Identity Protection Risk Remediation Agent (Security Copilot)](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/AgentIdentity.MenuView/~/overview/objectId/7bdc5afa-6b4f-4e37-a72a-321f6bf3e3e2/menuId/overview) | ✅ Enabled |\n| `agentIdentity` | [Identity Protection Risk Remediation Agent (Security Copilot)](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/AgentIdentity.MenuView/~/overview/objectId/63f44f3a-a681-49d1-86fb-a64614fbf1b9/menuId/overview) | ✅ Enabled |\n| `agentIdentity` | [Incident Response Agent](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/AgentIdentity.MenuView/~/overview/objectId/b1f56a43-d033-4fb8-9de4-88b9a25f26e6/menuId/overview) | ✅ Enabled |\n| `agentIdentity` | [Infrastructure Monitor](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/AgentIdentity.MenuView/~/overview/objectId/82bd081e-8797-4ded-a40c-f65a7eb63eda/menuId/overview) | ✅ Enabled |\n| `agentIdentity` | [Insurance Underwriting Agent](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/AgentIdentity.MenuView/~/overview/objectId/23551c1c-297e-4ba3-8071-264d87890bf2/menuId/overview) | ✅ Enabled |\n| `agentIdentity` | [Intune Analyst Agent v4_Choice (Security Copilot)](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/AgentIdentity.MenuView/~/overview/objectId/69a871ed-1536-4910-b32e-2b65dec16633/menuId/overview) | ✅ Enabled |\n| `agentIdentity` | [Intune Vulnerability Remediation Agent (Security Copilot)](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/AgentIdentity.MenuView/~/overview/objectId/2cc327ef-4c80-4af7-a8ff-bc3560ffc80d/menuId/overview) | ✅ Enabled |\n| `agentIdentity` | [Intune Vulnerability Remediation Agent (Security Copilot)](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/AgentIdentity.MenuView/~/overview/objectId/2bde734c-9be9-4283-9221-792fc0780da3/menuId/overview) | ✅ Enabled |\n| `agentIdentity` | [Inventory Management Agent](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/AgentIdentity.MenuView/~/overview/objectId/cf3587d5-3e56-42c3-9537-ea9808e2cee9/menuId/overview) | ✅ Enabled |\n| `agentIdentity` | [Invoice Processing Agent](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/AgentIdentity.MenuView/~/overview/objectId/6fac12fe-0f11-4e97-89c9-fa360081b2eb/menuId/overview) | ✅ Enabled |\n| `agentIdentity` | [ISV Fraud Detection Agent](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/AgentIdentity.MenuView/~/overview/objectId/26602b44-d92c-413c-b377-e420d862523d/menuId/overview) | ✅ Enabled |\n| `agentIdentity` | [IT Helpdesk Agent](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/AgentIdentity.MenuView/~/overview/objectId/1f65704e-ae39-4a0b-9777-2dbc3ea72056/menuId/overview) | ✅ Enabled |\n| `agentIdentity` | [Jose Productivity Agent - Dev (Microsoft Copilot Studio)](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/AgentIdentity.MenuView/~/overview/objectId/da311182-24dc-4168-9cd3-d76309feffbc/menuId/overview) | ✅ Enabled |\n| `agentIdentity` | [Knowledge Base Agent](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/AgentIdentity.MenuView/~/overview/objectId/ce942c72-c24b-4887-af84-53c50b224731/menuId/overview) | ✅ Enabled |\n| `agentIdentity` | [Lead Scoring Agent](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/AgentIdentity.MenuView/~/overview/objectId/0f3a9b6d-eac0-452d-9fe2-ceeb33b26449/menuId/overview) | ✅ Enabled |\n| `agentIdentity` | [Legal Compliance Agent](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/AgentIdentity.MenuView/~/overview/objectId/53ae4f4c-6d2b-4da0-81a4-14b082bc1756/menuId/overview) | ✅ Enabled |\n| `agentIdentity` | [License Compliance Agent](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/AgentIdentity.MenuView/~/overview/objectId/19100fe5-3aa4-41dc-a353-d7da089f1771/menuId/overview) | ✅ Enabled |\n| `agentIdentity` | [Liran-test-MCS-agent (Microsoft Copilot Studio)](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/AgentIdentity.MenuView/~/overview/objectId/abc1717d-a463-418e-875d-71a72138b48d/menuId/overview) | ✅ Enabled |\n| `agentIdentity` | [Loan Processing Agent](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/AgentIdentity.MenuView/~/overview/objectId/eaabb208-1a15-43c5-8e5d-a044d1b87752/menuId/overview) | ✅ Enabled |\n| `agentIdentity` | [Log Analytics Agent](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/AgentIdentity.MenuView/~/overview/objectId/6f702c59-218f-4064-b3a7-27afa76a6ac6/menuId/overview) | ✅ Enabled |\n| `agentIdentity` | [Meeting Productivity Assistant (Microsoft Copilot Studio)](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/AgentIdentity.MenuView/~/overview/objectId/97ef70f2-5768-4f7f-a8ff-2edf586347af/menuId/overview) | ✅ Enabled |\n| `agentIdentity` | [Meeting Scheduler](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/AgentIdentity.MenuView/~/overview/objectId/fc51b10e-9da3-45a5-808c-1f5f43cb948a/menuId/overview) | ✅ Enabled |\n| `agentIdentity` | [Metrics Collector](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/AgentIdentity.MenuView/~/overview/objectId/49de5f63-391d-4b32-ac8f-d35cf991c9da/menuId/overview) | ✅ Enabled |\n| `agentIdentity` | [Microsoft Tech Info Assistant (Microsoft Copilot Studio)](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/AgentIdentity.MenuView/~/overview/objectId/3ab5f364-312b-46b4-bc34-44921db20635/menuId/overview) | ✅ Enabled |\n| `agentIdentity` | [Moses Lake (Microsoft Copilot Studio)](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/AgentIdentity.MenuView/~/overview/objectId/c9b70334-0488-46c0-827d-f9e83671cbb4/menuId/overview) | ✅ Enabled |\n| `agentIdentity` | [Network Monitor Agent](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/AgentIdentity.MenuView/~/overview/objectId/24c20311-01b4-4b1e-a8e1-eafd0c6108fb/menuId/overview) | ✅ Enabled |\n| `agentIdentity` | [Notification Dispatcher](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/AgentIdentity.MenuView/~/overview/objectId/a52bd039-e460-4404-865c-423de19b7166/menuId/overview) | ✅ Enabled |\n| `agentIdentity` | [onboarding-comms-agent](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/AgentIdentity.MenuView/~/overview/objectId/b79ed8bf-438f-4414-aaae-9cd1b7e6f1d8/menuId/overview) | ✅ Enabled |\n| `agentIdentity` | [onboarding-it-agent](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/AgentIdentity.MenuView/~/overview/objectId/6464f442-ff7d-49ec-8161-5caf322f8824/menuId/overview) | ✅ Enabled |\n| `agentIdentity` | [onboarding-people-agent](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/AgentIdentity.MenuView/~/overview/objectId/747cd2a4-f34e-4eac-a36f-4dd91db039fe/menuId/overview) | ✅ Enabled |\n| `agentIdentity` | [Oracle DB updates to ServiceNow (Microsoft Copilot Studio)](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/AgentIdentity.MenuView/~/overview/objectId/65f3b08b-3806-4ecc-9444-944aa8c60391/menuId/overview) | ✅ Enabled |\n| `agentIdentity` | [Order Fulfillment Agent](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/AgentIdentity.MenuView/~/overview/objectId/ac41597f-c0d8-473e-b7dd-fcbe9c3b38a5/menuId/overview) | ✅ Enabled |\n| `agentIdentity` | [Padma Test CPS 21Jan2026 (Microsoft Copilot Studio)](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/AgentIdentity.MenuView/~/overview/objectId/cd4fb7d6-1d08-4582-bcde-16e6e2b9b2b4/menuId/overview) | ✅ Enabled |\n| `agentIdentity` | [Patch Management Agent](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/AgentIdentity.MenuView/~/overview/objectId/f568cb8b-508b-4525-97a8-ce4d8f2fcb9a/menuId/overview) | ✅ Enabled |\n| `agentIdentity` | [Patient Intake Agent](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/AgentIdentity.MenuView/~/overview/objectId/652b2350-87cb-4cd8-8ea6-d80b5906f787/menuId/overview) | ✅ Enabled |\n| `agentIdentity` | [Payroll Services Agent](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/AgentIdentity.MenuView/~/overview/objectId/64f0803d-6f5b-46f0-8650-b05bce8d879b/menuId/overview) | ✅ Enabled |\n| `agentIdentity` | [Performance Optimizer](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/AgentIdentity.MenuView/~/overview/objectId/d713a7ca-3701-4f70-8693-335d7493ba2a/menuId/overview) | ✅ Enabled |\n| `agentIdentity` | [Policy Enforcement Agent](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/AgentIdentity.MenuView/~/overview/objectId/7052d6ce-edd2-4549-a846-8a8480a7b18e/menuId/overview) | ✅ Enabled |\n| `agentIdentity` | [Price Optimization Agent](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/AgentIdentity.MenuView/~/overview/objectId/1ae0d1e0-5018-49a7-8f5a-8578725f9474/menuId/overview) | ✅ Enabled |\n| `agentIdentity` | [Procurement Agent](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/AgentIdentity.MenuView/~/overview/objectId/60e517dc-852c-4f35-b5a9-46b02020be15/menuId/overview) | ✅ Enabled |\n| `agentIdentity` | [ProdAgent (Microsoft Copilot Studio)](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/AgentIdentity.MenuView/~/overview/objectId/0b8bebe9-0491-4ff2-9f89-3dc74d26f069/menuId/overview) | ✅ Enabled |\n| `agentIdentity` | [Product Catalog Agent](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/AgentIdentity.MenuView/~/overview/objectId/a2732152-9b10-4fcd-b7e1-ce3635ac9993/menuId/overview) | ✅ Enabled |\n| `agentIdentity` | [Purview DSPM Discovery Agent (Security Copilot)](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/AgentIdentity.MenuView/~/overview/objectId/89733620-a253-40b1-9311-200a08abd7a3/menuId/overview) | ✅ Enabled |\n| `agentIdentity` | [Purview DSPM Discovery Agent (Security Copilot)](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/AgentIdentity.MenuView/~/overview/objectId/c2b6d709-0309-4e67-893b-ebd7ea558ad3/menuId/overview) | ✅ Enabled |\n| `agentIdentity` | [Purview DSPM Discovery Agent (Security Copilot)](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/AgentIdentity.MenuView/~/overview/objectId/7c1660e7-d1fd-4a20-a0b9-cccf5309a54d/menuId/overview) | ✅ Enabled |\n| `agentIdentity` | [Purview IRM Alert Triage Agent (Security Copilot)](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/AgentIdentity.MenuView/~/overview/objectId/52131ebc-5de8-4462-b6c0-60c240b74f31/menuId/overview) | ✅ Enabled |\n| `agentIdentity` | [Quality Assurance Agent](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/AgentIdentity.MenuView/~/overview/objectId/ca5f23a0-2229-4257-9618-b482dcea0102/menuId/overview) | ✅ Enabled |\n| `agentIdentity` | [Quality Evaluation Agent - Incident (Microsoft Copilot Studio)](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/AgentIdentity.MenuView/~/overview/objectId/b0ee8017-a18f-494f-a3a6-afa35ce6411c/menuId/overview) | ✅ Enabled |\n| `agentIdentity` | [Quality Evaluation Agent (Microsoft Copilot Studio)](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/AgentIdentity.MenuView/~/overview/objectId/c09cfff0-19ed-467e-a745-3c1ab933e3cb/menuId/overview) | ✅ Enabled |\n| `agentIdentity` | [QualityEvaluationAgentForConversation (Microsoft Copilot Studio)](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/AgentIdentity.MenuView/~/overview/objectId/564d91c3-0a21-4b00-a206-33b654807c33/menuId/overview) | ✅ Enabled |\n| `agentIdentity` | [Recruitment Agent](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/AgentIdentity.MenuView/~/overview/objectId/518fa4db-ba8d-4109-8d6d-a4f0048fe776/menuId/overview) | ✅ Enabled |\n| `agentIdentity` | [Regulatory Filing Agent](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/AgentIdentity.MenuView/~/overview/objectId/e4f3feb2-3835-46c2-8782-4e5632541655/menuId/overview) | ✅ Enabled |\n| `agentIdentity` | [Release Manager Agent](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/AgentIdentity.MenuView/~/overview/objectId/bbb7f06a-67df-4c6d-b2d1-bd7a42d694b5/menuId/overview) | ✅ Enabled |\n| `agentIdentity` | [Report Generator](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/AgentIdentity.MenuView/~/overview/objectId/e9ef7b28-50a0-44e8-b5c1-32af247a398f/menuId/overview) | ✅ Enabled |\n| `agentIdentity` | [Resource Provisioner](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/AgentIdentity.MenuView/~/overview/objectId/9c5b50a8-2855-495d-a827-3fa2ca7999a5/menuId/overview) | ✅ Enabled |\n| `agentIdentity` | [Revenue Recognition Agent](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/AgentIdentity.MenuView/~/overview/objectId/845a3f12-07f2-4be3-84db-d539e3af1d40/menuId/overview) | ✅ Enabled |\n| `agentIdentity` | [Risk Assessment Agent](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/AgentIdentity.MenuView/~/overview/objectId/ec9c0667-f658-4034-9b97-3acd4eec38eb/menuId/overview) | ✅ Enabled |\n| `agentIdentity` | [Roundtable Synthesizer (Microsoft Copilot Studio)](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/AgentIdentity.MenuView/~/overview/objectId/11840fb4-1f60-4631-b90a-86394b281719/menuId/overview) | ✅ Enabled |\n| `agentIdentity` | [RSA2026 Escalation Agent](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/AgentIdentity.MenuView/~/overview/objectId/ee7d2ebf-71ad-4e1f-8c04-dfbf6dca005b/menuId/overview) | ✅ Enabled |\n| `agentIdentity` | [RSA2026 Triage Agent](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/AgentIdentity.MenuView/~/overview/objectId/abfee1b3-88e0-45db-8e0c-cb6c3d6235a0/menuId/overview) | ❌ Disabled |\n| `agentIdentity` | [Sales Close Agent (Microsoft Copilot Studio)](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/AgentIdentity.MenuView/~/overview/objectId/e3b6dde8-7ab4-44cc-8a54-e73f85223d30/menuId/overview) | ✅ Enabled |\n| `agentIdentity` | [Sales Close Agent (Microsoft Copilot Studio)](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/AgentIdentity.MenuView/~/overview/objectId/2f1ef369-a2d0-4158-8bd4-0a3815f79752/menuId/overview) | ✅ Enabled |\n| `agentIdentity` | [Sales Operations Agent](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/AgentIdentity.MenuView/~/overview/objectId/ef9b5af2-def1-4e3b-95ac-7538ec8c7980/menuId/overview) | ✅ Enabled |\n| `agentIdentity` | [Sales Opportunity Agent - Account Research (Microsoft Copilot Studio)](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/AgentIdentity.MenuView/~/overview/objectId/d54e838a-8e0d-480f-973d-199242cbb025/menuId/overview) | ✅ Enabled |\n| `agentIdentity` | [Sales Opportunity Agent - Compete Research (Microsoft Copilot Studio)](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/AgentIdentity.MenuView/~/overview/objectId/21a570c8-23bc-4881-bfc9-7f9a42caf43e/menuId/overview) | ✅ Enabled |\n| `agentIdentity` | [Sales Opportunity Agent - Custom Research (Microsoft Copilot Studio)](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/AgentIdentity.MenuView/~/overview/objectId/8bd8a75d-ee19-4b5a-ad16-473145d652c4/menuId/overview) | ✅ Enabled |\n| `agentIdentity` | [Sales Opportunity Agent - Stakeholder (Microsoft Copilot Studio)](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/AgentIdentity.MenuView/~/overview/objectId/b6096cf5-fc48-4a1b-8295-fd48e115098f/menuId/overview) | ✅ Enabled |\n| `agentIdentity` | [Sales Opportunity Agent (Microsoft Copilot Studio)](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/AgentIdentity.MenuView/~/overview/objectId/f64ec8a8-7ced-46b4-99f7-e144fa42c880/menuId/overview) | ✅ Enabled |\n| `agentIdentity` | [Sales Profiler Agent (Microsoft Copilot Studio)](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/AgentIdentity.MenuView/~/overview/objectId/f8aa4949-78b5-4999-aa95-9cc77bd93aab/menuId/overview) | ✅ Enabled |\n| `agentIdentity` | [Sales Profiler Agent (Microsoft Copilot Studio)](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/AgentIdentity.MenuView/~/overview/objectId/1e262eac-c999-410e-b885-f2becc295a10/menuId/overview) | ✅ Enabled |\n| `agentIdentity` | [Sales Qualification Agent Config Assistant (Microsoft Copilot Studio)](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/AgentIdentity.MenuView/~/overview/objectId/a79f6762-31cb-4ebd-9e9e-f2688aff9951/menuId/overview) | ✅ Enabled |\n| `agentIdentity` | [Sales Qualification Agent Config Assistant (Microsoft Copilot Studio)](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/AgentIdentity.MenuView/~/overview/objectId/9347258b-53ff-4689-b249-2401ec3a0ea3/menuId/overview) | ✅ Enabled |\n| `agentIdentity` | [Security Monitoring Agent (Microsoft Copilot Studio)](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/AgentIdentity.MenuView/~/overview/objectId/f44e64e9-434f-40c7-8f44-f8bd32c817a0/menuId/overview) | ✅ Enabled |\n| `agentIdentity` | [Security Operations Agent](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/AgentIdentity.MenuView/~/overview/objectId/0006562e-934e-466c-8f90-fdafe90ef357/menuId/overview) | ✅ Enabled |\n| `agentIdentity` | [Security Scanner](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/AgentIdentity.MenuView/~/overview/objectId/bd425971-3aae-4970-8f81-0dcfebf4b39f/menuId/overview) | ✅ Enabled |\n| `agentIdentity` | [SecurityCopilotAgentIdentity-02c77c33-698a-434e-a0d3-d233132f3e68](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/AgentIdentity.MenuView/~/overview/objectId/e963a334-cf34-42b0-bd64-92a330cfebcf/menuId/overview) | ✅ Enabled |\n| `agentIdentity` | [SecurityCopilotAgentIdentity-037f8323-48a8-41bd-b278-3a4e2c7d1ec6](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/AgentIdentity.MenuView/~/overview/objectId/396eb352-f48d-44de-8f92-a48cf528e90c/menuId/overview) | ✅ Enabled |\n| `agentIdentity` | [SecurityCopilotAgentIdentity-0b544072-2515-492e-a3cb-8956a390d2b2](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/AgentIdentity.MenuView/~/overview/objectId/f4635903-90f2-4b4b-a8ac-dec8cc1d3b0c/menuId/overview) | ✅ Enabled |\n| `agentIdentity` | [SecurityCopilotAgentIdentity-0c5b1f36-0cbe-49a5-be41-1893694abc79](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/AgentIdentity.MenuView/~/overview/objectId/c2cb254e-8de0-41b6-b428-18c668e491b9/menuId/overview) | ✅ Enabled |\n| `agentIdentity` | [SecurityCopilotAgentIdentity-0fcabf23-5286-438d-a67f-ba37b937a05a](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/AgentIdentity.MenuView/~/overview/objectId/1e486b8a-4968-4783-bb81-924d0af04a0b/menuId/overview) | ✅ Enabled |\n| `agentIdentity` | [SecurityCopilotAgentIdentity-11ae8c93-78ee-4a60-9566-dd8a82032431](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/AgentIdentity.MenuView/~/overview/objectId/eb89f6ce-b413-426c-ba32-ca0cf500f6c1/menuId/overview) | ✅ Enabled |\n| `agentIdentity` | [SecurityCopilotAgentIdentity-13932e35-45c3-46e6-8f23-08d3a197c377](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/AgentIdentity.MenuView/~/overview/objectId/36f45602-0827-451c-83f1-8f1eb5f90959/menuId/overview) | ✅ Enabled |\n| `agentIdentity` | [SecurityCopilotAgentIdentity-1d89bd8d-9945-41f4-9d20-00ccdbda8fda](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/AgentIdentity.MenuView/~/overview/objectId/ed939ae2-0d85-49bf-bed5-910ba89dbd70/menuId/overview) | ✅ Enabled |\n| `agentIdentity` | [SecurityCopilotAgentIdentity-1dd36604-5c83-471c-97ab-2ea8aca63e97](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/AgentIdentity.MenuView/~/overview/objectId/e482ccef-9a67-4254-84d5-8b700f180c63/menuId/overview) | ✅ Enabled |\n| `agentIdentity` | [SecurityCopilotAgentIdentity-1f6d1651-ceee-4f45-a5a3-b5f39df21963](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/AgentIdentity.MenuView/~/overview/objectId/3d1e10ba-b33e-42c6-b69b-82533f6aadc5/menuId/overview) | ✅ Enabled |\n| `agentIdentity` | [SecurityCopilotAgentIdentity-236381d3-a98a-4cfd-aceb-6667cccf92f6](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/AgentIdentity.MenuView/~/overview/objectId/094f932c-cd32-43c1-a865-2d2990e59dd5/menuId/overview) | ✅ Enabled |\n| `agentIdentity` | [SecurityCopilotAgentIdentity-252d3660-9f59-4a9e-b2f7-95af00985bbd](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/AgentIdentity.MenuView/~/overview/objectId/b91a0454-56bc-4e5a-b70f-483ae8b6d407/menuId/overview) | ✅ Enabled |\n| `agentIdentity` | [SecurityCopilotAgentIdentity-253ee1cb-27e9-415c-8075-0a51a7a2d833](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/AgentIdentity.MenuView/~/overview/objectId/92d851d9-f675-4c42-a1fa-4e9f39c754eb/menuId/overview) | ✅ Enabled |\n| `agentIdentity` | [SecurityCopilotAgentIdentity-26886a24-818d-43e6-8d28-957536f2c9a5](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/AgentIdentity.MenuView/~/overview/objectId/dd1f6a50-ba73-4553-b6a0-d4034eaadedd/menuId/overview) | ✅ Enabled |\n| `agentIdentity` | [SecurityCopilotAgentIdentity-298a0e5a-e4f4-4b70-8433-1144ddca5d29](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/AgentIdentity.MenuView/~/overview/objectId/dc9b2cf2-ef50-4f76-966d-b13043624d9f/menuId/overview) | ✅ Enabled |\n| `agentIdentity` | [SecurityCopilotAgentIdentity-36ff65e1-792c-4c71-a082-d0e535807294](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/AgentIdentity.MenuView/~/overview/objectId/4d867bf5-3746-4180-8bca-16c78a55cc92/menuId/overview) | ✅ Enabled |\n| `agentIdentity` | [SecurityCopilotAgentIdentity-37762879-283c-489f-bfda-69199d5df07b](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/AgentIdentity.MenuView/~/overview/objectId/8b9d57f2-fad5-4eb0-ad1b-bd660d835d25/menuId/overview) | ✅ Enabled |\n| `agentIdentity` | [SecurityCopilotAgentIdentity-3f10c32e-2d8d-4a23-aeed-5a49dac3d10c](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/AgentIdentity.MenuView/~/overview/objectId/d86db10d-999b-4dac-9b14-4b17e0aede6d/menuId/overview) | ✅ Enabled |\n| `agentIdentity` | [SecurityCopilotAgentIdentity-472474fe-706c-4e96-82e6-b1b0b96b8767](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/AgentIdentity.MenuView/~/overview/objectId/23b743d5-8634-4f47-89de-f5064d1b97ed/menuId/overview) | ✅ Enabled |\n| `agentIdentity` | [SecurityCopilotAgentIdentity-4aa7a87a-4081-4f06-85ee-4d13f6ead45b](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/AgentIdentity.MenuView/~/overview/objectId/9adea0a3-1ab4-4ca4-bb6d-31ebe6aafbd9/menuId/overview) | ✅ Enabled |\n| `agentIdentity` | [SecurityCopilotAgentIdentity-4ea1dfd7-d614-42cf-8da2-73cb60134971](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/AgentIdentity.MenuView/~/overview/objectId/c3c2a78e-a495-46f7-9876-6eec67e55ad6/menuId/overview) | ✅ Enabled |\n| `agentIdentity` | [SecurityCopilotAgentIdentity-538cbe5f-7293-4c48-9102-99f1cf4db972](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/AgentIdentity.MenuView/~/overview/objectId/f26cc5b2-ae10-4b94-b8f6-8aec06197655/menuId/overview) | ✅ Enabled |\n| `agentIdentity` | [SecurityCopilotAgentIdentity-546a6b15-6c52-4897-ac5a-115896ad47d7](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/AgentIdentity.MenuView/~/overview/objectId/d095740a-e7f0-4bdf-a65d-025f35dba975/menuId/overview) | ✅ Enabled |\n| `agentIdentity` | [SecurityCopilotAgentIdentity-56578e93-9ef4-442f-a6a0-2b8b22200f1c](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/AgentIdentity.MenuView/~/overview/objectId/b19ea00e-2949-43a4-9487-73c73102a04e/menuId/overview) | ✅ Enabled |\n| `agentIdentity` | [SecurityCopilotAgentIdentity-5fc83af5-f6f2-4259-977a-7df1f7bbdfd2](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/AgentIdentity.MenuView/~/overview/objectId/3b5d157f-5e5d-497a-8f23-7945856af3d9/menuId/overview) | ✅ Enabled |\n| `agentIdentity` | [SecurityCopilotAgentIdentity-6012c9fc-219a-4cc7-b5f9-a29c353d82fe](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/AgentIdentity.MenuView/~/overview/objectId/bfa5f58b-2479-4355-9050-28789ff2640a/menuId/overview) | ✅ Enabled |\n| `agentIdentity` | [SecurityCopilotAgentIdentity-60ca4bf6-a2e4-49fb-be27-8ca7360f7b41](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/AgentIdentity.MenuView/~/overview/objectId/fc1488b1-474d-40e9-8545-df8f066838c7/menuId/overview) | ✅ Enabled |\n| `agentIdentity` | [SecurityCopilotAgentIdentity-6a43d038-ac97-4b28-b879-274102277546](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/AgentIdentity.MenuView/~/overview/objectId/8995d08b-e2c4-4cff-afe8-d0088689fb16/menuId/overview) | ✅ Enabled |\n| `agentIdentity` | [SecurityCopilotAgentIdentity-6a94e25c-747c-4d53-bddc-8321dca71aa3](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/AgentIdentity.MenuView/~/overview/objectId/5c3722a4-5545-462f-94aa-03221e0b3518/menuId/overview) | ✅ Enabled |\n| `agentIdentity` | [SecurityCopilotAgentIdentity-7feb151a-fa8a-4cb1-83f3-26911e9994c7](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/AgentIdentity.MenuView/~/overview/objectId/b18f5f76-7cf9-478b-a5ef-405c70444c67/menuId/overview) | ✅ Enabled |\n| `agentIdentity` | [SecurityCopilotAgentIdentity-84a4fa89-0381-4c27-8777-1a78902b5434](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/AgentIdentity.MenuView/~/overview/objectId/c35beeb5-85e8-4d03-b6ef-26311355d140/menuId/overview) | ✅ Enabled |\n| `agentIdentity` | [SecurityCopilotAgentIdentity-88f412da-5184-4c15-9ed0-740db08a073f](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/AgentIdentity.MenuView/~/overview/objectId/c0eb713b-b415-4db2-99d5-dfcefbf51a71/menuId/overview) | ✅ Enabled |\n| `agentIdentity` | [SecurityCopilotAgentIdentity-895b26b2-122d-41e6-87a1-8f72baca0064](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/AgentIdentity.MenuView/~/overview/objectId/9bc16fbb-1444-4f07-af42-602688a89fcb/menuId/overview) | ✅ Enabled |\n| `agentIdentity` | [SecurityCopilotAgentIdentity-8a9cefc4-b0ab-4eb1-8a59-61bcd4f98888](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/AgentIdentity.MenuView/~/overview/objectId/6c0cbdfc-e93a-428b-8f54-1d92732b7247/menuId/overview) | ✅ Enabled |\n| `agentIdentity` | [SecurityCopilotAgentIdentity-8ab621e6-883a-4a48-85e1-6ffe6c941c0c](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/AgentIdentity.MenuView/~/overview/objectId/92cda4a7-2e20-4f0f-b1dd-c58177b57459/menuId/overview) | ✅ Enabled |\n| `agentIdentity` | [SecurityCopilotAgentIdentity-8b1b4aa4-ac2e-4703-93c4-eb734742f759](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/AgentIdentity.MenuView/~/overview/objectId/2d1aa366-d6f0-4b1e-b55d-7d16962ec4cf/menuId/overview) | ✅ Enabled |\n| `agentIdentity` | [SecurityCopilotAgentIdentity-907c50a6-c8eb-4248-8bd5-6a330291fccd](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/AgentIdentity.MenuView/~/overview/objectId/1596648f-2906-4578-ad33-4e9f233856e2/menuId/overview) | ✅ Enabled |\n| `agentIdentity` | [SecurityCopilotAgentIdentity-a0d9a96b-9b08-4907-90b0-b9ecfcca8954](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/AgentIdentity.MenuView/~/overview/objectId/940e5a11-3d0e-45ba-84c0-7f360aa97d68/menuId/overview) | ✅ Enabled |\n| `agentIdentity` | [SecurityCopilotAgentIdentity-a182efed-c1f9-45e4-a37e-3a9c46f6d36c](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/AgentIdentity.MenuView/~/overview/objectId/7492057c-4467-471f-b157-b655a3021d52/menuId/overview) | ✅ Enabled |\n| `agentIdentity` | [SecurityCopilotAgentIdentity-a182efed-c1f9-45e4-a37e-3a9c46f6d36c](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/AgentIdentity.MenuView/~/overview/objectId/ef0de165-8b09-402c-8911-9ead54a1a10d/menuId/overview) | ✅ Enabled |\n| `agentIdentity` | [SecurityCopilotAgentIdentity-a71cb3c4-430b-4c48-ab64-f2f9a71962e6](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/AgentIdentity.MenuView/~/overview/objectId/7fdf1056-df3a-4b90-9531-9b4147733e0f/menuId/overview) | ✅ Enabled |\n| `agentIdentity` | [SecurityCopilotAgentIdentity-a9d6aea9-825e-4822-a7a6-d6aab558968c](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/AgentIdentity.MenuView/~/overview/objectId/730dbc08-6cae-497d-b90a-c913c4c28cf1/menuId/overview) | ✅ Enabled |\n| `agentIdentity` | [SecurityCopilotAgentIdentity-ae41843d-8f64-47e4-a26a-a40bba85dddb](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/AgentIdentity.MenuView/~/overview/objectId/0d4376d6-afa2-44b6-9273-e802ef4f2b00/menuId/overview) | ✅ Enabled |\n| `agentIdentity` | [SecurityCopilotAgentIdentity-afdddb67-9a23-4641-a60d-49b0af424980](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/AgentIdentity.MenuView/~/overview/objectId/2fa8f510-1e46-4280-90dd-3680097ca80a/menuId/overview) | ✅ Enabled |\n| `agentIdentity` | [SecurityCopilotAgentIdentity-b2722658-fb6d-42c9-b62c-fe1bf0e7902c](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/AgentIdentity.MenuView/~/overview/objectId/80f80054-346a-4e18-8cdc-873459f88b05/menuId/overview) | ✅ Enabled |\n| `agentIdentity` | [SecurityCopilotAgentIdentity-b32e662a-5705-4d4f-8c37-15f06314c5c7](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/AgentIdentity.MenuView/~/overview/objectId/cad2be78-dfa5-462f-8edf-1ce81dfacd5f/menuId/overview) | ✅ Enabled |\n| `agentIdentity` | [SecurityCopilotAgentIdentity-b46bff89-3ef1-4a48-a735-7df9701a4db0](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/AgentIdentity.MenuView/~/overview/objectId/2881643f-fba7-4ece-beaa-308ca9d99a4a/menuId/overview) | ✅ Enabled |\n| `agentIdentity` | [SecurityCopilotAgentIdentity-b5c9af83-baed-49fc-b73a-4564a4e0d3f9](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/AgentIdentity.MenuView/~/overview/objectId/18860bb3-fe57-4e2b-89b8-7745dd5dad15/menuId/overview) | ✅ Enabled |\n| `agentIdentity` | [SecurityCopilotAgentIdentity-b6cb0950-4449-4ad9-b2e3-946bdcced2ca](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/AgentIdentity.MenuView/~/overview/objectId/4dc2f386-8653-4b61-a0c3-069783fb114e/menuId/overview) | ✅ Enabled |\n| `agentIdentity` | [SecurityCopilotAgentIdentity-bae8e936-f19e-40ba-b7b6-86c8dca01521](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/AgentIdentity.MenuView/~/overview/objectId/40c7db53-0225-4cf9-9fa5-d35d92e30a9b/menuId/overview) | ✅ Enabled |\n| `agentIdentity` | [SecurityCopilotAgentIdentity-bb3a64e2-36c3-43e6-b08b-4753cb86c433](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/AgentIdentity.MenuView/~/overview/objectId/71e7299b-490c-45f5-8eb2-677712e2854b/menuId/overview) | ✅ Enabled |\n| `agentIdentity` | [SecurityCopilotAgentIdentity-bd62ce89-11c1-4d52-9ba1-b94c27e54366](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/AgentIdentity.MenuView/~/overview/objectId/bcfa65f8-7503-4997-b53d-3f046044de3a/menuId/overview) | ✅ Enabled |\n| `agentIdentity` | [SecurityCopilotAgentIdentity-bf7fbf39-c643-4f96-a42f-1c6e8b58acc3](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/AgentIdentity.MenuView/~/overview/objectId/cc0551a7-6e81-4898-9e29-5caa8cddee33/menuId/overview) | ✅ Enabled |\n| `agentIdentity` | [SecurityCopilotAgentIdentity-bfb78649-54af-4b34-b754-af45ccc92a86](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/AgentIdentity.MenuView/~/overview/objectId/a8e8fa4a-4ed4-4344-a142-830603a4ee85/menuId/overview) | ✅ Enabled |\n| `agentIdentity` | [SecurityCopilotAgentIdentity-c0a6b598-8dd9-4e1b-b3d3-630c00f9f283](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/AgentIdentity.MenuView/~/overview/objectId/a5be2ca0-9160-4707-befd-692cf00fbc8e/menuId/overview) | ✅ Enabled |\n| `agentIdentity` | [SecurityCopilotAgentIdentity-c2e8e95f-49ab-4242-a956-252fe0e7b4d2](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/AgentIdentity.MenuView/~/overview/objectId/b99de51f-7c98-47e0-917d-5f26792a2ce1/menuId/overview) | ✅ Enabled |\n| `agentIdentity` | [SecurityCopilotAgentIdentity-c83f7f9e-1fe1-496d-b43b-9da0a2638be6](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/AgentIdentity.MenuView/~/overview/objectId/5c1a5eb2-d829-454e-80dd-2b2db50f9840/menuId/overview) | ✅ Enabled |\n| `agentIdentity` | [SecurityCopilotAgentIdentity-cbf9cebf-f419-4339-afab-891e9295e722](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/AgentIdentity.MenuView/~/overview/objectId/ed2a8d3d-34f1-4e16-bb59-112b212a77ae/menuId/overview) | ✅ Enabled |\n| `agentIdentity` | [SecurityCopilotAgentIdentity-cc23b939-a786-4c1c-8594-e48bba300905](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/AgentIdentity.MenuView/~/overview/objectId/87c5c26c-4dfe-43b3-a938-b75f9875d697/menuId/overview) | ✅ Enabled |\n| `agentIdentity` | [SecurityCopilotAgentIdentity-ccebd11a-5c6a-4bab-8b26-08e5639bbcc5](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/AgentIdentity.MenuView/~/overview/objectId/36a8d38d-0f77-4486-b2b7-8c7697d1c0c1/menuId/overview) | ✅ Enabled |\n| `agentIdentity` | [SecurityCopilotAgentIdentity-cf591160-848a-464d-b535-51bc8566e501](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/AgentIdentity.MenuView/~/overview/objectId/01b0e512-d0d6-45c6-877a-ffcc7acf3e90/menuId/overview) | ✅ Enabled |\n| `agentIdentity` | [SecurityCopilotAgentIdentity-d19d7b0d-aad7-4fb0-bf24-e6e4b7827310](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/AgentIdentity.MenuView/~/overview/objectId/8cfa4831-fb36-4821-a52e-ff260c056891/menuId/overview) | ✅ Enabled |\n| `agentIdentity` | [SecurityCopilotAgentIdentity-d21662de-4bdf-489e-b936-89d0408beb44](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/AgentIdentity.MenuView/~/overview/objectId/8d7c206d-63a6-4a3c-bba2-ccbd608be828/menuId/overview) | ✅ Enabled |\n| `agentIdentity` | [SecurityCopilotAgentIdentity-d344f1e3-b3a0-483b-b1f1-5e9739fc8245](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/AgentIdentity.MenuView/~/overview/objectId/71529564-4147-48da-a290-7b55906d975d/menuId/overview) | ✅ Enabled |\n| `agentIdentity` | [SecurityCopilotAgentIdentity-d5cb1f69-e9e5-414c-b284-838ee5145750](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/AgentIdentity.MenuView/~/overview/objectId/b5644e02-1300-4155-8c8d-af9e9a29cba9/menuId/overview) | ✅ Enabled |\n| `agentIdentity` | [SecurityCopilotAgentIdentity-d99a00c5-3f10-44af-a067-784fc0023813](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/AgentIdentity.MenuView/~/overview/objectId/d6484b1b-4111-40db-b09c-5051e1cc5468/menuId/overview) | ✅ Enabled |\n| `agentIdentity` | [SecurityCopilotAgentIdentity-dfd4919a-56e3-4fc8-b18a-810e6987ea2a](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/AgentIdentity.MenuView/~/overview/objectId/6f1ecd3b-7067-4de9-8edb-522a52b222da/menuId/overview) | ✅ Enabled |\n| `agentIdentity` | [SecurityCopilotAgentIdentity-e3c73ab3-f9d1-4f71-ad13-6ab0d72026fa](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/AgentIdentity.MenuView/~/overview/objectId/f7f664a5-c5e6-4961-8096-e551f865c349/menuId/overview) | ✅ Enabled |\n| `agentIdentity` | [SecurityCopilotAgentIdentity-ec330555-03c4-4cb0-9da3-8922359420fa](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/AgentIdentity.MenuView/~/overview/objectId/8d6994cd-9625-4362-9850-2dfaacaba16a/menuId/overview) | ✅ Enabled |\n| `agentIdentity` | [SecurityCopilotAgentIdentity-ed3cdfd9-c86a-45ac-9d0d-e24ff7dd99c1](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/AgentIdentity.MenuView/~/overview/objectId/07b47306-3162-4457-8f09-fe1b25133172/menuId/overview) | ✅ Enabled |\n| `agentIdentity` | [SecurityCopilotAgentIdentity-eefd0cf5-7bb0-4a4b-8b6e-27648554185a](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/AgentIdentity.MenuView/~/overview/objectId/cfc5d608-b4fe-40c5-80e4-4d873b8ab7ce/menuId/overview) | ✅ Enabled |\n| `agentIdentity` | [SecurityCopilotAgentIdentity-efab47b7-25fe-4e83-b9de-9171fc62bb7a](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/AgentIdentity.MenuView/~/overview/objectId/72d13ab2-4aef-49ae-9a4c-3cfa8f08dd3c/menuId/overview) | ✅ Enabled |\n| `agentIdentity` | [SecurityCopilotAgentIdentity-f64cddc3-e9ab-492b-bde9-84747b20cea0](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/AgentIdentity.MenuView/~/overview/objectId/8a5d1fb5-666f-4fad-b517-f8244bae5b4b/menuId/overview) | ✅ Enabled |\n| `agentIdentity` | [SecurityCopilotAgentIdentity-f9074de8-4007-4242-bcf4-7913b93f2129](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/AgentIdentity.MenuView/~/overview/objectId/bb373445-01e0-478c-b6e9-e72eb8ee3663/menuId/overview) | ✅ Enabled |\n| `agentIdentity` | [SecurityCopilotAgentIdentity-fa11924a-343f-4280-9cf7-a692a4b1e76c](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/AgentIdentity.MenuView/~/overview/objectId/ede4ef77-0bdc-4853-888d-53f951a18689/menuId/overview) | ✅ Enabled |\n| `agentIdentity` | [SecurityCopilotAgentIdentity-fabff31b-dfc7-4da7-96e7-bced6a4517aa](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/AgentIdentity.MenuView/~/overview/objectId/a2ba5146-96e6-4de1-8821-b2be227546af/menuId/overview) | ✅ Enabled |\n| `agentIdentity` | [SecurityCopilotAgentIdentity-fc5e141b-ce93-4657-bbf5-dab480da7935](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/AgentIdentity.MenuView/~/overview/objectId/f0f2eff6-4c06-4420-8909-4a1ea30988fb/menuId/overview) | ✅ Enabled |\n| `agentIdentity` | [Sentiment Analysis Agent](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/AgentIdentity.MenuView/~/overview/objectId/c29c6de1-e188-4d34-8099-0c1afc9ffd63/menuId/overview) | ✅ Enabled |\n| `agentIdentity` | [Sentinel Incident Monitor (Microsoft Copilot Studio)](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/AgentIdentity.MenuView/~/overview/objectId/40caa45b-81a6-44d3-96b0-1ecc2098a20a/menuId/overview) | ✅ Enabled |\n| `agentIdentity` | [Sentinel MCP Query Agent (Microsoft Copilot Studio)](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/AgentIdentity.MenuView/~/overview/objectId/b2eeef11-525a-4815-91b0-61a999fa3873/menuId/overview) | ✅ Enabled |\n| `agentIdentity` | [sentinel-mcp-data-exploration-re-sentinel-mcp-data-exploration-AgentIdentity](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/AgentIdentity.MenuView/~/overview/objectId/a73d2497-f07d-4d14-aadd-9de48bf774cf/menuId/overview) | ✅ Enabled |\n| `agentIdentity` | [Sentinell MCP Tools Finder (Microsoft Copilot Studio)](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/AgentIdentity.MenuView/~/overview/objectId/55f83b22-0687-4fe2-ba1b-249de90c0cf4/menuId/overview) | ✅ Enabled |\n| `agentIdentity` | [SentinelMCPTest (Microsoft Copilot Studio)](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/AgentIdentity.MenuView/~/overview/objectId/d6ce2023-a01c-49c6-87ff-9059d1145f7c/menuId/overview) | ✅ Enabled |\n| `agentIdentity` | [Service Catalog Agent](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/AgentIdentity.MenuView/~/overview/objectId/df4b3877-2fa4-4d27-9bbc-70450aa83361/menuId/overview) | ✅ Enabled |\n| `agentIdentity` | [Shipping & Logistics Agent](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/AgentIdentity.MenuView/~/overview/objectId/72dfd922-73ac-4ed5-84c5-77a856e32507/menuId/overview) | ✅ Enabled |\n| `agentIdentity` | [Sign-In Anomaly Detection Agent (Microsoft Copilot Studio)](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/AgentIdentity.MenuView/~/overview/objectId/83f01a2e-3433-4104-b436-0630fa49cf01/menuId/overview) | ✅ Enabled |\n| `agentIdentity` | [Sign-In Log Security Monitor (Microsoft Copilot Studio)](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/AgentIdentity.MenuView/~/overview/objectId/23bb7cff-23a9-405e-abd8-d7ad4acfaa7d/menuId/overview) | ✅ Enabled |\n| `agentIdentity` | [SLA Monitor Agent](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/AgentIdentity.MenuView/~/overview/objectId/3db4cd46-1291-4e58-b6dd-8c5b407d18b1/menuId/overview) | ✅ Enabled |\n| `agentIdentity` | [Supply Chain Agent](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/AgentIdentity.MenuView/~/overview/objectId/775c3af8-7eb7-40cd-a001-4c4c81705011/menuId/overview) | ✅ Enabled |\n| `agentIdentity` | [Task Assistance Copilot (Microsoft Copilot Studio)](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/AgentIdentity.MenuView/~/overview/objectId/74a73e2a-9efa-4b1c-b8f1-a89e5707f1cf/menuId/overview) | ✅ Enabled |\n| `agentIdentity` | [Tax Compliance Agent](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/AgentIdentity.MenuView/~/overview/objectId/06afd4f1-411a-448a-a045-6ed72b4763f1/menuId/overview) | ✅ Enabled |\n| `agentIdentity` | [Technical Support Agent](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/AgentIdentity.MenuView/~/overview/objectId/54ab50ff-6e08-46bc-a389-c047ac1621fb/menuId/overview) | ✅ Enabled |\n| `agentIdentity` | [Telemetry Collector](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/AgentIdentity.MenuView/~/overview/objectId/ccf9f471-358e-4c14-a313-30d563b178c7/menuId/overview) | ✅ Enabled |\n| `agentIdentity` | [Test (Microsoft Copilot Studio)](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/AgentIdentity.MenuView/~/overview/objectId/08fd10ad-8879-4121-a71e-288e60fad0df/menuId/overview) | ✅ Enabled |\n| `agentIdentity` | [Test Agent (Microsoft Copilot Studio)](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/AgentIdentity.MenuView/~/overview/objectId/6b27b6fd-6288-4153-9e6b-eb6bb57ec29a/menuId/overview) | ✅ Enabled |\n| `agentIdentity` | [Test Agent (Microsoft Copilot Studio)](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/AgentIdentity.MenuView/~/overview/objectId/350db4d8-3c7c-4253-9683-907ffda33464/menuId/overview) | ✅ Enabled |\n| `agentIdentity` | [test browser automation (Microsoft Copilot Studio)](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/AgentIdentity.MenuView/~/overview/objectId/11e8555b-af23-4041-b718-91c10a11b3a9/menuId/overview) | ✅ Enabled |\n| `agentIdentity` | [testremy (Microsoft Copilot Studio)](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/AgentIdentity.MenuView/~/overview/objectId/b38c72e8-0bbd-4585-b6f1-af446912f080/menuId/overview) | ✅ Enabled |\n| `agentIdentity` | [Threat Detection Agent](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/AgentIdentity.MenuView/~/overview/objectId/584301f4-c19f-450e-833b-2b35812b287e/menuId/overview) | ✅ Enabled |\n| `agentIdentity` | [Threat Hunting Agent (Security Copilot)](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/AgentIdentity.MenuView/~/overview/objectId/672b6935-9438-49b7-b583-2867cdafdf16/menuId/overview) | ✅ Enabled |\n| `agentIdentity` | [Threat Intelligence Briefing Agent - TI (Microsoft Copilot Studio)](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/AgentIdentity.MenuView/~/overview/objectId/699f780e-27f9-4317-908b-32a167f0ebd2/menuId/overview) | ✅ Enabled |\n| `agentIdentity` | [Threat Intelligence Briefing Agent (Security Copilot)](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/AgentIdentity.MenuView/~/overview/objectId/192b35aa-86fa-4949-b86e-f616fb32f9b9/menuId/overview) | ✅ Enabled |\n| `agentIdentity` | [Threat Intelligence Briefing Agent (Security Copilot)](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/AgentIdentity.MenuView/~/overview/objectId/00bc047f-4a0d-4eb0-aacc-9ff465502dea/menuId/overview) | ✅ Enabled |\n| `agentIdentity` | [Threat Intelligence Briefing Agent (Security Copilot)](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/AgentIdentity.MenuView/~/overview/objectId/42f3f47a-54d9-4d8d-85b0-337b65352f7a/menuId/overview) | ✅ Enabled |\n| `agentIdentity` | [Threat Intelligence Briefing Agent (Security Copilot)](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/AgentIdentity.MenuView/~/overview/objectId/f873d9e8-84f0-4991-a4df-9efcb0f5fd34/menuId/overview) | ✅ Enabled |\n| `agentIdentity` | [Threat Intelligence Briefing Agent (Security Copilot)](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/AgentIdentity.MenuView/~/overview/objectId/7b33146d-8967-42dd-8e58-5f98c22aa9d6/menuId/overview) | ✅ Enabled |\n| `agentIdentity` | [Threat Intelligence Briefing Agent (Security Copilot)](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/AgentIdentity.MenuView/~/overview/objectId/012542e1-d3c1-45f0-9c2c-8cd208204579/menuId/overview) | ✅ Enabled |\n| `agentIdentity` | [Training & Development Agent](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/AgentIdentity.MenuView/~/overview/objectId/84d060be-a68b-4892-ad3a-f79de0701ad5/menuId/overview) | ✅ Enabled |\n| `agentIdentity` | [Translation Services Agent](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/AgentIdentity.MenuView/~/overview/objectId/5ae980bf-c550-4ce9-b2b5-5e6eb21c6799/menuId/overview) | ✅ Enabled |\n| `agentIdentity` | [Travel & Expense Agent](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/AgentIdentity.MenuView/~/overview/objectId/8dd90ba2-1727-4d66-b6be-685f4e7baec3/menuId/overview) | ✅ Enabled |\n| `agentIdentity` | [Triage emails and chats (Microsoft Copilot Studio)](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/AgentIdentity.MenuView/~/overview/objectId/ace6ff96-c3d4-4699-a0a1-55929423ac77/menuId/overview) | ✅ Enabled |\n| `agentIdentity` | [Usage Analytics Agent](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/AgentIdentity.MenuView/~/overview/objectId/780d24db-a067-4351-a96e-bc569f269326/menuId/overview) | ✅ Enabled |\n| `agentIdentity` | [Vendor Management Agent](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/AgentIdentity.MenuView/~/overview/objectId/a46f0038-ec21-4066-b1a3-8cc38fa5146a/menuId/overview) | ✅ Enabled |\n| `agentIdentity` | [Vulnerability Scanner](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/AgentIdentity.MenuView/~/overview/objectId/69221653-681d-4cbe-a48d-b2e199a9f8c4/menuId/overview) | ✅ Enabled |\n| `agentIdentity` | [Warranty Claims Agent](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/AgentIdentity.MenuView/~/overview/objectId/776b2e0a-7eb6-4b6e-b5a8-002e622bcef0/menuId/overview) | ✅ Enabled |\n| `agentIdentity` | [Website Q&A (Microsoft Copilot Studio)](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/AgentIdentity.MenuView/~/overview/objectId/94e584cf-8792-414a-9bcb-2579cecd0229/menuId/overview) | ✅ Enabled |\n| `agentIdentity` | [WidgetBuilder Identity](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/AgentIdentity.MenuView/~/overview/objectId/366bbe3d-5ff9-4c00-a272-9c8cac935c6b/menuId/overview) | ✅ Enabled |\n| `agentIdentity` | [Workflow Automation Agent](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/AgentIdentity.MenuView/~/overview/objectId/d8ae4047-e81b-445c-b882-4d27fb8ad1f4/menuId/overview) | ✅ Enabled |\n| `agentIdentity` | [Zava Billing Agent (Microsoft Copilot Studio)](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/AgentIdentity.MenuView/~/overview/objectId/50fd65c6-2588-4b97-ac26-40da76bc2b7b/menuId/overview) | ✅ Enabled |\n| `agentIdentity` | [Zava Customer Recommendations (Microsoft Copilot Studio)](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/AgentIdentity.MenuView/~/overview/objectId/f25b025d-8be8-48c4-afda-7a6339dd3ef7/menuId/overview) | ✅ Enabled |\n| `agentIdentity` | [Zava Information Assistant (Microsoft Copilot Studio)](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/AgentIdentity.MenuView/~/overview/objectId/15848f13-0fa4-4e8e-9006-cf7585d71994/menuId/overview) | ✅ Enabled |\n| `agentIdentityBlueprintPrincipal` | [agent-quick-start-zn7uy-MDC Blueprint](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/AgentBlueprintDetails.MenuView/~/overview/objectId/b7d47567-77c8-4641-9184-1df9f192ff92) | ✅ Enabled |\n| `agentIdentityBlueprintPrincipal` | [AI-avo716-2028-ai-avo716-2028-project-ITHelpdesk-SuperAgent-AgentIdentityBlueprint](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/AgentBlueprintDetails.MenuView/~/overview/objectId/c84d42fe-5a11-4d54-ae03-76bc023e72e5) | ❌ Disabled |\n| `agentIdentityBlueprintPrincipal` | [ais-489n-procurementagent-aifp-489n-procurementagent-AgentIdentityBlueprint](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/AgentBlueprintDetails.MenuView/~/overview/objectId/3e8a999a-b7e6-404e-965b-9acdadbd5c6f) | ✅ Enabled |\n| `agentIdentityBlueprintPrincipal` | [ais-489n-procurementagent-aifp-489n-procurementagent-procurement-v2-chat-agent-5bb0f-AgentIdentityBlueprint](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/AgentBlueprintDetails.MenuView/~/overview/objectId/d43bafba-8414-4d0a-b079-8ee8164c7533) | ✅ Enabled |\n| `agentIdentityBlueprintPrincipal` | [ais-489n-procurementagent-aifp-489n-procurementagent-procurement-v2-orchestrator-agent-15196-AgentIdentityBlueprint](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/AgentBlueprintDetails.MenuView/~/overview/objectId/5e3be08f-41ff-4d20-998b-9508f5d10891) | ✅ Enabled |\n| `agentIdentityBlueprintPrincipal` | [ais-489n-procurementagent-aifp-489n-procurementagent-procurement-v2-policy-agent-7fa59-AgentIdentityBlueprint](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/AgentBlueprintDetails.MenuView/~/overview/objectId/0f5959f3-674d-4d52-9e59-74be380e2284) | ✅ Enabled |\n| `agentIdentityBlueprintPrincipal` | [ais-489n-procurementagent-aifp-489n-procurementagent-procurement-v2-product-agent-3a96a-AgentIdentityBlueprint](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/AgentBlueprintDetails.MenuView/~/overview/objectId/055417e6-ed2d-4633-b9e8-036e708acc05) | ✅ Enabled |\n| `agentIdentityBlueprintPrincipal` | [ais-procurementagent-aifp-procurementagent-naha84-test-03e48-AgentIdentityBlueprint](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/AgentBlueprintDetails.MenuView/~/overview/objectId/ebd51377-dff6-439d-a009-c7fae3527e01) | ✅ Enabled |\n| `agentIdentityBlueprintPrincipal` | [ais-yxhw-procurementagent-aifp-yxhw-procurementagent-AgentIdentityBlueprint](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/AgentBlueprintDetails.MenuView/~/overview/objectId/e555e85e-0d2e-46b6-8343-21d25afc71cb) | ✅ Enabled |\n| `agentIdentityBlueprintPrincipal` | [ais-yxhw-procurementagent-aifp-yxhw-procurementagent-procurement-v2-chat-agent-b16a9-AgentIdentityBlueprint](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/AgentBlueprintDetails.MenuView/~/overview/objectId/49c0cbbc-fb22-410a-a61d-ffb6aee14d6a) | ✅ Enabled |\n| `agentIdentityBlueprintPrincipal` | [ais-yxhw-procurementagent-aifp-yxhw-procurementagent-procurement-v2-orchestrator-agent-55c4e-AgentIdentityBlueprint](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/AgentBlueprintDetails.MenuView/~/overview/objectId/4f3c7b83-e7fd-4db8-a114-f5422fb50552) | ✅ Enabled |\n| `agentIdentityBlueprintPrincipal` | [ais-yxhw-procurementagent-aifp-yxhw-procurementagent-procurement-v2-policy-agent-c685a-AgentIdentityBlueprint](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/AgentBlueprintDetails.MenuView/~/overview/objectId/9c3882ea-22d3-4506-9b47-255ef04dfc9b) | ✅ Enabled |\n| `agentIdentityBlueprintPrincipal` | [ais-yxhw-procurementagent-aifp-yxhw-procurementagent-procurement-v2-product-agent-d5da9-AgentIdentityBlueprint](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/AgentBlueprintDetails.MenuView/~/overview/objectId/dcf8c9da-ea79-448e-a4d9-5708e61abfd8) | ✅ Enabled |\n| `agentIdentityBlueprintPrincipal` | [App Lifecycle Management Agent Blueprint - Prod](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/AgentBlueprintDetails.MenuView/~/overview/objectId/2657a894-5f06-4c1a-b5ae-b22c9e671041) | ✅ Enabled |\n| `agentIdentityBlueprintPrincipal` | [AR Agent Agent Prod Blueprint](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/AgentBlueprintDetails.MenuView/~/overview/objectId/1ce26f3e-4152-41ce-a76a-ad50a67428e0) | ✅ Enabled |\n| `agentIdentityBlueprintPrincipal` | [Conditional Access Agent](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/AgentBlueprintDetails.MenuView/~/overview/objectId/826a7c3a-b27e-41e2-bc8b-0137ca1a9dd5) | ✅ Enabled |\n| `agentIdentityBlueprintPrincipal` | [finance-data-analysis-resource-finance-data-analysis-AgentIdentityBlueprint](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/AgentBlueprintDetails.MenuView/~/overview/objectId/18710959-c14e-4b85-9212-8a640cdef2eb) | ❌ Disabled |\n| `agentIdentityBlueprintPrincipal` | [FoundryEY-EY001-AgentIdentityBlueprint](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/AgentBlueprintDetails.MenuView/~/overview/objectId/2eb99441-d6d4-4024-96d3-187765107875) | ✅ Enabled |\n| `agentIdentityBlueprintPrincipal` | [FoundryEY-EY001-EY001-AgentIdentityBlueprint](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/AgentBlueprintDetails.MenuView/~/overview/objectId/12c72e7f-894e-465e-a985-28abc08759c0) | ✅ Enabled |\n| `agentIdentityBlueprintPrincipal` | [Genspark](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/AgentBlueprintDetails.MenuView/~/overview/objectId/8d1b328b-221a-40db-b9bf-00ce07ff11e3) | ✅ Enabled |\n| `agentIdentityBlueprintPrincipal` | [Intune Policy Agent](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/AgentBlueprintDetails.MenuView/~/overview/objectId/db3b6b9a-b06d-427b-8db3-a97bc8881a4d) | ✅ Enabled |\n| `agentIdentityBlueprintPrincipal` | [Intune Vulnerability Remediation Agent](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/AgentBlueprintDetails.MenuView/~/overview/objectId/6f70776f-92af-411f-b061-30ef3b3c456a) | ✅ Enabled |\n| `agentIdentityBlueprintPrincipal` | [IP Risk Remediation Agent Blueprint](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/AgentBlueprintDetails.MenuView/~/overview/objectId/49300dbd-7869-489d-b1e1-01a90f8eed85) | ✅ Enabled |\n| `agentIdentityBlueprintPrincipal` | [ISV Fraud Detection Blueprint](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/AgentBlueprintDetails.MenuView/~/overview/objectId/3893f59a-efa9-473b-98c4-a2cb8e73a7d4) | ❌ Disabled |\n| `agentIdentityBlueprintPrincipal` | [kpa588-3556-resource-kpa588-3556-AgentIdentityBlueprint](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/AgentBlueprintDetails.MenuView/~/overview/objectId/2c4646b7-3f50-413f-8657-06887cef3e09) | ✅ Enabled |\n| `agentIdentityBlueprintPrincipal` | [kpa588-3556-resource-kpa588-3556-nk-dlp-purviewagent-f9d26-AgentIdentityBlueprint](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/AgentBlueprintDetails.MenuView/~/overview/objectId/9cfd09a1-95eb-4a5e-a191-3df8315c2907) | ✅ Enabled |\n| `agentIdentityBlueprintPrincipal` | [kpa588-3556-resource-kpa588-3556-purview-dlp-agent-9afdd-AgentIdentityBlueprint](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/AgentBlueprintDetails.MenuView/~/overview/objectId/5848cb85-0fc1-45e4-a598-6af9e6a5351c) | ✅ Enabled |\n| `agentIdentityBlueprintPrincipal` | [mame55-0957-resource-mame55-0957-4-Gad-Foundry-AgentIdentityBlueprint](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/AgentBlueprintDetails.MenuView/~/overview/objectId/707b9ca1-bf4b-42bc-8241-153f55325a10) | ❌ Disabled |\n| `agentIdentityBlueprintPrincipal` | [mia404-4409-resource-mia404-4409-Zava-Social-Media-Agent-AgentIdentityBlueprint](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/AgentBlueprintDetails.MenuView/~/overview/objectId/a69313ca-b7de-4fc2-9f47-2fb7b40deecf) | ❌ Disabled |\n| `agentIdentityBlueprintPrincipal` | [Microsoft Copilot Studio agent identity blueprint](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/AgentBlueprintDetails.MenuView/~/overview/objectId/722eaee1-e786-444a-aa1d-a0c833bc434f) | ✅ Enabled |\n| `agentIdentityBlueprintPrincipal` | [Microsoft Defender Hunting Agent](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/AgentBlueprintDetails.MenuView/~/overview/objectId/009db432-b85a-4d79-93e6-b3ae838b9468) | ✅ Enabled |\n| `agentIdentityBlueprintPrincipal` | [MOSTeamTest Blueprint](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/AgentBlueprintDetails.MenuView/~/overview/objectId/4c6fcb1e-b555-4e51-a6a8-92f708402d12) | ✅ Enabled |\n| `agentIdentityBlueprintPrincipal` | [noer62-7587-resource-noer62-7587-AgentIdentityBlueprint](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/AgentBlueprintDetails.MenuView/~/overview/objectId/1bbcd497-28a1-4e01-9b55-33c45a0e28d0) | ❌ Disabled |\n| `agentIdentityBlueprintPrincipal` | [Onboarding Orchestrator Blueprint](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/AgentBlueprintDetails.MenuView/~/overview/objectId/c473e15d-792c-4365-9653-949244241c0e) | ✅ Enabled |\n| `agentIdentityBlueprintPrincipal` | [optimize-hunting-agent](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/AgentBlueprintDetails.MenuView/~/overview/objectId/1b8059a8-e79a-4c0c-a7e9-0cf7c8e1718a) | ✅ Enabled |\n| `agentIdentityBlueprintPrincipal` | [PROD-OpalAgenticApp](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/AgentBlueprintDetails.MenuView/~/overview/objectId/f13f09e5-6d3f-49cc-a25f-38351a8e10f9) | ✅ Enabled |\n| `agentIdentityBlueprintPrincipal` | [Purview DLP Alert Triage Agent](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/AgentBlueprintDetails.MenuView/~/overview/objectId/019c4146-09a5-4a8f-9fa1-4b558ea9cfdf) | ✅ Enabled |\n| `agentIdentityBlueprintPrincipal` | [Purview DSPM Discovery Agent Blueprint](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/AgentBlueprintDetails.MenuView/~/overview/objectId/3d100158-8c00-4919-9c59-82b7ca5d22aa) | ✅ Enabled |\n| `agentIdentityBlueprintPrincipal` | [Purview IRM Triage Agent](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/AgentBlueprintDetails.MenuView/~/overview/objectId/ded969f7-5756-4e42-9948-f90f497e0dc3) | ✅ Enabled |\n| `agentIdentityBlueprintPrincipal` | [RSA2026 Agent Blueprint](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/AgentBlueprintDetails.MenuView/~/overview/objectId/a02d6894-3d33-45aa-9727-c4ed2e813d4a) | ✅ Enabled |\n| `agentIdentityBlueprintPrincipal` | [rsa2026triageacct-rsa2026triageproj-triage-helper-agent-AgentIdentityBlueprint](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/AgentBlueprintDetails.MenuView/~/overview/objectId/2f1a026d-b99e-4243-abbe-a54bcb4751fb) | ❌ Disabled |\n| `agentIdentityBlueprintPrincipal` | [sentinel-mcp-data-exploration-re-sentinel-mcp-data-exploration-foundry-search-test-d0c1d-AgentIdentityBlueprint](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/AgentBlueprintDetails.MenuView/~/overview/objectId/fd465018-7822-49e4-b2a4-b69b54bc09ce) | ✅ Enabled |\n| `agentIdentityBlueprintPrincipal` | [sentinel-mcp-data-exploration-re-sentinel-mcp-data-exploration-seths-test-agent-a980f-AgentIdentityBlueprint](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/AgentBlueprintDetails.MenuView/~/overview/objectId/998d2eb0-b87a-48b6-9547-c5cb362b39cc) | ✅ Enabled |\n| `agentIdentityBlueprintPrincipal` | [sentinel-mcp-data-exploration-re-sentinel-mcp-data-exploration-uplaod-test-74ee4-AgentIdentityBlueprint](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/AgentBlueprintDetails.MenuView/~/overview/objectId/c29a867c-c671-47f6-ac22-89b767ac61e8) | ✅ Enabled |\n| `agentIdentityBlueprintPrincipal` | [sentinel-mcp-data-exploration-re-sentinel-mcp-data-exploration-vectorization-ea-demo-7ca98-AgentIdentityBlueprint](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/AgentBlueprintDetails.MenuView/~/overview/objectId/b6ef3dbe-6d7d-4af8-8b1d-4c66afcde24c) | ✅ Enabled |\n| `agentIdentityBlueprintPrincipal` | [sentinel-mcp-data-exploration-re-sentinel-mcp-data-exploration-zachs-custom-tool-auto-agent-0447a-AgentIdentityBlueprint](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/AgentBlueprintDetails.MenuView/~/overview/objectId/13a20bb8-cb1c-4546-b4ac-81c5d2c0ed8e) | ✅ Enabled |\n| `agentIdentityBlueprintPrincipal` | [sentinel-mcp-data-exploration-re-sentinel-mcp-data-exploration-Zachs-VSCode-Agent-f6842-AgentIdentityBlueprint](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/AgentBlueprintDetails.MenuView/~/overview/objectId/2866dd42-866c-4cbc-97d3-3aa4360db4b3) | ❌ Disabled |\n| `agentIdentityBlueprintPrincipal` | [soc-vision-resource-soc_vision-incident-Investigation-multi-agents-AgentIdentityBlueprint](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/AgentBlueprintDetails.MenuView/~/overview/objectId/917176f0-da9b-48e1-a5d6-21fd3352da1a) | ❌ Disabled |\n| `agentIdentityBlueprintPrincipal` | [soc-vision-resource-soc_vision-incident-triage-84eae-AgentIdentityBlueprint](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/AgentBlueprintDetails.MenuView/~/overview/objectId/8f2cc7ef-7ce9-40c6-a8a6-d9880817154c) | ✅ Enabled |\n| `agentIdentityBlueprintPrincipal` | [soc-vision-resource-soc_vision-nemotron-3-super-120b-a12b-Agent-d2a22-AgentIdentityBlueprint](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/AgentBlueprintDetails.MenuView/~/overview/objectId/5b885c2c-b4c1-4945-9cc8-5dd89a6f63d0) | ❌ Disabled |\n| `agentIdentityBlueprintPrincipal` | [soc-vision-resource-soc_vision-Nemotron-AgenticSoc-Test-75f67-AgentIdentityBlueprint](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/AgentBlueprintDetails.MenuView/~/overview/objectId/2a7c307b-9e44-4d9c-a42f-043d69ecdb59) | ❌ Disabled |\n| `agentIdentityBlueprintPrincipal` | [soc-vision-resource-soc_vision-Sentinel-MCP-Auth-780b8-AgentIdentityBlueprint](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/AgentBlueprintDetails.MenuView/~/overview/objectId/4bb96f38-31d9-4daa-84f2-75820f8c317a) | ✅ Enabled |\n| `agentIdentityBlueprintPrincipal` | [soc-vision-resource-soc_vision-yanivsh-0423-754c5-AgentIdentityBlueprint](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/AgentBlueprintDetails.MenuView/~/overview/objectId/20af38fa-28d9-4469-b91b-9dd18d238175) | ❌ Disabled |\n| `agentIdentityBlueprintPrincipal` | [test-puerview-dlp-agent-test-puerview-dlp-agent-proj-AgentIdentityBlueprint](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/AgentBlueprintDetails.MenuView/~/overview/objectId/7bad2c69-f165-4497-aab8-17cbceb8e9bf) | ✅ Enabled |\n| `agentIdentityBlueprintPrincipal` | [thbe13-3899-resource-thbe13-3899-AgentIdentityBlueprint](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/AgentBlueprintDetails.MenuView/~/overview/objectId/2306468d-ed37-4b59-b5f5-f5c56cc99599) | ❌ Disabled |\n| `agentIdentityBlueprintPrincipal` | [TIB Agent Blueprint App](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/AgentBlueprintDetails.MenuView/~/overview/objectId/84a537c1-a3a7-4645-9547-bd766475b3a0) | ✅ Enabled |\n| `agentIdentityBlueprintPrincipal` | [USX Investigation Agent](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/AgentBlueprintDetails.MenuView/~/overview/objectId/21f23461-e7d1-46e1-8cce-dce0f96dbfa2) | ✅ Enabled |\n| `agentIdentityBlueprintPrincipal` | [USX Triage Agent](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/AgentBlueprintDetails.MenuView/~/overview/objectId/fd405949-1ca9-4154-9927-a3364974e657) | ✅ Enabled |\n| `agentIdentityBlueprintPrincipal` | [WidgetBuilder Blueprint](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/AgentBlueprintDetails.MenuView/~/overview/objectId/605f8f5f-35f9-4ccf-ac36-3a177cf4e28e) | ✅ Enabled |\n| `agentIdentityBlueprintPrincipal` | [woodgrovefoundry-woodgroveaiassistant-AgentIdentityBlueprint](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/AgentBlueprintDetails.MenuView/~/overview/objectId/4df43f77-61bb-4f4f-83d3-31a4bced1f9b) | ❌ Disabled |\n\r\n\r\n\r\n## Disabled agent identities and blueprint principals\r\n\r\n| Object type | Display name | Account enabled |\r\n| :---------- | :----------- | :-------------- |\r\n| `agentIdentity` | [\\[Actor\\]-AgentID](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/AgentIdentity.MenuView/~/overview/objectId/def723dc-01f5-4cec-aaa3-9694bacb5a0e/menuId/overview) | ❌ Disabled |\n| `agentIdentity` | [\\[AgentID\\] HR Test](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/AgentIdentity.MenuView/~/overview/objectId/cc7ecc7a-cd34-49ce-ac68-7d7b23e07249/menuId/overview) | ❌ Disabled |\n| `agentIdentity` | [MOSTeamTest Identity](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/AgentIdentity.MenuView/~/overview/objectId/6df68097-d282-4713-a5a6-b5ff6f764deb/menuId/overview) | ❌ Disabled |\n| `agentIdentity` | [RSA2026 Triage Agent](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/AgentIdentity.MenuView/~/overview/objectId/abfee1b3-88e0-45db-8e0c-cb6c3d6235a0/menuId/overview) | ❌ Disabled |\n| `agentIdentity` | [Test00001](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/AgentIdentity.MenuView/~/overview/objectId/8b893104-2a19-4897-9273-98910d19ae9c/menuId/overview) | ❌ Disabled |\n| `agentIdentityBlueprintPrincipal` | [AI-avo716-2028-ai-avo716-2028-project-ITHelpdesk-SuperAgent-AgentIdentityBlueprint](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/AgentBlueprintDetails.MenuView/~/overview/objectId/c84d42fe-5a11-4d54-ae03-76bc023e72e5) | ❌ Disabled |\n| `agentIdentityBlueprintPrincipal` | [finance-data-analysis-resource-finance-data-analysis-AgentIdentityBlueprint](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/AgentBlueprintDetails.MenuView/~/overview/objectId/18710959-c14e-4b85-9212-8a640cdef2eb) | ❌ Disabled |\n| `agentIdentityBlueprintPrincipal` | [ISV Fraud Detection Blueprint](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/AgentBlueprintDetails.MenuView/~/overview/objectId/3893f59a-efa9-473b-98c4-a2cb8e73a7d4) | ❌ Disabled |\n| `agentIdentityBlueprintPrincipal` | [mame55-0957-resource-mame55-0957-4-Gad-Foundry-AgentIdentityBlueprint](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/AgentBlueprintDetails.MenuView/~/overview/objectId/707b9ca1-bf4b-42bc-8241-153f55325a10) | ❌ Disabled |\n| `agentIdentityBlueprintPrincipal` | [mia404-4409-resource-mia404-4409-Zava-Social-Media-Agent-AgentIdentityBlueprint](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/AgentBlueprintDetails.MenuView/~/overview/objectId/a69313ca-b7de-4fc2-9f47-2fb7b40deecf) | ❌ Disabled |\n| `agentIdentityBlueprintPrincipal` | [noer62-7587-resource-noer62-7587-AgentIdentityBlueprint](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/AgentBlueprintDetails.MenuView/~/overview/objectId/1bbcd497-28a1-4e01-9b55-33c45a0e28d0) | ❌ Disabled |\n| `agentIdentityBlueprintPrincipal` | [rsa2026triageacct-rsa2026triageproj-triage-helper-agent-AgentIdentityBlueprint](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/AgentBlueprintDetails.MenuView/~/overview/objectId/2f1a026d-b99e-4243-abbe-a54bcb4751fb) | ❌ Disabled |\n| `agentIdentityBlueprintPrincipal` | [sentinel-mcp-data-exploration-re-sentinel-mcp-data-exploration-Zachs-VSCode-Agent-f6842-AgentIdentityBlueprint](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/AgentBlueprintDetails.MenuView/~/overview/objectId/2866dd42-866c-4cbc-97d3-3aa4360db4b3) | ❌ Disabled |\n| `agentIdentityBlueprintPrincipal` | [soc-vision-resource-soc_vision-incident-Investigation-multi-agents-AgentIdentityBlueprint](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/AgentBlueprintDetails.MenuView/~/overview/objectId/917176f0-da9b-48e1-a5d6-21fd3352da1a) | ❌ Disabled |\n| `agentIdentityBlueprintPrincipal` | [soc-vision-resource-soc_vision-nemotron-3-super-120b-a12b-Agent-d2a22-AgentIdentityBlueprint](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/AgentBlueprintDetails.MenuView/~/overview/objectId/5b885c2c-b4c1-4945-9cc8-5dd89a6f63d0) | ❌ Disabled |\n| `agentIdentityBlueprintPrincipal` | [soc-vision-resource-soc_vision-Nemotron-AgenticSoc-Test-75f67-AgentIdentityBlueprint](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/AgentBlueprintDetails.MenuView/~/overview/objectId/2a7c307b-9e44-4d9c-a42f-043d69ecdb59) | ❌ Disabled |\n| `agentIdentityBlueprintPrincipal` | [soc-vision-resource-soc_vision-yanivsh-0423-754c5-AgentIdentityBlueprint](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/AgentBlueprintDetails.MenuView/~/overview/objectId/20af38fa-28d9-4469-b91b-9dd18d238175) | ❌ Disabled |\n| `agentIdentityBlueprintPrincipal` | [thbe13-3899-resource-thbe13-3899-AgentIdentityBlueprint](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/AgentBlueprintDetails.MenuView/~/overview/objectId/2306468d-ed37-4b59-b5f5-f5c56cc99599) | ❌ Disabled |\n| `agentIdentityBlueprintPrincipal` | [woodgrovefoundry-woodgroveaiassistant-AgentIdentityBlueprint](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/AgentBlueprintDetails.MenuView/~/overview/objectId/4df43f77-61bb-4f4f-83d3-31a4bced1f9b) | ❌ Disabled |\n\r\n\r\n","TestSfiPillar":"Protect identities and secrets","TestStatus":"Failed","TestImpact":"Medium","TestPillar":"AI","TestId":"61014","TestRisk":"High","TestDescription":"Agent identities and agent identity blueprint principals are the two service-principal-derived types that carry runtime access in Microsoft Entra Agent ID. Agent identities are instantiated agents that acquire tokens and access resources directly; blueprint principals are the provisioning surface from which agent identities are created, and they hold their own app role assignments, delegated permission grants, and group memberships that can propagate to child agents. The `owners` relationship on each object designates the human user(s) responsible for technical operations and incident response, distinct from the `sponsors` relationship that carries business accountability for lifecycle and access decisions. When either object type has no owner, the tenant has an active principal that the security operations team cannot route to a responsible party when ID Protection flags it as risky, when anomalous resource-access patterns emerge, or when access-package extension requests require approval. A threat actor who compromises an ownerless agent or blueprint principal — through credential theft, blueprint exploitation, or malicious delegated consent — operates against a principal with no designated human for immediate containment, extending dwell time from minutes to the next manual directory audit cycle. The second failure mode is disabled objects that were blocked as part of triage but never deleted: a disabled object's `accountEnabled` property is `false` and it cannot acquire new tokens, but its app role assignments, group memberships, and OAuth2 permission grants persist in the directory. If a disabled agent identity is re-enabled — by an administrator who mistakes the disabled state for a provisioning error, or by a threat actor who has obtained directory write access — every permission snaps back without re-approval. If a disabled blueprint principal is re-enabled, it restores the provisioning surface for all child agent identities. The combination of ownerless objects and stale disabled objects is a standing-privilege accumulation pattern: the ownerless object has no human to initiate deletion, and the disabled-but-not-deleted object retains the privilege surface that deletion would have eliminated.\r\n\r\n**Remediation action**\r\n\r\nAdministrative relationships for agent IDs — owners, sponsors, and managers\r\n- [Administrative relationships in Microsoft Entra Agent ID (Owners, sponsors, and managers)](https://learn.microsoft.com/entra/agent-id/agent-owners-sponsors-managers)\r\n\r\nManage agent identities in your organization — add owners, enable/disable, delete\r\n- [Manage agent identities in your organization](https://learn.microsoft.com/entra/agent-id/manage-agent-identities-organization)\r\n\r\nGoverning agent identities — full governance lifecycle overview\r\n- [Governing agent identities](https://learn.microsoft.com/entra/id-governance/agent-id-governance-overview)\r\n\r\nManage agents in end-user experience — sponsors and owners can manage agents from the My Account portal\r\n- [Manage agent identities (end user)](https://learn.microsoft.com/entra/agent-id/manage-agent-identities-end-user)\r\n\r\n","TestTags":null,"TestMinimumLicense":["AAD_BASIC","AAD_PREMIUM"],"SkippedReason":null,"TestAppliesTo":null,"TestImplementationCost":"Medium","TestCategory":"Agent Lifecycle"},{"TestTitle":"Quick Access has assigned users or groups","TestSkipped":"","TestResult":"\r\n⚠️ Quick Access application is not configured in the tenant.\r\n\r\n","TestSfiPillar":"Protect networks","TestStatus":"Investigate","TestImpact":"Low","TestPillar":"Network","TestId":"25480","TestRisk":"Medium","TestDescription":"When Quick Access lacks user or group assignments, the service prevents connections to fully qualified domain names (FQDNs) and IP addresses that you configure in the application segments. This restriction disrupts access to internal resources like file shares, web applications, and databases. When users can't reach resources through the Global Secure Access client, they might seek alternative access methods that bypass security controls such as Conditional Access policies and multifactor authentication.\r\n\r\nIf you don't assign users to Quick Access:\r\n\r\n- Authorized users can't reach internal resources through Private Access, creating gaps in business continuity.\r\n- Administrators might implement temporary workarounds that weaken the organization's security posture.\r\n\r\n**Remediation action**\r\n\r\n- [Assign users and groups to Quick Access](https://learn.microsoft.com/entra/global-secure-access/how-to-configure-quick-access?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci) to enable Private Access connectivity to configured application segments.\r\n","TestTags":null,"TestMinimumLicense":["Entra_Premium_Private_Access"],"SkippedReason":null,"TestAppliesTo":null,"TestImplementationCost":"Low","TestCategory":"Global Secure Access"},{"TestId":"61004","TestCategory":"AI Cloud Posture","TestImpact":"Low","TestResult":"\r\n❌ One or more in-scope Azure subscriptions do not have the Defender CSPM plan enabled.\n\n\r\n\r\n## [Subscriptions missing Defender CSPM plan](https://portal.azure.com/#view/Microsoft_Azure_Security/SecurityMenuBlade/~/EnvironmentSettings)\r\n\r\n| Subscription | Pricing tier | Status |\r\n| :----------- | :----------- | :----- |\r\n| [Microsoft Azure Sponsorship 2](https://portal.azure.com/#view/Microsoft_Azure_Security/PolicyMenuBlade/~/pricingTier/subscriptionId/126905b4-2ebc-4ae5-8bf9-1001de049091) | Free | ❌ Fail |\n| [Microsoft Azure Sponsorship 2](https://portal.azure.com/#view/Microsoft_Azure_Security/PolicyMenuBlade/~/pricingTier/subscriptionId/7619e183-fb89-4e4b-a3b3-924fba956be7) | Free | ❌ Fail |\n\r\n","SkippedReason":null,"TestMinimumLicense":"Microsoft_Defender_for_Cloud","TestAppliesTo":null,"TestTags":null,"TestSfiPillar":"Protect tenants and production systems","TestImplementationCost":"Medium","TestSkipped":"","TestPillar":"AI","TestTitle":"Microsoft Defender for Cloud CSPM plan is enabled on all Azure subscriptions","TestStatus":"Failed","TestDescription":"Defender CSPM is the plan in Microsoft Defender for Cloud that scans your subscriptions, inventories your AI workloads, and surfaces risks through security recommendations and attack path analysis. Without it, there is no AI inventory, no flagging of misconfigured AI services, and no modeling of how an attacker could reach sensitive grounding data through an exposed endpoint. This check verifies the plan is enabled on every subscription that hosts AI workloads.\r\n\r\nWhen Defender CSPM is not enabled on a subscription hosting AI workloads, misconfigured AI service accounts — publicly exposed, secured only by API keys, lacking private endpoints — are never surfaced as risks and remain accessible indefinitely. Threat actors can exploit this visibility gap because the attack path from an exposed AI endpoint to the sensitive grounding or fine-tuning data it connects to has never been modeled by defenders. Without Defender CSPM, the organization cannot identify those paths before an attacker follows them.\r\n\r\n**Source:** [Overview - AI security posture management](https://learn.microsoft.com/azure/defender-for-cloud/ai-security-posture)\r\n\r\n**Remediation action**\r\n\r\n- [Enable Microsoft Defender for Cloud CSPM plan](https://learn.microsoft.com/azure/defender-for-cloud/tutorial-enable-cspm-plan)\r\n- [AI security posture management in Defender for Cloud](https://learn.microsoft.com/azure/defender-for-cloud/ai-security-posture)\r\n- [Enable plans programmatically (PUT .../pricings/CloudPosture)](https://learn.microsoft.com/rest/api/defenderforcloud/pricings/update)\r\n\r\n","TestRisk":"High"},{"TestTitle":"Entra Private Access Application segments are defined to enforce least-privilege access","TestSkipped":"","TestResult":"\r\n⚠️ No per-app Private Access applications configured. Please review the documentation on how to configure Private Access applications with granular network segments.\n\n\n## Summary\n\n| Metric | Value |\n|---|---|\n| Total Private Access apps | 0 |\n| Apps with broad segments | 0 |\n| Apps with CSA assigned | 0 |\n| Apps without CSA | 0 |\n| CA policies using applicationFilter | 0 |\n\n\r\n\r\n","TestSfiPillar":"Protect networks","TestStatus":"Investigate","TestImpact":"Medium","TestPillar":"Network","TestId":"25395","TestRisk":"High","TestDescription":"When organizations configure Microsoft Entra Private Access with broad application segments, such as wide IP ranges, multiple protocols, or Quick Access configurations, they effectively replicate the over-permissive access model of traditional VPNs. This approach contradicts the Zero Trust principle of least privilege, where users should only reach the specific resources required for their role.\r\n\r\nRisks of broad segmentation:\r\n\r\n- Threat actors who compromise a user's credentials or device can use broad network permissions to perform reconnaissance, identifying other systems and services within the permitted range.\r\n- Lateral movement becomes easier as attackers can access multiple systems through a single compromised credential.\r\n- Incident response is complicated because security teams can't quickly determine which specific resources a compromised identity could access.\r\n\r\nConfiguring per-application segmentation with tightly scoped destination hosts, specific ports, and Custom Security Attributes enables dynamic Conditional Access enforcement. This approach requires stronger authentication or device compliance for high-risk applications while streamlining access to lower-risk resources.\r\n\r\n**Remediation action**\r\n\r\n- [Review and refine application segments](https://learn.microsoft.com/entra/global-secure-access/how-to-configure-per-app-access?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci) to use specific FQDNs, IP addresses, and specific port ranges that match application requirements rather than wide port ranges.\r\n","TestTags":null,"TestMinimumLicense":["Entra_Premium_Private_Access"],"SkippedReason":null,"TestAppliesTo":null,"TestImplementationCost":"High","TestCategory":"Global Secure Access"},{"TestTitle":"Network access logs are retained for security analysis and compliance requirements","TestSkipped":"","TestResult":"\r\n✅ Global Secure Access logs are retained for at least 90 days, supporting security analysis and compliance requirements\n\n\n## [Diagnostic settings configuration](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ActiveDirectoryMenuBlade/~/DiagnosticSettings)\n\n### Log retention status\r\n\r\n| Log category | Enabled | Destination type | Retention period | Meets minimum (90 days) |\r\n| :--- | :--- | :--- | :--- | :--- |\r\n| AuditLogs | Yes | Workspace & Storage | 365 days | Yes |\n| NetworkAccessTrafficLogs | Yes | Workspace & Storage | 365 days | Yes |\n| EnrichedOffice365AuditLogs | Yes | Workspace & Storage | 365 days | Yes |\n| RemoteNetworkHealthLogs | Yes | Workspace & Storage | 365 days | Yes |\n| NetworkAccessAlerts | Yes | Workspace & Storage | 365 days | Yes |\n| NetworkAccessConnectionEvents | Yes | Workspace & Storage | 365 days | Yes |\n| NetworkAccessGenerativeAIInsights | Yes | Workspace & Storage | 365 days | Yes |\n\r\n### Destination details\r\n\r\n| Destination type | Resource name | Default retention | Status |\r\n| :--- | :--- | :--- | :--- |\r\n| [Log Analytics workspace](https://portal.azure.com/?feature.msaljs=true#browse/Microsoft.OperationalInsights%2Fworkspaces) & [Storage Account](https://portal.azure.com/?feature.msaljs=true#view/Microsoft_Azure_StorageHub/StorageHub.MenuView/~/StorageAccountsBrowse) | Woodgrove-LogAnalyiticsWorkspace | 365 days | Adequate |\n\r\n### Summary\n\n| Metric | Value |\n| :--- | :--- |\n| Total diagnostic settings | 1 |\n| Settings with long-term destination | 1 |\n| Average retention period | 365 days |\n| Minimum retention found | 365 days |\n| Meets 90-day minimum | Yes |\n\r\n\r\n","TestSfiPillar":"Monitor and detect cyberthreats","TestStatus":"Passed","TestImpact":"Low","TestPillar":"Network","TestId":"25420","TestRisk":"High","TestDescription":"Without extended retention for Global Secure Access audit and traffic logs, threat actors can operate beyond the default 30-day retention window, knowing that their activities are automatically purged before detection occurs. Security investigations often require historical analysis spanning weeks or months to identify compromise vectors, lateral movement patterns, and data exfiltration channels.\r\n\r\nWithout adequate log retention:\r\n\r\n- Security teams can't establish baseline behavior patterns, perform retrospective threat hunting, or correlate network access events across extended timeframes.\r\n- Organizations subject to regulatory frameworks like [GDPR](https://learn.microsoft.com/compliance/regulatory/gdpr?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci), HIPAA, PCI DSS, and SOX face compliance violations when they're unable to produce audit trails for mandated retention periods.\r\n- Root cause analysis during incident response is limited, potentially allowing threat actors to maintain persistence while organizations focus on visible symptoms.\r\n\r\n**Remediation action**\r\n\r\n- [Configure diagnostic settings with a Log Analytics workspace](https://learn.microsoft.com/entra/identity/monitoring-health/howto-integrate-activity-logs-with-azure-monitor-logs?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci) for an extended retention of 90-730 days, with query capabilities.\r\n- [Configure Log Analytics workspace retention](https://learn.microsoft.com/azure/azure-monitor/logs/data-retention-archive?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci) to meet organizational security and compliance requirements (minimum 90 days recommended).\r\n- [Enable table-level retention](https://learn.microsoft.com/azure/azure-monitor/logs/data-retention-archive?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci#configure-table-level-retention) for specific Global Secure Access tables to extend beyond workspace defaults.\r\n","TestTags":null,"TestMinimumLicense":["Entra_Premium_Private_Access","Entra_Premium_Internet_Access"],"SkippedReason":null,"TestAppliesTo":null,"TestImplementationCost":"Low","TestCategory":"Global Secure Access"},{"TestId":"61022","TestCategory":"AI Threat Detection","TestImpact":"Low","TestResult":"\r\n✅ Microsoft Defender for AI Services is enabled on every Azure subscription that hosts Azure OpenAI or Azure AI Services accounts.\n\n\r\n\r\n## [Defender for Cloud — Environment settings](https://portal.azure.com/#view/Microsoft_Azure_Security/SecurityMenuBlade/~/EnvironmentSettings)\r\n\r\n| Subscription | AI accounts in subscription | Defender for AI Services plan | Status |\r\n| :----------- | :-------------------------- | :---------------------------- | :----- |\r\n| [Cloud Security](https://portal.azure.com/#view/Microsoft_Azure_Security/PolicyMenuBlade/~/pricingTier/subscriptionId/ee301620-7f47-414b-97b7-9d84046f4d38) | 2 | Standard | ✅ Pass |\n| [Woodgrove - GTP Demos (External/Sponsored)](https://portal.azure.com/#view/Microsoft_Azure_Security/PolicyMenuBlade/~/pricingTier/subscriptionId/ab48f397-fc82-4634-aa52-62dd91b3ebaa) | 44 | Standard | ✅ Pass |\n| [Woodgrove - SANDBOXv2](https://portal.azure.com/#view/Microsoft_Azure_Security/PolicyMenuBlade/~/pricingTier/subscriptionId/855b095a-349d-42bf-b161-f93dc2438660) | 4 | Standard | ✅ Pass |\n\r\n","SkippedReason":null,"TestMinimumLicense":"Microsoft_Defender_for_AI_Services","TestAppliesTo":null,"TestTags":null,"TestSfiPillar":"Monitor and detect cyberthreats","TestImplementationCost":"Low","TestSkipped":"","TestPillar":"AI","TestTitle":"Microsoft Defender for AI Services is enabled on every Azure subscription that hosts Azure OpenAI or Azure AI Services accounts","TestStatus":"Passed","TestDescription":"Defender for Cloud's AI threat protection plan detects attacks against Azure OpenAI and Azure AI Services accounts and must be enabled at the subscription level. A subscription without the plan enabled emits no AI threat alerts, regardless of how Sentinel or Defender XDR is configured downstream. This check verifies the plan is active on every subscription that hosts Azure OpenAI or Azure AI Services accounts.\r\n\r\nWhen the plan is not enabled on every subscription, the SOC cannot determine whether a silent subscription is clean or simply unmonitored — there is no way to tell the difference. Threat actors who target an unmonitored AI endpoint can carry out attacks without generating a single alert. Without coverage on every subscription, the organization cannot confirm that any of its AI workloads are protected.\r\n\r\n**Source:** [Overview - AI threat protection](https://learn.microsoft.com/azure/defender-for-cloud/ai-threat-protection)\r\n\r\n**Remediation action**\r\n\r\n- [Enable threat protection for AI services (step-by-step)](https://learn.microsoft.com/azure/defender-for-cloud/ai-onboarding)\r\n- [Overview — AI threat protection](https://learn.microsoft.com/azure/defender-for-cloud/ai-threat-protection)\r\n- [Defender for AI Services alert reference](https://learn.microsoft.com/azure/defender-for-cloud/alerts-ai-workloads)\r\n- [Microsoft.Security/pricings REST reference (read / set the `AI` plan)](https://learn.microsoft.com/rest/api/defenderforcloud/pricings/get)\r\n\r\n","TestRisk":"High"},{"TestTitle":"Private DNS is configured for internal name resolution","TestSkipped":"","TestResult":"\r\n❌ No Quick Access application found with 'NetworkAccessQuickAccessApplication' tag.\r\n\r\n","TestSfiPillar":"Protect networks","TestStatus":"Failed","TestImpact":"Low","TestPillar":"Network","TestId":"25399","TestRisk":"Medium","TestDescription":"Without private DNS configuration, remote users can't resolve internal domain names through Microsoft Entra Private Access and must rely on public DNS servers. Threat actors can exploit this gap through DNS spoofing attacks that redirect users to malicious sites, enabling credential harvesting and data exfiltration. Organizations also lose visibility into DNS queries and can't enforce consistent security policies.\r\n\r\n**Remediation action**\r\n\r\n- [Configure private DNS for internal name resolution](https://learn.microsoft.com/entra/global-secure-access/how-to-configure-quick-access?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci#add-private-dns-suffixes)\r\n","TestTags":null,"TestMinimumLicense":["Entra_Premium_Private_Access"],"SkippedReason":null,"TestAppliesTo":null,"TestImplementationCost":"Medium","TestCategory":"Global Secure Access"},{"TestTitle":"Domain controller RDP access is protected by phishing-resistant authentication through Global Secure Access","TestSkipped":"NotApplicable","TestResult":"\r\nNo Private Access applications configured in this tenant.\r\n\r\n","TestSfiPillar":"Protect networks","TestStatus":"Skipped","TestImpact":"Low","TestPillar":"Network","TestId":25398,"TestRisk":"High","TestDescription":"When administrators use Microsoft Entra Private Access to reach domain controllers through Remote Desktop Protocol (RDP), they authenticate through Microsoft Entra ID before the Global Secure Access client tunnels their connection to the on-premises network. Domain controllers hold the cryptographic keys to the entire Active Directory forest. Compromising one domain controller offers a way to compromise every identity and resource in the organization.\r\n\r\nWithout phishing-resistant authentication:\r\n\r\n- Threat actors can intercept credentials during phishing campaigns or adversary-in-the-middle attacks.\r\n- Stolen session tokens can be replayed to establish RDP connections to domain controllers.\r\n- Once connected, threat actors can execute DCSync attacks to harvest all password hashes in the domain.\r\n- Attackers can create golden tickets for indefinite domain persistence.\r\n- Group Policy Objects can be modified to deploy ransomware or backdoors across all domain-joined machines.\r\n\r\nBy requiring phishing-resistant authentication, organizations ensure that even if users are successfully phished, threat actors can't replay credentials because these methods require cryptographic proof of possession.\r\n\r\n**Remediation action**\r\n\r\n- [Deploy phishing-resistant authentication methods to domain controller administrators](https://learn.microsoft.com/entra/identity/authentication/how-to-deploy-phishing-resistant-passwordless-authentication?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci).\r\n- [Require phishing-resistant authentication for administrators accessing domain controllers via RDP](https://learn.microsoft.com/entra/global-secure-access/how-to-configure-domain-controllers?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci).\r\n","TestTags":null,"TestMinimumLicense":["Entra_Premium_Private_Access"],"SkippedReason":"This test is not applicable to the current environment.","TestAppliesTo":null,"TestImplementationCost":"Medium","TestCategory":"Global Secure Access"},{"TestId":"25405","TestCategory":"Global Secure Access","TestImpact":"Medium","TestResult":"\r\n✅ At least one private network is configured in your tenant.\n\n\n## Private Networks\n\nFound 1 private network(s) configured for Intelligent Local Access.\n\n| Network name | Id |\r\n| :--- | :--- |\r\n| [Main Office](https://entra.microsoft.com/#view/Microsoft_Azure_Network_Access/PrivateNetworks.ReactView) | 014e7f3a-7090-4bc4-bde8-7dcbaa4556ef |\n\r\n\r\n\r\n","SkippedReason":null,"TestMinimumLicense":"P1","TestAppliesTo":null,"TestTags":null,"TestSfiPillar":"Protect networks","TestImplementationCost":"Medium","TestSkipped":"","TestPillar":"Network","TestTitle":"Intelligent Local Access is enabled and configured","TestStatus":"Passed","TestDescription":"Intelligent Local Access (ILA) routes Microsoft Entra Private Access traffic locally instead of through the cloud, improving performance while maintaining policy enforcement. Without ILA, users might disable the Global Secure Access client to improve performance and bypass Conditional Access policies. Configure private networks for your user sites to ensure local routing while preserving security controls.\r\n\r\n**Remediation action**\r\n\r\n- [Enable Intelligent Local Network](https://learn.microsoft.com/entra/global-secure-access/enable-intelligent-local-access?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci)\r\n","TestRisk":"Medium"},{"TestTitle":"Internal Rights Management licensing is enabled","TestSkipped":"NotConnectedToService","TestResult":"\r\nSkipped. This test requires connection to the service(s) \"ExchangeOnline\" currently disconnected. Please use _Connect-ZtAssessment_ to connect.\r\n\r\n","TestSfiPillar":"Protect tenants and production systems","TestStatus":"Skipped","TestImpact":"High","TestPillar":"AI","TestId":"35025","TestRisk":"High","TestDescription":"Internal RMS licensing allows users and services in the organization to license protected content for internal distribution and sharing. It's enabled automatically when Azure RMS is activated. If disabled, users can't collaborate on encrypted emails and files internally, and legal holds, eDiscovery, and data recovery operations can't access encrypted content.\r\n\r\n**Remediation action**\r\n\r\n- [Set up Message Encryption](https://learn.microsoft.com/purview/set-up-new-message-encryption-capabilities?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci)\r\n","TestTags":null,"TestMinimumLicense":["RMS_S_PREMIUM"],"SkippedReason":"This test requires connection to the service(s) \"ExchangeOnline\" currently disconnected. Please use _Connect-ZtAssessment_ to connect.","TestAppliesTo":null,"TestImplementationCost":"Low","TestCategory":"Rights Management Service (RMS)"},{"TestId":"26880","TestCategory":"Azure Network Security","TestImpact":"Low","TestResult":"\r\n✅ All Azure Front Door WAF policies attached to Azure Front Door are enabled, running in Prevention mode, and have request body inspection enabled.\n\n## [Azure Front Door WAF Policies](https://portal.azure.com/#view/Microsoft_Azure_HybridNetworking/FirewallManagerMenuBlade/~/wafMenuItem)\r\n\r\n| Policy name | Subscription name | Enabled state | WAF mode | Request body check | Status |\r\n| :---------- | :---------------- | :-----------: | :------: | :----------------: | :----: |\r\n| [AFDCopilotWAFPolicy](https://portal.azure.com/#resource/subscriptions/ab48f397-fc82-4634-aa52-62dd91b3ebaa/resourceGroups/Woodgrove-RG/providers/Microsoft.Network/frontdoorWebApplicationFirewallPolicies/AFDCopilotWAFPolicy) | [Woodgrove - GTP Demos (External/Sponsored)](https://portal.azure.com/#resource/subscriptions/ab48f397-fc82-4634-aa52-62dd91b3ebaa) | ✅ Enabled | ✅ Prevention | ✅ Enabled | ✅ Pass |\n\r\n\r\n","SkippedReason":null,"TestMinimumLicense":"Azure WAF","TestAppliesTo":null,"TestTags":null,"TestSfiPillar":"Protect networks","TestImplementationCost":"Low","TestSkipped":"","TestPillar":"Network","TestTitle":"Request Body Inspection is enabled in Azure Front Door WAF","TestStatus":"Passed","TestDescription":"Azure Front Door Web Application Firewall (WAF) provides centralized protection for web applications against common exploits and vulnerabilities. Request body inspection is a critical capability that allows the WAF to analyze the content of HTTP POST, PUT, and PATCH request bodies for malicious patterns. When request body inspection is disabled, threat actors can craft attacks that embed malicious SQL statements, scripts, or command injection payloads within form submissions, API calls, or file uploads that bypass all WAF rule evaluation. This creates a direct path for exploitation where threat actors gain initial access through unprotected application endpoints, execute arbitrary commands or queries against backend databases through SQL injection, exfiltrate sensitive data including credentials and customer information, establish persistence by modifying application data or injecting backdoors, and pivot to internal systems through compromised application server credentials. The WAF's managed rule sets, including OWASP Core Rule Set and Microsoft's threat intelligence-based rules, cannot evaluate threats they cannot see; disabling request body inspection renders these protections ineffective against body-based attack vectors that represent the majority of modern web application attacks.\r\n\r\n**Remediation action**\r\n\r\nOverview of WAF capabilities on Azure Front Door including request body inspection\r\n- [Azure Web Application Firewall on Azure Front Door](https://learn.microsoft.com/en-us/azure/web-application-firewall/afds/afds-overview)\r\n\r\nDetailed guidance on configuring WAF policy settings including request body inspection\r\n- [Policy settings for Web Application Firewall on Azure Front Door](https://learn.microsoft.com/en-us/azure/web-application-firewall/afds/waf-front-door-policy-settings)\r\n\r\nBest practices for tuning WAF including request body inspection limits\r\n- [Tuning Azure Web Application Firewall for Azure Front Door](https://learn.microsoft.com/en-us/azure/web-application-firewall/afds/waf-front-door-tuning)\r\n\r\n","TestRisk":"High"},{"TestTitle":"Azure Rights Management service is activated","TestSkipped":"NotConnectedToService","TestResult":"\r\nSkipped. This test requires connection to the service(s) \"ExchangeOnline\" currently disconnected. Please use _Connect-ZtAssessment_ to connect.\r\n\r\n","TestSfiPillar":"Protect tenants and production systems","TestStatus":"Skipped","TestImpact":"High","TestPillar":"AI","TestId":"35024","TestRisk":"High","TestDescription":"The Azure Rights Management service provides the foundational encryption and access control technology for Microsoft Purview Information Protection. It's used with sensitivity labels that apply encryption, protects emails with Microsoft Purview Message Encryption, and even used with the older protection technologies such as SharePoint IRM and mail flow rules that apply encryption. This service should be activated for the tenant before you configure any other information protection features.\r\n\r\n**Remediation action**\r\n\r\n- [Activate the Azure Rights Management service](https://learn.microsoft.com/purview/activate-rights-management-service?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci)\r\n","TestTags":null,"TestMinimumLicense":["RMS_S_PREMIUM"],"SkippedReason":"This test requires connection to the service(s) \"ExchangeOnline\" currently disconnected. Please use _Connect-ZtAssessment_ to connect.","TestAppliesTo":null,"TestImplementationCost":"Low","TestCategory":"Rights Management Service"},{"TestTitle":"Container labels are configured for collaborative workspaces","TestSkipped":"NotConnectedToService","TestResult":"\r\nSkipped. This test requires connection to the service(s) \"SecurityCompliance\" currently disconnected. Please use _Connect-ZtAssessment_ to connect.\r\n\r\n","TestSfiPillar":"Protect tenants and production systems","TestStatus":"Skipped","TestImpact":"High","TestPillar":"AI","TestId":"35012","TestRisk":"Medium","TestDescription":"Container labels extend sensitivity labels beyond individual items to entire collaboration workspaces like Microsoft Teams, Microsoft 365 Groups, SharePoint sites, Viva Engage communities, and Loop workspaces. These labels can control workspace-level settings such as external sharing, guest access, device restrictions, and privacy.\r\n\r\nWithout container labels, users might be able to create Teams with external guest access even when handling confidential information. This action creates data exfiltration risks where properly labeled documents exist in improperly secured workspaces. Container labels can help to ensure that workspace security matches the sensitivity of stored content, for example, prevent documents labeled as \"Highly Confidential\" from residing in Teams sites that permit external sharing.\r\n\r\n**Remediation action**\r\n\r\n- [Use sensitivity labels to protect collaborative workspaces (groups and sites)](https://learn.microsoft.com/purview/sensitivity-labels-teams-groups-sites?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci)\r\n","TestTags":null,"TestMinimumLicense":["RMS_S_PREMIUM2"],"SkippedReason":"This test requires connection to the service(s) \"SecurityCompliance\" currently disconnected. Please use _Connect-ZtAssessment_ to connect.","TestAppliesTo":null,"TestImplementationCost":"Medium","TestCategory":"Sensitivity Labels Configuration"},{"TestTitle":"Risk-based Conditional Access blocks risky agent identities","TestSkipped":"","TestResult":"\r\n✅ The tenant has at least one enabled risk-based Conditional Access policy that blocks high-risk agent identities.\n\n\r\n\r\n## [Risk-based Conditional Access policies for agent principals](https://entra.microsoft.com/#view/Microsoft_AAD_ConditionalAccess/ConditionalAccessBlade/~/Policies)\r\n\r\n| Policy | State | Agent risk level | Grant controls | Status |\r\n| :----- | :---- | :--------------- | :------------- | :----- |\r\n| [Allow only approved agents to access resources](https://entra.microsoft.com/#view/Microsoft_AAD_ConditionalAccess/PolicyBlade/policyId/8ba6907e-3f9d-4172-81a7-a13d1bd28355) | 🟡 Report-only | ❌ Not configured | ✅ block | ❌ Fail |\n| [AWSBedrockPolicy](https://entra.microsoft.com/#view/Microsoft_AAD_ConditionalAccess/PolicyBlade/policyId/9b4077ef-8320-40fb-87b5-42fa08c63d1d) | 🟡 Report-only | ❌ Not configured | ✅ block | ❌ Fail |\n| [Block Agent ID Blueprint_AgentResource](https://entra.microsoft.com/#view/Microsoft_AAD_ConditionalAccess/PolicyBlade/policyId/62c6b998-633c-411b-8e6b-1f33200aa5ae) | 🟡 Report-only | ❌ Not configured | ✅ block | ❌ Fail |\n| [Block AgentID BluePrint_ Allresources](https://entra.microsoft.com/#view/Microsoft_AAD_ConditionalAccess/PolicyBlade/policyId/6dfb1cd7-e656-481a-a9c6-7bff54c71193) | 🟡 Report-only | ❌ Not configured | ✅ block | ❌ Fail |\n| [Block all high risk agents from accessing all resources](https://entra.microsoft.com/#view/Microsoft_AAD_ConditionalAccess/PolicyBlade/policyId/5a430e91-92ef-4cea-af93-27c247c2be1f) | 🟢 Enabled | ✅ high | ✅ block | ✅ Pass |\n\r\n\r\n","TestSfiPillar":"Protect identities and secrets","TestStatus":"Passed","TestImpact":"Low","TestPillar":"AI","TestId":"61012","TestRisk":"High","TestDescription":"When an organisation enables AI agents in Microsoft Entra, two distinct non-human principal types start acquiring access tokens against organisational resources without any of the device, location, or interactive-MFA signals that classic Conditional Access uses to make trust decisions for human sign-ins: **agent identities** (instantiated agents, modelled as service principals, that act with their own identity or on a user's behalf). Microsoft Entra ID Protection for agents continuously evaluates each agent's behaviour and emits a risk level — high, medium, or low — driven by signals such as unfamiliar resource access (the agent reaches outside its established pattern), sign-in spikes (token replay or automation abuse), failed-access probing (an attacker enumerating resources with the agent's credentials), sign-ins by risky users during delegated authentication, and admin-confirmed compromise. Risk detection alone does not stop anything: without a Conditional Access policy that consumes the risk level and blocks token issuance, the platform records that an agent is high risk while continuing to mint the very tokens the adversary needs to keep moving — the report says \"compromised\", the resource still says \"yes\". As of May 2026, only agent identities support risk evaluation in conditional access. Agent ID Users are not covered by risk-based conditional policies.\r\n\r\n**Remediation action**\r\n\r\n- ID Protection for agents (concept, signals, and risk levels): \r\n- Conditional Access for Agent ID (Preview) — covers the three agent access patterns and the single \"All agent users\" assignment for agent users: \r\n- Plan a Conditional Access deployment (recommended: deploy in report-only mode and validate via sign-in logs filtered by `agentType` before switching to enforcement): \r\n- Microsoft Entra ID P2 feature comparison (license precondition for ID Protection signal generation): \r\n","TestTags":null,"TestMinimumLicense":["AAD_PREMIUM_P2 AND AGENT_365"],"SkippedReason":null,"TestAppliesTo":null,"TestImplementationCost":"Low","TestCategory":"AI Authentication & Access"},{"TestTitle":"Agents deployed to Microsoft 365 Copilot are discoverable in the Agent Registry","TestSkipped":"","TestResult":"\r\n✅ Agents deployed to Microsoft 365 Copilot are visible in the Agent Registry.\n\n\r\n## [Agents visible in the Microsoft 365 Agent Registry](https://admin.cloud.microsoft/?#/agents/all)\r\n\r\n| Display name | Element types | Available to | Deployed to |\r\n| :----------- | :------------ | :----------- | :---------- |\r\n| Lexis® Create DMS for Copilot | ComposeExtensions | allowedForAll | acquiredForNone |\n| Jira Cloud | Bots, ComposeExtensions, ConfigurableTabs, Connectors, StaticTabs | allowedForAll | acquiredForNone |\n| Writing Coach | DeclarativeCopilots | allowedForAll | acquiredForNone |\n| Viva Goals | Activities, ComposeExtensions, StaticTabs | allowedForAll | acquiredForNone |\n| Lucidchart for Microsoft Teams | Bots, ComposeExtensions, ConfigurableTabs, StaticTabs | allowedForAll | acquiredForNone |\n| 1Page | Bots, ComposeExtensions, ConfigurableTabs, StaticTabs | allowedForAll | acquiredForNone |\n| iPlanner Pro for Teams | Bots, ComposeExtensions, StaticTabs | allowedForAll | acquiredForNone |\n| Workway | ComposeExtensions, ConfigurableTabs, DeclarativeCopilots, StaticTabs | allowedForAll | acquiredForNone |\n| Seismic | Bots, ComposeExtensions | allowedForAll | acquiredForNone |\n| Dropbox | Bots, ComposeExtensions, ConfigurableTabs, StaticTabs | allowedForAll | acquiredForNone |\n\n\n_**Note**: This table is truncated and showing the first 10 of 965 agents._\n\r\n","TestSfiPillar":"Protect tenants and production systems","TestStatus":"Passed","TestImpact":"Low","TestPillar":"AI","TestId":"61005","TestRisk":"High","TestDescription":"The Microsoft 365 Agent Registry is the tenant-scoped catalogue that lists every declarative agent, connected agent, and custom Copilot extension that has been published to users in the tenant. Its role is to provide the central answer to two questions that security teams must be able to answer at any moment: \"which agents are operating inside our Microsoft 365 environment\" and \"who are they available to\". Without a populated Agent Registry view, those questions cannot be answered consistently — agent deployments proliferate through individual authoring and sideloading paths, each with its own audit signal, and no single surface enumerates them. Threat actors exploit this inventory gap by publishing agents that impersonate legitimate productivity tools, by distributing agents to broad audiences when only a narrow scope was approved, and by relying on the visibility asymmetry to keep malicious or retired agents running long after they should have been removed. Confirming that the Agent Registry returns results — and, in follow-up specs, that those results match the organisation's approved inventory — is the baseline control that makes every downstream agent-governance check possible.\r\n\r\n**Remediation action**\r\n\r\n1. [Manage agents for Microsoft 365 Copilot](https://learn.microsoft.com/microsoft-365-copilot/extensibility/agent-registry)\r\n2. [Publish and deploy an agent](https://learn.microsoft.com/microsoft-365-copilot/extensibility/build-agent)\r\n3. [Governance of agents in Microsoft 365 Copilot](https://learn.microsoft.com/microsoft-365-copilot/extensibility/governance)\r\n\r\n","TestTags":null,"TestMinimumLicense":["Microsoft_365_Copilot","AGENT_365"],"SkippedReason":null,"TestAppliesTo":null,"TestImplementationCost":"Low","TestCategory":"AI Inventory & Lifecycle"},{"TestId":"27017","TestCategory":"Azure Network Security","TestImpact":"Low","TestResult":"\r\n❌ One or more Application Gateway WAF policies attached to Application Gateways are disabled, running in Detection mode, have no JavaScript challenge rules configured, or have JavaScript challenge rules configured but all set to Disabled state, leaving applications without browser verification against automated bots.\n\n\r\n## [Application Gateway WAF policies](https://portal.azure.com/#browse/Microsoft.Network%2FapplicationGatewayWebApplicationFirewallPolicies)\r\n\r\n| Policy name | Subscription name | Policy state | Mode | JS Challenge rules count | Rule state | JavaScript Challenge expiration (mins) | Status |\r\n| :---------- | :---------------- | :----------- | :--- | :----------------------- | :--------- | :------------------------------------- | :----- |\r\n| [WAFAppGWcopilotPolicy](https://portal.azure.com/#resource/subscriptions/ab48f397-fc82-4634-aa52-62dd91b3ebaa/resourceGroups/Woodgrove-RG/providers/Microsoft.Network/applicationGatewayWebApplicationFirewallPolicies/WAFAppGWcopilotPolicy) | [Woodgrove - GTP Demos (External/Sponsored)](https://portal.azure.com/#resource/subscriptions/ab48f397-fc82-4634-aa52-62dd91b3ebaa) | ✅ Enabled | ✅ Prevention | ❌ 0 | N/A | N/A | ❌ |\n\r\n\r\n","SkippedReason":null,"TestMinimumLicense":"Azure WAF","TestAppliesTo":null,"TestTags":null,"TestSfiPillar":"Protect networks","TestImplementationCost":"Low","TestSkipped":"","TestPillar":"Network","TestTitle":"JavaScript Challenge is Enabled in Application Gateway WAF","TestStatus":"Failed","TestDescription":"Azure Application Gateway Web Application Firewall (WAF) supports JavaScript challenge as a defense mechanism against automated bots and headless browsers. JavaScript challenge works by serving a small JavaScript snippet that must be executed by the client browser to prove that the request originates from a real browser capable of running JavaScript, rather than a simple HTTP client or bot.\r\n\r\nWhen a request triggers a JavaScript challenge, the WAF responds with a challenge page containing JavaScript code that the browser must execute to obtain a valid challenge cookie. If the client successfully executes the JavaScript and returns with a valid cookie, subsequent requests proceed normally until the cookie expires. Bots and automated tools that cannot execute JavaScript fail this challenge and are blocked from accessing protected resources. This mechanism is particularly effective against credential stuffing bots, web scrapers, and distributed denial of service bots that use simple HTTP libraries without JavaScript engines.\r\n\r\nThe `jsChallengeCookieExpirationInMins` setting controls how long the challenge cookie remains valid before the client must complete another challenge. JavaScript challenge provides a middle ground between allowing all traffic and blocking suspected bots outright—it verifies browser capability without requiring user interaction like CAPTCHA. By configuring custom rules with JavaScript challenge action, organizations can protect sensitive endpoints like login pages, API endpoints, and high-value resources from automated abuse while maintaining a seamless experience for legitimate users.\r\n\r\n\r\n**Remediation action**\r\n\r\n- [What is Azure Web Application Firewall on Azure Application Gateway?](https://learn.microsoft.com/en-us/azure/web-application-firewall/ag/ag-overview) - Overview of WAF capabilities on Application Gateway including custom rules and actions\r\n- [Create and use Web Application Firewall v2 custom rules on Application Gateway](https://learn.microsoft.com/en-us/azure/web-application-firewall/ag/create-custom-waf-rules) - Step-by-step guidance on creating custom rules with different actions including JavaScript challenge\r\n- [Web Application Firewall custom rules](https://learn.microsoft.com/en-us/azure/web-application-firewall/ag/custom-waf-rules-overview) - Detailed documentation of custom rule types and available actions\r\n- [Bot protection overview for Application Gateway WAF](https://learn.microsoft.com/en-us/azure/web-application-firewall/ag/bot-protection-overview) - Overview of bot protection capabilities including challenge actions\r\n\r\n\r\n","TestRisk":"Medium"},{"TestId":"26888","TestCategory":"Azure Network Security","TestImpact":"Low","TestResult":"\r\n✅ Diagnostic logging is enabled for Application Gateway WAF with active log collection configured.\n\n\n## [Application Gateway WAF diagnostic logging status](https://portal.azure.com/#browse/Microsoft.Network%2FapplicationGateways)\n\n| Subscription | Gateway name | Location | SKU tier | Diagnostic settings count | Destination configured | Enabled log categories | Status |\r\n| :--- | :--- | :--- | :--- | :--- | :--- | :--- | :--- |\r\n| [Woodgrove - GTP Demos (External/Sponsored)](https://portal.azure.com/#resource/subscriptions/ab48f397-fc82-4634-aa52-62dd91b3ebaa/overview) | [AppGWcopilot](https://portal.azure.com/#resource/subscriptions/ab48f397-fc82-4634-aa52-62dd91b3ebaa/resourceGroups/Woodgrove-RG/providers/Microsoft.Network/applicationGateways/AppGWcopilot/diagnostics) | westus2 | WAF_v2 | 1 | Yes | allLogs | ✅ Pass |\n\r\n**Summary:**\n\n- Total Application Gateways with WAF evaluated: 1\n- Gateways with diagnostic logging enabled: 1\n- Gateways without diagnostic logging: 0\n\r\n","SkippedReason":null,"TestMinimumLicense":"Azure_Application_Gateway_WAF","TestAppliesTo":null,"TestTags":null,"TestSfiPillar":"Monitor and detect cyberthreats","TestImplementationCost":"Low","TestSkipped":"","TestPillar":"Network","TestTitle":"Diagnostic logging is enabled in Application Gateway WAF","TestStatus":"Passed","TestDescription":"Azure Application Gateway Web Application Firewall (WAF) protects web applications from common exploits and vulnerabilities such as SQL injection, cross-site scripting, and other OWASP Top 10 threats. When diagnostic logging is not enabled, security operations teams lose visibility into blocked attacks, rule matches, access patterns, and firewall events. A threat actor attempting to exploit web application vulnerabilities would go undetected because no WAF logs are being captured or analyzed. The absence of logging prevents correlation of WAF events with other security telemetry, eliminating the ability to construct attack timelines during incident investigations. Furthermore, compliance frameworks such as PCI-DSS, HIPAA, and SOC 2 require organizations to maintain audit logs of web application security events, and the lack of WAF diagnostic logging creates audit failures. Azure Application Gateway WAF provides multiple log categories including Application Gateway Access Logs, Performance Logs, and Firewall Logs, all of which must be routed to a destination such as Log Analytics, Storage Account, or Event Hub to enable security monitoring and forensic analysis.\r\n\r\n**Remediation action**\r\n\r\nCreate a Log Analytics workspace for storing Application Gateway WAF logs\r\n- [Create a Log Analytics workspace](https://learn.microsoft.com/en-us/azure/azure-monitor/logs/quick-create-workspace)\r\n\r\nConfigure diagnostic settings for Application Gateway to enable log collection\r\n- [Create diagnostic settings in Azure Monitor](https://learn.microsoft.com/en-us/azure/azure-monitor/essentials/create-diagnostic-settings)\r\n\r\nEnable WAF logging to capture firewall events and rule matches\r\n- [Application Gateway WAF logs and metrics](https://learn.microsoft.com/en-us/azure/web-application-firewall/ag/application-gateway-waf-metrics)\r\n\r\nMonitor Application Gateway using diagnostic logs and metrics\r\n- [Monitor Azure Application Gateway](https://learn.microsoft.com/en-us/azure/application-gateway/application-gateway-diagnostics)\r\n\r\nUse Azure Monitor Workbooks for visualizing and analyzing WAF logs\r\n- [Azure Monitor Workbooks](https://learn.microsoft.com/en-us/azure/azure-monitor/visualize/workbooks-overview)\r\n\r\n","TestRisk":"High"},{"TestTitle":"Network access activity is visible to security operations for threat detection and response","TestSkipped":"","TestResult":"\r\n✅ All required Global Secure Access log categories are integrated with a Log Analytics workspace for security monitoring and threat detection.\n\n\n## [Diagnostic settings configuration](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ActiveDirectoryMenuBlade/~/DiagnosticSettings)\n\n| Log category | Woodgrove_Diagnostic_Settings |\n| :--- | :---: |\n| NetworkAccessTrafficLogs | ✅ Enabled |\n| EnrichedOffice365AuditLogs | ✅ Enabled |\n| RemoteNetworkHealthLogs | ✅ Enabled |\n| NetworkAccessAlerts | ✅ Enabled |\n| NetworkAccessConnectionEvents | ✅ Enabled |\n| NetworkAccessGenerativeAIInsights | ✅ Enabled |\n| Workspace | ✅ [woodgrove-loganalyiticsworkspace](https://portal.azure.com/#resource/subscriptions/ab48f397-fc82-4634-aa52-62dd91b3ebaa/resourcegroups/woodgrove-rg/providers/microsoft.operationalinsights/workspaces/woodgrove-loganalyiticsworkspace/overview) |\n\n**Summary:**\n\n- Total diagnostic settings: 1\n- Diagnostic settings passing criteria (all six categories + workspace): 1\n\r\n\r\n","TestSfiPillar":"Monitor and detect cyberthreats","TestStatus":"Passed","TestImpact":"Low","TestPillar":"Network","TestId":"25419","TestRisk":"Medium","TestDescription":"Without Global Secure Access logs integrated into a Microsoft Sentinel workspace, security operations teams lack centralized visibility into network traffic patterns, connection attempts, and access anomalies across Private Access, Internet Access, and Microsoft 365 traffic forwarding. Threat actors who compromise user credentials or devices can use these network access paths to perform reconnaissance, move laterally, or exfiltrate data without detection.\r\n\r\nWithout this integration:\r\n\r\n- Security teams can't correlate network-layer activities with identity-based signals in Microsoft Entra ID or endpoint detections.\r\n- Security information and event management (SIEM) systems can't apply behavioral analytics, threat intelligence correlation, or automated response playbooks to Global Secure Access traffic.\r\n- Security teams can't investigate historical network access patterns or hunt for threats across network and identity signals.\r\n\r\n**Remediation action**\r\n\r\n- [Configure Microsoft Entra diagnostic settings](https://learn.microsoft.com/entra/global-secure-access/how-to-sentinel-integration?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci) to send Global Secure Access logs to a Log Analytics workspace for Microsoft Sentinel integration.\r\n- [Enable all required Global Secure Access identity log categories](https://learn.microsoft.com/entra/identity/monitoring-health/concept-diagnostic-settings-logs-options?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci), including `NetworkAccessTrafficLogs`, `EnrichedOffice365AuditLogs`, `RemoteNetworkHealthLogs`, `NetworkAccessAlerts`, `NetworkAccessConnectionEvents`, and `NetworkAccessGenerativeAIInsights` in diagnostic settings.\r\n- [Integrate Microsoft Entra activity logs with Azure Monitor](https://learn.microsoft.com/entra/identity/monitoring-health/howto-integrate-activity-logs-with-azure-monitor-logs?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci) for centralized log collection.\r\n- [Configure a Microsoft Sentinel workspace](https://learn.microsoft.com/azure/sentinel/quickstart-onboard?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci) and install the Global Secure Access solution from the content hub.\r\n","TestTags":null,"TestMinimumLicense":["Entra_Premium_Private_Access","Entra_Premium_Internet_Access"],"SkippedReason":null,"TestAppliesTo":null,"TestImplementationCost":"Low","TestCategory":"Global Secure Access"},{"TestTitle":"Custom sensitive information types are configured","TestSkipped":"NotConnectedToService","TestResult":"\r\nSkipped. This test requires connection to the service(s) \"SecurityCompliance\" currently disconnected. Please use _Connect-ZtAssessment_ to connect.\r\n\r\n","TestSfiPillar":"Protect tenants and production systems","TestStatus":"Skipped","TestImpact":"Medium","TestPillar":"AI","TestId":"35033","TestRisk":"High","TestDescription":"Custom sensitive information types (SITs) extend Microsoft Purview's ability to detect sensitive information beyond the built-in SITs to cover organization-specific data patterns, proprietary identifiers, internal classification schemes, specialized industry codes, or other formats that built-in SITs don't look for. Use them to create tailored detection rules that align with your organization's unique data protection needs, ensuring that more sensitive information is accurately identified and protected.\r\n\r\n**Remediation action**\r\n\r\n- [Create custom sensitive information types](https://learn.microsoft.com/purview/create-a-custom-sensitive-information-type?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci)\r\n","TestTags":null,"TestMinimumLicense":["EXCHANGE_S_ENTERPRISE"],"SkippedReason":"This test requires connection to the service(s) \"SecurityCompliance\" currently disconnected. Please use _Connect-ZtAssessment_ to connect.","TestAppliesTo":null,"TestImplementationCost":"High","TestCategory":"Advanced Classification"},{"TestTitle":"AI Gateway protects enterprise generative AI applications from prompt injection attacks","TestSkipped":"","TestResult":"\r\n❌ Prompt Shield is not properly configured - no prompt policies exist.\n\n[View Prompt Shield Configuration](https://entra.microsoft.com/#view/Microsoft_Azure_Network_Access/PromptPolicy.ReactView)\n\r\n\r\n","TestSfiPillar":"Protect networks","TestStatus":"Failed","TestImpact":"Low","TestPillar":["Network","AI"],"TestId":"25415","TestRisk":"High","TestDescription":"If organizations don't use Prompt Shield protection, threat actors can exploit prompt injection vulnerabilities to compromise AI-powered workflows. Malicious users can craft adversarial inputs that manipulate large language models into ignoring system instructions, disclosing confidential data, or executing unintended actions like generating phishing content.\r\n\r\nWithout network-level prompt filtering:\r\n\r\n- Direct prompt injection attacks can bypass application-layer safety mechanisms through sophisticated jailbreak techniques.\r\n- Indirect prompt injection occurs when threat actors embed malicious instructions in external content that the AI processes.\r\n- Each AI application must independently implement protection, creating inconsistent security postures and inadequate safeguards against new or custom AI deployments.\r\n\r\n**Remediation action**\r\n\r\n- [Enable the Internet Access traffic forwarding profile to route internet traffic through Global Secure Access](https://learn.microsoft.com/entra/global-secure-access/how-to-manage-internet-access-profile?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci).\r\n- [Configure TLS inspection settings and deploy the CA certificate to allow inspection of encrypted AI application traffic](https://learn.microsoft.com/entra/global-secure-access/how-to-transport-layer-security-settings?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci).\r\n- Follow the steps in [Protect enterprise generative AI applications with Prompt Shield](https://learn.microsoft.com/entra/global-secure-access/how-to-ai-prompt-shield?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci) to:\r\n - Create prompt policies to scan and block malicious prompts targeting generative AI applications.\r\n - Link prompt policies to security profiles to organize them for Conditional Access targeting.\r\n - Create Conditional Access policies to apply security profiles with prompt policies to users accessing internet resources.\r\n- [Install the Global Secure Access client on user devices to enable traffic acquisition](https://learn.microsoft.com/entra/global-secure-access/how-to-install-windows-client?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci).\r\n","TestTags":null,"TestMinimumLicense":["Entra_Premium_Internet_Access"],"SkippedReason":null,"TestAppliesTo":null,"TestImplementationCost":"Medium","TestCategory":"Global Secure Access"},{"TestTitle":"PDF labeling is enabled in SharePoint","TestSkipped":"NotConnectedToService","TestResult":"\r\nSkipped. This test requires connection to the service(s) \"SharePointOnline\" currently disconnected. Please use _Connect-ZtAssessment_ to connect.\r\n\r\n","TestSfiPillar":"Protect tenants and production systems","TestStatus":"Skipped","TestImpact":"Low","TestPillar":"AI","TestId":"35006","TestRisk":"Medium","TestDescription":"When PDF labeling is disabled (the default) in SharePoint, PDF files can't be labeled or display existing labels, which creates a protection gap. Unlike Office files, PDFs can circulate externally without visible classification markers, making it impossible for recipients to determine the handling requirements or for data loss prevention (DLP) policies to detect sensitive content.\r\n\r\nEnabling PDF labeling for SharePoint and OneDrive extends sensitivity label support to PDFs, allowing users to apply labels by using Office for the web and SharePoint, and supports other labeling methods such as auto-labeling policies to classify PDF content automatically.\r\n\r\n**Remediation action**\r\n\r\n- [Enable sensitivity labels for PDF files in SharePoint and OneDrive](https://learn.microsoft.com/purview/sensitivity-labels-sharepoint-onedrive-files?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci#adding-support-for-pdf)\r\n","TestTags":null,"TestMinimumLicense":["RMS_S_PREMIUM"],"SkippedReason":"This test requires connection to the service(s) \"SharePointOnline\" currently disconnected. Please use _Connect-ZtAssessment_ to connect.","TestAppliesTo":null,"TestImplementationCost":"Low","TestCategory":"SharePoint Online"},{"TestTitle":"Sensitivity labels with encryption are configured","TestSkipped":"NotConnectedToService","TestResult":"\r\nSkipped. This test requires connection to the service(s) \"SecurityCompliance\" currently disconnected. Please use _Connect-ZtAssessment_ to connect.\r\n\r\n","TestSfiPillar":"Protect tenants and production systems","TestStatus":"Skipped","TestImpact":"High","TestPillar":"AI","TestId":"35013","TestRisk":"High","TestDescription":"Without encryption, sensitivity labels denote an item's sensitivity level without preventing unauthorized access, unless supplemented by another protection mechanism. Sensitivity labels that are configured to apply encryption from the Azure Rights Management service enforce access control and usage rights. This protection persists regardless of where the content is stored or shared. For example, users can still share a document labeled as \"Confidential\", but if that label applies encryption, unauthorized people won't be able to open it.\r\n\r\nOrganizations using labels without encryption gain visibility of the sensitivity level but the labels themselves lack technical enforcement. Labels that apply encryption ensure only authorized users can decrypt content and use it with any restrictions that are specified for that user. For example, read-only, or prevent copying. This protection helps prevent data exfiltration even if files are leaked or improperly shared. At least one sensitivity label should be configured to apply encryption for high-value data that requires protection beyond identifying the sensitivity level.\r\n\r\n**Remediation action**\r\n\r\n- [Restrict access to content by using encryption in sensitivity labels](https://learn.microsoft.com/purview/encryption-sensitivity-labels?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci)\r\n","TestTags":null,"TestMinimumLicense":["RMS_S_PREMIUM"],"SkippedReason":"This test requires connection to the service(s) \"SecurityCompliance\" currently disconnected. Please use _Connect-ZtAssessment_ to connect.","TestAppliesTo":null,"TestImplementationCost":"Medium","TestCategory":"Sensitivity Labels Configuration"},{"TestTitle":"Named entity sensitive information types are used in auto-labeling and data loss prevention policies","TestSkipped":"NotConnectedToService","TestResult":"\r\nSkipped. This test requires connection to the service(s) \"SecurityCompliance\" currently disconnected. Please use _Connect-ZtAssessment_ to connect.\r\n\r\n","TestSfiPillar":"Protect tenants and production systems","TestStatus":"Skipped","TestImpact":"Medium","TestPillar":"AI","TestId":"35035","TestRisk":"High","TestDescription":"Named entity sensitive information types (SITs) are prebuilt Microsoft classifiers that detect common sensitive entities like people's names, physical addresses, and medical terminology. They extend data protection beyond pattern matching into context aware classification, and can be used in auto-labeling policies and DLP rules without any custom development.\r\n\r\n**Remediation action**\r\n\r\n- [Learn about named entities](https://learn.microsoft.com/purview/sit-named-entities-learn?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci)\r\n- [Use named entities in your data loss prevention policies](https://learn.microsoft.com/purview/sit-named-entities-use?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci)\r\n","TestTags":null,"TestMinimumLicense":["EXCHANGE_S_ENTERPRISE"],"SkippedReason":"This test requires connection to the service(s) \"SecurityCompliance\" currently disconnected. Please use _Connect-ZtAssessment_ to connect.","TestAppliesTo":null,"TestImplementationCost":"Low","TestCategory":"Advanced Classification"},{"TestTitle":"Double Key Encryption labels are configured","TestSkipped":"NotConnectedToService","TestResult":"\r\nSkipped. This test requires connection to the service(s) \"SecurityCompliance\" currently disconnected. Please use _Connect-ZtAssessment_ to connect.\r\n\r\n","TestSfiPillar":"Protect tenants and production systems","TestStatus":"Skipped","TestImpact":"High","TestPillar":"AI","TestId":"35010","TestRisk":"Low","TestDescription":"Double Key Encryption (DKE) provides an extra layer of protection for highly sensitive data by requiring two keys to decrypt content: one managed by Microsoft and one by the customer. This \"hold your own key\" approach ensures Microsoft can't decrypt content even with legal compulsion, meeting stringent regulatory requirements for data sovereignty.\r\n\r\nHowever, DKE introduces significant operational complexity including dedicated key service infrastructure, reduced feature compatibility, and increased support burden. Organizations should maintain 1-3 labels reserved for truly mission-critical or heavily regulated data, with documented business justification for each DKE label. Use standard encryption for general business content. Excessive DKE labels (4 or more) create management overhead, user confusion, and reduce collaboration. DKE should never be broadly deployed, as key service unavailability prevents access to business-critical documents.\r\n\r\n**Remediation action**\r\n\r\n- [Double Key Encryption](https://learn.microsoft.com/purview/double-key-encryption?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci)\r\n- [Set up Double Key Encryption](https://learn.microsoft.com/purview/double-key-encryption-setup?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci)\r\n","TestTags":null,"TestMinimumLicense":["RMS_S_PREMIUM2"],"SkippedReason":"This test requires connection to the service(s) \"SecurityCompliance\" currently disconnected. Please use _Connect-ZtAssessment_ to connect.","TestAppliesTo":null,"TestImplementationCost":"Medium","TestCategory":"Encryption"},{"TestTitle":"Mandatory labeling is enabled in sensitivity label policies","TestSkipped":"NotConnectedToService","TestResult":"\r\nSkipped. This test requires connection to the service(s) \"SecurityCompliance\" currently disconnected. Please use _Connect-ZtAssessment_ to connect.\r\n\r\n","TestSfiPillar":"Protect tenants and production systems","TestStatus":"Skipped","TestImpact":"High","TestPillar":"AI","TestId":"35016","TestRisk":"High","TestDescription":"The policy setting **Require users to apply a label** ensures a sensitivity label must be applied before users can save files and send emails or meeting invites, create new groups or sites, and use Power BI content. This setting also prevents users from completely removing a sensitivity label. Unlabeled items create security and compliance risks. For example, threat actors can exfiltrate sensitive data that could be prevented by protection solutions that trigger based on label detection.\r\n\r\n**Remediation action**\r\n\r\n- [Publish sensitivity labels by creating a label policy](https://learn.microsoft.com/purview/create-sensitivity-labels?tabs=modern-label-scheme&wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci#publish-sensitivity-labels-by-creating-a-label-policy)\r\n- [Require users to apply a label to their email and documents](https://learn.microsoft.com/purview/sensitivity-labels-office-apps?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci#require-users-to-apply-a-label-to-their-email-and-documents)\r\n","TestTags":null,"TestMinimumLicense":["RMS_S_PREMIUM"],"SkippedReason":"This test requires connection to the service(s) \"SecurityCompliance\" currently disconnected. Please use _Connect-ZtAssessment_ to connect.","TestAppliesTo":null,"TestImplementationCost":"Medium","TestCategory":"Information Protection"},{"TestTitle":"Global and GSA admin privileges are tightly limited to prevent tenant-wide compromise","TestSkipped":"","TestResult":"\r\n❌ GA/GSA roles include groups, guests, or service principals requiring immediate review.\n\n\n## [Global Administrator assignments](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/RolesManagementMenuBlade/~/AllRoles)\n\n**Role Definition ID**: 62e90394-69f5-4237-9190-012177145e10 \n**Total Assignment Count**: 20 \n**Valid Assignment Count**: 9 \n**Issue Count**: 11 \n\n### ❌ Non-compliant assignments\n\n| Name | Principal name | Type | User type | Account enabled | Status |\n| :----------- | :-- | :--- | :-------- | :-------------- | :----- |\n| Sec-Removal-Guest | | servicePrincipal | | | Fail |\n| DesiredStateMonitor | | servicePrincipal | | | Fail |\n| wg-remove-8-hours | | servicePrincipal | | | Fail |\n| wg-remove-8-hour-la | | servicePrincipal | | | Fail |\n| wg-disable-acct | | servicePrincipal | | | Fail |\n\n*Showing first 5 of 10 records. [View all assignments in Entra Portal](https://entra.microsoft.com/#view/Microsoft_Azure_PIMCommon/UserRolesViewModelMenuBlade/~/members/roleObjectId/62e90394-69f5-4237-9190-012177145e10/roleId/62e90394-69f5-4237-9190-012177145e10/roleTemplateId/62e90394-69f5-4237-9190-012177145e10/roleName/Global%20Administrator/isRoleCustom~/false/resourceScopeId/%2F/resourceId/aaaabbbb-0000-cccc-1111-dddd2222eeee)*\n\n### ⚠️ Disabled accounts with privileged roles\n\n| Name | Principal name | Type | User type | Account enabled | Status |\n| :----------- | :-- | :--- | :-------- | :-------------- | :----- |\n| Suresh Basiang (OPS) | demouser12@contoso.com | user | Member | False | Investigate |\n\n### ✅ Valid Member User assignments\n\n| Name | Principal name | Type | User type | Account enabled | Status |\n| :----------- | :-- | :--- | :-------- | :-------------- | :----- |\n| Morgan Wilson (ASH OPS) | demouser13@contoso.com | user | Member | True | Valid |\n| Fahmi Ibrahim | demouser14@contoso.com | user | Member | True | Valid |\n| John Salk | demouser15@contoso.com | user | Member | True | Valid |\n| Irma Janu (OPS) | demouser16@contoso.com | user | Member | True | Valid |\n| Ismat Bekarevich (OPS) | demouser17@contoso.com | user | Member | True | Valid |\n\n*Showing first 5 of 9 records. [View all assignments in Entra Portal](https://entra.microsoft.com/#view/Microsoft_Azure_PIMCommon/UserRolesViewModelMenuBlade/~/members/roleObjectId/62e90394-69f5-4237-9190-012177145e10/roleId/62e90394-69f5-4237-9190-012177145e10/roleTemplateId/62e90394-69f5-4237-9190-012177145e10/roleName/Global%20Administrator/isRoleCustom~/false/resourceScopeId/%2F/resourceId/aaaabbbb-0000-cccc-1111-dddd2222eeee)*\n\n\n## [Global Secure Access Administrator assignments](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/RolesManagementMenuBlade/~/AllRoles)\n\n**Role Definition ID**: ac434307-12b9-4fa1-a708-88bf58caabc1 \n**Total Assignment Count**: 12 \n**Valid Assignment Count**: 10 \n**Issue Count**: 2 \n\n### ❌ Non-compliant assignments\n\n| Name | Principal name | Type | User type | Account enabled | Status |\n| :----------- | :-- | :--- | :-------- | :-------------- | :----- |\n| wg_role_Entra_Suite_admin | | group | | | Fail |\n| wg_role_GSA_admin | | group | | | Fail |\n\n### ✅ Valid Member User assignments\n\n| Name | Principal name | Type | User type | Account enabled | Status |\n| :----------- | :-- | :--- | :-------- | :-------------- | :----- |\n| Krishnaprabha Nachini | demouser18@contoso.com | user | Member | True | Valid |\n| Lenka Stastna | demouser19@contoso.com | user | Member | True | Valid |\n| Martina Benarjee | demouser20@contoso.com | user | Member | True | Valid |\n| Mihail Jordanovski | demouser21@contoso.com | user | Member | True | Valid |\n| Siti Acharya | demouser22@contoso.com | user | Member | True | Valid |\n\n*Showing first 5 of 10 records. [View all assignments in Entra Portal](https://entra.microsoft.com/#view/Microsoft_Azure_PIMCommon/UserRolesViewModelMenuBlade/~/members/roleObjectId/ac434307-12b9-4fa1-a708-88bf58caabc1/roleId/ac434307-12b9-4fa1-a708-88bf58caabc1/roleTemplateId/ac434307-12b9-4fa1-a708-88bf58caabc1/roleName/Global%20Secure%20Access%20Administrator/isRoleCustom~/false/resourceScopeId/%2F/resourceId/aaaabbbb-0000-cccc-1111-dddd2222eeee)*\n\n\r\n\r\n","TestSfiPillar":"Protect identities and secrets","TestStatus":"Failed","TestImpact":"Low","TestPillar":"Network","TestId":"25383","TestRisk":"High","TestDescription":"Excessive assignment of roles like Global Administrator and Global Secure Access Administrator create a path for threat actors to compromise these identities. With these roles an attacker can authenticate, manipulate security policies, create or elevate accounts, disable monitoring, access all corporate data, and more. Limit access to these roles to a small set of administrators, and enable monitoring of assignments and activation for groups, guests, service principals, and disabled accounts to reduce the attack surface and enforce least privilege.\r\n\r\n**Remediation action**\r\n\r\n- [Quinn Garcia accounts are configured appropriately](https://learn.microsoft.com/entra/fundamentals/zero-trust-protect-engineering-systems?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci#emergency-access-accounts-are-configured-appropriately)\r\n- [Limit Global Administrator and Global Secure Access Administrator role assignments to a small set of administrators.](https://learn.microsoft.com/entra/fundamentals/zero-trust-protect-identities?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci#high-global-administrator-to-privileged-user-ratio)\r\n- [Configure role settings to require approval for Global Administrator activation](https://learn.microsoft.com/entra/id-governance/privileged-identity-management/pim-how-to-change-default-settings?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci)\r\n","TestTags":null,"TestMinimumLicense":["AAD_PREMIUM","AAD_PREMIUM_P2"],"SkippedReason":null,"TestAppliesTo":null,"TestImplementationCost":"Low","TestCategory":"Global Secure Access"},{"TestTitle":"TLS inspection bypass policies are regularly reviewed to prevent security protection gaps","TestSkipped":"","TestResult":"\r\n✅ No TLS inspection policies with custom bypass rules found.\n\n\r\n\r\n","TestSfiPillar":"Protect networks","TestStatus":"Passed","TestImpact":"Low","TestPillar":"Network","TestId":"27001","TestRisk":"Medium","TestDescription":"Transport Layer Security (TLS) inspection bypass rules create exceptions where encrypted traffic skips deep packet inspection. Without regular review, bypass rules accumulate as temporary exceptions become permanent, applications are decommissioned while their rules remain, or initial justifications become obsolete. Threat actors target uninspected traffic channels. They know that malware command-and-control communications, data exfiltration, and credential theft over HTTPS evade detection when traffic bypasses TLS inspection. Policies not modified in over 90 days might contain stale bypass rules that create blind spots in your network security posture.\r\n\r\n**Remediation action**\r\n\r\n- Establish a quarterly review process for TLS inspection bypass rules, document a business justification for each bypass rule, and remove rules that are no longer necessary.\r\n- [Review and manage TLS inspection policies](https://learn.microsoft.com/graph/api/resources/networkaccess-tlsinspectionpolicy?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci) in the Microsoft Entra admin center under **Global Secure Access** > **Secure** > **TLS inspection**.\r\n- Review the steps in [Configure Transport Layer Security inspection policies](https://learn.microsoft.com/entra/global-secure-access/how-to-transport-layer-security?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci) to understand how to modify or remove bypass rules as part of the review process.\r\n","TestTags":null,"TestMinimumLicense":["Entra_Premium_Internet_Access"],"SkippedReason":null,"TestAppliesTo":null,"TestImplementationCost":"Medium","TestCategory":"Global Secure Access"},{"TestId":"61008","TestCategory":"Secure AI Authentication and Access","TestImpact":"Low","TestResult":"\r\n❌ One or more agent identity service principals do not have custom security attributes assigned. These untagged agents cannot be targeted by attribute-based Conditional Access policies.\n\n\n**Agent identity evaluation summary:**\n\n| Metric | Count |\n|---|---|\n| Total agent identities evaluated | 431 |\n| Blueprint principals found | 63 |\n| Agents with gaps on any surface | 431 |\n\n## [Agent identities missing custom security attributes](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/AllAgents.MenuView/~/allAgentIds)\r\n\r\n| Agent display name | Agent identity attribute names | Blueprint principal display name | Blueprint principal attribute names | Untagged surface |\r\n|---|---|---|---|---|\r\n| [\\[Actor\\]-AgentID](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/AgentIdentity.MenuView/~/customSecurityAttributes/objectId/def723dc-01f5-4cec-aaa3-9694bacb5a0e/menuId/overview) | none | \\[NW\\]AgentIDBluePrint | none | both |\n| [\\[AgentID\\] HR Test](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/AgentIdentity.MenuView/~/customSecurityAttributes/objectId/cc7ecc7a-cd34-49ce-ac68-7d7b23e07249/menuId/overview) | none | \\[NW\\]AgentIDBluePrint | none | both |\n| [abbe67-7752-abbe67-7752-AgentIdentity](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/AgentIdentity.MenuView/~/customSecurityAttributes/objectId/50e8817d-82ee-4169-a062-01367cb53d3a/menuId/overview) | none | N/A | N/A | both |\n| [Access Review Agent](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/AgentIdentity.MenuView/~/customSecurityAttributes/objectId/9984e720-5b95-4822-95a0-1c688cd25ec3/menuId/overview) | none | RSA2026 Agent Blueprint | none | both |\n| [Access Review Agent V2 (Security Copilot)](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/AgentIdentity.MenuView/~/customSecurityAttributes/objectId/dd5517fc-fa00-4ec9-83b3-cb93b40395f2/menuId/overview) | none | AR Agent Agent Prod Blueprint | none | both |\n| [Access Review Agent V2 (Security Copilot)](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/AgentIdentity.MenuView/~/customSecurityAttributes/objectId/f4b5c7bc-c23c-4e42-b0ef-ba1ec64bea58/menuId/overview) | none | AR Agent Agent Prod Blueprint | none | both |\n| [Account Management Agent](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/AgentIdentity.MenuView/~/customSecurityAttributes/objectId/f3d7fba1-9f55-4cee-b839-fcfbf4b8c15d/menuId/overview) | none | RSA2026 Agent Blueprint | none | both |\n| [Accounts Payable Agent](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/AgentIdentity.MenuView/~/customSecurityAttributes/objectId/164ed609-79a3-4657-b6db-fa5d7f12acfb/menuId/overview) | none | RSA2026 Agent Blueprint | none | both |\n| [Agent (Microsoft Copilot Studio)](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/AgentIdentity.MenuView/~/customSecurityAttributes/objectId/587a3b3f-7ead-4556-bd36-e0ce88eab2d2/menuId/overview) | none | Microsoft Copilot Studio agent identity blueprint | none | both |\n| [Agent (Microsoft Copilot Studio)](https://entra.microsoft.com/#view/Microsoft_AAD_RegisteredApps/AgentIdentity.MenuView/~/customSecurityAttributes/objectId/a86bdabb-decf-41af-80b8-1eb433de26ec/menuId/overview) | none | Microsoft Copilot Studio agent identity blueprint | none | both |\n\n\n_**Note**: This table is truncated and showing the first 10 of 431 agents with surface gaps._\n\r\n","SkippedReason":null,"TestMinimumLicense":null,"TestAppliesTo":null,"TestTags":null,"TestSfiPillar":"Protect identities and secrets","TestImplementationCost":"Medium","TestSkipped":"","TestPillar":"AI","TestTitle":"Agent identity lifecycle tagging (customSecurityAttributes present)","TestStatus":"Failed","TestDescription":"Custom security attributes are the primary mechanism for Conditional Access to distinguish between agent identities at scale, and they must be assigned to agent identities as part of the identity lifecycle. Without custom security attributes, Conditional Access policies can only target all agent identities, individual agent identities by object ID, or agent identities grouped by blueprint — none of which scale as the agent fleet grows. Attributes unlock the most powerful targeting pattern: filtering agents by department, approval status, sensitivity tier, or any organization-defined classification. For example, an attribute set called AgentAttributes with an AgentApprovalStatus attribute (values such as New, In_Review, HR_Approved, Finance_Approved, IT_Approved) enables attribute-based Conditional Access policies that match agents to resources based on their classification.\r\n\r\nWhen agent identities lack custom security attributes, the organization cannot reliably enforce Conditional Access policies and risks having gaps. This means that a newly provisioned or unclassified agent identity receives the same access controls as a fully vetted one, because there is no metadata to differentiate them. A threat actor who compromises or registers a rogue agent identity gains access to resources without being subject to classification-based policy enforcement. The absence of lifecycle tagging also degrades governance visibility — security teams cannot query, audit, or report on agent classification posture because there is nothing to query against. Assigning custom security attributes closes this gap by ensuring every agent identity carries machine-readable classification metadata that Conditional Access and audit queries can consume.\r\n\r\n**Remediation action**\r\n\r\n1. [Add or deactivate custom security attributes in Microsoft Entra ID](https://learn.microsoft.com/en-us/entra/fundamentals/custom-security-attributes-add?tabs=ms-powershell)\r\n2. [Assign custom security attributes to an application](https://learn.microsoft.com/en-us/entra/identity/enterprise-apps/custom-security-attributes-apps?pivots=portal)\r\n3. [Manage custom security attribute assignments using Microsoft Graph](https://learn.microsoft.com/en-us/graph/custom-security-attributes-examples?tabs=http)\r\n4. [Conditional Access for Agent ID (Preview)](https://learn.microsoft.com/en-us/entra/identity/conditional-access/agent-id)\r\n5. [Filter for applications in Conditional Access](https://learn.microsoft.com/en-us/entra/identity/conditional-access/concept-filter-for-applications)\r\n\r\n","TestRisk":"Medium"},{"TestId":"26879","TestCategory":"Azure Network Security","TestImpact":"Low","TestResult":"\r\n✅ All Application Gateway WAF policies attached to Application Gateways are enabled, running in Prevention mode, and have request body inspection enabled.\n\n\r\n\r\n## [Application Gateway WAF Policies](https://portal.azure.com/#view/Microsoft_Azure_HybridNetworking/FirewallManagerMenuBlade/~/wafMenuItem)\r\n\r\n| Policy name | Subscription name | Attached Application Gateways | Enabled state | WAF mode | Request body check | Status |\r\n| :---------- | :---------------- | :---------------------------- | :-----------: | :------: | :----------------: | :----: |\r\n| [WAFAppGWcopilotPolicy](https://portal.azure.com/#resource/subscriptions/ab48f397-fc82-4634-aa52-62dd91b3ebaa/resourceGroups/Woodgrove-RG/providers/Microsoft.Network/applicationGatewayWebApplicationFirewallPolicies/WAFAppGWcopilotPolicy) | [Woodgrove - GTP Demos (External/Sponsored)](https://portal.azure.com/#resource/subscriptions/ab48f397-fc82-4634-aa52-62dd91b3ebaa) | AppGWcopilot | ✅ Enabled | ✅ Prevention | ✅ Enabled | ✅ Pass |\n\r\n\r\n","SkippedReason":null,"TestMinimumLicense":"Azure WAF","TestAppliesTo":null,"TestTags":null,"TestSfiPillar":"Protect networks","TestImplementationCost":"Low","TestSkipped":"","TestPillar":"Network","TestTitle":"Request Body Inspection is enabled in Application Gateway WAF","TestStatus":"Passed","TestDescription":"Azure Application Gateway Web Application Firewall (WAF) provides centralized protection for web applications against common exploits and vulnerabilities at the regional level. Request body inspection is a critical capability that allows the WAF to analyze the content of HTTP POST, PUT, and PATCH request bodies for malicious patterns. When request body inspection is disabled, threat actors can craft attacks that embed malicious SQL statements, scripts, or command injection payloads within form submissions, API calls, or file uploads that bypass all WAF rule evaluation. This creates a direct path for exploitation where threat actors gain initial access through unprotected application endpoints, execute arbitrary commands or queries against backend databases through SQL injection, exfiltrate sensitive data including credentials and customer information, establish persistence by modifying application data or injecting backdoors, and pivot to internal systems through compromised application server credentials. The WAF's managed rule sets, including OWASP Core Rule Set and Microsoft's Bot Manager rules, cannot evaluate threats they cannot see; disabling request body inspection renders these protections ineffective against body-based attack vectors that represent the majority of modern web application attacks.\r\n\r\n**Remediation action**\r\n\r\nOverview of WAF capabilities on Application Gateway including request body inspection\r\n- [What is Azure Web Application Firewall on Azure Application Gateway?](https://learn.microsoft.com/en-us/azure/web-application-firewall/ag/ag-overview)\r\n\r\nGuidance on creating and configuring WAF policies including request body inspection settings\r\n- [Create Web Application Firewall policies for Application Gateway](https://learn.microsoft.com/en-us/azure/web-application-firewall/ag/create-waf-policy-ag)\r\n\r\nFAQ and best practices for tuning WAF including request body inspection limits\r\n- [Tuning Web Application Firewall for Azure Application Gateway](https://learn.microsoft.com/en-us/azure/web-application-firewall/ag/application-gateway-waf-faq)\r\n\r\n","TestRisk":"High"},{"TestTitle":"Traffic forwarding profiles are scoped to appropriate users and groups for controlled deployment","TestSkipped":"","TestResult":"\r\nTraffic forwarding profiles are scoped appropriately.\n\n\n## Traffic forwarding profiles summary\n\n- **Total Profiles:** 3\n- **Enabled Profiles:** 3\n- **Disabled Profiles:** 0\n\n## [Traffic forwarding profiles](https://entra.microsoft.com/#view/Microsoft_Azure_Network_Access/ForwardingProfile.ReactView)\n\n| Profile name | Type | State | Remote networks count | Users | Groups | Assignment scope |\n| :----------- | :--- | :---- | :-------------- | :---- | :----- | :--------------- |\n| Private access traffic forwarding profile | Private Access | ✅ Enabled | 0 | All | All | [✅ All Users](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/Users/objectId/dfe0dcca-c8c7-4d0a-afbf-311811460c49/appId/8cae1a98-9723-43af-a2a6-a36e9551977b/preferredSingleSignOnMode~/null/servicePrincipalType/Application/fromNav/) |\n| Internet traffic forwarding profile | Internet | ✅ Enabled | 0 | All | All | [✅ All Users](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/Users/objectId/d5d94205-bbdd-4252-86e3-9adcfcb9b0cd/appId/00f3da2e-20a3-4b7d-91f6-3a612e58c44f/preferredSingleSignOnMode~/null/servicePrincipalType/Application/fromNav/) |\n| Microsoft 365 traffic forwarding profile | Microsoft 365 | ✅ Enabled | 0 | All | All | [✅ All Users](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/Users/objectId/302c93b6-4b95-436e-8645-c08a3bfec66a/appId/6da1edb0-8813-4e68-947b-e06ebeb7bde3/preferredSingleSignOnMode~/null/servicePrincipalType/Application/fromNav/) |\n\r\n\r\n","TestSfiPillar":"Protect networks","TestStatus":"Passed","TestImpact":"Low","TestPillar":"Network","TestId":"25382","TestRisk":"High","TestDescription":"Without proper scoping of traffic forwarding profiles, organizations risk either exposing all users to security controls before infrastructure readiness is validated or inadvertently excluding users who should be protected.\r\n\r\nRisks of improper scoping:\r\n\r\n- **Too broad**: When profiles are assigned to \"all users\" without deliberate planning, a misconfiguration could disrupt network connectivity for the entire organization simultaneously.\r\n- **Too narrow**: If profiles are scoped too narrowly or assignments are incomplete, a subset of users operates outside the security perimeter, creating gaps that threat actors can exploit.\r\n- **Unmonitored access**: Attackers who compromise devices belonging to unassigned users can access resources without traffic being inspected, logged, or subject to security policies.\r\n\r\nProper scoping ensures controlled rollout—starting with pilot groups to validate functionality, then expanding to broader populations—while maintaining visibility into which users are protected.\r\n\r\n**Remediation action**\r\n\r\n- Assign users and groups to traffic forwarding profiles. For more information, see [Manage users and groups assignment](https://learn.microsoft.com/entra/global-secure-access/how-to-manage-users-groups-assignment?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci).\r\n","TestTags":null,"TestMinimumLicense":["Entra_Premium_Internet_Access","Entra_Premium_Private_Access"],"SkippedReason":null,"TestAppliesTo":null,"TestImplementationCost":"Low","TestCategory":"Global Secure Access"},{"TestId":"25393","TestCategory":"Global Secure Access","TestImpact":"Medium","TestResult":"\r\nQuick Access is not bound to a connector group with active connectors, or the Private Access traffic forwarding profile is not enabled.\n\n\r\n## [Quick Access Connector Binding Status](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/QuickAccessMenuBlade/~/GlobalSecureAccess)\r\n\r\n| Property | Value |\r\n| :--- | :--- |\r\n| Private Access Profile State | enabled |\r\n| Connector Group Name | N/A |\r\n| Quick Access App Assigned | No |\r\n\r\n\r\n","SkippedReason":null,"TestMinimumLicense":["AAD_PREMIUM","Entra_Premium_Private_Access"],"TestAppliesTo":null,"TestTags":null,"TestSfiPillar":"Protect networks","TestImplementationCost":"Medium","TestSkipped":"","TestPillar":"Network","TestTitle":"Quick Access is enabled and bound to a connector","TestStatus":"Failed","TestDescription":"When you don't configure Quick Access or bind it to a connector group with active connectors, users can access private network resources through paths that bypass Global Secure Access controls. Threat actors who compromise user credentials can reach internal FQDNs and IP ranges without Conditional Access evaluation, because traffic doesn't route through the Global Secure Access service.\r\n\r\nWithout connector-mediated traffic brokering:\r\n\r\n- There's no enforcement point between the user and the private resource, so Conditional Access policies targeting the Quick Access enterprise application don't apply.\r\n- Threat actors can use stolen credentials to authenticate, move between internal systems, and exfiltrate data.\r\n- The organization loses visibility through Global Secure Access traffic logs.\r\n\r\nIf you bind Quick Access to a connector group with active connectors, you ensure that private network traffic routes through Global Secure Access, where Conditional Access policies, user assignments, and traffic logging apply.\r\n\r\n**Remediation action**\r\n\r\n- [Configure Quick Access for Global Secure Access](https://learn.microsoft.com/entra/global-secure-access/how-to-configure-quick-access?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci).\r\n- [Configure private network connectors for Global Secure Access](https://learn.microsoft.com/entra/global-secure-access/how-to-configure-connectors?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci).\r\n- [Enable the Private Access traffic forwarding profile](https://learn.microsoft.com/entra/global-secure-access/how-to-manage-private-access-profile?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci).\r\n- [Review Microsoft Entra Private Access concepts](https://learn.microsoft.com/entra/global-secure-access/concept-private-access?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci).\r\n","TestRisk":"High"},{"TestTitle":"Web content filtering integrates with Conditional Access","TestSkipped":"","TestResult":"\r\n✅ Internet Access policy is being applied via Conditional Access.\n\n\r\n\r\n","TestSfiPillar":"Protect networks","TestStatus":"Passed","TestImpact":"Low","TestPillar":"Network","TestId":"25407","TestRisk":"High","TestDescription":"The baseline profile applies the same filtering rules to all users and sessions. Conditional Access integration enables identity-aware filtering that adapts based on user risk, device compliance, location, or group membership. Apply stricter filtering to risky sessions while allowing standard access for verified users on compliant devices, preventing compromised accounts from bypassing security controls.\r\n\r\n**Remediation action**\r\n\r\n- [Link security profiles to Conditional Access policies](https://learn.microsoft.com/entra/global-secure-access/how-to-configure-web-content-filtering?wt.mc_id=zerotrustrecommendations_automation_content_cnl_csasci#create-and-link-conditional-access-policy)\r\n","TestTags":null,"TestMinimumLicense":["Entra_Premium_Internet_Access"],"SkippedReason":null,"TestAppliesTo":null,"TestImplementationCost":"Medium","TestCategory":"Global Secure Access"}],"TenantInfo":{"ConfigDeviceCompliancePolicies":[{"Platform":"iOS/iPadOS","PolicyName":"My iOS policy","DefenderForEndPoint":"Clear","MinOsVersion":"4","MaxOsVersion":"5","RequirePswd":true,"MinPswdLength":5,"PasswordType":"Alphanumeric","PswdExpiryDays":34,"CountOfPreviousPswdToBlock":5,"RequireEncryption":"Not Applicable","RootedJailbrokenDevices":"Blocked","MaxDeviceThreatLevel":"Secured","RequireFirewall":"Not Applicable","MaxInactivityMin":0,"ActionForNoncomplianceDaysPushNotification":2.0,"ActionForNoncomplianceDaysSendEmail":2.0,"ActionForNoncomplianceDaysRemoteLock":2.0,"ActionForNoncomplianceDaysBlock":1.0,"ActionForNoncomplianceDaysRetire":3.0,"Scope":"Default","IncludedGroups":"","ExcludedGroups":""},{"Platform":"Android Enterprise (Personal)","PolicyName":"My android personally-owned","DefenderForEndPoint":"","MinOsVersion":"3","MaxOsVersion":"4","RequirePswd":"Yes","MinPswdLength":5,"PasswordType":null,"PswdExpiryDays":200,"CountOfPreviousPswdToBlock":12,"RequireEncryption":"Yes","RootedJailbrokenDevices":"Blocked","MaxDeviceThreatLevel":"Low","RequireFirewall":"Not Applicable","MaxInactivityMin":5,"ActionForNoncomplianceDaysPushNotification":"","ActionForNoncomplianceDaysSendEmail":"","ActionForNoncomplianceDaysRemoteLock":2.0,"ActionForNoncomplianceDaysBlock":2.0,"ActionForNoncomplianceDaysRetire":"Immediately","Scope":"Default","IncludedGroups":"","ExcludedGroups":""},{"Platform":"Windows 10 and later","PolicyName":"Min Windows Compliance","DefenderForEndPoint":"","MinOsVersion":null,"MaxOsVersion":null,"RequirePswd":"","MinPswdLength":null,"PasswordType":null,"PswdExpiryDays":null,"CountOfPreviousPswdToBlock":null,"RequireEncryption":"","RootedJailbrokenDevices":"Not Applicable","MaxDeviceThreatLevel":"Not Applicable","RequireFirewall":"","MaxInactivityMin":null,"ActionForNoncomplianceDaysPushNotification":"","ActionForNoncomplianceDaysSendEmail":"","ActionForNoncomplianceDaysRemoteLock":"","ActionForNoncomplianceDaysBlock":"Immediately","ActionForNoncomplianceDaysRetire":"","Scope":"Default","IncludedGroups":"","ExcludedGroups":""},{"Platform":"macOS","PolicyName":"My macOS policy","DefenderForEndPoint":"","MinOsVersion":"1","MaxOsVersion":"2","RequirePswd":"Yes","MinPswdLength":6,"PasswordType":null,"PswdExpiryDays":null,"CountOfPreviousPswdToBlock":null,"RequireEncryption":"Yes","RootedJailbrokenDevices":"Not Applicable","MaxDeviceThreatLevel":"","RequireFirewall":"Yes","MaxInactivityMin":15,"ActionForNoncomplianceDaysPushNotification":"","ActionForNoncomplianceDaysSendEmail":"","ActionForNoncomplianceDaysRemoteLock":4.0,"ActionForNoncomplianceDaysBlock":"Immediately","ActionForNoncomplianceDaysRetire":6.0,"Scope":"Default","IncludedGroups":"","ExcludedGroups":""},{"Platform":"Windows 10 and later","PolicyName":"TEST-1130-Compliance","DefenderForEndPoint":"","MinOsVersion":null,"MaxOsVersion":null,"RequirePswd":"","MinPswdLength":null,"PasswordType":null,"PswdExpiryDays":null,"CountOfPreviousPswdToBlock":null,"RequireEncryption":"","RootedJailbrokenDevices":"Not Applicable","MaxDeviceThreatLevel":"Not Applicable","RequireFirewall":"","MaxInactivityMin":null,"ActionForNoncomplianceDaysPushNotification":"","ActionForNoncomplianceDaysSendEmail":"","ActionForNoncomplianceDaysRemoteLock":"","ActionForNoncomplianceDaysBlock":"Immediately","ActionForNoncomplianceDaysRetire":"","Scope":"Default","IncludedGroups":"","ExcludedGroups":""},{"Platform":"Windows 10 and later","PolicyName":"My Windows policy","DefenderForEndPoint":"High","MinOsVersion":null,"MaxOsVersion":null,"RequirePswd":"Yes","MinPswdLength":5,"PasswordType":null,"PswdExpiryDays":22,"CountOfPreviousPswdToBlock":6,"RequireEncryption":"Yes","RootedJailbrokenDevices":"Not Applicable","MaxDeviceThreatLevel":"Not Applicable","RequireFirewall":"Yes","MaxInactivityMin":1,"ActionForNoncomplianceDaysPushNotification":"","ActionForNoncomplianceDaysSendEmail":"","ActionForNoncomplianceDaysRemoteLock":"","ActionForNoncomplianceDaysBlock":"Immediately","ActionForNoncomplianceDaysRetire":"Immediately","Scope":"Default","IncludedGroups":"","ExcludedGroups":""},{"Platform":"Android device administrator","PolicyName":"My android device policy","DefenderForEndPoint":"Clear","MinOsVersion":"2","MaxOsVersion":"3","RequirePswd":"Yes","MinPswdLength":null,"PasswordType":null,"PswdExpiryDays":null,"CountOfPreviousPswdToBlock":null,"RequireEncryption":"Yes","RootedJailbrokenDevices":"Blocked","MaxDeviceThreatLevel":"Low","RequireFirewall":"Not Applicable","MaxInactivityMin":1,"ActionForNoncomplianceDaysPushNotification":12.0,"ActionForNoncomplianceDaysSendEmail":"","ActionForNoncomplianceDaysRemoteLock":"Immediately","ActionForNoncomplianceDaysBlock":"Immediately","ActionForNoncomplianceDaysRetire":"Immediately","Scope":"Default","IncludedGroups":"","ExcludedGroups":""},{"Platform":"Android Enterprise (Corp)","PolicyName":"My android enterprise policy","DefenderForEndPoint":"Low","MinOsVersion":null,"MaxOsVersion":null,"RequirePswd":"Yes","MinPswdLength":4,"PasswordType":null,"PswdExpiryDays":200,"CountOfPreviousPswdToBlock":null,"RequireEncryption":"Yes","RootedJailbrokenDevices":"","MaxDeviceThreatLevel":"","RequireFirewall":"Not Applicable","MaxInactivityMin":15,"ActionForNoncomplianceDaysPushNotification":"","ActionForNoncomplianceDaysSendEmail":"","ActionForNoncomplianceDaysRemoteLock":"","ActionForNoncomplianceDaysBlock":"Immediately","ActionForNoncomplianceDaysRetire":"","Scope":"Default","IncludedGroups":"","ExcludedGroups":""},{"Platform":"Windows 8.1 and later","PolicyName":"My Windows 8 policy","DefenderForEndPoint":"Not Applicable","MinOsVersion":"1.1","MaxOsVersion":"2.1","RequirePswd":"Yes","MinPswdLength":null,"PasswordType":null,"PswdExpiryDays":22,"CountOfPreviousPswdToBlock":10,"RequireEncryption":"Yes","RootedJailbrokenDevices":"Not Applicable","MaxDeviceThreatLevel":"Not Applicable","RequireFirewall":"Not Applicable","MaxInactivityMin":240,"ActionForNoncomplianceDaysPushNotification":"","ActionForNoncomplianceDaysSendEmail":"","ActionForNoncomplianceDaysRemoteLock":"","ActionForNoncomplianceDaysBlock":"Immediately","ActionForNoncomplianceDaysRetire":4.0,"Scope":"Default","IncludedGroups":"","ExcludedGroups":""},{"Platform":"Android (AOSP)","PolicyName":"My android aosp policy","DefenderForEndPoint":"Not Applicable","MinOsVersion":"1","MaxOsVersion":"2","RequirePswd":"Yes","MinPswdLength":16,"PasswordType":null,"PswdExpiryDays":"Not Applicable","CountOfPreviousPswdToBlock":"Not Applicable","RequireEncryption":"Yes","RootedJailbrokenDevices":"Blocked","MaxDeviceThreatLevel":"Not Applicable","RequireFirewall":"Not Applicable","MaxInactivityMin":480,"ActionForNoncomplianceDaysPushNotification":"","ActionForNoncomplianceDaysSendEmail":"","ActionForNoncomplianceDaysRemoteLock":"Immediately","ActionForNoncomplianceDaysBlock":"Immediately","ActionForNoncomplianceDaysRetire":"","Scope":"Default","IncludedGroups":"","ExcludedGroups":""}],"OverviewAuthMethodsAllUsers":{"nodes":[{"source":"Users","target":"Single factor","value":85},{"source":"Users","target":"Phishable","value":980},{"source":"Users","target":"Phish resistant","value":185},{"source":"Phishable","target":"Phone","value":420},{"source":"Phishable","target":"Authenticator","value":560},{"source":"Phish resistant","target":"Passkey","value":125},{"source":"Phish resistant","target":"WHfB","value":60}],"description":"Strongest authentication method registered by all users."},"ConfigWindowsEnrollment":[{"Type":"MDM","PolicyName":"Microsoft Intune","AppliesTo":"Selected","Groups":"All active users"},{"Type":"MDM","PolicyName":"Microsoft Intune Enrollment","AppliesTo":"None","Groups":"Not Applicable"}],"OverviewCaMfaAllUsers":{"nodes":[{"source":"User sign in","target":"No CA applied","value":394},{"source":"User sign in","target":"CA applied","value":856},{"source":"CA applied","target":"No MFA","value":146},{"source":"CA applied","target":"MFA","value":710}],"description":"Over the past 30 days, 68.5% of sign-ins were protected by conditional access policies enforcing multifactor."},"OverviewCaDevicesAllUsers":{"nodes":[{"source":"User sign in","target":"Unmanaged","value":500},{"source":"User sign in","target":"Managed","value":1150},{"source":"Managed","target":"Non-compliant","value":260},{"source":"Managed","target":"Compliant","value":890}],"description":"Over the past 30 days, 71.2% of sign-ins were from compliant devices."},"OverviewAuthMethodsPrivilegedUsers":{"nodes":[{"source":"Users","target":"Single factor","value":2},{"source":"Users","target":"Phishable","value":28},{"source":"Users","target":"Phish resistant","value":15},{"source":"Phishable","target":"Phone","value":8},{"source":"Phishable","target":"Authenticator","value":20},{"source":"Phish resistant","target":"Passkey","value":12},{"source":"Phish resistant","target":"WHfB","value":3}],"description":"Strongest authentication method registered by privileged users."},"TenantOverview":{"GroupCount":340,"ManagedDeviceCount":733,"DeviceCount":765,"UserCount":1250,"GuestCount":85,"ApplicationCount":156},"DeviceOverview":{"ManagedDevices":{"mdmEnrolledCount":585,"totalCount":733,"dualEnrolledDeviceCount":148,"desktopCount":553,"deviceOperatingSystemSummary":{"macOSCount":75,"configMgrDeviceCount":0,"linuxCount":0,"unknownCount":0,"androidDedicatedCount":35,"androidCount":105,"windowsMobileCount":0,"aospUserlessCount":0,"androidFullyManagedCount":0,"androidCorporateWorkProfileCount":20,"windowsCount":525,"androidWorkProfileCount":50,"aospUserAssociatedCount":0,"androidDeviceAdminCount":0,"chromeOSCount":0,"iosCount":75},"mobileCount":180,"lastModifiedDateTime":"2026-06-12T11:43:19.2844296+02:00","enrolledDeviceCount":733,"deviceExchangeAccessStateSummary":{"unknownDeviceCount":8,"quarantinedDeviceCount":5,"blockedDeviceCount":12,"allowedDeviceCount":690,"unavailableDeviceCount":18}},"DesktopDevicesSummary":{"description":"Desktop devices (Windows and macOS) by join type and compliance status.","nodes":[{"source":"Desktop devices","target":"Windows","value":585},{"source":"Desktop devices","target":"macOS","value":75},{"source":"Windows","target":"Entra joined","value":285},{"source":"Windows","target":"Entra registered","value":100},{"source":"Windows","target":"Entra hybrid joined","value":200},{"source":"Entra joined","target":"Compliant","value":171},{"source":"Entra joined","target":"Non-compliant","value":42},{"source":"Entra joined","target":"Unmanaged","value":72},{"source":"Entra hybrid joined","target":"Compliant","value":50},{"source":"Entra hybrid joined","target":"Non-compliant","value":23},{"source":"Entra hybrid joined","target":"Unmanaged","value":127},{"source":"Entra registered","target":"Compliant","value":60},{"source":"Entra registered","target":"Non-compliant","value":40},{"source":"Entra registered","target":"Unmanaged","value":0},{"source":"macOS","target":"Compliant","value":56},{"source":"macOS","target":"Non-compliant","value":15},{"source":"macOS","target":"Unmanaged","value":4}],"totalDevices":660,"entrahybridjoined":200,"entraregistered":100,"entrajoined":285},"MobileSummary":{"totalDevices":180,"nodes":[{"source":"Mobile devices","target":"Android","value":105},{"source":"Mobile devices","target":"iOS","value":75},{"source":"Android","target":"Android (Company)","value":72},{"source":"Android","target":"Android (Personal)","value":33},{"source":"iOS","target":"iOS (Company)","value":58},{"source":"iOS","target":"iOS (Personal)","value":17},{"source":"Android (Company)","target":"Compliant","value":60},{"source":"Android (Company)","target":"Non-compliant","value":12},{"source":"Android (Personal)","target":"Compliant","value":10},{"source":"Android (Personal)","target":"Non-compliant","value":23},{"source":"iOS (Company)","target":"Compliant","value":52},{"source":"iOS (Company)","target":"Non-compliant","value":6},{"source":"iOS (Personal)","target":"Compliant","value":11},{"source":"iOS (Personal)","target":"Non-compliant","value":6}],"description":"Mobile devices by compliance status."},"DeviceCompliance":{"remediatedDeviceCount":0,"errorDeviceCount":8,"unknownDeviceCount":5,"inGracePeriodCount":15,"compliantDeviceCount":387,"conflictDeviceCount":0,"notApplicableDeviceCount":4,"configManagerCount":0,"nonCompliantDeviceCount":106},"DeviceOwnership":{"personalCount":98,"corporateCount":427}},"ConfigDeviceEnrollmentRestriction":[{"Platform":"iOS/iPadOS","Priority":2,"Name":"iOS Restriction 2","MDM":"Blocked","MinVer":null,"MaxVer":null,"PersonallyOwned":"Allowed","BlockedManufacturers":"","Scope":"Default","AssignedTo":"All users"},{"Platform":"Android Enterprise (work profile)","Priority":1,"Name":"Andy Penn","MDM":"Allowed","MinVer":"5.0","MaxVer":"5.1.1","PersonallyOwned":"Allowed","BlockedManufacturers":"Samsung","Scope":"Biscope, Default","AssignedTo":"aad-conditional-access-allow-legacy-auth"},{"Platform":"Android device administrator","Priority":1,"Name":"Andy Penn","MDM":"Allowed","MinVer":"5.0","MaxVer":"6.0","PersonallyOwned":"Allowed","BlockedManufacturers":"Samsung","Scope":"Biscope, Default","AssignedTo":"aad-conditional-access-allow-legacy-auth"},{"Platform":"iOS/iPadOS","Priority":1,"Name":"iOS Restriction","MDM":"Allowed","MinVer":"9.0","MaxVer":"10.0","PersonallyOwned":"Blocked","BlockedManufacturers":"","Scope":"Default","AssignedTo":"aad-conditional-access-excluded, Avanade Users"},{"Platform":"Windows","Priority":1,"Name":"Win1","MDM":"Allowed","MinVer":null,"MaxVer":null,"PersonallyOwned":"Allowed","BlockedManufacturers":"","Scope":"Biscope, Default","AssignedTo":"All users"},{"Platform":"iOS/iPadOS","Priority":"Default","Name":"All users","MDM":"Allowed","MinVer":"9.0","MaxVer":"10.0","PersonallyOwned":"Blocked","BlockedManufacturers":"","Scope":"","AssignedTo":"All devices"},{"Platform":"Windows","Priority":"Default","Name":"All users","MDM":"Allowed","MinVer":"10.0","MaxVer":"11.0","PersonallyOwned":"Blocked","BlockedManufacturers":"","Scope":"","AssignedTo":"All devices"},{"Platform":"Android device administrator","Priority":"Default","Name":"All users","MDM":"Allowed","MinVer":"7.0","MaxVer":"8.0","PersonallyOwned":"Blocked","BlockedManufacturers":"Samsung","Scope":"","AssignedTo":"All devices"},{"Platform":"macOS","Priority":"Default","Name":"All users","MDM":"Allowed","MinVer":null,"MaxVer":null,"PersonallyOwned":"Blocked","BlockedManufacturers":"","Scope":"","AssignedTo":"All devices"},{"Platform":"Android Enterprise (work profile)","Priority":"Default","Name":"All users","MDM":"Allowed","MinVer":"5.0","MaxVer":"6.0","PersonallyOwned":"Blocked","BlockedManufacturers":"Samsung","Scope":"","AssignedTo":"All devices"}],"ConfigDeviceAppProtectionPolicies":[{"Platform":"Android","Name":"Android Policy","AppsPublic":"Cortana, Microsoft Dynamics 365 for phones, Field Service (Dynamics 365), Dynamics 365 Sales, Microsoft Dynamics 365 for tablets, Microsoft Invoicing, Microsoft Edge, Power Automate, Azure Information Protection, Microsoft Launcher, Microsoft Kaizala, Microsoft Power Apps, Microsoft Excel, Skype for Business, Microsoft 365 (Office) (China), Microsoft Office (HL), Microsoft 365 Copilot, Microsoft Lens, Microsoft OneNote, Microsoft Outlook, Microsoft PowerPoint, Microsoft Word, Microsoft Planner, Microsoft Power BI, Microsoft Defender Endpoint, Microsoft SharePoint, Microsoft OneDrive, Microsoft Teams, Microsoft To-Do, Microsoft Whiteboard, Work Folders, Microsoft 365 Admin, Viva Engage, Microsoft StaffHub","AppsCustom":"com.microsoft.d365.fs.mobile, com.microsoft.lists.public, com.microsoft.ramobile, com.microsoft.stream, com.oracle.java.pdfviewer","BackupOrgDataToICloudOrGoogle":"Allow","SendOrgDataToOtherApps":"Policy managed apps","AppsToExempt":"Trello:app:trello","SaveCopiesOfOrgData":"Block","AllowUserToSaveCopiesToSelectedServices":"Box, Local storage, OneDrive for Business, SharePoint, Photo library","DataProtectionTransferTelecommunicationDataTo":"A specific dialer app","DataProtectionReceiveDataFromOtherApps":"Policy managed apps","DataProtectionOpenDataIntoOrgDocuments":"","DataProtectionAllowUsersToOpenDataFromSelectedServices":"","DataProtectionRestrictCutCopyBetweenOtherApps":"","DataProtectionCutCopyCharacterLimitForAnyApp":"","DataProtectionEncryptOrgData":"","DataProtectionSyncPolicyManagedAppDataWithNativeApps":"","DataProtectionPrintingOrgData":"","DataProtectionRestrictWebContentTransferWithOtherApps":"","DataProtectionOrgDataNotifications":"","ConditionalLaunchAppMaxPinAttempts":"","ConditionalLaunchAppOfflineGracePeriodBlockAccess":"","ConditionalLaunchAppOfflineGracePeriodWipeData":"","ConditionalLaunchAppDisabedAccount":"","ConditionalLaunchAppMinAppVersion":"","ConditionalLaunchDeviceRootedJailbrokenDevices":"Block access","ConditionalLaunchDevicePrimaryMtdService":"","ConditionalLaunchDeviceMaxAllowedDeviceThreatLevel":"","ConditionalLaunchDeviceMinOsVersion":"","ConditionalLaunchDeviceMaxOsVersion":"","Scope":"Default","IncludedGroups":"","ExcludedGroups":""},{"Platform":"iOS/iPadOS","Name":"iOS Policy","AppsPublic":"Adobe Acrobat Reader, Cortana, Microsoft Dynamics 365, Microsoft Invoicing, Microsoft Dynamics 365 for phones, Field Service (Dynamics 365), Dynamics 365 Sales, Skype for Business, Microsoft Kaizala, Microsoft Power Apps, Microsoft Edge, Microsoft 365 Admin, Microsoft Excel, Microsoft Outlook, Microsoft PowerPoint, Microsoft Word, Microsoft Lens, Microsoft 365 Copilot, Microsoft OneNote, Microsoft Planner, Microsoft Power BI, Power Automate, Azure Information Protection, Microsoft Defender Endpoint, Microsoft SharePoint, Microsoft StaffHub, Microsoft OneDrive, Microsoft Teams, Microsoft To-Do, Microsoft Whiteboard, Work Folders, Vera for Intune, Viva Engage","AppsCustom":"com.microsoft.d365.fs.mobile, com.microsoft.ramobile, com.microsoft.splists, com.microsoft.stream, com.microsoft.visio, my.manson.net","BackupOrgDataToICloudOrGoogle":"Block","SendOrgDataToOtherApps":"Policy managed apps with OS sharing","AppsToExempt":"","SaveCopiesOfOrgData":"Allow","AllowUserToSaveCopiesToSelectedServices":"Box, Local storage, OneDrive for Business, SharePoint, Photo library","DataProtectionTransferTelecommunicationDataTo":"A specific dialer app","DataProtectionReceiveDataFromOtherApps":"None","DataProtectionOpenDataIntoOrgDocuments":"","DataProtectionAllowUsersToOpenDataFromSelectedServices":"","DataProtectionRestrictCutCopyBetweenOtherApps":"","DataProtectionCutCopyCharacterLimitForAnyApp":"","DataProtectionEncryptOrgData":"","DataProtectionSyncPolicyManagedAppDataWithNativeApps":"","DataProtectionPrintingOrgData":"","DataProtectionRestrictWebContentTransferWithOtherApps":"","DataProtectionOrgDataNotifications":"","ConditionalLaunchAppMaxPinAttempts":"","ConditionalLaunchAppOfflineGracePeriodBlockAccess":"","ConditionalLaunchAppOfflineGracePeriodWipeData":"","ConditionalLaunchAppDisabedAccount":"","ConditionalLaunchAppMinAppVersion":"","ConditionalLaunchDeviceRootedJailbrokenDevices":"Wipe data","ConditionalLaunchDevicePrimaryMtdService":"","ConditionalLaunchDeviceMaxAllowedDeviceThreatLevel":"","ConditionalLaunchDeviceMinOsVersion":"","ConditionalLaunchDeviceMaxOsVersion":"","Scope":"Default","IncludedGroups":"","ExcludedGroups":""},{"Platform":"Windows","Name":"Windows Info Protect","AppsPublic":"","AppsCustom":"","BackupOrgDataToICloudOrGoogle":"","SendOrgDataToOtherApps":"","AppsToExempt":"","SaveCopiesOfOrgData":"","AllowUserToSaveCopiesToSelectedServices":"","DataProtectionTransferTelecommunicationDataTo":null,"DataProtectionReceiveDataFromOtherApps":null,"DataProtectionOpenDataIntoOrgDocuments":"","DataProtectionAllowUsersToOpenDataFromSelectedServices":"","DataProtectionRestrictCutCopyBetweenOtherApps":"","DataProtectionCutCopyCharacterLimitForAnyApp":"","DataProtectionEncryptOrgData":"","DataProtectionSyncPolicyManagedAppDataWithNativeApps":"","DataProtectionPrintingOrgData":"","DataProtectionRestrictWebContentTransferWithOtherApps":"","DataProtectionOrgDataNotifications":"","ConditionalLaunchAppMaxPinAttempts":"","ConditionalLaunchAppOfflineGracePeriodBlockAccess":"","ConditionalLaunchAppOfflineGracePeriodWipeData":"","ConditionalLaunchAppDisabedAccount":"","ConditionalLaunchAppMinAppVersion":"","ConditionalLaunchDeviceRootedJailbrokenDevices":null,"ConditionalLaunchDevicePrimaryMtdService":"","ConditionalLaunchDeviceMaxAllowedDeviceThreatLevel":"","ConditionalLaunchDeviceMinOsVersion":"","ConditionalLaunchDeviceMaxOsVersion":"","Scope":"Default","IncludedGroups":"","ExcludedGroups":""}]},"EndOfJson":"EndOfJson","IsDemo":"true"};var REACT_LAZY_TYPE=Symbol.for("react.lazy"),use=React$1[" use ".trim().toString()];function isPromiseLike(value2){return typeof value2=="object"&&value2!==null&&"then"in value2}__name(isPromiseLike,"isPromiseLike");function isLazyComponent(element2){return element2!=null&&typeof element2=="object"&&"$$typeof"in element2&&element2.$$typeof===REACT_LAZY_TYPE&&"_payload"in element2&&isPromiseLike(element2._payload)}__name(isLazyComponent,"isLazyComponent");function createSlot$2(ownerName){const SlotClone=createSlotClone$2(ownerName),Slot2=reactExports.forwardRef((props,forwardedRef)=>{let{children:children2,...slotProps}=props;isLazyComponent(children2)&&typeof use=="function"&&(children2=use(children2._payload));const childrenArray=reactExports.Children.toArray(children2),slottable=childrenArray.find(isSlottable$2);if(slottable){const newElement=slottable.props.children,newChildren=childrenArray.map(child=>child===slottable?reactExports.Children.count(newElement)>1?reactExports.Children.only(null):reactExports.isValidElement(newElement)?newElement.props.children:null:child);return jsxRuntimeExports.jsx(SlotClone,{...slotProps,ref:forwardedRef,children:reactExports.isValidElement(newElement)?reactExports.cloneElement(newElement,void 0,newChildren):null})}return jsxRuntimeExports.jsx(SlotClone,{...slotProps,ref:forwardedRef,children:children2})});return Slot2.displayName=`${ownerName}.Slot`,Slot2}__name(createSlot$2,"createSlot$2");var Slot$1=createSlot$2("Slot");function createSlotClone$2(ownerName){const SlotClone=reactExports.forwardRef((props,forwardedRef)=>{let{children:children2,...slotProps}=props;if(isLazyComponent(children2)&&typeof use=="function"&&(children2=use(children2._payload)),reactExports.isValidElement(children2)){const childrenRef=getElementRef$2(children2),props2=mergeProps$2(slotProps,children2.props);return children2.type!==reactExports.Fragment&&(props2.ref=forwardedRef?composeRefs(forwardedRef,childrenRef):childrenRef),reactExports.cloneElement(children2,props2)}return reactExports.Children.count(children2)>1?reactExports.Children.only(null):null});return SlotClone.displayName=`${ownerName}.SlotClone`,SlotClone}__name(createSlotClone$2,"createSlotClone$2");var SLOTTABLE_IDENTIFIER$3=Symbol("radix.slottable");function isSlottable$2(child){return reactExports.isValidElement(child)&&typeof child.type=="function"&&"__radixId"in child.type&&child.type.__radixId===SLOTTABLE_IDENTIFIER$3}__name(isSlottable$2,"isSlottable$2");function mergeProps$2(slotProps,childProps){const overrideProps={...childProps};for(const propName in childProps){const slotPropValue=slotProps[propName],childPropValue=childProps[propName];/^on[A-Z]/.test(propName)?slotPropValue&&childPropValue?overrideProps[propName]=(...args)=>{const result=childPropValue(...args);return slotPropValue(...args),result}:slotPropValue&&(overrideProps[propName]=slotPropValue):propName==="style"?overrideProps[propName]={...slotPropValue,...childPropValue}:propName==="className"&&(overrideProps[propName]=[slotPropValue,childPropValue].filter(Boolean).join(" "))}return{...slotProps,...overrideProps}}__name(mergeProps$2,"mergeProps$2");function getElementRef$2(element2){let getter=Object.getOwnPropertyDescriptor(element2.props,"ref")?.get,mayWarn=getter&&"isReactWarning"in getter&&getter.isReactWarning;return mayWarn?element2.ref:(getter=Object.getOwnPropertyDescriptor(element2,"ref")?.get,mayWarn=getter&&"isReactWarning"in getter&&getter.isReactWarning,mayWarn?element2.props.ref:element2.props.ref||element2.ref)}__name(getElementRef$2,"getElementRef$2");const buttonVariants=cva("inline-flex items-center justify-center whitespace-nowrap rounded-md text-sm font-medium ring-offset-background transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50",{variants:{variant:{default:"bg-primary text-primary-foreground hover:bg-primary/90",destructive:"bg-destructive text-destructive-foreground hover:bg-destructive/90",outline:"border border-input bg-background hover:bg-accent hover:text-accent-foreground",secondary:"bg-secondary text-secondary-foreground hover:bg-secondary/80",ghost:"hover:bg-accent hover:text-accent-foreground",link:"text-primary underline-offset-4 hover:underline"},size:{default:"h-10 px-4 py-2",sm:"h-9 rounded-md px-3",lg:"h-11 rounded-md px-8",icon:"h-10 w-10"}},defaultVariants:{variant:"default",size:"default"}}),Button=reactExports.forwardRef(({className,variant,size:size2,asChild=!1,...props},ref)=>{const Comp=asChild?Slot$1:"button";return jsxRuntimeExports.jsx(Comp,{className:cn$2(buttonVariants({variant,size:size2,className})),ref,...props})});Button.displayName="Button";function createSlot$1(ownerName){const SlotClone=createSlotClone$1(ownerName),Slot2=reactExports.forwardRef((props,forwardedRef)=>{const{children:children2,...slotProps}=props,childrenArray=reactExports.Children.toArray(children2),slottable=childrenArray.find(isSlottable$1);if(slottable){const newElement=slottable.props.children,newChildren=childrenArray.map(child=>child===slottable?reactExports.Children.count(newElement)>1?reactExports.Children.only(null):reactExports.isValidElement(newElement)?newElement.props.children:null:child);return jsxRuntimeExports.jsx(SlotClone,{...slotProps,ref:forwardedRef,children:reactExports.isValidElement(newElement)?reactExports.cloneElement(newElement,void 0,newChildren):null})}return jsxRuntimeExports.jsx(SlotClone,{...slotProps,ref:forwardedRef,children:children2})});return Slot2.displayName=`${ownerName}.Slot`,Slot2}__name(createSlot$1,"createSlot$1");function createSlotClone$1(ownerName){const SlotClone=reactExports.forwardRef((props,forwardedRef)=>{const{children:children2,...slotProps}=props;if(reactExports.isValidElement(children2)){const childrenRef=getElementRef$1(children2),props2=mergeProps$1(slotProps,children2.props);return children2.type!==reactExports.Fragment&&(props2.ref=forwardedRef?composeRefs(forwardedRef,childrenRef):childrenRef),reactExports.cloneElement(children2,props2)}return reactExports.Children.count(children2)>1?reactExports.Children.only(null):null});return SlotClone.displayName=`${ownerName}.SlotClone`,SlotClone}__name(createSlotClone$1,"createSlotClone$1");var SLOTTABLE_IDENTIFIER$2=Symbol("radix.slottable");function isSlottable$1(child){return reactExports.isValidElement(child)&&typeof child.type=="function"&&"__radixId"in child.type&&child.type.__radixId===SLOTTABLE_IDENTIFIER$2}__name(isSlottable$1,"isSlottable$1");function mergeProps$1(slotProps,childProps){const overrideProps={...childProps};for(const propName in childProps){const slotPropValue=slotProps[propName],childPropValue=childProps[propName];/^on[A-Z]/.test(propName)?slotPropValue&&childPropValue?overrideProps[propName]=(...args)=>{const result=childPropValue(...args);return slotPropValue(...args),result}:slotPropValue&&(overrideProps[propName]=slotPropValue):propName==="style"?overrideProps[propName]={...slotPropValue,...childPropValue}:propName==="className"&&(overrideProps[propName]=[slotPropValue,childPropValue].filter(Boolean).join(" "))}return{...slotProps,...overrideProps}}__name(mergeProps$1,"mergeProps$1");function getElementRef$1(element2){let getter=Object.getOwnPropertyDescriptor(element2.props,"ref")?.get,mayWarn=getter&&"isReactWarning"in getter&&getter.isReactWarning;return mayWarn?element2.ref:(getter=Object.getOwnPropertyDescriptor(element2,"ref")?.get,mayWarn=getter&&"isReactWarning"in getter&&getter.isReactWarning,mayWarn?element2.props.ref:element2.props.ref||element2.ref)}__name(getElementRef$1,"getElementRef$1");function createCollection(name2){const PROVIDER_NAME2=name2+"CollectionProvider",[createCollectionContext,createCollectionScope2]=createContextScope$1(PROVIDER_NAME2),[CollectionProviderImpl,useCollectionContext]=createCollectionContext(PROVIDER_NAME2,{collectionRef:{current:null},itemMap:new Map}),CollectionProvider=__name(props=>{const{scope,children:children2}=props,ref=React.useRef(null),itemMap=React.useRef(new Map).current;return jsxRuntimeExports.jsx(CollectionProviderImpl,{scope,itemMap,collectionRef:ref,children:children2})},"CollectionProvider");CollectionProvider.displayName=PROVIDER_NAME2;const COLLECTION_SLOT_NAME=name2+"CollectionSlot",CollectionSlotImpl=createSlot$1(COLLECTION_SLOT_NAME),CollectionSlot=React.forwardRef((props,forwardedRef)=>{const{scope,children:children2}=props,context=useCollectionContext(COLLECTION_SLOT_NAME,scope),composedRefs=useComposedRefs(forwardedRef,context.collectionRef);return jsxRuntimeExports.jsx(CollectionSlotImpl,{ref:composedRefs,children:children2})});CollectionSlot.displayName=COLLECTION_SLOT_NAME;const ITEM_SLOT_NAME=name2+"CollectionItemSlot",ITEM_DATA_ATTR="data-radix-collection-item",CollectionItemSlotImpl=createSlot$1(ITEM_SLOT_NAME),CollectionItemSlot=React.forwardRef((props,forwardedRef)=>{const{scope,children:children2,...itemData}=props,ref=React.useRef(null),composedRefs=useComposedRefs(forwardedRef,ref),context=useCollectionContext(ITEM_SLOT_NAME,scope);return React.useEffect(()=>(context.itemMap.set(ref,{ref,...itemData}),()=>{context.itemMap.delete(ref)})),jsxRuntimeExports.jsx(CollectionItemSlotImpl,{[ITEM_DATA_ATTR]:"",ref:composedRefs,children:children2})});CollectionItemSlot.displayName=ITEM_SLOT_NAME;function useCollection2(scope){const context=useCollectionContext(name2+"CollectionConsumer",scope);return React.useCallback(()=>{const collectionNode=context.collectionRef.current;if(!collectionNode)return[];const orderedNodes=Array.from(collectionNode.querySelectorAll(`[${ITEM_DATA_ATTR}]`));return Array.from(context.itemMap.values()).sort((a2,b2)=>orderedNodes.indexOf(a2.ref.current)-orderedNodes.indexOf(b2.ref.current))},[context.collectionRef,context.itemMap])}return __name(useCollection2,"useCollection"),[{Provider:CollectionProvider,Slot:CollectionSlot,ItemSlot:CollectionItemSlot},useCollection2,createCollectionScope2]}__name(createCollection,"createCollection");var DirectionContext=reactExports.createContext(void 0);function useDirection(localDir){const globalDir=reactExports.useContext(DirectionContext);return localDir||globalDir||"ltr"}__name(useDirection,"useDirection");const sides=["top","right","bottom","left"],min$3=Math.min,max$3=Math.max,round$1=Math.round,floor=Math.floor,createCoords=__name(v2=>({x:v2,y:v2}),"createCoords"),oppositeSideMap={left:"right",right:"left",bottom:"top",top:"bottom"},oppositeAlignmentMap={start:"end",end:"start"};function clamp$1(start2,value2,end){return max$3(start2,min$3(value2,end))}__name(clamp$1,"clamp$1");function evaluate(value2,param){return typeof value2=="function"?value2(param):value2}__name(evaluate,"evaluate");function getSide(placement){return placement.split("-")[0]}__name(getSide,"getSide");function getAlignment(placement){return placement.split("-")[1]}__name(getAlignment,"getAlignment");function getOppositeAxis(axis){return axis==="x"?"y":"x"}__name(getOppositeAxis,"getOppositeAxis");function getAxisLength(axis){return axis==="y"?"height":"width"}__name(getAxisLength,"getAxisLength");const yAxisSides=new Set(["top","bottom"]);function getSideAxis(placement){return yAxisSides.has(getSide(placement))?"y":"x"}__name(getSideAxis,"getSideAxis");function getAlignmentAxis(placement){return getOppositeAxis(getSideAxis(placement))}__name(getAlignmentAxis,"getAlignmentAxis");function getAlignmentSides(placement,rects,rtl){rtl===void 0&&(rtl=!1);const alignment=getAlignment(placement),alignmentAxis=getAlignmentAxis(placement),length=getAxisLength(alignmentAxis);let mainAlignmentSide=alignmentAxis==="x"?alignment===(rtl?"end":"start")?"right":"left":alignment==="start"?"bottom":"top";return rects.reference[length]>rects.floating[length]&&(mainAlignmentSide=getOppositePlacement(mainAlignmentSide)),[mainAlignmentSide,getOppositePlacement(mainAlignmentSide)]}__name(getAlignmentSides,"getAlignmentSides");function getExpandedPlacements(placement){const oppositePlacement=getOppositePlacement(placement);return[getOppositeAlignmentPlacement(placement),oppositePlacement,getOppositeAlignmentPlacement(oppositePlacement)]}__name(getExpandedPlacements,"getExpandedPlacements");function getOppositeAlignmentPlacement(placement){return placement.replace(/start|end/g,alignment=>oppositeAlignmentMap[alignment])}__name(getOppositeAlignmentPlacement,"getOppositeAlignmentPlacement");const lrPlacement=["left","right"],rlPlacement=["right","left"],tbPlacement=["top","bottom"],btPlacement=["bottom","top"];function getSideList(side,isStart,rtl){switch(side){case"top":case"bottom":return rtl?isStart?rlPlacement:lrPlacement:isStart?lrPlacement:rlPlacement;case"left":case"right":return isStart?tbPlacement:btPlacement;default:return[]}}__name(getSideList,"getSideList");function getOppositeAxisPlacements(placement,flipAlignment,direction,rtl){const alignment=getAlignment(placement);let list2=getSideList(getSide(placement),direction==="start",rtl);return alignment&&(list2=list2.map(side=>side+"-"+alignment),flipAlignment&&(list2=list2.concat(list2.map(getOppositeAlignmentPlacement)))),list2}__name(getOppositeAxisPlacements,"getOppositeAxisPlacements");function getOppositePlacement(placement){return placement.replace(/left|right|bottom|top/g,side=>oppositeSideMap[side])}__name(getOppositePlacement,"getOppositePlacement");function expandPaddingObject(padding){return{top:0,right:0,bottom:0,left:0,...padding}}__name(expandPaddingObject,"expandPaddingObject");function getPaddingObject(padding){return typeof padding!="number"?expandPaddingObject(padding):{top:padding,right:padding,bottom:padding,left:padding}}__name(getPaddingObject,"getPaddingObject");function rectToClientRect(rect){const{x:x2,y:y2,width,height}=rect;return{width,height,top:y2,left:x2,right:x2+width,bottom:y2+height,x:x2,y:y2}}__name(rectToClientRect,"rectToClientRect");function computeCoordsFromPlacement(_ref,placement,rtl){let{reference,floating}=_ref;const sideAxis=getSideAxis(placement),alignmentAxis=getAlignmentAxis(placement),alignLength=getAxisLength(alignmentAxis),side=getSide(placement),isVertical=sideAxis==="y",commonX=reference.x+reference.width/2-floating.width/2,commonY=reference.y+reference.height/2-floating.height/2,commonAlign=reference[alignLength]/2-floating[alignLength]/2;let coords;switch(side){case"top":coords={x:commonX,y:reference.y-floating.height};break;case"bottom":coords={x:commonX,y:reference.y+reference.height};break;case"right":coords={x:reference.x+reference.width,y:commonY};break;case"left":coords={x:reference.x-floating.width,y:commonY};break;default:coords={x:reference.x,y:reference.y}}switch(getAlignment(placement)){case"start":coords[alignmentAxis]-=commonAlign*(rtl&&isVertical?-1:1);break;case"end":coords[alignmentAxis]+=commonAlign*(rtl&&isVertical?-1:1);break}return coords}__name(computeCoordsFromPlacement,"computeCoordsFromPlacement");const computePosition$1=__name(async(reference,floating,config2)=>{const{placement="bottom",strategy="absolute",middleware=[],platform:platform2}=config2,validMiddleware=middleware.filter(Boolean),rtl=await(platform2.isRTL==null?void 0:platform2.isRTL(floating));let rects=await platform2.getElementRects({reference,floating,strategy}),{x:x2,y:y2}=computeCoordsFromPlacement(rects,placement,rtl),statefulPlacement=placement,middlewareData={},resetCount=0;for(let i2=0;i2({name:"arrow",options,async fn(state){const{x:x2,y:y2,placement,rects,platform:platform2,elements,middlewareData}=state,{element:element2,padding=0}=evaluate(options,state)||{};if(element2==null)return{};const paddingObject=getPaddingObject(padding),coords={x:x2,y:y2},axis=getAlignmentAxis(placement),length=getAxisLength(axis),arrowDimensions=await platform2.getDimensions(element2),isYAxis=axis==="y",minProp=isYAxis?"top":"left",maxProp=isYAxis?"bottom":"right",clientProp=isYAxis?"clientHeight":"clientWidth",endDiff=rects.reference[length]+rects.reference[axis]-coords[axis]-rects.floating[length],startDiff=coords[axis]-rects.reference[axis],arrowOffsetParent=await(platform2.getOffsetParent==null?void 0:platform2.getOffsetParent(element2));let clientSize=arrowOffsetParent?arrowOffsetParent[clientProp]:0;(!clientSize||!await(platform2.isElement==null?void 0:platform2.isElement(arrowOffsetParent)))&&(clientSize=elements.floating[clientProp]||rects.floating[length]);const centerToReference=endDiff/2-startDiff/2,largestPossiblePadding=clientSize/2-arrowDimensions[length]/2-1,minPadding=min$3(paddingObject[minProp],largestPossiblePadding),maxPadding=min$3(paddingObject[maxProp],largestPossiblePadding),min$12=minPadding,max2=clientSize-arrowDimensions[length]-maxPadding,center2=clientSize/2-arrowDimensions[length]/2+centerToReference,offset2=clamp$1(min$12,center2,max2),shouldAddOffset=!middlewareData.arrow&&getAlignment(placement)!=null&¢er2!==offset2&&rects.reference[length]/2-(center2side2<=0)){var _middlewareData$flip2,_overflowsData$filter;const nextIndex=(((_middlewareData$flip2=middlewareData.flip)==null?void 0:_middlewareData$flip2.index)||0)+1,nextPlacement=placements[nextIndex];if(nextPlacement&&(!(checkCrossAxis==="alignment"?initialSideAxis!==getSideAxis(nextPlacement):!1)||overflowsData.every(d=>getSideAxis(d.placement)===initialSideAxis?d.overflows[0]>0:!0)))return{data:{index:nextIndex,overflows:overflowsData},reset:{placement:nextPlacement}};let resetPlacement=(_overflowsData$filter=overflowsData.filter(d=>d.overflows[0]<=0).sort((a2,b2)=>a2.overflows[1]-b2.overflows[1])[0])==null?void 0:_overflowsData$filter.placement;if(!resetPlacement)switch(fallbackStrategy){case"bestFit":{var _overflowsData$filter2;const placement2=(_overflowsData$filter2=overflowsData.filter(d=>{if(hasFallbackAxisSideDirection){const currentSideAxis=getSideAxis(d.placement);return currentSideAxis===initialSideAxis||currentSideAxis==="y"}return!0}).map(d=>[d.placement,d.overflows.filter(overflow2=>overflow2>0).reduce((acc,overflow2)=>acc+overflow2,0)]).sort((a2,b2)=>a2[1]-b2[1])[0])==null?void 0:_overflowsData$filter2[0];placement2&&(resetPlacement=placement2);break}case"initialPlacement":resetPlacement=initialPlacement;break}if(placement!==resetPlacement)return{reset:{placement:resetPlacement}}}return{}}}},"flip$2");function getSideOffsets(overflow,rect){return{top:overflow.top-rect.height,right:overflow.right-rect.width,bottom:overflow.bottom-rect.height,left:overflow.left-rect.width}}__name(getSideOffsets,"getSideOffsets");function isAnySideFullyClipped(overflow){return sides.some(side=>overflow[side]>=0)}__name(isAnySideFullyClipped,"isAnySideFullyClipped");const hide$2=__name(function(options){return options===void 0&&(options={}),{name:"hide",options,async fn(state){const{rects}=state,{strategy="referenceHidden",...detectOverflowOptions}=evaluate(options,state);switch(strategy){case"referenceHidden":{const overflow=await detectOverflow(state,{...detectOverflowOptions,elementContext:"reference"}),offsets=getSideOffsets(overflow,rects.reference);return{data:{referenceHiddenOffsets:offsets,referenceHidden:isAnySideFullyClipped(offsets)}}}case"escaped":{const overflow=await detectOverflow(state,{...detectOverflowOptions,altBoundary:!0}),offsets=getSideOffsets(overflow,rects.floating);return{data:{escapedOffsets:offsets,escaped:isAnySideFullyClipped(offsets)}}}default:return{}}}}},"hide$2"),originSides=new Set(["left","top"]);async function convertValueToCoords(state,options){const{placement,platform:platform2,elements}=state,rtl=await(platform2.isRTL==null?void 0:platform2.isRTL(elements.floating)),side=getSide(placement),alignment=getAlignment(placement),isVertical=getSideAxis(placement)==="y",mainAxisMulti=originSides.has(side)?-1:1,crossAxisMulti=rtl&&isVertical?-1:1,rawValue=evaluate(options,state);let{mainAxis,crossAxis,alignmentAxis}=typeof rawValue=="number"?{mainAxis:rawValue,crossAxis:0,alignmentAxis:null}:{mainAxis:rawValue.mainAxis||0,crossAxis:rawValue.crossAxis||0,alignmentAxis:rawValue.alignmentAxis};return alignment&&typeof alignmentAxis=="number"&&(crossAxis=alignment==="end"?alignmentAxis*-1:alignmentAxis),isVertical?{x:crossAxis*crossAxisMulti,y:mainAxis*mainAxisMulti}:{x:mainAxis*mainAxisMulti,y:crossAxis*crossAxisMulti}}__name(convertValueToCoords,"convertValueToCoords");const offset$2=__name(function(options){return options===void 0&&(options=0),{name:"offset",options,async fn(state){var _middlewareData$offse,_middlewareData$arrow;const{x:x2,y:y2,placement,middlewareData}=state,diffCoords=await convertValueToCoords(state,options);return placement===((_middlewareData$offse=middlewareData.offset)==null?void 0:_middlewareData$offse.placement)&&(_middlewareData$arrow=middlewareData.arrow)!=null&&_middlewareData$arrow.alignmentOffset?{}:{x:x2+diffCoords.x,y:y2+diffCoords.y,data:{...diffCoords,placement}}}}},"offset$2"),shift$2=__name(function(options){return options===void 0&&(options={}),{name:"shift",options,async fn(state){const{x:x2,y:y2,placement}=state,{mainAxis:checkMainAxis=!0,crossAxis:checkCrossAxis=!1,limiter={fn:__name(_ref=>{let{x:x3,y:y3}=_ref;return{x:x3,y:y3}},"fn")},...detectOverflowOptions}=evaluate(options,state),coords={x:x2,y:y2},overflow=await detectOverflow(state,detectOverflowOptions),crossAxis=getSideAxis(getSide(placement)),mainAxis=getOppositeAxis(crossAxis);let mainAxisCoord=coords[mainAxis],crossAxisCoord=coords[crossAxis];if(checkMainAxis){const minSide=mainAxis==="y"?"top":"left",maxSide=mainAxis==="y"?"bottom":"right",min2=mainAxisCoord+overflow[minSide],max2=mainAxisCoord-overflow[maxSide];mainAxisCoord=clamp$1(min2,mainAxisCoord,max2)}if(checkCrossAxis){const minSide=crossAxis==="y"?"top":"left",maxSide=crossAxis==="y"?"bottom":"right",min2=crossAxisCoord+overflow[minSide],max2=crossAxisCoord-overflow[maxSide];crossAxisCoord=clamp$1(min2,crossAxisCoord,max2)}const limitedCoords=limiter.fn({...state,[mainAxis]:mainAxisCoord,[crossAxis]:crossAxisCoord});return{...limitedCoords,data:{x:limitedCoords.x-x2,y:limitedCoords.y-y2,enabled:{[mainAxis]:checkMainAxis,[crossAxis]:checkCrossAxis}}}}}},"shift$2"),limitShift$2=__name(function(options){return options===void 0&&(options={}),{options,fn(state){const{x:x2,y:y2,placement,rects,middlewareData}=state,{offset:offset2=0,mainAxis:checkMainAxis=!0,crossAxis:checkCrossAxis=!0}=evaluate(options,state),coords={x:x2,y:y2},crossAxis=getSideAxis(placement),mainAxis=getOppositeAxis(crossAxis);let mainAxisCoord=coords[mainAxis],crossAxisCoord=coords[crossAxis];const rawOffset=evaluate(offset2,state),computedOffset=typeof rawOffset=="number"?{mainAxis:rawOffset,crossAxis:0}:{mainAxis:0,crossAxis:0,...rawOffset};if(checkMainAxis){const len=mainAxis==="y"?"height":"width",limitMin=rects.reference[mainAxis]-rects.floating[len]+computedOffset.mainAxis,limitMax=rects.reference[mainAxis]+rects.reference[len]-computedOffset.mainAxis;mainAxisCoordlimitMax&&(mainAxisCoord=limitMax)}if(checkCrossAxis){var _middlewareData$offse,_middlewareData$offse2;const len=mainAxis==="y"?"width":"height",isOriginSide=originSides.has(getSide(placement)),limitMin=rects.reference[crossAxis]-rects.floating[len]+(isOriginSide&&((_middlewareData$offse=middlewareData.offset)==null?void 0:_middlewareData$offse[crossAxis])||0)+(isOriginSide?0:computedOffset.crossAxis),limitMax=rects.reference[crossAxis]+rects.reference[len]+(isOriginSide?0:((_middlewareData$offse2=middlewareData.offset)==null?void 0:_middlewareData$offse2[crossAxis])||0)-(isOriginSide?computedOffset.crossAxis:0);crossAxisCoordlimitMax&&(crossAxisCoord=limitMax)}return{[mainAxis]:mainAxisCoord,[crossAxis]:crossAxisCoord}}}},"limitShift$2"),size$2=__name(function(options){return options===void 0&&(options={}),{name:"size",options,async fn(state){var _state$middlewareData,_state$middlewareData2;const{placement,rects,platform:platform2,elements}=state,{apply=__name(()=>{},"apply"),...detectOverflowOptions}=evaluate(options,state),overflow=await detectOverflow(state,detectOverflowOptions),side=getSide(placement),alignment=getAlignment(placement),isYAxis=getSideAxis(placement)==="y",{width,height}=rects.floating;let heightSide,widthSide;side==="top"||side==="bottom"?(heightSide=side,widthSide=alignment===(await(platform2.isRTL==null?void 0:platform2.isRTL(elements.floating))?"start":"end")?"left":"right"):(widthSide=side,heightSide=alignment==="end"?"top":"bottom");const maximumClippingHeight=height-overflow.top-overflow.bottom,maximumClippingWidth=width-overflow.left-overflow.right,overflowAvailableHeight=min$3(height-overflow[heightSide],maximumClippingHeight),overflowAvailableWidth=min$3(width-overflow[widthSide],maximumClippingWidth),noShift=!state.middlewareData.shift;let availableHeight=overflowAvailableHeight,availableWidth=overflowAvailableWidth;if((_state$middlewareData=state.middlewareData.shift)!=null&&_state$middlewareData.enabled.x&&(availableWidth=maximumClippingWidth),(_state$middlewareData2=state.middlewareData.shift)!=null&&_state$middlewareData2.enabled.y&&(availableHeight=maximumClippingHeight),noShift&&!alignment){const xMin=max$3(overflow.left,0),xMax=max$3(overflow.right,0),yMin=max$3(overflow.top,0),yMax=max$3(overflow.bottom,0);isYAxis?availableWidth=width-2*(xMin!==0||xMax!==0?xMin+xMax:max$3(overflow.left,overflow.right)):availableHeight=height-2*(yMin!==0||yMax!==0?yMin+yMax:max$3(overflow.top,overflow.bottom))}await apply({...state,availableWidth,availableHeight});const nextDimensions=await platform2.getDimensions(elements.floating);return width!==nextDimensions.width||height!==nextDimensions.height?{reset:{rects:!0}}:{}}}},"size$2");function hasWindow(){return typeof window<"u"}__name(hasWindow,"hasWindow");function getNodeName(node2){return isNode(node2)?(node2.nodeName||"").toLowerCase():"#document"}__name(getNodeName,"getNodeName");function getWindow(node2){var _node$ownerDocument;return(node2==null||(_node$ownerDocument=node2.ownerDocument)==null?void 0:_node$ownerDocument.defaultView)||window}__name(getWindow,"getWindow");function getDocumentElement(node2){var _ref;return(_ref=(isNode(node2)?node2.ownerDocument:node2.document)||window.document)==null?void 0:_ref.documentElement}__name(getDocumentElement,"getDocumentElement");function isNode(value2){return hasWindow()?value2 instanceof Node||value2 instanceof getWindow(value2).Node:!1}__name(isNode,"isNode");function isElement(value2){return hasWindow()?value2 instanceof Element||value2 instanceof getWindow(value2).Element:!1}__name(isElement,"isElement");function isHTMLElement(value2){return hasWindow()?value2 instanceof HTMLElement||value2 instanceof getWindow(value2).HTMLElement:!1}__name(isHTMLElement,"isHTMLElement");function isShadowRoot(value2){return!hasWindow()||typeof ShadowRoot>"u"?!1:value2 instanceof ShadowRoot||value2 instanceof getWindow(value2).ShadowRoot}__name(isShadowRoot,"isShadowRoot");const invalidOverflowDisplayValues=new Set(["inline","contents"]);function isOverflowElement(element2){const{overflow,overflowX,overflowY,display}=getComputedStyle$1(element2);return/auto|scroll|overlay|hidden|clip/.test(overflow+overflowY+overflowX)&&!invalidOverflowDisplayValues.has(display)}__name(isOverflowElement,"isOverflowElement");const tableElements$1=new Set(["table","td","th"]);function isTableElement(element2){return tableElements$1.has(getNodeName(element2))}__name(isTableElement,"isTableElement");const topLayerSelectors=[":popover-open",":modal"];function isTopLayer(element2){return topLayerSelectors.some(selector=>{try{return element2.matches(selector)}catch{return!1}})}__name(isTopLayer,"isTopLayer");const transformProperties=["transform","translate","scale","rotate","perspective"],willChangeValues=["transform","translate","scale","rotate","perspective","filter"],containValues=["paint","layout","strict","content"];function isContainingBlock(elementOrCss){const webkit=isWebKit(),css=isElement(elementOrCss)?getComputedStyle$1(elementOrCss):elementOrCss;return transformProperties.some(value2=>css[value2]?css[value2]!=="none":!1)||(css.containerType?css.containerType!=="normal":!1)||!webkit&&(css.backdropFilter?css.backdropFilter!=="none":!1)||!webkit&&(css.filter?css.filter!=="none":!1)||willChangeValues.some(value2=>(css.willChange||"").includes(value2))||containValues.some(value2=>(css.contain||"").includes(value2))}__name(isContainingBlock,"isContainingBlock");function getContainingBlock(element2){let currentNode=getParentNode(element2);for(;isHTMLElement(currentNode)&&!isLastTraversableNode(currentNode);){if(isContainingBlock(currentNode))return currentNode;if(isTopLayer(currentNode))return null;currentNode=getParentNode(currentNode)}return null}__name(getContainingBlock,"getContainingBlock");function isWebKit(){return typeof CSS>"u"||!CSS.supports?!1:CSS.supports("-webkit-backdrop-filter","none")}__name(isWebKit,"isWebKit");const lastTraversableNodeNames=new Set(["html","body","#document"]);function isLastTraversableNode(node2){return lastTraversableNodeNames.has(getNodeName(node2))}__name(isLastTraversableNode,"isLastTraversableNode");function getComputedStyle$1(element2){return getWindow(element2).getComputedStyle(element2)}__name(getComputedStyle$1,"getComputedStyle$1");function getNodeScroll(element2){return isElement(element2)?{scrollLeft:element2.scrollLeft,scrollTop:element2.scrollTop}:{scrollLeft:element2.scrollX,scrollTop:element2.scrollY}}__name(getNodeScroll,"getNodeScroll");function getParentNode(node2){if(getNodeName(node2)==="html")return node2;const result=node2.assignedSlot||node2.parentNode||isShadowRoot(node2)&&node2.host||getDocumentElement(node2);return isShadowRoot(result)?result.host:result}__name(getParentNode,"getParentNode");function getNearestOverflowAncestor(node2){const parentNode=getParentNode(node2);return isLastTraversableNode(parentNode)?node2.ownerDocument?node2.ownerDocument.body:node2.body:isHTMLElement(parentNode)&&isOverflowElement(parentNode)?parentNode:getNearestOverflowAncestor(parentNode)}__name(getNearestOverflowAncestor,"getNearestOverflowAncestor");function getOverflowAncestors(node2,list2,traverseIframes){var _node$ownerDocument2;list2===void 0&&(list2=[]),traverseIframes===void 0&&(traverseIframes=!0);const scrollableAncestor=getNearestOverflowAncestor(node2),isBody=scrollableAncestor===((_node$ownerDocument2=node2.ownerDocument)==null?void 0:_node$ownerDocument2.body),win=getWindow(scrollableAncestor);if(isBody){const frameElement=getFrameElement(win);return list2.concat(win,win.visualViewport||[],isOverflowElement(scrollableAncestor)?scrollableAncestor:[],frameElement&&traverseIframes?getOverflowAncestors(frameElement):[])}return list2.concat(scrollableAncestor,getOverflowAncestors(scrollableAncestor,[],traverseIframes))}__name(getOverflowAncestors,"getOverflowAncestors");function getFrameElement(win){return win.parent&&Object.getPrototypeOf(win.parent)?win.frameElement:null}__name(getFrameElement,"getFrameElement");function getCssDimensions(element2){const css=getComputedStyle$1(element2);let width=parseFloat(css.width)||0,height=parseFloat(css.height)||0;const hasOffset=isHTMLElement(element2),offsetWidth=hasOffset?element2.offsetWidth:width,offsetHeight=hasOffset?element2.offsetHeight:height,shouldFallback=round$1(width)!==offsetWidth||round$1(height)!==offsetHeight;return shouldFallback&&(width=offsetWidth,height=offsetHeight),{width,height,$:shouldFallback}}__name(getCssDimensions,"getCssDimensions");function unwrapElement(element2){return isElement(element2)?element2:element2.contextElement}__name(unwrapElement,"unwrapElement");function getScale(element2){const domElement=unwrapElement(element2);if(!isHTMLElement(domElement))return createCoords(1);const rect=domElement.getBoundingClientRect(),{width,height,$:$2}=getCssDimensions(domElement);let x2=($2?round$1(rect.width):rect.width)/width,y2=($2?round$1(rect.height):rect.height)/height;return(!x2||!Number.isFinite(x2))&&(x2=1),(!y2||!Number.isFinite(y2))&&(y2=1),{x:x2,y:y2}}__name(getScale,"getScale");const noOffsets=createCoords(0);function getVisualOffsets(element2){const win=getWindow(element2);return!isWebKit()||!win.visualViewport?noOffsets:{x:win.visualViewport.offsetLeft,y:win.visualViewport.offsetTop}}__name(getVisualOffsets,"getVisualOffsets");function shouldAddVisualOffsets(element2,isFixed,floatingOffsetParent){return isFixed===void 0&&(isFixed=!1),!floatingOffsetParent||isFixed&&floatingOffsetParent!==getWindow(element2)?!1:isFixed}__name(shouldAddVisualOffsets,"shouldAddVisualOffsets");function getBoundingClientRect(element2,includeScale,isFixedStrategy,offsetParent){includeScale===void 0&&(includeScale=!1),isFixedStrategy===void 0&&(isFixedStrategy=!1);const clientRect=element2.getBoundingClientRect(),domElement=unwrapElement(element2);let scale=createCoords(1);includeScale&&(offsetParent?isElement(offsetParent)&&(scale=getScale(offsetParent)):scale=getScale(element2));const visualOffsets=shouldAddVisualOffsets(domElement,isFixedStrategy,offsetParent)?getVisualOffsets(domElement):createCoords(0);let x2=(clientRect.left+visualOffsets.x)/scale.x,y2=(clientRect.top+visualOffsets.y)/scale.y,width=clientRect.width/scale.x,height=clientRect.height/scale.y;if(domElement){const win=getWindow(domElement),offsetWin=offsetParent&&isElement(offsetParent)?getWindow(offsetParent):offsetParent;let currentWin=win,currentIFrame=getFrameElement(currentWin);for(;currentIFrame&&offsetParent&&offsetWin!==currentWin;){const iframeScale=getScale(currentIFrame),iframeRect=currentIFrame.getBoundingClientRect(),css=getComputedStyle$1(currentIFrame),left2=iframeRect.left+(currentIFrame.clientLeft+parseFloat(css.paddingLeft))*iframeScale.x,top=iframeRect.top+(currentIFrame.clientTop+parseFloat(css.paddingTop))*iframeScale.y;x2*=iframeScale.x,y2*=iframeScale.y,width*=iframeScale.x,height*=iframeScale.y,x2+=left2,y2+=top,currentWin=getWindow(currentIFrame),currentIFrame=getFrameElement(currentWin)}}return rectToClientRect({width,height,x:x2,y:y2})}__name(getBoundingClientRect,"getBoundingClientRect");function getWindowScrollBarX(element2,rect){const leftScroll=getNodeScroll(element2).scrollLeft;return rect?rect.left+leftScroll:getBoundingClientRect(getDocumentElement(element2)).left+leftScroll}__name(getWindowScrollBarX,"getWindowScrollBarX");function getHTMLOffset(documentElement,scroll){const htmlRect=documentElement.getBoundingClientRect(),x2=htmlRect.left+scroll.scrollLeft-getWindowScrollBarX(documentElement,htmlRect),y2=htmlRect.top+scroll.scrollTop;return{x:x2,y:y2}}__name(getHTMLOffset,"getHTMLOffset");function convertOffsetParentRelativeRectToViewportRelativeRect(_ref){let{elements,rect,offsetParent,strategy}=_ref;const isFixed=strategy==="fixed",documentElement=getDocumentElement(offsetParent),topLayer=elements?isTopLayer(elements.floating):!1;if(offsetParent===documentElement||topLayer&&isFixed)return rect;let scroll={scrollLeft:0,scrollTop:0},scale=createCoords(1);const offsets=createCoords(0),isOffsetParentAnElement=isHTMLElement(offsetParent);if((isOffsetParentAnElement||!isOffsetParentAnElement&&!isFixed)&&((getNodeName(offsetParent)!=="body"||isOverflowElement(documentElement))&&(scroll=getNodeScroll(offsetParent)),isHTMLElement(offsetParent))){const offsetRect=getBoundingClientRect(offsetParent);scale=getScale(offsetParent),offsets.x=offsetRect.x+offsetParent.clientLeft,offsets.y=offsetRect.y+offsetParent.clientTop}const htmlOffset=documentElement&&!isOffsetParentAnElement&&!isFixed?getHTMLOffset(documentElement,scroll):createCoords(0);return{width:rect.width*scale.x,height:rect.height*scale.y,x:rect.x*scale.x-scroll.scrollLeft*scale.x+offsets.x+htmlOffset.x,y:rect.y*scale.y-scroll.scrollTop*scale.y+offsets.y+htmlOffset.y}}__name(convertOffsetParentRelativeRectToViewportRelativeRect,"convertOffsetParentRelativeRectToViewportRelativeRect");function getClientRects(element2){return Array.from(element2.getClientRects())}__name(getClientRects,"getClientRects");function getDocumentRect(element2){const html2=getDocumentElement(element2),scroll=getNodeScroll(element2),body=element2.ownerDocument.body,width=max$3(html2.scrollWidth,html2.clientWidth,body.scrollWidth,body.clientWidth),height=max$3(html2.scrollHeight,html2.clientHeight,body.scrollHeight,body.clientHeight);let x2=-scroll.scrollLeft+getWindowScrollBarX(element2);const y2=-scroll.scrollTop;return getComputedStyle$1(body).direction==="rtl"&&(x2+=max$3(html2.clientWidth,body.clientWidth)-width),{width,height,x:x2,y:y2}}__name(getDocumentRect,"getDocumentRect");const SCROLLBAR_MAX=25;function getViewportRect(element2,strategy){const win=getWindow(element2),html2=getDocumentElement(element2),visualViewport=win.visualViewport;let width=html2.clientWidth,height=html2.clientHeight,x2=0,y2=0;if(visualViewport){width=visualViewport.width,height=visualViewport.height;const visualViewportBased=isWebKit();(!visualViewportBased||visualViewportBased&&strategy==="fixed")&&(x2=visualViewport.offsetLeft,y2=visualViewport.offsetTop)}const windowScrollbarX=getWindowScrollBarX(html2);if(windowScrollbarX<=0){const doc=html2.ownerDocument,body=doc.body,bodyStyles=getComputedStyle(body),bodyMarginInline=doc.compatMode==="CSS1Compat"&&parseFloat(bodyStyles.marginLeft)+parseFloat(bodyStyles.marginRight)||0,clippingStableScrollbarWidth=Math.abs(html2.clientWidth-body.clientWidth-bodyMarginInline);clippingStableScrollbarWidth<=SCROLLBAR_MAX&&(width-=clippingStableScrollbarWidth)}else windowScrollbarX<=SCROLLBAR_MAX&&(width+=windowScrollbarX);return{width,height,x:x2,y:y2}}__name(getViewportRect,"getViewportRect");const absoluteOrFixed=new Set(["absolute","fixed"]);function getInnerBoundingClientRect(element2,strategy){const clientRect=getBoundingClientRect(element2,!0,strategy==="fixed"),top=clientRect.top+element2.clientTop,left2=clientRect.left+element2.clientLeft,scale=isHTMLElement(element2)?getScale(element2):createCoords(1),width=element2.clientWidth*scale.x,height=element2.clientHeight*scale.y,x2=left2*scale.x,y2=top*scale.y;return{width,height,x:x2,y:y2}}__name(getInnerBoundingClientRect,"getInnerBoundingClientRect");function getClientRectFromClippingAncestor(element2,clippingAncestor,strategy){let rect;if(clippingAncestor==="viewport")rect=getViewportRect(element2,strategy);else if(clippingAncestor==="document")rect=getDocumentRect(getDocumentElement(element2));else if(isElement(clippingAncestor))rect=getInnerBoundingClientRect(clippingAncestor,strategy);else{const visualOffsets=getVisualOffsets(element2);rect={x:clippingAncestor.x-visualOffsets.x,y:clippingAncestor.y-visualOffsets.y,width:clippingAncestor.width,height:clippingAncestor.height}}return rectToClientRect(rect)}__name(getClientRectFromClippingAncestor,"getClientRectFromClippingAncestor");function hasFixedPositionAncestor(element2,stopNode){const parentNode=getParentNode(element2);return parentNode===stopNode||!isElement(parentNode)||isLastTraversableNode(parentNode)?!1:getComputedStyle$1(parentNode).position==="fixed"||hasFixedPositionAncestor(parentNode,stopNode)}__name(hasFixedPositionAncestor,"hasFixedPositionAncestor");function getClippingElementAncestors(element2,cache){const cachedResult=cache.get(element2);if(cachedResult)return cachedResult;let result=getOverflowAncestors(element2,[],!1).filter(el=>isElement(el)&&getNodeName(el)!=="body"),currentContainingBlockComputedStyle=null;const elementIsFixed=getComputedStyle$1(element2).position==="fixed";let currentNode=elementIsFixed?getParentNode(element2):element2;for(;isElement(currentNode)&&!isLastTraversableNode(currentNode);){const computedStyle=getComputedStyle$1(currentNode),currentNodeIsContaining=isContainingBlock(currentNode);!currentNodeIsContaining&&computedStyle.position==="fixed"&&(currentContainingBlockComputedStyle=null),(elementIsFixed?!currentNodeIsContaining&&!currentContainingBlockComputedStyle:!currentNodeIsContaining&&computedStyle.position==="static"&&!!currentContainingBlockComputedStyle&&absoluteOrFixed.has(currentContainingBlockComputedStyle.position)||isOverflowElement(currentNode)&&!currentNodeIsContaining&&hasFixedPositionAncestor(element2,currentNode))?result=result.filter(ancestor=>ancestor!==currentNode):currentContainingBlockComputedStyle=computedStyle,currentNode=getParentNode(currentNode)}return cache.set(element2,result),result}__name(getClippingElementAncestors,"getClippingElementAncestors");function getClippingRect(_ref){let{element:element2,boundary,rootBoundary,strategy}=_ref;const clippingAncestors=[...boundary==="clippingAncestors"?isTopLayer(element2)?[]:getClippingElementAncestors(element2,this._c):[].concat(boundary),rootBoundary],firstClippingAncestor=clippingAncestors[0],clippingRect=clippingAncestors.reduce((accRect,clippingAncestor)=>{const rect=getClientRectFromClippingAncestor(element2,clippingAncestor,strategy);return accRect.top=max$3(rect.top,accRect.top),accRect.right=min$3(rect.right,accRect.right),accRect.bottom=min$3(rect.bottom,accRect.bottom),accRect.left=max$3(rect.left,accRect.left),accRect},getClientRectFromClippingAncestor(element2,firstClippingAncestor,strategy));return{width:clippingRect.right-clippingRect.left,height:clippingRect.bottom-clippingRect.top,x:clippingRect.left,y:clippingRect.top}}__name(getClippingRect,"getClippingRect");function getDimensions(element2){const{width,height}=getCssDimensions(element2);return{width,height}}__name(getDimensions,"getDimensions");function getRectRelativeToOffsetParent(element2,offsetParent,strategy){const isOffsetParentAnElement=isHTMLElement(offsetParent),documentElement=getDocumentElement(offsetParent),isFixed=strategy==="fixed",rect=getBoundingClientRect(element2,!0,isFixed,offsetParent);let scroll={scrollLeft:0,scrollTop:0};const offsets=createCoords(0);function setLeftRTLScrollbarOffset(){offsets.x=getWindowScrollBarX(documentElement)}if(__name(setLeftRTLScrollbarOffset,"setLeftRTLScrollbarOffset"),isOffsetParentAnElement||!isOffsetParentAnElement&&!isFixed)if((getNodeName(offsetParent)!=="body"||isOverflowElement(documentElement))&&(scroll=getNodeScroll(offsetParent)),isOffsetParentAnElement){const offsetRect=getBoundingClientRect(offsetParent,!0,isFixed,offsetParent);offsets.x=offsetRect.x+offsetParent.clientLeft,offsets.y=offsetRect.y+offsetParent.clientTop}else documentElement&&setLeftRTLScrollbarOffset();isFixed&&!isOffsetParentAnElement&&documentElement&&setLeftRTLScrollbarOffset();const htmlOffset=documentElement&&!isOffsetParentAnElement&&!isFixed?getHTMLOffset(documentElement,scroll):createCoords(0),x2=rect.left+scroll.scrollLeft-offsets.x-htmlOffset.x,y2=rect.top+scroll.scrollTop-offsets.y-htmlOffset.y;return{x:x2,y:y2,width:rect.width,height:rect.height}}__name(getRectRelativeToOffsetParent,"getRectRelativeToOffsetParent");function isStaticPositioned(element2){return getComputedStyle$1(element2).position==="static"}__name(isStaticPositioned,"isStaticPositioned");function getTrueOffsetParent(element2,polyfill2){if(!isHTMLElement(element2)||getComputedStyle$1(element2).position==="fixed")return null;if(polyfill2)return polyfill2(element2);let rawOffsetParent=element2.offsetParent;return getDocumentElement(element2)===rawOffsetParent&&(rawOffsetParent=rawOffsetParent.ownerDocument.body),rawOffsetParent}__name(getTrueOffsetParent,"getTrueOffsetParent");function getOffsetParent(element2,polyfill2){const win=getWindow(element2);if(isTopLayer(element2))return win;if(!isHTMLElement(element2)){let svgOffsetParent=getParentNode(element2);for(;svgOffsetParent&&!isLastTraversableNode(svgOffsetParent);){if(isElement(svgOffsetParent)&&!isStaticPositioned(svgOffsetParent))return svgOffsetParent;svgOffsetParent=getParentNode(svgOffsetParent)}return win}let offsetParent=getTrueOffsetParent(element2,polyfill2);for(;offsetParent&&isTableElement(offsetParent)&&isStaticPositioned(offsetParent);)offsetParent=getTrueOffsetParent(offsetParent,polyfill2);return offsetParent&&isLastTraversableNode(offsetParent)&&isStaticPositioned(offsetParent)&&!isContainingBlock(offsetParent)?win:offsetParent||getContainingBlock(element2)||win}__name(getOffsetParent,"getOffsetParent");const getElementRects=__name(async function(data){const getOffsetParentFn=this.getOffsetParent||getOffsetParent,getDimensionsFn=this.getDimensions,floatingDimensions=await getDimensionsFn(data.floating);return{reference:getRectRelativeToOffsetParent(data.reference,await getOffsetParentFn(data.floating),data.strategy),floating:{x:0,y:0,width:floatingDimensions.width,height:floatingDimensions.height}}},"getElementRects");function isRTL(element2){return getComputedStyle$1(element2).direction==="rtl"}__name(isRTL,"isRTL");const platform={convertOffsetParentRelativeRectToViewportRelativeRect,getDocumentElement,getClippingRect,getOffsetParent,getElementRects,getClientRects,getDimensions,getScale,isElement,isRTL};function rectsAreEqual(a2,b2){return a2.x===b2.x&&a2.y===b2.y&&a2.width===b2.width&&a2.height===b2.height}__name(rectsAreEqual,"rectsAreEqual");function observeMove(element2,onMove){let io=null,timeoutId;const root2=getDocumentElement(element2);function cleanup(){var _io;clearTimeout(timeoutId),(_io=io)==null||_io.disconnect(),io=null}__name(cleanup,"cleanup");function refresh(skip,threshold2){skip===void 0&&(skip=!1),threshold2===void 0&&(threshold2=1),cleanup();const elementRectForRootMargin=element2.getBoundingClientRect(),{left:left2,top,width,height}=elementRectForRootMargin;if(skip||onMove(),!width||!height)return;const insetTop=floor(top),insetRight=floor(root2.clientWidth-(left2+width)),insetBottom=floor(root2.clientHeight-(top+height)),insetLeft=floor(left2),options={rootMargin:-insetTop+"px "+-insetRight+"px "+-insetBottom+"px "+-insetLeft+"px",threshold:max$3(0,min$3(1,threshold2))||1};let isFirstUpdate=!0;function handleObserve(entries){const ratio=entries[0].intersectionRatio;if(ratio!==threshold2){if(!isFirstUpdate)return refresh();ratio?refresh(!1,ratio):timeoutId=setTimeout(()=>{refresh(!1,1e-7)},1e3)}ratio===1&&!rectsAreEqual(elementRectForRootMargin,element2.getBoundingClientRect())&&refresh(),isFirstUpdate=!1}__name(handleObserve,"handleObserve");try{io=new IntersectionObserver(handleObserve,{...options,root:root2.ownerDocument})}catch{io=new IntersectionObserver(handleObserve,options)}io.observe(element2)}return __name(refresh,"refresh"),refresh(!0),cleanup}__name(observeMove,"observeMove");function autoUpdate(reference,floating,update2,options){options===void 0&&(options={});const{ancestorScroll=!0,ancestorResize=!0,elementResize=typeof ResizeObserver=="function",layoutShift=typeof IntersectionObserver=="function",animationFrame=!1}=options,referenceEl=unwrapElement(reference),ancestors=ancestorScroll||ancestorResize?[...referenceEl?getOverflowAncestors(referenceEl):[],...getOverflowAncestors(floating)]:[];ancestors.forEach(ancestor=>{ancestorScroll&&ancestor.addEventListener("scroll",update2,{passive:!0}),ancestorResize&&ancestor.addEventListener("resize",update2)});const cleanupIo=referenceEl&&layoutShift?observeMove(referenceEl,update2):null;let reobserveFrame=-1,resizeObserver=null;elementResize&&(resizeObserver=new ResizeObserver(_ref=>{let[firstEntry]=_ref;firstEntry&&firstEntry.target===referenceEl&&resizeObserver&&(resizeObserver.unobserve(floating),cancelAnimationFrame(reobserveFrame),reobserveFrame=requestAnimationFrame(()=>{var _resizeObserver;(_resizeObserver=resizeObserver)==null||_resizeObserver.observe(floating)})),update2()}),referenceEl&&!animationFrame&&resizeObserver.observe(referenceEl),resizeObserver.observe(floating));let frameId,prevRefRect=animationFrame?getBoundingClientRect(reference):null;animationFrame&&frameLoop2();function frameLoop2(){const nextRefRect=getBoundingClientRect(reference);prevRefRect&&!rectsAreEqual(prevRefRect,nextRefRect)&&update2(),prevRefRect=nextRefRect,frameId=requestAnimationFrame(frameLoop2)}return __name(frameLoop2,"frameLoop"),update2(),()=>{var _resizeObserver2;ancestors.forEach(ancestor=>{ancestorScroll&&ancestor.removeEventListener("scroll",update2),ancestorResize&&ancestor.removeEventListener("resize",update2)}),cleanupIo?.(),(_resizeObserver2=resizeObserver)==null||_resizeObserver2.disconnect(),resizeObserver=null,animationFrame&&cancelAnimationFrame(frameId)}}__name(autoUpdate,"autoUpdate");const offset$1=offset$2,shift$1=shift$2,flip$1=flip$2,size$1=size$2,hide$1=hide$2,arrow$2=arrow$3,limitShift$1=limitShift$2,computePosition=__name((reference,floating,options)=>{const cache=new Map,mergedOptions={platform,...options},platformWithCache={...mergedOptions.platform,_c:cache};return computePosition$1(reference,floating,{...mergedOptions,platform:platformWithCache})},"computePosition");var isClient=typeof document<"u",noop$2=__name(function(){},"noop"),index$1=isClient?reactExports.useLayoutEffect:noop$2;function deepEqual$1(a2,b2){if(a2===b2)return!0;if(typeof a2!=typeof b2)return!1;if(typeof a2=="function"&&a2.toString()===b2.toString())return!0;let length,i2,keys2;if(a2&&b2&&typeof a2=="object"){if(Array.isArray(a2)){if(length=a2.length,length!==b2.length)return!1;for(i2=length;i2--!==0;)if(!deepEqual$1(a2[i2],b2[i2]))return!1;return!0}if(keys2=Object.keys(a2),length=keys2.length,length!==Object.keys(b2).length)return!1;for(i2=length;i2--!==0;)if(!{}.hasOwnProperty.call(b2,keys2[i2]))return!1;for(i2=length;i2--!==0;){const key=keys2[i2];if(!(key==="_owner"&&a2.$$typeof)&&!deepEqual$1(a2[key],b2[key]))return!1}return!0}return a2!==a2&&b2!==b2}__name(deepEqual$1,"deepEqual$1");function getDPR(element2){return typeof window>"u"?1:(element2.ownerDocument.defaultView||window).devicePixelRatio||1}__name(getDPR,"getDPR");function roundByDPR(element2,value2){const dpr=getDPR(element2);return Math.round(value2*dpr)/dpr}__name(roundByDPR,"roundByDPR");function useLatestRef(value2){const ref=reactExports.useRef(value2);return index$1(()=>{ref.current=value2}),ref}__name(useLatestRef,"useLatestRef");function useFloating(options){options===void 0&&(options={});const{placement="bottom",strategy="absolute",middleware=[],platform:platform2,elements:{reference:externalReference,floating:externalFloating}={},transform:transform2=!0,whileElementsMounted,open}=options,[data,setData]=reactExports.useState({x:0,y:0,strategy,placement,middlewareData:{},isPositioned:!1}),[latestMiddleware,setLatestMiddleware]=reactExports.useState(middleware);deepEqual$1(latestMiddleware,middleware)||setLatestMiddleware(middleware);const[_reference,_setReference]=reactExports.useState(null),[_floating,_setFloating]=reactExports.useState(null),setReference=reactExports.useCallback(node2=>{node2!==referenceRef.current&&(referenceRef.current=node2,_setReference(node2))},[]),setFloating=reactExports.useCallback(node2=>{node2!==floatingRef.current&&(floatingRef.current=node2,_setFloating(node2))},[]),referenceEl=externalReference||_reference,floatingEl=externalFloating||_floating,referenceRef=reactExports.useRef(null),floatingRef=reactExports.useRef(null),dataRef=reactExports.useRef(data),hasWhileElementsMounted=whileElementsMounted!=null,whileElementsMountedRef=useLatestRef(whileElementsMounted),platformRef=useLatestRef(platform2),openRef=useLatestRef(open),update2=reactExports.useCallback(()=>{if(!referenceRef.current||!floatingRef.current)return;const config2={placement,strategy,middleware:latestMiddleware};platformRef.current&&(config2.platform=platformRef.current),computePosition(referenceRef.current,floatingRef.current,config2).then(data2=>{const fullData={...data2,isPositioned:openRef.current!==!1};isMountedRef.current&&!deepEqual$1(dataRef.current,fullData)&&(dataRef.current=fullData,reactDomExports.flushSync(()=>{setData(fullData)}))})},[latestMiddleware,placement,strategy,platformRef,openRef]);index$1(()=>{open===!1&&dataRef.current.isPositioned&&(dataRef.current.isPositioned=!1,setData(data2=>({...data2,isPositioned:!1})))},[open]);const isMountedRef=reactExports.useRef(!1);index$1(()=>(isMountedRef.current=!0,()=>{isMountedRef.current=!1}),[]),index$1(()=>{if(referenceEl&&(referenceRef.current=referenceEl),floatingEl&&(floatingRef.current=floatingEl),referenceEl&&floatingEl){if(whileElementsMountedRef.current)return whileElementsMountedRef.current(referenceEl,floatingEl,update2);update2()}},[referenceEl,floatingEl,update2,whileElementsMountedRef,hasWhileElementsMounted]);const refs=reactExports.useMemo(()=>({reference:referenceRef,floating:floatingRef,setReference,setFloating}),[setReference,setFloating]),elements=reactExports.useMemo(()=>({reference:referenceEl,floating:floatingEl}),[referenceEl,floatingEl]),floatingStyles=reactExports.useMemo(()=>{const initialStyles={position:strategy,left:0,top:0};if(!elements.floating)return initialStyles;const x2=roundByDPR(elements.floating,data.x),y2=roundByDPR(elements.floating,data.y);return transform2?{...initialStyles,transform:"translate("+x2+"px, "+y2+"px)",...getDPR(elements.floating)>=1.5&&{willChange:"transform"}}:{position:strategy,left:x2,top:y2}},[strategy,transform2,elements.floating,data.x,data.y]);return reactExports.useMemo(()=>({...data,update:update2,refs,elements,floatingStyles}),[data,update2,refs,elements,floatingStyles])}__name(useFloating,"useFloating");const arrow$1=__name(options=>{function isRef(value2){return{}.hasOwnProperty.call(value2,"current")}return __name(isRef,"isRef"),{name:"arrow",options,fn(state){const{element:element2,padding}=typeof options=="function"?options(state):options;return element2&&isRef(element2)?element2.current!=null?arrow$2({element:element2.current,padding}).fn(state):{}:element2?arrow$2({element:element2,padding}).fn(state):{}}}},"arrow$1"),offset=__name((options,deps)=>({...offset$1(options),options:[options,deps]}),"offset"),shift=__name((options,deps)=>({...shift$1(options),options:[options,deps]}),"shift"),limitShift=__name((options,deps)=>({...limitShift$1(options),options:[options,deps]}),"limitShift"),flip=__name((options,deps)=>({...flip$1(options),options:[options,deps]}),"flip"),size=__name((options,deps)=>({...size$1(options),options:[options,deps]}),"size"),hide=__name((options,deps)=>({...hide$1(options),options:[options,deps]}),"hide"),arrow=__name((options,deps)=>({...arrow$1(options),options:[options,deps]}),"arrow");var NAME$2="Arrow",Arrow$1=reactExports.forwardRef((props,forwardedRef)=>{const{children:children2,width=10,height=5,...arrowProps}=props;return jsxRuntimeExports.jsx(Primitive$2.svg,{...arrowProps,ref:forwardedRef,width,height,viewBox:"0 0 30 10",preserveAspectRatio:"none",children:props.asChild?children2:jsxRuntimeExports.jsx("polygon",{points:"0,0 30,0 15,10"})})});Arrow$1.displayName=NAME$2;var Root$5=Arrow$1;function useSize(element2){const[size2,setSize]=reactExports.useState(void 0);return useLayoutEffect2(()=>{if(element2){setSize({width:element2.offsetWidth,height:element2.offsetHeight});const resizeObserver=new ResizeObserver(entries=>{if(!Array.isArray(entries)||!entries.length)return;const entry=entries[0];let width,height;if("borderBoxSize"in entry){const borderSizeEntry=entry.borderBoxSize,borderSize=Array.isArray(borderSizeEntry)?borderSizeEntry[0]:borderSizeEntry;width=borderSize.inlineSize,height=borderSize.blockSize}else width=element2.offsetWidth,height=element2.offsetHeight;setSize({width,height})});return resizeObserver.observe(element2,{box:"border-box"}),()=>resizeObserver.unobserve(element2)}else setSize(void 0)},[element2]),size2}__name(useSize,"useSize");var POPPER_NAME="Popper",[createPopperContext,createPopperScope]=createContextScope$1(POPPER_NAME),[PopperProvider,usePopperContext]=createPopperContext(POPPER_NAME),Popper=__name(props=>{const{__scopePopper,children:children2}=props,[anchor,setAnchor]=reactExports.useState(null);return jsxRuntimeExports.jsx(PopperProvider,{scope:__scopePopper,anchor,onAnchorChange:setAnchor,children:children2})},"Popper");Popper.displayName=POPPER_NAME;var ANCHOR_NAME$1="PopperAnchor",PopperAnchor=reactExports.forwardRef((props,forwardedRef)=>{const{__scopePopper,virtualRef,...anchorProps}=props,context=usePopperContext(ANCHOR_NAME$1,__scopePopper),ref=reactExports.useRef(null),composedRefs=useComposedRefs(forwardedRef,ref),anchorRef=reactExports.useRef(null);return reactExports.useEffect(()=>{const previousAnchor=anchorRef.current;anchorRef.current=virtualRef?.current||ref.current,previousAnchor!==anchorRef.current&&context.onAnchorChange(anchorRef.current)}),virtualRef?null:jsxRuntimeExports.jsx(Primitive$2.div,{...anchorProps,ref:composedRefs})});PopperAnchor.displayName=ANCHOR_NAME$1;var CONTENT_NAME$6="PopperContent",[PopperContentProvider,useContentContext]=createPopperContext(CONTENT_NAME$6),PopperContent=reactExports.forwardRef((props,forwardedRef)=>{const{__scopePopper,side="bottom",sideOffset=0,align="center",alignOffset=0,arrowPadding=0,avoidCollisions=!0,collisionBoundary=[],collisionPadding:collisionPaddingProp=0,sticky="partial",hideWhenDetached=!1,updatePositionStrategy="optimized",onPlaced,...contentProps}=props,context=usePopperContext(CONTENT_NAME$6,__scopePopper),[content2,setContent]=reactExports.useState(null),composedRefs=useComposedRefs(forwardedRef,node2=>setContent(node2)),[arrow$12,setArrow]=reactExports.useState(null),arrowSize=useSize(arrow$12),arrowWidth=arrowSize?.width??0,arrowHeight=arrowSize?.height??0,desiredPlacement=side+(align!=="center"?"-"+align:""),collisionPadding=typeof collisionPaddingProp=="number"?collisionPaddingProp:{top:0,right:0,bottom:0,left:0,...collisionPaddingProp},boundary=Array.isArray(collisionBoundary)?collisionBoundary:[collisionBoundary],hasExplicitBoundaries=boundary.length>0,detectOverflowOptions={padding:collisionPadding,boundary:boundary.filter(isNotNull),altBoundary:hasExplicitBoundaries},{refs,floatingStyles,placement,isPositioned,middlewareData}=useFloating({strategy:"fixed",placement:desiredPlacement,whileElementsMounted:__name((...args)=>autoUpdate(...args,{animationFrame:updatePositionStrategy==="always"}),"whileElementsMounted"),elements:{reference:context.anchor},middleware:[offset({mainAxis:sideOffset+arrowHeight,alignmentAxis:alignOffset}),avoidCollisions&&shift({mainAxis:!0,crossAxis:!1,limiter:sticky==="partial"?limitShift():void 0,...detectOverflowOptions}),avoidCollisions&&flip({...detectOverflowOptions}),size({...detectOverflowOptions,apply:__name(({elements,rects,availableWidth,availableHeight})=>{const{width:anchorWidth,height:anchorHeight}=rects.reference,contentStyle=elements.floating.style;contentStyle.setProperty("--radix-popper-available-width",`${availableWidth}px`),contentStyle.setProperty("--radix-popper-available-height",`${availableHeight}px`),contentStyle.setProperty("--radix-popper-anchor-width",`${anchorWidth}px`),contentStyle.setProperty("--radix-popper-anchor-height",`${anchorHeight}px`)},"apply")}),arrow$12&&arrow({element:arrow$12,padding:arrowPadding}),transformOrigin({arrowWidth,arrowHeight}),hideWhenDetached&&hide({strategy:"referenceHidden",...detectOverflowOptions})]}),[placedSide,placedAlign]=getSideAndAlignFromPlacement(placement),handlePlaced=useCallbackRef$1(onPlaced);useLayoutEffect2(()=>{isPositioned&&handlePlaced?.()},[isPositioned,handlePlaced]);const arrowX=middlewareData.arrow?.x,arrowY=middlewareData.arrow?.y,cannotCenterArrow=middlewareData.arrow?.centerOffset!==0,[contentZIndex,setContentZIndex]=reactExports.useState();return useLayoutEffect2(()=>{content2&&setContentZIndex(window.getComputedStyle(content2).zIndex)},[content2]),jsxRuntimeExports.jsx("div",{ref:refs.setFloating,"data-radix-popper-content-wrapper":"",style:{...floatingStyles,transform:isPositioned?floatingStyles.transform:"translate(0, -200%)",minWidth:"max-content",zIndex:contentZIndex,"--radix-popper-transform-origin":[middlewareData.transformOrigin?.x,middlewareData.transformOrigin?.y].join(" "),...middlewareData.hide?.referenceHidden&&{visibility:"hidden",pointerEvents:"none"}},dir:props.dir,children:jsxRuntimeExports.jsx(PopperContentProvider,{scope:__scopePopper,placedSide,onArrowChange:setArrow,arrowX,arrowY,shouldHideArrow:cannotCenterArrow,children:jsxRuntimeExports.jsx(Primitive$2.div,{"data-side":placedSide,"data-align":placedAlign,...contentProps,ref:composedRefs,style:{...contentProps.style,animation:isPositioned?void 0:"none"}})})})});PopperContent.displayName=CONTENT_NAME$6;var ARROW_NAME$3="PopperArrow",OPPOSITE_SIDE={top:"bottom",right:"left",bottom:"top",left:"right"},PopperArrow=reactExports.forwardRef(__name(function(props,forwardedRef){const{__scopePopper,...arrowProps}=props,contentContext=useContentContext(ARROW_NAME$3,__scopePopper),baseSide=OPPOSITE_SIDE[contentContext.placedSide];return jsxRuntimeExports.jsx("span",{ref:contentContext.onArrowChange,style:{position:"absolute",left:contentContext.arrowX,top:contentContext.arrowY,[baseSide]:0,transformOrigin:{top:"",right:"0 0",bottom:"center 0",left:"100% 0"}[contentContext.placedSide],transform:{top:"translateY(100%)",right:"translateY(50%) rotate(90deg) translateX(-50%)",bottom:"rotate(180deg)",left:"translateY(50%) rotate(-90deg) translateX(50%)"}[contentContext.placedSide],visibility:contentContext.shouldHideArrow?"hidden":void 0},children:jsxRuntimeExports.jsx(Root$5,{...arrowProps,ref:forwardedRef,style:{...arrowProps.style,display:"block"}})})},"PopperArrow2"));PopperArrow.displayName=ARROW_NAME$3;function isNotNull(value2){return value2!==null}__name(isNotNull,"isNotNull");var transformOrigin=__name(options=>({name:"transformOrigin",options,fn(data){const{placement,rects,middlewareData}=data,isArrowHidden=middlewareData.arrow?.centerOffset!==0,arrowWidth=isArrowHidden?0:options.arrowWidth,arrowHeight=isArrowHidden?0:options.arrowHeight,[placedSide,placedAlign]=getSideAndAlignFromPlacement(placement),noArrowAlign={start:"0%",center:"50%",end:"100%"}[placedAlign],arrowXCenter=(middlewareData.arrow?.x??0)+arrowWidth/2,arrowYCenter=(middlewareData.arrow?.y??0)+arrowHeight/2;let x2="",y2="";return placedSide==="bottom"?(x2=isArrowHidden?noArrowAlign:`${arrowXCenter}px`,y2=`${-arrowHeight}px`):placedSide==="top"?(x2=isArrowHidden?noArrowAlign:`${arrowXCenter}px`,y2=`${rects.floating.height+arrowHeight}px`):placedSide==="right"?(x2=`${-arrowHeight}px`,y2=isArrowHidden?noArrowAlign:`${arrowYCenter}px`):placedSide==="left"&&(x2=`${rects.floating.width+arrowHeight}px`,y2=isArrowHidden?noArrowAlign:`${arrowYCenter}px`),{data:{x:x2,y:y2}}}}),"transformOrigin");function getSideAndAlignFromPlacement(placement){const[side,align="center"]=placement.split("-");return[side,align]}__name(getSideAndAlignFromPlacement,"getSideAndAlignFromPlacement");var Root2$3=Popper,Anchor=PopperAnchor,Content$2=PopperContent,Arrow=PopperArrow,ENTRY_FOCUS="rovingFocusGroup.onEntryFocus",EVENT_OPTIONS={bubbles:!1,cancelable:!0},GROUP_NAME$2="RovingFocusGroup",[Collection$2,useCollection$2,createCollectionScope$2]=createCollection(GROUP_NAME$2),[createRovingFocusGroupContext,createRovingFocusGroupScope]=createContextScope$1(GROUP_NAME$2,[createCollectionScope$2]),[RovingFocusProvider,useRovingFocusContext]=createRovingFocusGroupContext(GROUP_NAME$2),RovingFocusGroup=reactExports.forwardRef((props,forwardedRef)=>jsxRuntimeExports.jsx(Collection$2.Provider,{scope:props.__scopeRovingFocusGroup,children:jsxRuntimeExports.jsx(Collection$2.Slot,{scope:props.__scopeRovingFocusGroup,children:jsxRuntimeExports.jsx(RovingFocusGroupImpl,{...props,ref:forwardedRef})})}));RovingFocusGroup.displayName=GROUP_NAME$2;var RovingFocusGroupImpl=reactExports.forwardRef((props,forwardedRef)=>{const{__scopeRovingFocusGroup,orientation,loop:loop2=!1,dir,currentTabStopId:currentTabStopIdProp,defaultCurrentTabStopId,onCurrentTabStopIdChange,onEntryFocus,preventScrollOnEntryFocus=!1,...groupProps}=props,ref=reactExports.useRef(null),composedRefs=useComposedRefs(forwardedRef,ref),direction=useDirection(dir),[currentTabStopId,setCurrentTabStopId]=useControllableState({prop:currentTabStopIdProp,defaultProp:defaultCurrentTabStopId??null,onChange:onCurrentTabStopIdChange,caller:GROUP_NAME$2}),[isTabbingBackOut,setIsTabbingBackOut]=reactExports.useState(!1),handleEntryFocus=useCallbackRef$1(onEntryFocus),getItems=useCollection$2(__scopeRovingFocusGroup),isClickFocusRef=reactExports.useRef(!1),[focusableItemsCount,setFocusableItemsCount]=reactExports.useState(0);return reactExports.useEffect(()=>{const node2=ref.current;if(node2)return node2.addEventListener(ENTRY_FOCUS,handleEntryFocus),()=>node2.removeEventListener(ENTRY_FOCUS,handleEntryFocus)},[handleEntryFocus]),jsxRuntimeExports.jsx(RovingFocusProvider,{scope:__scopeRovingFocusGroup,orientation,dir:direction,loop:loop2,currentTabStopId,onItemFocus:reactExports.useCallback(tabStopId=>setCurrentTabStopId(tabStopId),[setCurrentTabStopId]),onItemShiftTab:reactExports.useCallback(()=>setIsTabbingBackOut(!0),[]),onFocusableItemAdd:reactExports.useCallback(()=>setFocusableItemsCount(prevCount=>prevCount+1),[]),onFocusableItemRemove:reactExports.useCallback(()=>setFocusableItemsCount(prevCount=>prevCount-1),[]),children:jsxRuntimeExports.jsx(Primitive$2.div,{tabIndex:isTabbingBackOut||focusableItemsCount===0?-1:0,"data-orientation":orientation,...groupProps,ref:composedRefs,style:{outline:"none",...props.style},onMouseDown:composeEventHandlers(props.onMouseDown,()=>{isClickFocusRef.current=!0}),onFocus:composeEventHandlers(props.onFocus,event=>{const isKeyboardFocus=!isClickFocusRef.current;if(event.target===event.currentTarget&&isKeyboardFocus&&!isTabbingBackOut){const entryFocusEvent=new CustomEvent(ENTRY_FOCUS,EVENT_OPTIONS);if(event.currentTarget.dispatchEvent(entryFocusEvent),!entryFocusEvent.defaultPrevented){const items=getItems().filter(item=>item.focusable),activeItem=items.find(item=>item.active),currentItem=items.find(item=>item.id===currentTabStopId),candidateNodes=[activeItem,currentItem,...items].filter(Boolean).map(item=>item.ref.current);focusFirst$1(candidateNodes,preventScrollOnEntryFocus)}}isClickFocusRef.current=!1}),onBlur:composeEventHandlers(props.onBlur,()=>setIsTabbingBackOut(!1))})})}),ITEM_NAME$3="RovingFocusGroupItem",RovingFocusGroupItem=reactExports.forwardRef((props,forwardedRef)=>{const{__scopeRovingFocusGroup,focusable=!0,active=!1,tabStopId,children:children2,...itemProps}=props,autoId=useId(),id=tabStopId||autoId,context=useRovingFocusContext(ITEM_NAME$3,__scopeRovingFocusGroup),isCurrentTabStop=context.currentTabStopId===id,getItems=useCollection$2(__scopeRovingFocusGroup),{onFocusableItemAdd,onFocusableItemRemove,currentTabStopId}=context;return reactExports.useEffect(()=>{if(focusable)return onFocusableItemAdd(),()=>onFocusableItemRemove()},[focusable,onFocusableItemAdd,onFocusableItemRemove]),jsxRuntimeExports.jsx(Collection$2.ItemSlot,{scope:__scopeRovingFocusGroup,id,focusable,active,children:jsxRuntimeExports.jsx(Primitive$2.span,{tabIndex:isCurrentTabStop?0:-1,"data-orientation":context.orientation,...itemProps,ref:forwardedRef,onMouseDown:composeEventHandlers(props.onMouseDown,event=>{focusable?context.onItemFocus(id):event.preventDefault()}),onFocus:composeEventHandlers(props.onFocus,()=>context.onItemFocus(id)),onKeyDown:composeEventHandlers(props.onKeyDown,event=>{if(event.key==="Tab"&&event.shiftKey){context.onItemShiftTab();return}if(event.target!==event.currentTarget)return;const focusIntent=getFocusIntent(event,context.orientation,context.dir);if(focusIntent!==void 0){if(event.metaKey||event.ctrlKey||event.altKey||event.shiftKey)return;event.preventDefault();let candidateNodes=getItems().filter(item=>item.focusable).map(item=>item.ref.current);if(focusIntent==="last")candidateNodes.reverse();else if(focusIntent==="prev"||focusIntent==="next"){focusIntent==="prev"&&candidateNodes.reverse();const currentIndex=candidateNodes.indexOf(event.currentTarget);candidateNodes=context.loop?wrapArray$1(candidateNodes,currentIndex+1):candidateNodes.slice(currentIndex+1)}setTimeout(()=>focusFirst$1(candidateNodes))}}),children:typeof children2=="function"?children2({isCurrentTabStop,hasTabStop:currentTabStopId!=null}):children2})})});RovingFocusGroupItem.displayName=ITEM_NAME$3;var MAP_KEY_TO_FOCUS_INTENT={ArrowLeft:"prev",ArrowUp:"prev",ArrowRight:"next",ArrowDown:"next",PageUp:"first",Home:"first",PageDown:"last",End:"last"};function getDirectionAwareKey(key,dir){return dir!=="rtl"?key:key==="ArrowLeft"?"ArrowRight":key==="ArrowRight"?"ArrowLeft":key}__name(getDirectionAwareKey,"getDirectionAwareKey");function getFocusIntent(event,orientation,dir){const key=getDirectionAwareKey(event.key,dir);if(!(orientation==="vertical"&&["ArrowLeft","ArrowRight"].includes(key))&&!(orientation==="horizontal"&&["ArrowUp","ArrowDown"].includes(key)))return MAP_KEY_TO_FOCUS_INTENT[key]}__name(getFocusIntent,"getFocusIntent");function focusFirst$1(candidates,preventScroll=!1){const PREVIOUSLY_FOCUSED_ELEMENT=document.activeElement;for(const candidate of candidates)if(candidate===PREVIOUSLY_FOCUSED_ELEMENT||(candidate.focus({preventScroll}),document.activeElement!==PREVIOUSLY_FOCUSED_ELEMENT))return}__name(focusFirst$1,"focusFirst$1");function wrapArray$1(array2,startIndex){return array2.map((_2,index2)=>array2[(startIndex+index2)%array2.length])}__name(wrapArray$1,"wrapArray$1");var Root$4=RovingFocusGroup,Item$1=RovingFocusGroupItem;function createSlot(ownerName){const SlotClone=createSlotClone(ownerName),Slot2=reactExports.forwardRef((props,forwardedRef)=>{const{children:children2,...slotProps}=props,childrenArray=reactExports.Children.toArray(children2),slottable=childrenArray.find(isSlottable);if(slottable){const newElement=slottable.props.children,newChildren=childrenArray.map(child=>child===slottable?reactExports.Children.count(newElement)>1?reactExports.Children.only(null):reactExports.isValidElement(newElement)?newElement.props.children:null:child);return jsxRuntimeExports.jsx(SlotClone,{...slotProps,ref:forwardedRef,children:reactExports.isValidElement(newElement)?reactExports.cloneElement(newElement,void 0,newChildren):null})}return jsxRuntimeExports.jsx(SlotClone,{...slotProps,ref:forwardedRef,children:children2})});return Slot2.displayName=`${ownerName}.Slot`,Slot2}__name(createSlot,"createSlot");function createSlotClone(ownerName){const SlotClone=reactExports.forwardRef((props,forwardedRef)=>{const{children:children2,...slotProps}=props;if(reactExports.isValidElement(children2)){const childrenRef=getElementRef(children2),props2=mergeProps(slotProps,children2.props);return children2.type!==reactExports.Fragment&&(props2.ref=forwardedRef?composeRefs(forwardedRef,childrenRef):childrenRef),reactExports.cloneElement(children2,props2)}return reactExports.Children.count(children2)>1?reactExports.Children.only(null):null});return SlotClone.displayName=`${ownerName}.SlotClone`,SlotClone}__name(createSlotClone,"createSlotClone");var SLOTTABLE_IDENTIFIER$1=Symbol("radix.slottable");function isSlottable(child){return reactExports.isValidElement(child)&&typeof child.type=="function"&&"__radixId"in child.type&&child.type.__radixId===SLOTTABLE_IDENTIFIER$1}__name(isSlottable,"isSlottable");function mergeProps(slotProps,childProps){const overrideProps={...childProps};for(const propName in childProps){const slotPropValue=slotProps[propName],childPropValue=childProps[propName];/^on[A-Z]/.test(propName)?slotPropValue&&childPropValue?overrideProps[propName]=(...args)=>{const result=childPropValue(...args);return slotPropValue(...args),result}:slotPropValue&&(overrideProps[propName]=slotPropValue):propName==="style"?overrideProps[propName]={...slotPropValue,...childPropValue}:propName==="className"&&(overrideProps[propName]=[slotPropValue,childPropValue].filter(Boolean).join(" "))}return{...slotProps,...overrideProps}}__name(mergeProps,"mergeProps");function getElementRef(element2){let getter=Object.getOwnPropertyDescriptor(element2.props,"ref")?.get,mayWarn=getter&&"isReactWarning"in getter&&getter.isReactWarning;return mayWarn?element2.ref:(getter=Object.getOwnPropertyDescriptor(element2,"ref")?.get,mayWarn=getter&&"isReactWarning"in getter&&getter.isReactWarning,mayWarn?element2.props.ref:element2.props.ref||element2.ref)}__name(getElementRef,"getElementRef");var SELECTION_KEYS=["Enter"," "],FIRST_KEYS=["ArrowDown","PageUp","Home"],LAST_KEYS=["ArrowUp","PageDown","End"],FIRST_LAST_KEYS=[...FIRST_KEYS,...LAST_KEYS],SUB_OPEN_KEYS={ltr:[...SELECTION_KEYS,"ArrowRight"],rtl:[...SELECTION_KEYS,"ArrowLeft"]},SUB_CLOSE_KEYS={ltr:["ArrowLeft"],rtl:["ArrowRight"]},MENU_NAME="Menu",[Collection$1,useCollection$1,createCollectionScope$1]=createCollection(MENU_NAME),[createMenuContext,createMenuScope]=createContextScope$1(MENU_NAME,[createCollectionScope$1,createPopperScope,createRovingFocusGroupScope]),usePopperScope$1=createPopperScope(),useRovingFocusGroupScope$1=createRovingFocusGroupScope(),[MenuProvider,useMenuContext]=createMenuContext(MENU_NAME),[MenuRootProvider,useMenuRootContext]=createMenuContext(MENU_NAME),Menu=__name(props=>{const{__scopeMenu,open=!1,children:children2,dir,onOpenChange,modal=!0}=props,popperScope=usePopperScope$1(__scopeMenu),[content2,setContent]=reactExports.useState(null),isUsingKeyboardRef=reactExports.useRef(!1),handleOpenChange=useCallbackRef$1(onOpenChange),direction=useDirection(dir);return reactExports.useEffect(()=>{const handleKeyDown=__name(()=>{isUsingKeyboardRef.current=!0,document.addEventListener("pointerdown",handlePointer,{capture:!0,once:!0}),document.addEventListener("pointermove",handlePointer,{capture:!0,once:!0})},"handleKeyDown"),handlePointer=__name(()=>isUsingKeyboardRef.current=!1,"handlePointer");return document.addEventListener("keydown",handleKeyDown,{capture:!0}),()=>{document.removeEventListener("keydown",handleKeyDown,{capture:!0}),document.removeEventListener("pointerdown",handlePointer,{capture:!0}),document.removeEventListener("pointermove",handlePointer,{capture:!0})}},[]),jsxRuntimeExports.jsx(Root2$3,{...popperScope,children:jsxRuntimeExports.jsx(MenuProvider,{scope:__scopeMenu,open,onOpenChange:handleOpenChange,content:content2,onContentChange:setContent,children:jsxRuntimeExports.jsx(MenuRootProvider,{scope:__scopeMenu,onClose:reactExports.useCallback(()=>handleOpenChange(!1),[handleOpenChange]),isUsingKeyboardRef,dir:direction,modal,children:children2})})})},"Menu");Menu.displayName=MENU_NAME;var ANCHOR_NAME="MenuAnchor",MenuAnchor=reactExports.forwardRef((props,forwardedRef)=>{const{__scopeMenu,...anchorProps}=props,popperScope=usePopperScope$1(__scopeMenu);return jsxRuntimeExports.jsx(Anchor,{...popperScope,...anchorProps,ref:forwardedRef})});MenuAnchor.displayName=ANCHOR_NAME;var PORTAL_NAME$2="MenuPortal",[PortalProvider$1,usePortalContext$1]=createMenuContext(PORTAL_NAME$2,{forceMount:void 0}),MenuPortal=__name(props=>{const{__scopeMenu,forceMount,children:children2,container}=props,context=useMenuContext(PORTAL_NAME$2,__scopeMenu);return jsxRuntimeExports.jsx(PortalProvider$1,{scope:__scopeMenu,forceMount,children:jsxRuntimeExports.jsx(Presence,{present:forceMount||context.open,children:jsxRuntimeExports.jsx(Portal$2,{asChild:!0,container,children:children2})})})},"MenuPortal");MenuPortal.displayName=PORTAL_NAME$2;var CONTENT_NAME$5="MenuContent",[MenuContentProvider,useMenuContentContext]=createMenuContext(CONTENT_NAME$5),MenuContent=reactExports.forwardRef((props,forwardedRef)=>{const portalContext=usePortalContext$1(CONTENT_NAME$5,props.__scopeMenu),{forceMount=portalContext.forceMount,...contentProps}=props,context=useMenuContext(CONTENT_NAME$5,props.__scopeMenu),rootContext=useMenuRootContext(CONTENT_NAME$5,props.__scopeMenu);return jsxRuntimeExports.jsx(Collection$1.Provider,{scope:props.__scopeMenu,children:jsxRuntimeExports.jsx(Presence,{present:forceMount||context.open,children:jsxRuntimeExports.jsx(Collection$1.Slot,{scope:props.__scopeMenu,children:rootContext.modal?jsxRuntimeExports.jsx(MenuRootContentModal,{...contentProps,ref:forwardedRef}):jsxRuntimeExports.jsx(MenuRootContentNonModal,{...contentProps,ref:forwardedRef})})})})}),MenuRootContentModal=reactExports.forwardRef((props,forwardedRef)=>{const context=useMenuContext(CONTENT_NAME$5,props.__scopeMenu),ref=reactExports.useRef(null),composedRefs=useComposedRefs(forwardedRef,ref);return reactExports.useEffect(()=>{const content2=ref.current;if(content2)return hideOthers(content2)},[]),jsxRuntimeExports.jsx(MenuContentImpl,{...props,ref:composedRefs,trapFocus:context.open,disableOutsidePointerEvents:context.open,disableOutsideScroll:!0,onFocusOutside:composeEventHandlers(props.onFocusOutside,event=>event.preventDefault(),{checkForDefaultPrevented:!1}),onDismiss:__name(()=>context.onOpenChange(!1),"onDismiss")})}),MenuRootContentNonModal=reactExports.forwardRef((props,forwardedRef)=>{const context=useMenuContext(CONTENT_NAME$5,props.__scopeMenu);return jsxRuntimeExports.jsx(MenuContentImpl,{...props,ref:forwardedRef,trapFocus:!1,disableOutsidePointerEvents:!1,disableOutsideScroll:!1,onDismiss:__name(()=>context.onOpenChange(!1),"onDismiss")})}),Slot=createSlot("MenuContent.ScrollLock"),MenuContentImpl=reactExports.forwardRef((props,forwardedRef)=>{const{__scopeMenu,loop:loop2=!1,trapFocus,onOpenAutoFocus,onCloseAutoFocus,disableOutsidePointerEvents,onEntryFocus,onEscapeKeyDown,onPointerDownOutside,onFocusOutside,onInteractOutside,onDismiss,disableOutsideScroll,...contentProps}=props,context=useMenuContext(CONTENT_NAME$5,__scopeMenu),rootContext=useMenuRootContext(CONTENT_NAME$5,__scopeMenu),popperScope=usePopperScope$1(__scopeMenu),rovingFocusGroupScope=useRovingFocusGroupScope$1(__scopeMenu),getItems=useCollection$1(__scopeMenu),[currentItemId,setCurrentItemId]=reactExports.useState(null),contentRef=reactExports.useRef(null),composedRefs=useComposedRefs(forwardedRef,contentRef,context.onContentChange),timerRef=reactExports.useRef(0),searchRef=reactExports.useRef(""),pointerGraceTimerRef=reactExports.useRef(0),pointerGraceIntentRef=reactExports.useRef(null),pointerDirRef=reactExports.useRef("right"),lastPointerXRef=reactExports.useRef(0),ScrollLockWrapper=disableOutsideScroll?ReactRemoveScroll:reactExports.Fragment,scrollLockWrapperProps=disableOutsideScroll?{as:Slot,allowPinchZoom:!0}:void 0,handleTypeaheadSearch=__name(key=>{const search2=searchRef.current+key,items=getItems().filter(item=>!item.disabled),currentItem=document.activeElement,currentMatch=items.find(item=>item.ref.current===currentItem)?.textValue,values=items.map(item=>item.textValue),nextMatch=getNextMatch(values,search2,currentMatch),newItem=items.find(item=>item.textValue===nextMatch)?.ref.current;__name((function updateSearch(value2){searchRef.current=value2,window.clearTimeout(timerRef.current),value2!==""&&(timerRef.current=window.setTimeout(()=>updateSearch(""),1e3))}),"updateSearch")(search2),newItem&&setTimeout(()=>newItem.focus())},"handleTypeaheadSearch");reactExports.useEffect(()=>()=>window.clearTimeout(timerRef.current),[]),useFocusGuards();const isPointerMovingToSubmenu=reactExports.useCallback(event=>pointerDirRef.current===pointerGraceIntentRef.current?.side&&isPointerInGraceArea(event,pointerGraceIntentRef.current?.area),[]);return jsxRuntimeExports.jsx(MenuContentProvider,{scope:__scopeMenu,searchRef,onItemEnter:reactExports.useCallback(event=>{isPointerMovingToSubmenu(event)&&event.preventDefault()},[isPointerMovingToSubmenu]),onItemLeave:reactExports.useCallback(event=>{isPointerMovingToSubmenu(event)||(contentRef.current?.focus(),setCurrentItemId(null))},[isPointerMovingToSubmenu]),onTriggerLeave:reactExports.useCallback(event=>{isPointerMovingToSubmenu(event)&&event.preventDefault()},[isPointerMovingToSubmenu]),pointerGraceTimerRef,onPointerGraceIntentChange:reactExports.useCallback(intent=>{pointerGraceIntentRef.current=intent},[]),children:jsxRuntimeExports.jsx(ScrollLockWrapper,{...scrollLockWrapperProps,children:jsxRuntimeExports.jsx(FocusScope,{asChild:!0,trapped:trapFocus,onMountAutoFocus:composeEventHandlers(onOpenAutoFocus,event=>{event.preventDefault(),contentRef.current?.focus({preventScroll:!0})}),onUnmountAutoFocus:onCloseAutoFocus,children:jsxRuntimeExports.jsx(DismissableLayer,{asChild:!0,disableOutsidePointerEvents,onEscapeKeyDown,onPointerDownOutside,onFocusOutside,onInteractOutside,onDismiss,children:jsxRuntimeExports.jsx(Root$4,{asChild:!0,...rovingFocusGroupScope,dir:rootContext.dir,orientation:"vertical",loop:loop2,currentTabStopId:currentItemId,onCurrentTabStopIdChange:setCurrentItemId,onEntryFocus:composeEventHandlers(onEntryFocus,event=>{rootContext.isUsingKeyboardRef.current||event.preventDefault()}),preventScrollOnEntryFocus:!0,children:jsxRuntimeExports.jsx(Content$2,{role:"menu","aria-orientation":"vertical","data-state":getOpenState(context.open),"data-radix-menu-content":"",dir:rootContext.dir,...popperScope,...contentProps,ref:composedRefs,style:{outline:"none",...contentProps.style},onKeyDown:composeEventHandlers(contentProps.onKeyDown,event=>{const isKeyDownInside=event.target.closest("[data-radix-menu-content]")===event.currentTarget,isModifierKey=event.ctrlKey||event.altKey||event.metaKey,isCharacterKey=event.key.length===1;isKeyDownInside&&(event.key==="Tab"&&event.preventDefault(),!isModifierKey&&isCharacterKey&&handleTypeaheadSearch(event.key));const content2=contentRef.current;if(event.target!==content2||!FIRST_LAST_KEYS.includes(event.key))return;event.preventDefault();const candidateNodes=getItems().filter(item=>!item.disabled).map(item=>item.ref.current);LAST_KEYS.includes(event.key)&&candidateNodes.reverse(),focusFirst(candidateNodes)}),onBlur:composeEventHandlers(props.onBlur,event=>{event.currentTarget.contains(event.target)||(window.clearTimeout(timerRef.current),searchRef.current="")}),onPointerMove:composeEventHandlers(props.onPointerMove,whenMouse(event=>{const target=event.target,pointerXHasChanged=lastPointerXRef.current!==event.clientX;if(event.currentTarget.contains(target)&&pointerXHasChanged){const newDir=event.clientX>lastPointerXRef.current?"right":"left";pointerDirRef.current=newDir,lastPointerXRef.current=event.clientX}}))})})})})})})});MenuContent.displayName=CONTENT_NAME$5;var GROUP_NAME$1="MenuGroup",MenuGroup=reactExports.forwardRef((props,forwardedRef)=>{const{__scopeMenu,...groupProps}=props;return jsxRuntimeExports.jsx(Primitive$2.div,{role:"group",...groupProps,ref:forwardedRef})});MenuGroup.displayName=GROUP_NAME$1;var LABEL_NAME$1="MenuLabel",MenuLabel=reactExports.forwardRef((props,forwardedRef)=>{const{__scopeMenu,...labelProps}=props;return jsxRuntimeExports.jsx(Primitive$2.div,{...labelProps,ref:forwardedRef})});MenuLabel.displayName=LABEL_NAME$1;var ITEM_NAME$2="MenuItem",ITEM_SELECT="menu.itemSelect",MenuItem=reactExports.forwardRef((props,forwardedRef)=>{const{disabled=!1,onSelect,...itemProps}=props,ref=reactExports.useRef(null),rootContext=useMenuRootContext(ITEM_NAME$2,props.__scopeMenu),contentContext=useMenuContentContext(ITEM_NAME$2,props.__scopeMenu),composedRefs=useComposedRefs(forwardedRef,ref),isPointerDownRef=reactExports.useRef(!1),handleSelect=__name(()=>{const menuItem=ref.current;if(!disabled&&menuItem){const itemSelectEvent=new CustomEvent(ITEM_SELECT,{bubbles:!0,cancelable:!0});menuItem.addEventListener(ITEM_SELECT,event=>onSelect?.(event),{once:!0}),dispatchDiscreteCustomEvent(menuItem,itemSelectEvent),itemSelectEvent.defaultPrevented?isPointerDownRef.current=!1:rootContext.onClose()}},"handleSelect");return jsxRuntimeExports.jsx(MenuItemImpl,{...itemProps,ref:composedRefs,disabled,onClick:composeEventHandlers(props.onClick,handleSelect),onPointerDown:__name(event=>{props.onPointerDown?.(event),isPointerDownRef.current=!0},"onPointerDown"),onPointerUp:composeEventHandlers(props.onPointerUp,event=>{isPointerDownRef.current||event.currentTarget?.click()}),onKeyDown:composeEventHandlers(props.onKeyDown,event=>{const isTypingAhead=contentContext.searchRef.current!=="";disabled||isTypingAhead&&event.key===" "||SELECTION_KEYS.includes(event.key)&&(event.currentTarget.click(),event.preventDefault())})})});MenuItem.displayName=ITEM_NAME$2;var MenuItemImpl=reactExports.forwardRef((props,forwardedRef)=>{const{__scopeMenu,disabled=!1,textValue,...itemProps}=props,contentContext=useMenuContentContext(ITEM_NAME$2,__scopeMenu),rovingFocusGroupScope=useRovingFocusGroupScope$1(__scopeMenu),ref=reactExports.useRef(null),composedRefs=useComposedRefs(forwardedRef,ref),[isFocused,setIsFocused]=reactExports.useState(!1),[textContent,setTextContent]=reactExports.useState("");return reactExports.useEffect(()=>{const menuItem=ref.current;menuItem&&setTextContent((menuItem.textContent??"").trim())},[itemProps.children]),jsxRuntimeExports.jsx(Collection$1.ItemSlot,{scope:__scopeMenu,disabled,textValue:textValue??textContent,children:jsxRuntimeExports.jsx(Item$1,{asChild:!0,...rovingFocusGroupScope,focusable:!disabled,children:jsxRuntimeExports.jsx(Primitive$2.div,{role:"menuitem","data-highlighted":isFocused?"":void 0,"aria-disabled":disabled||void 0,"data-disabled":disabled?"":void 0,...itemProps,ref:composedRefs,onPointerMove:composeEventHandlers(props.onPointerMove,whenMouse(event=>{disabled?contentContext.onItemLeave(event):(contentContext.onItemEnter(event),event.defaultPrevented||event.currentTarget.focus({preventScroll:!0}))})),onPointerLeave:composeEventHandlers(props.onPointerLeave,whenMouse(event=>contentContext.onItemLeave(event))),onFocus:composeEventHandlers(props.onFocus,()=>setIsFocused(!0)),onBlur:composeEventHandlers(props.onBlur,()=>setIsFocused(!1))})})})}),CHECKBOX_ITEM_NAME$1="MenuCheckboxItem",MenuCheckboxItem=reactExports.forwardRef((props,forwardedRef)=>{const{checked=!1,onCheckedChange,...checkboxItemProps}=props;return jsxRuntimeExports.jsx(ItemIndicatorProvider,{scope:props.__scopeMenu,checked,children:jsxRuntimeExports.jsx(MenuItem,{role:"menuitemcheckbox","aria-checked":isIndeterminate(checked)?"mixed":checked,...checkboxItemProps,ref:forwardedRef,"data-state":getCheckedState(checked),onSelect:composeEventHandlers(checkboxItemProps.onSelect,()=>onCheckedChange?.(isIndeterminate(checked)?!0:!checked),{checkForDefaultPrevented:!1})})})});MenuCheckboxItem.displayName=CHECKBOX_ITEM_NAME$1;var RADIO_GROUP_NAME$1="MenuRadioGroup",[RadioGroupProvider,useRadioGroupContext]=createMenuContext(RADIO_GROUP_NAME$1,{value:void 0,onValueChange:__name(()=>{},"onValueChange")}),MenuRadioGroup=reactExports.forwardRef((props,forwardedRef)=>{const{value:value2,onValueChange,...groupProps}=props,handleValueChange=useCallbackRef$1(onValueChange);return jsxRuntimeExports.jsx(RadioGroupProvider,{scope:props.__scopeMenu,value:value2,onValueChange:handleValueChange,children:jsxRuntimeExports.jsx(MenuGroup,{...groupProps,ref:forwardedRef})})});MenuRadioGroup.displayName=RADIO_GROUP_NAME$1;var RADIO_ITEM_NAME$1="MenuRadioItem",MenuRadioItem=reactExports.forwardRef((props,forwardedRef)=>{const{value:value2,...radioItemProps}=props,context=useRadioGroupContext(RADIO_ITEM_NAME$1,props.__scopeMenu),checked=value2===context.value;return jsxRuntimeExports.jsx(ItemIndicatorProvider,{scope:props.__scopeMenu,checked,children:jsxRuntimeExports.jsx(MenuItem,{role:"menuitemradio","aria-checked":checked,...radioItemProps,ref:forwardedRef,"data-state":getCheckedState(checked),onSelect:composeEventHandlers(radioItemProps.onSelect,()=>context.onValueChange?.(value2),{checkForDefaultPrevented:!1})})})});MenuRadioItem.displayName=RADIO_ITEM_NAME$1;var ITEM_INDICATOR_NAME="MenuItemIndicator",[ItemIndicatorProvider,useItemIndicatorContext]=createMenuContext(ITEM_INDICATOR_NAME,{checked:!1}),MenuItemIndicator=reactExports.forwardRef((props,forwardedRef)=>{const{__scopeMenu,forceMount,...itemIndicatorProps}=props,indicatorContext=useItemIndicatorContext(ITEM_INDICATOR_NAME,__scopeMenu);return jsxRuntimeExports.jsx(Presence,{present:forceMount||isIndeterminate(indicatorContext.checked)||indicatorContext.checked===!0,children:jsxRuntimeExports.jsx(Primitive$2.span,{...itemIndicatorProps,ref:forwardedRef,"data-state":getCheckedState(indicatorContext.checked)})})});MenuItemIndicator.displayName=ITEM_INDICATOR_NAME;var SEPARATOR_NAME$1="MenuSeparator",MenuSeparator=reactExports.forwardRef((props,forwardedRef)=>{const{__scopeMenu,...separatorProps}=props;return jsxRuntimeExports.jsx(Primitive$2.div,{role:"separator","aria-orientation":"horizontal",...separatorProps,ref:forwardedRef})});MenuSeparator.displayName=SEPARATOR_NAME$1;var ARROW_NAME$2="MenuArrow",MenuArrow=reactExports.forwardRef((props,forwardedRef)=>{const{__scopeMenu,...arrowProps}=props,popperScope=usePopperScope$1(__scopeMenu);return jsxRuntimeExports.jsx(Arrow,{...popperScope,...arrowProps,ref:forwardedRef})});MenuArrow.displayName=ARROW_NAME$2;var SUB_NAME="MenuSub",[MenuSubProvider,useMenuSubContext]=createMenuContext(SUB_NAME),SUB_TRIGGER_NAME$1="MenuSubTrigger",MenuSubTrigger=reactExports.forwardRef((props,forwardedRef)=>{const context=useMenuContext(SUB_TRIGGER_NAME$1,props.__scopeMenu),rootContext=useMenuRootContext(SUB_TRIGGER_NAME$1,props.__scopeMenu),subContext=useMenuSubContext(SUB_TRIGGER_NAME$1,props.__scopeMenu),contentContext=useMenuContentContext(SUB_TRIGGER_NAME$1,props.__scopeMenu),openTimerRef=reactExports.useRef(null),{pointerGraceTimerRef,onPointerGraceIntentChange}=contentContext,scope={__scopeMenu:props.__scopeMenu},clearOpenTimer=reactExports.useCallback(()=>{openTimerRef.current&&window.clearTimeout(openTimerRef.current),openTimerRef.current=null},[]);return reactExports.useEffect(()=>clearOpenTimer,[clearOpenTimer]),reactExports.useEffect(()=>{const pointerGraceTimer=pointerGraceTimerRef.current;return()=>{window.clearTimeout(pointerGraceTimer),onPointerGraceIntentChange(null)}},[pointerGraceTimerRef,onPointerGraceIntentChange]),jsxRuntimeExports.jsx(MenuAnchor,{asChild:!0,...scope,children:jsxRuntimeExports.jsx(MenuItemImpl,{id:subContext.triggerId,"aria-haspopup":"menu","aria-expanded":context.open,"aria-controls":subContext.contentId,"data-state":getOpenState(context.open),...props,ref:composeRefs(forwardedRef,subContext.onTriggerChange),onClick:__name(event=>{props.onClick?.(event),!(props.disabled||event.defaultPrevented)&&(event.currentTarget.focus(),context.open||context.onOpenChange(!0))},"onClick"),onPointerMove:composeEventHandlers(props.onPointerMove,whenMouse(event=>{contentContext.onItemEnter(event),!event.defaultPrevented&&!props.disabled&&!context.open&&!openTimerRef.current&&(contentContext.onPointerGraceIntentChange(null),openTimerRef.current=window.setTimeout(()=>{context.onOpenChange(!0),clearOpenTimer()},100))})),onPointerLeave:composeEventHandlers(props.onPointerLeave,whenMouse(event=>{clearOpenTimer();const contentRect=context.content?.getBoundingClientRect();if(contentRect){const side=context.content?.dataset.side,rightSide=side==="right",bleed=rightSide?-5:5,contentNearEdge=contentRect[rightSide?"left":"right"],contentFarEdge=contentRect[rightSide?"right":"left"];contentContext.onPointerGraceIntentChange({area:[{x:event.clientX+bleed,y:event.clientY},{x:contentNearEdge,y:contentRect.top},{x:contentFarEdge,y:contentRect.top},{x:contentFarEdge,y:contentRect.bottom},{x:contentNearEdge,y:contentRect.bottom}],side}),window.clearTimeout(pointerGraceTimerRef.current),pointerGraceTimerRef.current=window.setTimeout(()=>contentContext.onPointerGraceIntentChange(null),300)}else{if(contentContext.onTriggerLeave(event),event.defaultPrevented)return;contentContext.onPointerGraceIntentChange(null)}})),onKeyDown:composeEventHandlers(props.onKeyDown,event=>{const isTypingAhead=contentContext.searchRef.current!=="";props.disabled||isTypingAhead&&event.key===" "||SUB_OPEN_KEYS[rootContext.dir].includes(event.key)&&(context.onOpenChange(!0),context.content?.focus(),event.preventDefault())})})})});MenuSubTrigger.displayName=SUB_TRIGGER_NAME$1;var SUB_CONTENT_NAME$1="MenuSubContent",MenuSubContent=reactExports.forwardRef((props,forwardedRef)=>{const portalContext=usePortalContext$1(CONTENT_NAME$5,props.__scopeMenu),{forceMount=portalContext.forceMount,...subContentProps}=props,context=useMenuContext(CONTENT_NAME$5,props.__scopeMenu),rootContext=useMenuRootContext(CONTENT_NAME$5,props.__scopeMenu),subContext=useMenuSubContext(SUB_CONTENT_NAME$1,props.__scopeMenu),ref=reactExports.useRef(null),composedRefs=useComposedRefs(forwardedRef,ref);return jsxRuntimeExports.jsx(Collection$1.Provider,{scope:props.__scopeMenu,children:jsxRuntimeExports.jsx(Presence,{present:forceMount||context.open,children:jsxRuntimeExports.jsx(Collection$1.Slot,{scope:props.__scopeMenu,children:jsxRuntimeExports.jsx(MenuContentImpl,{id:subContext.contentId,"aria-labelledby":subContext.triggerId,...subContentProps,ref:composedRefs,align:"start",side:rootContext.dir==="rtl"?"left":"right",disableOutsidePointerEvents:!1,disableOutsideScroll:!1,trapFocus:!1,onOpenAutoFocus:__name(event=>{rootContext.isUsingKeyboardRef.current&&ref.current?.focus(),event.preventDefault()},"onOpenAutoFocus"),onCloseAutoFocus:__name(event=>event.preventDefault(),"onCloseAutoFocus"),onFocusOutside:composeEventHandlers(props.onFocusOutside,event=>{event.target!==subContext.trigger&&context.onOpenChange(!1)}),onEscapeKeyDown:composeEventHandlers(props.onEscapeKeyDown,event=>{rootContext.onClose(),event.preventDefault()}),onKeyDown:composeEventHandlers(props.onKeyDown,event=>{const isKeyDownInside=event.currentTarget.contains(event.target),isCloseKey=SUB_CLOSE_KEYS[rootContext.dir].includes(event.key);isKeyDownInside&&isCloseKey&&(context.onOpenChange(!1),subContext.trigger?.focus(),event.preventDefault())})})})})})});MenuSubContent.displayName=SUB_CONTENT_NAME$1;function getOpenState(open){return open?"open":"closed"}__name(getOpenState,"getOpenState");function isIndeterminate(checked){return checked==="indeterminate"}__name(isIndeterminate,"isIndeterminate");function getCheckedState(checked){return isIndeterminate(checked)?"indeterminate":checked?"checked":"unchecked"}__name(getCheckedState,"getCheckedState");function focusFirst(candidates){const PREVIOUSLY_FOCUSED_ELEMENT=document.activeElement;for(const candidate of candidates)if(candidate===PREVIOUSLY_FOCUSED_ELEMENT||(candidate.focus(),document.activeElement!==PREVIOUSLY_FOCUSED_ELEMENT))return}__name(focusFirst,"focusFirst");function wrapArray(array2,startIndex){return array2.map((_2,index2)=>array2[(startIndex+index2)%array2.length])}__name(wrapArray,"wrapArray");function getNextMatch(values,search2,currentMatch){const normalizedSearch=search2.length>1&&Array.from(search2).every(char=>char===search2[0])?search2[0]:search2,currentMatchIndex=currentMatch?values.indexOf(currentMatch):-1;let wrappedValues=wrapArray(values,Math.max(currentMatchIndex,0));normalizedSearch.length===1&&(wrappedValues=wrappedValues.filter(v2=>v2!==currentMatch));const nextMatch=wrappedValues.find(value2=>value2.toLowerCase().startsWith(normalizedSearch.toLowerCase()));return nextMatch!==currentMatch?nextMatch:void 0}__name(getNextMatch,"getNextMatch");function isPointInPolygon$1(point2,polygon){const{x:x2,y:y2}=point2;let inside=!1;for(let i2=0,j2=polygon.length-1;i2y2!=yj>y2&&x2<(xj-xi)*(y2-yi)/(yj-yi)+xi&&(inside=!inside)}return inside}__name(isPointInPolygon$1,"isPointInPolygon$1");function isPointerInGraceArea(event,area){if(!area)return!1;const cursorPos={x:event.clientX,y:event.clientY};return isPointInPolygon$1(cursorPos,area)}__name(isPointerInGraceArea,"isPointerInGraceArea");function whenMouse(handler){return event=>event.pointerType==="mouse"?handler(event):void 0}__name(whenMouse,"whenMouse");var Root3$1=Menu,Anchor2=MenuAnchor,Portal=MenuPortal,Content2$3=MenuContent,Group=MenuGroup,Label$1=MenuLabel,Item2$1=MenuItem,CheckboxItem=MenuCheckboxItem,RadioGroup=MenuRadioGroup,RadioItem=MenuRadioItem,ItemIndicator=MenuItemIndicator,Separator$2=MenuSeparator,Arrow2=MenuArrow,SubTrigger=MenuSubTrigger,SubContent=MenuSubContent,DROPDOWN_MENU_NAME="DropdownMenu",[createDropdownMenuContext]=createContextScope$1(DROPDOWN_MENU_NAME,[createMenuScope]),useMenuScope=createMenuScope(),[DropdownMenuProvider,useDropdownMenuContext]=createDropdownMenuContext(DROPDOWN_MENU_NAME),DropdownMenu$1=__name(props=>{const{__scopeDropdownMenu,children:children2,dir,open:openProp,defaultOpen,onOpenChange,modal=!0}=props,menuScope=useMenuScope(__scopeDropdownMenu),triggerRef=reactExports.useRef(null),[open,setOpen]=useControllableState({prop:openProp,defaultProp:defaultOpen??!1,onChange:onOpenChange,caller:DROPDOWN_MENU_NAME});return jsxRuntimeExports.jsx(DropdownMenuProvider,{scope:__scopeDropdownMenu,triggerId:useId(),triggerRef,contentId:useId(),open,onOpenChange:setOpen,onOpenToggle:reactExports.useCallback(()=>setOpen(prevOpen=>!prevOpen),[setOpen]),modal,children:jsxRuntimeExports.jsx(Root3$1,{...menuScope,open,onOpenChange:setOpen,dir,modal,children:children2})})},"DropdownMenu$1");DropdownMenu$1.displayName=DROPDOWN_MENU_NAME;var TRIGGER_NAME$4="DropdownMenuTrigger",DropdownMenuTrigger$1=reactExports.forwardRef((props,forwardedRef)=>{const{__scopeDropdownMenu,disabled=!1,...triggerProps}=props,context=useDropdownMenuContext(TRIGGER_NAME$4,__scopeDropdownMenu),menuScope=useMenuScope(__scopeDropdownMenu);return jsxRuntimeExports.jsx(Anchor2,{asChild:!0,...menuScope,children:jsxRuntimeExports.jsx(Primitive$2.button,{type:"button",id:context.triggerId,"aria-haspopup":"menu","aria-expanded":context.open,"aria-controls":context.open?context.contentId:void 0,"data-state":context.open?"open":"closed","data-disabled":disabled?"":void 0,disabled,...triggerProps,ref:composeRefs(forwardedRef,context.triggerRef),onPointerDown:composeEventHandlers(props.onPointerDown,event=>{!disabled&&event.button===0&&event.ctrlKey===!1&&(context.onOpenToggle(),context.open||event.preventDefault())}),onKeyDown:composeEventHandlers(props.onKeyDown,event=>{disabled||(["Enter"," "].includes(event.key)&&context.onOpenToggle(),event.key==="ArrowDown"&&context.onOpenChange(!0),["Enter"," ","ArrowDown"].includes(event.key)&&event.preventDefault())})})})});DropdownMenuTrigger$1.displayName=TRIGGER_NAME$4;var PORTAL_NAME$1="DropdownMenuPortal",DropdownMenuPortal=__name(props=>{const{__scopeDropdownMenu,...portalProps}=props,menuScope=useMenuScope(__scopeDropdownMenu);return jsxRuntimeExports.jsx(Portal,{...menuScope,...portalProps})},"DropdownMenuPortal");DropdownMenuPortal.displayName=PORTAL_NAME$1;var CONTENT_NAME$4="DropdownMenuContent",DropdownMenuContent$1=reactExports.forwardRef((props,forwardedRef)=>{const{__scopeDropdownMenu,...contentProps}=props,context=useDropdownMenuContext(CONTENT_NAME$4,__scopeDropdownMenu),menuScope=useMenuScope(__scopeDropdownMenu),hasInteractedOutsideRef=reactExports.useRef(!1);return jsxRuntimeExports.jsx(Content2$3,{id:context.contentId,"aria-labelledby":context.triggerId,...menuScope,...contentProps,ref:forwardedRef,onCloseAutoFocus:composeEventHandlers(props.onCloseAutoFocus,event=>{hasInteractedOutsideRef.current||context.triggerRef.current?.focus(),hasInteractedOutsideRef.current=!1,event.preventDefault()}),onInteractOutside:composeEventHandlers(props.onInteractOutside,event=>{const originalEvent=event.detail.originalEvent,ctrlLeftClick=originalEvent.button===0&&originalEvent.ctrlKey===!0,isRightClick=originalEvent.button===2||ctrlLeftClick;(!context.modal||isRightClick)&&(hasInteractedOutsideRef.current=!0)}),style:{...props.style,"--radix-dropdown-menu-content-transform-origin":"var(--radix-popper-transform-origin)","--radix-dropdown-menu-content-available-width":"var(--radix-popper-available-width)","--radix-dropdown-menu-content-available-height":"var(--radix-popper-available-height)","--radix-dropdown-menu-trigger-width":"var(--radix-popper-anchor-width)","--radix-dropdown-menu-trigger-height":"var(--radix-popper-anchor-height)"}})});DropdownMenuContent$1.displayName=CONTENT_NAME$4;var GROUP_NAME="DropdownMenuGroup",DropdownMenuGroup=reactExports.forwardRef((props,forwardedRef)=>{const{__scopeDropdownMenu,...groupProps}=props,menuScope=useMenuScope(__scopeDropdownMenu);return jsxRuntimeExports.jsx(Group,{...menuScope,...groupProps,ref:forwardedRef})});DropdownMenuGroup.displayName=GROUP_NAME;var LABEL_NAME="DropdownMenuLabel",DropdownMenuLabel$1=reactExports.forwardRef((props,forwardedRef)=>{const{__scopeDropdownMenu,...labelProps}=props,menuScope=useMenuScope(__scopeDropdownMenu);return jsxRuntimeExports.jsx(Label$1,{...menuScope,...labelProps,ref:forwardedRef})});DropdownMenuLabel$1.displayName=LABEL_NAME;var ITEM_NAME$1="DropdownMenuItem",DropdownMenuItem$1=reactExports.forwardRef((props,forwardedRef)=>{const{__scopeDropdownMenu,...itemProps}=props,menuScope=useMenuScope(__scopeDropdownMenu);return jsxRuntimeExports.jsx(Item2$1,{...menuScope,...itemProps,ref:forwardedRef})});DropdownMenuItem$1.displayName=ITEM_NAME$1;var CHECKBOX_ITEM_NAME="DropdownMenuCheckboxItem",DropdownMenuCheckboxItem$1=reactExports.forwardRef((props,forwardedRef)=>{const{__scopeDropdownMenu,...checkboxItemProps}=props,menuScope=useMenuScope(__scopeDropdownMenu);return jsxRuntimeExports.jsx(CheckboxItem,{...menuScope,...checkboxItemProps,ref:forwardedRef})});DropdownMenuCheckboxItem$1.displayName=CHECKBOX_ITEM_NAME;var RADIO_GROUP_NAME="DropdownMenuRadioGroup",DropdownMenuRadioGroup=reactExports.forwardRef((props,forwardedRef)=>{const{__scopeDropdownMenu,...radioGroupProps}=props,menuScope=useMenuScope(__scopeDropdownMenu);return jsxRuntimeExports.jsx(RadioGroup,{...menuScope,...radioGroupProps,ref:forwardedRef})});DropdownMenuRadioGroup.displayName=RADIO_GROUP_NAME;var RADIO_ITEM_NAME="DropdownMenuRadioItem",DropdownMenuRadioItem$1=reactExports.forwardRef((props,forwardedRef)=>{const{__scopeDropdownMenu,...radioItemProps}=props,menuScope=useMenuScope(__scopeDropdownMenu);return jsxRuntimeExports.jsx(RadioItem,{...menuScope,...radioItemProps,ref:forwardedRef})});DropdownMenuRadioItem$1.displayName=RADIO_ITEM_NAME;var INDICATOR_NAME="DropdownMenuItemIndicator",DropdownMenuItemIndicator=reactExports.forwardRef((props,forwardedRef)=>{const{__scopeDropdownMenu,...itemIndicatorProps}=props,menuScope=useMenuScope(__scopeDropdownMenu);return jsxRuntimeExports.jsx(ItemIndicator,{...menuScope,...itemIndicatorProps,ref:forwardedRef})});DropdownMenuItemIndicator.displayName=INDICATOR_NAME;var SEPARATOR_NAME="DropdownMenuSeparator",DropdownMenuSeparator$1=reactExports.forwardRef((props,forwardedRef)=>{const{__scopeDropdownMenu,...separatorProps}=props,menuScope=useMenuScope(__scopeDropdownMenu);return jsxRuntimeExports.jsx(Separator$2,{...menuScope,...separatorProps,ref:forwardedRef})});DropdownMenuSeparator$1.displayName=SEPARATOR_NAME;var ARROW_NAME$1="DropdownMenuArrow",DropdownMenuArrow=reactExports.forwardRef((props,forwardedRef)=>{const{__scopeDropdownMenu,...arrowProps}=props,menuScope=useMenuScope(__scopeDropdownMenu);return jsxRuntimeExports.jsx(Arrow2,{...menuScope,...arrowProps,ref:forwardedRef})});DropdownMenuArrow.displayName=ARROW_NAME$1;var SUB_TRIGGER_NAME="DropdownMenuSubTrigger",DropdownMenuSubTrigger$1=reactExports.forwardRef((props,forwardedRef)=>{const{__scopeDropdownMenu,...subTriggerProps}=props,menuScope=useMenuScope(__scopeDropdownMenu);return jsxRuntimeExports.jsx(SubTrigger,{...menuScope,...subTriggerProps,ref:forwardedRef})});DropdownMenuSubTrigger$1.displayName=SUB_TRIGGER_NAME;var SUB_CONTENT_NAME="DropdownMenuSubContent",DropdownMenuSubContent$1=reactExports.forwardRef((props,forwardedRef)=>{const{__scopeDropdownMenu,...subContentProps}=props,menuScope=useMenuScope(__scopeDropdownMenu);return jsxRuntimeExports.jsx(SubContent,{...menuScope,...subContentProps,ref:forwardedRef,style:{...props.style,"--radix-dropdown-menu-content-transform-origin":"var(--radix-popper-transform-origin)","--radix-dropdown-menu-content-available-width":"var(--radix-popper-available-width)","--radix-dropdown-menu-content-available-height":"var(--radix-popper-available-height)","--radix-dropdown-menu-trigger-width":"var(--radix-popper-anchor-width)","--radix-dropdown-menu-trigger-height":"var(--radix-popper-anchor-height)"}})});DropdownMenuSubContent$1.displayName=SUB_CONTENT_NAME;var Root2$2=DropdownMenu$1,Trigger$3=DropdownMenuTrigger$1,Portal2=DropdownMenuPortal,Content2$2=DropdownMenuContent$1,Label2=DropdownMenuLabel$1,Item2=DropdownMenuItem$1,CheckboxItem2=DropdownMenuCheckboxItem$1,RadioItem2=DropdownMenuRadioItem$1,ItemIndicator2=DropdownMenuItemIndicator,Separator2=DropdownMenuSeparator$1,SubTrigger2=DropdownMenuSubTrigger$1,SubContent2=DropdownMenuSubContent$1;const DropdownMenu=Root2$2,DropdownMenuTrigger=Trigger$3,DropdownMenuSubTrigger=reactExports.forwardRef(({className,inset,children:children2,...props},ref)=>jsxRuntimeExports.jsxs(SubTrigger2,{ref,className:cn$2("flex cursor-default select-none items-center rounded-sm px-2 py-1.5 text-sm outline-none focus:bg-accent data-[state=open]:bg-accent",inset&&"pl-8",className),...props,children:[children2,jsxRuntimeExports.jsx(ChevronRight,{className:"ml-auto h-4 w-4"})]}));DropdownMenuSubTrigger.displayName=SubTrigger2.displayName;const DropdownMenuSubContent=reactExports.forwardRef(({className,...props},ref)=>jsxRuntimeExports.jsx(SubContent2,{ref,className:cn$2("z-50 min-w-[8rem] overflow-hidden rounded-md border bg-popover p-1 text-popover-foreground shadow-lg data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2",className),...props}));DropdownMenuSubContent.displayName=SubContent2.displayName;const DropdownMenuContent=reactExports.forwardRef(({className,sideOffset=4,...props},ref)=>jsxRuntimeExports.jsx(Portal2,{children:jsxRuntimeExports.jsx(Content2$2,{ref,sideOffset,className:cn$2("z-50 min-w-[8rem] overflow-hidden rounded-md border bg-popover p-1 text-popover-foreground shadow-md data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2",className),...props})}));DropdownMenuContent.displayName=Content2$2.displayName;const DropdownMenuItem=reactExports.forwardRef(({className,inset,...props},ref)=>jsxRuntimeExports.jsx(Item2,{ref,className:cn$2("relative flex cursor-default select-none items-center rounded-sm px-2 py-1.5 text-sm outline-none transition-colors focus:bg-accent focus:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50",inset&&"pl-8",className),...props}));DropdownMenuItem.displayName=Item2.displayName;const DropdownMenuCheckboxItem=reactExports.forwardRef(({className,children:children2,checked,...props},ref)=>jsxRuntimeExports.jsxs(CheckboxItem2,{ref,className:cn$2("relative flex cursor-default select-none items-center rounded-sm py-1.5 pl-8 pr-2 text-sm outline-none transition-colors focus:bg-accent focus:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50",className),checked,...props,children:[jsxRuntimeExports.jsx("span",{className:"absolute left-2 flex h-3.5 w-3.5 items-center justify-center",children:jsxRuntimeExports.jsx(ItemIndicator2,{children:jsxRuntimeExports.jsx(Check,{className:"h-4 w-4"})})}),children2]}));DropdownMenuCheckboxItem.displayName=CheckboxItem2.displayName;const DropdownMenuRadioItem=reactExports.forwardRef(({className,children:children2,...props},ref)=>jsxRuntimeExports.jsxs(RadioItem2,{ref,className:cn$2("relative flex cursor-default select-none items-center rounded-sm py-1.5 pl-8 pr-2 text-sm outline-none transition-colors focus:bg-accent focus:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50",className),...props,children:[jsxRuntimeExports.jsx("span",{className:"absolute left-2 flex h-3.5 w-3.5 items-center justify-center",children:jsxRuntimeExports.jsx(ItemIndicator2,{children:jsxRuntimeExports.jsx(Circle,{className:"h-2 w-2 fill-current"})})}),children2]}));DropdownMenuRadioItem.displayName=RadioItem2.displayName;const DropdownMenuLabel=reactExports.forwardRef(({className,inset,...props},ref)=>jsxRuntimeExports.jsx(Label2,{ref,className:cn$2("px-2 py-1.5 text-sm font-semibold",inset&&"pl-8",className),...props}));DropdownMenuLabel.displayName=Label2.displayName;const DropdownMenuSeparator=reactExports.forwardRef(({className,...props},ref)=>jsxRuntimeExports.jsx(Separator2,{ref,className:cn$2("-mx-1 my-1 h-px bg-muted",className),...props}));DropdownMenuSeparator.displayName=Separator2.displayName;function _objectWithoutPropertiesLoose$j(source,excluded){if(source==null)return{};var target={},sourceKeys=Object.keys(source),key,i2;for(i2=0;i2=0)&&(target[key]=source[key]);return target}__name(_objectWithoutPropertiesLoose$j,"_objectWithoutPropertiesLoose$j");var _excluded$e$1=["color"],ArrowDownIcon=reactExports.forwardRef(function(_ref,forwardedRef){var _ref$color=_ref.color,color=_ref$color===void 0?"currentColor":_ref$color,props=_objectWithoutPropertiesLoose$j(_ref,_excluded$e$1);return reactExports.createElement("svg",Object.assign({width:"15",height:"15",viewBox:"0 0 15 15",fill:"none",xmlns:"http://www.w3.org/2000/svg"},props,{ref:forwardedRef}),reactExports.createElement("path",{d:"M7.5 2C7.77614 2 8 2.22386 8 2.5L8 11.2929L11.1464 8.14645C11.3417 7.95118 11.6583 7.95118 11.8536 8.14645C12.0488 8.34171 12.0488 8.65829 11.8536 8.85355L7.85355 12.8536C7.75979 12.9473 7.63261 13 7.5 13C7.36739 13 7.24021 12.9473 7.14645 12.8536L3.14645 8.85355C2.95118 8.65829 2.95118 8.34171 3.14645 8.14645C3.34171 7.95118 3.65829 7.95118 3.85355 8.14645L7 11.2929L7 2.5C7 2.22386 7.22386 2 7.5 2Z",fill:color,fillRule:"evenodd",clipRule:"evenodd"}))}),_excluded$g$1=["color"],ArrowRightIcon=reactExports.forwardRef(function(_ref,forwardedRef){var _ref$color=_ref.color,color=_ref$color===void 0?"currentColor":_ref$color,props=_objectWithoutPropertiesLoose$j(_ref,_excluded$g$1);return reactExports.createElement("svg",Object.assign({width:"15",height:"15",viewBox:"0 0 15 15",fill:"none",xmlns:"http://www.w3.org/2000/svg"},props,{ref:forwardedRef}),reactExports.createElement("path",{d:"M8.14645 3.14645C8.34171 2.95118 8.65829 2.95118 8.85355 3.14645L12.8536 7.14645C13.0488 7.34171 13.0488 7.65829 12.8536 7.85355L8.85355 11.8536C8.65829 12.0488 8.34171 12.0488 8.14645 11.8536C7.95118 11.6583 7.95118 11.3417 8.14645 11.1464L11.2929 8H2.5C2.22386 8 2 7.77614 2 7.5C2 7.22386 2.22386 7 2.5 7H11.2929L8.14645 3.85355C7.95118 3.65829 7.95118 3.34171 8.14645 3.14645Z",fill:color,fillRule:"evenodd",clipRule:"evenodd"}))}),_excluded$j=["color"],ArrowUpIcon=reactExports.forwardRef(function(_ref,forwardedRef){var _ref$color=_ref.color,color=_ref$color===void 0?"currentColor":_ref$color,props=_objectWithoutPropertiesLoose$j(_ref,_excluded$j);return reactExports.createElement("svg",Object.assign({width:"15",height:"15",viewBox:"0 0 15 15",fill:"none",xmlns:"http://www.w3.org/2000/svg"},props,{ref:forwardedRef}),reactExports.createElement("path",{d:"M7.14645 2.14645C7.34171 1.95118 7.65829 1.95118 7.85355 2.14645L11.8536 6.14645C12.0488 6.34171 12.0488 6.65829 11.8536 6.85355C11.6583 7.04882 11.3417 7.04882 11.1464 6.85355L8 3.70711L8 12.5C8 12.7761 7.77614 13 7.5 13C7.22386 13 7 12.7761 7 12.5L7 3.70711L3.85355 6.85355C3.65829 7.04882 3.34171 7.04882 3.14645 6.85355C2.95118 6.65829 2.95118 6.34171 3.14645 6.14645L7.14645 2.14645Z",fill:color,fillRule:"evenodd",clipRule:"evenodd"}))}),_excluded$U=["color"],CheckCircledIcon=reactExports.forwardRef(function(_ref,forwardedRef){var _ref$color=_ref.color,color=_ref$color===void 0?"currentColor":_ref$color,props=_objectWithoutPropertiesLoose$j(_ref,_excluded$U);return reactExports.createElement("svg",Object.assign({width:"15",height:"15",viewBox:"0 0 15 15",fill:"none",xmlns:"http://www.w3.org/2000/svg"},props,{ref:forwardedRef}),reactExports.createElement("path",{d:"M7.49991 0.877045C3.84222 0.877045 0.877075 3.84219 0.877075 7.49988C0.877075 11.1575 3.84222 14.1227 7.49991 14.1227C11.1576 14.1227 14.1227 11.1575 14.1227 7.49988C14.1227 3.84219 11.1576 0.877045 7.49991 0.877045ZM1.82708 7.49988C1.82708 4.36686 4.36689 1.82704 7.49991 1.82704C10.6329 1.82704 13.1727 4.36686 13.1727 7.49988C13.1727 10.6329 10.6329 13.1727 7.49991 13.1727C4.36689 13.1727 1.82708 10.6329 1.82708 7.49988ZM10.1589 5.53774C10.3178 5.31191 10.2636 5.00001 10.0378 4.84109C9.81194 4.68217 9.50004 4.73642 9.34112 4.96225L6.51977 8.97154L5.35681 7.78706C5.16334 7.59002 4.84677 7.58711 4.64973 7.78058C4.45268 7.97404 4.44978 8.29061 4.64325 8.48765L6.22658 10.1003C6.33054 10.2062 6.47617 10.2604 6.62407 10.2483C6.77197 10.2363 6.90686 10.1591 6.99226 10.0377L10.1589 5.53774Z",fill:color,fillRule:"evenodd",clipRule:"evenodd"}))}),_excluded$W=["color"],ChevronDownIcon=reactExports.forwardRef(function(_ref,forwardedRef){var _ref$color=_ref.color,color=_ref$color===void 0?"currentColor":_ref$color,props=_objectWithoutPropertiesLoose$j(_ref,_excluded$W);return reactExports.createElement("svg",Object.assign({width:"15",height:"15",viewBox:"0 0 15 15",fill:"none",xmlns:"http://www.w3.org/2000/svg"},props,{ref:forwardedRef}),reactExports.createElement("path",{d:"M3.13523 6.15803C3.3241 5.95657 3.64052 5.94637 3.84197 6.13523L7.5 9.56464L11.158 6.13523C11.3595 5.94637 11.6759 5.95657 11.8648 6.15803C12.0536 6.35949 12.0434 6.67591 11.842 6.86477L7.84197 10.6148C7.64964 10.7951 7.35036 10.7951 7.15803 10.6148L3.15803 6.86477C2.95657 6.67591 2.94637 6.35949 3.13523 6.15803Z",fill:color,fillRule:"evenodd",clipRule:"evenodd"}))}),_excluded$1s=["color"],CrossCircledIcon=reactExports.forwardRef(function(_ref,forwardedRef){var _ref$color=_ref.color,color=_ref$color===void 0?"currentColor":_ref$color,props=_objectWithoutPropertiesLoose$j(_ref,_excluded$1s);return reactExports.createElement("svg",Object.assign({width:"15",height:"15",viewBox:"0 0 15 15",fill:"none",xmlns:"http://www.w3.org/2000/svg"},props,{ref:forwardedRef}),reactExports.createElement("path",{d:"M0.877075 7.49988C0.877075 3.84219 3.84222 0.877045 7.49991 0.877045C11.1576 0.877045 14.1227 3.84219 14.1227 7.49988C14.1227 11.1575 11.1576 14.1227 7.49991 14.1227C3.84222 14.1227 0.877075 11.1575 0.877075 7.49988ZM7.49991 1.82704C4.36689 1.82704 1.82708 4.36686 1.82708 7.49988C1.82708 10.6329 4.36689 13.1727 7.49991 13.1727C10.6329 13.1727 13.1727 10.6329 13.1727 7.49988C13.1727 4.36686 10.6329 1.82704 7.49991 1.82704ZM9.85358 5.14644C10.0488 5.3417 10.0488 5.65829 9.85358 5.85355L8.20713 7.49999L9.85358 9.14644C10.0488 9.3417 10.0488 9.65829 9.85358 9.85355C9.65832 10.0488 9.34173 10.0488 9.14647 9.85355L7.50002 8.2071L5.85358 9.85355C5.65832 10.0488 5.34173 10.0488 5.14647 9.85355C4.95121 9.65829 4.95121 9.3417 5.14647 9.14644L6.79292 7.49999L5.14647 5.85355C4.95121 5.65829 4.95121 5.3417 5.14647 5.14644C5.34173 4.95118 5.65832 4.95118 5.85358 5.14644L7.50002 6.79289L9.14647 5.14644C9.34173 4.95118 9.65832 4.95118 9.85358 5.14644Z",fill:color,fillRule:"evenodd",clipRule:"evenodd"}))}),_excluded$20=["color"],ExclamationTriangleIcon=reactExports.forwardRef(function(_ref,forwardedRef){var _ref$color=_ref.color,color=_ref$color===void 0?"currentColor":_ref$color,props=_objectWithoutPropertiesLoose$j(_ref,_excluded$20);return reactExports.createElement("svg",Object.assign({width:"15",height:"15",viewBox:"0 0 15 15",fill:"none",xmlns:"http://www.w3.org/2000/svg"},props,{ref:forwardedRef}),reactExports.createElement("path",{d:"M8.4449 0.608765C8.0183 -0.107015 6.9817 -0.107015 6.55509 0.608766L0.161178 11.3368C-0.275824 12.07 0.252503 13 1.10608 13H13.8939C14.7475 13 15.2758 12.07 14.8388 11.3368L8.4449 0.608765ZM7.4141 1.12073C7.45288 1.05566 7.54712 1.05566 7.5859 1.12073L13.9798 11.8488C14.0196 11.9154 13.9715 12 13.8939 12H1.10608C1.02849 12 0.980454 11.9154 1.02018 11.8488L7.4141 1.12073ZM6.8269 4.48611C6.81221 4.10423 7.11783 3.78663 7.5 3.78663C7.88217 3.78663 8.18778 4.10423 8.1731 4.48612L8.01921 8.48701C8.00848 8.766 7.7792 8.98664 7.5 8.98664C7.2208 8.98664 6.99151 8.766 6.98078 8.48701L6.8269 4.48611ZM8.24989 10.476C8.24989 10.8902 7.9141 11.226 7.49989 11.226C7.08567 11.226 6.74989 10.8902 6.74989 10.476C6.74989 10.0618 7.08567 9.72599 7.49989 9.72599C7.9141 9.72599 8.24989 10.0618 8.24989 10.476Z",fill:color,fillRule:"evenodd",clipRule:"evenodd"}))}),_excluded$37=["color"],MinusIcon=reactExports.forwardRef(function(_ref,forwardedRef){var _ref$color=_ref.color,color=_ref$color===void 0?"currentColor":_ref$color,props=_objectWithoutPropertiesLoose$j(_ref,_excluded$37);return reactExports.createElement("svg",Object.assign({width:"15",height:"15",viewBox:"0 0 15 15",fill:"none",xmlns:"http://www.w3.org/2000/svg"},props,{ref:forwardedRef}),reactExports.createElement("path",{d:"M2.25 7.5C2.25 7.22386 2.47386 7 2.75 7H12.25C12.5261 7 12.75 7.22386 12.75 7.5C12.75 7.77614 12.5261 8 12.25 8H2.75C2.47386 8 2.25 7.77614 2.25 7.5Z",fill:color,fillRule:"evenodd",clipRule:"evenodd"}))}),_excluded$3e=["color"],MoonIcon=reactExports.forwardRef(function(_ref,forwardedRef){var _ref$color=_ref.color,color=_ref$color===void 0?"currentColor":_ref$color,props=_objectWithoutPropertiesLoose$j(_ref,_excluded$3e);return reactExports.createElement("svg",Object.assign({width:"15",height:"15",viewBox:"0 0 15 15",fill:"none",xmlns:"http://www.w3.org/2000/svg"},props,{ref:forwardedRef}),reactExports.createElement("path",{d:"M2.89998 0.499976C2.89998 0.279062 2.72089 0.0999756 2.49998 0.0999756C2.27906 0.0999756 2.09998 0.279062 2.09998 0.499976V1.09998H1.49998C1.27906 1.09998 1.09998 1.27906 1.09998 1.49998C1.09998 1.72089 1.27906 1.89998 1.49998 1.89998H2.09998V2.49998C2.09998 2.72089 2.27906 2.89998 2.49998 2.89998C2.72089 2.89998 2.89998 2.72089 2.89998 2.49998V1.89998H3.49998C3.72089 1.89998 3.89998 1.72089 3.89998 1.49998C3.89998 1.27906 3.72089 1.09998 3.49998 1.09998H2.89998V0.499976ZM5.89998 3.49998C5.89998 3.27906 5.72089 3.09998 5.49998 3.09998C5.27906 3.09998 5.09998 3.27906 5.09998 3.49998V4.09998H4.49998C4.27906 4.09998 4.09998 4.27906 4.09998 4.49998C4.09998 4.72089 4.27906 4.89998 4.49998 4.89998H5.09998V5.49998C5.09998 5.72089 5.27906 5.89998 5.49998 5.89998C5.72089 5.89998 5.89998 5.72089 5.89998 5.49998V4.89998H6.49998C6.72089 4.89998 6.89998 4.72089 6.89998 4.49998C6.89998 4.27906 6.72089 4.09998 6.49998 4.09998H5.89998V3.49998ZM1.89998 6.49998C1.89998 6.27906 1.72089 6.09998 1.49998 6.09998C1.27906 6.09998 1.09998 6.27906 1.09998 6.49998V7.09998H0.499976C0.279062 7.09998 0.0999756 7.27906 0.0999756 7.49998C0.0999756 7.72089 0.279062 7.89998 0.499976 7.89998H1.09998V8.49998C1.09998 8.72089 1.27906 8.89997 1.49998 8.89997C1.72089 8.89997 1.89998 8.72089 1.89998 8.49998V7.89998H2.49998C2.72089 7.89998 2.89998 7.72089 2.89998 7.49998C2.89998 7.27906 2.72089 7.09998 2.49998 7.09998H1.89998V6.49998ZM8.54406 0.98184L8.24618 0.941586C8.03275 0.917676 7.90692 1.1655 8.02936 1.34194C8.17013 1.54479 8.29981 1.75592 8.41754 1.97445C8.91878 2.90485 9.20322 3.96932 9.20322 5.10022C9.20322 8.37201 6.82247 11.0878 3.69887 11.6097C3.45736 11.65 3.20988 11.6772 2.96008 11.6906C2.74563 11.702 2.62729 11.9535 2.77721 12.1072C2.84551 12.1773 2.91535 12.2458 2.98667 12.3128L3.05883 12.3795L3.31883 12.6045L3.50684 12.7532L3.62796 12.8433L3.81491 12.9742L3.99079 13.089C4.11175 13.1651 4.23536 13.2375 4.36157 13.3059L4.62496 13.4412L4.88553 13.5607L5.18837 13.6828L5.43169 13.7686C5.56564 13.8128 5.70149 13.8529 5.83857 13.8885C5.94262 13.9155 6.04767 13.9401 6.15405 13.9622C6.27993 13.9883 6.40713 14.0109 6.53544 14.0298L6.85241 14.0685L7.11934 14.0892C7.24637 14.0965 7.37436 14.1002 7.50322 14.1002C11.1483 14.1002 14.1032 11.1453 14.1032 7.50023C14.1032 7.25044 14.0893 7.00389 14.0623 6.76131L14.0255 6.48407C13.991 6.26083 13.9453 6.04129 13.8891 5.82642C13.8213 5.56709 13.7382 5.31398 13.6409 5.06881L13.5279 4.80132L13.4507 4.63542L13.3766 4.48666C13.2178 4.17773 13.0353 3.88295 12.8312 3.60423L12.6782 3.40352L12.4793 3.16432L12.3157 2.98361L12.1961 2.85951L12.0355 2.70246L11.8134 2.50184L11.4925 2.24191L11.2483 2.06498L10.9562 1.87446L10.6346 1.68894L10.3073 1.52378L10.1938 1.47176L9.95488 1.3706L9.67791 1.2669L9.42566 1.1846L9.10075 1.09489L8.83599 1.03486L8.54406 0.98184ZM10.4032 5.30023C10.4032 4.27588 10.2002 3.29829 9.83244 2.40604C11.7623 3.28995 13.1032 5.23862 13.1032 7.50023C13.1032 10.593 10.596 13.1002 7.50322 13.1002C6.63646 13.1002 5.81597 12.9036 5.08355 12.5522C6.5419 12.0941 7.81081 11.2082 8.74322 10.0416C8.87963 10.2284 9.10028 10.3497 9.34928 10.3497C9.76349 10.3497 10.0993 10.0139 10.0993 9.59971C10.0993 9.24256 9.84965 8.94373 9.51535 8.86816C9.57741 8.75165 9.63653 8.63334 9.6926 8.51332C9.88358 8.63163 10.1088 8.69993 10.35 8.69993C11.0403 8.69993 11.6 8.14028 11.6 7.44993C11.6 6.75976 11.0406 6.20024 10.3505 6.19993C10.3853 5.90487 10.4032 5.60464 10.4032 5.30023Z",fill:color,fillRule:"evenodd",clipRule:"evenodd"}))}),_excluded$3A=["color"],QuestionMarkCircledIcon=reactExports.forwardRef(function(_ref,forwardedRef){var _ref$color=_ref.color,color=_ref$color===void 0?"currentColor":_ref$color,props=_objectWithoutPropertiesLoose$j(_ref,_excluded$3A);return reactExports.createElement("svg",Object.assign({width:"15",height:"15",viewBox:"0 0 15 15",fill:"none",xmlns:"http://www.w3.org/2000/svg"},props,{ref:forwardedRef}),reactExports.createElement("path",{d:"M0.877075 7.49972C0.877075 3.84204 3.84222 0.876892 7.49991 0.876892C11.1576 0.876892 14.1227 3.84204 14.1227 7.49972C14.1227 11.1574 11.1576 14.1226 7.49991 14.1226C3.84222 14.1226 0.877075 11.1574 0.877075 7.49972ZM7.49991 1.82689C4.36689 1.82689 1.82708 4.36671 1.82708 7.49972C1.82708 10.6327 4.36689 13.1726 7.49991 13.1726C10.6329 13.1726 13.1727 10.6327 13.1727 7.49972C13.1727 4.36671 10.6329 1.82689 7.49991 1.82689ZM8.24993 10.5C8.24993 10.9142 7.91414 11.25 7.49993 11.25C7.08571 11.25 6.74993 10.9142 6.74993 10.5C6.74993 10.0858 7.08571 9.75 7.49993 9.75C7.91414 9.75 8.24993 10.0858 8.24993 10.5ZM6.05003 6.25C6.05003 5.57211 6.63511 4.925 7.50003 4.925C8.36496 4.925 8.95003 5.57211 8.95003 6.25C8.95003 6.74118 8.68002 6.99212 8.21447 7.27494C8.16251 7.30651 8.10258 7.34131 8.03847 7.37854L8.03841 7.37858C7.85521 7.48497 7.63788 7.61119 7.47449 7.73849C7.23214 7.92732 6.95003 8.23198 6.95003 8.7C6.95004 9.00376 7.19628 9.25 7.50004 9.25C7.8024 9.25 8.04778 9.00601 8.05002 8.70417L8.05056 8.7033C8.05924 8.6896 8.08493 8.65735 8.15058 8.6062C8.25207 8.52712 8.36508 8.46163 8.51567 8.37436L8.51571 8.37433C8.59422 8.32883 8.68296 8.27741 8.78559 8.21506C9.32004 7.89038 10.05 7.35382 10.05 6.25C10.05 4.92789 8.93511 3.825 7.50003 3.825C6.06496 3.825 4.95003 4.92789 4.95003 6.25C4.95003 6.55376 5.19628 6.8 5.50003 6.8C5.80379 6.8 6.05003 6.55376 6.05003 6.25Z",fill:color,fillRule:"evenodd",clipRule:"evenodd"}))}),_excluded$4e=["color"],StopwatchIcon=reactExports.forwardRef(function(_ref,forwardedRef){var _ref$color=_ref.color,color=_ref$color===void 0?"currentColor":_ref$color,props=_objectWithoutPropertiesLoose$j(_ref,_excluded$4e);return reactExports.createElement("svg",Object.assign({width:"15",height:"15",viewBox:"0 0 15 15",fill:"none",xmlns:"http://www.w3.org/2000/svg"},props,{ref:forwardedRef}),reactExports.createElement("path",{d:"M5.49998 0.5C5.49998 0.223858 5.72383 0 5.99998 0H7.49998H8.99998C9.27612 0 9.49998 0.223858 9.49998 0.5C9.49998 0.776142 9.27612 1 8.99998 1H7.99998V2.11922C9.09832 2.20409 10.119 2.56622 10.992 3.13572C11.0116 3.10851 11.0336 3.08252 11.058 3.05806L11.858 2.25806C12.1021 2.01398 12.4978 2.01398 12.7419 2.25806C12.986 2.50214 12.986 2.89786 12.7419 3.14194L11.967 3.91682C13.1595 5.07925 13.9 6.70314 13.9 8.49998C13.9 12.0346 11.0346 14.9 7.49998 14.9C3.96535 14.9 1.09998 12.0346 1.09998 8.49998C1.09998 5.13362 3.69904 2.3743 6.99998 2.11922V1H5.99998C5.72383 1 5.49998 0.776142 5.49998 0.5ZM2.09998 8.49998C2.09998 5.51764 4.51764 3.09998 7.49998 3.09998C10.4823 3.09998 12.9 5.51764 12.9 8.49998C12.9 11.4823 10.4823 13.9 7.49998 13.9C4.51764 13.9 2.09998 11.4823 2.09998 8.49998ZM7.99998 4.5C7.99998 4.22386 7.77612 4 7.49998 4C7.22383 4 6.99998 4.22386 6.99998 4.5V9.5C6.99998 9.77614 7.22383 10 7.49998 10C7.77612 10 7.99998 9.77614 7.99998 9.5V4.5Z",fill:color,fillRule:"evenodd",clipRule:"evenodd"}))}),_excluded$4i=["color"],SunIcon=reactExports.forwardRef(function(_ref,forwardedRef){var _ref$color=_ref.color,color=_ref$color===void 0?"currentColor":_ref$color,props=_objectWithoutPropertiesLoose$j(_ref,_excluded$4i);return reactExports.createElement("svg",Object.assign({width:"15",height:"15",viewBox:"0 0 15 15",fill:"none",xmlns:"http://www.w3.org/2000/svg"},props,{ref:forwardedRef}),reactExports.createElement("path",{d:"M7.5 0C7.77614 0 8 0.223858 8 0.5V2.5C8 2.77614 7.77614 3 7.5 3C7.22386 3 7 2.77614 7 2.5V0.5C7 0.223858 7.22386 0 7.5 0ZM2.1967 2.1967C2.39196 2.00144 2.70854 2.00144 2.90381 2.1967L4.31802 3.61091C4.51328 3.80617 4.51328 4.12276 4.31802 4.31802C4.12276 4.51328 3.80617 4.51328 3.61091 4.31802L2.1967 2.90381C2.00144 2.70854 2.00144 2.39196 2.1967 2.1967ZM0.5 7C0.223858 7 0 7.22386 0 7.5C0 7.77614 0.223858 8 0.5 8H2.5C2.77614 8 3 7.77614 3 7.5C3 7.22386 2.77614 7 2.5 7H0.5ZM2.1967 12.8033C2.00144 12.608 2.00144 12.2915 2.1967 12.0962L3.61091 10.682C3.80617 10.4867 4.12276 10.4867 4.31802 10.682C4.51328 10.8772 4.51328 11.1938 4.31802 11.3891L2.90381 12.8033C2.70854 12.9986 2.39196 12.9986 2.1967 12.8033ZM12.5 7C12.2239 7 12 7.22386 12 7.5C12 7.77614 12.2239 8 12.5 8H14.5C14.7761 8 15 7.77614 15 7.5C15 7.22386 14.7761 7 14.5 7H12.5ZM10.682 4.31802C10.4867 4.12276 10.4867 3.80617 10.682 3.61091L12.0962 2.1967C12.2915 2.00144 12.608 2.00144 12.8033 2.1967C12.9986 2.39196 12.9986 2.70854 12.8033 2.90381L11.3891 4.31802C11.1938 4.51328 10.8772 4.51328 10.682 4.31802ZM8 12.5C8 12.2239 7.77614 12 7.5 12C7.22386 12 7 12.2239 7 12.5V14.5C7 14.7761 7.22386 15 7.5 15C7.77614 15 8 14.7761 8 14.5V12.5ZM10.682 10.682C10.8772 10.4867 11.1938 10.4867 11.3891 10.682L12.8033 12.0962C12.9986 12.2915 12.9986 12.608 12.8033 12.8033C12.608 12.9986 12.2915 12.9986 12.0962 12.8033L10.682 11.3891C10.4867 11.1938 10.4867 10.8772 10.682 10.682ZM5.5 7.5C5.5 6.39543 6.39543 5.5 7.5 5.5C8.60457 5.5 9.5 6.39543 9.5 7.5C9.5 8.60457 8.60457 9.5 7.5 9.5C6.39543 9.5 5.5 8.60457 5.5 7.5ZM7.5 4.5C5.84315 4.5 4.5 5.84315 4.5 7.5C4.5 9.15685 5.84315 10.5 7.5 10.5C9.15685 10.5 10.5 9.15685 10.5 7.5C10.5 5.84315 9.15685 4.5 7.5 4.5Z",fill:color,fillRule:"evenodd",clipRule:"evenodd"}))}),_excluded$4W=["color"],ViewVerticalIcon=reactExports.forwardRef(function(_ref,forwardedRef){var _ref$color=_ref.color,color=_ref$color===void 0?"currentColor":_ref$color,props=_objectWithoutPropertiesLoose$j(_ref,_excluded$4W);return reactExports.createElement("svg",Object.assign({width:"15",height:"15",viewBox:"0 0 15 15",fill:"none",xmlns:"http://www.w3.org/2000/svg"},props,{ref:forwardedRef}),reactExports.createElement("path",{d:"M8 2H13.5C13.7761 2 14 2.22386 14 2.5V12.5C14 12.7761 13.7761 13 13.5 13H8V2ZM7 2H1.5C1.22386 2 1 2.22386 1 2.5V12.5C1 12.7761 1.22386 13 1.5 13H7V2ZM0 2.5C0 1.67157 0.671573 1 1.5 1H13.5C14.3284 1 15 1.67157 15 2.5V12.5C15 13.3284 14.3284 14 13.5 14H1.5C0.671573 14 0 13.3284 0 12.5V2.5Z",fill:color,fillRule:"evenodd",clipRule:"evenodd"}))});function useTheme(){const context=reactExports.useContext(ThemeProviderContext);if(context===void 0)throw new Error("useTheme must be used within a ThemeProvider");return context}__name(useTheme,"useTheme");function ModeToggle(){const{theme,setTheme}=useTheme(),toggleTheme=__name(()=>{if(theme==="dark")setTheme("light");else if(theme==="light")setTheme("dark");else{const systemTheme=window.matchMedia("(prefers-color-scheme: dark)").matches?"dark":"light";setTheme(systemTheme==="dark"?"light":"dark")}},"toggleTheme");return jsxRuntimeExports.jsxs(Button,{variant:"ghost",className:"w-9 px-0",onClick:toggleTheme,children:[jsxRuntimeExports.jsx(SunIcon,{className:"h-[1.2rem] w-[1.2rem] rotate-0 scale-100 transition-all dark:-rotate-90 dark:scale-0"}),jsxRuntimeExports.jsx(MoonIcon,{className:"absolute h-[1.2rem] w-[1.2rem] rotate-90 scale-0 transition-all dark:rotate-0 dark:scale-100"}),jsxRuntimeExports.jsx("span",{className:"sr-only",children:"Toggle theme"})]})}__name(ModeToggle,"ModeToggle");const allMenuItems=[{title:"Overview",to:""},{title:"Identity",to:"identity"},{title:"Devices",to:"devices"},{title:"Network",to:"network"},{title:"Infrastructure",to:"infrastructure"},{title:"Data",to:"data"},{title:"SecOps",to:"secops"},{title:"AI",to:"ai"}],mainMenu=allMenuItems.filter(item=>item.title==="Network"?reportData.TestResultSummary?.NetworkTotal!==void 0:item.title==="Data"?reportData.TestResultSummary?.DataTotal!==void 0:item.title==="Infrastructure"?reportData.TestResultSummary?.InfrastructureTotal!==void 0:item.title==="SecOps"?reportData.TestResultSummary?.SecOpsTotal!==void 0:item.title==="AI"?reportData.TestResultSummary?.AITotal!==void 0:!0);function clamp(value2,[min2,max2]){return Math.min(max2,Math.max(min2,value2))}__name(clamp,"clamp");function useStateMachine(initialState2,machine){return reactExports.useReducer((state,event)=>machine[state][event]??state,initialState2)}__name(useStateMachine,"useStateMachine");var SCROLL_AREA_NAME="ScrollArea",[createScrollAreaContext]=createContextScope$1(SCROLL_AREA_NAME),[ScrollAreaProvider,useScrollAreaContext]=createScrollAreaContext(SCROLL_AREA_NAME),ScrollArea=reactExports.forwardRef((props,forwardedRef)=>{const{__scopeScrollArea,type="hover",dir,scrollHideDelay=600,...scrollAreaProps}=props,[scrollArea,setScrollArea]=reactExports.useState(null),[viewport,setViewport]=reactExports.useState(null),[content2,setContent]=reactExports.useState(null),[scrollbarX,setScrollbarX]=reactExports.useState(null),[scrollbarY,setScrollbarY]=reactExports.useState(null),[cornerWidth,setCornerWidth]=reactExports.useState(0),[cornerHeight,setCornerHeight]=reactExports.useState(0),[scrollbarXEnabled,setScrollbarXEnabled]=reactExports.useState(!1),[scrollbarYEnabled,setScrollbarYEnabled]=reactExports.useState(!1),composedRefs=useComposedRefs(forwardedRef,node2=>setScrollArea(node2)),direction=useDirection(dir);return jsxRuntimeExports.jsx(ScrollAreaProvider,{scope:__scopeScrollArea,type,dir:direction,scrollHideDelay,scrollArea,viewport,onViewportChange:setViewport,content:content2,onContentChange:setContent,scrollbarX,onScrollbarXChange:setScrollbarX,scrollbarXEnabled,onScrollbarXEnabledChange:setScrollbarXEnabled,scrollbarY,onScrollbarYChange:setScrollbarY,scrollbarYEnabled,onScrollbarYEnabledChange:setScrollbarYEnabled,onCornerWidthChange:setCornerWidth,onCornerHeightChange:setCornerHeight,children:jsxRuntimeExports.jsx(Primitive$2.div,{dir:direction,...scrollAreaProps,ref:composedRefs,style:{position:"relative","--radix-scroll-area-corner-width":cornerWidth+"px","--radix-scroll-area-corner-height":cornerHeight+"px",...props.style}})})});ScrollArea.displayName=SCROLL_AREA_NAME;var VIEWPORT_NAME="ScrollAreaViewport",ScrollAreaViewport=reactExports.forwardRef((props,forwardedRef)=>{const{__scopeScrollArea,children:children2,nonce,...viewportProps}=props,context=useScrollAreaContext(VIEWPORT_NAME,__scopeScrollArea),ref=reactExports.useRef(null),composedRefs=useComposedRefs(forwardedRef,ref,context.onViewportChange);return jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment,{children:[jsxRuntimeExports.jsx("style",{dangerouslySetInnerHTML:{__html:"[data-radix-scroll-area-viewport]{scrollbar-width:none;-ms-overflow-style:none;-webkit-overflow-scrolling:touch;}[data-radix-scroll-area-viewport]::-webkit-scrollbar{display:none}"},nonce}),jsxRuntimeExports.jsx(Primitive$2.div,{"data-radix-scroll-area-viewport":"",...viewportProps,ref:composedRefs,style:{overflowX:context.scrollbarXEnabled?"scroll":"hidden",overflowY:context.scrollbarYEnabled?"scroll":"hidden",...props.style},children:jsxRuntimeExports.jsx("div",{ref:context.onContentChange,style:{minWidth:"100%",display:"table"},children:children2})})]})});ScrollAreaViewport.displayName=VIEWPORT_NAME;var SCROLLBAR_NAME="ScrollAreaScrollbar",ScrollAreaScrollbar=reactExports.forwardRef((props,forwardedRef)=>{const{forceMount,...scrollbarProps}=props,context=useScrollAreaContext(SCROLLBAR_NAME,props.__scopeScrollArea),{onScrollbarXEnabledChange,onScrollbarYEnabledChange}=context,isHorizontal=props.orientation==="horizontal";return reactExports.useEffect(()=>(isHorizontal?onScrollbarXEnabledChange(!0):onScrollbarYEnabledChange(!0),()=>{isHorizontal?onScrollbarXEnabledChange(!1):onScrollbarYEnabledChange(!1)}),[isHorizontal,onScrollbarXEnabledChange,onScrollbarYEnabledChange]),context.type==="hover"?jsxRuntimeExports.jsx(ScrollAreaScrollbarHover,{...scrollbarProps,ref:forwardedRef,forceMount}):context.type==="scroll"?jsxRuntimeExports.jsx(ScrollAreaScrollbarScroll,{...scrollbarProps,ref:forwardedRef,forceMount}):context.type==="auto"?jsxRuntimeExports.jsx(ScrollAreaScrollbarAuto,{...scrollbarProps,ref:forwardedRef,forceMount}):context.type==="always"?jsxRuntimeExports.jsx(ScrollAreaScrollbarVisible,{...scrollbarProps,ref:forwardedRef}):null});ScrollAreaScrollbar.displayName=SCROLLBAR_NAME;var ScrollAreaScrollbarHover=reactExports.forwardRef((props,forwardedRef)=>{const{forceMount,...scrollbarProps}=props,context=useScrollAreaContext(SCROLLBAR_NAME,props.__scopeScrollArea),[visible,setVisible]=reactExports.useState(!1);return reactExports.useEffect(()=>{const scrollArea=context.scrollArea;let hideTimer=0;if(scrollArea){const handlePointerEnter=__name(()=>{window.clearTimeout(hideTimer),setVisible(!0)},"handlePointerEnter"),handlePointerLeave=__name(()=>{hideTimer=window.setTimeout(()=>setVisible(!1),context.scrollHideDelay)},"handlePointerLeave");return scrollArea.addEventListener("pointerenter",handlePointerEnter),scrollArea.addEventListener("pointerleave",handlePointerLeave),()=>{window.clearTimeout(hideTimer),scrollArea.removeEventListener("pointerenter",handlePointerEnter),scrollArea.removeEventListener("pointerleave",handlePointerLeave)}}},[context.scrollArea,context.scrollHideDelay]),jsxRuntimeExports.jsx(Presence,{present:forceMount||visible,children:jsxRuntimeExports.jsx(ScrollAreaScrollbarAuto,{"data-state":visible?"visible":"hidden",...scrollbarProps,ref:forwardedRef})})}),ScrollAreaScrollbarScroll=reactExports.forwardRef((props,forwardedRef)=>{const{forceMount,...scrollbarProps}=props,context=useScrollAreaContext(SCROLLBAR_NAME,props.__scopeScrollArea),isHorizontal=props.orientation==="horizontal",debounceScrollEnd=useDebounceCallback(()=>send("SCROLL_END"),100),[state,send]=useStateMachine("hidden",{hidden:{SCROLL:"scrolling"},scrolling:{SCROLL_END:"idle",POINTER_ENTER:"interacting"},interacting:{SCROLL:"interacting",POINTER_LEAVE:"idle"},idle:{HIDE:"hidden",SCROLL:"scrolling",POINTER_ENTER:"interacting"}});return reactExports.useEffect(()=>{if(state==="idle"){const hideTimer=window.setTimeout(()=>send("HIDE"),context.scrollHideDelay);return()=>window.clearTimeout(hideTimer)}},[state,context.scrollHideDelay,send]),reactExports.useEffect(()=>{const viewport=context.viewport,scrollDirection=isHorizontal?"scrollLeft":"scrollTop";if(viewport){let prevScrollPos=viewport[scrollDirection];const handleScroll2=__name(()=>{const scrollPos=viewport[scrollDirection];prevScrollPos!==scrollPos&&(send("SCROLL"),debounceScrollEnd()),prevScrollPos=scrollPos},"handleScroll");return viewport.addEventListener("scroll",handleScroll2),()=>viewport.removeEventListener("scroll",handleScroll2)}},[context.viewport,isHorizontal,send,debounceScrollEnd]),jsxRuntimeExports.jsx(Presence,{present:forceMount||state!=="hidden",children:jsxRuntimeExports.jsx(ScrollAreaScrollbarVisible,{"data-state":state==="hidden"?"hidden":"visible",...scrollbarProps,ref:forwardedRef,onPointerEnter:composeEventHandlers(props.onPointerEnter,()=>send("POINTER_ENTER")),onPointerLeave:composeEventHandlers(props.onPointerLeave,()=>send("POINTER_LEAVE"))})})}),ScrollAreaScrollbarAuto=reactExports.forwardRef((props,forwardedRef)=>{const context=useScrollAreaContext(SCROLLBAR_NAME,props.__scopeScrollArea),{forceMount,...scrollbarProps}=props,[visible,setVisible]=reactExports.useState(!1),isHorizontal=props.orientation==="horizontal",handleResize=useDebounceCallback(()=>{if(context.viewport){const isOverflowX=context.viewport.offsetWidth{const{orientation="vertical",...scrollbarProps}=props,context=useScrollAreaContext(SCROLLBAR_NAME,props.__scopeScrollArea),thumbRef=reactExports.useRef(null),pointerOffsetRef=reactExports.useRef(0),[sizes,setSizes]=reactExports.useState({content:0,viewport:0,scrollbar:{size:0,paddingStart:0,paddingEnd:0}}),thumbRatio=getThumbRatio(sizes.viewport,sizes.content),commonProps={...scrollbarProps,sizes,onSizesChange:setSizes,hasThumb:thumbRatio>0&&thumbRatio<1,onThumbChange:__name(thumb=>thumbRef.current=thumb,"onThumbChange"),onThumbPointerUp:__name(()=>pointerOffsetRef.current=0,"onThumbPointerUp"),onThumbPointerDown:__name(pointerPos=>pointerOffsetRef.current=pointerPos,"onThumbPointerDown")};function getScrollPosition(pointerPos,dir){return getScrollPositionFromPointer(pointerPos,pointerOffsetRef.current,sizes,dir)}return __name(getScrollPosition,"getScrollPosition"),orientation==="horizontal"?jsxRuntimeExports.jsx(ScrollAreaScrollbarX,{...commonProps,ref:forwardedRef,onThumbPositionChange:__name(()=>{if(context.viewport&&thumbRef.current){const scrollPos=context.viewport.scrollLeft,offset2=getThumbOffsetFromScroll(scrollPos,sizes,context.dir);thumbRef.current.style.transform=`translate3d(${offset2}px, 0, 0)`}},"onThumbPositionChange"),onWheelScroll:__name(scrollPos=>{context.viewport&&(context.viewport.scrollLeft=scrollPos)},"onWheelScroll"),onDragScroll:__name(pointerPos=>{context.viewport&&(context.viewport.scrollLeft=getScrollPosition(pointerPos,context.dir))},"onDragScroll")}):orientation==="vertical"?jsxRuntimeExports.jsx(ScrollAreaScrollbarY,{...commonProps,ref:forwardedRef,onThumbPositionChange:__name(()=>{if(context.viewport&&thumbRef.current){const scrollPos=context.viewport.scrollTop,offset2=getThumbOffsetFromScroll(scrollPos,sizes);thumbRef.current.style.transform=`translate3d(0, ${offset2}px, 0)`}},"onThumbPositionChange"),onWheelScroll:__name(scrollPos=>{context.viewport&&(context.viewport.scrollTop=scrollPos)},"onWheelScroll"),onDragScroll:__name(pointerPos=>{context.viewport&&(context.viewport.scrollTop=getScrollPosition(pointerPos))},"onDragScroll")}):null}),ScrollAreaScrollbarX=reactExports.forwardRef((props,forwardedRef)=>{const{sizes,onSizesChange,...scrollbarProps}=props,context=useScrollAreaContext(SCROLLBAR_NAME,props.__scopeScrollArea),[computedStyle,setComputedStyle]=reactExports.useState(),ref=reactExports.useRef(null),composeRefs2=useComposedRefs(forwardedRef,ref,context.onScrollbarXChange);return reactExports.useEffect(()=>{ref.current&&setComputedStyle(getComputedStyle(ref.current))},[ref]),jsxRuntimeExports.jsx(ScrollAreaScrollbarImpl,{"data-orientation":"horizontal",...scrollbarProps,ref:composeRefs2,sizes,style:{bottom:0,left:context.dir==="rtl"?"var(--radix-scroll-area-corner-width)":0,right:context.dir==="ltr"?"var(--radix-scroll-area-corner-width)":0,"--radix-scroll-area-thumb-width":getThumbSize(sizes)+"px",...props.style},onThumbPointerDown:__name(pointerPos=>props.onThumbPointerDown(pointerPos.x),"onThumbPointerDown"),onDragScroll:__name(pointerPos=>props.onDragScroll(pointerPos.x),"onDragScroll"),onWheelScroll:__name((event,maxScrollPos)=>{if(context.viewport){const scrollPos=context.viewport.scrollLeft+event.deltaX;props.onWheelScroll(scrollPos),isScrollingWithinScrollbarBounds(scrollPos,maxScrollPos)&&event.preventDefault()}},"onWheelScroll"),onResize:__name(()=>{ref.current&&context.viewport&&computedStyle&&onSizesChange({content:context.viewport.scrollWidth,viewport:context.viewport.offsetWidth,scrollbar:{size:ref.current.clientWidth,paddingStart:toInt(computedStyle.paddingLeft),paddingEnd:toInt(computedStyle.paddingRight)}})},"onResize")})}),ScrollAreaScrollbarY=reactExports.forwardRef((props,forwardedRef)=>{const{sizes,onSizesChange,...scrollbarProps}=props,context=useScrollAreaContext(SCROLLBAR_NAME,props.__scopeScrollArea),[computedStyle,setComputedStyle]=reactExports.useState(),ref=reactExports.useRef(null),composeRefs2=useComposedRefs(forwardedRef,ref,context.onScrollbarYChange);return reactExports.useEffect(()=>{ref.current&&setComputedStyle(getComputedStyle(ref.current))},[ref]),jsxRuntimeExports.jsx(ScrollAreaScrollbarImpl,{"data-orientation":"vertical",...scrollbarProps,ref:composeRefs2,sizes,style:{top:0,right:context.dir==="ltr"?0:void 0,left:context.dir==="rtl"?0:void 0,bottom:"var(--radix-scroll-area-corner-height)","--radix-scroll-area-thumb-height":getThumbSize(sizes)+"px",...props.style},onThumbPointerDown:__name(pointerPos=>props.onThumbPointerDown(pointerPos.y),"onThumbPointerDown"),onDragScroll:__name(pointerPos=>props.onDragScroll(pointerPos.y),"onDragScroll"),onWheelScroll:__name((event,maxScrollPos)=>{if(context.viewport){const scrollPos=context.viewport.scrollTop+event.deltaY;props.onWheelScroll(scrollPos),isScrollingWithinScrollbarBounds(scrollPos,maxScrollPos)&&event.preventDefault()}},"onWheelScroll"),onResize:__name(()=>{ref.current&&context.viewport&&computedStyle&&onSizesChange({content:context.viewport.scrollHeight,viewport:context.viewport.offsetHeight,scrollbar:{size:ref.current.clientHeight,paddingStart:toInt(computedStyle.paddingTop),paddingEnd:toInt(computedStyle.paddingBottom)}})},"onResize")})}),[ScrollbarProvider,useScrollbarContext]=createScrollAreaContext(SCROLLBAR_NAME),ScrollAreaScrollbarImpl=reactExports.forwardRef((props,forwardedRef)=>{const{__scopeScrollArea,sizes,hasThumb,onThumbChange,onThumbPointerUp,onThumbPointerDown,onThumbPositionChange,onDragScroll,onWheelScroll,onResize,...scrollbarProps}=props,context=useScrollAreaContext(SCROLLBAR_NAME,__scopeScrollArea),[scrollbar,setScrollbar]=reactExports.useState(null),composeRefs2=useComposedRefs(forwardedRef,node2=>setScrollbar(node2)),rectRef=reactExports.useRef(null),prevWebkitUserSelectRef=reactExports.useRef(""),viewport=context.viewport,maxScrollPos=sizes.content-sizes.viewport,handleWheelScroll=useCallbackRef$1(onWheelScroll),handleThumbPositionChange=useCallbackRef$1(onThumbPositionChange),handleResize=useDebounceCallback(onResize,10);function handleDragScroll(event){if(rectRef.current){const x2=event.clientX-rectRef.current.left,y2=event.clientY-rectRef.current.top;onDragScroll({x:x2,y:y2})}}return __name(handleDragScroll,"handleDragScroll"),reactExports.useEffect(()=>{const handleWheel=__name(event=>{const element2=event.target;scrollbar?.contains(element2)&&handleWheelScroll(event,maxScrollPos)},"handleWheel");return document.addEventListener("wheel",handleWheel,{passive:!1}),()=>document.removeEventListener("wheel",handleWheel,{passive:!1})},[viewport,scrollbar,maxScrollPos,handleWheelScroll]),reactExports.useEffect(handleThumbPositionChange,[sizes,handleThumbPositionChange]),useResizeObserver(scrollbar,handleResize),useResizeObserver(context.content,handleResize),jsxRuntimeExports.jsx(ScrollbarProvider,{scope:__scopeScrollArea,scrollbar,hasThumb,onThumbChange:useCallbackRef$1(onThumbChange),onThumbPointerUp:useCallbackRef$1(onThumbPointerUp),onThumbPositionChange:handleThumbPositionChange,onThumbPointerDown:useCallbackRef$1(onThumbPointerDown),children:jsxRuntimeExports.jsx(Primitive$2.div,{...scrollbarProps,ref:composeRefs2,style:{position:"absolute",...scrollbarProps.style},onPointerDown:composeEventHandlers(props.onPointerDown,event=>{event.button===0&&(event.target.setPointerCapture(event.pointerId),rectRef.current=scrollbar.getBoundingClientRect(),prevWebkitUserSelectRef.current=document.body.style.webkitUserSelect,document.body.style.webkitUserSelect="none",context.viewport&&(context.viewport.style.scrollBehavior="auto"),handleDragScroll(event))}),onPointerMove:composeEventHandlers(props.onPointerMove,handleDragScroll),onPointerUp:composeEventHandlers(props.onPointerUp,event=>{const element2=event.target;element2.hasPointerCapture(event.pointerId)&&element2.releasePointerCapture(event.pointerId),document.body.style.webkitUserSelect=prevWebkitUserSelectRef.current,context.viewport&&(context.viewport.style.scrollBehavior=""),rectRef.current=null})})})}),THUMB_NAME="ScrollAreaThumb",ScrollAreaThumb=reactExports.forwardRef((props,forwardedRef)=>{const{forceMount,...thumbProps}=props,scrollbarContext=useScrollbarContext(THUMB_NAME,props.__scopeScrollArea);return jsxRuntimeExports.jsx(Presence,{present:forceMount||scrollbarContext.hasThumb,children:jsxRuntimeExports.jsx(ScrollAreaThumbImpl,{ref:forwardedRef,...thumbProps})})}),ScrollAreaThumbImpl=reactExports.forwardRef((props,forwardedRef)=>{const{__scopeScrollArea,style:style2,...thumbProps}=props,scrollAreaContext=useScrollAreaContext(THUMB_NAME,__scopeScrollArea),scrollbarContext=useScrollbarContext(THUMB_NAME,__scopeScrollArea),{onThumbPositionChange}=scrollbarContext,composedRef=useComposedRefs(forwardedRef,node2=>scrollbarContext.onThumbChange(node2)),removeUnlinkedScrollListenerRef=reactExports.useRef(void 0),debounceScrollEnd=useDebounceCallback(()=>{removeUnlinkedScrollListenerRef.current&&(removeUnlinkedScrollListenerRef.current(),removeUnlinkedScrollListenerRef.current=void 0)},100);return reactExports.useEffect(()=>{const viewport=scrollAreaContext.viewport;if(viewport){const handleScroll2=__name(()=>{if(debounceScrollEnd(),!removeUnlinkedScrollListenerRef.current){const listener=addUnlinkedScrollListener(viewport,onThumbPositionChange);removeUnlinkedScrollListenerRef.current=listener,onThumbPositionChange()}},"handleScroll");return onThumbPositionChange(),viewport.addEventListener("scroll",handleScroll2),()=>viewport.removeEventListener("scroll",handleScroll2)}},[scrollAreaContext.viewport,debounceScrollEnd,onThumbPositionChange]),jsxRuntimeExports.jsx(Primitive$2.div,{"data-state":scrollbarContext.hasThumb?"visible":"hidden",...thumbProps,ref:composedRef,style:{width:"var(--radix-scroll-area-thumb-width)",height:"var(--radix-scroll-area-thumb-height)",...style2},onPointerDownCapture:composeEventHandlers(props.onPointerDownCapture,event=>{const thumbRect=event.target.getBoundingClientRect(),x2=event.clientX-thumbRect.left,y2=event.clientY-thumbRect.top;scrollbarContext.onThumbPointerDown({x:x2,y:y2})}),onPointerUp:composeEventHandlers(props.onPointerUp,scrollbarContext.onThumbPointerUp)})});ScrollAreaThumb.displayName=THUMB_NAME;var CORNER_NAME="ScrollAreaCorner",ScrollAreaCorner=reactExports.forwardRef((props,forwardedRef)=>{const context=useScrollAreaContext(CORNER_NAME,props.__scopeScrollArea),hasBothScrollbarsVisible=!!(context.scrollbarX&&context.scrollbarY);return context.type!=="scroll"&&hasBothScrollbarsVisible?jsxRuntimeExports.jsx(ScrollAreaCornerImpl,{...props,ref:forwardedRef}):null});ScrollAreaCorner.displayName=CORNER_NAME;var ScrollAreaCornerImpl=reactExports.forwardRef((props,forwardedRef)=>{const{__scopeScrollArea,...cornerProps}=props,context=useScrollAreaContext(CORNER_NAME,__scopeScrollArea),[width,setWidth]=reactExports.useState(0),[height,setHeight]=reactExports.useState(0),hasSize=!!(width&&height);return useResizeObserver(context.scrollbarX,()=>{const height2=context.scrollbarX?.offsetHeight||0;context.onCornerHeightChange(height2),setHeight(height2)}),useResizeObserver(context.scrollbarY,()=>{const width2=context.scrollbarY?.offsetWidth||0;context.onCornerWidthChange(width2),setWidth(width2)}),hasSize?jsxRuntimeExports.jsx(Primitive$2.div,{...cornerProps,ref:forwardedRef,style:{width,height,position:"absolute",right:context.dir==="ltr"?0:void 0,left:context.dir==="rtl"?0:void 0,bottom:0,...props.style}}):null});function toInt(value2){return value2?parseInt(value2,10):0}__name(toInt,"toInt");function getThumbRatio(viewportSize,contentSize){const ratio=viewportSize/contentSize;return isNaN(ratio)?0:ratio}__name(getThumbRatio,"getThumbRatio");function getThumbSize(sizes){const ratio=getThumbRatio(sizes.viewport,sizes.content),scrollbarPadding=sizes.scrollbar.paddingStart+sizes.scrollbar.paddingEnd,thumbSize=(sizes.scrollbar.size-scrollbarPadding)*ratio;return Math.max(thumbSize,18)}__name(getThumbSize,"getThumbSize");function getScrollPositionFromPointer(pointerPos,pointerOffset,sizes,dir="ltr"){const thumbSizePx=getThumbSize(sizes),thumbCenter=thumbSizePx/2,offset2=pointerOffset||thumbCenter,thumbOffsetFromEnd=thumbSizePx-offset2,minPointerPos=sizes.scrollbar.paddingStart+offset2,maxPointerPos=sizes.scrollbar.size-sizes.scrollbar.paddingEnd-thumbOffsetFromEnd,maxScrollPos=sizes.content-sizes.viewport,scrollRange=dir==="ltr"?[0,maxScrollPos]:[maxScrollPos*-1,0];return linearScale([minPointerPos,maxPointerPos],scrollRange)(pointerPos)}__name(getScrollPositionFromPointer,"getScrollPositionFromPointer");function getThumbOffsetFromScroll(scrollPos,sizes,dir="ltr"){const thumbSizePx=getThumbSize(sizes),scrollbarPadding=sizes.scrollbar.paddingStart+sizes.scrollbar.paddingEnd,scrollbar=sizes.scrollbar.size-scrollbarPadding,maxScrollPos=sizes.content-sizes.viewport,maxThumbPos=scrollbar-thumbSizePx,scrollClampRange=dir==="ltr"?[0,maxScrollPos]:[maxScrollPos*-1,0],scrollWithoutMomentum=clamp(scrollPos,scrollClampRange);return linearScale([0,maxScrollPos],[0,maxThumbPos])(scrollWithoutMomentum)}__name(getThumbOffsetFromScroll,"getThumbOffsetFromScroll");function linearScale(input,output){return value2=>{if(input[0]===input[1]||output[0]===output[1])return output[0];const ratio=(output[1]-output[0])/(input[1]-input[0]);return output[0]+ratio*(value2-input[0])}}__name(linearScale,"linearScale");function isScrollingWithinScrollbarBounds(scrollPos,maxScrollPos){return scrollPos>0&&scrollPos{})=>{let prevPosition={left:node2.scrollLeft,top:node2.scrollTop},rAF=0;return __name((function loop2(){const position2={left:node2.scrollLeft,top:node2.scrollTop},isHorizontalScroll=prevPosition.left!==position2.left,isVerticalScroll=prevPosition.top!==position2.top;(isHorizontalScroll||isVerticalScroll)&&handler(),prevPosition=position2,rAF=window.requestAnimationFrame(loop2)}),"loop")(),()=>window.cancelAnimationFrame(rAF)},"addUnlinkedScrollListener");function useDebounceCallback(callback,delay){const handleCallback=useCallbackRef$1(callback),debounceTimerRef=reactExports.useRef(0);return reactExports.useEffect(()=>()=>window.clearTimeout(debounceTimerRef.current),[]),reactExports.useCallback(()=>{window.clearTimeout(debounceTimerRef.current),debounceTimerRef.current=window.setTimeout(handleCallback,delay)},[handleCallback,delay])}__name(useDebounceCallback,"useDebounceCallback");function useResizeObserver(element2,onResize){const handleResize=useCallbackRef$1(onResize);useLayoutEffect2(()=>{let rAF=0;if(element2){const resizeObserver=new ResizeObserver(()=>{cancelAnimationFrame(rAF),rAF=window.requestAnimationFrame(handleResize)});return resizeObserver.observe(element2),()=>{window.cancelAnimationFrame(rAF),resizeObserver.unobserve(element2)}}},[element2,handleResize])}__name(useResizeObserver,"useResizeObserver");function Logo(){return jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment,{children:[jsxRuntimeExports.jsx(Icons.logo,{className:"h-6 w-6"}),jsxRuntimeExports.jsx("span",{className:"font-bold",children:ztAppConfig.name})]})}__name(Logo,"Logo");var COLLAPSIBLE_NAME="Collapsible",[createCollapsibleContext,createCollapsibleScope]=createContextScope$1(COLLAPSIBLE_NAME),[CollapsibleProvider,useCollapsibleContext]=createCollapsibleContext(COLLAPSIBLE_NAME),Collapsible=reactExports.forwardRef((props,forwardedRef)=>{const{__scopeCollapsible,open:openProp,defaultOpen,disabled,onOpenChange,...collapsibleProps}=props,[open,setOpen]=useControllableState({prop:openProp,defaultProp:defaultOpen??!1,onChange:onOpenChange,caller:COLLAPSIBLE_NAME});return jsxRuntimeExports.jsx(CollapsibleProvider,{scope:__scopeCollapsible,disabled,contentId:useId(),open,onOpenToggle:reactExports.useCallback(()=>setOpen(prevOpen=>!prevOpen),[setOpen]),children:jsxRuntimeExports.jsx(Primitive$2.div,{"data-state":getState$1(open),"data-disabled":disabled?"":void 0,...collapsibleProps,ref:forwardedRef})})});Collapsible.displayName=COLLAPSIBLE_NAME;var TRIGGER_NAME$3="CollapsibleTrigger",CollapsibleTrigger=reactExports.forwardRef((props,forwardedRef)=>{const{__scopeCollapsible,...triggerProps}=props,context=useCollapsibleContext(TRIGGER_NAME$3,__scopeCollapsible);return jsxRuntimeExports.jsx(Primitive$2.button,{type:"button","aria-controls":context.contentId,"aria-expanded":context.open||!1,"data-state":getState$1(context.open),"data-disabled":context.disabled?"":void 0,disabled:context.disabled,...triggerProps,ref:forwardedRef,onClick:composeEventHandlers(props.onClick,context.onOpenToggle)})});CollapsibleTrigger.displayName=TRIGGER_NAME$3;var CONTENT_NAME$3="CollapsibleContent",CollapsibleContent=reactExports.forwardRef((props,forwardedRef)=>{const{forceMount,...contentProps}=props,context=useCollapsibleContext(CONTENT_NAME$3,props.__scopeCollapsible);return jsxRuntimeExports.jsx(Presence,{present:forceMount||context.open,children:__name(({present})=>jsxRuntimeExports.jsx(CollapsibleContentImpl,{...contentProps,ref:forwardedRef,present}),"children")})});CollapsibleContent.displayName=CONTENT_NAME$3;var CollapsibleContentImpl=reactExports.forwardRef((props,forwardedRef)=>{const{__scopeCollapsible,present,children:children2,...contentProps}=props,context=useCollapsibleContext(CONTENT_NAME$3,__scopeCollapsible),[isPresent,setIsPresent]=reactExports.useState(present),ref=reactExports.useRef(null),composedRefs=useComposedRefs(forwardedRef,ref),heightRef=reactExports.useRef(0),height=heightRef.current,widthRef=reactExports.useRef(0),width=widthRef.current,isOpen=context.open||isPresent,isMountAnimationPreventedRef=reactExports.useRef(isOpen),originalStylesRef=reactExports.useRef(void 0);return reactExports.useEffect(()=>{const rAF=requestAnimationFrame(()=>isMountAnimationPreventedRef.current=!1);return()=>cancelAnimationFrame(rAF)},[]),useLayoutEffect2(()=>{const node2=ref.current;if(node2){originalStylesRef.current=originalStylesRef.current||{transitionDuration:node2.style.transitionDuration,animationName:node2.style.animationName},node2.style.transitionDuration="0s",node2.style.animationName="none";const rect=node2.getBoundingClientRect();heightRef.current=rect.height,widthRef.current=rect.width,isMountAnimationPreventedRef.current||(node2.style.transitionDuration=originalStylesRef.current.transitionDuration,node2.style.animationName=originalStylesRef.current.animationName),setIsPresent(present)}},[context.open,present]),jsxRuntimeExports.jsx(Primitive$2.div,{"data-state":getState$1(context.open),"data-disabled":context.disabled?"":void 0,id:context.contentId,hidden:!isOpen,...contentProps,ref:composedRefs,style:{"--radix-collapsible-content-height":height?`${height}px`:void 0,"--radix-collapsible-content-width":width?`${width}px`:void 0,...props.style},children:isOpen&&children2})});function getState$1(open){return open?"open":"closed"}__name(getState$1,"getState$1");var Root$3=Collapsible,Trigger$2=CollapsibleTrigger,Content$1=CollapsibleContent,ACCORDION_NAME="Accordion",ACCORDION_KEYS=["Home","End","ArrowDown","ArrowUp","ArrowLeft","ArrowRight"],[Collection,useCollection,createCollectionScope]=createCollection(ACCORDION_NAME),[createAccordionContext]=createContextScope$1(ACCORDION_NAME,[createCollectionScope,createCollapsibleScope]),useCollapsibleScope=createCollapsibleScope(),Accordion$1=React.forwardRef((props,forwardedRef)=>{const{type,...accordionProps}=props,singleProps=accordionProps,multipleProps=accordionProps;return jsxRuntimeExports.jsx(Collection.Provider,{scope:props.__scopeAccordion,children:type==="multiple"?jsxRuntimeExports.jsx(AccordionImplMultiple,{...multipleProps,ref:forwardedRef}):jsxRuntimeExports.jsx(AccordionImplSingle,{...singleProps,ref:forwardedRef})})});Accordion$1.displayName=ACCORDION_NAME;var[AccordionValueProvider,useAccordionValueContext]=createAccordionContext(ACCORDION_NAME),[AccordionCollapsibleProvider,useAccordionCollapsibleContext]=createAccordionContext(ACCORDION_NAME,{collapsible:!1}),AccordionImplSingle=React.forwardRef((props,forwardedRef)=>{const{value:valueProp,defaultValue,onValueChange=__name(()=>{},"onValueChange"),collapsible=!1,...accordionSingleProps}=props,[value2,setValue]=useControllableState({prop:valueProp,defaultProp:defaultValue??"",onChange:onValueChange,caller:ACCORDION_NAME});return jsxRuntimeExports.jsx(AccordionValueProvider,{scope:props.__scopeAccordion,value:React.useMemo(()=>value2?[value2]:[],[value2]),onItemOpen:setValue,onItemClose:React.useCallback(()=>collapsible&&setValue(""),[collapsible,setValue]),children:jsxRuntimeExports.jsx(AccordionCollapsibleProvider,{scope:props.__scopeAccordion,collapsible,children:jsxRuntimeExports.jsx(AccordionImpl,{...accordionSingleProps,ref:forwardedRef})})})}),AccordionImplMultiple=React.forwardRef((props,forwardedRef)=>{const{value:valueProp,defaultValue,onValueChange=__name(()=>{},"onValueChange"),...accordionMultipleProps}=props,[value2,setValue]=useControllableState({prop:valueProp,defaultProp:defaultValue??[],onChange:onValueChange,caller:ACCORDION_NAME}),handleItemOpen=React.useCallback(itemValue=>setValue((prevValue=[])=>[...prevValue,itemValue]),[setValue]),handleItemClose=React.useCallback(itemValue=>setValue((prevValue=[])=>prevValue.filter(value22=>value22!==itemValue)),[setValue]);return jsxRuntimeExports.jsx(AccordionValueProvider,{scope:props.__scopeAccordion,value:value2,onItemOpen:handleItemOpen,onItemClose:handleItemClose,children:jsxRuntimeExports.jsx(AccordionCollapsibleProvider,{scope:props.__scopeAccordion,collapsible:!0,children:jsxRuntimeExports.jsx(AccordionImpl,{...accordionMultipleProps,ref:forwardedRef})})})}),[AccordionImplProvider,useAccordionContext]=createAccordionContext(ACCORDION_NAME),AccordionImpl=React.forwardRef((props,forwardedRef)=>{const{__scopeAccordion,disabled,dir,orientation="vertical",...accordionProps}=props,accordionRef=React.useRef(null),composedRefs=useComposedRefs(accordionRef,forwardedRef),getItems=useCollection(__scopeAccordion),isDirectionLTR=useDirection(dir)==="ltr",handleKeyDown=composeEventHandlers(props.onKeyDown,event=>{if(!ACCORDION_KEYS.includes(event.key))return;const target=event.target,triggerCollection=getItems().filter(item=>!item.ref.current?.disabled),triggerIndex=triggerCollection.findIndex(item=>item.ref.current===target),triggerCount=triggerCollection.length;if(triggerIndex===-1)return;event.preventDefault();let nextIndex=triggerIndex;const homeIndex=0,endIndex=triggerCount-1,moveNext=__name(()=>{nextIndex=triggerIndex+1,nextIndex>endIndex&&(nextIndex=homeIndex)},"moveNext"),movePrev=__name(()=>{nextIndex=triggerIndex-1,nextIndex{const{__scopeAccordion,value:value2,...accordionItemProps}=props,accordionContext=useAccordionContext(ITEM_NAME,__scopeAccordion),valueContext=useAccordionValueContext(ITEM_NAME,__scopeAccordion),collapsibleScope=useCollapsibleScope(__scopeAccordion),triggerId=useId(),open=value2&&valueContext.value.includes(value2)||!1,disabled=accordionContext.disabled||props.disabled;return jsxRuntimeExports.jsx(AccordionItemProvider,{scope:__scopeAccordion,open,disabled,triggerId,children:jsxRuntimeExports.jsx(Root$3,{"data-orientation":accordionContext.orientation,"data-state":getState(open),...collapsibleScope,...accordionItemProps,ref:forwardedRef,disabled,open,onOpenChange:__name(open2=>{open2?valueContext.onItemOpen(value2):valueContext.onItemClose(value2)},"onOpenChange")})})});AccordionItem$1.displayName=ITEM_NAME;var HEADER_NAME="AccordionHeader",AccordionHeader=React.forwardRef((props,forwardedRef)=>{const{__scopeAccordion,...headerProps}=props,accordionContext=useAccordionContext(ACCORDION_NAME,__scopeAccordion),itemContext=useAccordionItemContext(HEADER_NAME,__scopeAccordion);return jsxRuntimeExports.jsx(Primitive$2.h3,{"data-orientation":accordionContext.orientation,"data-state":getState(itemContext.open),"data-disabled":itemContext.disabled?"":void 0,...headerProps,ref:forwardedRef})});AccordionHeader.displayName=HEADER_NAME;var TRIGGER_NAME$2="AccordionTrigger",AccordionTrigger$1=React.forwardRef((props,forwardedRef)=>{const{__scopeAccordion,...triggerProps}=props,accordionContext=useAccordionContext(ACCORDION_NAME,__scopeAccordion),itemContext=useAccordionItemContext(TRIGGER_NAME$2,__scopeAccordion),collapsibleContext=useAccordionCollapsibleContext(TRIGGER_NAME$2,__scopeAccordion),collapsibleScope=useCollapsibleScope(__scopeAccordion);return jsxRuntimeExports.jsx(Collection.ItemSlot,{scope:__scopeAccordion,children:jsxRuntimeExports.jsx(Trigger$2,{"aria-disabled":itemContext.open&&!collapsibleContext.collapsible||void 0,"data-orientation":accordionContext.orientation,id:itemContext.triggerId,...collapsibleScope,...triggerProps,ref:forwardedRef})})});AccordionTrigger$1.displayName=TRIGGER_NAME$2;var CONTENT_NAME$2="AccordionContent",AccordionContent$1=React.forwardRef((props,forwardedRef)=>{const{__scopeAccordion,...contentProps}=props,accordionContext=useAccordionContext(ACCORDION_NAME,__scopeAccordion),itemContext=useAccordionItemContext(CONTENT_NAME$2,__scopeAccordion),collapsibleScope=useCollapsibleScope(__scopeAccordion);return jsxRuntimeExports.jsx(Content$1,{role:"region","aria-labelledby":itemContext.triggerId,"data-orientation":accordionContext.orientation,...collapsibleScope,...contentProps,ref:forwardedRef,style:{"--radix-accordion-content-height":"var(--radix-collapsible-content-height)","--radix-accordion-content-width":"var(--radix-collapsible-content-width)",...props.style}})});AccordionContent$1.displayName=CONTENT_NAME$2;function getState(open){return open?"open":"closed"}__name(getState,"getState");var Root2$1=Accordion$1,Item=AccordionItem$1,Header$1=AccordionHeader,Trigger2=AccordionTrigger$1,Content2$1=AccordionContent$1;const Accordion=Root2$1,AccordionItem=reactExports.forwardRef(({className,...props},ref)=>jsxRuntimeExports.jsx(Item,{ref,className:cn$2("border-b",className),...props}));AccordionItem.displayName="AccordionItem";const AccordionTrigger=reactExports.forwardRef(({className,children:children2,...props},ref)=>jsxRuntimeExports.jsx(Header$1,{className:"flex",children:jsxRuntimeExports.jsxs(Trigger2,{ref,className:cn$2("flex flex-1 items-center justify-between py-4 font-medium transition-all hover:underline [&[data-state=open]>svg]:rotate-180",className),...props,children:[children2,jsxRuntimeExports.jsx(ChevronDown,{className:"h-4 w-4 shrink-0 transition-transform duration-200"})]})}));AccordionTrigger.displayName=Trigger2.displayName;const AccordionContent=reactExports.forwardRef(({className,children:children2,...props},ref)=>jsxRuntimeExports.jsx(Content2$1,{ref,className:"overflow-hidden text-sm transition-all data-[state=closed]:animate-accordion-up data-[state=open]:animate-accordion-down",...props,children:jsxRuntimeExports.jsx("div",{className:cn$2("pb-4 pt-0",className),children:children2})}));AccordionContent.displayName=Content2$1.displayName;function Header(){const[open,setOpen]=reactExports.useState(!1),location2=useLocation();return console.log(reportData),jsxRuntimeExports.jsx("header",{className:"supports-backdrop-blur:bg-background/60 sticky top-0 z-50 w-full border-b bg-background/90 backdrop-blur",children:jsxRuntimeExports.jsxs("div",{className:"container px-4 md:px-8 flex h-14 items-center",children:[jsxRuntimeExports.jsxs("div",{className:"mr-4 hidden md:flex",children:[jsxRuntimeExports.jsx(NavLink,{to:"/",className:"mr-6 flex items-center space-x-2",children:jsxRuntimeExports.jsx(Logo,{})}),jsxRuntimeExports.jsx("nav",{className:"flex items-center space-x-6 text-sm font-medium",children:mainMenu.map((menu,index2)=>menu.items!==void 0?jsxRuntimeExports.jsxs(DropdownMenu,{children:[jsxRuntimeExports.jsxs(DropdownMenuTrigger,{className:cn$2("flex items-center py-1 focus:outline-none text-sm font-medium transition-colors hover:text-primary",menu.items.filter(subitem=>subitem.to!==void 0).map(subitem=>subitem.to).includes(location2.pathname)?"text-foreground":"text-foreground/60"),children:[menu.title,jsxRuntimeExports.jsx(ChevronDownIcon,{className:"ml-1 -mr-1 h-3 w-3 text-muted-foreground"})]}),jsxRuntimeExports.jsx(DropdownMenuContent,{className:"w-48",align:"start",forceMount:!0,children:menu.items.map((subitem,subindex)=>subitem.to!==void 0?jsxRuntimeExports.jsx(NavLink,{to:subitem.to,children:jsxRuntimeExports.jsx(DropdownMenuItem,{className:cn$2("hover:cursor-pointer",{"bg-muted":subitem.to===location2.pathname}),children:subitem.title})},subindex):subitem.label?jsxRuntimeExports.jsx(DropdownMenuLabel,{children:subitem.title},subindex):jsxRuntimeExports.jsx(DropdownMenuSeparator,{},subindex))})]},index2):jsxRuntimeExports.jsx(NavLink,{to:menu.to??"",className:__name(({isActive})=>cn$2("text-sm font-medium transition-colors hover:text-primary",isActive?"text-foreground":"text-foreground/60"),"className"),children:menu.title},index2))})]}),jsxRuntimeExports.jsxs(Sheet,{open,onOpenChange:setOpen,children:[jsxRuntimeExports.jsx(SheetTrigger,{asChild:!0,children:jsxRuntimeExports.jsxs(Button,{variant:"ghost",className:"mr-4 px-0 text-base hover:bg-transparent focus-visible:bg-transparent focus-visible:ring-0 focus-visible:ring-offset-0 md:hidden",children:[jsxRuntimeExports.jsx(ViewVerticalIcon,{className:"h-5 w-5"}),jsxRuntimeExports.jsx("span",{className:"sr-only",children:"Toggle Menu"})]})}),jsxRuntimeExports.jsxs(SheetContent,{side:"left",className:"pr-0 sm:max-w-xs",children:[jsxRuntimeExports.jsx(NavLink,{to:"/",onClick:__name(()=>setOpen(!1),"onClick"),className:"flex items-center space-x-2",children:jsxRuntimeExports.jsx(Logo,{})}),jsxRuntimeExports.jsx(ScrollArea,{className:"my-4 h-[calc(100vh-8rem)] pb-8 pl-8",children:jsxRuntimeExports.jsx(Accordion,{type:"single",collapsible:!0,className:"w-full",defaultValue:"item-"+mainMenu.findIndex(item=>item.items!==void 0?item.items.filter(subitem=>subitem.to!==void 0).map(subitem=>subitem.to).includes(location2.pathname):!1),children:jsxRuntimeExports.jsx("div",{className:"flex flex-col space-y-3",children:mainMenu.map((menu,index2)=>menu.items!==void 0?jsxRuntimeExports.jsxs(AccordionItem,{value:`item-${index2}`,className:"border-b-0 pr-6",children:[jsxRuntimeExports.jsx(AccordionTrigger,{className:cn$2("py-1 hover:no-underline hover:text-primary [&[data-state=open]]:text-primary",menu.items.filter(subitem=>subitem.to!==void 0).map(subitem=>subitem.to).includes(location2.pathname)?"text-foreground":"text-foreground/60"),children:jsxRuntimeExports.jsx("div",{className:"flex",children:menu.title})}),jsxRuntimeExports.jsx(AccordionContent,{className:"pb-1 pl-4",children:jsxRuntimeExports.jsx("div",{className:"mt-1",children:menu.items.map((submenu,subindex)=>submenu.to!==void 0?jsxRuntimeExports.jsx(NavLink,{to:submenu.to,onClick:__name(()=>setOpen(!1),"onClick"),className:__name(({isActive})=>cn$2("block justify-start py-1 h-auto font-normal hover:text-primary",isActive?"text-foreground":"text-foreground/60"),"className"),children:submenu.title},subindex):submenu.label!==""?null:jsxRuntimeExports.jsx("div",{className:"px-3"}))})})]},index2):jsxRuntimeExports.jsx(NavLink,{to:menu.to??"",onClick:__name(()=>setOpen(!1),"onClick"),className:__name(({isActive})=>cn$2("py-1 text-sm font-medium transition-colors hover:text-primary",isActive?"text-foreground":"text-foreground/60"),"className"),children:menu.title},index2))})})})]})]}),jsxRuntimeExports.jsxs("a",{href:"/",className:"mr-6 flex items-center space-x-2 md:hidden",children:[jsxRuntimeExports.jsx(Icons.logo,{className:"h-6 w-6"}),jsxRuntimeExports.jsx("span",{className:"font-bold inline-block",children:ztAppConfig.name})]}),jsxRuntimeExports.jsxs("div",{className:"flex flex-1 items-center justify-between space-x-2 md:justify-end",children:[jsxRuntimeExports.jsx("div",{className:"w-full flex-1 md:w-auto md:flex-none"}),jsxRuntimeExports.jsxs("nav",{className:"flex items-center space-x-2",children:[jsxRuntimeExports.jsx(ModeToggle,{}),jsxRuntimeExports.jsx("a",{href:ztAppConfig.github.url,title:ztAppConfig.github.title,target:"_blank",rel:"noreferrer",children:jsxRuntimeExports.jsxs("div",{className:cn$2(buttonVariants({variant:"ghost"}),"w-9 px-0"),children:[jsxRuntimeExports.jsx(Icons.gitHub,{className:"h-4 w-4"}),jsxRuntimeExports.jsx("span",{className:"sr-only",children:"GitHub"})]})})]}),jsxRuntimeExports.jsx("nav",{className:"flex items-center space-x-2",children:jsxRuntimeExports.jsxs(DropdownMenu,{children:[jsxRuntimeExports.jsx(DropdownMenuTrigger,{asChild:!0,children:jsxRuntimeExports.jsx(Button,{variant:"ghost",className:"relative h-8",children:reportData.TenantName})}),jsxRuntimeExports.jsxs(DropdownMenuContent,{className:"w-100",align:"end",forceMount:!0,children:[jsxRuntimeExports.jsx(DropdownMenuLabel,{className:"font-normal",children:jsxRuntimeExports.jsxs("div",{className:"flex flex-col space-y-1",children:[jsxRuntimeExports.jsx("p",{className:"text-sm font-medium leading-none",children:"Tenant"}),jsxRuntimeExports.jsx("p",{className:"text-xs leading-none text-muted-foreground",children:reportData.Domain})]})}),jsxRuntimeExports.jsx(DropdownMenuLabel,{className:"font-normal",children:jsxRuntimeExports.jsxs("div",{className:"flex flex-col space-y-1",children:[jsxRuntimeExports.jsx("p",{className:"text-sm font-medium leading-none",children:"Tenant ID"}),jsxRuntimeExports.jsx("p",{className:"text-xs leading-none text-muted-foreground",children:reportData.TenantId})]})}),jsxRuntimeExports.jsx(DropdownMenuSeparator,{}),jsxRuntimeExports.jsx(DropdownMenuLabel,{className:"font-normal",children:jsxRuntimeExports.jsxs("div",{className:"flex flex-col space-y-1",children:[jsxRuntimeExports.jsx("p",{className:"text-sm font-medium leading-none",children:"Assessment generated by"}),jsxRuntimeExports.jsx("p",{className:"text-xs leading-none text-muted-foreground",children:reportData.Account})]})}),jsxRuntimeExports.jsx(DropdownMenuSeparator,{}),jsxRuntimeExports.jsx(DropdownMenuLabel,{className:"font-normal",children:jsxRuntimeExports.jsxs("div",{className:"flex flex-col space-y-1",children:[jsxRuntimeExports.jsx("p",{className:"text-sm font-medium leading-none",children:"Assessment run on"}),jsxRuntimeExports.jsx("p",{className:"text-xs leading-none text-muted-foreground",children:new Date(reportData.ExecutedAt).toLocaleDateString("en",{day:"numeric",month:"long",year:"numeric",hour12:!0,hour:"numeric",minute:"numeric"})})]})}),jsxRuntimeExports.jsx(DropdownMenuSeparator,{}),jsxRuntimeExports.jsx(DropdownMenuLabel,{className:"font-normal",children:jsxRuntimeExports.jsxs("div",{className:"flex flex-col space-y-1",children:[jsxRuntimeExports.jsx("p",{className:"text-sm font-medium leading-none",children:"Version"}),jsxRuntimeExports.jsx("p",{className:"text-xs leading-none text-muted-foreground",children:reportData.CurrentVersion})]})})]})]})})]})]})})}__name(Header,"Header");function Footer(){const assessmentDate=__name(dateString=>{try{return new Date(dateString).toLocaleDateString("en-US",{year:"numeric",month:"long",day:"numeric"})}catch{return"Invalid Date"}},"formatDate")(reportData.ExecutedAt);return jsxRuntimeExports.jsx("footer",{className:"border-t bg-background/95 backdrop-blur supports-[backdrop-filter]:bg-background/60",children:jsxRuntimeExports.jsxs("div",{className:"container mx-auto px-4 py-8",children:[jsxRuntimeExports.jsxs("div",{className:"grid grid-cols-1 md:grid-cols-3 gap-8 items-start",children:[jsxRuntimeExports.jsxs("div",{className:"space-y-4",children:[jsxRuntimeExports.jsxs("div",{className:"flex items-center space-x-2",children:[jsxRuntimeExports.jsx(Icons.logo,{className:"h-6 w-6"}),jsxRuntimeExports.jsx("span",{className:"font-semibold text-foreground",children:"Zero Trust Assessment"})]}),jsxRuntimeExports.jsx("p",{className:"text-sm text-muted-foreground leading-relaxed",children:"An automated assessment tool that evaluates your Microsoft tenant's zero trust security posture."})]}),jsxRuntimeExports.jsxs("div",{className:"space-y-4",children:[jsxRuntimeExports.jsx("h4",{className:"font-semibold text-foreground",children:"Resources"}),jsxRuntimeExports.jsxs("div",{className:"space-y-2",children:[jsxRuntimeExports.jsx("a",{href:"https://aka.ms/zerotrust/assessment",target:"_blank",rel:"noreferrer noopener",className:"block text-sm text-muted-foreground hover:text-foreground transition-colors duration-200 hover:underline underline-offset-4",children:"Zero Trust Assessment"}),jsxRuntimeExports.jsx("a",{href:"https://aka.ms/zerotrust/workshop",target:"_blank",rel:"noreferrer noopener",className:"block text-sm text-muted-foreground hover:text-foreground transition-colors duration-200 hover:underline underline-offset-4",children:"Zero Trust Workshop"})]})]}),jsxRuntimeExports.jsxs("div",{className:"space-y-4",children:[jsxRuntimeExports.jsx("h4",{className:"font-semibold text-foreground",children:"Support"}),jsxRuntimeExports.jsxs("div",{className:"space-y-2",children:[jsxRuntimeExports.jsx("a",{href:"https://aka.ms/zerotrust/feedback",target:"_blank",rel:"noreferrer noopener",className:"block text-sm text-muted-foreground hover:text-foreground transition-colors duration-200 hover:underline underline-offset-4",children:"Share Feedback"}),jsxRuntimeExports.jsx("a",{href:"https://aka.ms/zerotrust/issues",target:"_blank",rel:"noreferrer noopener",className:"block text-sm text-muted-foreground hover:text-foreground transition-colors duration-200 hover:underline underline-offset-4",children:"Report Issues"}),jsxRuntimeExports.jsxs("a",{href:"https://github.com/microsoft/zerotrustassessment",target:"_blank",rel:"noreferrer noopener",className:"flex items-center space-x-2 text-sm text-muted-foreground hover:text-foreground transition-colors duration-200 hover:underline underline-offset-4",children:[jsxRuntimeExports.jsx(Icons.gitHub,{className:"h-4 w-4"}),jsxRuntimeExports.jsx("span",{children:"GitHub"})]})]})]})]}),jsxRuntimeExports.jsxs("div",{className:"border-t mt-8 pt-6 flex flex-col md:flex-row justify-between items-center space-y-4 md:space-y-0",children:[jsxRuntimeExports.jsxs("div",{className:"text-center md:text-left",children:[jsxRuntimeExports.jsxs("p",{className:"text-xs text-muted-foreground",children:["© ",new Date().getFullYear()," Microsoft Corporation. All rights reserved."]}),jsxRuntimeExports.jsx("p",{className:"text-xs text-muted-foreground mt-1",children:"This is a community project and not an official Microsoft product."})]}),jsxRuntimeExports.jsxs("div",{className:"flex items-center space-x-4 text-xs text-muted-foreground",children:[jsxRuntimeExports.jsx("a",{href:"https://privacy.microsoft.com/privacystatement",target:"_blank",rel:"noreferrer noopener",className:"hover:text-foreground transition-colors duration-200",children:"Privacy"}),jsxRuntimeExports.jsx("span",{children:"•"}),jsxRuntimeExports.jsx("a",{href:"https://www.microsoft.com/legal/terms-of-use",target:"_blank",rel:"noreferrer noopener",className:"hover:text-foreground transition-colors duration-200",children:"Terms"}),jsxRuntimeExports.jsx("span",{children:"•"}),jsxRuntimeExports.jsx("span",{children:assessmentDate})]}),jsxRuntimeExports.jsx("div",{className:"hidden"})]})]})})}__name(Footer,"Footer");function Applayout(){return jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment,{children:[jsxRuntimeExports.jsx(Header,{}),jsxRuntimeExports.jsx("div",{className:"flex-grow flex flex-col",children:jsxRuntimeExports.jsx("div",{className:"container max-w-6xl px-4 md:px-8 flex-grow flex flex-col",children:jsxRuntimeExports.jsx(Outlet,{})})}),jsxRuntimeExports.jsx("div",{className:"container max-w-6xl px-4 md:px-8",children:jsxRuntimeExports.jsx(Footer,{})})]})}__name(Applayout,"Applayout");function NoMatch(){return jsxRuntimeExports.jsx("div",{className:"bg-background text-foreground flex-grow flex items-center justify-center",children:jsxRuntimeExports.jsxs("div",{className:"space-y-4",children:[jsxRuntimeExports.jsx("h2",{className:"text-8xl mb-4",children:"404"}),jsxRuntimeExports.jsx("h1",{className:"text-3xl font-semibold",children:"Oops! Page not found"}),jsxRuntimeExports.jsx("p",{className:"text-sm text-muted-foreground",children:"We are sorry, but the page you requested was not found"}),jsxRuntimeExports.jsx(NavLink,{to:"/",className:buttonVariants(),children:"Back to Home"})]})})}__name(NoMatch,"NoMatch");var isArray_1,hasRequiredIsArray;function requireIsArray(){if(hasRequiredIsArray)return isArray_1;hasRequiredIsArray=1;var isArray2=Array.isArray;return isArray_1=isArray2,isArray_1}__name(requireIsArray,"requireIsArray");var _freeGlobal,hasRequired_freeGlobal;function require_freeGlobal(){if(hasRequired_freeGlobal)return _freeGlobal;hasRequired_freeGlobal=1;var define_global_default2={basename:""},freeGlobal=typeof define_global_default2=="object"&&define_global_default2&&define_global_default2.Object===Object&&define_global_default2;return _freeGlobal=freeGlobal,_freeGlobal}__name(require_freeGlobal,"require_freeGlobal");var _root,hasRequired_root;function require_root(){if(hasRequired_root)return _root;hasRequired_root=1;var freeGlobal=require_freeGlobal(),freeSelf=typeof self=="object"&&self&&self.Object===Object&&self,root2=freeGlobal||freeSelf||Function("return this")();return _root=root2,_root}__name(require_root,"require_root");var _Symbol,hasRequired_Symbol;function require_Symbol(){if(hasRequired_Symbol)return _Symbol;hasRequired_Symbol=1;var root2=require_root(),Symbol2=root2.Symbol;return _Symbol=Symbol2,_Symbol}__name(require_Symbol,"require_Symbol");var _getRawTag,hasRequired_getRawTag;function require_getRawTag(){if(hasRequired_getRawTag)return _getRawTag;hasRequired_getRawTag=1;var Symbol2=require_Symbol(),objectProto=Object.prototype,hasOwnProperty2=objectProto.hasOwnProperty,nativeObjectToString=objectProto.toString,symToStringTag=Symbol2?Symbol2.toStringTag:void 0;function getRawTag(value2){var isOwn=hasOwnProperty2.call(value2,symToStringTag),tag=value2[symToStringTag];try{value2[symToStringTag]=void 0;var unmasked=!0}catch{}var result=nativeObjectToString.call(value2);return unmasked&&(isOwn?value2[symToStringTag]=tag:delete value2[symToStringTag]),result}return __name(getRawTag,"getRawTag"),_getRawTag=getRawTag,_getRawTag}__name(require_getRawTag,"require_getRawTag");var _objectToString,hasRequired_objectToString;function require_objectToString(){if(hasRequired_objectToString)return _objectToString;hasRequired_objectToString=1;var objectProto=Object.prototype,nativeObjectToString=objectProto.toString;function objectToString(value2){return nativeObjectToString.call(value2)}return __name(objectToString,"objectToString"),_objectToString=objectToString,_objectToString}__name(require_objectToString,"require_objectToString");var _baseGetTag,hasRequired_baseGetTag;function require_baseGetTag(){if(hasRequired_baseGetTag)return _baseGetTag;hasRequired_baseGetTag=1;var Symbol2=require_Symbol(),getRawTag=require_getRawTag(),objectToString=require_objectToString(),nullTag="[object Null]",undefinedTag="[object Undefined]",symToStringTag=Symbol2?Symbol2.toStringTag:void 0;function baseGetTag(value2){return value2==null?value2===void 0?undefinedTag:nullTag:symToStringTag&&symToStringTag in Object(value2)?getRawTag(value2):objectToString(value2)}return __name(baseGetTag,"baseGetTag"),_baseGetTag=baseGetTag,_baseGetTag}__name(require_baseGetTag,"require_baseGetTag");var isObjectLike_1,hasRequiredIsObjectLike;function requireIsObjectLike(){if(hasRequiredIsObjectLike)return isObjectLike_1;hasRequiredIsObjectLike=1;function isObjectLike(value2){return value2!=null&&typeof value2=="object"}return __name(isObjectLike,"isObjectLike"),isObjectLike_1=isObjectLike,isObjectLike_1}__name(requireIsObjectLike,"requireIsObjectLike");var isSymbol_1,hasRequiredIsSymbol;function requireIsSymbol(){if(hasRequiredIsSymbol)return isSymbol_1;hasRequiredIsSymbol=1;var baseGetTag=require_baseGetTag(),isObjectLike=requireIsObjectLike(),symbolTag="[object Symbol]";function isSymbol(value2){return typeof value2=="symbol"||isObjectLike(value2)&&baseGetTag(value2)==symbolTag}return __name(isSymbol,"isSymbol"),isSymbol_1=isSymbol,isSymbol_1}__name(requireIsSymbol,"requireIsSymbol");var _isKey,hasRequired_isKey;function require_isKey(){if(hasRequired_isKey)return _isKey;hasRequired_isKey=1;var isArray2=requireIsArray(),isSymbol=requireIsSymbol(),reIsDeepProp=/\.|\[(?:[^[\]]*|(["'])(?:(?!\1)[^\\]|\\.)*?\1)\]/,reIsPlainProp=/^\w*$/;function isKey(value2,object2){if(isArray2(value2))return!1;var type=typeof value2;return type=="number"||type=="symbol"||type=="boolean"||value2==null||isSymbol(value2)?!0:reIsPlainProp.test(value2)||!reIsDeepProp.test(value2)||object2!=null&&value2 in Object(object2)}return __name(isKey,"isKey"),_isKey=isKey,_isKey}__name(require_isKey,"require_isKey");var isObject_1,hasRequiredIsObject;function requireIsObject(){if(hasRequiredIsObject)return isObject_1;hasRequiredIsObject=1;function isObject2(value2){var type=typeof value2;return value2!=null&&(type=="object"||type=="function")}return __name(isObject2,"isObject"),isObject_1=isObject2,isObject_1}__name(requireIsObject,"requireIsObject");var isFunction_1,hasRequiredIsFunction;function requireIsFunction(){if(hasRequiredIsFunction)return isFunction_1;hasRequiredIsFunction=1;var baseGetTag=require_baseGetTag(),isObject2=requireIsObject(),asyncTag="[object AsyncFunction]",funcTag="[object Function]",genTag="[object GeneratorFunction]",proxyTag="[object Proxy]";function isFunction2(value2){if(!isObject2(value2))return!1;var tag=baseGetTag(value2);return tag==funcTag||tag==genTag||tag==asyncTag||tag==proxyTag}return __name(isFunction2,"isFunction"),isFunction_1=isFunction2,isFunction_1}__name(requireIsFunction,"requireIsFunction");var _coreJsData,hasRequired_coreJsData;function require_coreJsData(){if(hasRequired_coreJsData)return _coreJsData;hasRequired_coreJsData=1;var root2=require_root(),coreJsData=root2["__core-js_shared__"];return _coreJsData=coreJsData,_coreJsData}__name(require_coreJsData,"require_coreJsData");var _isMasked,hasRequired_isMasked;function require_isMasked(){if(hasRequired_isMasked)return _isMasked;hasRequired_isMasked=1;var coreJsData=require_coreJsData(),maskSrcKey=(function(){var uid=/[^.]+$/.exec(coreJsData&&coreJsData.keys&&coreJsData.keys.IE_PROTO||"");return uid?"Symbol(src)_1."+uid:""})();function isMasked(func){return!!maskSrcKey&&maskSrcKey in func}return __name(isMasked,"isMasked"),_isMasked=isMasked,_isMasked}__name(require_isMasked,"require_isMasked");var _toSource,hasRequired_toSource;function require_toSource(){if(hasRequired_toSource)return _toSource;hasRequired_toSource=1;var funcProto=Function.prototype,funcToString=funcProto.toString;function toSource(func){if(func!=null){try{return funcToString.call(func)}catch{}try{return func+""}catch{}}return""}return __name(toSource,"toSource"),_toSource=toSource,_toSource}__name(require_toSource,"require_toSource");var _baseIsNative,hasRequired_baseIsNative;function require_baseIsNative(){if(hasRequired_baseIsNative)return _baseIsNative;hasRequired_baseIsNative=1;var isFunction2=requireIsFunction(),isMasked=require_isMasked(),isObject2=requireIsObject(),toSource=require_toSource(),reRegExpChar=/[\\^$.*+?()[\]{}|]/g,reIsHostCtor=/^\[object .+?Constructor\]$/,funcProto=Function.prototype,objectProto=Object.prototype,funcToString=funcProto.toString,hasOwnProperty2=objectProto.hasOwnProperty,reIsNative=RegExp("^"+funcToString.call(hasOwnProperty2).replace(reRegExpChar,"\\$&").replace(/hasOwnProperty|(function).*?(?=\\\()| for .+?(?=\\\])/g,"$1.*?")+"$");function baseIsNative(value2){if(!isObject2(value2)||isMasked(value2))return!1;var pattern=isFunction2(value2)?reIsNative:reIsHostCtor;return pattern.test(toSource(value2))}return __name(baseIsNative,"baseIsNative"),_baseIsNative=baseIsNative,_baseIsNative}__name(require_baseIsNative,"require_baseIsNative");var _getValue,hasRequired_getValue;function require_getValue(){if(hasRequired_getValue)return _getValue;hasRequired_getValue=1;function getValue(object2,key){return object2?.[key]}return __name(getValue,"getValue"),_getValue=getValue,_getValue}__name(require_getValue,"require_getValue");var _getNative,hasRequired_getNative;function require_getNative(){if(hasRequired_getNative)return _getNative;hasRequired_getNative=1;var baseIsNative=require_baseIsNative(),getValue=require_getValue();function getNative(object2,key){var value2=getValue(object2,key);return baseIsNative(value2)?value2:void 0}return __name(getNative,"getNative"),_getNative=getNative,_getNative}__name(require_getNative,"require_getNative");var _nativeCreate,hasRequired_nativeCreate;function require_nativeCreate(){if(hasRequired_nativeCreate)return _nativeCreate;hasRequired_nativeCreate=1;var getNative=require_getNative(),nativeCreate=getNative(Object,"create");return _nativeCreate=nativeCreate,_nativeCreate}__name(require_nativeCreate,"require_nativeCreate");var _hashClear,hasRequired_hashClear;function require_hashClear(){if(hasRequired_hashClear)return _hashClear;hasRequired_hashClear=1;var nativeCreate=require_nativeCreate();function hashClear(){this.__data__=nativeCreate?nativeCreate(null):{},this.size=0}return __name(hashClear,"hashClear"),_hashClear=hashClear,_hashClear}__name(require_hashClear,"require_hashClear");var _hashDelete,hasRequired_hashDelete;function require_hashDelete(){if(hasRequired_hashDelete)return _hashDelete;hasRequired_hashDelete=1;function hashDelete(key){var result=this.has(key)&&delete this.__data__[key];return this.size-=result?1:0,result}return __name(hashDelete,"hashDelete"),_hashDelete=hashDelete,_hashDelete}__name(require_hashDelete,"require_hashDelete");var _hashGet,hasRequired_hashGet;function require_hashGet(){if(hasRequired_hashGet)return _hashGet;hasRequired_hashGet=1;var nativeCreate=require_nativeCreate(),HASH_UNDEFINED="__lodash_hash_undefined__",objectProto=Object.prototype,hasOwnProperty2=objectProto.hasOwnProperty;function hashGet(key){var data=this.__data__;if(nativeCreate){var result=data[key];return result===HASH_UNDEFINED?void 0:result}return hasOwnProperty2.call(data,key)?data[key]:void 0}return __name(hashGet,"hashGet"),_hashGet=hashGet,_hashGet}__name(require_hashGet,"require_hashGet");var _hashHas,hasRequired_hashHas;function require_hashHas(){if(hasRequired_hashHas)return _hashHas;hasRequired_hashHas=1;var nativeCreate=require_nativeCreate(),objectProto=Object.prototype,hasOwnProperty2=objectProto.hasOwnProperty;function hashHas(key){var data=this.__data__;return nativeCreate?data[key]!==void 0:hasOwnProperty2.call(data,key)}return __name(hashHas,"hashHas"),_hashHas=hashHas,_hashHas}__name(require_hashHas,"require_hashHas");var _hashSet,hasRequired_hashSet;function require_hashSet(){if(hasRequired_hashSet)return _hashSet;hasRequired_hashSet=1;var nativeCreate=require_nativeCreate(),HASH_UNDEFINED="__lodash_hash_undefined__";function hashSet(key,value2){var data=this.__data__;return this.size+=this.has(key)?0:1,data[key]=nativeCreate&&value2===void 0?HASH_UNDEFINED:value2,this}return __name(hashSet,"hashSet"),_hashSet=hashSet,_hashSet}__name(require_hashSet,"require_hashSet");var _Hash,hasRequired_Hash;function require_Hash(){if(hasRequired_Hash)return _Hash;hasRequired_Hash=1;var hashClear=require_hashClear(),hashDelete=require_hashDelete(),hashGet=require_hashGet(),hashHas=require_hashHas(),hashSet=require_hashSet();function Hash2(entries){var index2=-1,length=entries==null?0:entries.length;for(this.clear();++index2-1}return __name(listCacheHas,"listCacheHas"),_listCacheHas=listCacheHas,_listCacheHas}__name(require_listCacheHas,"require_listCacheHas");var _listCacheSet,hasRequired_listCacheSet;function require_listCacheSet(){if(hasRequired_listCacheSet)return _listCacheSet;hasRequired_listCacheSet=1;var assocIndexOf=require_assocIndexOf();function listCacheSet(key,value2){var data=this.__data__,index2=assocIndexOf(data,key);return index2<0?(++this.size,data.push([key,value2])):data[index2][1]=value2,this}return __name(listCacheSet,"listCacheSet"),_listCacheSet=listCacheSet,_listCacheSet}__name(require_listCacheSet,"require_listCacheSet");var _ListCache,hasRequired_ListCache;function require_ListCache(){if(hasRequired_ListCache)return _ListCache;hasRequired_ListCache=1;var listCacheClear=require_listCacheClear(),listCacheDelete=require_listCacheDelete(),listCacheGet=require_listCacheGet(),listCacheHas=require_listCacheHas(),listCacheSet=require_listCacheSet();function ListCache(entries){var index2=-1,length=entries==null?0:entries.length;for(this.clear();++index20?1:-1},"mathSign"),isPercent=__name(function(value2){return O$4(value2)&&value2.indexOf("%")===value2.length-1},"isPercent"),isNumber$1=__name(function(value2){return isNumber$2(value2)&&!isNan(value2)},"isNumber"),isNullish=__name(function(value2){return isNil(value2)},"isNullish"),isNumOrStr=__name(function(value2){return isNumber$1(value2)||O$4(value2)},"isNumOrStr"),idCounter=0,uniqueId=__name(function(prefix2){var id=++idCounter;return"".concat(prefix2||"").concat(id)},"uniqueId"),getPercentValue=__name(function(percent,totalValue){var defaultValue=arguments.length>2&&arguments[2]!==void 0?arguments[2]:0,validate=arguments.length>3&&arguments[3]!==void 0?arguments[3]:!1;if(!isNumber$1(percent)&&!O$4(percent))return defaultValue;var value2;if(isPercent(percent)){var index2=percent.indexOf("%");value2=totalValue*parseFloat(percent.slice(0,index2))/100}else value2=+percent;return isNan(value2)&&(value2=defaultValue),validate&&value2>totalValue&&(value2=totalValue),value2},"getPercentValue"),getAnyElementOfObject=__name(function(obj){if(!obj)return null;var keys2=Object.keys(obj);return keys2&&keys2.length?obj[keys2[0]]:null},"getAnyElementOfObject"),hasDuplicate=__name(function(ary){if(!Array.isArray(ary))return!1;for(var len=ary.length,cache={},i2=0;i2=0)&&Object.prototype.propertyIsEnumerable.call(source,key)&&(target[key]=source[key])}return target}__name(_objectWithoutProperties$i,"_objectWithoutProperties$i");function _objectWithoutPropertiesLoose$i(source,excluded){if(source==null)return{};var target={};for(var key in source)if(Object.prototype.hasOwnProperty.call(source,key)){if(excluded.indexOf(key)>=0)continue;target[key]=source[key]}return target}__name(_objectWithoutPropertiesLoose$i,"_objectWithoutPropertiesLoose$i");var REACT_BROWSER_EVENT_MAP={click:"onClick",mousedown:"onMouseDown",mouseup:"onMouseUp",mouseover:"onMouseOver",mousemove:"onMouseMove",mouseout:"onMouseOut",mouseenter:"onMouseEnter",mouseleave:"onMouseLeave",touchcancel:"onTouchCancel",touchend:"onTouchEnd",touchmove:"onTouchMove",touchstart:"onTouchStart",contextmenu:"onContextMenu",dblclick:"onDoubleClick"},getDisplayName$1=__name(function(Comp){return typeof Comp=="string"?Comp:Comp?Comp.displayName||Comp.name||"Component":""},"getDisplayName"),lastChildren=null,lastResult=null,toArray$1=__name(function toArray(children2){if(children2===lastChildren&&Array.isArray(lastResult))return lastResult;var result=[];return reactExports.Children.forEach(children2,function(child){isNil(child)||(reactIsExports.isFragment(child)?result=result.concat(toArray(child.props.children)):result.push(child))}),lastResult=result,lastChildren=children2,result},"toArray");function findAllByType(children2,type){var result=[],types2=[];return Array.isArray(type)?types2=type.map(function(t2){return getDisplayName$1(t2)}):types2=[getDisplayName$1(type)],toArray$1(children2).forEach(function(child){var childType=ke(child,"type.displayName")||ke(child,"type.name");types2.indexOf(childType)!==-1&&result.push(child)}),result}__name(findAllByType,"findAllByType");function findChildByType(children2,type){var result=findAllByType(children2,type);return result&&result[0]}__name(findChildByType,"findChildByType");var validateWidthHeight=__name(function(el){if(!el||!el.props)return!1;var _el$props=el.props,width=_el$props.width,height=_el$props.height;return!(!isNumber$1(width)||width<=0||!isNumber$1(height)||height<=0)},"validateWidthHeight"),SVG_TAGS=["a","altGlyph","altGlyphDef","altGlyphItem","animate","animateColor","animateMotion","animateTransform","circle","clipPath","color-profile","cursor","defs","desc","ellipse","feBlend","feColormatrix","feComponentTransfer","feComposite","feConvolveMatrix","feDiffuseLighting","feDisplacementMap","feDistantLight","feFlood","feFuncA","feFuncB","feFuncG","feFuncR","feGaussianBlur","feImage","feMerge","feMergeNode","feMorphology","feOffset","fePointLight","feSpecularLighting","feSpotLight","feTile","feTurbulence","filter","font","font-face","font-face-format","font-face-name","font-face-url","foreignObject","g","glyph","glyphRef","hkern","image","line","lineGradient","marker","mask","metadata","missing-glyph","mpath","path","pattern","polygon","polyline","radialGradient","rect","script","set","stop","style","svg","switch","symbol","text","textPath","title","tref","tspan","use","view","vkern"],isSvgElement=__name(function(child){return child&&child.type&&O$4(child.type)&&SVG_TAGS.indexOf(child.type)>=0},"isSvgElement"),isValidSpreadableProp=__name(function(property,key,includeEvents,svgElementType){var _FilteredElementKeyMa,matchingElementTypeKeys=(_FilteredElementKeyMa=FilteredElementKeyMap?.[svgElementType])!==null&&_FilteredElementKeyMa!==void 0?_FilteredElementKeyMa:[];return key.startsWith("data-")||!Qe(property)&&(svgElementType&&matchingElementTypeKeys.includes(key)||SVGElementPropKeys.includes(key))||includeEvents&&EventKeys.includes(key)},"isValidSpreadableProp"),filterProps=__name(function(props,includeEvents,svgElementType){if(!props||typeof props=="function"||typeof props=="boolean")return null;var inputProps=props;if(reactExports.isValidElement(props)&&(inputProps=props.props),!isObject(inputProps))return null;var out={};return Object.keys(inputProps).forEach(function(key){var _inputProps;isValidSpreadableProp((_inputProps=inputProps)===null||_inputProps===void 0?void 0:_inputProps[key],key,includeEvents,svgElementType)&&(out[key]=inputProps[key])}),out},"filterProps"),isChildrenEqual=__name(function isChildrenEqual2(nextChildren,prevChildren){if(nextChildren===prevChildren)return!0;var count2=reactExports.Children.count(nextChildren);if(count2!==reactExports.Children.count(prevChildren))return!1;if(count2===0)return!0;if(count2===1)return isSingleChildEqual(Array.isArray(nextChildren)?nextChildren[0]:nextChildren,Array.isArray(prevChildren)?prevChildren[0]:prevChildren);for(var i2=0;i2=0)&&Object.prototype.propertyIsEnumerable.call(source,key)&&(target[key]=source[key])}return target}__name(_objectWithoutProperties$h,"_objectWithoutProperties$h");function _objectWithoutPropertiesLoose$h(source,excluded){if(source==null)return{};var target={};for(var key in source)if(Object.prototype.hasOwnProperty.call(source,key)){if(excluded.indexOf(key)>=0)continue;target[key]=source[key]}return target}__name(_objectWithoutPropertiesLoose$h,"_objectWithoutPropertiesLoose$h");function Surface(props){var children2=props.children,width=props.width,height=props.height,viewBox=props.viewBox,className=props.className,style2=props.style,title=props.title,desc=props.desc,others=_objectWithoutProperties$h(props,_excluded$h),svgView=viewBox||{width,height,x:0,y:0},layerClass=clsx("recharts-surface",className);return React.createElement("svg",_extends$u({},filterProps(others,!0,"svg"),{className:layerClass,width,height,style:style2,viewBox:"".concat(svgView.x," ").concat(svgView.y," ").concat(svgView.width," ").concat(svgView.height)}),React.createElement("title",null,title),React.createElement("desc",null,desc),children2)}__name(Surface,"Surface");var _excluded$g=["children","className"];function _extends$t(){return _extends$t=Object.assign?Object.assign.bind():function(target){for(var i2=1;i2=0)&&Object.prototype.propertyIsEnumerable.call(source,key)&&(target[key]=source[key])}return target}__name(_objectWithoutProperties$g,"_objectWithoutProperties$g");function _objectWithoutPropertiesLoose$g(source,excluded){if(source==null)return{};var target={};for(var key in source)if(Object.prototype.hasOwnProperty.call(source,key)){if(excluded.indexOf(key)>=0)continue;target[key]=source[key]}return target}__name(_objectWithoutPropertiesLoose$g,"_objectWithoutPropertiesLoose$g");var Layer=React.forwardRef(function(props,ref){var children2=props.children,className=props.className,others=_objectWithoutProperties$g(props,_excluded$g),layerClass=clsx("recharts-layer",className);return React.createElement("g",_extends$t({className:layerClass},filterProps(others,!0),{ref}),children2)}),warn=__name(function(condition,format2){for(var _len=arguments.length,args=new Array(_len>2?_len-2:0),_key=2;_key<_len;_key++)args[_key-2]=arguments[_key]},"warn2"),_baseSlice,hasRequired_baseSlice;function require_baseSlice(){if(hasRequired_baseSlice)return _baseSlice;hasRequired_baseSlice=1;function baseSlice(array2,start2,end){var index2=-1,length=array2.length;start2<0&&(start2=-start2>length?0:length+start2),end=end>length?length:end,end<0&&(end+=length),length=start2>end?0:end-start2>>>0,start2>>>=0;for(var result=Array(length);++index2=length?array2:baseSlice(array2,start2,end)}return __name(castSlice,"castSlice"),_castSlice=castSlice,_castSlice}__name(require_castSlice,"require_castSlice");var _hasUnicode,hasRequired_hasUnicode;function require_hasUnicode(){if(hasRequired_hasUnicode)return _hasUnicode;hasRequired_hasUnicode=1;var rsAstralRange="\\ud800-\\udfff",rsComboMarksRange="\\u0300-\\u036f",reComboHalfMarksRange="\\ufe20-\\ufe2f",rsComboSymbolsRange="\\u20d0-\\u20ff",rsComboRange=rsComboMarksRange+reComboHalfMarksRange+rsComboSymbolsRange,rsVarRange="\\ufe0e\\ufe0f",rsZWJ="\\u200d",reHasUnicode=RegExp("["+rsZWJ+rsAstralRange+rsComboRange+rsVarRange+"]");function hasUnicode(string2){return reHasUnicode.test(string2)}return __name(hasUnicode,"hasUnicode"),_hasUnicode=hasUnicode,_hasUnicode}__name(require_hasUnicode,"require_hasUnicode");var _asciiToArray,hasRequired_asciiToArray;function require_asciiToArray(){if(hasRequired_asciiToArray)return _asciiToArray;hasRequired_asciiToArray=1;function asciiToArray(string2){return string2.split("")}return __name(asciiToArray,"asciiToArray"),_asciiToArray=asciiToArray,_asciiToArray}__name(require_asciiToArray,"require_asciiToArray");var _unicodeToArray,hasRequired_unicodeToArray;function require_unicodeToArray(){if(hasRequired_unicodeToArray)return _unicodeToArray;hasRequired_unicodeToArray=1;var rsAstralRange="\\ud800-\\udfff",rsComboMarksRange="\\u0300-\\u036f",reComboHalfMarksRange="\\ufe20-\\ufe2f",rsComboSymbolsRange="\\u20d0-\\u20ff",rsComboRange=rsComboMarksRange+reComboHalfMarksRange+rsComboSymbolsRange,rsVarRange="\\ufe0e\\ufe0f",rsAstral="["+rsAstralRange+"]",rsCombo="["+rsComboRange+"]",rsFitz="\\ud83c[\\udffb-\\udfff]",rsModifier="(?:"+rsCombo+"|"+rsFitz+")",rsNonAstral="[^"+rsAstralRange+"]",rsRegional="(?:\\ud83c[\\udde6-\\uddff]){2}",rsSurrPair="[\\ud800-\\udbff][\\udc00-\\udfff]",rsZWJ="\\u200d",reOptMod=rsModifier+"?",rsOptVar="["+rsVarRange+"]?",rsOptJoin="(?:"+rsZWJ+"(?:"+[rsNonAstral,rsRegional,rsSurrPair].join("|")+")"+rsOptVar+reOptMod+")*",rsSeq=rsOptVar+reOptMod+rsOptJoin,rsSymbol="(?:"+[rsNonAstral+rsCombo+"?",rsCombo,rsRegional,rsSurrPair,rsAstral].join("|")+")",reUnicode=RegExp(rsFitz+"(?="+rsFitz+")|"+rsSymbol+rsSeq,"g");function unicodeToArray(string2){return string2.match(reUnicode)||[]}return __name(unicodeToArray,"unicodeToArray"),_unicodeToArray=unicodeToArray,_unicodeToArray}__name(require_unicodeToArray,"require_unicodeToArray");var _stringToArray,hasRequired_stringToArray;function require_stringToArray(){if(hasRequired_stringToArray)return _stringToArray;hasRequired_stringToArray=1;var asciiToArray=require_asciiToArray(),hasUnicode=require_hasUnicode(),unicodeToArray=require_unicodeToArray();function stringToArray(string2){return hasUnicode(string2)?unicodeToArray(string2):asciiToArray(string2)}return __name(stringToArray,"stringToArray"),_stringToArray=stringToArray,_stringToArray}__name(require_stringToArray,"require_stringToArray");var _createCaseFirst,hasRequired_createCaseFirst;function require_createCaseFirst(){if(hasRequired_createCaseFirst)return _createCaseFirst;hasRequired_createCaseFirst=1;var castSlice=require_castSlice(),hasUnicode=require_hasUnicode(),stringToArray=require_stringToArray(),toString2=requireToString();function createCaseFirst(methodName){return function(string2){string2=toString2(string2);var strSymbols=hasUnicode(string2)?stringToArray(string2):void 0,chr=strSymbols?strSymbols[0]:string2.charAt(0),trailing=strSymbols?castSlice(strSymbols,1).join(""):string2.slice(1);return chr[methodName]()+trailing}}return __name(createCaseFirst,"createCaseFirst"),_createCaseFirst=createCaseFirst,_createCaseFirst}__name(require_createCaseFirst,"require_createCaseFirst");var upperFirst_1,hasRequiredUpperFirst;function requireUpperFirst(){if(hasRequiredUpperFirst)return upperFirst_1;hasRequiredUpperFirst=1;var createCaseFirst=require_createCaseFirst(),upperFirst2=createCaseFirst("toUpperCase");return upperFirst_1=upperFirst2,upperFirst_1}__name(requireUpperFirst,"requireUpperFirst");var upperFirstExports=requireUpperFirst();const upperFirst=getDefaultExportFromCjs(upperFirstExports);function constant$2(x2){return __name(function(){return x2},"constant")}__name(constant$2,"constant$2");const cos=Math.cos,sin=Math.sin,sqrt$1=Math.sqrt,epsilon$1=1e-12,pi$1=Math.PI,tau$1=2*pi$1,pi=Math.PI,tau=2*pi,epsilon=1e-6,tauEpsilon=tau-epsilon;function append(strings){this._+=strings[0];for(let i2=1,n2=strings.length;i2=0))throw new Error(`invalid digits: ${digits}`);if(d>15)return append;const k2=10**d;return function(strings){this._+=strings[0];for(let i2=1,n2=strings.length;i2epsilon)if(!(Math.abs(y01*x21-y21*x01)>epsilon)||!r2)this._append`L${this._x1=x1},${this._y1=y1}`;else{let x20=x2-x0,y20=y2-y0,l21_2=x21*x21+y21*y21,l20_2=x20*x20+y20*y20,l21=Math.sqrt(l21_2),l01=Math.sqrt(l01_2),l2=r2*Math.tan((pi-Math.acos((l21_2+l01_2-l20_2)/(2*l21*l01)))/2),t01=l2/l01,t21=l2/l21;Math.abs(t01-1)>epsilon&&this._append`L${x1+t01*x01},${y1+t01*y01}`,this._append`A${r2},${r2},0,0,${+(y01*x20>x01*y20)},${this._x1=x1+t21*x21},${this._y1=y1+t21*y21}`}}arc(x2,y2,r2,a0,a1,ccw){if(x2=+x2,y2=+y2,r2=+r2,ccw=!!ccw,r2<0)throw new Error(`negative radius: ${r2}`);let dx=r2*Math.cos(a0),dy=r2*Math.sin(a0),x0=x2+dx,y0=y2+dy,cw=1^ccw,da=ccw?a0-a1:a1-a0;this._x1===null?this._append`M${x0},${y0}`:(Math.abs(this._x1-x0)>epsilon||Math.abs(this._y1-y0)>epsilon)&&this._append`L${x0},${y0}`,r2&&(da<0&&(da=da%tau+tau),da>tauEpsilon?this._append`A${r2},${r2},0,1,${cw},${x2-dx},${y2-dy}A${r2},${r2},0,1,${cw},${this._x1=x0},${this._y1=y0}`:da>epsilon&&this._append`A${r2},${r2},0,${+(da>=pi)},${cw},${this._x1=x2+r2*Math.cos(a1)},${this._y1=y2+r2*Math.sin(a1)}`)}rect(x2,y2,w2,h2){this._append`M${this._x0=this._x1=+x2},${this._y0=this._y1=+y2}h${w2=+w2}v${+h2}h${-w2}Z`}toString(){return this._}};__name(_Path,"Path");let Path=_Path;function withPath(shape){let digits=3;return shape.digits=function(_2){if(!arguments.length)return digits;if(_2==null)digits=null;else{const d=Math.floor(_2);if(!(d>=0))throw new RangeError(`invalid digits: ${_2}`);digits=d}return shape},()=>new Path(digits)}__name(withPath,"withPath");function array(x2){return typeof x2=="object"&&"length"in x2?x2:Array.from(x2)}__name(array,"array");function Linear(context){this._context=context}__name(Linear,"Linear");Linear.prototype={areaStart:__name(function(){this._line=0},"areaStart"),areaEnd:__name(function(){this._line=NaN},"areaEnd"),lineStart:__name(function(){this._point=0},"lineStart"),lineEnd:__name(function(){(this._line||this._line!==0&&this._point===1)&&this._context.closePath(),this._line=1-this._line},"lineEnd"),point:__name(function(x2,y2){switch(x2=+x2,y2=+y2,this._point){case 0:this._point=1,this._line?this._context.lineTo(x2,y2):this._context.moveTo(x2,y2);break;case 1:this._point=2;default:this._context.lineTo(x2,y2);break}},"point")};function sr(context){return new Linear(context)}__name(sr,"sr");function x$2(p2){return p2[0]}__name(x$2,"x$2");function y$1(p2){return p2[1]}__name(y$1,"y$1");function N$2(x2,y2){var defined3=constant$2(!0),context=null,curve=sr,output=null,path2=withPath(line);x2=typeof x2=="function"?x2:x2===void 0?x$2:constant$2(x2),y2=typeof y2=="function"?y2:y2===void 0?y$1:constant$2(y2);function line(data){var i2,n2=(data=array(data)).length,d,defined0=!1,buffer;for(context==null&&(output=curve(buffer=path2())),i2=0;i2<=n2;++i2)!(i2=j2;--k2)output.point(x0z[k2],y0z[k2]);output.lineEnd(),output.areaEnd()}defined0&&(x0z[i2]=+x0(d,i2,data),y0z[i2]=+y0(d,i2,data),output.point(x1?+x1(d,i2,data):x0z[i2],y1?+y1(d,i2,data):y0z[i2]))}if(buffer)return output=null,buffer+""||null}__name(area,"area");function arealine(){return N$2().defined(defined3).curve(curve).context(context)}return __name(arealine,"arealine"),area.x=function(_2){return arguments.length?(x0=typeof _2=="function"?_2:constant$2(+_2),x1=null,area):x0},area.x0=function(_2){return arguments.length?(x0=typeof _2=="function"?_2:constant$2(+_2),area):x0},area.x1=function(_2){return arguments.length?(x1=_2==null?null:typeof _2=="function"?_2:constant$2(+_2),area):x1},area.y=function(_2){return arguments.length?(y0=typeof _2=="function"?_2:constant$2(+_2),y1=null,area):y0},area.y0=function(_2){return arguments.length?(y0=typeof _2=="function"?_2:constant$2(+_2),area):y0},area.y1=function(_2){return arguments.length?(y1=_2==null?null:typeof _2=="function"?_2:constant$2(+_2),area):y1},area.lineX0=area.lineY0=function(){return arealine().x(x0).y(y0)},area.lineY1=function(){return arealine().x(x0).y(y1)},area.lineX1=function(){return arealine().x(x1).y(y0)},area.defined=function(_2){return arguments.length?(defined3=typeof _2=="function"?_2:constant$2(!!_2),area):defined3},area.curve=function(_2){return arguments.length?(curve=_2,context!=null&&(output=curve(context)),area):curve},area.context=function(_2){return arguments.length?(_2==null?context=output=null:output=curve(context=_2),area):context},area}__name(shapeArea,"shapeArea");const _Bump=class _Bump{constructor(context,x2){this._context=context,this._x=x2}areaStart(){this._line=0}areaEnd(){this._line=NaN}lineStart(){this._point=0}lineEnd(){(this._line||this._line!==0&&this._point===1)&&this._context.closePath(),this._line=1-this._line}point(x2,y2){switch(x2=+x2,y2=+y2,this._point){case 0:{this._point=1,this._line?this._context.lineTo(x2,y2):this._context.moveTo(x2,y2);break}case 1:this._point=2;default:{this._x?this._context.bezierCurveTo(this._x0=(this._x0+x2)/2,this._y0,this._x0,y2,x2,y2):this._context.bezierCurveTo(this._x0,this._y0=(this._y0+y2)/2,x2,this._y0,x2,y2);break}}this._x0=x2,this._y0=y2}};__name(_Bump,"Bump");let Bump=_Bump;function bumpX(context){return new Bump(context,!0)}__name(bumpX,"bumpX");function bumpY(context){return new Bump(context,!1)}__name(bumpY,"bumpY");const symbolCircle={draw(context,size2){const r2=sqrt$1(size2/pi$1);context.moveTo(r2,0),context.arc(0,0,r2,0,tau$1)}},symbolCross={draw(context,size2){const r2=sqrt$1(size2/5)/2;context.moveTo(-3*r2,-r2),context.lineTo(-r2,-r2),context.lineTo(-r2,-3*r2),context.lineTo(r2,-3*r2),context.lineTo(r2,-r2),context.lineTo(3*r2,-r2),context.lineTo(3*r2,r2),context.lineTo(r2,r2),context.lineTo(r2,3*r2),context.lineTo(-r2,3*r2),context.lineTo(-r2,r2),context.lineTo(-3*r2,r2),context.closePath()}},tan30=sqrt$1(1/3),tan30_2=tan30*2,symbolDiamond={draw(context,size2){const y2=sqrt$1(size2/tan30_2),x2=y2*tan30;context.moveTo(0,-y2),context.lineTo(x2,0),context.lineTo(0,y2),context.lineTo(-x2,0),context.closePath()}},symbolSquare={draw(context,size2){const w2=sqrt$1(size2),x2=-w2/2;context.rect(x2,x2,w2,w2)}},ka=.8908130915292852,kr$1=sin(pi$1/10)/sin(7*pi$1/10),kx=sin(tau$1/10)*kr$1,ky=-cos(tau$1/10)*kr$1,symbolStar={draw(context,size2){const r2=sqrt$1(size2*ka),x2=kx*r2,y2=ky*r2;context.moveTo(0,-r2),context.lineTo(x2,y2);for(let i2=1;i2<5;++i2){const a2=tau$1*i2/5,c2=cos(a2),s2=sin(a2);context.lineTo(s2*r2,-c2*r2),context.lineTo(c2*x2-s2*y2,s2*x2+c2*y2)}context.closePath()}},sqrt3=sqrt$1(3),symbolTriangle={draw(context,size2){const y2=-sqrt$1(size2/(sqrt3*3));context.moveTo(0,y2*2),context.lineTo(-sqrt3*y2,-y2),context.lineTo(sqrt3*y2,-y2),context.closePath()}},c$3=-.5,s$1=sqrt$1(3)/2,k$3=1/sqrt$1(12),a$1=(k$3/2+1)*3,symbolWye={draw(context,size2){const r2=sqrt$1(size2/a$1),x0=r2/2,y0=r2*k$3,x1=x0,y1=r2*k$3+r2,x2=-x1,y2=y1;context.moveTo(x0,y0),context.lineTo(x1,y1),context.lineTo(x2,y2),context.lineTo(c$3*x0-s$1*y0,s$1*x0+c$3*y0),context.lineTo(c$3*x1-s$1*y1,s$1*x1+c$3*y1),context.lineTo(c$3*x2-s$1*y2,s$1*x2+c$3*y2),context.lineTo(c$3*x0+s$1*y0,c$3*y0-s$1*x0),context.lineTo(c$3*x1+s$1*y1,c$3*y1-s$1*x1),context.lineTo(c$3*x2+s$1*y2,c$3*y2-s$1*x2),context.closePath()}};function Symbol$1(type,size2){let context=null,path2=withPath(symbol);type=typeof type=="function"?type:constant$2(type||symbolCircle),size2=typeof size2=="function"?size2:constant$2(size2===void 0?64:+size2);function symbol(){let buffer;if(context||(context=buffer=path2()),type.apply(this,arguments).draw(context,+size2.apply(this,arguments)),buffer)return context=null,buffer+""||null}return __name(symbol,"symbol"),symbol.type=function(_2){return arguments.length?(type=typeof _2=="function"?_2:constant$2(_2),symbol):type},symbol.size=function(_2){return arguments.length?(size2=typeof _2=="function"?_2:constant$2(+_2),symbol):size2},symbol.context=function(_2){return arguments.length?(context=_2??null,symbol):context},symbol}__name(Symbol$1,"Symbol$1");function noop$1(){}__name(noop$1,"noop$1");function point$8(that,x2,y2){that._context.bezierCurveTo((2*that._x0+that._x1)/3,(2*that._y0+that._y1)/3,(that._x0+2*that._x1)/3,(that._y0+2*that._y1)/3,(that._x0+4*that._x1+x2)/6,(that._y0+4*that._y1+y2)/6)}__name(point$8,"point$8");function Basis(context){this._context=context}__name(Basis,"Basis");Basis.prototype={areaStart:__name(function(){this._line=0},"areaStart"),areaEnd:__name(function(){this._line=NaN},"areaEnd"),lineStart:__name(function(){this._x0=this._x1=this._y0=this._y1=NaN,this._point=0},"lineStart"),lineEnd:__name(function(){switch(this._point){case 3:point$8(this,this._x1,this._y1);case 2:this._context.lineTo(this._x1,this._y1);break}(this._line||this._line!==0&&this._point===1)&&this._context.closePath(),this._line=1-this._line},"lineEnd"),point:__name(function(x2,y2){switch(x2=+x2,y2=+y2,this._point){case 0:this._point=1,this._line?this._context.lineTo(x2,y2):this._context.moveTo(x2,y2);break;case 1:this._point=2;break;case 2:this._point=3,this._context.lineTo((5*this._x0+this._x1)/6,(5*this._y0+this._y1)/6);default:point$8(this,x2,y2);break}this._x0=this._x1,this._x1=x2,this._y0=this._y1,this._y1=y2},"point")};function $e$1(context){return new Basis(context)}__name($e$1,"$e$1");function BasisClosed(context){this._context=context}__name(BasisClosed,"BasisClosed");BasisClosed.prototype={areaStart:noop$1,areaEnd:noop$1,lineStart:__name(function(){this._x0=this._x1=this._x2=this._x3=this._x4=this._y0=this._y1=this._y2=this._y3=this._y4=NaN,this._point=0},"lineStart"),lineEnd:__name(function(){switch(this._point){case 1:{this._context.moveTo(this._x2,this._y2),this._context.closePath();break}case 2:{this._context.moveTo((this._x2+2*this._x3)/3,(this._y2+2*this._y3)/3),this._context.lineTo((this._x3+2*this._x2)/3,(this._y3+2*this._y2)/3),this._context.closePath();break}case 3:{this.point(this._x2,this._y2),this.point(this._x3,this._y3),this.point(this._x4,this._y4);break}}},"lineEnd"),point:__name(function(x2,y2){switch(x2=+x2,y2=+y2,this._point){case 0:this._point=1,this._x2=x2,this._y2=y2;break;case 1:this._point=2,this._x3=x2,this._y3=y2;break;case 2:this._point=3,this._x4=x2,this._y4=y2,this._context.moveTo((this._x0+4*this._x1+x2)/6,(this._y0+4*this._y1+y2)/6);break;default:point$8(this,x2,y2);break}this._x0=this._x1,this._x1=x2,this._y0=this._y1,this._y1=y2},"point")};function er(context){return new BasisClosed(context)}__name(er,"er");function BasisOpen(context){this._context=context}__name(BasisOpen,"BasisOpen");BasisOpen.prototype={areaStart:__name(function(){this._line=0},"areaStart"),areaEnd:__name(function(){this._line=NaN},"areaEnd"),lineStart:__name(function(){this._x0=this._x1=this._y0=this._y1=NaN,this._point=0},"lineStart"),lineEnd:__name(function(){(this._line||this._line!==0&&this._point===3)&&this._context.closePath(),this._line=1-this._line},"lineEnd"),point:__name(function(x2,y2){switch(x2=+x2,y2=+y2,this._point){case 0:this._point=1;break;case 1:this._point=2;break;case 2:this._point=3;var x0=(this._x0+4*this._x1+x2)/6,y0=(this._y0+4*this._y1+y2)/6;this._line?this._context.lineTo(x0,y0):this._context.moveTo(x0,y0);break;case 3:this._point=4;default:point$8(this,x2,y2);break}this._x0=this._x1,this._x1=x2,this._y0=this._y1,this._y1=y2},"point")};function rr(context){return new BasisOpen(context)}__name(rr,"rr");function Bundle(context,beta){this._basis=new Basis(context),this._beta=beta}__name(Bundle,"Bundle");Bundle.prototype={lineStart:__name(function(){this._x=[],this._y=[],this._basis.lineStart()},"lineStart"),lineEnd:__name(function(){var x2=this._x,y2=this._y,j2=x2.length-1;if(j2>0)for(var x0=x2[0],y0=y2[0],dx=x2[j2]-x0,dy=y2[j2]-y0,i2=-1,t2;++i2<=j2;)t2=i2/j2,this._basis.point(this._beta*x2[i2]+(1-this._beta)*(x0+t2*dx),this._beta*y2[i2]+(1-this._beta)*(y0+t2*dy));this._x=this._y=null,this._basis.lineEnd()},"lineEnd"),point:__name(function(x2,y2){this._x.push(+x2),this._y.push(+y2)},"point")};const tr=__name((function custom(beta){function bundle(context){return beta===1?new Basis(context):new Bundle(context,beta)}return __name(bundle,"bundle"),bundle.beta=function(beta2){return custom(+beta2)},bundle}),"custom")(.85);function point$7(that,x2,y2){that._context.bezierCurveTo(that._x1+that._k*(that._x2-that._x0),that._y1+that._k*(that._y2-that._y0),that._x2+that._k*(that._x1-x2),that._y2+that._k*(that._y1-y2),that._x2,that._y2)}__name(point$7,"point$7");function Cardinal(context,tension){this._context=context,this._k=(1-tension)/6}__name(Cardinal,"Cardinal");Cardinal.prototype={areaStart:__name(function(){this._line=0},"areaStart"),areaEnd:__name(function(){this._line=NaN},"areaEnd"),lineStart:__name(function(){this._x0=this._x1=this._x2=this._y0=this._y1=this._y2=NaN,this._point=0},"lineStart"),lineEnd:__name(function(){switch(this._point){case 2:this._context.lineTo(this._x2,this._y2);break;case 3:point$7(this,this._x1,this._y1);break}(this._line||this._line!==0&&this._point===1)&&this._context.closePath(),this._line=1-this._line},"lineEnd"),point:__name(function(x2,y2){switch(x2=+x2,y2=+y2,this._point){case 0:this._point=1,this._line?this._context.lineTo(x2,y2):this._context.moveTo(x2,y2);break;case 1:this._point=2,this._x1=x2,this._y1=y2;break;case 2:this._point=3;default:point$7(this,x2,y2);break}this._x0=this._x1,this._x1=this._x2,this._x2=x2,this._y0=this._y1,this._y1=this._y2,this._y2=y2},"point")};const nr=__name((function custom2(tension){function cardinal(context){return new Cardinal(context,tension)}return __name(cardinal,"cardinal"),cardinal.tension=function(tension2){return custom2(+tension2)},cardinal}),"custom")(0);function CardinalClosed(context,tension){this._context=context,this._k=(1-tension)/6}__name(CardinalClosed,"CardinalClosed");CardinalClosed.prototype={areaStart:noop$1,areaEnd:noop$1,lineStart:__name(function(){this._x0=this._x1=this._x2=this._x3=this._x4=this._x5=this._y0=this._y1=this._y2=this._y3=this._y4=this._y5=NaN,this._point=0},"lineStart"),lineEnd:__name(function(){switch(this._point){case 1:{this._context.moveTo(this._x3,this._y3),this._context.closePath();break}case 2:{this._context.lineTo(this._x3,this._y3),this._context.closePath();break}case 3:{this.point(this._x3,this._y3),this.point(this._x4,this._y4),this.point(this._x5,this._y5);break}}},"lineEnd"),point:__name(function(x2,y2){switch(x2=+x2,y2=+y2,this._point){case 0:this._point=1,this._x3=x2,this._y3=y2;break;case 1:this._point=2,this._context.moveTo(this._x4=x2,this._y4=y2);break;case 2:this._point=3,this._x5=x2,this._y5=y2;break;default:point$7(this,x2,y2);break}this._x0=this._x1,this._x1=this._x2,this._x2=x2,this._y0=this._y1,this._y1=this._y2,this._y2=y2},"point")};const ir=__name((function custom3(tension){function cardinal(context){return new CardinalClosed(context,tension)}return __name(cardinal,"cardinal"),cardinal.tension=function(tension2){return custom3(+tension2)},cardinal}),"custom")(0);function CardinalOpen(context,tension){this._context=context,this._k=(1-tension)/6}__name(CardinalOpen,"CardinalOpen");CardinalOpen.prototype={areaStart:__name(function(){this._line=0},"areaStart"),areaEnd:__name(function(){this._line=NaN},"areaEnd"),lineStart:__name(function(){this._x0=this._x1=this._x2=this._y0=this._y1=this._y2=NaN,this._point=0},"lineStart"),lineEnd:__name(function(){(this._line||this._line!==0&&this._point===3)&&this._context.closePath(),this._line=1-this._line},"lineEnd"),point:__name(function(x2,y2){switch(x2=+x2,y2=+y2,this._point){case 0:this._point=1;break;case 1:this._point=2;break;case 2:this._point=3,this._line?this._context.lineTo(this._x2,this._y2):this._context.moveTo(this._x2,this._y2);break;case 3:this._point=4;default:point$7(this,x2,y2);break}this._x0=this._x1,this._x1=this._x2,this._x2=x2,this._y0=this._y1,this._y1=this._y2,this._y2=y2},"point")};const or=__name((function custom4(tension){function cardinal(context){return new CardinalOpen(context,tension)}return __name(cardinal,"cardinal"),cardinal.tension=function(tension2){return custom4(+tension2)},cardinal}),"custom")(0);function point$6(that,x2,y2){var x1=that._x1,y1=that._y1,x22=that._x2,y22=that._y2;if(that._l01_a>epsilon$1){var a2=2*that._l01_2a+3*that._l01_a*that._l12_a+that._l12_2a,n2=3*that._l01_a*(that._l01_a+that._l12_a);x1=(x1*a2-that._x0*that._l12_2a+that._x2*that._l01_2a)/n2,y1=(y1*a2-that._y0*that._l12_2a+that._y2*that._l01_2a)/n2}if(that._l23_a>epsilon$1){var b2=2*that._l23_2a+3*that._l23_a*that._l12_a+that._l12_2a,m2=3*that._l23_a*(that._l23_a+that._l12_a);x22=(x22*b2+that._x1*that._l23_2a-x2*that._l12_2a)/m2,y22=(y22*b2+that._y1*that._l23_2a-y2*that._l12_2a)/m2}that._context.bezierCurveTo(x1,y1,x22,y22,that._x2,that._y2)}__name(point$6,"point$6");function CatmullRom(context,alpha3){this._context=context,this._alpha=alpha3}__name(CatmullRom,"CatmullRom");CatmullRom.prototype={areaStart:__name(function(){this._line=0},"areaStart"),areaEnd:__name(function(){this._line=NaN},"areaEnd"),lineStart:__name(function(){this._x0=this._x1=this._x2=this._y0=this._y1=this._y2=NaN,this._l01_a=this._l12_a=this._l23_a=this._l01_2a=this._l12_2a=this._l23_2a=this._point=0},"lineStart"),lineEnd:__name(function(){switch(this._point){case 2:this._context.lineTo(this._x2,this._y2);break;case 3:this.point(this._x2,this._y2);break}(this._line||this._line!==0&&this._point===1)&&this._context.closePath(),this._line=1-this._line},"lineEnd"),point:__name(function(x2,y2){if(x2=+x2,y2=+y2,this._point){var x23=this._x2-x2,y23=this._y2-y2;this._l23_a=Math.sqrt(this._l23_2a=Math.pow(x23*x23+y23*y23,this._alpha))}switch(this._point){case 0:this._point=1,this._line?this._context.lineTo(x2,y2):this._context.moveTo(x2,y2);break;case 1:this._point=2;break;case 2:this._point=3;default:point$6(this,x2,y2);break}this._l01_a=this._l12_a,this._l12_a=this._l23_a,this._l01_2a=this._l12_2a,this._l12_2a=this._l23_2a,this._x0=this._x1,this._x1=this._x2,this._x2=x2,this._y0=this._y1,this._y1=this._y2,this._y2=y2},"point")};const lr=__name((function custom5(alpha3){function catmullRom(context){return alpha3?new CatmullRom(context,alpha3):new Cardinal(context,0)}return __name(catmullRom,"catmullRom"),catmullRom.alpha=function(alpha4){return custom5(+alpha4)},catmullRom}),"custom")(.5);function CatmullRomClosed(context,alpha3){this._context=context,this._alpha=alpha3}__name(CatmullRomClosed,"CatmullRomClosed");CatmullRomClosed.prototype={areaStart:noop$1,areaEnd:noop$1,lineStart:__name(function(){this._x0=this._x1=this._x2=this._x3=this._x4=this._x5=this._y0=this._y1=this._y2=this._y3=this._y4=this._y5=NaN,this._l01_a=this._l12_a=this._l23_a=this._l01_2a=this._l12_2a=this._l23_2a=this._point=0},"lineStart"),lineEnd:__name(function(){switch(this._point){case 1:{this._context.moveTo(this._x3,this._y3),this._context.closePath();break}case 2:{this._context.lineTo(this._x3,this._y3),this._context.closePath();break}case 3:{this.point(this._x3,this._y3),this.point(this._x4,this._y4),this.point(this._x5,this._y5);break}}},"lineEnd"),point:__name(function(x2,y2){if(x2=+x2,y2=+y2,this._point){var x23=this._x2-x2,y23=this._y2-y2;this._l23_a=Math.sqrt(this._l23_2a=Math.pow(x23*x23+y23*y23,this._alpha))}switch(this._point){case 0:this._point=1,this._x3=x2,this._y3=y2;break;case 1:this._point=2,this._context.moveTo(this._x4=x2,this._y4=y2);break;case 2:this._point=3,this._x5=x2,this._y5=y2;break;default:point$6(this,x2,y2);break}this._l01_a=this._l12_a,this._l12_a=this._l23_a,this._l01_2a=this._l12_2a,this._l12_2a=this._l23_2a,this._x0=this._x1,this._x1=this._x2,this._x2=x2,this._y0=this._y1,this._y1=this._y2,this._y2=y2},"point")};const ar=__name((function custom6(alpha3){function catmullRom(context){return alpha3?new CatmullRomClosed(context,alpha3):new CardinalClosed(context,0)}return __name(catmullRom,"catmullRom"),catmullRom.alpha=function(alpha4){return custom6(+alpha4)},catmullRom}),"custom")(.5);function CatmullRomOpen(context,alpha3){this._context=context,this._alpha=alpha3}__name(CatmullRomOpen,"CatmullRomOpen");CatmullRomOpen.prototype={areaStart:__name(function(){this._line=0},"areaStart"),areaEnd:__name(function(){this._line=NaN},"areaEnd"),lineStart:__name(function(){this._x0=this._x1=this._x2=this._y0=this._y1=this._y2=NaN,this._l01_a=this._l12_a=this._l23_a=this._l01_2a=this._l12_2a=this._l23_2a=this._point=0},"lineStart"),lineEnd:__name(function(){(this._line||this._line!==0&&this._point===3)&&this._context.closePath(),this._line=1-this._line},"lineEnd"),point:__name(function(x2,y2){if(x2=+x2,y2=+y2,this._point){var x23=this._x2-x2,y23=this._y2-y2;this._l23_a=Math.sqrt(this._l23_2a=Math.pow(x23*x23+y23*y23,this._alpha))}switch(this._point){case 0:this._point=1;break;case 1:this._point=2;break;case 2:this._point=3,this._line?this._context.lineTo(this._x2,this._y2):this._context.moveTo(this._x2,this._y2);break;case 3:this._point=4;default:point$6(this,x2,y2);break}this._l01_a=this._l12_a,this._l12_a=this._l23_a,this._l01_2a=this._l12_2a,this._l12_2a=this._l23_2a,this._x0=this._x1,this._x1=this._x2,this._x2=x2,this._y0=this._y1,this._y1=this._y2,this._y2=y2},"point")};const dr=__name((function custom7(alpha3){function catmullRom(context){return alpha3?new CatmullRomOpen(context,alpha3):new CardinalOpen(context,0)}return __name(catmullRom,"catmullRom"),catmullRom.alpha=function(alpha4){return custom7(+alpha4)},catmullRom}),"custom")(.5);function LinearClosed(context){this._context=context}__name(LinearClosed,"LinearClosed");LinearClosed.prototype={areaStart:noop$1,areaEnd:noop$1,lineStart:__name(function(){this._point=0},"lineStart"),lineEnd:__name(function(){this._point&&this._context.closePath()},"lineEnd"),point:__name(function(x2,y2){x2=+x2,y2=+y2,this._point?this._context.lineTo(x2,y2):(this._point=1,this._context.moveTo(x2,y2))},"point")};function ur(context){return new LinearClosed(context)}__name(ur,"ur");function sign(x2){return x2<0?-1:1}__name(sign,"sign");function slope3(that,x2,y2){var h0=that._x1-that._x0,h1=x2-that._x1,s0=(that._y1-that._y0)/(h0||h1<0&&-0),s1=(y2-that._y1)/(h1||h0<0&&-0),p2=(s0*h1+s1*h0)/(h0+h1);return(sign(s0)+sign(s1))*Math.min(Math.abs(s0),Math.abs(s1),.5*Math.abs(p2))||0}__name(slope3,"slope3");function slope2(that,t2){var h2=that._x1-that._x0;return h2?(3*(that._y1-that._y0)/h2-t2)/2:t2}__name(slope2,"slope2");function point$5(that,t02,t12){var x0=that._x0,y0=that._y0,x1=that._x1,y1=that._y1,dx=(x1-x0)/3;that._context.bezierCurveTo(x0+dx,y0+dx*t02,x1-dx,y1-dx*t12,x1,y1)}__name(point$5,"point$5");function MonotoneX(context){this._context=context}__name(MonotoneX,"MonotoneX");MonotoneX.prototype={areaStart:__name(function(){this._line=0},"areaStart"),areaEnd:__name(function(){this._line=NaN},"areaEnd"),lineStart:__name(function(){this._x0=this._x1=this._y0=this._y1=this._t0=NaN,this._point=0},"lineStart"),lineEnd:__name(function(){switch(this._point){case 2:this._context.lineTo(this._x1,this._y1);break;case 3:point$5(this,this._t0,slope2(this,this._t0));break}(this._line||this._line!==0&&this._point===1)&&this._context.closePath(),this._line=1-this._line},"lineEnd"),point:__name(function(x2,y2){var t12=NaN;if(x2=+x2,y2=+y2,!(x2===this._x1&&y2===this._y1)){switch(this._point){case 0:this._point=1,this._line?this._context.lineTo(x2,y2):this._context.moveTo(x2,y2);break;case 1:this._point=2;break;case 2:this._point=3,point$5(this,slope2(this,t12=slope3(this,x2,y2)),t12);break;default:point$5(this,this._t0,t12=slope3(this,x2,y2));break}this._x0=this._x1,this._x1=x2,this._y0=this._y1,this._y1=y2,this._t0=t12}},"point")};function MonotoneY(context){this._context=new ReflectContext(context)}__name(MonotoneY,"MonotoneY");(MonotoneY.prototype=Object.create(MonotoneX.prototype)).point=function(x2,y2){MonotoneX.prototype.point.call(this,y2,x2)};function ReflectContext(context){this._context=context}__name(ReflectContext,"ReflectContext");ReflectContext.prototype={moveTo:__name(function(x2,y2){this._context.moveTo(y2,x2)},"moveTo"),closePath:__name(function(){this._context.closePath()},"closePath"),lineTo:__name(function(x2,y2){this._context.lineTo(y2,x2)},"lineTo"),bezierCurveTo:__name(function(x1,y1,x2,y2,x3,y3){this._context.bezierCurveTo(y1,x1,y2,x2,y3,x3)},"bezierCurveTo")};function monotoneX(context){return new MonotoneX(context)}__name(monotoneX,"monotoneX");function monotoneY(context){return new MonotoneY(context)}__name(monotoneY,"monotoneY");function Natural(context){this._context=context}__name(Natural,"Natural");Natural.prototype={areaStart:__name(function(){this._line=0},"areaStart"),areaEnd:__name(function(){this._line=NaN},"areaEnd"),lineStart:__name(function(){this._x=[],this._y=[]},"lineStart"),lineEnd:__name(function(){var x2=this._x,y2=this._y,n2=x2.length;if(n2)if(this._line?this._context.lineTo(x2[0],y2[0]):this._context.moveTo(x2[0],y2[0]),n2===2)this._context.lineTo(x2[1],y2[1]);else for(var px=controlPoints(x2),py=controlPoints(y2),i0=0,i1=1;i1=0;--i2)a2[i2]=(r2[i2]-a2[i2+1])/b2[i2];for(b2[n2-1]=(x2[n2]+a2[n2-1])/2,i2=0;i2=0&&(this._t=1-this._t,this._line=1-this._line)},"lineEnd"),point:__name(function(x2,y2){switch(x2=+x2,y2=+y2,this._point){case 0:this._point=1,this._line?this._context.lineTo(x2,y2):this._context.moveTo(x2,y2);break;case 1:this._point=2;default:{if(this._t<=0)this._context.lineTo(this._x,y2),this._context.lineTo(x2,y2);else{var x1=this._x*(1-this._t)+x2*this._t;this._context.lineTo(x1,this._y),this._context.lineTo(x1,y2)}break}}this._x=x2,this._y=y2},"point")};function hr(context){return new Step(context,.5)}__name(hr,"hr");function stepBefore(context){return new Step(context,0)}__name(stepBefore,"stepBefore");function stepAfter(context){return new Step(context,1)}__name(stepAfter,"stepAfter");function xr(series,order2){if((n2=series.length)>1)for(var i2=1,j2,s0,s1=series[order2[0]],n2,m2=s1.length;i2=0;)o2[n2]=n2;return o2}__name(_r,"_r");function stackValue(d,key){return d[key]}__name(stackValue,"stackValue");function stackSeries(key){const series=[];return series.key=key,series}__name(stackSeries,"stackSeries");function shapeStack(){var keys2=constant$2([]),order2=_r,offset2=xr,value2=stackValue;function stack(data){var sz=Array.from(keys2.apply(this,arguments),stackSeries),i2,n2=sz.length,j2=-1,oz;for(const d of data)for(i2=0,++j2;i20){for(var i2,n2,j2=0,m2=series[0].length,y2;j20){for(var j2=0,s0=series[order2[0]],n2,m2=s0.length;j20)||!((m2=(s0=series[order2[0]]).length)>0))){for(var y2=0,j2=1,s0,m2,n2;j2=0)&&Object.prototype.propertyIsEnumerable.call(source,key)&&(target[key]=source[key])}return target}__name(_objectWithoutProperties$f,"_objectWithoutProperties$f");function _objectWithoutPropertiesLoose$f(source,excluded){if(source==null)return{};var target={};for(var key in source)if(Object.prototype.hasOwnProperty.call(source,key)){if(excluded.indexOf(key)>=0)continue;target[key]=source[key]}return target}__name(_objectWithoutPropertiesLoose$f,"_objectWithoutPropertiesLoose$f");var symbolFactories={symbolCircle,symbolCross,symbolDiamond,symbolSquare,symbolStar,symbolTriangle,symbolWye},RADIAN$2=Math.PI/180,getSymbolFactory=__name(function(type){var name2="symbol".concat(upperFirst(type));return symbolFactories[name2]||symbolCircle},"getSymbolFactory"),calculateAreaSize=__name(function(size2,sizeType,type){if(sizeType==="area")return size2;switch(type){case"cross":return 5*size2*size2/9;case"diamond":return .5*size2*size2/Math.sqrt(3);case"square":return size2*size2;case"star":{var angle=18*RADIAN$2;return 1.25*size2*size2*(Math.tan(angle)-Math.tan(angle*2)*Math.pow(Math.tan(angle),2))}case"triangle":return Math.sqrt(3)*size2*size2/4;case"wye":return(21-10*Math.sqrt(3))*size2*size2/8;default:return Math.PI*size2*size2/4}},"calculateAreaSize"),registerSymbol=__name(function(key,factory){symbolFactories["symbol".concat(upperFirst(key))]=factory},"registerSymbol"),Symbols=__name(function(_ref){var _ref$type=_ref.type,type=_ref$type===void 0?"circle":_ref$type,_ref$size=_ref.size,size2=_ref$size===void 0?64:_ref$size,_ref$sizeType=_ref.sizeType,sizeType=_ref$sizeType===void 0?"area":_ref$sizeType,rest=_objectWithoutProperties$f(_ref,_excluded$f),props=_objectSpread$C(_objectSpread$C({},rest),{},{type,size:size2,sizeType}),getPath4=__name(function(){var symbolFactory=getSymbolFactory(type),symbol=Symbol$1().type(symbolFactory).size(calculateAreaSize(size2,sizeType,type));return symbol()},"getPath"),className=props.className,cx2=props.cx,cy=props.cy,filteredProps=filterProps(props,!0);return cx2===+cx2&&cy===+cy&&size2===+size2?React.createElement("path",_extends$s({},filteredProps,{className:clsx("recharts-symbols",className),transform:"translate(".concat(cx2,", ").concat(cy,")"),d:getPath4()})):null},"Symbols");Symbols.registerSymbol=registerSymbol;function _typeof$I(o2){"@babel/helpers - typeof";return _typeof$I=typeof Symbol=="function"&&typeof Symbol.iterator=="symbol"?function(o3){return typeof o3}:function(o3){return o3&&typeof Symbol=="function"&&o3.constructor===Symbol&&o3!==Symbol.prototype?"symbol":typeof o3},_typeof$I(o2)}__name(_typeof$I,"_typeof$I");function _extends$r(){return _extends$r=Object.assign?Object.assign.bind():function(target){for(var i2=1;i2`);var color=entry.inactive?inactiveColor:entry.color;return React.createElement("li",_extends$r({className,style:itemStyle,key:"legend-item-".concat(i2)},adaptEventsOfChild(_this.props,entry,i2)),React.createElement(Surface,{width:iconSize,height:iconSize,viewBox,style:svgStyle},_this.renderIcon(entry)),React.createElement("span",{className:"recharts-legend-item-text",style:{color}},finalFormatter?finalFormatter(entryValue,entry,i2):entryValue))})},"renderItems")},{key:"render",value:__name(function(){var _this$props2=this.props,payload=_this$props2.payload,layout=_this$props2.layout,align=_this$props2.align;if(!payload||!payload.length)return null;var finalStyle={padding:0,margin:0,textAlign:layout==="horizontal"?align:"left"};return React.createElement("ul",{className:"recharts-default-legend",style:finalStyle},this.renderItems())},"render")}])})(reactExports.PureComponent);_defineProperty$H(DefaultLegendContent,"displayName","Legend");_defineProperty$H(DefaultLegendContent,"defaultProps",{iconSize:14,layout:"horizontal",align:"center",verticalAlign:"middle",inactiveColor:"#ccc"});var _stackClear,hasRequired_stackClear;function require_stackClear(){if(hasRequired_stackClear)return _stackClear;hasRequired_stackClear=1;var ListCache=require_ListCache();function stackClear(){this.__data__=new ListCache,this.size=0}return __name(stackClear,"stackClear"),_stackClear=stackClear,_stackClear}__name(require_stackClear,"require_stackClear");var _stackDelete,hasRequired_stackDelete;function require_stackDelete(){if(hasRequired_stackDelete)return _stackDelete;hasRequired_stackDelete=1;function stackDelete(key){var data=this.__data__,result=data.delete(key);return this.size=data.size,result}return __name(stackDelete,"stackDelete"),_stackDelete=stackDelete,_stackDelete}__name(require_stackDelete,"require_stackDelete");var _stackGet,hasRequired_stackGet;function require_stackGet(){if(hasRequired_stackGet)return _stackGet;hasRequired_stackGet=1;function stackGet(key){return this.__data__.get(key)}return __name(stackGet,"stackGet"),_stackGet=stackGet,_stackGet}__name(require_stackGet,"require_stackGet");var _stackHas,hasRequired_stackHas;function require_stackHas(){if(hasRequired_stackHas)return _stackHas;hasRequired_stackHas=1;function stackHas(key){return this.__data__.has(key)}return __name(stackHas,"stackHas"),_stackHas=stackHas,_stackHas}__name(require_stackHas,"require_stackHas");var _stackSet,hasRequired_stackSet;function require_stackSet(){if(hasRequired_stackSet)return _stackSet;hasRequired_stackSet=1;var ListCache=require_ListCache(),Map2=require_Map(),MapCache=require_MapCache(),LARGE_ARRAY_SIZE=200;function stackSet(key,value2){var data=this.__data__;if(data instanceof ListCache){var pairs=data.__data__;if(!Map2||pairs.lengtharrLength))return!1;var arrStacked=stack.get(array2),othStacked=stack.get(other);if(arrStacked&&othStacked)return arrStacked==other&&othStacked==array2;var index2=-1,result=!0,seen=bitmask&COMPARE_UNORDERED_FLAG?new SetCache:void 0;for(stack.set(array2,other),stack.set(other,array2);++index2-1&&value2%1==0&&value2-1&&value2%1==0&&value2<=MAX_SAFE_INTEGER2}return __name(isLength2,"isLength"),isLength_1=isLength2,isLength_1}__name(requireIsLength,"requireIsLength");var _baseIsTypedArray,hasRequired_baseIsTypedArray;function require_baseIsTypedArray(){if(hasRequired_baseIsTypedArray)return _baseIsTypedArray;hasRequired_baseIsTypedArray=1;var baseGetTag=require_baseGetTag(),isLength2=requireIsLength(),isObjectLike=requireIsObjectLike(),argsTag="[object Arguments]",arrayTag="[object Array]",boolTag="[object Boolean]",dateTag="[object Date]",errorTag="[object Error]",funcTag="[object Function]",mapTag="[object Map]",numberTag="[object Number]",objectTag="[object Object]",regexpTag="[object RegExp]",setTag="[object Set]",stringTag="[object String]",weakMapTag="[object WeakMap]",arrayBufferTag="[object ArrayBuffer]",dataViewTag="[object DataView]",float32Tag="[object Float32Array]",float64Tag="[object Float64Array]",int8Tag="[object Int8Array]",int16Tag="[object Int16Array]",int32Tag="[object Int32Array]",uint8Tag="[object Uint8Array]",uint8ClampedTag="[object Uint8ClampedArray]",uint16Tag="[object Uint16Array]",uint32Tag="[object Uint32Array]",typedArrayTags={};typedArrayTags[float32Tag]=typedArrayTags[float64Tag]=typedArrayTags[int8Tag]=typedArrayTags[int16Tag]=typedArrayTags[int32Tag]=typedArrayTags[uint8Tag]=typedArrayTags[uint8ClampedTag]=typedArrayTags[uint16Tag]=typedArrayTags[uint32Tag]=!0,typedArrayTags[argsTag]=typedArrayTags[arrayTag]=typedArrayTags[arrayBufferTag]=typedArrayTags[boolTag]=typedArrayTags[dataViewTag]=typedArrayTags[dateTag]=typedArrayTags[errorTag]=typedArrayTags[funcTag]=typedArrayTags[mapTag]=typedArrayTags[numberTag]=typedArrayTags[objectTag]=typedArrayTags[regexpTag]=typedArrayTags[setTag]=typedArrayTags[stringTag]=typedArrayTags[weakMapTag]=!1;function baseIsTypedArray(value2){return isObjectLike(value2)&&isLength2(value2.length)&&!!typedArrayTags[baseGetTag(value2)]}return __name(baseIsTypedArray,"baseIsTypedArray"),_baseIsTypedArray=baseIsTypedArray,_baseIsTypedArray}__name(require_baseIsTypedArray,"require_baseIsTypedArray");var _baseUnary,hasRequired_baseUnary;function require_baseUnary(){if(hasRequired_baseUnary)return _baseUnary;hasRequired_baseUnary=1;function baseUnary(func){return function(value2){return func(value2)}}return __name(baseUnary,"baseUnary"),_baseUnary=baseUnary,_baseUnary}__name(require_baseUnary,"require_baseUnary");var _nodeUtil={exports:{}};_nodeUtil.exports;var hasRequired_nodeUtil;function require_nodeUtil(){return hasRequired_nodeUtil||(hasRequired_nodeUtil=1,(function(module,exports$1){var freeGlobal=require_freeGlobal(),freeExports=exports$1&&!exports$1.nodeType&&exports$1,freeModule=freeExports&&!0&&module&&!module.nodeType&&module,moduleExports=freeModule&&freeModule.exports===freeExports,freeProcess=moduleExports&&freeGlobal.process,nodeUtil=(function(){try{var types2=freeModule&&freeModule.require&&freeModule.require("util").types;return types2||freeProcess&&freeProcess.binding&&freeProcess.binding("util")}catch{}})();module.exports=nodeUtil})(_nodeUtil,_nodeUtil.exports)),_nodeUtil.exports}__name(require_nodeUtil,"require_nodeUtil");var isTypedArray_1,hasRequiredIsTypedArray;function requireIsTypedArray(){if(hasRequiredIsTypedArray)return isTypedArray_1;hasRequiredIsTypedArray=1;var baseIsTypedArray=require_baseIsTypedArray(),baseUnary=require_baseUnary(),nodeUtil=require_nodeUtil(),nodeIsTypedArray=nodeUtil&&nodeUtil.isTypedArray,isTypedArray2=nodeIsTypedArray?baseUnary(nodeIsTypedArray):baseIsTypedArray;return isTypedArray_1=isTypedArray2,isTypedArray_1}__name(requireIsTypedArray,"requireIsTypedArray");var _arrayLikeKeys,hasRequired_arrayLikeKeys;function require_arrayLikeKeys(){if(hasRequired_arrayLikeKeys)return _arrayLikeKeys;hasRequired_arrayLikeKeys=1;var baseTimes=require_baseTimes(),isArguments=requireIsArguments(),isArray2=requireIsArray(),isBuffer2=requireIsBuffer(),isIndex=require_isIndex(),isTypedArray2=requireIsTypedArray(),objectProto=Object.prototype,hasOwnProperty2=objectProto.hasOwnProperty;function arrayLikeKeys(value2,inherited){var isArr=isArray2(value2),isArg=!isArr&&isArguments(value2),isBuff=!isArr&&!isArg&&isBuffer2(value2),isType=!isArr&&!isArg&&!isBuff&&isTypedArray2(value2),skipIndexes=isArr||isArg||isBuff||isType,result=skipIndexes?baseTimes(value2.length,String):[],length=result.length;for(var key in value2)(inherited||hasOwnProperty2.call(value2,key))&&!(skipIndexes&&(key=="length"||isBuff&&(key=="offset"||key=="parent")||isType&&(key=="buffer"||key=="byteLength"||key=="byteOffset")||isIndex(key,length)))&&result.push(key);return result}return __name(arrayLikeKeys,"arrayLikeKeys"),_arrayLikeKeys=arrayLikeKeys,_arrayLikeKeys}__name(require_arrayLikeKeys,"require_arrayLikeKeys");var _isPrototype,hasRequired_isPrototype;function require_isPrototype(){if(hasRequired_isPrototype)return _isPrototype;hasRequired_isPrototype=1;var objectProto=Object.prototype;function isPrototype(value2){var Ctor=value2&&value2.constructor,proto2=typeof Ctor=="function"&&Ctor.prototype||objectProto;return value2===proto2}return __name(isPrototype,"isPrototype"),_isPrototype=isPrototype,_isPrototype}__name(require_isPrototype,"require_isPrototype");var _overArg,hasRequired_overArg;function require_overArg(){if(hasRequired_overArg)return _overArg;hasRequired_overArg=1;function overArg(func,transform2){return function(arg){return func(transform2(arg))}}return __name(overArg,"overArg"),_overArg=overArg,_overArg}__name(require_overArg,"require_overArg");var _nativeKeys,hasRequired_nativeKeys;function require_nativeKeys(){if(hasRequired_nativeKeys)return _nativeKeys;hasRequired_nativeKeys=1;var overArg=require_overArg(),nativeKeys=overArg(Object.keys,Object);return _nativeKeys=nativeKeys,_nativeKeys}__name(require_nativeKeys,"require_nativeKeys");var _baseKeys,hasRequired_baseKeys;function require_baseKeys(){if(hasRequired_baseKeys)return _baseKeys;hasRequired_baseKeys=1;var isPrototype=require_isPrototype(),nativeKeys=require_nativeKeys(),objectProto=Object.prototype,hasOwnProperty2=objectProto.hasOwnProperty;function baseKeys(object2){if(!isPrototype(object2))return nativeKeys(object2);var result=[];for(var key in Object(object2))hasOwnProperty2.call(object2,key)&&key!="constructor"&&result.push(key);return result}return __name(baseKeys,"baseKeys"),_baseKeys=baseKeys,_baseKeys}__name(require_baseKeys,"require_baseKeys");var isArrayLike_1,hasRequiredIsArrayLike;function requireIsArrayLike(){if(hasRequiredIsArrayLike)return isArrayLike_1;hasRequiredIsArrayLike=1;var isFunction2=requireIsFunction(),isLength2=requireIsLength();function isArrayLike(value2){return value2!=null&&isLength2(value2.length)&&!isFunction2(value2)}return __name(isArrayLike,"isArrayLike"),isArrayLike_1=isArrayLike,isArrayLike_1}__name(requireIsArrayLike,"requireIsArrayLike");var keys_1,hasRequiredKeys;function requireKeys(){if(hasRequiredKeys)return keys_1;hasRequiredKeys=1;var arrayLikeKeys=require_arrayLikeKeys(),baseKeys=require_baseKeys(),isArrayLike=requireIsArrayLike();function keys2(object2){return isArrayLike(object2)?arrayLikeKeys(object2):baseKeys(object2)}return __name(keys2,"keys"),keys_1=keys2,keys_1}__name(requireKeys,"requireKeys");var _getAllKeys,hasRequired_getAllKeys;function require_getAllKeys(){if(hasRequired_getAllKeys)return _getAllKeys;hasRequired_getAllKeys=1;var baseGetAllKeys=require_baseGetAllKeys(),getSymbols=require_getSymbols(),keys2=requireKeys();function getAllKeys(object2){return baseGetAllKeys(object2,keys2,getSymbols)}return __name(getAllKeys,"getAllKeys"),_getAllKeys=getAllKeys,_getAllKeys}__name(require_getAllKeys,"require_getAllKeys");var _equalObjects,hasRequired_equalObjects;function require_equalObjects(){if(hasRequired_equalObjects)return _equalObjects;hasRequired_equalObjects=1;var getAllKeys=require_getAllKeys(),COMPARE_PARTIAL_FLAG=1,objectProto=Object.prototype,hasOwnProperty2=objectProto.hasOwnProperty;function equalObjects(object2,other,bitmask,customizer,equalFunc,stack){var isPartial=bitmask&COMPARE_PARTIAL_FLAG,objProps=getAllKeys(object2),objLength=objProps.length,othProps=getAllKeys(other),othLength=othProps.length;if(objLength!=othLength&&!isPartial)return!1;for(var index2=objLength;index2--;){var key=objProps[index2];if(!(isPartial?key in other:hasOwnProperty2.call(other,key)))return!1}var objStacked=stack.get(object2),othStacked=stack.get(other);if(objStacked&&othStacked)return objStacked==other&&othStacked==object2;var result=!0;stack.set(object2,other),stack.set(other,object2);for(var skipCtor=isPartial;++index2-1}return __name(arrayIncludes,"arrayIncludes"),_arrayIncludes=arrayIncludes,_arrayIncludes}__name(require_arrayIncludes,"require_arrayIncludes");var _arrayIncludesWith,hasRequired_arrayIncludesWith;function require_arrayIncludesWith(){if(hasRequired_arrayIncludesWith)return _arrayIncludesWith;hasRequired_arrayIncludesWith=1;function arrayIncludesWith(array2,value2,comparator){for(var index2=-1,length=array2==null?0:array2.length;++index2=LARGE_ARRAY_SIZE){var set=iteratee?null:createSet(array2);if(set)return setToArray(set);isCommon=!1,includes=cacheHas,seen=new SetCache}else seen=iteratee?[]:result;outer:for(;++index2=0)&&Object.prototype.propertyIsEnumerable.call(source,key)&&(target[key]=source[key])}return target}__name(_objectWithoutProperties$e,"_objectWithoutProperties$e");function _objectWithoutPropertiesLoose$e(source,excluded){if(source==null)return{};var target={};for(var key in source)if(Object.prototype.hasOwnProperty.call(source,key)){if(excluded.indexOf(key)>=0)continue;target[key]=source[key]}return target}__name(_objectWithoutPropertiesLoose$e,"_objectWithoutPropertiesLoose$e");function defaultUniqBy$1(entry){return entry.value}__name(defaultUniqBy$1,"defaultUniqBy$1");function renderContent$1(content2,props){if(React.isValidElement(content2))return React.cloneElement(content2,props);if(typeof content2=="function")return React.createElement(content2,props);props.ref;var otherProps=_objectWithoutProperties$e(props,_excluded$e);return React.createElement(DefaultLegendContent,otherProps)}__name(renderContent$1,"renderContent$1");var EPS$1=1,Legend=(function(_PureComponent){function Legend2(){var _this;_classCallCheck$k(this,Legend2);for(var _len=arguments.length,args=new Array(_len),_key=0;_key<_len;_key++)args[_key]=arguments[_key];return _this=_callSuper$g(this,Legend2,[].concat(args)),_defineProperty$G(_this,"lastBoundingBox",{width:-1,height:-1}),_this}return __name(Legend2,"Legend"),_inherits$h(Legend2,_PureComponent),_createClass$k(Legend2,[{key:"componentDidMount",value:__name(function(){this.updateBBox()},"componentDidMount")},{key:"componentDidUpdate",value:__name(function(){this.updateBBox()},"componentDidUpdate")},{key:"getBBox",value:__name(function(){if(this.wrapperNode&&this.wrapperNode.getBoundingClientRect){var box=this.wrapperNode.getBoundingClientRect();return box.height=this.wrapperNode.offsetHeight,box.width=this.wrapperNode.offsetWidth,box}return null},"getBBox")},{key:"updateBBox",value:__name(function(){var onBBoxUpdate=this.props.onBBoxUpdate,box=this.getBBox();box?(Math.abs(box.width-this.lastBoundingBox.width)>EPS$1||Math.abs(box.height-this.lastBoundingBox.height)>EPS$1)&&(this.lastBoundingBox.width=box.width,this.lastBoundingBox.height=box.height,onBBoxUpdate&&onBBoxUpdate(box)):(this.lastBoundingBox.width!==-1||this.lastBoundingBox.height!==-1)&&(this.lastBoundingBox.width=-1,this.lastBoundingBox.height=-1,onBBoxUpdate&&onBBoxUpdate(null))},"updateBBox")},{key:"getBBoxSnapshot",value:__name(function(){return this.lastBoundingBox.width>=0&&this.lastBoundingBox.height>=0?_objectSpread$A({},this.lastBoundingBox):{width:0,height:0}},"getBBoxSnapshot")},{key:"getDefaultPosition",value:__name(function(style2){var _this$props=this.props,layout=_this$props.layout,align=_this$props.align,verticalAlign=_this$props.verticalAlign,margin=_this$props.margin,chartWidth=_this$props.chartWidth,chartHeight=_this$props.chartHeight,hPos,vPos;if(!style2||(style2.left===void 0||style2.left===null)&&(style2.right===void 0||style2.right===null))if(align==="center"&&layout==="vertical"){var box=this.getBBoxSnapshot();hPos={left:((chartWidth||0)-box.width)/2}}else hPos=align==="right"?{right:margin&&margin.right||0}:{left:margin&&margin.left||0};if(!style2||(style2.top===void 0||style2.top===null)&&(style2.bottom===void 0||style2.bottom===null))if(verticalAlign==="middle"){var _box=this.getBBoxSnapshot();vPos={top:((chartHeight||0)-_box.height)/2}}else vPos=verticalAlign==="bottom"?{bottom:margin&&margin.bottom||0}:{top:margin&&margin.top||0};return _objectSpread$A(_objectSpread$A({},hPos),vPos)},"getDefaultPosition")},{key:"render",value:__name(function(){var _this2=this,_this$props2=this.props,content2=_this$props2.content,width=_this$props2.width,height=_this$props2.height,wrapperStyle=_this$props2.wrapperStyle,payloadUniqBy=_this$props2.payloadUniqBy,payload=_this$props2.payload,outerStyle=_objectSpread$A(_objectSpread$A({position:"absolute",width:width||"auto",height:height||"auto"},this.getDefaultPosition(wrapperStyle)),wrapperStyle);return React.createElement("div",{className:"recharts-legend-wrapper",style:outerStyle,ref:__name(function(node2){_this2.wrapperNode=node2},"ref")},renderContent$1(content2,_objectSpread$A(_objectSpread$A({},this.props),{},{payload:getUniqPayload(payload,payloadUniqBy,defaultUniqBy$1)})))},"render")}],[{key:"getWithHeight",value:__name(function(item,chartWidth){var _this$defaultProps$it=_objectSpread$A(_objectSpread$A({},this.defaultProps),item.props),layout=_this$defaultProps$it.layout;return layout==="vertical"&&isNumber$1(item.props.height)?{height:item.props.height}:layout==="horizontal"?{width:item.props.width||chartWidth}:null},"getWithHeight")}])})(reactExports.PureComponent);_defineProperty$G(Legend,"displayName","Legend");_defineProperty$G(Legend,"defaultProps",{iconSize:14,layout:"horizontal",align:"center",verticalAlign:"bottom"});var _isFlattenable,hasRequired_isFlattenable;function require_isFlattenable(){if(hasRequired_isFlattenable)return _isFlattenable;hasRequired_isFlattenable=1;var Symbol2=require_Symbol(),isArguments=requireIsArguments(),isArray2=requireIsArray(),spreadableSymbol=Symbol2?Symbol2.isConcatSpreadable:void 0;function isFlattenable(value2){return isArray2(value2)||isArguments(value2)||!!(spreadableSymbol&&value2&&value2[spreadableSymbol])}return __name(isFlattenable,"isFlattenable"),_isFlattenable=isFlattenable,_isFlattenable}__name(require_isFlattenable,"require_isFlattenable");var _baseFlatten,hasRequired_baseFlatten;function require_baseFlatten(){if(hasRequired_baseFlatten)return _baseFlatten;hasRequired_baseFlatten=1;var arrayPush=require_arrayPush(),isFlattenable=require_isFlattenable();function baseFlatten(array2,depth,predicate,isStrict,result){var index2=-1,length=array2.length;for(predicate||(predicate=isFlattenable),result||(result=[]);++index20&&predicate(value2)?depth>1?baseFlatten(value2,depth-1,predicate,isStrict,result):arrayPush(result,value2):isStrict||(result[result.length]=value2)}return result}return __name(baseFlatten,"baseFlatten"),_baseFlatten=baseFlatten,_baseFlatten}__name(require_baseFlatten,"require_baseFlatten");var _createBaseFor,hasRequired_createBaseFor;function require_createBaseFor(){if(hasRequired_createBaseFor)return _createBaseFor;hasRequired_createBaseFor=1;function createBaseFor(fromRight){return function(object2,iteratee,keysFunc){for(var index2=-1,iterable=Object(object2),props=keysFunc(object2),length=props.length;length--;){var key=props[fromRight?length:++index2];if(iteratee(iterable[key],key,iterable)===!1)break}return object2}}return __name(createBaseFor,"createBaseFor"),_createBaseFor=createBaseFor,_createBaseFor}__name(require_createBaseFor,"require_createBaseFor");var _baseFor,hasRequired_baseFor;function require_baseFor(){if(hasRequired_baseFor)return _baseFor;hasRequired_baseFor=1;var createBaseFor=require_createBaseFor(),baseFor=createBaseFor();return _baseFor=baseFor,_baseFor}__name(require_baseFor,"require_baseFor");var _baseForOwn,hasRequired_baseForOwn;function require_baseForOwn(){if(hasRequired_baseForOwn)return _baseForOwn;hasRequired_baseForOwn=1;var baseFor=require_baseFor(),keys2=requireKeys();function baseForOwn(object2,iteratee){return object2&&baseFor(object2,iteratee,keys2)}return __name(baseForOwn,"baseForOwn"),_baseForOwn=baseForOwn,_baseForOwn}__name(require_baseForOwn,"require_baseForOwn");var _createBaseEach,hasRequired_createBaseEach;function require_createBaseEach(){if(hasRequired_createBaseEach)return _createBaseEach;hasRequired_createBaseEach=1;var isArrayLike=requireIsArrayLike();function createBaseEach(eachFunc,fromRight){return function(collection,iteratee){if(collection==null)return collection;if(!isArrayLike(collection))return eachFunc(collection,iteratee);for(var length=collection.length,index2=fromRight?length:-1,iterable=Object(collection);(fromRight?index2--:++index2other||valIsSymbol&&othIsDefined&&othIsReflexive&&!othIsNull&&!othIsSymbol||valIsNull&&othIsDefined&&othIsReflexive||!valIsDefined&&othIsReflexive||!valIsReflexive)return 1;if(!valIsNull&&!valIsSymbol&&!othIsSymbol&&value2=ordersLength)return result;var order2=orders[index2];return result*(order2=="desc"?-1:1)}}return object2.index-other.index}return __name(compareMultiple,"compareMultiple"),_compareMultiple=compareMultiple,_compareMultiple}__name(require_compareMultiple,"require_compareMultiple");var _baseOrderBy,hasRequired_baseOrderBy;function require_baseOrderBy(){if(hasRequired_baseOrderBy)return _baseOrderBy;hasRequired_baseOrderBy=1;var arrayMap=require_arrayMap(),baseGet=require_baseGet(),baseIteratee=require_baseIteratee(),baseMap=require_baseMap(),baseSortBy=require_baseSortBy(),baseUnary=require_baseUnary(),compareMultiple=require_compareMultiple(),identity3=requireIdentity(),isArray2=requireIsArray();function baseOrderBy(collection,iteratees,orders){iteratees.length?iteratees=arrayMap(iteratees,function(iteratee){return isArray2(iteratee)?function(value2){return baseGet(value2,iteratee.length===1?iteratee[0]:iteratee)}:iteratee}):iteratees=[identity3];var index2=-1;iteratees=arrayMap(iteratees,baseUnary(baseIteratee));var result=baseMap(collection,function(value2,key,collection2){var criteria=arrayMap(iteratees,function(iteratee){return iteratee(value2)});return{criteria,index:++index2,value:value2}});return baseSortBy(result,function(object2,other){return compareMultiple(object2,other,orders)})}return __name(baseOrderBy,"baseOrderBy"),_baseOrderBy=baseOrderBy,_baseOrderBy}__name(require_baseOrderBy,"require_baseOrderBy");var _apply,hasRequired_apply;function require_apply(){if(hasRequired_apply)return _apply;hasRequired_apply=1;function apply(func,thisArg,args){switch(args.length){case 0:return func.call(thisArg);case 1:return func.call(thisArg,args[0]);case 2:return func.call(thisArg,args[0],args[1]);case 3:return func.call(thisArg,args[0],args[1],args[2])}return func.apply(thisArg,args)}return __name(apply,"apply"),_apply=apply,_apply}__name(require_apply,"require_apply");var _overRest,hasRequired_overRest;function require_overRest(){if(hasRequired_overRest)return _overRest;hasRequired_overRest=1;var apply=require_apply(),nativeMax=Math.max;function overRest(func,start2,transform2){return start2=nativeMax(start2===void 0?func.length-1:start2,0),function(){for(var args=arguments,index2=-1,length=nativeMax(args.length-start2,0),array2=Array(length);++index20){if(++count2>=HOT_COUNT)return arguments[0]}else count2=0;return func.apply(void 0,arguments)}}return __name(shortOut,"shortOut"),_shortOut=shortOut,_shortOut}__name(require_shortOut,"require_shortOut");var _setToString,hasRequired_setToString;function require_setToString(){if(hasRequired_setToString)return _setToString;hasRequired_setToString=1;var baseSetToString=require_baseSetToString(),shortOut=require_shortOut(),setToString=shortOut(baseSetToString);return _setToString=setToString,_setToString}__name(require_setToString,"require_setToString");var _baseRest,hasRequired_baseRest;function require_baseRest(){if(hasRequired_baseRest)return _baseRest;hasRequired_baseRest=1;var identity3=requireIdentity(),overRest=require_overRest(),setToString=require_setToString();function baseRest(func,start2){return setToString(overRest(func,start2,identity3),func+"")}return __name(baseRest,"baseRest"),_baseRest=baseRest,_baseRest}__name(require_baseRest,"require_baseRest");var _isIterateeCall,hasRequired_isIterateeCall;function require_isIterateeCall(){if(hasRequired_isIterateeCall)return _isIterateeCall;hasRequired_isIterateeCall=1;var eq=requireEq(),isArrayLike=requireIsArrayLike(),isIndex=require_isIndex(),isObject2=requireIsObject();function isIterateeCall(value2,index2,object2){if(!isObject2(object2))return!1;var type=typeof index2;return(type=="number"?isArrayLike(object2)&&isIndex(index2,object2.length):type=="string"&&index2 in object2)?eq(object2[index2],value2):!1}return __name(isIterateeCall,"isIterateeCall"),_isIterateeCall=isIterateeCall,_isIterateeCall}__name(require_isIterateeCall,"require_isIterateeCall");var sortBy_1,hasRequiredSortBy;function requireSortBy(){if(hasRequiredSortBy)return sortBy_1;hasRequiredSortBy=1;var baseFlatten=require_baseFlatten(),baseOrderBy=require_baseOrderBy(),baseRest=require_baseRest(),isIterateeCall=require_isIterateeCall(),sortBy2=baseRest(function(collection,iteratees){if(collection==null)return[];var length=iteratees.length;return length>1&&isIterateeCall(collection,iteratees[0],iteratees[1])?iteratees=[]:length>2&&isIterateeCall(iteratees[0],iteratees[1],iteratees[2])&&(iteratees=[iteratees[0]]),baseOrderBy(collection,baseFlatten(iteratees,1),[])});return sortBy_1=sortBy2,sortBy_1}__name(requireSortBy,"requireSortBy");var sortByExports=requireSortBy();const sortBy=getDefaultExportFromCjs(sortByExports);function _typeof$G(o2){"@babel/helpers - typeof";return _typeof$G=typeof Symbol=="function"&&typeof Symbol.iterator=="symbol"?function(o3){return typeof o3}:function(o3){return o3&&typeof Symbol=="function"&&o3.constructor===Symbol&&o3!==Symbol.prototype?"symbol":typeof o3},_typeof$G(o2)}__name(_typeof$G,"_typeof$G");function _extends$q(){return _extends$q=Object.assign?Object.assign.bind():function(target){for(var i2=1;i2[id(d,i2,nodes2),d]));for(const[i2,link2]of links2.entries()){link2.index=i2;let{source,target}=link2;typeof source!="object"&&(source=link2.source=find$1(nodeById,source)),typeof target!="object"&&(target=link2.target=find$1(nodeById,target)),source.sourceLinks.push(link2),target.targetLinks.push(link2)}if(linkSort!=null)for(const{sourceLinks,targetLinks}of nodes2)sourceLinks.sort(linkSort),targetLinks.sort(linkSort)}__name(computeNodeLinks,"computeNodeLinks");function computeNodeValues({nodes:nodes2}){for(const node2 of nodes2)node2.value=node2.fixedValue===void 0?Math.max(sum$1(node2.sourceLinks,value),sum$1(node2.targetLinks,value)):node2.fixedValue}__name(computeNodeValues,"computeNodeValues");function computeNodeDepths({nodes:nodes2}){const n2=nodes2.length;let current=new Set(nodes2),next2=new Set,x2=0;for(;current.size;){for(const node2 of current){node2.depth=x2;for(const{target}of node2.sourceLinks)next2.add(target)}if(++x2>n2)throw new Error("circular link");current=next2,next2=new Set}}__name(computeNodeDepths,"computeNodeDepths");function computeNodeHeights({nodes:nodes2}){const n2=nodes2.length;let current=new Set(nodes2),next2=new Set,x2=0;for(;current.size;){for(const node2 of current){node2.height=x2;for(const{source}of node2.targetLinks)next2.add(source)}if(++x2>n2)throw new Error("circular link");current=next2,next2=new Set}}__name(computeNodeHeights,"computeNodeHeights");function computeNodeLayers({nodes:nodes2}){const x2=max$2(nodes2,d=>d.depth)+1,kx2=(x1-x0-dx)/(x2-1),columns2=new Array(x2);for(const node2 of nodes2){const i2=Math.max(0,Math.min(x2-1,Math.floor(align.call(null,node2,x2))));node2.layer=i2,node2.x0=x0+i2*kx2,node2.x1=node2.x0+dx,columns2[i2]?columns2[i2].push(node2):columns2[i2]=[node2]}if(sort)for(const column of columns2)column.sort(sort);return columns2}__name(computeNodeLayers,"computeNodeLayers");function initializeNodeBreadths(columns2){const ky2=min$2(columns2,c2=>(y1-y0-(c2.length-1)*py)/sum$1(c2,value));for(const nodes2 of columns2){let y2=y0;for(const node2 of nodes2){node2.y0=y2,node2.y1=y2+node2.value*ky2,y2=node2.y1+py;for(const link2 of node2.sourceLinks)link2.width=link2.value*ky2}y2=(y1-y2+py)/(nodes2.length+1);for(let i2=0;i2c2.length)-1)),initializeNodeBreadths(columns2);for(let i2=0;i20))continue;let dy2=(y2/w2-target.y0)*alpha3;target.y0+=dy2,target.y1+=dy2,reorderNodeLinks(target)}sort===void 0&&column.sort(ascendingBreadth),resolveCollisions(column,beta)}}__name(relaxLeftToRight,"relaxLeftToRight");function relaxRightToLeft(columns2,alpha3,beta){for(let n2=columns2.length,i2=n2-2;i2>=0;--i2){const column=columns2[i2];for(const source of column){let y2=0,w2=0;for(const{target,value:value2}of source.sourceLinks){let v2=value2*(target.layer-source.layer);y2+=sourceTop(source,target)*v2,w2+=v2}if(!(w2>0))continue;let dy2=(y2/w2-source.y0)*alpha3;source.y0+=dy2,source.y1+=dy2,reorderNodeLinks(source)}sort===void 0&&column.sort(ascendingBreadth),resolveCollisions(column,beta)}}__name(relaxRightToLeft,"relaxRightToLeft");function resolveCollisions(nodes2,alpha3){const i2=nodes2.length>>1,subject=nodes2[i2];resolveCollisionsBottomToTop(nodes2,subject.y0-py,i2-1,alpha3),resolveCollisionsTopToBottom(nodes2,subject.y1+py,i2+1,alpha3),resolveCollisionsBottomToTop(nodes2,y1,nodes2.length-1,alpha3),resolveCollisionsTopToBottom(nodes2,y0,0,alpha3)}__name(resolveCollisions,"resolveCollisions");function resolveCollisionsTopToBottom(nodes2,y2,i2,alpha3){for(;i21e-6&&(node2.y0+=dy2,node2.y1+=dy2),y2=node2.y1+py}}__name(resolveCollisionsTopToBottom,"resolveCollisionsTopToBottom");function resolveCollisionsBottomToTop(nodes2,y2,i2,alpha3){for(;i2>=0;--i2){const node2=nodes2[i2],dy2=(node2.y1-y2)*alpha3;dy2>1e-6&&(node2.y0-=dy2,node2.y1-=dy2),y2=node2.y0-py}}__name(resolveCollisionsBottomToTop,"resolveCollisionsBottomToTop");function reorderNodeLinks({sourceLinks,targetLinks}){if(linkSort===void 0){for(const{source:{sourceLinks:sourceLinks2}}of targetLinks)sourceLinks2.sort(ascendingTargetBreadth);for(const{target:{targetLinks:targetLinks2}}of sourceLinks)targetLinks2.sort(ascendingSourceBreadth)}}__name(reorderNodeLinks,"reorderNodeLinks");function reorderLinks(nodes2){if(linkSort===void 0)for(const{sourceLinks,targetLinks}of nodes2)sourceLinks.sort(ascendingTargetBreadth),targetLinks.sort(ascendingSourceBreadth)}__name(reorderLinks,"reorderLinks");function targetTop(source,target){let y2=source.y0-(source.sourceLinks.length-1)*py/2;for(const{target:node2,width}of source.sourceLinks){if(node2===target)break;y2+=width+py}for(const{source:node2,width}of target.targetLinks){if(node2===source)break;y2-=width}return y2}__name(targetTop,"targetTop");function sourceTop(source,target){let y2=target.y0-(target.targetLinks.length-1)*py/2;for(const{source:node2,width}of target.targetLinks){if(node2===source)break;y2+=width+py}for(const{target:node2,width}of source.sourceLinks){if(node2===target)break;y2-=width}return y2}return __name(sourceTop,"sourceTop"),sankey}__name(Sankey,"Sankey");var cloneDeep_1,hasRequiredCloneDeep;function requireCloneDeep(){if(hasRequiredCloneDeep)return cloneDeep_1;hasRequiredCloneDeep=1;var baseClone=require_baseClone(),CLONE_DEEP_FLAG=1,CLONE_SYMBOLS_FLAG=4;function cloneDeep(value2){return baseClone(value2,CLONE_DEEP_FLAG|CLONE_SYMBOLS_FLAG)}return __name(cloneDeep,"cloneDeep"),cloneDeep_1=cloneDeep,cloneDeep_1}__name(requireCloneDeep,"requireCloneDeep");var cloneDeepExports=requireCloneDeep();const w$1=getDefaultExportFromCjs(cloneDeepExports);function S$1(){return S$1=Object.assign?Object.assign.bind():function(e3){for(var o2=1;o2 ",jsxRuntimeExports.jsx("strong",{children:o2.target.label}),jsxRuntimeExports.jsx(g$1,{color:o2.target.color,style:z.targetChip}),jsxRuntimeExports.jsx("strong",{children:o2.formattedValue})]})})},"linkTooltip"),legends:[],layers:["links","nodes","labels","legends"],role:"img",animate:!0,motionConfig:"gentle"},V=__name(function(e3){return e3.id},"V"),A=__name(function(n2){var t2=n2.data,i2=n2.valueFormat,r2=n2.layout,c2=n2.width,s2=n2.height,u2=n2.sort,h2=n2.align,v2=n2.colors,p2=n2.nodeThickness,g2=n2.nodeSpacing,f2=n2.nodeInnerPadding,y2=n2.nodeBorderColor,m2=n2.label,k2=n2.labelTextColor,C2=reactExports.useState(null),x2=C2[0],O2=C2[1],L2=reactExports.useState(null),M2=L2[0],T2=L2[1],H=reactExports.useMemo((function(){if(u2!=="auto")return u2==="input"?null:u2==="ascending"?function(e3,o2){return e3.value-o2.value}:u2==="descending"?function(e3,o2){return o2.value-e3.value}:u2}),[u2]),P2=u2==="input"?null:void 0,W2=reactExports.useMemo((function(){return typeof h2=="function"?h2:j(h2)}),[h2]),N2=zt(),F2=pr(v2,"id"),R2=Xe(y2,N2),S2=Wn(m2),z2=Xe(k2,N2),E2=Ot(i2),G=reactExports.useMemo((function(){return(function(e3){var o2=e3.data,n3=e3.formatValue,t3=e3.layout,i3=e3.alignFunction,r3=e3.sortFunction,l2=e3.linkSortMode,a2=e3.nodeThickness,d=e3.nodeSpacing,c3=e3.nodeInnerPadding,s3=e3.width,u3=e3.height,h3=e3.getColor,v3=e3.getLabel,p3=Sankey().nodeAlign(i3).nodeSort(r3).linkSort(l2).nodeWidth(a2).nodePadding(d).size(t3==="horizontal"?[s3,u3]:[u3,s3]).nodeId(V),g3=w$1(o2);return p3(g3),g3.nodes.forEach((function(e4){if(e4.color=h3(e4),e4.label=v3(e4),e4.formattedValue=n3(e4.value),t3==="horizontal")e4.x=e4.x0+c3,e4.y=e4.y0,e4.width=Math.max(e4.x1-e4.x0-2*c3,0),e4.height=Math.max(e4.y1-e4.y0,0);else{e4.x=e4.y0,e4.y=e4.x0+c3,e4.width=Math.max(e4.y1-e4.y0,0),e4.height=Math.max(e4.x1-e4.x0-2*c3,0);var o3=e4.x0,i4=e4.x1;e4.x0=e4.y0,e4.x1=e4.y1,e4.y0=o3,e4.y1=i4}})),g3.links.forEach((function(e4){e4.formattedValue=n3(e4.value),e4.color=e4.source.color,e4.pos0=e4.y0,e4.pos1=e4.y1,e4.thickness=e4.width,delete e4.y0,delete e4.y1,delete e4.width})),g3})({data:t2,formatValue:E2,layout:r2,alignFunction:W2,sortFunction:H,linkSortMode:P2,nodeThickness:p2,nodeSpacing:g2,nodeInnerPadding:f2,width:c2,height:s2,getColor:F2,getLabel:S2})}),[t2,E2,r2,W2,H,P2,p2,g2,f2,c2,s2,F2,S2]),D2=G.nodes,A2=G.links,Z2=reactExports.useMemo((function(){return D2.map((function(e3){return{id:e3.id,label:e3.label,color:e3.color}}))}),[D2]);return{nodes:D2,links:A2,legendData:Z2,getNodeBorderColor:R2,currentNode:x2,setCurrentNode:O2,currentLink:M2,setCurrentLink:T2,getLabelTextColor:z2}},"A"),Z=__name(function(e3){var o2=e3.node,i2=e3.x,r2=e3.y,l2=e3.width,a2=e3.height,d=e3.color,s2=e3.opacity,u2=e3.borderWidth,h2=e3.borderColor,v2=e3.borderRadius,p2=e3.setCurrent,g2=e3.isInteractive,f2=e3.onClick,y2=e3.tooltip,m2=Ur(),k2=m2.animate,b2=m2.config,C2=useSpring({x:i2,y:r2,width:l2,height:a2,opacity:s2,color:d,config:b2,immediate:!k2}),x2=k$2(),M2=x2.showTooltipFromEvent,T2=x2.hideTooltip,w2=reactExports.useCallback((function(e4){p2(o2),M2(reactExports.createElement(y2,{node:o2}),e4,"left")}),[p2,o2,M2,y2]),B2=reactExports.useCallback((function(e4){M2(reactExports.createElement(y2,{node:o2}),e4,"left")}),[M2,o2,y2]),I2=reactExports.useCallback((function(){p2(null),T2()}),[p2,T2]),W2=reactExports.useCallback((function(e4){f2?.(o2,e4)}),[f2,o2]);return jsxRuntimeExports.jsx(animated.rect,{x:C2.x,y:C2.y,rx:v2,ry:v2,width:C2.width.to((function(e4){return Math.max(e4,0)})),height:C2.height.to((function(e4){return Math.max(e4,0)})),fill:C2.color,fillOpacity:C2.opacity,strokeWidth:u2,stroke:h2,strokeOpacity:s2,onMouseEnter:g2?w2:void 0,onMouseMove:g2?B2:void 0,onMouseLeave:g2?I2:void 0,onClick:g2?W2:void 0})},"Z"),q=__name(function(e3){var o2=e3.nodes,n2=e3.nodeOpacity,t2=e3.nodeHoverOpacity,i2=e3.nodeHoverOthersOpacity,r2=e3.borderWidth,l2=e3.getBorderColor,a2=e3.borderRadius,d=e3.setCurrentNode,c2=e3.currentNode,s2=e3.currentLink,u2=e3.isCurrentNode,h2=e3.isInteractive,v2=e3.onClick,p2=e3.tooltip,g2=__name(function(e4){return c2||s2?u2(e4)?t2:i2:n2},"g");return jsxRuntimeExports.jsx(jsxRuntimeExports.Fragment,{children:o2.map((function(e4){return jsxRuntimeExports.jsx(Z,{node:e4,x:e4.x,y:e4.y,width:e4.width,height:e4.height,color:e4.color,opacity:g2(e4),borderWidth:r2,borderColor:l2(e4),borderRadius:a2,setCurrent:d,isInteractive:h2,onClick:v2,tooltip:p2},e4.id)}))})},"q"),U=__name(function(e3){var o2=e3.id,n2=e3.layout,t2=e3.startColor,i2=e3.endColor;return jsxRuntimeExports.jsxs("linearGradient",S$1({id:o2,spreadMethod:"pad"},n2==="horizontal"?{x1:"0%",x2:"100%",y1:"0%",y2:"0%"}:{x1:"0%",x2:"0%",y1:"0%",y2:"100%"},{children:[jsxRuntimeExports.jsx("stop",{offset:"0%",stopColor:t2}),jsxRuntimeExports.jsx("stop",{offset:"100%",stopColor:i2})]}))},"U"),J=__name(function(e3){var o2=e3.link,i2=e3.layout,r2=e3.path,l2=e3.color,a2=e3.opacity,d=e3.blendMode,u2=e3.enableGradient,h2=e3.setCurrent,v2=e3.tooltip,p2=e3.isInteractive,g2=e3.onClick,f2=o2.source.id+"."+o2.target.id+"."+o2.index,y2=Ur(),m2=y2.animate,k2=y2.config,b2=Fr(r2),C2=useSpring({color:l2,opacity:a2,config:k2,immediate:!m2}),x2=k$2(),w2=x2.showTooltipFromEvent,B2=x2.hideTooltip,I2=reactExports.useCallback((function(e4){h2(o2),w2(reactExports.createElement(v2,{link:o2}),e4,"left")}),[h2,o2,w2,v2]),W2=reactExports.useCallback((function(e4){w2(reactExports.createElement(v2,{link:o2}),e4,"left")}),[w2,o2,v2]),N2=reactExports.useCallback((function(){h2(null),B2()}),[h2,B2]),F2=reactExports.useCallback((function(e4){g2?.(o2,e4)}),[g2,o2]);return jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment,{children:[u2&&jsxRuntimeExports.jsx(U,{id:f2,layout:i2,startColor:o2.startColor||o2.source.color,endColor:o2.endColor||o2.target.color}),jsxRuntimeExports.jsx(animated.path,{fill:u2?'url("#'+encodeURI(f2)+'")':C2.color,d:b2,fillOpacity:C2.opacity,onMouseEnter:p2?I2:void 0,onMouseMove:p2?W2:void 0,onMouseLeave:p2?N2:void 0,onClick:p2?F2:void 0,style:{mixBlendMode:d}})]})},"J"),K=__name(function(e3){var n2=e3.links,t2=e3.layout,i2=e3.linkOpacity,r2=e3.linkHoverOpacity,l2=e3.linkHoverOthersOpacity,a2=e3.linkContract,d=e3.linkBlendMode,c2=e3.enableLinkGradient,s2=e3.setCurrentLink,u2=e3.currentLink,h2=e3.currentNode,v2=e3.isCurrentLink,p2=e3.isInteractive,g2=e3.onClick,f2=e3.tooltip,y2=__name(function(e4){return h2||u2?v2(e4)?r2:l2:i2},"y"),m2=reactExports.useMemo((function(){return t2==="horizontal"?(e4=N$2().curve(monotoneX),function(o2,n3){var t3=Math.max(1,o2.thickness-2*n3)/2,i3=.12*(o2.target.x0-o2.source.x1),r3=[[o2.source.x1,o2.pos0-t3],[o2.source.x1+i3,o2.pos0-t3],[o2.target.x0-i3,o2.pos1-t3],[o2.target.x0,o2.pos1-t3],[o2.target.x0,o2.pos1+t3],[o2.target.x0-i3,o2.pos1+t3],[o2.source.x1+i3,o2.pos0+t3],[o2.source.x1,o2.pos0+t3],[o2.source.x1,o2.pos0-t3]];return e4(r3)+"Z"}):(function(){var e6=N$2().curve(monotoneY);return function(o2,n3){var t3=Math.max(1,o2.thickness-2*n3)/2,i3=.12*(o2.target.y0-o2.source.y1),r3=[[o2.pos0+t3,o2.source.y1],[o2.pos0+t3,o2.source.y1+i3],[o2.pos1+t3,o2.target.y0-i3],[o2.pos1+t3,o2.target.y0],[o2.pos1-t3,o2.target.y0],[o2.pos1-t3,o2.target.y0-i3],[o2.pos0-t3,o2.source.y1+i3],[o2.pos0-t3,o2.source.y1],[o2.pos0+t3,o2.source.y1]];return e6(r3)+"Z"}})();var e4}),[t2]);return jsxRuntimeExports.jsx(jsxRuntimeExports.Fragment,{children:n2.map((function(e4){return jsxRuntimeExports.jsx(J,{link:e4,layout:t2,path:m2(e4,a2),color:e4.color,opacity:y2(e4),blendMode:d,enableGradient:c2,setCurrent:s2,isInteractive:p2,onClick:g2,tooltip:f2},e4.source.id+"."+e4.target.id+"."+e4.index)}))})},"K"),Q=__name(function(e3){var o2=e3.nodes,n2=e3.layout,t2=e3.width,i2=e3.height,r2=e3.labelPosition,a2=e3.labelPadding,d=e3.labelOrientation,s2=e3.getLabelTextColor,u2=zt(),h2=d==="vertical"?-90:0,v2=o2.map((function(e4){var o3,l2,c2;return n2==="horizontal"?(l2=e4.y+e4.height/2,e4.x=0||(i3[n3]=e4[n3]);return i3})(e3,X);return jsxRuntimeExports.jsx(St,{animate:i2,isInteractive:n2,motionConfig:l2,renderWrapper:d,theme:a2,children:jsxRuntimeExports.jsx(Y,S$1({isInteractive:n2},c2))})},"$$1"),_$1=__name(function(e3){return jsxRuntimeExports.jsx(It,{children:__name(function(o2){var n2=o2.width,t2=o2.height;return jsxRuntimeExports.jsx($$1,S$1({width:n2,height:t2},e3))},"children")})},"_$1");const ZtResponsiveSankey=__name(({isDark,data})=>{const connectedNodeIds=new Set;for(const link2 of data.links)connectedNodeIds.add(link2.source),connectedNodeIds.add(link2.target);const filteredData={nodes:data.nodes.filter(node2=>connectedNodeIds.has(node2.id)),links:data.links},theme={tooltip:{container:{background:isDark?"rgba(33, 33, 33, 0.95)":"rgba(255, 255, 255, 0.95)",color:isDark?"#ffffff":"#000000",border:isDark?"1px solid #555":"1px solid #ccc",borderRadius:"4px",boxShadow:"0 2px 8px rgba(0, 0, 0, 0.15)",fontSize:"12px",padding:"8px 12px"}},labels:{text:{fontSize:12}}};return jsxRuntimeExports.jsx("div",{className:`h-full w-full ${isDark?"sankey-dark-mode":"sankey-light-mode"}`,children:jsxRuntimeExports.jsx(_$1,{data:filteredData,theme,margin:{top:10,right:10,bottom:10,left:10},align:"justify",colors:__name(node2=>node2.nodeColor,"colors"),nodeOpacity:1,nodeHoverOthersOpacity:.35,nodeThickness:18,nodeSpacing:24,nodeBorderWidth:0,nodeBorderColor:{from:"color",modifiers:[["darker",.8]]},nodeBorderRadius:3,linkOpacity:.5,linkHoverOthersOpacity:.1,linkContract:3,linkBlendMode:isDark?"lighten":"multiply",enableLinkGradient:!0,labelPosition:"inside",labelOrientation:"horizontal",labelPadding:16,labelTextColor:isDark?"#ffffff":"#000000",sort:"input",legends:[],valueFormat:__name(value2=>`${value2}`,"valueFormat")})})},"ZtResponsiveSankey"),CaSankey=__name(({data})=>{const theme=reactExports.useContext(ThemeProviderContext),filteredData=data.filter(link2=>link2.value!=null&&link2.value>0);return jsxRuntimeExports.jsx(ZtResponsiveSankey,{isDark:!!(theme.theme==="dark"||theme.theme==="system"&&window.matchMedia("(prefers-color-scheme: dark)").matches),data:{nodes:[{id:"User sign in",nodeColor:"hsl(28, 100%, 53%)"},{id:"No CA applied",nodeColor:"hsl(0, 100%, 50%)"},{id:"CA applied",nodeColor:"hsl(12, 76%, 61%)"},{id:"No MFA",nodeColor:"hsl(0, 69%, 50%)"},{id:"MFA",nodeColor:"hsl(99, 70%, 50%)"}],links:filteredData}})},"CaSankey"),CaDeviceSankey=__name(({data})=>{const theme=reactExports.useContext(ThemeProviderContext),filteredData=data.filter(link2=>link2.value!=null&&link2.value>0);return jsxRuntimeExports.jsx(ZtResponsiveSankey,{isDark:!!(theme.theme==="dark"||theme.theme==="system"&&window.matchMedia("(prefers-color-scheme: dark)").matches),data:{nodes:[{id:"User sign in",nodeColor:"hsl(28, 100%, 53%)"},{id:"Unmanaged",nodeColor:"hsl(0, 100%, 50%)"},{id:"Managed",nodeColor:"hsl(12, 76%, 61%)"},{id:"Non-compliant",nodeColor:"hsl(0, 100%, 50%)"},{id:"Compliant",nodeColor:"hsl(99, 70%, 50%)"}],links:filteredData}})},"CaDeviceSankey"),AuthMethodSankey=__name(({data})=>{const theme=reactExports.useContext(ThemeProviderContext),filteredData=data.filter(link2=>link2.value!=null&&link2.value>0);return jsxRuntimeExports.jsx(ZtResponsiveSankey,{isDark:!!(theme.theme==="dark"||theme.theme==="system"&&window.matchMedia("(prefers-color-scheme: dark)").matches),data:{nodes:[{id:"Users",nodeColor:"hsl(28, 100%, 53%)"},{id:"Single factor",nodeColor:"hsl(0, 100%, 50%)"},{id:"Phishable",nodeColor:"hsl(12, 76%, 61%)"},{id:"Phone",nodeColor:"hsl(12, 76%, 61%)"},{id:"Authenticator",nodeColor:"hsl(12, 76%, 61%)"},{id:"Phish resistant",nodeColor:"hsl(99, 70%, 50%)"},{id:"Passkey",nodeColor:"hsl(99, 70%, 50%)"},{id:"WHfB",nodeColor:"hsl(99, 70%, 50%)"}],links:filteredData}})},"AuthMethodSankey"),DesktopDevicesSankey=__name(({data})=>{const theme=reactExports.useContext(ThemeProviderContext),filteredData=data.filter(link2=>link2.value!=null&&link2.value>0);return jsxRuntimeExports.jsx(ZtResponsiveSankey,{isDark:!!(theme.theme==="dark"||theme.theme==="system"&&window.matchMedia("(prefers-color-scheme: dark)").matches),data:{nodes:[{id:"Desktop devices",nodeColor:"hsl(28, 100%, 53%)"},{id:"Windows",nodeColor:"hsl(35, 100%, 50%)"},{id:"macOS",nodeColor:"hsl(200, 100%, 50%)"},{id:"Entra joined",nodeColor:"hsl(12, 76%, 61%)"},{id:"Entra registered",nodeColor:"hsl(12, 76%, 61%)"},{id:"Entra hybrid joined",nodeColor:"hsl(12, 76%, 61%)"},{id:"Compliant",nodeColor:"hsl(99, 70%, 50%)"},{id:"Non-compliant",nodeColor:"hsl(0, 100%, 50%)"},{id:"Unmanaged",nodeColor:"hsl(220, 10%, 60%)"}],links:filteredData}})},"DesktopDevicesSankey"),MobileSankey=__name(({data})=>{const theme=reactExports.useContext(ThemeProviderContext),filteredData=data.filter(link2=>link2.value!=null&&link2.value>0);return jsxRuntimeExports.jsx(ZtResponsiveSankey,{isDark:!!(theme.theme==="dark"||theme.theme==="system"&&window.matchMedia("(prefers-color-scheme: dark)").matches),data:{nodes:[{id:"Mobile devices",nodeColor:"hsl(28, 100%, 53%)"},{id:"Android",nodeColor:"hsl(35, 100%, 50%)"},{id:"iOS",nodeColor:"hsl(210, 100%, 50%)"},{id:"Android (Company)",nodeColor:"hsl(30, 100%, 45%)"},{id:"Android (Personal)",nodeColor:"hsl(40, 100%, 55%)"},{id:"iOS (Company)",nodeColor:"hsl(210, 100%, 45%)"},{id:"iOS (Personal)",nodeColor:"hsl(210, 100%, 55%)"},{id:"Compliant",nodeColor:"hsl(99, 70%, 50%)"},{id:"Non-compliant",nodeColor:"hsl(0, 100%, 50%)"}],links:filteredData}})},"MobileSankey");var NODES=["a","button","div","form","h2","h3","img","input","label","li","nav","ol","p","select","span","svg","ul"],Primitive=NODES.reduce((primitive,node2)=>{const Slot2=createSlot$2(`Primitive.${node2}`),Node2=reactExports.forwardRef((props,forwardedRef)=>{const{asChild,...primitiveProps}=props,Comp=asChild?Slot2:node2;return typeof window<"u"&&(window[Symbol.for("radix-ui")]=!0),jsxRuntimeExports.jsx(Comp,{...primitiveProps,ref:forwardedRef})});return Node2.displayName=`Primitive.${node2}`,{...primitive,[node2]:Node2}},{}),NAME="Separator",DEFAULT_ORIENTATION="horizontal",ORIENTATIONS=["horizontal","vertical"],Separator$1=reactExports.forwardRef((props,forwardedRef)=>{const{decorative,orientation:orientationProp=DEFAULT_ORIENTATION,...domProps}=props,orientation=isValidOrientation(orientationProp)?orientationProp:DEFAULT_ORIENTATION,semanticProps=decorative?{role:"none"}:{"aria-orientation":orientation==="vertical"?orientation:void 0,role:"separator"};return jsxRuntimeExports.jsx(Primitive.div,{"data-orientation":orientation,...semanticProps,...domProps,ref:forwardedRef})});Separator$1.displayName=NAME;function isValidOrientation(orientation){return ORIENTATIONS.includes(orientation)}__name(isValidOrientation,"isValidOrientation");var Root=Separator$1;const Separator=reactExports.forwardRef(({className,orientation="horizontal",decorative=!0,...props},ref)=>jsxRuntimeExports.jsx(Root,{ref,decorative,orientation,className:cn$2("shrink-0 bg-border",orientation==="horizontal"?"h-[1px] w-full":"h-full w-[1px]",className),...props}));Separator.displayName=Root.displayName;function formatNumber(value2){return value2==null||isNaN(value2)?"0":value2<1e3?value2.toLocaleString():value2<1e5?`${(value2/1e3).toFixed(1)}K`:`${Math.round(value2/1e3)}K`}__name(formatNumber,"formatNumber");const metricDescriptions={users:"Total number of user accounts in the tenant (excluding guests)",guests:"Total number of guest user accounts",groups:"Total number of groups (security, Microsoft 365, etc.)",apps:"Total number of registered applications",devices:"Including both managed and unmanaged devices",managed:"Total number of Intune managed devices"};function Dashboard(){return jsxRuntimeExports.jsxs(TooltipProvider,{delayDuration:200,children:[jsxRuntimeExports.jsx("div",{className:"w-full flex max-w-7xl flex-col gap-6 mt-12",children:jsxRuntimeExports.jsxs("div",{className:"grid w-full gap-6 lg:grid-cols-3",children:[jsxRuntimeExports.jsxs(Card,{children:[jsxRuntimeExports.jsx(CardHeader,{className:"pb-3",children:jsxRuntimeExports.jsxs(CardTitle,{className:"flex items-center gap-2",children:[jsxRuntimeExports.jsx(Building2,{className:"size-5"}),"Tenant"]})}),jsxRuntimeExports.jsx(CardContent,{children:jsxRuntimeExports.jsxs("div",{className:"space-y-4",children:[jsxRuntimeExports.jsxs("div",{className:"flex flex-col gap-1",children:[jsxRuntimeExports.jsx("span",{className:"text-sm text-muted-foreground",children:"Name"}),jsxRuntimeExports.jsx("span",{className:"font-medium",children:reportData.TenantName})]}),jsxRuntimeExports.jsxs("div",{className:"flex flex-col gap-1",children:[jsxRuntimeExports.jsx("span",{className:"text-sm text-muted-foreground",children:"Tenant ID"}),jsxRuntimeExports.jsx("span",{className:"font-mono text-xs",children:reportData.TenantId})]}),jsxRuntimeExports.jsxs("div",{className:"flex flex-col gap-1",children:[jsxRuntimeExports.jsx("span",{className:"text-sm text-muted-foreground",children:"Primary Domain"}),jsxRuntimeExports.jsx("span",{className:"font-medium",children:reportData.Domain})]})]})})]}),jsxRuntimeExports.jsxs("div",{className:"grid gap-4 grid-cols-2 grid-rows-3",children:[jsxRuntimeExports.jsxs(Tooltip,{children:[jsxRuntimeExports.jsx(TooltipTrigger,{asChild:!0,children:jsxRuntimeExports.jsxs("div",{className:"flex items-center gap-3 rounded-md border px-4 py-3",children:[jsxRuntimeExports.jsx(Avatar,{className:"size-8.5 rounded-sm",children:jsxRuntimeExports.jsx(AvatarFallback,{className:"text-blue-600 shrink-0 rounded-sm",children:jsxRuntimeExports.jsx(User,{className:"size-8"})})}),jsxRuntimeExports.jsxs("div",{className:"flex flex-col gap-0.5",children:[jsxRuntimeExports.jsx("span",{className:"text-muted-foreground text-sm font-medium",children:"Users"}),jsxRuntimeExports.jsx("span",{className:"text-lg font-medium",children:formatNumber(reportData.TenantInfo?.TenantOverview?.UserCount)})]})]})}),jsxRuntimeExports.jsx(TooltipContent,{children:jsxRuntimeExports.jsxs("div",{className:"space-y-1",children:[jsxRuntimeExports.jsxs("p",{className:"font-semibold",children:[reportData.TenantInfo?.TenantOverview?.UserCount?.toLocaleString()||"0"," Users"]}),jsxRuntimeExports.jsx("p",{className:"text-xs text-muted-foreground",children:metricDescriptions.users})]})})]}),jsxRuntimeExports.jsxs(Tooltip,{children:[jsxRuntimeExports.jsx(TooltipTrigger,{asChild:!0,children:jsxRuntimeExports.jsxs("div",{className:"flex items-center gap-3 rounded-md border px-4 py-3",children:[jsxRuntimeExports.jsx(Avatar,{className:"size-8.5 rounded-sm",children:jsxRuntimeExports.jsx(AvatarFallback,{className:"text-indigo-600 shrink-0 rounded-sm",children:jsxRuntimeExports.jsx(Luggage,{className:"size-8"})})}),jsxRuntimeExports.jsxs("div",{className:"flex flex-col gap-0.5",children:[jsxRuntimeExports.jsx("span",{className:"text-muted-foreground text-sm font-medium",children:"Guests"}),jsxRuntimeExports.jsx("span",{className:"text-lg font-medium",children:formatNumber(reportData.TenantInfo?.TenantOverview?.GuestCount)})]})]})}),jsxRuntimeExports.jsx(TooltipContent,{children:jsxRuntimeExports.jsxs("div",{className:"space-y-1",children:[jsxRuntimeExports.jsxs("p",{className:"font-semibold",children:[reportData.TenantInfo?.TenantOverview?.GuestCount?.toLocaleString()||"0"," Guests"]}),jsxRuntimeExports.jsx("p",{className:"text-xs text-muted-foreground",children:metricDescriptions.guests})]})})]}),jsxRuntimeExports.jsxs(Tooltip,{children:[jsxRuntimeExports.jsx(TooltipTrigger,{asChild:!0,children:jsxRuntimeExports.jsxs("div",{className:"flex items-center gap-3 rounded-md border px-4 py-3",children:[jsxRuntimeExports.jsx(Avatar,{className:"size-8.5 rounded-sm",children:jsxRuntimeExports.jsx(AvatarFallback,{className:"text-purple-600 shrink-0 rounded-sm",children:jsxRuntimeExports.jsx(Users,{className:"size-8"})})}),jsxRuntimeExports.jsxs("div",{className:"flex flex-col gap-0.5",children:[jsxRuntimeExports.jsx("span",{className:"text-muted-foreground text-sm font-medium",children:"Groups"}),jsxRuntimeExports.jsx("span",{className:"text-lg font-medium",children:formatNumber(reportData.TenantInfo?.TenantOverview?.GroupCount)})]})]})}),jsxRuntimeExports.jsx(TooltipContent,{children:jsxRuntimeExports.jsxs("div",{className:"space-y-1",children:[jsxRuntimeExports.jsxs("p",{className:"font-semibold",children:[reportData.TenantInfo?.TenantOverview?.GroupCount?.toLocaleString()||"0"," Groups"]}),jsxRuntimeExports.jsx("p",{className:"text-xs text-muted-foreground",children:metricDescriptions.groups})]})})]}),jsxRuntimeExports.jsxs(Tooltip,{children:[jsxRuntimeExports.jsx(TooltipTrigger,{asChild:!0,children:jsxRuntimeExports.jsxs("div",{className:"flex items-center gap-3 rounded-md border px-4 py-3",children:[jsxRuntimeExports.jsx(Avatar,{className:"size-8.5 rounded-sm",children:jsxRuntimeExports.jsx(AvatarFallback,{className:"text-rose-600 shrink-0 rounded-sm",children:jsxRuntimeExports.jsx(Layers3,{className:"size-8"})})}),jsxRuntimeExports.jsxs("div",{className:"flex flex-col gap-0.5",children:[jsxRuntimeExports.jsx("span",{className:"text-muted-foreground text-sm font-medium",children:"Apps"}),jsxRuntimeExports.jsx("span",{className:"text-lg font-medium",children:formatNumber(reportData.TenantInfo?.TenantOverview?.ApplicationCount)})]})]})}),jsxRuntimeExports.jsx(TooltipContent,{children:jsxRuntimeExports.jsxs("div",{className:"space-y-1",children:[jsxRuntimeExports.jsxs("p",{className:"font-semibold",children:[reportData.TenantInfo?.TenantOverview?.ApplicationCount?.toLocaleString()||"0"," Applications"]}),jsxRuntimeExports.jsx("p",{className:"text-xs text-muted-foreground",children:metricDescriptions.apps})]})})]}),jsxRuntimeExports.jsxs(Tooltip,{children:[jsxRuntimeExports.jsx(TooltipTrigger,{asChild:!0,children:jsxRuntimeExports.jsxs("div",{className:"flex items-center gap-3 rounded-md border px-4 py-3",children:[jsxRuntimeExports.jsx(Avatar,{className:"size-8.5 rounded-sm",children:jsxRuntimeExports.jsx(AvatarFallback,{className:"text-orange-600 shrink-0 rounded-sm",children:jsxRuntimeExports.jsx(MonitorSmartphone,{className:"size-8"})})}),jsxRuntimeExports.jsxs("div",{className:"flex flex-col gap-0.5",children:[jsxRuntimeExports.jsx("span",{className:"text-muted-foreground text-sm font-medium",children:"Devices"}),jsxRuntimeExports.jsx("span",{className:"text-lg font-medium",children:formatNumber(reportData.TenantInfo?.TenantOverview?.DeviceCount)})]})]})}),jsxRuntimeExports.jsx(TooltipContent,{children:jsxRuntimeExports.jsxs("div",{className:"space-y-1",children:[jsxRuntimeExports.jsxs("p",{className:"font-semibold",children:[reportData.TenantInfo?.TenantOverview?.DeviceCount?.toLocaleString()||"0"," Devices"]}),jsxRuntimeExports.jsx("p",{className:"text-xs text-muted-foreground",children:metricDescriptions.devices})]})})]}),jsxRuntimeExports.jsxs(Tooltip,{children:[jsxRuntimeExports.jsx(TooltipTrigger,{asChild:!0,children:jsxRuntimeExports.jsxs("div",{className:"flex items-center gap-3 rounded-md border px-4 py-3",children:[jsxRuntimeExports.jsx(Avatar,{className:"size-8.5 rounded-sm",children:jsxRuntimeExports.jsx(AvatarFallback,{className:"text-emerald-600 shrink-0 rounded-sm",children:jsxRuntimeExports.jsx(MonitorSmartphone,{className:"size-8"})})}),jsxRuntimeExports.jsxs("div",{className:"flex flex-col gap-0.5",children:[jsxRuntimeExports.jsx("span",{className:"text-muted-foreground text-sm font-medium",children:"Managed"}),jsxRuntimeExports.jsx("span",{className:"text-lg font-medium",children:formatNumber(reportData.TenantInfo?.TenantOverview?.ManagedDeviceCount)})]})]})}),jsxRuntimeExports.jsx(TooltipContent,{children:jsxRuntimeExports.jsxs("div",{className:"space-y-1",children:[jsxRuntimeExports.jsxs("p",{className:"font-semibold",children:[reportData.TenantInfo?.TenantOverview?.ManagedDeviceCount?.toLocaleString()||"0"," Managed Devices"]}),jsxRuntimeExports.jsx("p",{className:"text-xs text-muted-foreground",children:metricDescriptions.managed})]})})]})]}),jsxRuntimeExports.jsxs(Card,{"x-chunk":"charts-01-chunk-5",children:[jsxRuntimeExports.jsx(CardHeader,{className:"pb-3",children:jsxRuntimeExports.jsxs(CardTitle,{className:"flex items-center gap-2",children:[jsxRuntimeExports.jsx(ShieldCheck,{className:"size-5"}),"Assessment"]})}),jsxRuntimeExports.jsxs(CardContent,{className:"flex gap-6",children:[jsxRuntimeExports.jsxs("div",{className:"flex flex-col gap-2",children:[jsxRuntimeExports.jsxs("div",{className:"grid auto-rows-min gap-0.5",children:[jsxRuntimeExports.jsx("div",{className:"text-sm text-muted-foreground",children:"Identity"}),jsxRuntimeExports.jsxs("div",{className:"flex items-baseline gap-1 text-xl font-bold tabular-nums leading-none",children:[reportData.TestResultSummary.IdentityPassed,"/",reportData.TestResultSummary.IdentityTotal,jsxRuntimeExports.jsx("span",{className:"text-sm font-normal text-muted-foreground",children:"tests"})]})]}),jsxRuntimeExports.jsxs("div",{className:"grid auto-rows-min gap-0.5",children:[jsxRuntimeExports.jsx("div",{className:"text-sm text-muted-foreground",children:"Devices"}),jsxRuntimeExports.jsxs("div",{className:"flex items-baseline gap-1 text-xl font-bold tabular-nums leading-none",children:[reportData.TestResultSummary.DevicesPassed,"/",reportData.TestResultSummary.DevicesTotal,jsxRuntimeExports.jsx("span",{className:"text-sm font-normal text-muted-foreground",children:"tests"})]})]}),jsxRuntimeExports.jsxs("div",{className:"grid flex-1 auto-rows-min gap-0.5",children:[jsxRuntimeExports.jsx("div",{className:"text-sm text-muted-foreground",children:"Data"}),jsxRuntimeExports.jsxs("div",{className:"flex items-baseline gap-1 text-xl font-bold tabular-nums leading-none",children:[reportData.TestResultSummary.DataPassed,"/",reportData.TestResultSummary.DataTotal,jsxRuntimeExports.jsx("span",{className:"text-sm font-normal text-muted-foreground",children:"tests"})]})]}),reportData.TestResultSummary.NetworkPassed!==void 0&&jsxRuntimeExports.jsxs("div",{className:"grid flex-1 auto-rows-min gap-0.5",children:[jsxRuntimeExports.jsx("div",{className:"text-sm text-muted-foreground",children:"Network"}),jsxRuntimeExports.jsxs("div",{className:"flex items-baseline gap-1 text-xl font-bold tabular-nums leading-none",children:[reportData.TestResultSummary.NetworkPassed,"/",reportData.TestResultSummary.NetworkTotal,jsxRuntimeExports.jsx("span",{className:"text-sm font-normal text-muted-foreground",children:"tests"})]})]}),reportData.TestResultSummary.InfrastructurePassed!==void 0&&jsxRuntimeExports.jsxs("div",{className:"grid flex-1 auto-rows-min gap-0.5",children:[jsxRuntimeExports.jsx("div",{className:"text-sm text-muted-foreground",children:"Infrastructure"}),jsxRuntimeExports.jsxs("div",{className:"flex items-baseline gap-1 text-xl font-bold tabular-nums leading-none",children:[reportData.TestResultSummary.InfrastructurePassed,"/",reportData.TestResultSummary.InfrastructureTotal,jsxRuntimeExports.jsx("span",{className:"text-sm font-normal text-muted-foreground",children:"tests"})]})]}),reportData.TestResultSummary.SecOpsPassed!==void 0&&jsxRuntimeExports.jsxs("div",{className:"grid flex-1 auto-rows-min gap-0.5",children:[jsxRuntimeExports.jsx("div",{className:"text-sm text-muted-foreground",children:"SecOps"}),jsxRuntimeExports.jsxs("div",{className:"flex items-baseline gap-1 text-xl font-bold tabular-nums leading-none",children:[reportData.TestResultSummary.SecOpsPassed,"/",reportData.TestResultSummary.SecOpsTotal,jsxRuntimeExports.jsx("span",{className:"text-sm font-normal text-muted-foreground",children:"tests"})]})]}),reportData.TestResultSummary.AIPassed!==void 0&&jsxRuntimeExports.jsxs("div",{className:"grid flex-1 auto-rows-min gap-0.5",children:[jsxRuntimeExports.jsx("div",{className:"text-sm text-muted-foreground",children:"AI"}),jsxRuntimeExports.jsxs("div",{className:"flex items-baseline gap-1 text-xl font-bold tabular-nums leading-none",children:[reportData.TestResultSummary.AIPassed,"/",reportData.TestResultSummary.AITotal,jsxRuntimeExports.jsx("span",{className:"text-sm font-normal text-muted-foreground",children:"tests"})]})]})]}),jsxRuntimeExports.jsx(ChartContainer,{config:{move:{label:"Identity",color:"hsl(var(--chart-1))"},exercise:{label:"Devices",color:"hsl(var(--chart-2))"},stand:{label:"Data",color:"hsl(var(--chart-3))"},network:{label:"Network",color:"hsl(var(--chart-4))"},infrastructure:{label:"Infrastructure",color:"hsl(var(--chart-5))"},secops:{label:"SecOps",color:"hsl(var(--chart-1))"},ai:{label:"AI",color:"hsl(var(--chart-2))"}},className:"mx-auto aspect-square w-full max-w-[80%]",children:jsxRuntimeExports.jsxs(RadialBarChart,{margin:{left:-10,right:-10,top:-10,bottom:-10},data:[...reportData.TestResultSummary.AIPassed!==void 0&&reportData.TestResultSummary.AITotal!==void 0?[{activity:"ai",value:reportData.TestResultSummary.AIPassed/reportData.TestResultSummary.AITotal*100,fill:"var(--color-ai)"}]:[],...reportData.TestResultSummary.SecOpsPassed!==void 0&&reportData.TestResultSummary.SecOpsTotal!==void 0?[{activity:"secops",value:reportData.TestResultSummary.SecOpsPassed/reportData.TestResultSummary.SecOpsTotal*100,fill:"var(--color-secops)"}]:[],...reportData.TestResultSummary.InfrastructurePassed!==void 0&&reportData.TestResultSummary.InfrastructureTotal!==void 0?[{activity:"infrastructure",value:reportData.TestResultSummary.InfrastructurePassed/reportData.TestResultSummary.InfrastructureTotal*100,fill:"var(--color-infrastructure)"}]:[],...reportData.TestResultSummary.NetworkPassed!==void 0&&reportData.TestResultSummary.NetworkTotal!==void 0?[{activity:"network",value:reportData.TestResultSummary.NetworkPassed/reportData.TestResultSummary.NetworkTotal*100,fill:"var(--color-network)"}]:[],{activity:"data",value:reportData.TestResultSummary.DataPassed/reportData.TestResultSummary.DataTotal*100,fill:"var(--color-stand)"},{activity:"devices",value:reportData.TestResultSummary.DevicesPassed/reportData.TestResultSummary.DevicesTotal*100,fill:"var(--color-exercise)"},{activity:"identity",value:reportData.TestResultSummary.IdentityPassed/reportData.TestResultSummary.IdentityTotal*100,fill:"var(--color-move)"}],innerRadius:"20%",barSize:24,startAngle:90,endAngle:450,children:[jsxRuntimeExports.jsx(PolarAngleAxis,{type:"number",domain:[0,100],dataKey:"value",tick:!1}),jsxRuntimeExports.jsx(RadialBar,{dataKey:"value",background:!0,cornerRadius:5})]})})]})]})]})}),jsxRuntimeExports.jsx("div",{className:"mx-auto flex max-w-7xl flex-col gap-6 mt-6",children:jsxRuntimeExports.jsxs("div",{className:"grid gap-6 grid-cols-1 lg:grid-cols-2",children:[jsxRuntimeExports.jsxs("div",{className:"grid w-full gap-6 lg:col-span-1",children:[reportData.TenantInfo?.OverviewAuthMethodsAllUsers?.nodes?jsxRuntimeExports.jsxs(Card,{className:"w-full","x-chunk":"charts-01-chunk-0",children:[jsxRuntimeExports.jsxs(CardHeader,{className:"space-y-0 pb-2 flex-row",children:[jsxRuntimeExports.jsx(UserCog,{className:"pr-2 size-8"}),jsxRuntimeExports.jsx(CardTitle,{className:"text-2xl tabular-nums",children:"Privileged users auth methods"})]}),jsxRuntimeExports.jsx(CardContent,{children:jsxRuntimeExports.jsx(ChartContainer,{config:{steps:{label:"Steps",color:"hsl(var(--chart-1))"}},children:reportData.TenantInfo?.OverviewAuthMethodsPrivilegedUsers?.nodes?jsxRuntimeExports.jsx(AuthMethodSankey,{data:reportData.TenantInfo.OverviewAuthMethodsPrivilegedUsers.nodes}):jsxRuntimeExports.jsx("div",{className:"flex items-center justify-center h-32 text-muted-foreground",children:"No data available"})})}),jsxRuntimeExports.jsx(CardFooter,{className:"flex-col items-start gap-1",children:jsxRuntimeExports.jsx(CardDescription,{children:reportData.TenantInfo?.OverviewAuthMethodsPrivilegedUsers?.description||"No description available"})})]}):null,reportData.TenantInfo?.OverviewAuthMethodsAllUsers?.nodes?jsxRuntimeExports.jsxs(Card,{className:"w-full","x-chunk":"charts-01-chunk-0",children:[jsxRuntimeExports.jsxs(CardHeader,{className:"space-y-0 pb-2 flex-row",children:[jsxRuntimeExports.jsx(Users,{className:"pr-2 size-8"}),jsxRuntimeExports.jsx(CardTitle,{className:"text-2xl tabular-nums",children:"All users auth methods"})]}),jsxRuntimeExports.jsx(CardContent,{children:jsxRuntimeExports.jsx(ChartContainer,{config:{steps:{label:"Steps",color:"hsl(var(--chart-1))"}},children:reportData.TenantInfo?.OverviewAuthMethodsAllUsers?.nodes?jsxRuntimeExports.jsx(AuthMethodSankey,{data:reportData.TenantInfo.OverviewAuthMethodsAllUsers.nodes}):jsxRuntimeExports.jsx("div",{className:"flex items-center justify-center h-32 text-muted-foreground",children:"No data available"})})}),jsxRuntimeExports.jsx(CardFooter,{className:"flex-col items-start gap-1",children:jsxRuntimeExports.jsx(CardDescription,{children:reportData.TenantInfo?.OverviewAuthMethodsAllUsers?.description||"No description available"})})]}):null]}),jsxRuntimeExports.jsxs("div",{className:"grid w-full gap-6 lg:col-span-1",children:[reportData.TenantInfo?.OverviewAuthMethodsAllUsers?.nodes?jsxRuntimeExports.jsxs(Card,{className:"lmax-w-xs","x-chunk":"charts-01-chunk-0",children:[jsxRuntimeExports.jsxs(CardHeader,{className:"space-y-0 pb-2 flex-row",children:[jsxRuntimeExports.jsx(User,{className:"pr-2 size-8"}),jsxRuntimeExports.jsx(CardTitle,{className:"text-2xl tabular-nums",children:"User authentication"})]}),jsxRuntimeExports.jsx(CardContent,{children:jsxRuntimeExports.jsx(ChartContainer,{config:{steps:{label:"Steps",color:"hsl(var(--chart-1))"}},children:reportData.TenantInfo?.OverviewCaMfaAllUsers?.nodes?jsxRuntimeExports.jsx(CaSankey,{data:reportData.TenantInfo.OverviewCaMfaAllUsers.nodes}):jsxRuntimeExports.jsx("div",{className:"flex items-center justify-center h-32 text-muted-foreground",children:"No data available"})})}),jsxRuntimeExports.jsx(CardFooter,{className:"flex-col items-start gap-1",children:jsxRuntimeExports.jsx(CardDescription,{children:reportData.TenantInfo?.OverviewCaMfaAllUsers?.description||"No description available"})})]}):null,reportData.TenantInfo?.OverviewAuthMethodsPrivilegedUsers?.nodes?jsxRuntimeExports.jsxs(Card,{className:"lmax-w-xs","x-chunk":"charts-01-chunk-0",children:[jsxRuntimeExports.jsxs(CardHeader,{className:"space-y-0 pb-2 flex-row",children:[jsxRuntimeExports.jsx(MonitorSmartphone,{className:"pr-2 size-8"}),jsxRuntimeExports.jsx(CardTitle,{className:"text-2xl tabular-nums ",children:"Device sign-ins"})]}),jsxRuntimeExports.jsx(CardContent,{children:jsxRuntimeExports.jsx(ChartContainer,{config:{steps:{label:"Steps",color:"hsl(var(--chart-1))"}},children:reportData.TenantInfo?.OverviewCaDevicesAllUsers?.nodes?jsxRuntimeExports.jsx(CaDeviceSankey,{data:reportData.TenantInfo.OverviewCaDevicesAllUsers.nodes}):jsxRuntimeExports.jsx("div",{className:"flex items-center justify-center h-32 text-muted-foreground",children:"No data available"})})}),jsxRuntimeExports.jsx(CardFooter,{className:"flex-col items-start gap-1",children:jsxRuntimeExports.jsx(CardDescription,{children:reportData.TenantInfo?.OverviewCaDevicesAllUsers?.description||"No description available"})})]}):null]})]})}),jsxRuntimeExports.jsx("div",{className:"flex max-w-7xl flex-col gap-6 mt-6",children:jsxRuntimeExports.jsxs("div",{className:"grid gap-6 grid-cols-1 lg:grid-cols-3",children:[reportData.TenantInfo?.DeviceOverview?.ManagedDevices?jsxRuntimeExports.jsxs(Card,{className:"w-full",children:[jsxRuntimeExports.jsxs(CardHeader,{className:"space-y-0 pb-2 flex-row",children:[jsxRuntimeExports.jsx(MonitorSmartphone,{className:"pr-2 size-8"}),jsxRuntimeExports.jsx(CardTitle,{className:"text-2xl tabular-nums",children:"Device summary"})]}),jsxRuntimeExports.jsx(CardContent,{className:"flex pb-4 h-[250px]",children:jsxRuntimeExports.jsx(ChartContainer,{config:{value:{label:"Devices"}},className:"h-[250px] w-full",children:jsxRuntimeExports.jsxs(BarChart,{margin:{left:12,right:0,top:0,bottom:10},data:[{dataKey:"Windows",value:reportData.TenantInfo?.DeviceOverview?.ManagedDevices?.deviceOperatingSystemSummary?.windowsCount,label:`${reportData.TenantInfo?.DeviceOverview?.ManagedDevices?.deviceOperatingSystemSummary?.windowsCount}`,fill:"hsl(var(--chart-1))"},{dataKey:"macOS",value:reportData.TenantInfo?.DeviceOverview?.ManagedDevices?.deviceOperatingSystemSummary?.macOSCount,label:`${reportData.TenantInfo?.DeviceOverview?.ManagedDevices?.deviceOperatingSystemSummary?.macOSCount}`,fill:"hsl(var(--chart-2))"},{dataKey:"iOS/iPadOS",value:reportData.TenantInfo?.DeviceOverview?.ManagedDevices?.deviceOperatingSystemSummary?.iosCount,label:`${reportData.TenantInfo?.DeviceOverview?.ManagedDevices?.deviceOperatingSystemSummary?.iosCount}`,fill:"hsl(var(--chart-3))"},{dataKey:"Android",value:reportData.TenantInfo?.DeviceOverview?.ManagedDevices?.deviceOperatingSystemSummary?.androidCount,label:`${reportData.TenantInfo?.DeviceOverview?.ManagedDevices?.deviceOperatingSystemSummary?.androidCount}`,fill:"hsl(var(--chart-5))"},{dataKey:"Linux",value:reportData.TenantInfo?.DeviceOverview?.ManagedDevices?.deviceOperatingSystemSummary?.linuxCount,label:`${reportData.TenantInfo?.DeviceOverview?.ManagedDevices?.deviceOperatingSystemSummary?.linuxCount}`,fill:"hsl(var(--chart-4))"}],layout:"vertical",barSize:32,barGap:2,children:[jsxRuntimeExports.jsx(XAxis,{type:"number",dataKey:"value",hide:!0}),jsxRuntimeExports.jsx(YAxis,{dataKey:"dataKey",type:"category",tickLine:!1,tickMargin:4,axisLine:!1,className:""}),jsxRuntimeExports.jsx(ChartTooltip,{cursor:!1,content:jsxRuntimeExports.jsx(ChartTooltipContent,{})}),jsxRuntimeExports.jsx(Bar,{dataKey:"value",radius:5,children:jsxRuntimeExports.jsx(LabelList,{position:"insideLeft",dataKey:"label",fill:"white",offset:8,fontSize:12})})]})})}),jsxRuntimeExports.jsx(CardFooter,{className:"flex flex-row border-t p-4",children:jsxRuntimeExports.jsxs("div",{className:"flex w-full items-center gap-2",children:[jsxRuntimeExports.jsxs("div",{className:"grid flex-1 auto-rows-min gap-0.5",children:[jsxRuntimeExports.jsx("div",{className:"text-xs text-muted-foreground",children:"Desktops"}),jsxRuntimeExports.jsxs("div",{className:"flex items-baseline gap-1 text-2xl font-bold tabular-nums leading-none",children:[Math.round(reportData.TenantInfo?.DeviceOverview?.ManagedDevices?.desktopCount/reportData.TenantInfo?.DeviceOverview?.ManagedDevices?.totalCount*100),jsxRuntimeExports.jsx("span",{className:"text-sm font-normal text-muted-foreground",children:"%"})]})]}),jsxRuntimeExports.jsx(Separator,{orientation:"vertical",className:"mx-2 h-10 w-px"}),jsxRuntimeExports.jsxs("div",{className:"grid flex-1 auto-rows-min gap-0.5",children:[jsxRuntimeExports.jsx("div",{className:"text-xs text-muted-foreground",children:"Mobiles"}),jsxRuntimeExports.jsxs("div",{className:"flex items-baseline gap-1 text-2xl font-bold tabular-nums leading-none",children:[Math.round(reportData.TenantInfo?.DeviceOverview?.ManagedDevices?.mobileCount/reportData.TenantInfo?.DeviceOverview?.ManagedDevices?.totalCount*100),jsxRuntimeExports.jsx("span",{className:"text-sm font-normal text-muted-foreground",children:"%"})]})]})]})})]}):null,reportData.TenantInfo?.DeviceOverview?.ManagedDevices&&reportData.TenantInfo?.DeviceOverview?.DeviceCompliance&&reportData.TenantInfo?.DeviceOverview?.DeviceCompliance?.compliantDeviceCount+reportData.TenantInfo?.DeviceOverview?.DeviceCompliance?.nonCompliantDeviceCount>0&&jsxRuntimeExports.jsxs(Card,{className:"w-full",children:[jsxRuntimeExports.jsxs(CardHeader,{className:"space-y-0 pb-2 flex-row",children:[jsxRuntimeExports.jsx(CircleCheckBig,{className:"pr-2 size-8"}),jsxRuntimeExports.jsx(CardTitle,{className:"text-2xl tabular-nums ",children:"Device compliance"})]}),jsxRuntimeExports.jsx(CardContent,{className:"flex pb-2 h-[250px]",children:jsxRuntimeExports.jsx(ChartContainer,{config:{compliant:{label:"Compliant",color:"hsl(142, 76%, 36%)"},nonCompliant:{label:"Non-compliant",color:"hsl(0, 84%, 60%)"}},className:"mx-auto aspect-square w-full max-h-full",children:jsxRuntimeExports.jsxs(PieChart,{margin:{top:5,right:5,bottom:5,left:5},children:[jsxRuntimeExports.jsxs(Pie,{data:[{name:"Compliant",value:reportData.TenantInfo?.DeviceOverview?.DeviceCompliance?.compliantDeviceCount,fill:"var(--color-compliant)"},{name:"Non-compliant",value:reportData.TenantInfo?.DeviceOverview?.DeviceCompliance?.nonCompliantDeviceCount,fill:"var(--color-nonCompliant)"}],cx:"50%",cy:"50%",innerRadius:50,outerRadius:100,paddingAngle:2,dataKey:"value",cornerRadius:5,children:[jsxRuntimeExports.jsx(Cell,{fill:"var(--color-compliant)"}),jsxRuntimeExports.jsx(Cell,{fill:"var(--color-nonCompliant)"})]}),jsxRuntimeExports.jsx(ChartTooltip,{content:jsxRuntimeExports.jsx(ChartTooltipContent,{})})]})})}),jsxRuntimeExports.jsx(CardFooter,{className:"flex flex-row border-t p-4",children:jsxRuntimeExports.jsxs("div",{className:"flex w-full items-center gap-2",children:[jsxRuntimeExports.jsxs("div",{className:"grid flex-1 auto-rows-min gap-0.5",children:[jsxRuntimeExports.jsxs("div",{className:"flex items-center gap-1 text-xs text-muted-foreground",children:[jsxRuntimeExports.jsx("div",{className:"w-3 h-3 rounded-sm bg-green-600"}),"Compliant"]}),jsxRuntimeExports.jsxs("div",{className:"flex items-baseline gap-1 text-2xl font-bold tabular-nums leading-none",children:[(()=>{const compliant=reportData.TenantInfo?.DeviceOverview?.DeviceCompliance?.compliantDeviceCount,nonCompliant=reportData.TenantInfo?.DeviceOverview?.DeviceCompliance?.nonCompliantDeviceCount,total=compliant+nonCompliant;return total>0?Math.round(compliant/total*100):0})(),jsxRuntimeExports.jsx("span",{className:"text-sm font-normal text-muted-foreground",children:"%"})]})]}),jsxRuntimeExports.jsx(Separator,{orientation:"vertical",className:"mx-2 h-10 w-px"}),jsxRuntimeExports.jsxs("div",{className:"grid flex-1 auto-rows-min gap-0.5",children:[jsxRuntimeExports.jsxs("div",{className:"flex items-center gap-1 text-xs text-muted-foreground",children:[jsxRuntimeExports.jsx("div",{className:"w-3 h-3 rounded-sm bg-red-500"}),"Non-compliant"]}),jsxRuntimeExports.jsxs("div",{className:"flex items-baseline gap-1 text-2xl font-bold tabular-nums leading-none",children:[(()=>{const compliant=reportData.TenantInfo?.DeviceOverview?.DeviceCompliance?.compliantDeviceCount,nonCompliant=reportData.TenantInfo?.DeviceOverview?.DeviceCompliance?.nonCompliantDeviceCount,total=compliant+nonCompliant;return total>0?Math.round(nonCompliant/total*100):0})(),jsxRuntimeExports.jsx("span",{className:"text-sm font-normal text-muted-foreground",children:"%"})]})]})]})})]}),reportData.TenantInfo?.DeviceOverview?.ManagedDevices&&reportData.TenantInfo?.DeviceOverview?.DeviceOwnership&&reportData.TenantInfo?.DeviceOverview?.DeviceOwnership?.corporateCount+reportData.TenantInfo?.DeviceOverview?.DeviceOwnership?.personalCount>0&&jsxRuntimeExports.jsxs(Card,{className:"w-full",children:[jsxRuntimeExports.jsxs(CardHeader,{className:"space-y-0 pb-2 flex-row",children:[jsxRuntimeExports.jsx(Briefcase,{className:"pr-2 size-8"}),jsxRuntimeExports.jsx(CardTitle,{className:"text-2xl tabular-nums ",children:"Device ownership"})]}),jsxRuntimeExports.jsx(CardContent,{className:"flex pb-2 h-[250px]",children:jsxRuntimeExports.jsx(ChartContainer,{config:{corporate:{label:"Corporate",color:"hsl(217, 91%, 60%)"},personal:{label:"Personal",color:"hsl(280, 85%, 60%)"}},className:"mx-auto aspect-square w-full max-h-full",children:jsxRuntimeExports.jsxs(PieChart,{margin:{top:5,right:5,bottom:5,left:5},children:[jsxRuntimeExports.jsxs(Pie,{data:[{name:"Corporate",value:reportData.TenantInfo?.DeviceOverview?.DeviceOwnership?.corporateCount,fill:"var(--color-corporate)"},{name:"Personal",value:reportData.TenantInfo?.DeviceOverview?.DeviceOwnership?.personalCount,fill:"var(--color-personal)"}],cx:"50%",cy:"50%",innerRadius:50,outerRadius:100,paddingAngle:2,dataKey:"value",cornerRadius:5,children:[jsxRuntimeExports.jsx(Cell,{fill:"var(--color-corporate)"}),jsxRuntimeExports.jsx(Cell,{fill:"var(--color-personal)"})]}),jsxRuntimeExports.jsx(ChartTooltip,{content:jsxRuntimeExports.jsx(ChartTooltipContent,{})})]})})}),jsxRuntimeExports.jsx(CardFooter,{className:"flex flex-row border-t p-4",children:jsxRuntimeExports.jsxs("div",{className:"flex w-full items-center gap-2",children:[jsxRuntimeExports.jsxs("div",{className:"grid flex-1 auto-rows-min gap-0.5",children:[jsxRuntimeExports.jsxs("div",{className:"flex items-center gap-1 text-xs text-muted-foreground",children:[jsxRuntimeExports.jsx("div",{className:"w-3 h-3 rounded-sm bg-blue-500"}),"Corporate"]}),jsxRuntimeExports.jsxs("div",{className:"flex items-baseline gap-1 text-2xl font-bold tabular-nums leading-none",children:[(()=>{const corporate=reportData.TenantInfo?.DeviceOverview?.DeviceOwnership?.corporateCount,personal=reportData.TenantInfo?.DeviceOverview?.DeviceOwnership?.personalCount,total=corporate+personal;return total>0?Math.round(corporate/total*100):0})(),jsxRuntimeExports.jsx("span",{className:"text-sm font-normal text-muted-foreground",children:"%"})]})]}),jsxRuntimeExports.jsx(Separator,{orientation:"vertical",className:"mx-2 h-10 w-px"}),jsxRuntimeExports.jsxs("div",{className:"grid flex-1 auto-rows-min gap-0.5",children:[jsxRuntimeExports.jsxs("div",{className:"flex items-center gap-1 text-xs text-muted-foreground",children:[jsxRuntimeExports.jsx("div",{className:"w-3 h-3 rounded-sm bg-purple-500"}),"Personal"]}),jsxRuntimeExports.jsxs("div",{className:"flex items-baseline gap-1 text-2xl font-bold tabular-nums leading-none",children:[(()=>{const corporate=reportData.TenantInfo?.DeviceOverview?.DeviceOwnership?.corporateCount,personal=reportData.TenantInfo?.DeviceOverview?.DeviceOwnership?.personalCount,total=corporate+personal;return total>0?Math.round(personal/total*100):0})(),jsxRuntimeExports.jsx("span",{className:"text-sm font-normal text-muted-foreground",children:"%"})]})]})]})})]}),reportData.TenantInfo?.DeviceOverview?.DesktopDevicesSummary?.nodes&&reportData.TenantInfo.DeviceOverview.DesktopDevicesSummary.nodes.length>0&&jsxRuntimeExports.jsxs(Card,{className:"w-full lg:col-span-3",children:[jsxRuntimeExports.jsxs(CardHeader,{className:"space-y-0 pb-2 flex-row",children:[jsxRuntimeExports.jsx(Monitor,{className:"pr-2 size-8"}),jsxRuntimeExports.jsx(CardTitle,{className:"text-2xl tabular-nums",children:"Desktop devices"})]}),jsxRuntimeExports.jsx(CardContent,{children:jsxRuntimeExports.jsx(ChartContainer,{config:{steps:{label:"Steps",color:"hsl(var(--chart-1))"}},className:"h-[350px] w-full",children:reportData.TenantInfo?.DeviceOverview?.DesktopDevicesSummary?.nodes?jsxRuntimeExports.jsx(DesktopDevicesSankey,{data:reportData.TenantInfo.DeviceOverview.DesktopDevicesSummary.nodes}):jsxRuntimeExports.jsx("div",{className:"flex items-center justify-center h-32 text-muted-foreground",children:"No data available"})})}),jsxRuntimeExports.jsx(CardFooter,{className:"flex flex-row border-t p-4",children:jsxRuntimeExports.jsxs("div",{className:"flex w-full items-center gap-2",children:[jsxRuntimeExports.jsxs("div",{className:"grid flex-1 auto-rows-min gap-0.5",children:[jsxRuntimeExports.jsx("div",{className:"text-xs text-muted-foreground",children:"Entra joined"}),jsxRuntimeExports.jsxs("div",{className:"flex items-baseline gap-1 text-2xl font-bold tabular-nums leading-none",children:[(()=>{const nodes=reportData.TenantInfo?.DeviceOverview?.DesktopDevicesSummary?.nodes||[],entraJoined=nodes.find(n2=>n2.target==="Entra joined")?.value||0,windowsDevices=nodes.find(n2=>n2.source==="Desktop devices"&&n2.target==="Windows")?.value||0,macOSDevices=nodes.find(n2=>n2.source==="Desktop devices"&&n2.target==="macOS")?.value||0,total=windowsDevices+macOSDevices;return Math.round(entraJoined/(total||1)*100)})(),jsxRuntimeExports.jsx("span",{className:"text-sm font-normal text-muted-foreground",children:"%"})]})]}),jsxRuntimeExports.jsx(Separator,{orientation:"vertical",className:"mx-2 h-10 w-px"}),jsxRuntimeExports.jsxs("div",{className:"grid flex-1 auto-rows-min gap-0.5",children:[jsxRuntimeExports.jsx("div",{className:"text-xs text-muted-foreground",children:"Entra hybrid joined"}),jsxRuntimeExports.jsxs("div",{className:"flex items-baseline gap-1 text-2xl font-bold tabular-nums leading-none",children:[(()=>{const nodes=reportData.TenantInfo?.DeviceOverview?.DesktopDevicesSummary?.nodes||[],entraHybrid=nodes.find(n2=>n2.target==="Entra hybrid joined")?.value||0,windowsDevices=nodes.find(n2=>n2.source==="Desktop devices"&&n2.target==="Windows")?.value||0,macOSDevices=nodes.find(n2=>n2.source==="Desktop devices"&&n2.target==="macOS")?.value||0,total=windowsDevices+macOSDevices;return Math.round(entraHybrid/(total||1)*100)})(),jsxRuntimeExports.jsx("span",{className:"text-sm font-normal text-muted-foreground",children:"%"})]})]}),jsxRuntimeExports.jsx(Separator,{orientation:"vertical",className:"mx-2 h-10 w-px"}),jsxRuntimeExports.jsxs("div",{className:"grid flex-1 auto-rows-min gap-0.5",children:[jsxRuntimeExports.jsx("div",{className:"text-xs text-muted-foreground",children:"Entra registered"}),jsxRuntimeExports.jsxs("div",{className:"flex items-baseline gap-1 text-2xl font-bold tabular-nums leading-none",children:[(()=>{const nodes=reportData.TenantInfo?.DeviceOverview?.DesktopDevicesSummary?.nodes||[],entraRegistered=nodes.find(n2=>n2.target==="Entra registered")?.value||0,windowsDevices=nodes.find(n2=>n2.source==="Desktop devices"&&n2.target==="Windows")?.value||0,macOSDevices=nodes.find(n2=>n2.source==="Desktop devices"&&n2.target==="macOS")?.value||0,total=windowsDevices+macOSDevices;return Math.round(entraRegistered/(total||1)*100)})(),jsxRuntimeExports.jsx("span",{className:"text-sm font-normal text-muted-foreground",children:"%"})]})]})]})})]}),reportData.TenantInfo?.DeviceOverview?.MobileSummary?.nodes&&reportData.TenantInfo?.DeviceOverview?.ManagedDevices&&jsxRuntimeExports.jsxs(Card,{className:"w-full lg:col-span-3",children:[jsxRuntimeExports.jsxs(CardHeader,{className:"space-y-0 pb-2 flex-row",children:[jsxRuntimeExports.jsx(MonitorSmartphone,{className:"pr-2 size-8"}),jsxRuntimeExports.jsx(CardTitle,{className:"text-2xl tabular-nums",children:"Mobile devices"})]}),jsxRuntimeExports.jsx(CardContent,{children:jsxRuntimeExports.jsx(ChartContainer,{config:{steps:{label:"Steps",color:"hsl(var(--chart-1))"}},className:"h-[350px] w-full",children:reportData.TenantInfo?.DeviceOverview?.MobileSummary?.nodes?jsxRuntimeExports.jsx(MobileSankey,{data:reportData.TenantInfo.DeviceOverview.MobileSummary.nodes}):jsxRuntimeExports.jsx("div",{className:"flex items-center justify-center h-32 text-muted-foreground",children:"No data available"})})}),jsxRuntimeExports.jsx(CardFooter,{className:"flex flex-row border-t p-4",children:jsxRuntimeExports.jsxs("div",{className:"flex w-full items-center gap-2",children:[jsxRuntimeExports.jsxs("div",{className:"grid flex-1 auto-rows-min gap-0.5",children:[jsxRuntimeExports.jsx("div",{className:"text-xs text-muted-foreground",children:"Android compliant"}),jsxRuntimeExports.jsxs("div",{className:"flex items-baseline gap-1 text-2xl font-bold tabular-nums leading-none",children:[(()=>{const nodes=reportData.TenantInfo?.DeviceOverview?.MobileSummary?.nodes||[],androidCompliant=nodes.filter(n2=>n2.source?.includes("Android")&&n2.target==="Compliant").reduce((sum2,n2)=>sum2+(n2.value||0),0),androidTotal=nodes.find(n2=>n2.source==="Mobile devices"&&n2.target==="Android")?.value||0;return androidTotal>0?Math.round(androidCompliant/androidTotal*100):0})(),jsxRuntimeExports.jsx("span",{className:"text-sm font-normal text-muted-foreground",children:"%"})]})]}),jsxRuntimeExports.jsx(Separator,{orientation:"vertical",className:"mx-2 h-10 w-px"}),jsxRuntimeExports.jsxs("div",{className:"grid flex-1 auto-rows-min gap-0.5",children:[jsxRuntimeExports.jsx("div",{className:"text-xs text-muted-foreground",children:"iOS compliant"}),jsxRuntimeExports.jsxs("div",{className:"flex items-baseline gap-1 text-2xl font-bold tabular-nums leading-none",children:[(()=>{const nodes=reportData.TenantInfo?.DeviceOverview?.MobileSummary?.nodes||[],iosCompliant=nodes.filter(n2=>n2.source?.includes("iOS")&&n2.target==="Compliant").reduce((sum2,n2)=>sum2+(n2.value||0),0),iosTotal=nodes.find(n2=>n2.source==="Mobile devices"&&n2.target==="iOS")?.value||0;return iosTotal>0?Math.round(iosCompliant/iosTotal*100):0})(),jsxRuntimeExports.jsx("span",{className:"text-sm font-normal text-muted-foreground",children:"%"})]})]}),jsxRuntimeExports.jsx(Separator,{orientation:"vertical",className:"mx-2 h-10 w-px"}),jsxRuntimeExports.jsxs("div",{className:"grid flex-1 auto-rows-min gap-0.5",children:[jsxRuntimeExports.jsx("div",{className:"text-xs text-muted-foreground",children:"Total devices"}),jsxRuntimeExports.jsx("div",{className:"flex items-baseline gap-1 text-2xl font-bold tabular-nums leading-none",children:(()=>{const nodes=reportData.TenantInfo?.DeviceOverview?.MobileSummary?.nodes||[],androidTotal=nodes.find(n2=>n2.source==="Mobile devices"&&n2.target==="Android")?.value||0,iosTotal=nodes.find(n2=>n2.source==="Mobile devices"&&n2.target==="iOS")?.value||0;return androidTotal+iosTotal})()})]})]})})]})]})})]})}__name(Dashboard,"Dashboard");var E=typeof window>"u",m=E?React.useEffect:React.useLayoutEffect,B=0,_=__name(()=>++B,"_"),v=!1;function O(){let[n2,r2]=React.useState(v?_:void 0);return m(()=>{n2===void 0&&r2(_()),v=!0},[]),n2===void 0?n2:`rwb-${n2.toString(32)}`}__name(O,"O");function R(){return React.useMemo(()=>"useId"in React?React.useId:O,[])()}__name(R,"R");var y="__wrap_b",f="__wrap_n",S="__wrap_o",T=__name((n2,r2,e3)=>{e3=e3||document.querySelector(`[data-br="${n2}"]`);let t2=e3?.parentElement;if(!t2)return;let l2=__name(u2=>e3.style.maxWidth=u2+"px","l");e3.style.maxWidth="";let i2=t2.clientWidth,d=t2.clientHeight,o2=i2/2-.25,s2=i2+.5,c2;if(i2){for(l2(o2),o2=Math.max(e3.scrollWidth,o2);o2+1{self.__wrap_b(0,+e3.dataset.brr,e3)})).observe(t2)},"T"),I=T.toString(),w='(self.CSS&&CSS.supports("text-wrap","balance")?1:2)',g=__name((n2,r2,e3="")=>(e3&&(e3=`self.${f}!=1&&${e3}`),React.createElement("script",{suppressHydrationWarning:!0,dangerouslySetInnerHTML:{__html:(n2?"":`self.${f}=self.${f}||${w};self.${y}=${I};`)+e3},nonce:r2})),"g"),h$1=React.createContext({preferNative:!0,hasProvider:!1});React.forwardRef(({ratio:n2=1,preferNative:r2,nonce:e3,children:t2,as:l2,...i2},d)=>{let o2=R(),s2=React.useRef(),c2=React.useContext(h$1),u2=r2??c2.preferNative,x2=l2||"span";return React.useImperativeHandle(d,()=>s2.current,[]),m(()=>{u2&&self[f]===1||s2.current&&(self[y]=T)(0,n2,s2.current)},[t2,u2,n2]),m(()=>{if(!(u2&&self[f]===1))return()=>{if(!s2.current)return;let b2=s2.current[S];b2&&(b2.disconnect(),delete s2.current[S])}},[u2]),React.createElement(React.Fragment,null,React.createElement(x2,{...i2,"data-br":o2,"data-brr":n2,ref:s2,style:{display:"inline-block",verticalAlign:"top",textDecoration:"inherit",textWrap:u2?"balance":"initial"},suppressHydrationWarning:!0},t2),g(c2.hasProvider,e3,`self.${y}("${o2}",${n2})`))});function PageHeader({className,children:children2,...props}){return jsxRuntimeExports.jsx("section",{className:cn$2("pt-6 pb-4 flex items-center justify-between space-y-2",className),...props,children:children2})}__name(PageHeader,"PageHeader");function PageHeaderHeading({className,...props}){return jsxRuntimeExports.jsx("h1",{className:cn$2("text-3xl font-semibold tracking-tight my-1",className),...props})}__name(PageHeaderHeading,"PageHeaderHeading");function functionalUpdate(updater,input){return typeof updater=="function"?updater(input):updater}__name(functionalUpdate,"functionalUpdate");function makeStateUpdater(key,instance){return updater=>{instance.setState(old=>({...old,[key]:functionalUpdate(updater,old[key])}))}}__name(makeStateUpdater,"makeStateUpdater");function isFunction(d){return d instanceof Function}__name(isFunction,"isFunction");function isNumberArray(d){return Array.isArray(d)&&d.every(val=>typeof val=="number")}__name(isNumberArray,"isNumberArray");function flattenBy(arr,getChildren){const flat=[],recurse=__name(subArr=>{subArr.forEach(item=>{flat.push(item);const children2=getChildren(item);children2!=null&&children2.length&&recurse(children2)})},"recurse");return recurse(arr),flat}__name(flattenBy,"flattenBy");function memo(getDeps,fn2,opts){let deps=[],result;return depArgs=>{let depTime;opts.key&&opts.debug&&(depTime=Date.now());const newDeps=getDeps(depArgs);if(!(newDeps.length!==deps.length||newDeps.some((dep,index2)=>deps[index2]!==dep)))return result;deps=newDeps;let resultTime;if(opts.key&&opts.debug&&(resultTime=Date.now()),result=fn2(...newDeps),opts==null||opts.onChange==null||opts.onChange(result),opts.key&&opts.debug&&opts!=null&&opts.debug()){const depEndTime=Math.round((Date.now()-depTime)*100)/100,resultEndTime=Math.round((Date.now()-resultTime)*100)/100,resultFpsPercentage=resultEndTime/16,pad2=__name((str,num)=>{for(str=String(str);str.length[id(d,i2,nodes2),d]));for(const[i2,link2]of links2.entries()){link2.index=i2;let{source,target}=link2;typeof source!="object"&&(source=link2.source=find$1(nodeById,source)),typeof target!="object"&&(target=link2.target=find$1(nodeById,target)),source.sourceLinks.push(link2),target.targetLinks.push(link2)}if(linkSort!=null)for(const{sourceLinks,targetLinks}of nodes2)sourceLinks.sort(linkSort),targetLinks.sort(linkSort)}__name(computeNodeLinks,"computeNodeLinks");function computeNodeValues({nodes:nodes2}){for(const node2 of nodes2)node2.value=node2.fixedValue===void 0?Math.max(sum$1(node2.sourceLinks,value),sum$1(node2.targetLinks,value)):node2.fixedValue}__name(computeNodeValues,"computeNodeValues");function computeNodeDepths({nodes:nodes2}){const n2=nodes2.length;let current=new Set(nodes2),next2=new Set,x2=0;for(;current.size;){for(const node2 of current){node2.depth=x2;for(const{target}of node2.sourceLinks)next2.add(target)}if(++x2>n2)throw new Error("circular link");current=next2,next2=new Set}}__name(computeNodeDepths,"computeNodeDepths");function computeNodeHeights({nodes:nodes2}){const n2=nodes2.length;let current=new Set(nodes2),next2=new Set,x2=0;for(;current.size;){for(const node2 of current){node2.height=x2;for(const{source}of node2.targetLinks)next2.add(source)}if(++x2>n2)throw new Error("circular link");current=next2,next2=new Set}}__name(computeNodeHeights,"computeNodeHeights");function computeNodeLayers({nodes:nodes2}){const x2=max$2(nodes2,d=>d.depth)+1,kx2=(x1-x0-dx)/(x2-1),columns2=new Array(x2);for(const node2 of nodes2){const i2=Math.max(0,Math.min(x2-1,Math.floor(align.call(null,node2,x2))));node2.layer=i2,node2.x0=x0+i2*kx2,node2.x1=node2.x0+dx,columns2[i2]?columns2[i2].push(node2):columns2[i2]=[node2]}if(sort)for(const column of columns2)column.sort(sort);return columns2}__name(computeNodeLayers,"computeNodeLayers");function initializeNodeBreadths(columns2){const ky2=min$2(columns2,c2=>(y1-y0-(c2.length-1)*py)/sum$1(c2,value));for(const nodes2 of columns2){let y2=y0;for(const node2 of nodes2){node2.y0=y2,node2.y1=y2+node2.value*ky2,y2=node2.y1+py;for(const link2 of node2.sourceLinks)link2.width=link2.value*ky2}y2=(y1-y2+py)/(nodes2.length+1);for(let i2=0;i2c2.length)-1)),initializeNodeBreadths(columns2);for(let i2=0;i20))continue;let dy2=(y2/w2-target.y0)*alpha3;target.y0+=dy2,target.y1+=dy2,reorderNodeLinks(target)}sort===void 0&&column.sort(ascendingBreadth),resolveCollisions(column,beta)}}__name(relaxLeftToRight,"relaxLeftToRight");function relaxRightToLeft(columns2,alpha3,beta){for(let n2=columns2.length,i2=n2-2;i2>=0;--i2){const column=columns2[i2];for(const source of column){let y2=0,w2=0;for(const{target,value:value2}of source.sourceLinks){let v2=value2*(target.layer-source.layer);y2+=sourceTop(source,target)*v2,w2+=v2}if(!(w2>0))continue;let dy2=(y2/w2-source.y0)*alpha3;source.y0+=dy2,source.y1+=dy2,reorderNodeLinks(source)}sort===void 0&&column.sort(ascendingBreadth),resolveCollisions(column,beta)}}__name(relaxRightToLeft,"relaxRightToLeft");function resolveCollisions(nodes2,alpha3){const i2=nodes2.length>>1,subject=nodes2[i2];resolveCollisionsBottomToTop(nodes2,subject.y0-py,i2-1,alpha3),resolveCollisionsTopToBottom(nodes2,subject.y1+py,i2+1,alpha3),resolveCollisionsBottomToTop(nodes2,y1,nodes2.length-1,alpha3),resolveCollisionsTopToBottom(nodes2,y0,0,alpha3)}__name(resolveCollisions,"resolveCollisions");function resolveCollisionsTopToBottom(nodes2,y2,i2,alpha3){for(;i21e-6&&(node2.y0+=dy2,node2.y1+=dy2),y2=node2.y1+py}}__name(resolveCollisionsTopToBottom,"resolveCollisionsTopToBottom");function resolveCollisionsBottomToTop(nodes2,y2,i2,alpha3){for(;i2>=0;--i2){const node2=nodes2[i2],dy2=(node2.y1-y2)*alpha3;dy2>1e-6&&(node2.y0-=dy2,node2.y1-=dy2),y2=node2.y0-py}}__name(resolveCollisionsBottomToTop,"resolveCollisionsBottomToTop");function reorderNodeLinks({sourceLinks,targetLinks}){if(linkSort===void 0){for(const{source:{sourceLinks:sourceLinks2}}of targetLinks)sourceLinks2.sort(ascendingTargetBreadth);for(const{target:{targetLinks:targetLinks2}}of sourceLinks)targetLinks2.sort(ascendingSourceBreadth)}}__name(reorderNodeLinks,"reorderNodeLinks");function reorderLinks(nodes2){if(linkSort===void 0)for(const{sourceLinks,targetLinks}of nodes2)sourceLinks.sort(ascendingTargetBreadth),targetLinks.sort(ascendingSourceBreadth)}__name(reorderLinks,"reorderLinks");function targetTop(source,target){let y2=source.y0-(source.sourceLinks.length-1)*py/2;for(const{target:node2,width}of source.sourceLinks){if(node2===target)break;y2+=width+py}for(const{source:node2,width}of target.targetLinks){if(node2===source)break;y2-=width}return y2}__name(targetTop,"targetTop");function sourceTop(source,target){let y2=target.y0-(target.targetLinks.length-1)*py/2;for(const{source:node2,width}of target.targetLinks){if(node2===source)break;y2+=width+py}for(const{target:node2,width}of source.sourceLinks){if(node2===target)break;y2-=width}return y2}return __name(sourceTop,"sourceTop"),sankey}__name(Sankey,"Sankey");var cloneDeep_1,hasRequiredCloneDeep;function requireCloneDeep(){if(hasRequiredCloneDeep)return cloneDeep_1;hasRequiredCloneDeep=1;var baseClone=require_baseClone(),CLONE_DEEP_FLAG=1,CLONE_SYMBOLS_FLAG=4;function cloneDeep(value2){return baseClone(value2,CLONE_DEEP_FLAG|CLONE_SYMBOLS_FLAG)}return __name(cloneDeep,"cloneDeep"),cloneDeep_1=cloneDeep,cloneDeep_1}__name(requireCloneDeep,"requireCloneDeep");var cloneDeepExports=requireCloneDeep();const w$1=getDefaultExportFromCjs(cloneDeepExports);function S$1(){return S$1=Object.assign?Object.assign.bind():function(e3){for(var o2=1;o2 ",jsxRuntimeExports.jsx("strong",{children:o2.target.label}),jsxRuntimeExports.jsx(g$1,{color:o2.target.color,style:z.targetChip}),jsxRuntimeExports.jsx("strong",{children:o2.formattedValue})]})})},"linkTooltip"),legends:[],layers:["links","nodes","labels","legends"],role:"img",animate:!0,motionConfig:"gentle"},V=__name(function(e3){return e3.id},"V"),A=__name(function(n2){var t2=n2.data,i2=n2.valueFormat,r2=n2.layout,c2=n2.width,s2=n2.height,u2=n2.sort,h2=n2.align,v2=n2.colors,p2=n2.nodeThickness,g2=n2.nodeSpacing,f2=n2.nodeInnerPadding,y2=n2.nodeBorderColor,m2=n2.label,k2=n2.labelTextColor,C2=reactExports.useState(null),x2=C2[0],O2=C2[1],L2=reactExports.useState(null),M2=L2[0],T2=L2[1],H=reactExports.useMemo((function(){if(u2!=="auto")return u2==="input"?null:u2==="ascending"?function(e3,o2){return e3.value-o2.value}:u2==="descending"?function(e3,o2){return o2.value-e3.value}:u2}),[u2]),P2=u2==="input"?null:void 0,W2=reactExports.useMemo((function(){return typeof h2=="function"?h2:j(h2)}),[h2]),N2=zt(),F2=pr(v2,"id"),R2=Xe(y2,N2),S2=Wn(m2),z2=Xe(k2,N2),E2=Ot(i2),G=reactExports.useMemo((function(){return(function(e3){var o2=e3.data,n3=e3.formatValue,t3=e3.layout,i3=e3.alignFunction,r3=e3.sortFunction,l2=e3.linkSortMode,a2=e3.nodeThickness,d=e3.nodeSpacing,c3=e3.nodeInnerPadding,s3=e3.width,u3=e3.height,h3=e3.getColor,v3=e3.getLabel,p3=Sankey().nodeAlign(i3).nodeSort(r3).linkSort(l2).nodeWidth(a2).nodePadding(d).size(t3==="horizontal"?[s3,u3]:[u3,s3]).nodeId(V),g3=w$1(o2);return p3(g3),g3.nodes.forEach((function(e4){if(e4.color=h3(e4),e4.label=v3(e4),e4.formattedValue=n3(e4.value),t3==="horizontal")e4.x=e4.x0+c3,e4.y=e4.y0,e4.width=Math.max(e4.x1-e4.x0-2*c3,0),e4.height=Math.max(e4.y1-e4.y0,0);else{e4.x=e4.y0,e4.y=e4.x0+c3,e4.width=Math.max(e4.y1-e4.y0,0),e4.height=Math.max(e4.x1-e4.x0-2*c3,0);var o3=e4.x0,i4=e4.x1;e4.x0=e4.y0,e4.x1=e4.y1,e4.y0=o3,e4.y1=i4}})),g3.links.forEach((function(e4){e4.formattedValue=n3(e4.value),e4.color=e4.source.color,e4.pos0=e4.y0,e4.pos1=e4.y1,e4.thickness=e4.width,delete e4.y0,delete e4.y1,delete e4.width})),g3})({data:t2,formatValue:E2,layout:r2,alignFunction:W2,sortFunction:H,linkSortMode:P2,nodeThickness:p2,nodeSpacing:g2,nodeInnerPadding:f2,width:c2,height:s2,getColor:F2,getLabel:S2})}),[t2,E2,r2,W2,H,P2,p2,g2,f2,c2,s2,F2,S2]),D2=G.nodes,A2=G.links,Z2=reactExports.useMemo((function(){return D2.map((function(e3){return{id:e3.id,label:e3.label,color:e3.color}}))}),[D2]);return{nodes:D2,links:A2,legendData:Z2,getNodeBorderColor:R2,currentNode:x2,setCurrentNode:O2,currentLink:M2,setCurrentLink:T2,getLabelTextColor:z2}},"A"),Z=__name(function(e3){var o2=e3.node,i2=e3.x,r2=e3.y,l2=e3.width,a2=e3.height,d=e3.color,s2=e3.opacity,u2=e3.borderWidth,h2=e3.borderColor,v2=e3.borderRadius,p2=e3.setCurrent,g2=e3.isInteractive,f2=e3.onClick,y2=e3.tooltip,m2=Ur(),k2=m2.animate,b2=m2.config,C2=useSpring({x:i2,y:r2,width:l2,height:a2,opacity:s2,color:d,config:b2,immediate:!k2}),x2=k$2(),M2=x2.showTooltipFromEvent,T2=x2.hideTooltip,w2=reactExports.useCallback((function(e4){p2(o2),M2(reactExports.createElement(y2,{node:o2}),e4,"left")}),[p2,o2,M2,y2]),B2=reactExports.useCallback((function(e4){M2(reactExports.createElement(y2,{node:o2}),e4,"left")}),[M2,o2,y2]),I2=reactExports.useCallback((function(){p2(null),T2()}),[p2,T2]),W2=reactExports.useCallback((function(e4){f2?.(o2,e4)}),[f2,o2]);return jsxRuntimeExports.jsx(animated.rect,{x:C2.x,y:C2.y,rx:v2,ry:v2,width:C2.width.to((function(e4){return Math.max(e4,0)})),height:C2.height.to((function(e4){return Math.max(e4,0)})),fill:C2.color,fillOpacity:C2.opacity,strokeWidth:u2,stroke:h2,strokeOpacity:s2,onMouseEnter:g2?w2:void 0,onMouseMove:g2?B2:void 0,onMouseLeave:g2?I2:void 0,onClick:g2?W2:void 0})},"Z"),q=__name(function(e3){var o2=e3.nodes,n2=e3.nodeOpacity,t2=e3.nodeHoverOpacity,i2=e3.nodeHoverOthersOpacity,r2=e3.borderWidth,l2=e3.getBorderColor,a2=e3.borderRadius,d=e3.setCurrentNode,c2=e3.currentNode,s2=e3.currentLink,u2=e3.isCurrentNode,h2=e3.isInteractive,v2=e3.onClick,p2=e3.tooltip,g2=__name(function(e4){return c2||s2?u2(e4)?t2:i2:n2},"g");return jsxRuntimeExports.jsx(jsxRuntimeExports.Fragment,{children:o2.map((function(e4){return jsxRuntimeExports.jsx(Z,{node:e4,x:e4.x,y:e4.y,width:e4.width,height:e4.height,color:e4.color,opacity:g2(e4),borderWidth:r2,borderColor:l2(e4),borderRadius:a2,setCurrent:d,isInteractive:h2,onClick:v2,tooltip:p2},e4.id)}))})},"q"),U=__name(function(e3){var o2=e3.id,n2=e3.layout,t2=e3.startColor,i2=e3.endColor;return jsxRuntimeExports.jsxs("linearGradient",S$1({id:o2,spreadMethod:"pad"},n2==="horizontal"?{x1:"0%",x2:"100%",y1:"0%",y2:"0%"}:{x1:"0%",x2:"0%",y1:"0%",y2:"100%"},{children:[jsxRuntimeExports.jsx("stop",{offset:"0%",stopColor:t2}),jsxRuntimeExports.jsx("stop",{offset:"100%",stopColor:i2})]}))},"U"),J=__name(function(e3){var o2=e3.link,i2=e3.layout,r2=e3.path,l2=e3.color,a2=e3.opacity,d=e3.blendMode,u2=e3.enableGradient,h2=e3.setCurrent,v2=e3.tooltip,p2=e3.isInteractive,g2=e3.onClick,f2=o2.source.id+"."+o2.target.id+"."+o2.index,y2=Ur(),m2=y2.animate,k2=y2.config,b2=Fr(r2),C2=useSpring({color:l2,opacity:a2,config:k2,immediate:!m2}),x2=k$2(),w2=x2.showTooltipFromEvent,B2=x2.hideTooltip,I2=reactExports.useCallback((function(e4){h2(o2),w2(reactExports.createElement(v2,{link:o2}),e4,"left")}),[h2,o2,w2,v2]),W2=reactExports.useCallback((function(e4){w2(reactExports.createElement(v2,{link:o2}),e4,"left")}),[w2,o2,v2]),N2=reactExports.useCallback((function(){h2(null),B2()}),[h2,B2]),F2=reactExports.useCallback((function(e4){g2?.(o2,e4)}),[g2,o2]);return jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment,{children:[u2&&jsxRuntimeExports.jsx(U,{id:f2,layout:i2,startColor:o2.startColor||o2.source.color,endColor:o2.endColor||o2.target.color}),jsxRuntimeExports.jsx(animated.path,{fill:u2?'url("#'+encodeURI(f2)+'")':C2.color,d:b2,fillOpacity:C2.opacity,onMouseEnter:p2?I2:void 0,onMouseMove:p2?W2:void 0,onMouseLeave:p2?N2:void 0,onClick:p2?F2:void 0,style:{mixBlendMode:d}})]})},"J"),K=__name(function(e3){var n2=e3.links,t2=e3.layout,i2=e3.linkOpacity,r2=e3.linkHoverOpacity,l2=e3.linkHoverOthersOpacity,a2=e3.linkContract,d=e3.linkBlendMode,c2=e3.enableLinkGradient,s2=e3.setCurrentLink,u2=e3.currentLink,h2=e3.currentNode,v2=e3.isCurrentLink,p2=e3.isInteractive,g2=e3.onClick,f2=e3.tooltip,y2=__name(function(e4){return h2||u2?v2(e4)?r2:l2:i2},"y"),m2=reactExports.useMemo((function(){return t2==="horizontal"?(e4=N$2().curve(monotoneX),function(o2,n3){var t3=Math.max(1,o2.thickness-2*n3)/2,i3=.12*(o2.target.x0-o2.source.x1),r3=[[o2.source.x1,o2.pos0-t3],[o2.source.x1+i3,o2.pos0-t3],[o2.target.x0-i3,o2.pos1-t3],[o2.target.x0,o2.pos1-t3],[o2.target.x0,o2.pos1+t3],[o2.target.x0-i3,o2.pos1+t3],[o2.source.x1+i3,o2.pos0+t3],[o2.source.x1,o2.pos0+t3],[o2.source.x1,o2.pos0-t3]];return e4(r3)+"Z"}):(function(){var e6=N$2().curve(monotoneY);return function(o2,n3){var t3=Math.max(1,o2.thickness-2*n3)/2,i3=.12*(o2.target.y0-o2.source.y1),r3=[[o2.pos0+t3,o2.source.y1],[o2.pos0+t3,o2.source.y1+i3],[o2.pos1+t3,o2.target.y0-i3],[o2.pos1+t3,o2.target.y0],[o2.pos1-t3,o2.target.y0],[o2.pos1-t3,o2.target.y0-i3],[o2.pos0-t3,o2.source.y1+i3],[o2.pos0-t3,o2.source.y1],[o2.pos0+t3,o2.source.y1]];return e6(r3)+"Z"}})();var e4}),[t2]);return jsxRuntimeExports.jsx(jsxRuntimeExports.Fragment,{children:n2.map((function(e4){return jsxRuntimeExports.jsx(J,{link:e4,layout:t2,path:m2(e4,a2),color:e4.color,opacity:y2(e4),blendMode:d,enableGradient:c2,setCurrent:s2,isInteractive:p2,onClick:g2,tooltip:f2},e4.source.id+"."+e4.target.id+"."+e4.index)}))})},"K"),Q=__name(function(e3){var o2=e3.nodes,n2=e3.layout,t2=e3.width,i2=e3.height,r2=e3.labelPosition,a2=e3.labelPadding,d=e3.labelOrientation,s2=e3.getLabelTextColor,u2=zt(),h2=d==="vertical"?-90:0,v2=o2.map((function(e4){var o3,l2,c2;return n2==="horizontal"?(l2=e4.y+e4.height/2,e4.x=0||(i3[n3]=e4[n3]);return i3})(e3,X);return jsxRuntimeExports.jsx(St,{animate:i2,isInteractive:n2,motionConfig:l2,renderWrapper:d,theme:a2,children:jsxRuntimeExports.jsx(Y,S$1({isInteractive:n2},c2))})},"$$1"),_$1=__name(function(e3){return jsxRuntimeExports.jsx(It,{children:__name(function(o2){var n2=o2.width,t2=o2.height;return jsxRuntimeExports.jsx($$1,S$1({width:n2,height:t2},e3))},"children")})},"_$1");const ZtResponsiveSankey=__name(({isDark,data})=>{const connectedNodeIds=new Set;for(const link2 of data.links)connectedNodeIds.add(link2.source),connectedNodeIds.add(link2.target);const filteredData={nodes:data.nodes.filter(node2=>connectedNodeIds.has(node2.id)),links:data.links},theme={tooltip:{container:{background:isDark?"rgba(33, 33, 33, 0.95)":"rgba(255, 255, 255, 0.95)",color:isDark?"#ffffff":"#000000",border:isDark?"1px solid #555":"1px solid #ccc",borderRadius:"4px",boxShadow:"0 2px 8px rgba(0, 0, 0, 0.15)",fontSize:"12px",padding:"8px 12px"}},labels:{text:{fontSize:12}}};return jsxRuntimeExports.jsx("div",{className:`h-full w-full ${isDark?"sankey-dark-mode":"sankey-light-mode"}`,children:jsxRuntimeExports.jsx(_$1,{data:filteredData,theme,margin:{top:10,right:10,bottom:10,left:10},align:"justify",colors:__name(node2=>node2.nodeColor,"colors"),nodeOpacity:1,nodeHoverOthersOpacity:.35,nodeThickness:18,nodeSpacing:24,nodeBorderWidth:0,nodeBorderColor:{from:"color",modifiers:[["darker",.8]]},nodeBorderRadius:3,linkOpacity:.5,linkHoverOthersOpacity:.1,linkContract:3,linkBlendMode:isDark?"lighten":"multiply",enableLinkGradient:!0,labelPosition:"inside",labelOrientation:"horizontal",labelPadding:16,labelTextColor:isDark?"#ffffff":"#000000",sort:"input",legends:[],valueFormat:__name(value2=>`${value2}`,"valueFormat")})})},"ZtResponsiveSankey"),CaSankey=__name(({data})=>{const theme=reactExports.useContext(ThemeProviderContext),filteredData=data.filter(link2=>link2.value!=null&&link2.value>0);return jsxRuntimeExports.jsx(ZtResponsiveSankey,{isDark:!!(theme.theme==="dark"||theme.theme==="system"&&window.matchMedia("(prefers-color-scheme: dark)").matches),data:{nodes:[{id:"User sign in",nodeColor:"hsl(28, 100%, 53%)"},{id:"No CA applied",nodeColor:"hsl(0, 100%, 50%)"},{id:"CA applied",nodeColor:"hsl(12, 76%, 61%)"},{id:"No MFA",nodeColor:"hsl(0, 69%, 50%)"},{id:"MFA",nodeColor:"hsl(99, 70%, 50%)"}],links:filteredData}})},"CaSankey"),CaDeviceSankey=__name(({data})=>{const theme=reactExports.useContext(ThemeProviderContext),filteredData=data.filter(link2=>link2.value!=null&&link2.value>0);return jsxRuntimeExports.jsx(ZtResponsiveSankey,{isDark:!!(theme.theme==="dark"||theme.theme==="system"&&window.matchMedia("(prefers-color-scheme: dark)").matches),data:{nodes:[{id:"User sign in",nodeColor:"hsl(28, 100%, 53%)"},{id:"Unmanaged",nodeColor:"hsl(0, 100%, 50%)"},{id:"Managed",nodeColor:"hsl(12, 76%, 61%)"},{id:"Non-compliant",nodeColor:"hsl(0, 100%, 50%)"},{id:"Compliant",nodeColor:"hsl(99, 70%, 50%)"}],links:filteredData}})},"CaDeviceSankey"),AuthMethodSankey=__name(({data})=>{const theme=reactExports.useContext(ThemeProviderContext),filteredData=data.filter(link2=>link2.value!=null&&link2.value>0);return jsxRuntimeExports.jsx(ZtResponsiveSankey,{isDark:!!(theme.theme==="dark"||theme.theme==="system"&&window.matchMedia("(prefers-color-scheme: dark)").matches),data:{nodes:[{id:"Users",nodeColor:"hsl(28, 100%, 53%)"},{id:"Single factor",nodeColor:"hsl(0, 100%, 50%)"},{id:"Phishable",nodeColor:"hsl(12, 76%, 61%)"},{id:"Phone",nodeColor:"hsl(12, 76%, 61%)"},{id:"Authenticator",nodeColor:"hsl(12, 76%, 61%)"},{id:"Phish resistant",nodeColor:"hsl(99, 70%, 50%)"},{id:"Passkey",nodeColor:"hsl(99, 70%, 50%)"},{id:"WHfB",nodeColor:"hsl(99, 70%, 50%)"}],links:filteredData}})},"AuthMethodSankey"),DesktopDevicesSankey=__name(({data})=>{const theme=reactExports.useContext(ThemeProviderContext),filteredData=data.filter(link2=>link2.value!=null&&link2.value>0);return jsxRuntimeExports.jsx(ZtResponsiveSankey,{isDark:!!(theme.theme==="dark"||theme.theme==="system"&&window.matchMedia("(prefers-color-scheme: dark)").matches),data:{nodes:[{id:"Desktop devices",nodeColor:"hsl(28, 100%, 53%)"},{id:"Windows",nodeColor:"hsl(35, 100%, 50%)"},{id:"macOS",nodeColor:"hsl(200, 100%, 50%)"},{id:"Entra joined",nodeColor:"hsl(12, 76%, 61%)"},{id:"Entra registered",nodeColor:"hsl(12, 76%, 61%)"},{id:"Entra hybrid joined",nodeColor:"hsl(12, 76%, 61%)"},{id:"Compliant",nodeColor:"hsl(99, 70%, 50%)"},{id:"Non-compliant",nodeColor:"hsl(0, 100%, 50%)"},{id:"Unmanaged",nodeColor:"hsl(220, 10%, 60%)"}],links:filteredData}})},"DesktopDevicesSankey"),MobileSankey=__name(({data})=>{const theme=reactExports.useContext(ThemeProviderContext),filteredData=data.filter(link2=>link2.value!=null&&link2.value>0);return jsxRuntimeExports.jsx(ZtResponsiveSankey,{isDark:!!(theme.theme==="dark"||theme.theme==="system"&&window.matchMedia("(prefers-color-scheme: dark)").matches),data:{nodes:[{id:"Mobile devices",nodeColor:"hsl(28, 100%, 53%)"},{id:"Android",nodeColor:"hsl(35, 100%, 50%)"},{id:"iOS",nodeColor:"hsl(210, 100%, 50%)"},{id:"Android (Company)",nodeColor:"hsl(30, 100%, 45%)"},{id:"Android (Personal)",nodeColor:"hsl(40, 100%, 55%)"},{id:"iOS (Company)",nodeColor:"hsl(210, 100%, 45%)"},{id:"iOS (Personal)",nodeColor:"hsl(210, 100%, 55%)"},{id:"Compliant",nodeColor:"hsl(99, 70%, 50%)"},{id:"Non-compliant",nodeColor:"hsl(0, 100%, 50%)"}],links:filteredData}})},"MobileSankey"),badgeVariants=cva("inline-flex items-center rounded-full border px-2.5 py-0.5 text-xs font-semibold transition-colors focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2",{variants:{variant:{default:"border-transparent bg-primary text-primary-foreground hover:bg-primary/80",secondary:"border-transparent bg-secondary text-secondary-foreground hover:bg-secondary/80",destructive:"border-transparent bg-destructive text-destructive-foreground hover:bg-destructive/80",outline:"text-foreground",warning:"border-transparent bg-amber-100 text-amber-800 hover:bg-amber-200 dark:bg-amber-900 dark:text-amber-200",success:"border-transparent bg-green-600 text-white hover:bg-green-700 dark:bg-green-700 dark:text-green-100"}},defaultVariants:{variant:"default"}});function Badge({className,variant,...props}){return jsxRuntimeExports.jsx("div",{className:cn$2(badgeVariants({variant}),className),...props})}__name(Badge,"Badge");const DEFENSE_LAYERS=[{id:1,name:"Context-aware network security",shortName:`Context-aware +network security`,specIds:["25406","25407","25410"]},{id:2,name:"TLS inspection, WCF, & TI filtering",shortName:`Web content and +threat intelligence filtering`,specIds:["25411","27001","27002","27003","27004","25408","25409","27000","25412"]},{id:3,name:"AI Gateway, content filtering & DLP",shortName:`Content filtering +and network DLP`,specIds:["25415","25413"]},{id:4,name:"Cloud firewall",shortName:`Cloud +firewall`,specIds:["25416"]},{id:5,name:"Advanced threat protection",shortName:`Advanced threat +protection`,specIds:[]}];function getLayerStatus(layer){if(layer.specIds.length===0)return{layer,status:"na",passed:0,failed:0,total:0,tests:[]};const matchedTests=layer.specIds.map(id=>reportData.Tests.find(t2=>t2.TestId===id)).filter(t2=>t2!==void 0);if(matchedTests.length===0)return{layer,status:"na",passed:0,failed:0,total:layer.specIds.length,tests:[]};const total=layer.specIds.length,passed=matchedTests.filter(t2=>t2.TestStatus==="Passed").length,skipped=matchedTests.filter(t2=>t2.TestStatus==="Skipped"||t2.TestStatus==="Planned").length,failed=matchedTests.length-passed-skipped;if(passed===0&&failed===0)return{layer,status:"na",passed,failed,total,tests:matchedTests};let status;return failed===0?status="pass":passed===0?status="fail":status="partial",{layer,status,passed,failed,total,tests:matchedTests}}__name(getLayerStatus,"getLayerStatus");const STATUS_FILLS={pass:["#1a7a30","#28a044","#38c05c","#50d878","#78e8a0"],partial:["#b07800","#cc9010","#e0a828","#f0c048","#f8d878"],fail:["#a01818","#c02424","#d83838","#e85050","#f07070"],na:["#606068","#787880","#909098","#a8a8b0","#c0c0c8"]};function getStatusLabel(status){switch(status){case"pass":return"Pass";case"partial":return"Partial";case"fail":return"Fail";case"na":return"N/A"}}__name(getStatusLabel,"getStatusLabel");function getStatusBadgeVariant(status){switch(status){case"pass":return"success";case"partial":return"warning";case"fail":return"destructive";default:return"secondary"}}__name(getStatusBadgeVariant,"getStatusBadgeVariant");function getTestStatusIcon(testStatus){switch(testStatus){case"Passed":return jsxRuntimeExports.jsx(CheckCircledIcon,{className:"text-teal-600 size-4"});case"Failed":case"Error":return jsxRuntimeExports.jsx(CrossCircledIcon,{className:"text-rose-500/80 size-4"});default:return jsxRuntimeExports.jsx(QuestionMarkCircledIcon,{className:"text-amber-500/80 size-4"})}}__name(getTestStatusIcon,"getTestStatusIcon");function isForwardingProfileFailed(results){const layer1=results.find(r2=>r2.layer.id===1);if(!layer1)return!1;const forwardingTest=layer1.tests.find(t2=>t2.TestId==="25406");return forwardingTest!==void 0&&(forwardingTest.TestStatus==="Failed"||forwardingTest.TestStatus==="Error")}__name(isForwardingProfileFailed,"isForwardingProfileFailed");function hasSwgData(){const allSpecIds=DEFENSE_LAYERS.flatMap(l2=>l2.specIds);return reportData.Tests.some(t2=>allSpecIds.includes(t2.TestId))}__name(hasSwgData,"hasSwgData");function SwgDefenseLayers(){const[hoveredLayer,setHoveredLayer]=reactExports.useState(null),layerResults=reactExports.useMemo(()=>DEFENSE_LAYERS.map(layer=>getLayerStatus(layer)),[]);if(!hasSwgData())return null;const forwardingFailed=isForwardingProfileFailed(layerResults),activeLayers=layerResults.filter(r2=>r2.layer.specIds.length>0),failingLayers=activeLayers.filter(r2=>r2.status==="fail"||r2.status==="partial"),allNotExecuted=activeLayers.length>0&&activeLayers.every(r2=>r2.status==="na"),overallPass=!allNotExecuted&&failingLayers.length===0&&activeLayers.some(r2=>r2.status==="pass"),centerX=210,centerY=220,layerDims=[{rx:195,ry:195,dy:0},{rx:158,ry:155,dy:14},{rx:122,ry:118,dy:26},{rx:88,ry:84,dy:36},{rx:58,ry:55,dy:44}];return jsxRuntimeExports.jsx("div",{className:"flex flex-col gap-4",children:jsxRuntimeExports.jsxs("div",{className:"flex flex-col lg:flex-row gap-6 items-center",children:[jsxRuntimeExports.jsx("div",{className:"flex-shrink-0",children:jsxRuntimeExports.jsxs("svg",{width:"420",height:"440",viewBox:"0 0 420 440",className:"max-w-full h-auto",children:[layerDims.map((dims,i2)=>{const result=layerResults[i2],isHovered=hoveredLayer===i2,fill=STATUS_FILLS[result.status][i2],cy=centerY+dims.dy,lines=result.layer.shortName.split(` +`),thisTop=centerY+dims.dy-dims.ry,bandHeight=(i2setHoveredLayer(i2),"onMouseEnter"),onMouseLeave:__name(()=>setHoveredLayer(null),"onMouseLeave"),className:"cursor-pointer",opacity:hoveredLayer!==null&&hoveredLayer!==i2?.65:1,children:[jsxRuntimeExports.jsx("ellipse",{cx:centerX,cy,rx:dims.rx,ry:dims.ry,fill,stroke:isHovered?"#ffffff":"rgba(255,255,255,0.25)",strokeWidth:isHovered?3:1.5}),lines.map((line,lineIdx)=>jsxRuntimeExports.jsx("text",{x:centerX,y:firstLineY+lineIdx*lineHeight,textAnchor:"middle",fill:i2===layerDims.length-1?"#52525b":"#ffffff",fontSize,fontWeight:"600",children:line},lineIdx))]},i2)}),forwardingFailed&&jsxRuntimeExports.jsx("text",{x:centerX,y:435,textAnchor:"middle",fill:"#946471",fontSize:"11",fontWeight:"600",children:"⚠ Forwarding profile disabled — all layers effectively inactive"})]})}),jsxRuntimeExports.jsx("div",{className:"flex-1 w-full min-w-0",children:jsxRuntimeExports.jsxs("div",{className:"space-y-1",children:[jsxRuntimeExports.jsx("div",{className:"flex items-center gap-2 mb-3",children:allNotExecuted?jsxRuntimeExports.jsx(Badge,{variant:"secondary",children:"No layer results available — checks not yet executed"}):overallPass?jsxRuntimeExports.jsx(Badge,{variant:"success",children:"All layers passing"}):jsxRuntimeExports.jsxs(Badge,{variant:"destructive",children:[failingLayers.length," of ",activeLayers.length," active layers have issues"]})}),jsxRuntimeExports.jsx(Accordion,{type:"multiple",className:"w-full",children:layerResults.map(result=>jsxRuntimeExports.jsxs(AccordionItem,{value:`layer-${result.layer.id}`,className:"border rounded-md mb-1 px-3",children:[jsxRuntimeExports.jsx(AccordionTrigger,{className:"py-2 hover:no-underline",children:jsxRuntimeExports.jsxs("div",{className:"flex items-center gap-3 w-full",children:[jsxRuntimeExports.jsx("span",{className:"text-xs font-mono text-muted-foreground w-4",children:result.layer.id}),jsxRuntimeExports.jsx("span",{className:"text-sm font-medium flex-1 text-left",children:result.layer.name}),jsxRuntimeExports.jsx(Badge,{variant:getStatusBadgeVariant(result.status),className:"mr-2",children:getStatusLabel(result.status)}),jsxRuntimeExports.jsxs("span",{className:"text-xs text-muted-foreground tabular-nums whitespace-nowrap",children:[result.passed,"/",result.total]})]})}),jsxRuntimeExports.jsxs(AccordionContent,{children:[result.tests.length===0?jsxRuntimeExports.jsx("p",{className:"text-xs text-muted-foreground italic py-1",children:"No test data available for this layer."}):jsxRuntimeExports.jsx("div",{className:"space-y-1 py-1",children:result.tests.map(test=>jsxRuntimeExports.jsxs("div",{className:"flex items-center gap-2 text-xs py-0.5",children:[getTestStatusIcon(test.TestStatus),jsxRuntimeExports.jsx("span",{className:"text-muted-foreground font-mono",children:test.TestId}),jsxRuntimeExports.jsx("span",{className:"flex-1 truncate",children:test.TestTitle})]},test.TestId))}),forwardingFailed&&result.layer.id>1&&jsxRuntimeExports.jsx("p",{className:"text-xs text-rose-500/80 mt-1",children:"⚠ This layer is effectively inactive because the Internet Access forwarding profile (25406) is not enabled."})]})]},result.layer.id))})]})})]})})}__name(SwgDefenseLayers,"SwgDefenseLayers");var NODES=["a","button","div","form","h2","h3","img","input","label","li","nav","ol","p","select","span","svg","ul"],Primitive=NODES.reduce((primitive,node2)=>{const Slot2=createSlot$2(`Primitive.${node2}`),Node2=reactExports.forwardRef((props,forwardedRef)=>{const{asChild,...primitiveProps}=props,Comp=asChild?Slot2:node2;return typeof window<"u"&&(window[Symbol.for("radix-ui")]=!0),jsxRuntimeExports.jsx(Comp,{...primitiveProps,ref:forwardedRef})});return Node2.displayName=`Primitive.${node2}`,{...primitive,[node2]:Node2}},{}),NAME="Separator",DEFAULT_ORIENTATION="horizontal",ORIENTATIONS=["horizontal","vertical"],Separator$1=reactExports.forwardRef((props,forwardedRef)=>{const{decorative,orientation:orientationProp=DEFAULT_ORIENTATION,...domProps}=props,orientation=isValidOrientation(orientationProp)?orientationProp:DEFAULT_ORIENTATION,semanticProps=decorative?{role:"none"}:{"aria-orientation":orientation==="vertical"?orientation:void 0,role:"separator"};return jsxRuntimeExports.jsx(Primitive.div,{"data-orientation":orientation,...semanticProps,...domProps,ref:forwardedRef})});Separator$1.displayName=NAME;function isValidOrientation(orientation){return ORIENTATIONS.includes(orientation)}__name(isValidOrientation,"isValidOrientation");var Root=Separator$1;const Separator=reactExports.forwardRef(({className,orientation="horizontal",decorative=!0,...props},ref)=>jsxRuntimeExports.jsx(Root,{ref,decorative,orientation,className:cn$2("shrink-0 bg-border",orientation==="horizontal"?"h-[1px] w-full":"h-full w-[1px]",className),...props}));Separator.displayName=Root.displayName;function formatNumber(value2){return value2==null||isNaN(value2)?"0":value2<1e3?value2.toLocaleString():value2<1e5?`${(value2/1e3).toFixed(1)}K`:`${Math.round(value2/1e3)}K`}__name(formatNumber,"formatNumber");const metricDescriptions={users:"Total number of user accounts in the tenant (excluding guests)",guests:"Total number of guest user accounts",groups:"Total number of groups (security, Microsoft 365, etc.)",apps:"Total number of registered applications",devices:"Including both managed and unmanaged devices",managed:"Total number of Intune managed devices"};function Dashboard(){return jsxRuntimeExports.jsxs(TooltipProvider,{delayDuration:200,children:[jsxRuntimeExports.jsx("div",{className:"w-full flex max-w-7xl flex-col gap-6 mt-12",children:jsxRuntimeExports.jsxs("div",{className:"grid w-full gap-6 lg:grid-cols-3",children:[jsxRuntimeExports.jsxs(Card,{children:[jsxRuntimeExports.jsx(CardHeader,{className:"pb-3",children:jsxRuntimeExports.jsxs(CardTitle,{className:"flex items-center gap-2",children:[jsxRuntimeExports.jsx(Building2,{className:"size-5"}),"Tenant"]})}),jsxRuntimeExports.jsx(CardContent,{children:jsxRuntimeExports.jsxs("div",{className:"space-y-4",children:[jsxRuntimeExports.jsxs("div",{className:"flex flex-col gap-1",children:[jsxRuntimeExports.jsx("span",{className:"text-sm text-muted-foreground",children:"Name"}),jsxRuntimeExports.jsx("span",{className:"font-medium",children:reportData.TenantName})]}),jsxRuntimeExports.jsxs("div",{className:"flex flex-col gap-1",children:[jsxRuntimeExports.jsx("span",{className:"text-sm text-muted-foreground",children:"Tenant ID"}),jsxRuntimeExports.jsx("span",{className:"font-mono text-xs",children:reportData.TenantId})]}),jsxRuntimeExports.jsxs("div",{className:"flex flex-col gap-1",children:[jsxRuntimeExports.jsx("span",{className:"text-sm text-muted-foreground",children:"Primary Domain"}),jsxRuntimeExports.jsx("span",{className:"font-medium",children:reportData.Domain})]})]})})]}),jsxRuntimeExports.jsxs("div",{className:"grid gap-4 grid-cols-2 grid-rows-3",children:[jsxRuntimeExports.jsxs(Tooltip,{children:[jsxRuntimeExports.jsx(TooltipTrigger,{asChild:!0,children:jsxRuntimeExports.jsxs("div",{className:"flex items-center gap-3 rounded-md border px-4 py-3",children:[jsxRuntimeExports.jsx(Avatar,{className:"size-8.5 rounded-sm",children:jsxRuntimeExports.jsx(AvatarFallback,{className:"text-blue-600 shrink-0 rounded-sm",children:jsxRuntimeExports.jsx(User,{className:"size-8"})})}),jsxRuntimeExports.jsxs("div",{className:"flex flex-col gap-0.5",children:[jsxRuntimeExports.jsx("span",{className:"text-muted-foreground text-sm font-medium",children:"Users"}),jsxRuntimeExports.jsx("span",{className:"text-lg font-medium",children:formatNumber(reportData.TenantInfo?.TenantOverview?.UserCount)})]})]})}),jsxRuntimeExports.jsx(TooltipContent,{children:jsxRuntimeExports.jsxs("div",{className:"space-y-1",children:[jsxRuntimeExports.jsxs("p",{className:"font-semibold",children:[reportData.TenantInfo?.TenantOverview?.UserCount?.toLocaleString()||"0"," Users"]}),jsxRuntimeExports.jsx("p",{className:"text-xs text-muted-foreground",children:metricDescriptions.users})]})})]}),jsxRuntimeExports.jsxs(Tooltip,{children:[jsxRuntimeExports.jsx(TooltipTrigger,{asChild:!0,children:jsxRuntimeExports.jsxs("div",{className:"flex items-center gap-3 rounded-md border px-4 py-3",children:[jsxRuntimeExports.jsx(Avatar,{className:"size-8.5 rounded-sm",children:jsxRuntimeExports.jsx(AvatarFallback,{className:"text-indigo-600 shrink-0 rounded-sm",children:jsxRuntimeExports.jsx(Luggage,{className:"size-8"})})}),jsxRuntimeExports.jsxs("div",{className:"flex flex-col gap-0.5",children:[jsxRuntimeExports.jsx("span",{className:"text-muted-foreground text-sm font-medium",children:"Guests"}),jsxRuntimeExports.jsx("span",{className:"text-lg font-medium",children:formatNumber(reportData.TenantInfo?.TenantOverview?.GuestCount)})]})]})}),jsxRuntimeExports.jsx(TooltipContent,{children:jsxRuntimeExports.jsxs("div",{className:"space-y-1",children:[jsxRuntimeExports.jsxs("p",{className:"font-semibold",children:[reportData.TenantInfo?.TenantOverview?.GuestCount?.toLocaleString()||"0"," Guests"]}),jsxRuntimeExports.jsx("p",{className:"text-xs text-muted-foreground",children:metricDescriptions.guests})]})})]}),jsxRuntimeExports.jsxs(Tooltip,{children:[jsxRuntimeExports.jsx(TooltipTrigger,{asChild:!0,children:jsxRuntimeExports.jsxs("div",{className:"flex items-center gap-3 rounded-md border px-4 py-3",children:[jsxRuntimeExports.jsx(Avatar,{className:"size-8.5 rounded-sm",children:jsxRuntimeExports.jsx(AvatarFallback,{className:"text-purple-600 shrink-0 rounded-sm",children:jsxRuntimeExports.jsx(Users,{className:"size-8"})})}),jsxRuntimeExports.jsxs("div",{className:"flex flex-col gap-0.5",children:[jsxRuntimeExports.jsx("span",{className:"text-muted-foreground text-sm font-medium",children:"Groups"}),jsxRuntimeExports.jsx("span",{className:"text-lg font-medium",children:formatNumber(reportData.TenantInfo?.TenantOverview?.GroupCount)})]})]})}),jsxRuntimeExports.jsx(TooltipContent,{children:jsxRuntimeExports.jsxs("div",{className:"space-y-1",children:[jsxRuntimeExports.jsxs("p",{className:"font-semibold",children:[reportData.TenantInfo?.TenantOverview?.GroupCount?.toLocaleString()||"0"," Groups"]}),jsxRuntimeExports.jsx("p",{className:"text-xs text-muted-foreground",children:metricDescriptions.groups})]})})]}),jsxRuntimeExports.jsxs(Tooltip,{children:[jsxRuntimeExports.jsx(TooltipTrigger,{asChild:!0,children:jsxRuntimeExports.jsxs("div",{className:"flex items-center gap-3 rounded-md border px-4 py-3",children:[jsxRuntimeExports.jsx(Avatar,{className:"size-8.5 rounded-sm",children:jsxRuntimeExports.jsx(AvatarFallback,{className:"text-rose-600 shrink-0 rounded-sm",children:jsxRuntimeExports.jsx(Layers3,{className:"size-8"})})}),jsxRuntimeExports.jsxs("div",{className:"flex flex-col gap-0.5",children:[jsxRuntimeExports.jsx("span",{className:"text-muted-foreground text-sm font-medium",children:"Apps"}),jsxRuntimeExports.jsx("span",{className:"text-lg font-medium",children:formatNumber(reportData.TenantInfo?.TenantOverview?.ApplicationCount)})]})]})}),jsxRuntimeExports.jsx(TooltipContent,{children:jsxRuntimeExports.jsxs("div",{className:"space-y-1",children:[jsxRuntimeExports.jsxs("p",{className:"font-semibold",children:[reportData.TenantInfo?.TenantOverview?.ApplicationCount?.toLocaleString()||"0"," Applications"]}),jsxRuntimeExports.jsx("p",{className:"text-xs text-muted-foreground",children:metricDescriptions.apps})]})})]}),jsxRuntimeExports.jsxs(Tooltip,{children:[jsxRuntimeExports.jsx(TooltipTrigger,{asChild:!0,children:jsxRuntimeExports.jsxs("div",{className:"flex items-center gap-3 rounded-md border px-4 py-3",children:[jsxRuntimeExports.jsx(Avatar,{className:"size-8.5 rounded-sm",children:jsxRuntimeExports.jsx(AvatarFallback,{className:"text-orange-600 shrink-0 rounded-sm",children:jsxRuntimeExports.jsx(MonitorSmartphone,{className:"size-8"})})}),jsxRuntimeExports.jsxs("div",{className:"flex flex-col gap-0.5",children:[jsxRuntimeExports.jsx("span",{className:"text-muted-foreground text-sm font-medium",children:"Devices"}),jsxRuntimeExports.jsx("span",{className:"text-lg font-medium",children:formatNumber(reportData.TenantInfo?.TenantOverview?.DeviceCount)})]})]})}),jsxRuntimeExports.jsx(TooltipContent,{children:jsxRuntimeExports.jsxs("div",{className:"space-y-1",children:[jsxRuntimeExports.jsxs("p",{className:"font-semibold",children:[reportData.TenantInfo?.TenantOverview?.DeviceCount?.toLocaleString()||"0"," Devices"]}),jsxRuntimeExports.jsx("p",{className:"text-xs text-muted-foreground",children:metricDescriptions.devices})]})})]}),jsxRuntimeExports.jsxs(Tooltip,{children:[jsxRuntimeExports.jsx(TooltipTrigger,{asChild:!0,children:jsxRuntimeExports.jsxs("div",{className:"flex items-center gap-3 rounded-md border px-4 py-3",children:[jsxRuntimeExports.jsx(Avatar,{className:"size-8.5 rounded-sm",children:jsxRuntimeExports.jsx(AvatarFallback,{className:"text-emerald-600 shrink-0 rounded-sm",children:jsxRuntimeExports.jsx(MonitorSmartphone,{className:"size-8"})})}),jsxRuntimeExports.jsxs("div",{className:"flex flex-col gap-0.5",children:[jsxRuntimeExports.jsx("span",{className:"text-muted-foreground text-sm font-medium",children:"Managed"}),jsxRuntimeExports.jsx("span",{className:"text-lg font-medium",children:formatNumber(reportData.TenantInfo?.TenantOverview?.ManagedDeviceCount)})]})]})}),jsxRuntimeExports.jsx(TooltipContent,{children:jsxRuntimeExports.jsxs("div",{className:"space-y-1",children:[jsxRuntimeExports.jsxs("p",{className:"font-semibold",children:[reportData.TenantInfo?.TenantOverview?.ManagedDeviceCount?.toLocaleString()||"0"," Managed Devices"]}),jsxRuntimeExports.jsx("p",{className:"text-xs text-muted-foreground",children:metricDescriptions.managed})]})})]})]}),jsxRuntimeExports.jsxs(Card,{"x-chunk":"charts-01-chunk-5",children:[jsxRuntimeExports.jsx(CardHeader,{className:"pb-3",children:jsxRuntimeExports.jsxs(CardTitle,{className:"flex items-center gap-2",children:[jsxRuntimeExports.jsx(ShieldCheck,{className:"size-5"}),"Assessment"]})}),jsxRuntimeExports.jsxs(CardContent,{className:"flex gap-6",children:[jsxRuntimeExports.jsxs("div",{className:"flex flex-col gap-2",children:[jsxRuntimeExports.jsxs("div",{className:"grid auto-rows-min gap-0.5",children:[jsxRuntimeExports.jsx("div",{className:"text-sm text-muted-foreground",children:"Identity"}),jsxRuntimeExports.jsxs("div",{className:"flex items-baseline gap-1 text-xl font-bold tabular-nums leading-none",children:[reportData.TestResultSummary.IdentityPassed,"/",reportData.TestResultSummary.IdentityTotal,jsxRuntimeExports.jsx("span",{className:"text-sm font-normal text-muted-foreground",children:"tests"})]})]}),jsxRuntimeExports.jsxs("div",{className:"grid auto-rows-min gap-0.5",children:[jsxRuntimeExports.jsx("div",{className:"text-sm text-muted-foreground",children:"Devices"}),jsxRuntimeExports.jsxs("div",{className:"flex items-baseline gap-1 text-xl font-bold tabular-nums leading-none",children:[reportData.TestResultSummary.DevicesPassed,"/",reportData.TestResultSummary.DevicesTotal,jsxRuntimeExports.jsx("span",{className:"text-sm font-normal text-muted-foreground",children:"tests"})]})]}),jsxRuntimeExports.jsxs("div",{className:"grid flex-1 auto-rows-min gap-0.5",children:[jsxRuntimeExports.jsx("div",{className:"text-sm text-muted-foreground",children:"Data"}),jsxRuntimeExports.jsxs("div",{className:"flex items-baseline gap-1 text-xl font-bold tabular-nums leading-none",children:[reportData.TestResultSummary.DataPassed,"/",reportData.TestResultSummary.DataTotal,jsxRuntimeExports.jsx("span",{className:"text-sm font-normal text-muted-foreground",children:"tests"})]})]}),reportData.TestResultSummary.NetworkPassed!==void 0&&jsxRuntimeExports.jsxs("div",{className:"grid flex-1 auto-rows-min gap-0.5",children:[jsxRuntimeExports.jsx("div",{className:"text-sm text-muted-foreground",children:"Network"}),jsxRuntimeExports.jsxs("div",{className:"flex items-baseline gap-1 text-xl font-bold tabular-nums leading-none",children:[reportData.TestResultSummary.NetworkPassed,"/",reportData.TestResultSummary.NetworkTotal,jsxRuntimeExports.jsx("span",{className:"text-sm font-normal text-muted-foreground",children:"tests"})]})]}),reportData.TestResultSummary.InfrastructurePassed!==void 0&&jsxRuntimeExports.jsxs("div",{className:"grid flex-1 auto-rows-min gap-0.5",children:[jsxRuntimeExports.jsx("div",{className:"text-sm text-muted-foreground",children:"Infrastructure"}),jsxRuntimeExports.jsxs("div",{className:"flex items-baseline gap-1 text-xl font-bold tabular-nums leading-none",children:[reportData.TestResultSummary.InfrastructurePassed,"/",reportData.TestResultSummary.InfrastructureTotal,jsxRuntimeExports.jsx("span",{className:"text-sm font-normal text-muted-foreground",children:"tests"})]})]}),reportData.TestResultSummary.SecOpsPassed!==void 0&&jsxRuntimeExports.jsxs("div",{className:"grid flex-1 auto-rows-min gap-0.5",children:[jsxRuntimeExports.jsx("div",{className:"text-sm text-muted-foreground",children:"SecOps"}),jsxRuntimeExports.jsxs("div",{className:"flex items-baseline gap-1 text-xl font-bold tabular-nums leading-none",children:[reportData.TestResultSummary.SecOpsPassed,"/",reportData.TestResultSummary.SecOpsTotal,jsxRuntimeExports.jsx("span",{className:"text-sm font-normal text-muted-foreground",children:"tests"})]})]}),reportData.TestResultSummary.AIPassed!==void 0&&jsxRuntimeExports.jsxs("div",{className:"grid flex-1 auto-rows-min gap-0.5",children:[jsxRuntimeExports.jsx("div",{className:"text-sm text-muted-foreground",children:"AI"}),jsxRuntimeExports.jsxs("div",{className:"flex items-baseline gap-1 text-xl font-bold tabular-nums leading-none",children:[reportData.TestResultSummary.AIPassed,"/",reportData.TestResultSummary.AITotal,jsxRuntimeExports.jsx("span",{className:"text-sm font-normal text-muted-foreground",children:"tests"})]})]})]}),jsxRuntimeExports.jsx(ChartContainer,{config:{move:{label:"Identity",color:"hsl(var(--chart-1))"},exercise:{label:"Devices",color:"hsl(var(--chart-2))"},stand:{label:"Data",color:"hsl(var(--chart-3))"},network:{label:"Network",color:"hsl(var(--chart-4))"},infrastructure:{label:"Infrastructure",color:"hsl(var(--chart-5))"},secops:{label:"SecOps",color:"hsl(var(--chart-1))"},ai:{label:"AI",color:"hsl(var(--chart-2))"}},className:"mx-auto aspect-square w-full max-w-[80%]",children:jsxRuntimeExports.jsxs(RadialBarChart,{margin:{left:-10,right:-10,top:-10,bottom:-10},data:[...reportData.TestResultSummary.AIPassed!==void 0&&reportData.TestResultSummary.AITotal!==void 0?[{activity:"ai",value:reportData.TestResultSummary.AIPassed/reportData.TestResultSummary.AITotal*100,fill:"var(--color-ai)"}]:[],...reportData.TestResultSummary.SecOpsPassed!==void 0&&reportData.TestResultSummary.SecOpsTotal!==void 0?[{activity:"secops",value:reportData.TestResultSummary.SecOpsPassed/reportData.TestResultSummary.SecOpsTotal*100,fill:"var(--color-secops)"}]:[],...reportData.TestResultSummary.InfrastructurePassed!==void 0&&reportData.TestResultSummary.InfrastructureTotal!==void 0?[{activity:"infrastructure",value:reportData.TestResultSummary.InfrastructurePassed/reportData.TestResultSummary.InfrastructureTotal*100,fill:"var(--color-infrastructure)"}]:[],...reportData.TestResultSummary.NetworkPassed!==void 0&&reportData.TestResultSummary.NetworkTotal!==void 0?[{activity:"network",value:reportData.TestResultSummary.NetworkPassed/reportData.TestResultSummary.NetworkTotal*100,fill:"var(--color-network)"}]:[],{activity:"data",value:reportData.TestResultSummary.DataPassed/reportData.TestResultSummary.DataTotal*100,fill:"var(--color-stand)"},{activity:"devices",value:reportData.TestResultSummary.DevicesPassed/reportData.TestResultSummary.DevicesTotal*100,fill:"var(--color-exercise)"},{activity:"identity",value:reportData.TestResultSummary.IdentityPassed/reportData.TestResultSummary.IdentityTotal*100,fill:"var(--color-move)"}],innerRadius:"20%",barSize:24,startAngle:90,endAngle:450,children:[jsxRuntimeExports.jsx(PolarAngleAxis,{type:"number",domain:[0,100],dataKey:"value",tick:!1}),jsxRuntimeExports.jsx(RadialBar,{dataKey:"value",background:!0,cornerRadius:5})]})})]})]})]})}),jsxRuntimeExports.jsx("div",{className:"mx-auto flex max-w-7xl flex-col gap-6 mt-6",children:jsxRuntimeExports.jsxs("div",{className:"grid gap-6 grid-cols-1 lg:grid-cols-2",children:[jsxRuntimeExports.jsxs("div",{className:"grid w-full gap-6 lg:col-span-1",children:[reportData.TenantInfo?.OverviewAuthMethodsAllUsers?.nodes?jsxRuntimeExports.jsxs(Card,{className:"w-full","x-chunk":"charts-01-chunk-0",children:[jsxRuntimeExports.jsxs(CardHeader,{className:"space-y-0 pb-2 flex-row",children:[jsxRuntimeExports.jsx(UserCog,{className:"pr-2 size-8"}),jsxRuntimeExports.jsx(CardTitle,{className:"text-2xl tabular-nums",children:"Privileged users auth methods"})]}),jsxRuntimeExports.jsx(CardContent,{children:jsxRuntimeExports.jsx(ChartContainer,{config:{steps:{label:"Steps",color:"hsl(var(--chart-1))"}},children:reportData.TenantInfo?.OverviewAuthMethodsPrivilegedUsers?.nodes?jsxRuntimeExports.jsx(AuthMethodSankey,{data:reportData.TenantInfo.OverviewAuthMethodsPrivilegedUsers.nodes}):jsxRuntimeExports.jsx("div",{className:"flex items-center justify-center h-32 text-muted-foreground",children:"No data available"})})}),jsxRuntimeExports.jsx(CardFooter,{className:"flex-col items-start gap-1",children:jsxRuntimeExports.jsx(CardDescription,{children:reportData.TenantInfo?.OverviewAuthMethodsPrivilegedUsers?.description||"No description available"})})]}):null,reportData.TenantInfo?.OverviewAuthMethodsAllUsers?.nodes?jsxRuntimeExports.jsxs(Card,{className:"w-full","x-chunk":"charts-01-chunk-0",children:[jsxRuntimeExports.jsxs(CardHeader,{className:"space-y-0 pb-2 flex-row",children:[jsxRuntimeExports.jsx(Users,{className:"pr-2 size-8"}),jsxRuntimeExports.jsx(CardTitle,{className:"text-2xl tabular-nums",children:"All users auth methods"})]}),jsxRuntimeExports.jsx(CardContent,{children:jsxRuntimeExports.jsx(ChartContainer,{config:{steps:{label:"Steps",color:"hsl(var(--chart-1))"}},children:reportData.TenantInfo?.OverviewAuthMethodsAllUsers?.nodes?jsxRuntimeExports.jsx(AuthMethodSankey,{data:reportData.TenantInfo.OverviewAuthMethodsAllUsers.nodes}):jsxRuntimeExports.jsx("div",{className:"flex items-center justify-center h-32 text-muted-foreground",children:"No data available"})})}),jsxRuntimeExports.jsx(CardFooter,{className:"flex-col items-start gap-1",children:jsxRuntimeExports.jsx(CardDescription,{children:reportData.TenantInfo?.OverviewAuthMethodsAllUsers?.description||"No description available"})})]}):null]}),jsxRuntimeExports.jsxs("div",{className:"grid w-full gap-6 lg:col-span-1",children:[reportData.TenantInfo?.OverviewAuthMethodsAllUsers?.nodes?jsxRuntimeExports.jsxs(Card,{className:"lmax-w-xs","x-chunk":"charts-01-chunk-0",children:[jsxRuntimeExports.jsxs(CardHeader,{className:"space-y-0 pb-2 flex-row",children:[jsxRuntimeExports.jsx(User,{className:"pr-2 size-8"}),jsxRuntimeExports.jsx(CardTitle,{className:"text-2xl tabular-nums",children:"User authentication"})]}),jsxRuntimeExports.jsx(CardContent,{children:jsxRuntimeExports.jsx(ChartContainer,{config:{steps:{label:"Steps",color:"hsl(var(--chart-1))"}},children:reportData.TenantInfo?.OverviewCaMfaAllUsers?.nodes?jsxRuntimeExports.jsx(CaSankey,{data:reportData.TenantInfo.OverviewCaMfaAllUsers.nodes}):jsxRuntimeExports.jsx("div",{className:"flex items-center justify-center h-32 text-muted-foreground",children:"No data available"})})}),jsxRuntimeExports.jsx(CardFooter,{className:"flex-col items-start gap-1",children:jsxRuntimeExports.jsx(CardDescription,{children:reportData.TenantInfo?.OverviewCaMfaAllUsers?.description||"No description available"})})]}):null,reportData.TenantInfo?.OverviewAuthMethodsPrivilegedUsers?.nodes?jsxRuntimeExports.jsxs(Card,{className:"lmax-w-xs","x-chunk":"charts-01-chunk-0",children:[jsxRuntimeExports.jsxs(CardHeader,{className:"space-y-0 pb-2 flex-row",children:[jsxRuntimeExports.jsx(MonitorSmartphone,{className:"pr-2 size-8"}),jsxRuntimeExports.jsx(CardTitle,{className:"text-2xl tabular-nums ",children:"Device sign-ins"})]}),jsxRuntimeExports.jsx(CardContent,{children:jsxRuntimeExports.jsx(ChartContainer,{config:{steps:{label:"Steps",color:"hsl(var(--chart-1))"}},children:reportData.TenantInfo?.OverviewCaDevicesAllUsers?.nodes?jsxRuntimeExports.jsx(CaDeviceSankey,{data:reportData.TenantInfo.OverviewCaDevicesAllUsers.nodes}):jsxRuntimeExports.jsx("div",{className:"flex items-center justify-center h-32 text-muted-foreground",children:"No data available"})})}),jsxRuntimeExports.jsx(CardFooter,{className:"flex-col items-start gap-1",children:jsxRuntimeExports.jsx(CardDescription,{children:reportData.TenantInfo?.OverviewCaDevicesAllUsers?.description||"No description available"})})]}):null]})]})}),jsxRuntimeExports.jsx("div",{className:"flex max-w-7xl flex-col gap-6 mt-6",children:jsxRuntimeExports.jsxs("div",{className:"grid gap-6 grid-cols-1 lg:grid-cols-3",children:[reportData.TenantInfo?.DeviceOverview?.ManagedDevices?jsxRuntimeExports.jsxs(Card,{className:"w-full",children:[jsxRuntimeExports.jsxs(CardHeader,{className:"space-y-0 pb-2 flex-row",children:[jsxRuntimeExports.jsx(MonitorSmartphone,{className:"pr-2 size-8"}),jsxRuntimeExports.jsx(CardTitle,{className:"text-2xl tabular-nums",children:"Device summary"})]}),jsxRuntimeExports.jsx(CardContent,{className:"flex pb-4 h-[250px]",children:jsxRuntimeExports.jsx(ChartContainer,{config:{value:{label:"Devices"}},className:"h-[250px] w-full",children:jsxRuntimeExports.jsxs(BarChart,{margin:{left:12,right:0,top:0,bottom:10},data:[{dataKey:"Windows",value:reportData.TenantInfo?.DeviceOverview?.ManagedDevices?.deviceOperatingSystemSummary?.windowsCount,label:`${reportData.TenantInfo?.DeviceOverview?.ManagedDevices?.deviceOperatingSystemSummary?.windowsCount}`,fill:"hsl(var(--chart-1))"},{dataKey:"macOS",value:reportData.TenantInfo?.DeviceOverview?.ManagedDevices?.deviceOperatingSystemSummary?.macOSCount,label:`${reportData.TenantInfo?.DeviceOverview?.ManagedDevices?.deviceOperatingSystemSummary?.macOSCount}`,fill:"hsl(var(--chart-2))"},{dataKey:"iOS/iPadOS",value:reportData.TenantInfo?.DeviceOverview?.ManagedDevices?.deviceOperatingSystemSummary?.iosCount,label:`${reportData.TenantInfo?.DeviceOverview?.ManagedDevices?.deviceOperatingSystemSummary?.iosCount}`,fill:"hsl(var(--chart-3))"},{dataKey:"Android",value:reportData.TenantInfo?.DeviceOverview?.ManagedDevices?.deviceOperatingSystemSummary?.androidCount,label:`${reportData.TenantInfo?.DeviceOverview?.ManagedDevices?.deviceOperatingSystemSummary?.androidCount}`,fill:"hsl(var(--chart-5))"},{dataKey:"Linux",value:reportData.TenantInfo?.DeviceOverview?.ManagedDevices?.deviceOperatingSystemSummary?.linuxCount,label:`${reportData.TenantInfo?.DeviceOverview?.ManagedDevices?.deviceOperatingSystemSummary?.linuxCount}`,fill:"hsl(var(--chart-4))"}],layout:"vertical",barSize:32,barGap:2,children:[jsxRuntimeExports.jsx(XAxis,{type:"number",dataKey:"value",hide:!0}),jsxRuntimeExports.jsx(YAxis,{dataKey:"dataKey",type:"category",tickLine:!1,tickMargin:4,axisLine:!1,className:""}),jsxRuntimeExports.jsx(ChartTooltip,{cursor:!1,content:jsxRuntimeExports.jsx(ChartTooltipContent,{})}),jsxRuntimeExports.jsx(Bar,{dataKey:"value",radius:5,children:jsxRuntimeExports.jsx(LabelList,{position:"insideLeft",dataKey:"label",fill:"white",offset:8,fontSize:12})})]})})}),jsxRuntimeExports.jsx(CardFooter,{className:"flex flex-row border-t p-4",children:jsxRuntimeExports.jsxs("div",{className:"flex w-full items-center gap-2",children:[jsxRuntimeExports.jsxs("div",{className:"grid flex-1 auto-rows-min gap-0.5",children:[jsxRuntimeExports.jsx("div",{className:"text-xs text-muted-foreground",children:"Desktops"}),jsxRuntimeExports.jsxs("div",{className:"flex items-baseline gap-1 text-2xl font-bold tabular-nums leading-none",children:[Math.round(reportData.TenantInfo?.DeviceOverview?.ManagedDevices?.desktopCount/reportData.TenantInfo?.DeviceOverview?.ManagedDevices?.totalCount*100),jsxRuntimeExports.jsx("span",{className:"text-sm font-normal text-muted-foreground",children:"%"})]})]}),jsxRuntimeExports.jsx(Separator,{orientation:"vertical",className:"mx-2 h-10 w-px"}),jsxRuntimeExports.jsxs("div",{className:"grid flex-1 auto-rows-min gap-0.5",children:[jsxRuntimeExports.jsx("div",{className:"text-xs text-muted-foreground",children:"Mobiles"}),jsxRuntimeExports.jsxs("div",{className:"flex items-baseline gap-1 text-2xl font-bold tabular-nums leading-none",children:[Math.round(reportData.TenantInfo?.DeviceOverview?.ManagedDevices?.mobileCount/reportData.TenantInfo?.DeviceOverview?.ManagedDevices?.totalCount*100),jsxRuntimeExports.jsx("span",{className:"text-sm font-normal text-muted-foreground",children:"%"})]})]})]})})]}):null,reportData.TenantInfo?.DeviceOverview?.ManagedDevices&&reportData.TenantInfo?.DeviceOverview?.DeviceCompliance&&reportData.TenantInfo?.DeviceOverview?.DeviceCompliance?.compliantDeviceCount+reportData.TenantInfo?.DeviceOverview?.DeviceCompliance?.nonCompliantDeviceCount>0&&jsxRuntimeExports.jsxs(Card,{className:"w-full",children:[jsxRuntimeExports.jsxs(CardHeader,{className:"space-y-0 pb-2 flex-row",children:[jsxRuntimeExports.jsx(CircleCheckBig,{className:"pr-2 size-8"}),jsxRuntimeExports.jsx(CardTitle,{className:"text-2xl tabular-nums ",children:"Device compliance"})]}),jsxRuntimeExports.jsx(CardContent,{className:"flex pb-2 h-[250px]",children:jsxRuntimeExports.jsx(ChartContainer,{config:{compliant:{label:"Compliant",color:"hsl(142, 76%, 36%)"},nonCompliant:{label:"Non-compliant",color:"hsl(0, 84%, 60%)"}},className:"mx-auto aspect-square w-full max-h-full",children:jsxRuntimeExports.jsxs(PieChart,{margin:{top:5,right:5,bottom:5,left:5},children:[jsxRuntimeExports.jsxs(Pie,{data:[{name:"Compliant",value:reportData.TenantInfo?.DeviceOverview?.DeviceCompliance?.compliantDeviceCount,fill:"var(--color-compliant)"},{name:"Non-compliant",value:reportData.TenantInfo?.DeviceOverview?.DeviceCompliance?.nonCompliantDeviceCount,fill:"var(--color-nonCompliant)"}],cx:"50%",cy:"50%",innerRadius:50,outerRadius:100,paddingAngle:2,dataKey:"value",cornerRadius:5,children:[jsxRuntimeExports.jsx(Cell,{fill:"var(--color-compliant)"}),jsxRuntimeExports.jsx(Cell,{fill:"var(--color-nonCompliant)"})]}),jsxRuntimeExports.jsx(ChartTooltip,{content:jsxRuntimeExports.jsx(ChartTooltipContent,{})})]})})}),jsxRuntimeExports.jsx(CardFooter,{className:"flex flex-row border-t p-4",children:jsxRuntimeExports.jsxs("div",{className:"flex w-full items-center gap-2",children:[jsxRuntimeExports.jsxs("div",{className:"grid flex-1 auto-rows-min gap-0.5",children:[jsxRuntimeExports.jsxs("div",{className:"flex items-center gap-1 text-xs text-muted-foreground",children:[jsxRuntimeExports.jsx("div",{className:"w-3 h-3 rounded-sm bg-green-600"}),"Compliant"]}),jsxRuntimeExports.jsxs("div",{className:"flex items-baseline gap-1 text-2xl font-bold tabular-nums leading-none",children:[(()=>{const compliant=reportData.TenantInfo?.DeviceOverview?.DeviceCompliance?.compliantDeviceCount,nonCompliant=reportData.TenantInfo?.DeviceOverview?.DeviceCompliance?.nonCompliantDeviceCount,total=compliant+nonCompliant;return total>0?Math.round(compliant/total*100):0})(),jsxRuntimeExports.jsx("span",{className:"text-sm font-normal text-muted-foreground",children:"%"})]})]}),jsxRuntimeExports.jsx(Separator,{orientation:"vertical",className:"mx-2 h-10 w-px"}),jsxRuntimeExports.jsxs("div",{className:"grid flex-1 auto-rows-min gap-0.5",children:[jsxRuntimeExports.jsxs("div",{className:"flex items-center gap-1 text-xs text-muted-foreground",children:[jsxRuntimeExports.jsx("div",{className:"w-3 h-3 rounded-sm bg-red-500"}),"Non-compliant"]}),jsxRuntimeExports.jsxs("div",{className:"flex items-baseline gap-1 text-2xl font-bold tabular-nums leading-none",children:[(()=>{const compliant=reportData.TenantInfo?.DeviceOverview?.DeviceCompliance?.compliantDeviceCount,nonCompliant=reportData.TenantInfo?.DeviceOverview?.DeviceCompliance?.nonCompliantDeviceCount,total=compliant+nonCompliant;return total>0?Math.round(nonCompliant/total*100):0})(),jsxRuntimeExports.jsx("span",{className:"text-sm font-normal text-muted-foreground",children:"%"})]})]})]})})]}),reportData.TenantInfo?.DeviceOverview?.ManagedDevices&&reportData.TenantInfo?.DeviceOverview?.DeviceOwnership&&reportData.TenantInfo?.DeviceOverview?.DeviceOwnership?.corporateCount+reportData.TenantInfo?.DeviceOverview?.DeviceOwnership?.personalCount>0&&jsxRuntimeExports.jsxs(Card,{className:"w-full",children:[jsxRuntimeExports.jsxs(CardHeader,{className:"space-y-0 pb-2 flex-row",children:[jsxRuntimeExports.jsx(Briefcase,{className:"pr-2 size-8"}),jsxRuntimeExports.jsx(CardTitle,{className:"text-2xl tabular-nums ",children:"Device ownership"})]}),jsxRuntimeExports.jsx(CardContent,{className:"flex pb-2 h-[250px]",children:jsxRuntimeExports.jsx(ChartContainer,{config:{corporate:{label:"Corporate",color:"hsl(217, 91%, 60%)"},personal:{label:"Personal",color:"hsl(280, 85%, 60%)"}},className:"mx-auto aspect-square w-full max-h-full",children:jsxRuntimeExports.jsxs(PieChart,{margin:{top:5,right:5,bottom:5,left:5},children:[jsxRuntimeExports.jsxs(Pie,{data:[{name:"Corporate",value:reportData.TenantInfo?.DeviceOverview?.DeviceOwnership?.corporateCount,fill:"var(--color-corporate)"},{name:"Personal",value:reportData.TenantInfo?.DeviceOverview?.DeviceOwnership?.personalCount,fill:"var(--color-personal)"}],cx:"50%",cy:"50%",innerRadius:50,outerRadius:100,paddingAngle:2,dataKey:"value",cornerRadius:5,children:[jsxRuntimeExports.jsx(Cell,{fill:"var(--color-corporate)"}),jsxRuntimeExports.jsx(Cell,{fill:"var(--color-personal)"})]}),jsxRuntimeExports.jsx(ChartTooltip,{content:jsxRuntimeExports.jsx(ChartTooltipContent,{})})]})})}),jsxRuntimeExports.jsx(CardFooter,{className:"flex flex-row border-t p-4",children:jsxRuntimeExports.jsxs("div",{className:"flex w-full items-center gap-2",children:[jsxRuntimeExports.jsxs("div",{className:"grid flex-1 auto-rows-min gap-0.5",children:[jsxRuntimeExports.jsxs("div",{className:"flex items-center gap-1 text-xs text-muted-foreground",children:[jsxRuntimeExports.jsx("div",{className:"w-3 h-3 rounded-sm bg-blue-500"}),"Corporate"]}),jsxRuntimeExports.jsxs("div",{className:"flex items-baseline gap-1 text-2xl font-bold tabular-nums leading-none",children:[(()=>{const corporate=reportData.TenantInfo?.DeviceOverview?.DeviceOwnership?.corporateCount,personal=reportData.TenantInfo?.DeviceOverview?.DeviceOwnership?.personalCount,total=corporate+personal;return total>0?Math.round(corporate/total*100):0})(),jsxRuntimeExports.jsx("span",{className:"text-sm font-normal text-muted-foreground",children:"%"})]})]}),jsxRuntimeExports.jsx(Separator,{orientation:"vertical",className:"mx-2 h-10 w-px"}),jsxRuntimeExports.jsxs("div",{className:"grid flex-1 auto-rows-min gap-0.5",children:[jsxRuntimeExports.jsxs("div",{className:"flex items-center gap-1 text-xs text-muted-foreground",children:[jsxRuntimeExports.jsx("div",{className:"w-3 h-3 rounded-sm bg-purple-500"}),"Personal"]}),jsxRuntimeExports.jsxs("div",{className:"flex items-baseline gap-1 text-2xl font-bold tabular-nums leading-none",children:[(()=>{const corporate=reportData.TenantInfo?.DeviceOverview?.DeviceOwnership?.corporateCount,personal=reportData.TenantInfo?.DeviceOverview?.DeviceOwnership?.personalCount,total=corporate+personal;return total>0?Math.round(personal/total*100):0})(),jsxRuntimeExports.jsx("span",{className:"text-sm font-normal text-muted-foreground",children:"%"})]})]})]})})]}),reportData.TenantInfo?.DeviceOverview?.DesktopDevicesSummary?.nodes&&reportData.TenantInfo.DeviceOverview.DesktopDevicesSummary.nodes.length>0&&jsxRuntimeExports.jsxs(Card,{className:"w-full lg:col-span-3",children:[jsxRuntimeExports.jsxs(CardHeader,{className:"space-y-0 pb-2 flex-row",children:[jsxRuntimeExports.jsx(Monitor,{className:"pr-2 size-8"}),jsxRuntimeExports.jsx(CardTitle,{className:"text-2xl tabular-nums",children:"Desktop devices"})]}),jsxRuntimeExports.jsx(CardContent,{children:jsxRuntimeExports.jsx(ChartContainer,{config:{steps:{label:"Steps",color:"hsl(var(--chart-1))"}},className:"h-[350px] w-full",children:reportData.TenantInfo?.DeviceOverview?.DesktopDevicesSummary?.nodes?jsxRuntimeExports.jsx(DesktopDevicesSankey,{data:reportData.TenantInfo.DeviceOverview.DesktopDevicesSummary.nodes}):jsxRuntimeExports.jsx("div",{className:"flex items-center justify-center h-32 text-muted-foreground",children:"No data available"})})}),jsxRuntimeExports.jsx(CardFooter,{className:"flex flex-row border-t p-4",children:jsxRuntimeExports.jsxs("div",{className:"flex w-full items-center gap-2",children:[jsxRuntimeExports.jsxs("div",{className:"grid flex-1 auto-rows-min gap-0.5",children:[jsxRuntimeExports.jsx("div",{className:"text-xs text-muted-foreground",children:"Entra joined"}),jsxRuntimeExports.jsxs("div",{className:"flex items-baseline gap-1 text-2xl font-bold tabular-nums leading-none",children:[(()=>{const nodes=reportData.TenantInfo?.DeviceOverview?.DesktopDevicesSummary?.nodes||[],entraJoined=nodes.find(n2=>n2.target==="Entra joined")?.value||0,windowsDevices=nodes.find(n2=>n2.source==="Desktop devices"&&n2.target==="Windows")?.value||0,macOSDevices=nodes.find(n2=>n2.source==="Desktop devices"&&n2.target==="macOS")?.value||0,total=windowsDevices+macOSDevices;return Math.round(entraJoined/(total||1)*100)})(),jsxRuntimeExports.jsx("span",{className:"text-sm font-normal text-muted-foreground",children:"%"})]})]}),jsxRuntimeExports.jsx(Separator,{orientation:"vertical",className:"mx-2 h-10 w-px"}),jsxRuntimeExports.jsxs("div",{className:"grid flex-1 auto-rows-min gap-0.5",children:[jsxRuntimeExports.jsx("div",{className:"text-xs text-muted-foreground",children:"Entra hybrid joined"}),jsxRuntimeExports.jsxs("div",{className:"flex items-baseline gap-1 text-2xl font-bold tabular-nums leading-none",children:[(()=>{const nodes=reportData.TenantInfo?.DeviceOverview?.DesktopDevicesSummary?.nodes||[],entraHybrid=nodes.find(n2=>n2.target==="Entra hybrid joined")?.value||0,windowsDevices=nodes.find(n2=>n2.source==="Desktop devices"&&n2.target==="Windows")?.value||0,macOSDevices=nodes.find(n2=>n2.source==="Desktop devices"&&n2.target==="macOS")?.value||0,total=windowsDevices+macOSDevices;return Math.round(entraHybrid/(total||1)*100)})(),jsxRuntimeExports.jsx("span",{className:"text-sm font-normal text-muted-foreground",children:"%"})]})]}),jsxRuntimeExports.jsx(Separator,{orientation:"vertical",className:"mx-2 h-10 w-px"}),jsxRuntimeExports.jsxs("div",{className:"grid flex-1 auto-rows-min gap-0.5",children:[jsxRuntimeExports.jsx("div",{className:"text-xs text-muted-foreground",children:"Entra registered"}),jsxRuntimeExports.jsxs("div",{className:"flex items-baseline gap-1 text-2xl font-bold tabular-nums leading-none",children:[(()=>{const nodes=reportData.TenantInfo?.DeviceOverview?.DesktopDevicesSummary?.nodes||[],entraRegistered=nodes.find(n2=>n2.target==="Entra registered")?.value||0,windowsDevices=nodes.find(n2=>n2.source==="Desktop devices"&&n2.target==="Windows")?.value||0,macOSDevices=nodes.find(n2=>n2.source==="Desktop devices"&&n2.target==="macOS")?.value||0,total=windowsDevices+macOSDevices;return Math.round(entraRegistered/(total||1)*100)})(),jsxRuntimeExports.jsx("span",{className:"text-sm font-normal text-muted-foreground",children:"%"})]})]})]})})]}),reportData.TenantInfo?.DeviceOverview?.MobileSummary?.nodes&&reportData.TenantInfo?.DeviceOverview?.ManagedDevices&&jsxRuntimeExports.jsxs(Card,{className:"w-full lg:col-span-3",children:[jsxRuntimeExports.jsxs(CardHeader,{className:"space-y-0 pb-2 flex-row",children:[jsxRuntimeExports.jsx(MonitorSmartphone,{className:"pr-2 size-8"}),jsxRuntimeExports.jsx(CardTitle,{className:"text-2xl tabular-nums",children:"Mobile devices"})]}),jsxRuntimeExports.jsx(CardContent,{children:jsxRuntimeExports.jsx(ChartContainer,{config:{steps:{label:"Steps",color:"hsl(var(--chart-1))"}},className:"h-[350px] w-full",children:reportData.TenantInfo?.DeviceOverview?.MobileSummary?.nodes?jsxRuntimeExports.jsx(MobileSankey,{data:reportData.TenantInfo.DeviceOverview.MobileSummary.nodes}):jsxRuntimeExports.jsx("div",{className:"flex items-center justify-center h-32 text-muted-foreground",children:"No data available"})})}),jsxRuntimeExports.jsx(CardFooter,{className:"flex flex-row border-t p-4",children:jsxRuntimeExports.jsxs("div",{className:"flex w-full items-center gap-2",children:[jsxRuntimeExports.jsxs("div",{className:"grid flex-1 auto-rows-min gap-0.5",children:[jsxRuntimeExports.jsx("div",{className:"text-xs text-muted-foreground",children:"Android compliant"}),jsxRuntimeExports.jsxs("div",{className:"flex items-baseline gap-1 text-2xl font-bold tabular-nums leading-none",children:[(()=>{const nodes=reportData.TenantInfo?.DeviceOverview?.MobileSummary?.nodes||[],androidCompliant=nodes.filter(n2=>n2.source?.includes("Android")&&n2.target==="Compliant").reduce((sum2,n2)=>sum2+(n2.value||0),0),androidTotal=nodes.find(n2=>n2.source==="Mobile devices"&&n2.target==="Android")?.value||0;return androidTotal>0?Math.round(androidCompliant/androidTotal*100):0})(),jsxRuntimeExports.jsx("span",{className:"text-sm font-normal text-muted-foreground",children:"%"})]})]}),jsxRuntimeExports.jsx(Separator,{orientation:"vertical",className:"mx-2 h-10 w-px"}),jsxRuntimeExports.jsxs("div",{className:"grid flex-1 auto-rows-min gap-0.5",children:[jsxRuntimeExports.jsx("div",{className:"text-xs text-muted-foreground",children:"iOS compliant"}),jsxRuntimeExports.jsxs("div",{className:"flex items-baseline gap-1 text-2xl font-bold tabular-nums leading-none",children:[(()=>{const nodes=reportData.TenantInfo?.DeviceOverview?.MobileSummary?.nodes||[],iosCompliant=nodes.filter(n2=>n2.source?.includes("iOS")&&n2.target==="Compliant").reduce((sum2,n2)=>sum2+(n2.value||0),0),iosTotal=nodes.find(n2=>n2.source==="Mobile devices"&&n2.target==="iOS")?.value||0;return iosTotal>0?Math.round(iosCompliant/iosTotal*100):0})(),jsxRuntimeExports.jsx("span",{className:"text-sm font-normal text-muted-foreground",children:"%"})]})]}),jsxRuntimeExports.jsx(Separator,{orientation:"vertical",className:"mx-2 h-10 w-px"}),jsxRuntimeExports.jsxs("div",{className:"grid flex-1 auto-rows-min gap-0.5",children:[jsxRuntimeExports.jsx("div",{className:"text-xs text-muted-foreground",children:"Total devices"}),jsxRuntimeExports.jsx("div",{className:"flex items-baseline gap-1 text-2xl font-bold tabular-nums leading-none",children:(()=>{const nodes=reportData.TenantInfo?.DeviceOverview?.MobileSummary?.nodes||[],androidTotal=nodes.find(n2=>n2.source==="Mobile devices"&&n2.target==="Android")?.value||0,iosTotal=nodes.find(n2=>n2.source==="Mobile devices"&&n2.target==="iOS")?.value||0;return androidTotal+iosTotal})()})]})]})})]})]})}),hasSwgData()&&jsxRuntimeExports.jsx("div",{className:"flex max-w-7xl flex-col gap-6 mt-6",children:jsxRuntimeExports.jsxs(Card,{children:[jsxRuntimeExports.jsxs(CardHeader,{className:"space-y-0 pb-2 flex-row",children:[jsxRuntimeExports.jsx(ShieldCheck,{className:"pr-2 size-8"}),jsxRuntimeExports.jsxs("div",{children:[jsxRuntimeExports.jsx(CardTitle,{className:"text-2xl tabular-nums",children:"SWG defense-in-depth"}),jsxRuntimeExports.jsx(CardDescription,{className:"mt-1",children:"Secure Web Gateway defense layers — internet traffic inspection posture"})]})]}),jsxRuntimeExports.jsx(CardContent,{children:jsxRuntimeExports.jsx(SwgDefenseLayers,{})})]})})]})}__name(Dashboard,"Dashboard");var E=typeof window>"u",m=E?React.useEffect:React.useLayoutEffect,B=0,_=__name(()=>++B,"_"),v=!1;function O(){let[n2,r2]=React.useState(v?_:void 0);return m(()=>{n2===void 0&&r2(_()),v=!0},[]),n2===void 0?n2:`rwb-${n2.toString(32)}`}__name(O,"O");function R(){return React.useMemo(()=>"useId"in React?React.useId:O,[])()}__name(R,"R");var y="__wrap_b",f="__wrap_n",S="__wrap_o",T=__name((n2,r2,e3)=>{e3=e3||document.querySelector(`[data-br="${n2}"]`);let t2=e3?.parentElement;if(!t2)return;let l2=__name(u2=>e3.style.maxWidth=u2+"px","l");e3.style.maxWidth="";let i2=t2.clientWidth,d=t2.clientHeight,o2=i2/2-.25,s2=i2+.5,c2;if(i2){for(l2(o2),o2=Math.max(e3.scrollWidth,o2);o2+1{self.__wrap_b(0,+e3.dataset.brr,e3)})).observe(t2)},"T"),I=T.toString(),w='(self.CSS&&CSS.supports("text-wrap","balance")?1:2)',g=__name((n2,r2,e3="")=>(e3&&(e3=`self.${f}!=1&&${e3}`),React.createElement("script",{suppressHydrationWarning:!0,dangerouslySetInnerHTML:{__html:(n2?"":`self.${f}=self.${f}||${w};self.${y}=${I};`)+e3},nonce:r2})),"g"),h$1=React.createContext({preferNative:!0,hasProvider:!1});React.forwardRef(({ratio:n2=1,preferNative:r2,nonce:e3,children:t2,as:l2,...i2},d)=>{let o2=R(),s2=React.useRef(),c2=React.useContext(h$1),u2=r2??c2.preferNative,x2=l2||"span";return React.useImperativeHandle(d,()=>s2.current,[]),m(()=>{u2&&self[f]===1||s2.current&&(self[y]=T)(0,n2,s2.current)},[t2,u2,n2]),m(()=>{if(!(u2&&self[f]===1))return()=>{if(!s2.current)return;let b2=s2.current[S];b2&&(b2.disconnect(),delete s2.current[S])}},[u2]),React.createElement(React.Fragment,null,React.createElement(x2,{...i2,"data-br":o2,"data-brr":n2,ref:s2,style:{display:"inline-block",verticalAlign:"top",textDecoration:"inherit",textWrap:u2?"balance":"initial"},suppressHydrationWarning:!0},t2),g(c2.hasProvider,e3,`self.${y}("${o2}",${n2})`))});function PageHeader({className,children:children2,...props}){return jsxRuntimeExports.jsx("section",{className:cn$2("pt-6 pb-4 flex items-center justify-between space-y-2",className),...props,children:children2})}__name(PageHeader,"PageHeader");function PageHeaderHeading({className,...props}){return jsxRuntimeExports.jsx("h1",{className:cn$2("text-3xl font-semibold tracking-tight my-1",className),...props})}__name(PageHeaderHeading,"PageHeaderHeading");function functionalUpdate(updater,input){return typeof updater=="function"?updater(input):updater}__name(functionalUpdate,"functionalUpdate");function makeStateUpdater(key,instance){return updater=>{instance.setState(old=>({...old,[key]:functionalUpdate(updater,old[key])}))}}__name(makeStateUpdater,"makeStateUpdater");function isFunction(d){return d instanceof Function}__name(isFunction,"isFunction");function isNumberArray(d){return Array.isArray(d)&&d.every(val=>typeof val=="number")}__name(isNumberArray,"isNumberArray");function flattenBy(arr,getChildren){const flat=[],recurse=__name(subArr=>{subArr.forEach(item=>{flat.push(item);const children2=getChildren(item);children2!=null&&children2.length&&recurse(children2)})},"recurse");return recurse(arr),flat}__name(flattenBy,"flattenBy");function memo(getDeps,fn2,opts){let deps=[],result;return depArgs=>{let depTime;opts.key&&opts.debug&&(depTime=Date.now());const newDeps=getDeps(depArgs);if(!(newDeps.length!==deps.length||newDeps.some((dep,index2)=>deps[index2]!==dep)))return result;deps=newDeps;let resultTime;if(opts.key&&opts.debug&&(resultTime=Date.now()),result=fn2(...newDeps),opts==null||opts.onChange==null||opts.onChange(result),opts.key&&opts.debug&&opts!=null&&opts.debug()){const depEndTime=Math.round((Date.now()-depTime)*100)/100,resultEndTime=Math.round((Date.now()-resultTime)*100)/100,resultFpsPercentage=resultEndTime/16,pad2=__name((str,num)=>{for(str=String(str);str.length{var _tableOptions$debugAl;return(_tableOptions$debugAl=tableOptions?.debugAll)!=null?_tableOptions$debugAl:tableOptions[debugLevel]},"debug"),key:!1,onChange}}__name(getMemoOptions,"getMemoOptions");function createCell(table2,row,column,columnId){const getRenderValue=__name(()=>{var _cell$getValue;return(_cell$getValue=cell.getValue())!=null?_cell$getValue:table2.options.renderFallbackValue},"getRenderValue"),cell={id:`${row.id}_${column.id}`,row,column,getValue:__name(()=>row.getValue(columnId),"getValue"),renderValue:getRenderValue,getContext:memo(()=>[table2,column,row,cell],(table22,column2,row2,cell2)=>({table:table22,column:column2,row:row2,cell:cell2,getValue:cell2.getValue,renderValue:cell2.renderValue}),getMemoOptions(table2.options,"debugCells"))};return table2._features.forEach(feature=>{feature.createCell==null||feature.createCell(cell,column,row,table2)},{}),cell}__name(createCell,"createCell");function createColumn(table2,columnDef,depth,parent){var _ref,_resolvedColumnDef$id;const resolvedColumnDef={...table2._getDefaultColumnDef(),...columnDef},accessorKey=resolvedColumnDef.accessorKey;let id=(_ref=(_resolvedColumnDef$id=resolvedColumnDef.id)!=null?_resolvedColumnDef$id:accessorKey?typeof String.prototype.replaceAll=="function"?accessorKey.replaceAll(".","_"):accessorKey.replace(/\./g,"_"):void 0)!=null?_ref:typeof resolvedColumnDef.header=="string"?resolvedColumnDef.header:void 0,accessorFn;if(resolvedColumnDef.accessorFn?accessorFn=resolvedColumnDef.accessorFn:accessorKey&&(accessorKey.includes(".")?accessorFn=__name(originalRow=>{let result=originalRow;for(const key of accessorKey.split(".")){var _result;result=(_result=result)==null?void 0:_result[key]}return result},"accessorFn"):accessorFn=__name(originalRow=>originalRow[resolvedColumnDef.accessorKey],"accessorFn")),!id)throw new Error;let column={id:`${String(id)}`,accessorFn,parent,depth,columnDef:resolvedColumnDef,columns:[],getFlatColumns:memo(()=>[!0],()=>{var _column$columns;return[column,...(_column$columns=column.columns)==null?void 0:_column$columns.flatMap(d=>d.getFlatColumns())]},getMemoOptions(table2.options,"debugColumns")),getLeafColumns:memo(()=>[table2._getOrderColumnsFn()],orderColumns2=>{var _column$columns2;if((_column$columns2=column.columns)!=null&&_column$columns2.length){let leafColumns=column.columns.flatMap(column2=>column2.getLeafColumns());return orderColumns2(leafColumns)}return[column]},getMemoOptions(table2.options,"debugColumns"))};for(const feature of table2._features)feature.createColumn==null||feature.createColumn(column,table2);return column}__name(createColumn,"createColumn");const debug="debugHeaders";function createHeader(table2,column,options){var _options$id;let header={id:(_options$id=options.id)!=null?_options$id:column.id,column,index:options.index,isPlaceholder:!!options.isPlaceholder,placeholderId:options.placeholderId,depth:options.depth,subHeaders:[],colSpan:0,rowSpan:0,headerGroup:null,getLeafHeaders:__name(()=>{const leafHeaders=[],recurseHeader=__name(h2=>{h2.subHeaders&&h2.subHeaders.length&&h2.subHeaders.map(recurseHeader),leafHeaders.push(h2)},"recurseHeader");return recurseHeader(header),leafHeaders},"getLeafHeaders"),getContext:__name(()=>({table:table2,header,column}),"getContext")};return table2._features.forEach(feature=>{feature.createHeader==null||feature.createHeader(header,table2)}),header}__name(createHeader,"createHeader");const Headers$1={createTable:__name(table2=>{table2.getHeaderGroups=memo(()=>[table2.getAllColumns(),table2.getVisibleLeafColumns(),table2.getState().columnPinning.left,table2.getState().columnPinning.right],(allColumns,leafColumns,left2,right2)=>{var _left$map$filter,_right$map$filter;const leftColumns=(_left$map$filter=left2?.map(columnId=>leafColumns.find(d=>d.id===columnId)).filter(Boolean))!=null?_left$map$filter:[],rightColumns=(_right$map$filter=right2?.map(columnId=>leafColumns.find(d=>d.id===columnId)).filter(Boolean))!=null?_right$map$filter:[],centerColumns=leafColumns.filter(column=>!(left2!=null&&left2.includes(column.id))&&!(right2!=null&&right2.includes(column.id)));return buildHeaderGroups(allColumns,[...leftColumns,...centerColumns,...rightColumns],table2)},getMemoOptions(table2.options,debug)),table2.getCenterHeaderGroups=memo(()=>[table2.getAllColumns(),table2.getVisibleLeafColumns(),table2.getState().columnPinning.left,table2.getState().columnPinning.right],(allColumns,leafColumns,left2,right2)=>(leafColumns=leafColumns.filter(column=>!(left2!=null&&left2.includes(column.id))&&!(right2!=null&&right2.includes(column.id))),buildHeaderGroups(allColumns,leafColumns,table2,"center")),getMemoOptions(table2.options,debug)),table2.getLeftHeaderGroups=memo(()=>[table2.getAllColumns(),table2.getVisibleLeafColumns(),table2.getState().columnPinning.left],(allColumns,leafColumns,left2)=>{var _left$map$filter2;const orderedLeafColumns=(_left$map$filter2=left2?.map(columnId=>leafColumns.find(d=>d.id===columnId)).filter(Boolean))!=null?_left$map$filter2:[];return buildHeaderGroups(allColumns,orderedLeafColumns,table2,"left")},getMemoOptions(table2.options,debug)),table2.getRightHeaderGroups=memo(()=>[table2.getAllColumns(),table2.getVisibleLeafColumns(),table2.getState().columnPinning.right],(allColumns,leafColumns,right2)=>{var _right$map$filter2;const orderedLeafColumns=(_right$map$filter2=right2?.map(columnId=>leafColumns.find(d=>d.id===columnId)).filter(Boolean))!=null?_right$map$filter2:[];return buildHeaderGroups(allColumns,orderedLeafColumns,table2,"right")},getMemoOptions(table2.options,debug)),table2.getFooterGroups=memo(()=>[table2.getHeaderGroups()],headerGroups=>[...headerGroups].reverse(),getMemoOptions(table2.options,debug)),table2.getLeftFooterGroups=memo(()=>[table2.getLeftHeaderGroups()],headerGroups=>[...headerGroups].reverse(),getMemoOptions(table2.options,debug)),table2.getCenterFooterGroups=memo(()=>[table2.getCenterHeaderGroups()],headerGroups=>[...headerGroups].reverse(),getMemoOptions(table2.options,debug)),table2.getRightFooterGroups=memo(()=>[table2.getRightHeaderGroups()],headerGroups=>[...headerGroups].reverse(),getMemoOptions(table2.options,debug)),table2.getFlatHeaders=memo(()=>[table2.getHeaderGroups()],headerGroups=>headerGroups.map(headerGroup=>headerGroup.headers).flat(),getMemoOptions(table2.options,debug)),table2.getLeftFlatHeaders=memo(()=>[table2.getLeftHeaderGroups()],left2=>left2.map(headerGroup=>headerGroup.headers).flat(),getMemoOptions(table2.options,debug)),table2.getCenterFlatHeaders=memo(()=>[table2.getCenterHeaderGroups()],left2=>left2.map(headerGroup=>headerGroup.headers).flat(),getMemoOptions(table2.options,debug)),table2.getRightFlatHeaders=memo(()=>[table2.getRightHeaderGroups()],left2=>left2.map(headerGroup=>headerGroup.headers).flat(),getMemoOptions(table2.options,debug)),table2.getCenterLeafHeaders=memo(()=>[table2.getCenterFlatHeaders()],flatHeaders=>flatHeaders.filter(header=>{var _header$subHeaders;return!((_header$subHeaders=header.subHeaders)!=null&&_header$subHeaders.length)}),getMemoOptions(table2.options,debug)),table2.getLeftLeafHeaders=memo(()=>[table2.getLeftFlatHeaders()],flatHeaders=>flatHeaders.filter(header=>{var _header$subHeaders2;return!((_header$subHeaders2=header.subHeaders)!=null&&_header$subHeaders2.length)}),getMemoOptions(table2.options,debug)),table2.getRightLeafHeaders=memo(()=>[table2.getRightFlatHeaders()],flatHeaders=>flatHeaders.filter(header=>{var _header$subHeaders3;return!((_header$subHeaders3=header.subHeaders)!=null&&_header$subHeaders3.length)}),getMemoOptions(table2.options,debug)),table2.getLeafHeaders=memo(()=>[table2.getLeftHeaderGroups(),table2.getCenterHeaderGroups(),table2.getRightHeaderGroups()],(left2,center2,right2)=>{var _left$0$headers,_left$,_center$0$headers,_center$,_right$0$headers,_right$;return[...(_left$0$headers=(_left$=left2[0])==null?void 0:_left$.headers)!=null?_left$0$headers:[],...(_center$0$headers=(_center$=center2[0])==null?void 0:_center$.headers)!=null?_center$0$headers:[],...(_right$0$headers=(_right$=right2[0])==null?void 0:_right$.headers)!=null?_right$0$headers:[]].map(header=>header.getLeafHeaders()).flat()},getMemoOptions(table2.options,debug))},"createTable")};function buildHeaderGroups(allColumns,columnsToGroup,table2,headerFamily){var _headerGroups$0$heade,_headerGroups$;let maxDepth=0;const findMaxDepth=__name(function(columns2,depth){depth===void 0&&(depth=1),maxDepth=Math.max(maxDepth,depth),columns2.filter(column=>column.getIsVisible()).forEach(column=>{var _column$columns;(_column$columns=column.columns)!=null&&_column$columns.length&&findMaxDepth(column.columns,depth+1)},0)},"findMaxDepth");findMaxDepth(allColumns);let headerGroups=[];const createHeaderGroup=__name((headersToGroup,depth)=>{const headerGroup={depth,id:[headerFamily,`${depth}`].filter(Boolean).join("_"),headers:[]},pendingParentHeaders=[];headersToGroup.forEach(headerToGroup=>{const latestPendingParentHeader=[...pendingParentHeaders].reverse()[0],isLeafHeader=headerToGroup.column.depth===headerGroup.depth;let column,isPlaceholder=!1;if(isLeafHeader&&headerToGroup.column.parent?column=headerToGroup.column.parent:(column=headerToGroup.column,isPlaceholder=!0),latestPendingParentHeader&&latestPendingParentHeader?.column===column)latestPendingParentHeader.subHeaders.push(headerToGroup);else{const header=createHeader(table2,column,{id:[headerFamily,depth,column.id,headerToGroup?.id].filter(Boolean).join("_"),isPlaceholder,placeholderId:isPlaceholder?`${pendingParentHeaders.filter(d=>d.column===column).length}`:void 0,depth,index:pendingParentHeaders.length});header.subHeaders.push(headerToGroup),pendingParentHeaders.push(header)}headerGroup.headers.push(headerToGroup),headerToGroup.headerGroup=headerGroup}),headerGroups.push(headerGroup),depth>0&&createHeaderGroup(pendingParentHeaders,depth-1)},"createHeaderGroup"),bottomHeaders=columnsToGroup.map((column,index2)=>createHeader(table2,column,{depth:maxDepth,index:index2}));createHeaderGroup(bottomHeaders,maxDepth-1),headerGroups.reverse();const recurseHeadersForSpans=__name(headers=>headers.filter(header=>header.column.getIsVisible()).map(header=>{let colSpan=0,rowSpan=0,childRowSpans=[0];header.subHeaders&&header.subHeaders.length?(childRowSpans=[],recurseHeadersForSpans(header.subHeaders).forEach(_ref=>{let{colSpan:childColSpan,rowSpan:childRowSpan}=_ref;colSpan+=childColSpan,childRowSpans.push(childRowSpan)})):colSpan=1;const minChildRowSpan=Math.min(...childRowSpans);return rowSpan=rowSpan+minChildRowSpan,header.colSpan=colSpan,header.rowSpan=rowSpan,{colSpan,rowSpan}}),"recurseHeadersForSpans");return recurseHeadersForSpans((_headerGroups$0$heade=(_headerGroups$=headerGroups[0])==null?void 0:_headerGroups$.headers)!=null?_headerGroups$0$heade:[]),headerGroups}__name(buildHeaderGroups,"buildHeaderGroups");const createRow=__name((table2,id,original,rowIndex,depth,subRows,parentId)=>{let row={id,index:rowIndex,original,depth,parentId,_valuesCache:{},_uniqueValuesCache:{},getValue:__name(columnId=>{if(row._valuesCache.hasOwnProperty(columnId))return row._valuesCache[columnId];const column=table2.getColumn(columnId);if(column!=null&&column.accessorFn)return row._valuesCache[columnId]=column.accessorFn(row.original,rowIndex),row._valuesCache[columnId]},"getValue"),getUniqueValues:__name(columnId=>{if(row._uniqueValuesCache.hasOwnProperty(columnId))return row._uniqueValuesCache[columnId];const column=table2.getColumn(columnId);if(column!=null&&column.accessorFn)return column.columnDef.getUniqueValues?(row._uniqueValuesCache[columnId]=column.columnDef.getUniqueValues(row.original,rowIndex),row._uniqueValuesCache[columnId]):(row._uniqueValuesCache[columnId]=[row.getValue(columnId)],row._uniqueValuesCache[columnId])},"getUniqueValues"),renderValue:__name(columnId=>{var _row$getValue;return(_row$getValue=row.getValue(columnId))!=null?_row$getValue:table2.options.renderFallbackValue},"renderValue"),subRows:[],getLeafRows:__name(()=>flattenBy(row.subRows,d=>d.subRows),"getLeafRows"),getParentRow:__name(()=>row.parentId?table2.getRow(row.parentId,!0):void 0,"getParentRow"),getParentRows:__name(()=>{let parentRows=[],currentRow=row;for(;;){const parentRow=currentRow.getParentRow();if(!parentRow)break;parentRows.push(parentRow),currentRow=parentRow}return parentRows.reverse()},"getParentRows"),getAllCells:memo(()=>[table2.getAllLeafColumns()],leafColumns=>leafColumns.map(column=>createCell(table2,row,column,column.id)),getMemoOptions(table2.options,"debugRows")),_getAllCellsByColumnId:memo(()=>[row.getAllCells()],allCells=>allCells.reduce((acc,cell)=>(acc[cell.column.id]=cell,acc),{}),getMemoOptions(table2.options,"debugRows"))};for(let i2=0;i2{column._getFacetedRowModel=table2.options.getFacetedRowModel&&table2.options.getFacetedRowModel(table2,column.id),column.getFacetedRowModel=()=>column._getFacetedRowModel?column._getFacetedRowModel():table2.getPreFilteredRowModel(),column._getFacetedUniqueValues=table2.options.getFacetedUniqueValues&&table2.options.getFacetedUniqueValues(table2,column.id),column.getFacetedUniqueValues=()=>column._getFacetedUniqueValues?column._getFacetedUniqueValues():new Map,column._getFacetedMinMaxValues=table2.options.getFacetedMinMaxValues&&table2.options.getFacetedMinMaxValues(table2,column.id),column.getFacetedMinMaxValues=()=>{if(column._getFacetedMinMaxValues)return column._getFacetedMinMaxValues()}},"createColumn")},includesString=__name((row,columnId,filterValue)=>{var _filterValue$toString,_row$getValue;const search2=filterValue==null||(_filterValue$toString=filterValue.toString())==null?void 0:_filterValue$toString.toLowerCase();return!!(!((_row$getValue=row.getValue(columnId))==null||(_row$getValue=_row$getValue.toString())==null||(_row$getValue=_row$getValue.toLowerCase())==null)&&_row$getValue.includes(search2))},"includesString");includesString.autoRemove=val=>testFalsey(val);const includesStringSensitive=__name((row,columnId,filterValue)=>{var _row$getValue2;return!!(!((_row$getValue2=row.getValue(columnId))==null||(_row$getValue2=_row$getValue2.toString())==null)&&_row$getValue2.includes(filterValue))},"includesStringSensitive");includesStringSensitive.autoRemove=val=>testFalsey(val);const equalsString=__name((row,columnId,filterValue)=>{var _row$getValue3;return((_row$getValue3=row.getValue(columnId))==null||(_row$getValue3=_row$getValue3.toString())==null?void 0:_row$getValue3.toLowerCase())===filterValue?.toLowerCase()},"equalsString");equalsString.autoRemove=val=>testFalsey(val);const arrIncludes=__name((row,columnId,filterValue)=>{var _row$getValue4;return(_row$getValue4=row.getValue(columnId))==null?void 0:_row$getValue4.includes(filterValue)},"arrIncludes");arrIncludes.autoRemove=val=>testFalsey(val);const arrIncludesAll=__name((row,columnId,filterValue)=>!filterValue.some(val=>{var _row$getValue5;return!((_row$getValue5=row.getValue(columnId))!=null&&_row$getValue5.includes(val))}),"arrIncludesAll");arrIncludesAll.autoRemove=val=>testFalsey(val)||!(val!=null&&val.length);const arrIncludesSome=__name((row,columnId,filterValue)=>filterValue.some(val=>{var _row$getValue6;return(_row$getValue6=row.getValue(columnId))==null?void 0:_row$getValue6.includes(val)}),"arrIncludesSome");arrIncludesSome.autoRemove=val=>testFalsey(val)||!(val!=null&&val.length);const equals=__name((row,columnId,filterValue)=>row.getValue(columnId)===filterValue,"equals");equals.autoRemove=val=>testFalsey(val);const weakEquals=__name((row,columnId,filterValue)=>row.getValue(columnId)==filterValue,"weakEquals");weakEquals.autoRemove=val=>testFalsey(val);const inNumberRange=__name((row,columnId,filterValue)=>{let[min2,max2]=filterValue;const rowValue=row.getValue(columnId);return rowValue>=min2&&rowValue<=max2},"inNumberRange");inNumberRange.resolveFilterValue=val=>{let[unsafeMin,unsafeMax]=val,parsedMin=typeof unsafeMin!="number"?parseFloat(unsafeMin):unsafeMin,parsedMax=typeof unsafeMax!="number"?parseFloat(unsafeMax):unsafeMax,min2=unsafeMin===null||Number.isNaN(parsedMin)?-1/0:parsedMin,max2=unsafeMax===null||Number.isNaN(parsedMax)?1/0:parsedMax;if(min2>max2){const temp=min2;min2=max2,max2=temp}return[min2,max2]};inNumberRange.autoRemove=val=>testFalsey(val)||testFalsey(val[0])&&testFalsey(val[1]);const filterFns={includesString,includesStringSensitive,equalsString,arrIncludes,arrIncludesAll,arrIncludesSome,equals,weakEquals,inNumberRange};function testFalsey(val){return val==null||val===""}__name(testFalsey,"testFalsey");const ColumnFiltering={getDefaultColumnDef:__name(()=>({filterFn:"auto"}),"getDefaultColumnDef"),getInitialState:__name(state=>({columnFilters:[],...state}),"getInitialState"),getDefaultOptions:__name(table2=>({onColumnFiltersChange:makeStateUpdater("columnFilters",table2),filterFromLeafRows:!1,maxLeafRowFilterDepth:100}),"getDefaultOptions"),createColumn:__name((column,table2)=>{column.getAutoFilterFn=()=>{const firstRow=table2.getCoreRowModel().flatRows[0],value2=firstRow?.getValue(column.id);return typeof value2=="string"?filterFns.includesString:typeof value2=="number"?filterFns.inNumberRange:typeof value2=="boolean"||value2!==null&&typeof value2=="object"?filterFns.equals:Array.isArray(value2)?filterFns.arrIncludes:filterFns.weakEquals},column.getFilterFn=()=>{var _table$options$filter,_table$options$filter2;return isFunction(column.columnDef.filterFn)?column.columnDef.filterFn:column.columnDef.filterFn==="auto"?column.getAutoFilterFn():(_table$options$filter=(_table$options$filter2=table2.options.filterFns)==null?void 0:_table$options$filter2[column.columnDef.filterFn])!=null?_table$options$filter:filterFns[column.columnDef.filterFn]},column.getCanFilter=()=>{var _column$columnDef$ena,_table$options$enable,_table$options$enable2;return((_column$columnDef$ena=column.columnDef.enableColumnFilter)!=null?_column$columnDef$ena:!0)&&((_table$options$enable=table2.options.enableColumnFilters)!=null?_table$options$enable:!0)&&((_table$options$enable2=table2.options.enableFilters)!=null?_table$options$enable2:!0)&&!!column.accessorFn},column.getIsFiltered=()=>column.getFilterIndex()>-1,column.getFilterValue=()=>{var _table$getState$colum;return(_table$getState$colum=table2.getState().columnFilters)==null||(_table$getState$colum=_table$getState$colum.find(d=>d.id===column.id))==null?void 0:_table$getState$colum.value},column.getFilterIndex=()=>{var _table$getState$colum2,_table$getState$colum3;return(_table$getState$colum2=(_table$getState$colum3=table2.getState().columnFilters)==null?void 0:_table$getState$colum3.findIndex(d=>d.id===column.id))!=null?_table$getState$colum2:-1},column.setFilterValue=value2=>{table2.setColumnFilters(old=>{const filterFn=column.getFilterFn(),previousFilter=old?.find(d=>d.id===column.id),newFilter=functionalUpdate(value2,previousFilter?previousFilter.value:void 0);if(shouldAutoRemoveFilter(filterFn,newFilter,column)){var _old$filter;return(_old$filter=old?.filter(d=>d.id!==column.id))!=null?_old$filter:[]}const newFilterObj={id:column.id,value:newFilter};if(previousFilter){var _old$map;return(_old$map=old?.map(d=>d.id===column.id?newFilterObj:d))!=null?_old$map:[]}return old!=null&&old.length?[...old,newFilterObj]:[newFilterObj]})}},"createColumn"),createRow:__name((row,_table)=>{row.columnFilters={},row.columnFiltersMeta={}},"createRow"),createTable:__name(table2=>{table2.setColumnFilters=updater=>{const leafColumns=table2.getAllLeafColumns(),updateFn=__name(old=>{var _functionalUpdate;return(_functionalUpdate=functionalUpdate(updater,old))==null?void 0:_functionalUpdate.filter(filter=>{const column=leafColumns.find(d=>d.id===filter.id);if(column){const filterFn=column.getFilterFn();if(shouldAutoRemoveFilter(filterFn,filter.value,column))return!1}return!0})},"updateFn");table2.options.onColumnFiltersChange==null||table2.options.onColumnFiltersChange(updateFn)},table2.resetColumnFilters=defaultState=>{var _table$initialState$c,_table$initialState;table2.setColumnFilters(defaultState?[]:(_table$initialState$c=(_table$initialState=table2.initialState)==null?void 0:_table$initialState.columnFilters)!=null?_table$initialState$c:[])},table2.getPreFilteredRowModel=()=>table2.getCoreRowModel(),table2.getFilteredRowModel=()=>(!table2._getFilteredRowModel&&table2.options.getFilteredRowModel&&(table2._getFilteredRowModel=table2.options.getFilteredRowModel(table2)),table2.options.manualFiltering||!table2._getFilteredRowModel?table2.getPreFilteredRowModel():table2._getFilteredRowModel())},"createTable")};function shouldAutoRemoveFilter(filterFn,value2,column){return(filterFn&&filterFn.autoRemove?filterFn.autoRemove(value2,column):!1)||typeof value2>"u"||typeof value2=="string"&&!value2}__name(shouldAutoRemoveFilter,"shouldAutoRemoveFilter");const sum=__name((columnId,_leafRows,childRows)=>childRows.reduce((sum2,next2)=>{const nextValue=next2.getValue(columnId);return sum2+(typeof nextValue=="number"?nextValue:0)},0),"sum"),min=__name((columnId,_leafRows,childRows)=>{let min2;return childRows.forEach(row=>{const value2=row.getValue(columnId);value2!=null&&(min2>value2||min2===void 0&&value2>=value2)&&(min2=value2)}),min2},"min"),max=__name((columnId,_leafRows,childRows)=>{let max2;return childRows.forEach(row=>{const value2=row.getValue(columnId);value2!=null&&(max2=value2)&&(max2=value2)}),max2},"max"),extent=__name((columnId,_leafRows,childRows)=>{let min2,max2;return childRows.forEach(row=>{const value2=row.getValue(columnId);value2!=null&&(min2===void 0?value2>=value2&&(min2=max2=value2):(min2>value2&&(min2=value2),max2{let count2=0,sum2=0;if(leafRows.forEach(row=>{let value2=row.getValue(columnId);value2!=null&&(value2=+value2)>=value2&&(++count2,sum2+=value2)}),count2)return sum2/count2},"mean"),median=__name((columnId,leafRows)=>{if(!leafRows.length)return;const values=leafRows.map(row=>row.getValue(columnId));if(!isNumberArray(values))return;if(values.length===1)return values[0];const mid=Math.floor(values.length/2),nums=values.sort((a2,b2)=>a2-b2);return values.length%2!==0?nums[mid]:(nums[mid-1]+nums[mid])/2},"median"),unique=__name((columnId,leafRows)=>Array.from(new Set(leafRows.map(d=>d.getValue(columnId))).values()),"unique"),uniqueCount=__name((columnId,leafRows)=>new Set(leafRows.map(d=>d.getValue(columnId))).size,"uniqueCount"),count=__name((_columnId,leafRows)=>leafRows.length,"count"),aggregationFns={sum,min,max,extent,mean,median,unique,uniqueCount,count},ColumnGrouping={getDefaultColumnDef:__name(()=>({aggregatedCell:__name(props=>{var _toString,_props$getValue;return(_toString=(_props$getValue=props.getValue())==null||_props$getValue.toString==null?void 0:_props$getValue.toString())!=null?_toString:null},"aggregatedCell"),aggregationFn:"auto"}),"getDefaultColumnDef"),getInitialState:__name(state=>({grouping:[],...state}),"getInitialState"),getDefaultOptions:__name(table2=>({onGroupingChange:makeStateUpdater("grouping",table2),groupedColumnMode:"reorder"}),"getDefaultOptions"),createColumn:__name((column,table2)=>{column.toggleGrouping=()=>{table2.setGrouping(old=>old!=null&&old.includes(column.id)?old.filter(d=>d!==column.id):[...old??[],column.id])},column.getCanGroup=()=>{var _column$columnDef$ena,_table$options$enable;return((_column$columnDef$ena=column.columnDef.enableGrouping)!=null?_column$columnDef$ena:!0)&&((_table$options$enable=table2.options.enableGrouping)!=null?_table$options$enable:!0)&&(!!column.accessorFn||!!column.columnDef.getGroupingValue)},column.getIsGrouped=()=>{var _table$getState$group;return(_table$getState$group=table2.getState().grouping)==null?void 0:_table$getState$group.includes(column.id)},column.getGroupedIndex=()=>{var _table$getState$group2;return(_table$getState$group2=table2.getState().grouping)==null?void 0:_table$getState$group2.indexOf(column.id)},column.getToggleGroupingHandler=()=>{const canGroup=column.getCanGroup();return()=>{canGroup&&column.toggleGrouping()}},column.getAutoAggregationFn=()=>{const firstRow=table2.getCoreRowModel().flatRows[0],value2=firstRow?.getValue(column.id);if(typeof value2=="number")return aggregationFns.sum;if(Object.prototype.toString.call(value2)==="[object Date]")return aggregationFns.extent},column.getAggregationFn=()=>{var _table$options$aggreg,_table$options$aggreg2;if(!column)throw new Error;return isFunction(column.columnDef.aggregationFn)?column.columnDef.aggregationFn:column.columnDef.aggregationFn==="auto"?column.getAutoAggregationFn():(_table$options$aggreg=(_table$options$aggreg2=table2.options.aggregationFns)==null?void 0:_table$options$aggreg2[column.columnDef.aggregationFn])!=null?_table$options$aggreg:aggregationFns[column.columnDef.aggregationFn]}},"createColumn"),createTable:__name(table2=>{table2.setGrouping=updater=>table2.options.onGroupingChange==null?void 0:table2.options.onGroupingChange(updater),table2.resetGrouping=defaultState=>{var _table$initialState$g,_table$initialState;table2.setGrouping(defaultState?[]:(_table$initialState$g=(_table$initialState=table2.initialState)==null?void 0:_table$initialState.grouping)!=null?_table$initialState$g:[])},table2.getPreGroupedRowModel=()=>table2.getFilteredRowModel(),table2.getGroupedRowModel=()=>(!table2._getGroupedRowModel&&table2.options.getGroupedRowModel&&(table2._getGroupedRowModel=table2.options.getGroupedRowModel(table2)),table2.options.manualGrouping||!table2._getGroupedRowModel?table2.getPreGroupedRowModel():table2._getGroupedRowModel())},"createTable"),createRow:__name((row,table2)=>{row.getIsGrouped=()=>!!row.groupingColumnId,row.getGroupingValue=columnId=>{if(row._groupingValuesCache.hasOwnProperty(columnId))return row._groupingValuesCache[columnId];const column=table2.getColumn(columnId);return column!=null&&column.columnDef.getGroupingValue?(row._groupingValuesCache[columnId]=column.columnDef.getGroupingValue(row.original),row._groupingValuesCache[columnId]):row.getValue(columnId)},row._groupingValuesCache={}},"createRow"),createCell:__name((cell,column,row,table2)=>{cell.getIsGrouped=()=>column.getIsGrouped()&&column.id===row.groupingColumnId,cell.getIsPlaceholder=()=>!cell.getIsGrouped()&&column.getIsGrouped(),cell.getIsAggregated=()=>{var _row$subRows;return!cell.getIsGrouped()&&!cell.getIsPlaceholder()&&!!((_row$subRows=row.subRows)!=null&&_row$subRows.length)}},"createCell")};function orderColumns(leafColumns,grouping,groupedColumnMode){if(!(grouping!=null&&grouping.length)||!groupedColumnMode)return leafColumns;const nonGroupingColumns=leafColumns.filter(col=>!grouping.includes(col.id));return groupedColumnMode==="remove"?nonGroupingColumns:[...grouping.map(g2=>leafColumns.find(col=>col.id===g2)).filter(Boolean),...nonGroupingColumns]}__name(orderColumns,"orderColumns");const ColumnOrdering={getInitialState:__name(state=>({columnOrder:[],...state}),"getInitialState"),getDefaultOptions:__name(table2=>({onColumnOrderChange:makeStateUpdater("columnOrder",table2)}),"getDefaultOptions"),createColumn:__name((column,table2)=>{column.getIndex=memo(position2=>[_getVisibleLeafColumns(table2,position2)],columns2=>columns2.findIndex(d=>d.id===column.id),getMemoOptions(table2.options,"debugColumns")),column.getIsFirstColumn=position2=>{var _columns$;return((_columns$=_getVisibleLeafColumns(table2,position2)[0])==null?void 0:_columns$.id)===column.id},column.getIsLastColumn=position2=>{var _columns;const columns2=_getVisibleLeafColumns(table2,position2);return((_columns=columns2[columns2.length-1])==null?void 0:_columns.id)===column.id}},"createColumn"),createTable:__name(table2=>{table2.setColumnOrder=updater=>table2.options.onColumnOrderChange==null?void 0:table2.options.onColumnOrderChange(updater),table2.resetColumnOrder=defaultState=>{var _table$initialState$c;table2.setColumnOrder(defaultState?[]:(_table$initialState$c=table2.initialState.columnOrder)!=null?_table$initialState$c:[])},table2._getOrderColumnsFn=memo(()=>[table2.getState().columnOrder,table2.getState().grouping,table2.options.groupedColumnMode],(columnOrder,grouping,groupedColumnMode)=>columns2=>{let orderedColumns=[];if(!(columnOrder!=null&&columnOrder.length))orderedColumns=columns2;else{const columnOrderCopy=[...columnOrder],columnsCopy=[...columns2];for(;columnsCopy.length&&columnOrderCopy.length;){const targetColumnId=columnOrderCopy.shift(),foundIndex=columnsCopy.findIndex(d=>d.id===targetColumnId);foundIndex>-1&&orderedColumns.push(columnsCopy.splice(foundIndex,1)[0])}orderedColumns=[...orderedColumns,...columnsCopy]}return orderColumns(orderedColumns,grouping,groupedColumnMode)},getMemoOptions(table2.options,"debugTable"))},"createTable")},getDefaultColumnPinningState=__name(()=>({left:[],right:[]}),"getDefaultColumnPinningState"),ColumnPinning={getInitialState:__name(state=>({columnPinning:getDefaultColumnPinningState(),...state}),"getInitialState"),getDefaultOptions:__name(table2=>({onColumnPinningChange:makeStateUpdater("columnPinning",table2)}),"getDefaultOptions"),createColumn:__name((column,table2)=>{column.pin=position2=>{const columnIds=column.getLeafColumns().map(d=>d.id).filter(Boolean);table2.setColumnPinning(old=>{var _old$left3,_old$right3;if(position2==="right"){var _old$left,_old$right;return{left:((_old$left=old?.left)!=null?_old$left:[]).filter(d=>!(columnIds!=null&&columnIds.includes(d))),right:[...((_old$right=old?.right)!=null?_old$right:[]).filter(d=>!(columnIds!=null&&columnIds.includes(d))),...columnIds]}}if(position2==="left"){var _old$left2,_old$right2;return{left:[...((_old$left2=old?.left)!=null?_old$left2:[]).filter(d=>!(columnIds!=null&&columnIds.includes(d))),...columnIds],right:((_old$right2=old?.right)!=null?_old$right2:[]).filter(d=>!(columnIds!=null&&columnIds.includes(d)))}}return{left:((_old$left3=old?.left)!=null?_old$left3:[]).filter(d=>!(columnIds!=null&&columnIds.includes(d))),right:((_old$right3=old?.right)!=null?_old$right3:[]).filter(d=>!(columnIds!=null&&columnIds.includes(d)))}})},column.getCanPin=()=>column.getLeafColumns().some(d=>{var _d$columnDef$enablePi,_ref,_table$options$enable;return((_d$columnDef$enablePi=d.columnDef.enablePinning)!=null?_d$columnDef$enablePi:!0)&&((_ref=(_table$options$enable=table2.options.enableColumnPinning)!=null?_table$options$enable:table2.options.enablePinning)!=null?_ref:!0)}),column.getIsPinned=()=>{const leafColumnIds=column.getLeafColumns().map(d=>d.id),{left:left2,right:right2}=table2.getState().columnPinning,isLeft=leafColumnIds.some(d=>left2?.includes(d)),isRight=leafColumnIds.some(d=>right2?.includes(d));return isLeft?"left":isRight?"right":!1},column.getPinnedIndex=()=>{var _table$getState$colum,_table$getState$colum2;const position2=column.getIsPinned();return position2?(_table$getState$colum=(_table$getState$colum2=table2.getState().columnPinning)==null||(_table$getState$colum2=_table$getState$colum2[position2])==null?void 0:_table$getState$colum2.indexOf(column.id))!=null?_table$getState$colum:-1:0}},"createColumn"),createRow:__name((row,table2)=>{row.getCenterVisibleCells=memo(()=>[row._getAllVisibleCells(),table2.getState().columnPinning.left,table2.getState().columnPinning.right],(allCells,left2,right2)=>{const leftAndRight=[...left2??[],...right2??[]];return allCells.filter(d=>!leftAndRight.includes(d.column.id))},getMemoOptions(table2.options,"debugRows")),row.getLeftVisibleCells=memo(()=>[row._getAllVisibleCells(),table2.getState().columnPinning.left],(allCells,left2)=>(left2??[]).map(columnId=>allCells.find(cell=>cell.column.id===columnId)).filter(Boolean).map(d=>({...d,position:"left"})),getMemoOptions(table2.options,"debugRows")),row.getRightVisibleCells=memo(()=>[row._getAllVisibleCells(),table2.getState().columnPinning.right],(allCells,right2)=>(right2??[]).map(columnId=>allCells.find(cell=>cell.column.id===columnId)).filter(Boolean).map(d=>({...d,position:"right"})),getMemoOptions(table2.options,"debugRows"))},"createRow"),createTable:__name(table2=>{table2.setColumnPinning=updater=>table2.options.onColumnPinningChange==null?void 0:table2.options.onColumnPinningChange(updater),table2.resetColumnPinning=defaultState=>{var _table$initialState$c,_table$initialState;return table2.setColumnPinning(defaultState?getDefaultColumnPinningState():(_table$initialState$c=(_table$initialState=table2.initialState)==null?void 0:_table$initialState.columnPinning)!=null?_table$initialState$c:getDefaultColumnPinningState())},table2.getIsSomeColumnsPinned=position2=>{var _pinningState$positio;const pinningState=table2.getState().columnPinning;if(!position2){var _pinningState$left,_pinningState$right;return!!((_pinningState$left=pinningState.left)!=null&&_pinningState$left.length||(_pinningState$right=pinningState.right)!=null&&_pinningState$right.length)}return!!((_pinningState$positio=pinningState[position2])!=null&&_pinningState$positio.length)},table2.getLeftLeafColumns=memo(()=>[table2.getAllLeafColumns(),table2.getState().columnPinning.left],(allColumns,left2)=>(left2??[]).map(columnId=>allColumns.find(column=>column.id===columnId)).filter(Boolean),getMemoOptions(table2.options,"debugColumns")),table2.getRightLeafColumns=memo(()=>[table2.getAllLeafColumns(),table2.getState().columnPinning.right],(allColumns,right2)=>(right2??[]).map(columnId=>allColumns.find(column=>column.id===columnId)).filter(Boolean),getMemoOptions(table2.options,"debugColumns")),table2.getCenterLeafColumns=memo(()=>[table2.getAllLeafColumns(),table2.getState().columnPinning.left,table2.getState().columnPinning.right],(allColumns,left2,right2)=>{const leftAndRight=[...left2??[],...right2??[]];return allColumns.filter(d=>!leftAndRight.includes(d.id))},getMemoOptions(table2.options,"debugColumns"))},"createTable")};function safelyAccessDocument(_document){return _document||(typeof document<"u"?document:null)}__name(safelyAccessDocument,"safelyAccessDocument");const defaultColumnSizing={size:150,minSize:20,maxSize:Number.MAX_SAFE_INTEGER},getDefaultColumnSizingInfoState=__name(()=>({startOffset:null,startSize:null,deltaOffset:null,deltaPercentage:null,isResizingColumn:!1,columnSizingStart:[]}),"getDefaultColumnSizingInfoState"),ColumnSizing={getDefaultColumnDef:__name(()=>defaultColumnSizing,"getDefaultColumnDef"),getInitialState:__name(state=>({columnSizing:{},columnSizingInfo:getDefaultColumnSizingInfoState(),...state}),"getInitialState"),getDefaultOptions:__name(table2=>({columnResizeMode:"onEnd",columnResizeDirection:"ltr",onColumnSizingChange:makeStateUpdater("columnSizing",table2),onColumnSizingInfoChange:makeStateUpdater("columnSizingInfo",table2)}),"getDefaultOptions"),createColumn:__name((column,table2)=>{column.getSize=()=>{var _column$columnDef$min,_ref,_column$columnDef$max;const columnSize=table2.getState().columnSizing[column.id];return Math.min(Math.max((_column$columnDef$min=column.columnDef.minSize)!=null?_column$columnDef$min:defaultColumnSizing.minSize,(_ref=columnSize??column.columnDef.size)!=null?_ref:defaultColumnSizing.size),(_column$columnDef$max=column.columnDef.maxSize)!=null?_column$columnDef$max:defaultColumnSizing.maxSize)},column.getStart=memo(position2=>[position2,_getVisibleLeafColumns(table2,position2),table2.getState().columnSizing],(position2,columns2)=>columns2.slice(0,column.getIndex(position2)).reduce((sum2,column2)=>sum2+column2.getSize(),0),getMemoOptions(table2.options,"debugColumns")),column.getAfter=memo(position2=>[position2,_getVisibleLeafColumns(table2,position2),table2.getState().columnSizing],(position2,columns2)=>columns2.slice(column.getIndex(position2)+1).reduce((sum2,column2)=>sum2+column2.getSize(),0),getMemoOptions(table2.options,"debugColumns")),column.resetSize=()=>{table2.setColumnSizing(_ref2=>{let{[column.id]:_2,...rest}=_ref2;return rest})},column.getCanResize=()=>{var _column$columnDef$ena,_table$options$enable;return((_column$columnDef$ena=column.columnDef.enableResizing)!=null?_column$columnDef$ena:!0)&&((_table$options$enable=table2.options.enableColumnResizing)!=null?_table$options$enable:!0)},column.getIsResizing=()=>table2.getState().columnSizingInfo.isResizingColumn===column.id},"createColumn"),createHeader:__name((header,table2)=>{header.getSize=()=>{let sum2=0;const recurse=__name(header2=>{if(header2.subHeaders.length)header2.subHeaders.forEach(recurse);else{var _header$column$getSiz;sum2+=(_header$column$getSiz=header2.column.getSize())!=null?_header$column$getSiz:0}},"recurse");return recurse(header),sum2},header.getStart=()=>{if(header.index>0){const prevSiblingHeader=header.headerGroup.headers[header.index-1];return prevSiblingHeader.getStart()+prevSiblingHeader.getSize()}return 0},header.getResizeHandler=_contextDocument=>{const column=table2.getColumn(header.column.id),canResize=column?.getCanResize();return e3=>{if(!column||!canResize||(e3.persist==null||e3.persist(),isTouchStartEvent(e3)&&e3.touches&&e3.touches.length>1))return;const startSize=header.getSize(),columnSizingStart=header?header.getLeafHeaders().map(d=>[d.column.id,d.column.getSize()]):[[column.id,column.getSize()]],clientX=isTouchStartEvent(e3)?Math.round(e3.touches[0].clientX):e3.clientX,newColumnSizing={},updateOffset=__name((eventType,clientXPos)=>{typeof clientXPos=="number"&&(table2.setColumnSizingInfo(old=>{var _old$startOffset,_old$startSize;const deltaDirection=table2.options.columnResizeDirection==="rtl"?-1:1,deltaOffset=(clientXPos-((_old$startOffset=old?.startOffset)!=null?_old$startOffset:0))*deltaDirection,deltaPercentage=Math.max(deltaOffset/((_old$startSize=old?.startSize)!=null?_old$startSize:0),-.999999);return old.columnSizingStart.forEach(_ref3=>{let[columnId,headerSize]=_ref3;newColumnSizing[columnId]=Math.round(Math.max(headerSize+headerSize*deltaPercentage,0)*100)/100}),{...old,deltaOffset,deltaPercentage}}),(table2.options.columnResizeMode==="onChange"||eventType==="end")&&table2.setColumnSizing(old=>({...old,...newColumnSizing})))},"updateOffset"),onMove=__name(clientXPos=>updateOffset("move",clientXPos),"onMove"),onEnd=__name(clientXPos=>{updateOffset("end",clientXPos),table2.setColumnSizingInfo(old=>({...old,isResizingColumn:!1,startOffset:null,startSize:null,deltaOffset:null,deltaPercentage:null,columnSizingStart:[]}))},"onEnd"),contextDocument=safelyAccessDocument(_contextDocument),mouseEvents={moveHandler:__name(e22=>onMove(e22.clientX),"moveHandler"),upHandler:__name(e22=>{contextDocument?.removeEventListener("mousemove",mouseEvents.moveHandler),contextDocument?.removeEventListener("mouseup",mouseEvents.upHandler),onEnd(e22.clientX)},"upHandler")},touchEvents={moveHandler:__name(e22=>(e22.cancelable&&(e22.preventDefault(),e22.stopPropagation()),onMove(e22.touches[0].clientX),!1),"moveHandler"),upHandler:__name(e22=>{var _e$touches$;contextDocument?.removeEventListener("touchmove",touchEvents.moveHandler),contextDocument?.removeEventListener("touchend",touchEvents.upHandler),e22.cancelable&&(e22.preventDefault(),e22.stopPropagation()),onEnd((_e$touches$=e22.touches[0])==null?void 0:_e$touches$.clientX)},"upHandler")},passiveIfSupported=passiveEventSupported()?{passive:!1}:!1;isTouchStartEvent(e3)?(contextDocument?.addEventListener("touchmove",touchEvents.moveHandler,passiveIfSupported),contextDocument?.addEventListener("touchend",touchEvents.upHandler,passiveIfSupported)):(contextDocument?.addEventListener("mousemove",mouseEvents.moveHandler,passiveIfSupported),contextDocument?.addEventListener("mouseup",mouseEvents.upHandler,passiveIfSupported)),table2.setColumnSizingInfo(old=>({...old,startOffset:clientX,startSize,deltaOffset:0,deltaPercentage:0,columnSizingStart,isResizingColumn:column.id}))}}},"createHeader"),createTable:__name(table2=>{table2.setColumnSizing=updater=>table2.options.onColumnSizingChange==null?void 0:table2.options.onColumnSizingChange(updater),table2.setColumnSizingInfo=updater=>table2.options.onColumnSizingInfoChange==null?void 0:table2.options.onColumnSizingInfoChange(updater),table2.resetColumnSizing=defaultState=>{var _table$initialState$c;table2.setColumnSizing(defaultState?{}:(_table$initialState$c=table2.initialState.columnSizing)!=null?_table$initialState$c:{})},table2.resetHeaderSizeInfo=defaultState=>{var _table$initialState$c2;table2.setColumnSizingInfo(defaultState?getDefaultColumnSizingInfoState():(_table$initialState$c2=table2.initialState.columnSizingInfo)!=null?_table$initialState$c2:getDefaultColumnSizingInfoState())},table2.getTotalSize=()=>{var _table$getHeaderGroup,_table$getHeaderGroup2;return(_table$getHeaderGroup=(_table$getHeaderGroup2=table2.getHeaderGroups()[0])==null?void 0:_table$getHeaderGroup2.headers.reduce((sum2,header)=>sum2+header.getSize(),0))!=null?_table$getHeaderGroup:0},table2.getLeftTotalSize=()=>{var _table$getLeftHeaderG,_table$getLeftHeaderG2;return(_table$getLeftHeaderG=(_table$getLeftHeaderG2=table2.getLeftHeaderGroups()[0])==null?void 0:_table$getLeftHeaderG2.headers.reduce((sum2,header)=>sum2+header.getSize(),0))!=null?_table$getLeftHeaderG:0},table2.getCenterTotalSize=()=>{var _table$getCenterHeade,_table$getCenterHeade2;return(_table$getCenterHeade=(_table$getCenterHeade2=table2.getCenterHeaderGroups()[0])==null?void 0:_table$getCenterHeade2.headers.reduce((sum2,header)=>sum2+header.getSize(),0))!=null?_table$getCenterHeade:0},table2.getRightTotalSize=()=>{var _table$getRightHeader,_table$getRightHeader2;return(_table$getRightHeader=(_table$getRightHeader2=table2.getRightHeaderGroups()[0])==null?void 0:_table$getRightHeader2.headers.reduce((sum2,header)=>sum2+header.getSize(),0))!=null?_table$getRightHeader:0}},"createTable")};let passiveSupported=null;function passiveEventSupported(){if(typeof passiveSupported=="boolean")return passiveSupported;let supported=!1;try{const options={get passive(){return supported=!0,!1}},noop22=__name(()=>{},"noop2");window.addEventListener("test",noop22,options),window.removeEventListener("test",noop22)}catch{supported=!1}return passiveSupported=supported,passiveSupported}__name(passiveEventSupported,"passiveEventSupported");function isTouchStartEvent(e3){return e3.type==="touchstart"}__name(isTouchStartEvent,"isTouchStartEvent");const ColumnVisibility={getInitialState:__name(state=>({columnVisibility:{},...state}),"getInitialState"),getDefaultOptions:__name(table2=>({onColumnVisibilityChange:makeStateUpdater("columnVisibility",table2)}),"getDefaultOptions"),createColumn:__name((column,table2)=>{column.toggleVisibility=value2=>{column.getCanHide()&&table2.setColumnVisibility(old=>({...old,[column.id]:value2??!column.getIsVisible()}))},column.getIsVisible=()=>{var _ref,_table$getState$colum;const childColumns=column.columns;return(_ref=childColumns.length?childColumns.some(c2=>c2.getIsVisible()):(_table$getState$colum=table2.getState().columnVisibility)==null?void 0:_table$getState$colum[column.id])!=null?_ref:!0},column.getCanHide=()=>{var _column$columnDef$ena,_table$options$enable;return((_column$columnDef$ena=column.columnDef.enableHiding)!=null?_column$columnDef$ena:!0)&&((_table$options$enable=table2.options.enableHiding)!=null?_table$options$enable:!0)},column.getToggleVisibilityHandler=()=>e3=>{column.toggleVisibility==null||column.toggleVisibility(e3.target.checked)}},"createColumn"),createRow:__name((row,table2)=>{row._getAllVisibleCells=memo(()=>[row.getAllCells(),table2.getState().columnVisibility],cells=>cells.filter(cell=>cell.column.getIsVisible()),getMemoOptions(table2.options,"debugRows")),row.getVisibleCells=memo(()=>[row.getLeftVisibleCells(),row.getCenterVisibleCells(),row.getRightVisibleCells()],(left2,center2,right2)=>[...left2,...center2,...right2],getMemoOptions(table2.options,"debugRows"))},"createRow"),createTable:__name(table2=>{const makeVisibleColumnsMethod=__name((key,getColumns)=>memo(()=>[getColumns(),getColumns().filter(d=>d.getIsVisible()).map(d=>d.id).join("_")],columns2=>columns2.filter(d=>d.getIsVisible==null?void 0:d.getIsVisible()),getMemoOptions(table2.options,"debugColumns")),"makeVisibleColumnsMethod");table2.getVisibleFlatColumns=makeVisibleColumnsMethod("getVisibleFlatColumns",()=>table2.getAllFlatColumns()),table2.getVisibleLeafColumns=makeVisibleColumnsMethod("getVisibleLeafColumns",()=>table2.getAllLeafColumns()),table2.getLeftVisibleLeafColumns=makeVisibleColumnsMethod("getLeftVisibleLeafColumns",()=>table2.getLeftLeafColumns()),table2.getRightVisibleLeafColumns=makeVisibleColumnsMethod("getRightVisibleLeafColumns",()=>table2.getRightLeafColumns()),table2.getCenterVisibleLeafColumns=makeVisibleColumnsMethod("getCenterVisibleLeafColumns",()=>table2.getCenterLeafColumns()),table2.setColumnVisibility=updater=>table2.options.onColumnVisibilityChange==null?void 0:table2.options.onColumnVisibilityChange(updater),table2.resetColumnVisibility=defaultState=>{var _table$initialState$c;table2.setColumnVisibility(defaultState?{}:(_table$initialState$c=table2.initialState.columnVisibility)!=null?_table$initialState$c:{})},table2.toggleAllColumnsVisible=value2=>{var _value;value2=(_value=value2)!=null?_value:!table2.getIsAllColumnsVisible(),table2.setColumnVisibility(table2.getAllLeafColumns().reduce((obj,column)=>({...obj,[column.id]:value2||!(column.getCanHide!=null&&column.getCanHide())}),{}))},table2.getIsAllColumnsVisible=()=>!table2.getAllLeafColumns().some(column=>!(column.getIsVisible!=null&&column.getIsVisible())),table2.getIsSomeColumnsVisible=()=>table2.getAllLeafColumns().some(column=>column.getIsVisible==null?void 0:column.getIsVisible()),table2.getToggleAllColumnsVisibilityHandler=()=>e3=>{var _target;table2.toggleAllColumnsVisible((_target=e3.target)==null?void 0:_target.checked)}},"createTable")};function _getVisibleLeafColumns(table2,position2){return position2?position2==="center"?table2.getCenterVisibleLeafColumns():position2==="left"?table2.getLeftVisibleLeafColumns():table2.getRightVisibleLeafColumns():table2.getVisibleLeafColumns()}__name(_getVisibleLeafColumns,"_getVisibleLeafColumns");const GlobalFaceting={createTable:__name(table2=>{table2._getGlobalFacetedRowModel=table2.options.getFacetedRowModel&&table2.options.getFacetedRowModel(table2,"__global__"),table2.getGlobalFacetedRowModel=()=>table2.options.manualFiltering||!table2._getGlobalFacetedRowModel?table2.getPreFilteredRowModel():table2._getGlobalFacetedRowModel(),table2._getGlobalFacetedUniqueValues=table2.options.getFacetedUniqueValues&&table2.options.getFacetedUniqueValues(table2,"__global__"),table2.getGlobalFacetedUniqueValues=()=>table2._getGlobalFacetedUniqueValues?table2._getGlobalFacetedUniqueValues():new Map,table2._getGlobalFacetedMinMaxValues=table2.options.getFacetedMinMaxValues&&table2.options.getFacetedMinMaxValues(table2,"__global__"),table2.getGlobalFacetedMinMaxValues=()=>{if(table2._getGlobalFacetedMinMaxValues)return table2._getGlobalFacetedMinMaxValues()}},"createTable")},GlobalFiltering={getInitialState:__name(state=>({globalFilter:void 0,...state}),"getInitialState"),getDefaultOptions:__name(table2=>({onGlobalFilterChange:makeStateUpdater("globalFilter",table2),globalFilterFn:"auto",getColumnCanGlobalFilter:__name(column=>{var _table$getCoreRowMode;const value2=(_table$getCoreRowMode=table2.getCoreRowModel().flatRows[0])==null||(_table$getCoreRowMode=_table$getCoreRowMode._getAllCellsByColumnId()[column.id])==null?void 0:_table$getCoreRowMode.getValue();return typeof value2=="string"||typeof value2=="number"},"getColumnCanGlobalFilter")}),"getDefaultOptions"),createColumn:__name((column,table2)=>{column.getCanGlobalFilter=()=>{var _column$columnDef$ena,_table$options$enable,_table$options$enable2,_table$options$getCol;return((_column$columnDef$ena=column.columnDef.enableGlobalFilter)!=null?_column$columnDef$ena:!0)&&((_table$options$enable=table2.options.enableGlobalFilter)!=null?_table$options$enable:!0)&&((_table$options$enable2=table2.options.enableFilters)!=null?_table$options$enable2:!0)&&((_table$options$getCol=table2.options.getColumnCanGlobalFilter==null?void 0:table2.options.getColumnCanGlobalFilter(column))!=null?_table$options$getCol:!0)&&!!column.accessorFn}},"createColumn"),createTable:__name(table2=>{table2.getGlobalAutoFilterFn=()=>filterFns.includesString,table2.getGlobalFilterFn=()=>{var _table$options$filter,_table$options$filter2;const{globalFilterFn}=table2.options;return isFunction(globalFilterFn)?globalFilterFn:globalFilterFn==="auto"?table2.getGlobalAutoFilterFn():(_table$options$filter=(_table$options$filter2=table2.options.filterFns)==null?void 0:_table$options$filter2[globalFilterFn])!=null?_table$options$filter:filterFns[globalFilterFn]},table2.setGlobalFilter=updater=>{table2.options.onGlobalFilterChange==null||table2.options.onGlobalFilterChange(updater)},table2.resetGlobalFilter=defaultState=>{table2.setGlobalFilter(defaultState?void 0:table2.initialState.globalFilter)}},"createTable")},RowExpanding={getInitialState:__name(state=>({expanded:{},...state}),"getInitialState"),getDefaultOptions:__name(table2=>({onExpandedChange:makeStateUpdater("expanded",table2),paginateExpandedRows:!0}),"getDefaultOptions"),createTable:__name(table2=>{let registered=!1,queued=!1;table2._autoResetExpanded=()=>{var _ref,_table$options$autoRe;if(!registered){table2._queue(()=>{registered=!0});return}if((_ref=(_table$options$autoRe=table2.options.autoResetAll)!=null?_table$options$autoRe:table2.options.autoResetExpanded)!=null?_ref:!table2.options.manualExpanding){if(queued)return;queued=!0,table2._queue(()=>{table2.resetExpanded(),queued=!1})}},table2.setExpanded=updater=>table2.options.onExpandedChange==null?void 0:table2.options.onExpandedChange(updater),table2.toggleAllRowsExpanded=expanded=>{expanded??!table2.getIsAllRowsExpanded()?table2.setExpanded(!0):table2.setExpanded({})},table2.resetExpanded=defaultState=>{var _table$initialState$e,_table$initialState;table2.setExpanded(defaultState?{}:(_table$initialState$e=(_table$initialState=table2.initialState)==null?void 0:_table$initialState.expanded)!=null?_table$initialState$e:{})},table2.getCanSomeRowsExpand=()=>table2.getPrePaginationRowModel().flatRows.some(row=>row.getCanExpand()),table2.getToggleAllRowsExpandedHandler=()=>e3=>{e3.persist==null||e3.persist(),table2.toggleAllRowsExpanded()},table2.getIsSomeRowsExpanded=()=>{const expanded=table2.getState().expanded;return expanded===!0||Object.values(expanded).some(Boolean)},table2.getIsAllRowsExpanded=()=>{const expanded=table2.getState().expanded;return typeof expanded=="boolean"?expanded===!0:!(!Object.keys(expanded).length||table2.getRowModel().flatRows.some(row=>!row.getIsExpanded()))},table2.getExpandedDepth=()=>{let maxDepth=0;return(table2.getState().expanded===!0?Object.keys(table2.getRowModel().rowsById):Object.keys(table2.getState().expanded)).forEach(id=>{const splitId=id.split(".");maxDepth=Math.max(maxDepth,splitId.length)}),maxDepth},table2.getPreExpandedRowModel=()=>table2.getSortedRowModel(),table2.getExpandedRowModel=()=>(!table2._getExpandedRowModel&&table2.options.getExpandedRowModel&&(table2._getExpandedRowModel=table2.options.getExpandedRowModel(table2)),table2.options.manualExpanding||!table2._getExpandedRowModel?table2.getPreExpandedRowModel():table2._getExpandedRowModel())},"createTable"),createRow:__name((row,table2)=>{row.toggleExpanded=expanded=>{table2.setExpanded(old=>{var _expanded;const exists=old===!0?!0:!!(old!=null&&old[row.id]);let oldExpanded={};if(old===!0?Object.keys(table2.getRowModel().rowsById).forEach(rowId=>{oldExpanded[rowId]=!0}):oldExpanded=old,expanded=(_expanded=expanded)!=null?_expanded:!exists,!exists&&expanded)return{...oldExpanded,[row.id]:!0};if(exists&&!expanded){const{[row.id]:_2,...rest}=oldExpanded;return rest}return old})},row.getIsExpanded=()=>{var _table$options$getIsR;const expanded=table2.getState().expanded;return!!((_table$options$getIsR=table2.options.getIsRowExpanded==null?void 0:table2.options.getIsRowExpanded(row))!=null?_table$options$getIsR:expanded===!0||expanded?.[row.id])},row.getCanExpand=()=>{var _table$options$getRow,_table$options$enable,_row$subRows;return(_table$options$getRow=table2.options.getRowCanExpand==null?void 0:table2.options.getRowCanExpand(row))!=null?_table$options$getRow:((_table$options$enable=table2.options.enableExpanding)!=null?_table$options$enable:!0)&&!!((_row$subRows=row.subRows)!=null&&_row$subRows.length)},row.getIsAllParentsExpanded=()=>{let isFullyExpanded=!0,currentRow=row;for(;isFullyExpanded&¤tRow.parentId;)currentRow=table2.getRow(currentRow.parentId,!0),isFullyExpanded=currentRow.getIsExpanded();return isFullyExpanded},row.getToggleExpandedHandler=()=>{const canExpand=row.getCanExpand();return()=>{canExpand&&row.toggleExpanded()}}},"createRow")},defaultPageIndex=0,defaultPageSize=10,getDefaultPaginationState=__name(()=>({pageIndex:defaultPageIndex,pageSize:defaultPageSize}),"getDefaultPaginationState"),RowPagination={getInitialState:__name(state=>({...state,pagination:{...getDefaultPaginationState(),...state?.pagination}}),"getInitialState"),getDefaultOptions:__name(table2=>({onPaginationChange:makeStateUpdater("pagination",table2)}),"getDefaultOptions"),createTable:__name(table2=>{let registered=!1,queued=!1;table2._autoResetPageIndex=()=>{var _ref,_table$options$autoRe;if(!registered){table2._queue(()=>{registered=!0});return}if((_ref=(_table$options$autoRe=table2.options.autoResetAll)!=null?_table$options$autoRe:table2.options.autoResetPageIndex)!=null?_ref:!table2.options.manualPagination){if(queued)return;queued=!0,table2._queue(()=>{table2.resetPageIndex(),queued=!1})}},table2.setPagination=updater=>{const safeUpdater=__name(old=>functionalUpdate(updater,old),"safeUpdater");return table2.options.onPaginationChange==null?void 0:table2.options.onPaginationChange(safeUpdater)},table2.resetPagination=defaultState=>{var _table$initialState$p;table2.setPagination(defaultState?getDefaultPaginationState():(_table$initialState$p=table2.initialState.pagination)!=null?_table$initialState$p:getDefaultPaginationState())},table2.setPageIndex=updater=>{table2.setPagination(old=>{let pageIndex=functionalUpdate(updater,old.pageIndex);const maxPageIndex=typeof table2.options.pageCount>"u"||table2.options.pageCount===-1?Number.MAX_SAFE_INTEGER:table2.options.pageCount-1;return pageIndex=Math.max(0,Math.min(pageIndex,maxPageIndex)),{...old,pageIndex}})},table2.resetPageIndex=defaultState=>{var _table$initialState$p2,_table$initialState;table2.setPageIndex(defaultState?defaultPageIndex:(_table$initialState$p2=(_table$initialState=table2.initialState)==null||(_table$initialState=_table$initialState.pagination)==null?void 0:_table$initialState.pageIndex)!=null?_table$initialState$p2:defaultPageIndex)},table2.resetPageSize=defaultState=>{var _table$initialState$p3,_table$initialState2;table2.setPageSize(defaultState?defaultPageSize:(_table$initialState$p3=(_table$initialState2=table2.initialState)==null||(_table$initialState2=_table$initialState2.pagination)==null?void 0:_table$initialState2.pageSize)!=null?_table$initialState$p3:defaultPageSize)},table2.setPageSize=updater=>{table2.setPagination(old=>{const pageSize=Math.max(1,functionalUpdate(updater,old.pageSize)),topRowIndex=old.pageSize*old.pageIndex,pageIndex=Math.floor(topRowIndex/pageSize);return{...old,pageIndex,pageSize}})},table2.setPageCount=updater=>table2.setPagination(old=>{var _table$options$pageCo;let newPageCount=functionalUpdate(updater,(_table$options$pageCo=table2.options.pageCount)!=null?_table$options$pageCo:-1);return typeof newPageCount=="number"&&(newPageCount=Math.max(-1,newPageCount)),{...old,pageCount:newPageCount}}),table2.getPageOptions=memo(()=>[table2.getPageCount()],pageCount=>{let pageOptions=[];return pageCount&&pageCount>0&&(pageOptions=[...new Array(pageCount)].fill(null).map((_2,i2)=>i2)),pageOptions},getMemoOptions(table2.options,"debugTable")),table2.getCanPreviousPage=()=>table2.getState().pagination.pageIndex>0,table2.getCanNextPage=()=>{const{pageIndex}=table2.getState().pagination,pageCount=table2.getPageCount();return pageCount===-1?!0:pageCount===0?!1:pageIndextable2.setPageIndex(old=>old-1),table2.nextPage=()=>table2.setPageIndex(old=>old+1),table2.firstPage=()=>table2.setPageIndex(0),table2.lastPage=()=>table2.setPageIndex(table2.getPageCount()-1),table2.getPrePaginationRowModel=()=>table2.getExpandedRowModel(),table2.getPaginationRowModel=()=>(!table2._getPaginationRowModel&&table2.options.getPaginationRowModel&&(table2._getPaginationRowModel=table2.options.getPaginationRowModel(table2)),table2.options.manualPagination||!table2._getPaginationRowModel?table2.getPrePaginationRowModel():table2._getPaginationRowModel()),table2.getPageCount=()=>{var _table$options$pageCo2;return(_table$options$pageCo2=table2.options.pageCount)!=null?_table$options$pageCo2:Math.ceil(table2.getRowCount()/table2.getState().pagination.pageSize)},table2.getRowCount=()=>{var _table$options$rowCou;return(_table$options$rowCou=table2.options.rowCount)!=null?_table$options$rowCou:table2.getPrePaginationRowModel().rows.length}},"createTable")},getDefaultRowPinningState=__name(()=>({top:[],bottom:[]}),"getDefaultRowPinningState"),RowPinning={getInitialState:__name(state=>({rowPinning:getDefaultRowPinningState(),...state}),"getInitialState"),getDefaultOptions:__name(table2=>({onRowPinningChange:makeStateUpdater("rowPinning",table2)}),"getDefaultOptions"),createRow:__name((row,table2)=>{row.pin=(position2,includeLeafRows,includeParentRows)=>{const leafRowIds=includeLeafRows?row.getLeafRows().map(_ref=>{let{id}=_ref;return id}):[],parentRowIds=includeParentRows?row.getParentRows().map(_ref2=>{let{id}=_ref2;return id}):[],rowIds=new Set([...parentRowIds,row.id,...leafRowIds]);table2.setRowPinning(old=>{var _old$top3,_old$bottom3;if(position2==="bottom"){var _old$top,_old$bottom;return{top:((_old$top=old?.top)!=null?_old$top:[]).filter(d=>!(rowIds!=null&&rowIds.has(d))),bottom:[...((_old$bottom=old?.bottom)!=null?_old$bottom:[]).filter(d=>!(rowIds!=null&&rowIds.has(d))),...Array.from(rowIds)]}}if(position2==="top"){var _old$top2,_old$bottom2;return{top:[...((_old$top2=old?.top)!=null?_old$top2:[]).filter(d=>!(rowIds!=null&&rowIds.has(d))),...Array.from(rowIds)],bottom:((_old$bottom2=old?.bottom)!=null?_old$bottom2:[]).filter(d=>!(rowIds!=null&&rowIds.has(d)))}}return{top:((_old$top3=old?.top)!=null?_old$top3:[]).filter(d=>!(rowIds!=null&&rowIds.has(d))),bottom:((_old$bottom3=old?.bottom)!=null?_old$bottom3:[]).filter(d=>!(rowIds!=null&&rowIds.has(d)))}})},row.getCanPin=()=>{var _ref3;const{enableRowPinning,enablePinning}=table2.options;return typeof enableRowPinning=="function"?enableRowPinning(row):(_ref3=enableRowPinning??enablePinning)!=null?_ref3:!0},row.getIsPinned=()=>{const rowIds=[row.id],{top,bottom}=table2.getState().rowPinning,isTop=rowIds.some(d=>top?.includes(d)),isBottom=rowIds.some(d=>bottom?.includes(d));return isTop?"top":isBottom?"bottom":!1},row.getPinnedIndex=()=>{var _ref4,_visiblePinnedRowIds$;const position2=row.getIsPinned();if(!position2)return-1;const visiblePinnedRowIds=(_ref4=position2==="top"?table2.getTopRows():table2.getBottomRows())==null?void 0:_ref4.map(_ref5=>{let{id}=_ref5;return id});return(_visiblePinnedRowIds$=visiblePinnedRowIds?.indexOf(row.id))!=null?_visiblePinnedRowIds$:-1}},"createRow"),createTable:__name(table2=>{table2.setRowPinning=updater=>table2.options.onRowPinningChange==null?void 0:table2.options.onRowPinningChange(updater),table2.resetRowPinning=defaultState=>{var _table$initialState$r,_table$initialState;return table2.setRowPinning(defaultState?getDefaultRowPinningState():(_table$initialState$r=(_table$initialState=table2.initialState)==null?void 0:_table$initialState.rowPinning)!=null?_table$initialState$r:getDefaultRowPinningState())},table2.getIsSomeRowsPinned=position2=>{var _pinningState$positio;const pinningState=table2.getState().rowPinning;if(!position2){var _pinningState$top,_pinningState$bottom;return!!((_pinningState$top=pinningState.top)!=null&&_pinningState$top.length||(_pinningState$bottom=pinningState.bottom)!=null&&_pinningState$bottom.length)}return!!((_pinningState$positio=pinningState[position2])!=null&&_pinningState$positio.length)},table2._getPinnedRows=(visibleRows,pinnedRowIds,position2)=>{var _table$options$keepPi;return((_table$options$keepPi=table2.options.keepPinnedRows)==null||_table$options$keepPi?(pinnedRowIds??[]).map(rowId=>{const row=table2.getRow(rowId,!0);return row.getIsAllParentsExpanded()?row:null}):(pinnedRowIds??[]).map(rowId=>visibleRows.find(row=>row.id===rowId))).filter(Boolean).map(d=>({...d,position:position2}))},table2.getTopRows=memo(()=>[table2.getRowModel().rows,table2.getState().rowPinning.top],(allRows,topPinnedRowIds)=>table2._getPinnedRows(allRows,topPinnedRowIds,"top"),getMemoOptions(table2.options,"debugRows")),table2.getBottomRows=memo(()=>[table2.getRowModel().rows,table2.getState().rowPinning.bottom],(allRows,bottomPinnedRowIds)=>table2._getPinnedRows(allRows,bottomPinnedRowIds,"bottom"),getMemoOptions(table2.options,"debugRows")),table2.getCenterRows=memo(()=>[table2.getRowModel().rows,table2.getState().rowPinning.top,table2.getState().rowPinning.bottom],(allRows,top,bottom)=>{const topAndBottom=new Set([...top??[],...bottom??[]]);return allRows.filter(d=>!topAndBottom.has(d.id))},getMemoOptions(table2.options,"debugRows"))},"createTable")},RowSelection={getInitialState:__name(state=>({rowSelection:{},...state}),"getInitialState"),getDefaultOptions:__name(table2=>({onRowSelectionChange:makeStateUpdater("rowSelection",table2),enableRowSelection:!0,enableMultiRowSelection:!0,enableSubRowSelection:!0}),"getDefaultOptions"),createTable:__name(table2=>{table2.setRowSelection=updater=>table2.options.onRowSelectionChange==null?void 0:table2.options.onRowSelectionChange(updater),table2.resetRowSelection=defaultState=>{var _table$initialState$r;return table2.setRowSelection(defaultState?{}:(_table$initialState$r=table2.initialState.rowSelection)!=null?_table$initialState$r:{})},table2.toggleAllRowsSelected=value2=>{table2.setRowSelection(old=>{value2=typeof value2<"u"?value2:!table2.getIsAllRowsSelected();const rowSelection={...old},preGroupedFlatRows=table2.getPreGroupedRowModel().flatRows;return value2?preGroupedFlatRows.forEach(row=>{row.getCanSelect()&&(rowSelection[row.id]=!0)}):preGroupedFlatRows.forEach(row=>{delete rowSelection[row.id]}),rowSelection})},table2.toggleAllPageRowsSelected=value2=>table2.setRowSelection(old=>{const resolvedValue=typeof value2<"u"?value2:!table2.getIsAllPageRowsSelected(),rowSelection={...old};return table2.getRowModel().rows.forEach(row=>{mutateRowIsSelected(rowSelection,row.id,resolvedValue,!0,table2)}),rowSelection}),table2.getPreSelectedRowModel=()=>table2.getCoreRowModel(),table2.getSelectedRowModel=memo(()=>[table2.getState().rowSelection,table2.getCoreRowModel()],(rowSelection,rowModel)=>Object.keys(rowSelection).length?selectRowsFn(table2,rowModel):{rows:[],flatRows:[],rowsById:{}},getMemoOptions(table2.options,"debugTable")),table2.getFilteredSelectedRowModel=memo(()=>[table2.getState().rowSelection,table2.getFilteredRowModel()],(rowSelection,rowModel)=>Object.keys(rowSelection).length?selectRowsFn(table2,rowModel):{rows:[],flatRows:[],rowsById:{}},getMemoOptions(table2.options,"debugTable")),table2.getGroupedSelectedRowModel=memo(()=>[table2.getState().rowSelection,table2.getSortedRowModel()],(rowSelection,rowModel)=>Object.keys(rowSelection).length?selectRowsFn(table2,rowModel):{rows:[],flatRows:[],rowsById:{}},getMemoOptions(table2.options,"debugTable")),table2.getIsAllRowsSelected=()=>{const preGroupedFlatRows=table2.getFilteredRowModel().flatRows,{rowSelection}=table2.getState();let isAllRowsSelected=!!(preGroupedFlatRows.length&&Object.keys(rowSelection).length);return isAllRowsSelected&&preGroupedFlatRows.some(row=>row.getCanSelect()&&!rowSelection[row.id])&&(isAllRowsSelected=!1),isAllRowsSelected},table2.getIsAllPageRowsSelected=()=>{const paginationFlatRows=table2.getPaginationRowModel().flatRows.filter(row=>row.getCanSelect()),{rowSelection}=table2.getState();let isAllPageRowsSelected=!!paginationFlatRows.length;return isAllPageRowsSelected&&paginationFlatRows.some(row=>!rowSelection[row.id])&&(isAllPageRowsSelected=!1),isAllPageRowsSelected},table2.getIsSomeRowsSelected=()=>{var _table$getState$rowSe;const totalSelected=Object.keys((_table$getState$rowSe=table2.getState().rowSelection)!=null?_table$getState$rowSe:{}).length;return totalSelected>0&&totalSelected{const paginationFlatRows=table2.getPaginationRowModel().flatRows;return table2.getIsAllPageRowsSelected()?!1:paginationFlatRows.filter(row=>row.getCanSelect()).some(d=>d.getIsSelected()||d.getIsSomeSelected())},table2.getToggleAllRowsSelectedHandler=()=>e3=>{table2.toggleAllRowsSelected(e3.target.checked)},table2.getToggleAllPageRowsSelectedHandler=()=>e3=>{table2.toggleAllPageRowsSelected(e3.target.checked)}},"createTable"),createRow:__name((row,table2)=>{row.toggleSelected=(value2,opts)=>{const isSelected=row.getIsSelected();table2.setRowSelection(old=>{var _opts$selectChildren;if(value2=typeof value2<"u"?value2:!isSelected,row.getCanSelect()&&isSelected===value2)return old;const selectedRowIds={...old};return mutateRowIsSelected(selectedRowIds,row.id,value2,(_opts$selectChildren=opts?.selectChildren)!=null?_opts$selectChildren:!0,table2),selectedRowIds})},row.getIsSelected=()=>{const{rowSelection}=table2.getState();return isRowSelected(row,rowSelection)},row.getIsSomeSelected=()=>{const{rowSelection}=table2.getState();return isSubRowSelected(row,rowSelection)==="some"},row.getIsAllSubRowsSelected=()=>{const{rowSelection}=table2.getState();return isSubRowSelected(row,rowSelection)==="all"},row.getCanSelect=()=>{var _table$options$enable;return typeof table2.options.enableRowSelection=="function"?table2.options.enableRowSelection(row):(_table$options$enable=table2.options.enableRowSelection)!=null?_table$options$enable:!0},row.getCanSelectSubRows=()=>{var _table$options$enable2;return typeof table2.options.enableSubRowSelection=="function"?table2.options.enableSubRowSelection(row):(_table$options$enable2=table2.options.enableSubRowSelection)!=null?_table$options$enable2:!0},row.getCanMultiSelect=()=>{var _table$options$enable3;return typeof table2.options.enableMultiRowSelection=="function"?table2.options.enableMultiRowSelection(row):(_table$options$enable3=table2.options.enableMultiRowSelection)!=null?_table$options$enable3:!0},row.getToggleSelectedHandler=()=>{const canSelect=row.getCanSelect();return e3=>{var _target;canSelect&&row.toggleSelected((_target=e3.target)==null?void 0:_target.checked)}}},"createRow")},mutateRowIsSelected=__name((selectedRowIds,id,value2,includeChildren,table2)=>{var _row$subRows;const row=table2.getRow(id,!0);value2?(row.getCanMultiSelect()||Object.keys(selectedRowIds).forEach(key=>delete selectedRowIds[key]),row.getCanSelect()&&(selectedRowIds[id]=!0)):delete selectedRowIds[id],includeChildren&&(_row$subRows=row.subRows)!=null&&_row$subRows.length&&row.getCanSelectSubRows()&&row.subRows.forEach(row2=>mutateRowIsSelected(selectedRowIds,row2.id,value2,includeChildren,table2))},"mutateRowIsSelected");function selectRowsFn(table2,rowModel){const rowSelection=table2.getState().rowSelection,newSelectedFlatRows=[],newSelectedRowsById={},recurseRows=__name(function(rows,depth){return rows.map(row=>{var _row$subRows2;const isSelected=isRowSelected(row,rowSelection);if(isSelected&&(newSelectedFlatRows.push(row),newSelectedRowsById[row.id]=row),(_row$subRows2=row.subRows)!=null&&_row$subRows2.length&&(row={...row,subRows:recurseRows(row.subRows)}),isSelected)return row}).filter(Boolean)},"recurseRows");return{rows:recurseRows(rowModel.rows),flatRows:newSelectedFlatRows,rowsById:newSelectedRowsById}}__name(selectRowsFn,"selectRowsFn");function isRowSelected(row,selection){var _selection$row$id;return(_selection$row$id=selection[row.id])!=null?_selection$row$id:!1}__name(isRowSelected,"isRowSelected");function isSubRowSelected(row,selection,table2){var _row$subRows3;if(!((_row$subRows3=row.subRows)!=null&&_row$subRows3.length))return!1;let allChildrenSelected=!0,someSelected=!1;return row.subRows.forEach(subRow=>{if(!(someSelected&&!allChildrenSelected)&&(subRow.getCanSelect()&&(isRowSelected(subRow,selection)?someSelected=!0:allChildrenSelected=!1),subRow.subRows&&subRow.subRows.length)){const subRowChildrenSelected=isSubRowSelected(subRow,selection);subRowChildrenSelected==="all"?someSelected=!0:(subRowChildrenSelected==="some"&&(someSelected=!0),allChildrenSelected=!1)}}),allChildrenSelected?"all":someSelected?"some":!1}__name(isSubRowSelected,"isSubRowSelected");const reSplitAlphaNumeric=/([0-9]+)/gm,alphanumeric=__name((rowA,rowB,columnId)=>compareAlphanumeric(toString$2(rowA.getValue(columnId)).toLowerCase(),toString$2(rowB.getValue(columnId)).toLowerCase()),"alphanumeric"),alphanumericCaseSensitive=__name((rowA,rowB,columnId)=>compareAlphanumeric(toString$2(rowA.getValue(columnId)),toString$2(rowB.getValue(columnId))),"alphanumericCaseSensitive"),text$9=__name((rowA,rowB,columnId)=>compareBasic(toString$2(rowA.getValue(columnId)).toLowerCase(),toString$2(rowB.getValue(columnId)).toLowerCase()),"text$9"),textCaseSensitive=__name((rowA,rowB,columnId)=>compareBasic(toString$2(rowA.getValue(columnId)),toString$2(rowB.getValue(columnId))),"textCaseSensitive"),datetime=__name((rowA,rowB,columnId)=>{const a2=rowA.getValue(columnId),b2=rowB.getValue(columnId);return a2>b2?1:a2compareBasic(rowA.getValue(columnId),rowB.getValue(columnId)),"basic");function compareBasic(a2,b2){return a2===b2?0:a2>b2?1:-1}__name(compareBasic,"compareBasic");function toString$2(a2){return typeof a2=="number"?isNaN(a2)||a2===1/0||a2===-1/0?"":String(a2):typeof a2=="string"?a2:""}__name(toString$2,"toString$2");function compareAlphanumeric(aStr,bStr){const a2=aStr.split(reSplitAlphaNumeric).filter(Boolean),b2=bStr.split(reSplitAlphaNumeric).filter(Boolean);for(;a2.length&&b2.length;){const aa=a2.shift(),bb=b2.shift(),an2=parseInt(aa,10),bn2=parseInt(bb,10),combo=[an2,bn2].sort();if(isNaN(combo[0])){if(aa>bb)return 1;if(bb>aa)return-1;continue}if(isNaN(combo[1]))return isNaN(an2)?-1:1;if(an2>bn2)return 1;if(bn2>an2)return-1}return a2.length-b2.length}__name(compareAlphanumeric,"compareAlphanumeric");const sortingFns={alphanumeric,alphanumericCaseSensitive,text:text$9,textCaseSensitive,datetime,basic},RowSorting={getInitialState:__name(state=>({sorting:[],...state}),"getInitialState"),getDefaultColumnDef:__name(()=>({sortingFn:"auto",sortUndefined:1}),"getDefaultColumnDef"),getDefaultOptions:__name(table2=>({onSortingChange:makeStateUpdater("sorting",table2),isMultiSortEvent:__name(e3=>e3.shiftKey,"isMultiSortEvent")}),"getDefaultOptions"),createColumn:__name((column,table2)=>{column.getAutoSortingFn=()=>{const firstRows=table2.getFilteredRowModel().flatRows.slice(10);let isString=!1;for(const row of firstRows){const value2=row?.getValue(column.id);if(Object.prototype.toString.call(value2)==="[object Date]")return sortingFns.datetime;if(typeof value2=="string"&&(isString=!0,value2.split(reSplitAlphaNumeric).length>1))return sortingFns.alphanumeric}return isString?sortingFns.text:sortingFns.basic},column.getAutoSortDir=()=>{const firstRow=table2.getFilteredRowModel().flatRows[0];return typeof firstRow?.getValue(column.id)=="string"?"asc":"desc"},column.getSortingFn=()=>{var _table$options$sortin,_table$options$sortin2;if(!column)throw new Error;return isFunction(column.columnDef.sortingFn)?column.columnDef.sortingFn:column.columnDef.sortingFn==="auto"?column.getAutoSortingFn():(_table$options$sortin=(_table$options$sortin2=table2.options.sortingFns)==null?void 0:_table$options$sortin2[column.columnDef.sortingFn])!=null?_table$options$sortin:sortingFns[column.columnDef.sortingFn]},column.toggleSorting=(desc,multi)=>{const nextSortingOrder=column.getNextSortingOrder(),hasManualValue=typeof desc<"u"&&desc!==null;table2.setSorting(old=>{const existingSorting=old?.find(d=>d.id===column.id),existingIndex=old?.findIndex(d=>d.id===column.id);let newSorting=[],sortAction,nextDesc=hasManualValue?desc:nextSortingOrder==="desc";if(old!=null&&old.length&&column.getCanMultiSort()&&multi?existingSorting?sortAction="toggle":sortAction="add":old!=null&&old.length&&existingIndex!==old.length-1?sortAction="replace":existingSorting?sortAction="toggle":sortAction="replace",sortAction==="toggle"&&(hasManualValue||nextSortingOrder||(sortAction="remove")),sortAction==="add"){var _table$options$maxMul;newSorting=[...old,{id:column.id,desc:nextDesc}],newSorting.splice(0,newSorting.length-((_table$options$maxMul=table2.options.maxMultiSortColCount)!=null?_table$options$maxMul:Number.MAX_SAFE_INTEGER))}else sortAction==="toggle"?newSorting=old.map(d=>d.id===column.id?{...d,desc:nextDesc}:d):sortAction==="remove"?newSorting=old.filter(d=>d.id!==column.id):newSorting=[{id:column.id,desc:nextDesc}];return newSorting})},column.getFirstSortDir=()=>{var _ref,_column$columnDef$sor;return((_ref=(_column$columnDef$sor=column.columnDef.sortDescFirst)!=null?_column$columnDef$sor:table2.options.sortDescFirst)!=null?_ref:column.getAutoSortDir()==="desc")?"desc":"asc"},column.getNextSortingOrder=multi=>{var _table$options$enable,_table$options$enable2;const firstSortDirection=column.getFirstSortDir(),isSorted=column.getIsSorted();return isSorted?isSorted!==firstSortDirection&&((_table$options$enable=table2.options.enableSortingRemoval)==null||_table$options$enable)&&(!(multi&&(_table$options$enable2=table2.options.enableMultiRemove)!=null)||_table$options$enable2)?!1:isSorted==="desc"?"asc":"desc":firstSortDirection},column.getCanSort=()=>{var _column$columnDef$ena,_table$options$enable3;return((_column$columnDef$ena=column.columnDef.enableSorting)!=null?_column$columnDef$ena:!0)&&((_table$options$enable3=table2.options.enableSorting)!=null?_table$options$enable3:!0)&&!!column.accessorFn},column.getCanMultiSort=()=>{var _ref2,_column$columnDef$ena2;return(_ref2=(_column$columnDef$ena2=column.columnDef.enableMultiSort)!=null?_column$columnDef$ena2:table2.options.enableMultiSort)!=null?_ref2:!!column.accessorFn},column.getIsSorted=()=>{var _table$getState$sorti;const columnSort=(_table$getState$sorti=table2.getState().sorting)==null?void 0:_table$getState$sorti.find(d=>d.id===column.id);return columnSort?columnSort.desc?"desc":"asc":!1},column.getSortIndex=()=>{var _table$getState$sorti2,_table$getState$sorti3;return(_table$getState$sorti2=(_table$getState$sorti3=table2.getState().sorting)==null?void 0:_table$getState$sorti3.findIndex(d=>d.id===column.id))!=null?_table$getState$sorti2:-1},column.clearSorting=()=>{table2.setSorting(old=>old!=null&&old.length?old.filter(d=>d.id!==column.id):[])},column.getToggleSortingHandler=()=>{const canSort=column.getCanSort();return e3=>{canSort&&(e3.persist==null||e3.persist(),column.toggleSorting==null||column.toggleSorting(void 0,column.getCanMultiSort()?table2.options.isMultiSortEvent==null?void 0:table2.options.isMultiSortEvent(e3):!1))}}},"createColumn"),createTable:__name(table2=>{table2.setSorting=updater=>table2.options.onSortingChange==null?void 0:table2.options.onSortingChange(updater),table2.resetSorting=defaultState=>{var _table$initialState$s,_table$initialState;table2.setSorting(defaultState?[]:(_table$initialState$s=(_table$initialState=table2.initialState)==null?void 0:_table$initialState.sorting)!=null?_table$initialState$s:[])},table2.getPreSortedRowModel=()=>table2.getGroupedRowModel(),table2.getSortedRowModel=()=>(!table2._getSortedRowModel&&table2.options.getSortedRowModel&&(table2._getSortedRowModel=table2.options.getSortedRowModel(table2)),table2.options.manualSorting||!table2._getSortedRowModel?table2.getPreSortedRowModel():table2._getSortedRowModel())},"createTable")},builtInFeatures=[Headers$1,ColumnVisibility,ColumnOrdering,ColumnPinning,ColumnFaceting,ColumnFiltering,GlobalFaceting,GlobalFiltering,RowSorting,ColumnGrouping,RowExpanding,RowPagination,RowPinning,RowSelection,ColumnSizing];function createTable(options){var _options$_features,_options$initialState;const _features=[...builtInFeatures,...(_options$_features=options._features)!=null?_options$_features:[]];let table2={_features};const defaultOptions=table2._features.reduce((obj,feature)=>Object.assign(obj,feature.getDefaultOptions==null?void 0:feature.getDefaultOptions(table2)),{}),mergeOptions=__name(options2=>table2.options.mergeOptions?table2.options.mergeOptions(defaultOptions,options2):{...defaultOptions,...options2},"mergeOptions");let initialState2={...{},...(_options$initialState=options.initialState)!=null?_options$initialState:{}};table2._features.forEach(feature=>{var _feature$getInitialSt;initialState2=(_feature$getInitialSt=feature.getInitialState==null?void 0:feature.getInitialState(initialState2))!=null?_feature$getInitialSt:initialState2});const queued=[];let queuedTimeout=!1;const coreInstance={_features,options:{...defaultOptions,...options},initialState:initialState2,_queue:__name(cb=>{queued.push(cb),queuedTimeout||(queuedTimeout=!0,Promise.resolve().then(()=>{for(;queued.length;)queued.shift()();queuedTimeout=!1}).catch(error=>setTimeout(()=>{throw error})))},"_queue"),reset:__name(()=>{table2.setState(table2.initialState)},"reset"),setOptions:__name(updater=>{const newOptions=functionalUpdate(updater,table2.options);table2.options=mergeOptions(newOptions)},"setOptions"),getState:__name(()=>table2.options.state,"getState"),setState:__name(updater=>{table2.options.onStateChange==null||table2.options.onStateChange(updater)},"setState"),_getRowId:__name((row,index2,parent)=>{var _table$options$getRow;return(_table$options$getRow=table2.options.getRowId==null?void 0:table2.options.getRowId(row,index2,parent))!=null?_table$options$getRow:`${parent?[parent.id,index2].join("."):index2}`},"_getRowId"),getCoreRowModel:__name(()=>(table2._getCoreRowModel||(table2._getCoreRowModel=table2.options.getCoreRowModel(table2)),table2._getCoreRowModel()),"getCoreRowModel"),getRowModel:__name(()=>table2.getPaginationRowModel(),"getRowModel"),getRow:__name((id,searchAll)=>{let row=(searchAll?table2.getPrePaginationRowModel():table2.getRowModel()).rowsById[id];if(!row&&(row=table2.getCoreRowModel().rowsById[id],!row))throw new Error;return row},"getRow"),_getDefaultColumnDef:memo(()=>[table2.options.defaultColumn],defaultColumn=>{var _defaultColumn;return defaultColumn=(_defaultColumn=defaultColumn)!=null?_defaultColumn:{},{header:__name(props=>{const resolvedColumnDef=props.header.column.columnDef;return resolvedColumnDef.accessorKey?resolvedColumnDef.accessorKey:resolvedColumnDef.accessorFn?resolvedColumnDef.id:null},"header"),cell:__name(props=>{var _props$renderValue$to,_props$renderValue;return(_props$renderValue$to=(_props$renderValue=props.renderValue())==null||_props$renderValue.toString==null?void 0:_props$renderValue.toString())!=null?_props$renderValue$to:null},"cell"),...table2._features.reduce((obj,feature)=>Object.assign(obj,feature.getDefaultColumnDef==null?void 0:feature.getDefaultColumnDef()),{}),...defaultColumn}},getMemoOptions(options,"debugColumns")),_getColumnDefs:__name(()=>table2.options.columns,"_getColumnDefs"),getAllColumns:memo(()=>[table2._getColumnDefs()],columnDefs=>{const recurseColumns=__name(function(columnDefs2,parent,depth){return depth===void 0&&(depth=0),columnDefs2.map(columnDef=>{const column=createColumn(table2,columnDef,depth,parent),groupingColumnDef=columnDef;return column.columns=groupingColumnDef.columns?recurseColumns(groupingColumnDef.columns,column,depth+1):[],column})},"recurseColumns");return recurseColumns(columnDefs)},getMemoOptions(options,"debugColumns")),getAllFlatColumns:memo(()=>[table2.getAllColumns()],allColumns=>allColumns.flatMap(column=>column.getFlatColumns()),getMemoOptions(options,"debugColumns")),_getAllFlatColumnsById:memo(()=>[table2.getAllFlatColumns()],flatColumns=>flatColumns.reduce((acc,column)=>(acc[column.id]=column,acc),{}),getMemoOptions(options,"debugColumns")),getAllLeafColumns:memo(()=>[table2.getAllColumns(),table2._getOrderColumnsFn()],(allColumns,orderColumns2)=>{let leafColumns=allColumns.flatMap(column=>column.getLeafColumns());return orderColumns2(leafColumns)},getMemoOptions(options,"debugColumns")),getColumn:__name(columnId=>table2._getAllFlatColumnsById()[columnId],"getColumn")};Object.assign(table2,coreInstance);for(let index2=0;index2memo(()=>[table2.options.data],data=>{const rowModel={rows:[],flatRows:[],rowsById:{}},accessRows=__name(function(originalRows,depth,parentRow){depth===void 0&&(depth=0);const rows=[];for(let i2=0;i2table2._autoResetPageIndex()))}__name(getCoreRowModel,"getCoreRowModel");function filterRows(rows,filterRowImpl,table2){return table2.options.filterFromLeafRows?filterRowModelFromLeafs(rows,filterRowImpl,table2):filterRowModelFromRoot(rows,filterRowImpl,table2)}__name(filterRows,"filterRows");function filterRowModelFromLeafs(rowsToFilter,filterRow,table2){var _table$options$maxLea;const newFilteredFlatRows=[],newFilteredRowsById={},maxDepth=(_table$options$maxLea=table2.options.maxLeafRowFilterDepth)!=null?_table$options$maxLea:100,recurseFilterRows=__name(function(rowsToFilter2,depth){depth===void 0&&(depth=0);const rows=[];for(let i2=0;i2memo(()=>[table2.getPreFilteredRowModel(),table2.getState().columnFilters,table2.getState().globalFilter],(rowModel,columnFilters,globalFilter)=>{if(!rowModel.rows.length||!(columnFilters!=null&&columnFilters.length)&&!globalFilter){for(let i2=0;i2{var _filterFn$resolveFilt;const column=table2.getColumn(d.id);if(!column)return;const filterFn=column.getFilterFn();filterFn&&resolvedColumnFilters.push({id:d.id,filterFn,resolvedValue:(_filterFn$resolveFilt=filterFn.resolveFilterValue==null?void 0:filterFn.resolveFilterValue(d.value))!=null?_filterFn$resolveFilt:d.value})});const filterableIds=(columnFilters??[]).map(d=>d.id),globalFilterFn=table2.getGlobalFilterFn(),globallyFilterableColumns=table2.getAllLeafColumns().filter(column=>column.getCanGlobalFilter());globalFilter&&globalFilterFn&&globallyFilterableColumns.length&&(filterableIds.push("__global__"),globallyFilterableColumns.forEach(column=>{var _globalFilterFn$resol;resolvedGlobalFilters.push({id:column.id,filterFn:globalFilterFn,resolvedValue:(_globalFilterFn$resol=globalFilterFn.resolveFilterValue==null?void 0:globalFilterFn.resolveFilterValue(globalFilter))!=null?_globalFilterFn$resol:globalFilter})}));let currentColumnFilter,currentGlobalFilter;for(let j2=0;j2{row.columnFiltersMeta[id]=filterMeta})}if(resolvedGlobalFilters.length){for(let i2=0;i2{row.columnFiltersMeta[id]=filterMeta})){row.columnFilters.__global__=!0;break}}row.columnFilters.__global__!==!0&&(row.columnFilters.__global__=!1)}}const filterRowsImpl=__name(row=>{for(let i2=0;i2table2._autoResetPageIndex()))}__name(getFilteredRowModel,"getFilteredRowModel");function getSortedRowModel(){return table2=>memo(()=>[table2.getState().sorting,table2.getPreSortedRowModel()],(sorting,rowModel)=>{if(!rowModel.rows.length||!(sorting!=null&&sorting.length))return rowModel;const sortingState=table2.getState().sorting,sortedFlatRows=[],availableSorting=sortingState.filter(sort=>{var _table$getColumn;return(_table$getColumn=table2.getColumn(sort.id))==null?void 0:_table$getColumn.getCanSort()}),columnInfoById={};availableSorting.forEach(sortEntry=>{const column=table2.getColumn(sortEntry.id);column&&(columnInfoById[sortEntry.id]={sortUndefined:column.columnDef.sortUndefined,invertSorting:column.columnDef.invertSorting,sortingFn:column.getSortingFn()})});const sortData=__name(rows=>{const sortedData=rows.map(row=>({...row}));return sortedData.sort((rowA,rowB)=>{for(let i2=0;i2{var _row$subRows;sortedFlatRows.push(row),(_row$subRows=row.subRows)!=null&&_row$subRows.length&&(row.subRows=sortData(row.subRows))}),sortedData},"sortData");return{rows:sortData(rowModel.rows),flatRows:sortedFlatRows,rowsById:rowModel.rowsById}},getMemoOptions(table2.options,"debugTable","getSortedRowModel",()=>table2._autoResetPageIndex()))}__name(getSortedRowModel,"getSortedRowModel");function flexRender(Comp,props){return Comp?isReactComponent(Comp)?reactExports.createElement(Comp,props):Comp:null}__name(flexRender,"flexRender");function isReactComponent(component){return isClassComponent(component)||typeof component=="function"||isExoticComponent(component)}__name(isReactComponent,"isReactComponent");function isClassComponent(component){return typeof component=="function"&&(()=>{const proto2=Object.getPrototypeOf(component);return proto2.prototype&&proto2.prototype.isReactComponent})()}__name(isClassComponent,"isClassComponent");function isExoticComponent(component){return typeof component=="object"&&typeof component.$$typeof=="symbol"&&["react.memo","react.forward_ref"].includes(component.$$typeof.description)}__name(isExoticComponent,"isExoticComponent");function useReactTable(options){const resolvedOptions={state:{},onStateChange:__name(()=>{},"onStateChange"),renderFallbackValue:null,...options},[tableRef]=reactExports.useState(()=>({current:createTable(resolvedOptions)})),[state,setState]=reactExports.useState(()=>tableRef.current.initialState);return tableRef.current.setOptions(prev=>({...prev,...options,state:{...state,...options.state},onStateChange:__name(updater=>{setState(updater),options.onStateChange==null||options.onStateChange(updater)},"onStateChange")})),tableRef.current}__name(useReactTable,"useReactTable");const Table=reactExports.forwardRef(({className,...props},ref)=>jsxRuntimeExports.jsx("div",{className:"relative w-full overflow-auto",children:jsxRuntimeExports.jsx("table",{ref,className:cn$2("w-full caption-bottom text-sm",className),...props})}));Table.displayName="Table";const TableHeader=reactExports.forwardRef(({className,...props},ref)=>jsxRuntimeExports.jsx("thead",{ref,className:cn$2("[&_tr]:border-b",className),...props}));TableHeader.displayName="TableHeader";const TableBody=reactExports.forwardRef(({className,...props},ref)=>jsxRuntimeExports.jsx("tbody",{ref,className:cn$2("[&_tr:last-child]:border-0",className),...props}));TableBody.displayName="TableBody";const TableFooter=reactExports.forwardRef(({className,...props},ref)=>jsxRuntimeExports.jsx("tfoot",{ref,className:cn$2("border-t bg-muted/50 font-medium [&>tr]:last:border-b-0",className),...props}));TableFooter.displayName="TableFooter";const TableRow=reactExports.forwardRef(({className,...props},ref)=>jsxRuntimeExports.jsx("tr",{ref,className:cn$2("border-b transition-colors hover:bg-muted/50 data-[state=selected]:bg-muted",className),...props}));TableRow.displayName="TableRow";const TableHead=reactExports.forwardRef(({className,...props},ref)=>jsxRuntimeExports.jsx("th",{ref,className:cn$2("h-12 px-4 text-left align-middle font-medium text-muted-foreground [&:has([role=checkbox])]:pr-0",className),...props}));TableHead.displayName="TableHead";const TableCell=reactExports.forwardRef(({className,...props},ref)=>jsxRuntimeExports.jsx("td",{ref,className:cn$2("p-4 align-middle [&:has([role=checkbox])]:pr-0",className),...props}));TableCell.displayName="TableCell";const TableCaption=reactExports.forwardRef(({className,...props},ref)=>jsxRuntimeExports.jsx("caption",{ref,className:cn$2("mt-4 text-sm text-muted-foreground",className),...props}));TableCaption.displayName="TableCaption";function parse$2(value2){const tokens=[],input=String(value2||"");let index2=input.indexOf(","),start2=0,end=!1;for(;!end;){index2===-1&&(index2=input.length,end=!0);const token=input.slice(start2,index2).trim();(token||!end)&&tokens.push(token),start2=index2+1,index2=input.indexOf(",",start2)}return tokens}__name(parse$2,"parse$2");function stringify$1(values,options){const settings={};return(values[values.length-1]===""?[...values,""]:values).join((settings.padRight?" ":"")+","+(settings.padLeft===!1?"":" ")).trim()}__name(stringify$1,"stringify$1");const nameRe=/^[$_\p{ID_Start}][$_\u{200C}\u{200D}\p{ID_Continue}]*$/u,nameReJsx=/^[$_\p{ID_Start}][-$_\u{200C}\u{200D}\p{ID_Continue}]*$/u,emptyOptions$4={};function name(name2,options){return(emptyOptions$4.jsx?nameReJsx:nameRe).test(name2)}__name(name,"name");const re=/[ \t\n\f\r]/g;function whitespace(thing){return typeof thing=="object"?thing.type==="text"?empty$1(thing.value):!1:empty$1(thing)}__name(whitespace,"whitespace");function empty$1(value2){return value2.replace(re,"")===""}__name(empty$1,"empty$1");const _Schema=class _Schema{constructor(property,normal,space2){this.normal=normal,this.property=property,space2&&(this.space=space2)}};__name(_Schema,"Schema");let Schema=_Schema;Schema.prototype.normal={};Schema.prototype.property={};Schema.prototype.space=void 0;function merge(definitions,space2){const property={},normal={};for(const definition2 of definitions)Object.assign(property,definition2.property),Object.assign(normal,definition2.normal);return new Schema(property,normal,space2)}__name(merge,"merge");function normalize$1(value2){return value2.toLowerCase()}__name(normalize$1,"normalize$1");const _Info=class _Info{constructor(property,attribute){this.attribute=attribute,this.property=property}};__name(_Info,"Info");let Info=_Info;Info.prototype.attribute="";Info.prototype.booleanish=!1;Info.prototype.boolean=!1;Info.prototype.commaOrSpaceSeparated=!1;Info.prototype.commaSeparated=!1;Info.prototype.defined=!1;Info.prototype.mustUseProperty=!1;Info.prototype.number=!1;Info.prototype.overloadedBoolean=!1;Info.prototype.property="";Info.prototype.spaceSeparated=!1;Info.prototype.space=void 0;let powers=0;const boolean=increment(),booleanish=increment(),overloadedBoolean=increment(),number=increment(),spaceSeparated=increment(),commaSeparated=increment(),commaOrSpaceSeparated=increment();function increment(){return 2**++powers}__name(increment,"increment");const types=Object.freeze(Object.defineProperty({__proto__:null,boolean,booleanish,commaOrSpaceSeparated,commaSeparated,number,overloadedBoolean,spaceSeparated},Symbol.toStringTag,{value:"Module"})),checks=Object.keys(types),_DefinedInfo=class _DefinedInfo extends Info{constructor(property,attribute,mask,space2){let index2=-1;if(super(property,attribute),mark(this,"space",space2),typeof mask=="number")for(;++index24&&normal.slice(0,4)==="data"&&valid.test(value2)){if(value2.charAt(4)==="-"){const rest=value2.slice(5).replace(dash,camelcase);property="data"+rest.charAt(0).toUpperCase()+rest.slice(1)}else{const rest=value2.slice(4);if(!dash.test(rest)){let dashes=rest.replace(cap$1,kebab);dashes.charAt(0)!=="-"&&(dashes="-"+dashes),value2="data"+dashes}}Type=DefinedInfo}return new Type(property,value2)}__name(find,"find");function kebab($0){return"-"+$0.toLowerCase()}__name(kebab,"kebab");function camelcase($0){return $0.charAt(1).toUpperCase()}__name(camelcase,"camelcase");const html$2=merge([aria$1,html$3,xlink,xmlns,xml],"html"),svg=merge([aria$1,svg$1,xlink,xmlns,xml],"svg");function parse$1(value2){const input=String(value2||"").trim();return input?input.split(/[ \t\n\r\f]+/g):[]}__name(parse$1,"parse$1");function stringify(values){return values.join(" ").trim()}__name(stringify,"stringify");var cjs$2={},cjs$1,hasRequiredCjs$2;function requireCjs$2(){if(hasRequiredCjs$2)return cjs$1;hasRequiredCjs$2=1;var COMMENT_REGEX=/\/\*[^*]*\*+([^/*][^*]*\*+)*\//g,NEWLINE_REGEX=/\n/g,WHITESPACE_REGEX=/^\s*/,PROPERTY_REGEX=/^(\*?[-#/*\\\w]+(\[[0-9a-z_-]+\])?)\s*/,COLON_REGEX=/^:\s*/,VALUE_REGEX=/^((?:'(?:\\'|.)*?'|"(?:\\"|.)*?"|\([^)]*?\)|[^};])+)/,SEMICOLON_REGEX=/^[;\s]*/,TRIM_REGEX=/^\s+|\s+$/g,NEWLINE=` @@ -190,11 +196,11 @@ `,...tracker.current()});return/^[\t ]/.test(value2)&&(value2=encodeCharacterReference(value2.charCodeAt(0))+value2.slice(1)),value2=value2?sequence2+" "+value2:sequence2,state.options.closeAtx&&(value2+=" "+sequence2),subexit(),exit2(),value2}__name(heading,"heading");html.peek=htmlPeek;function html(node2){return node2.value||""}__name(html,"html");function htmlPeek(){return"<"}__name(htmlPeek,"htmlPeek");image.peek=imagePeek;function image(node2,_2,state,info){const quote=checkQuote(state),suffix=quote==='"'?"Quote":"Apostrophe",exit2=state.enter("image");let subexit=state.enter("label");const tracker=state.createTracker(info);let value2=tracker.move("![");return value2+=tracker.move(state.safe(node2.alt,{before:value2,after:"]",...tracker.current()})),value2+=tracker.move("]("),subexit(),!node2.url&&node2.title||/[\0- \u007F]/.test(node2.url)?(subexit=state.enter("destinationLiteral"),value2+=tracker.move("<"),value2+=tracker.move(state.safe(node2.url,{before:value2,after:">",...tracker.current()})),value2+=tracker.move(">")):(subexit=state.enter("destinationRaw"),value2+=tracker.move(state.safe(node2.url,{before:value2,after:node2.title?" ":")",...tracker.current()}))),subexit(),node2.title&&(subexit=state.enter(`title${suffix}`),value2+=tracker.move(" "+quote),value2+=tracker.move(state.safe(node2.title,{before:value2,after:quote,...tracker.current()})),value2+=tracker.move(quote),subexit()),value2+=tracker.move(")"),exit2(),value2}__name(image,"image");function imagePeek(){return"!"}__name(imagePeek,"imagePeek");imageReference.peek=imageReferencePeek;function imageReference(node2,_2,state,info){const type=node2.referenceType,exit2=state.enter("imageReference");let subexit=state.enter("label");const tracker=state.createTracker(info);let value2=tracker.move("![");const alt=state.safe(node2.alt,{before:value2,after:"]",...tracker.current()});value2+=tracker.move(alt+"]["),subexit();const stack=state.stack;state.stack=[],subexit=state.enter("reference");const reference=state.safe(state.associationId(node2),{before:value2,after:"]",...tracker.current()});return subexit(),state.stack=stack,exit2(),type==="full"||!alt||alt!==reference?value2+=tracker.move(reference+"]"):type==="shortcut"?value2=value2.slice(0,-1):value2+=tracker.move("]"),value2}__name(imageReference,"imageReference");function imageReferencePeek(){return"!"}__name(imageReferencePeek,"imageReferencePeek");inlineCode.peek=inlineCodePeek;function inlineCode(node2,_2,state){let value2=node2.value||"",sequence2="`",index2=-1;for(;new RegExp("(^|[^`])"+sequence2+"([^`]|$)").test(value2);)sequence2+="`";for(/[^ \r\n]/.test(value2)&&(/^[ \r\n]/.test(value2)&&/[ \r\n]$/.test(value2)||/^`|`$/.test(value2))&&(value2=" "+value2+" ");++index2\u007F]/.test(node2.url))}__name(formatLinkAsAutolink,"formatLinkAsAutolink");link.peek=linkPeek;function link(node2,_2,state,info){const quote=checkQuote(state),suffix=quote==='"'?"Quote":"Apostrophe",tracker=state.createTracker(info);let exit2,subexit;if(formatLinkAsAutolink(node2,state)){const stack=state.stack;state.stack=[],exit2=state.enter("autolink");let value3=tracker.move("<");return value3+=tracker.move(state.containerPhrasing(node2,{before:value3,after:">",...tracker.current()})),value3+=tracker.move(">"),exit2(),state.stack=stack,value3}exit2=state.enter("link"),subexit=state.enter("label");let value2=tracker.move("[");return value2+=tracker.move(state.containerPhrasing(node2,{before:value2,after:"](",...tracker.current()})),value2+=tracker.move("]("),subexit(),!node2.url&&node2.title||/[\0- \u007F]/.test(node2.url)?(subexit=state.enter("destinationLiteral"),value2+=tracker.move("<"),value2+=tracker.move(state.safe(node2.url,{before:value2,after:">",...tracker.current()})),value2+=tracker.move(">")):(subexit=state.enter("destinationRaw"),value2+=tracker.move(state.safe(node2.url,{before:value2,after:node2.title?" ":")",...tracker.current()}))),subexit(),node2.title&&(subexit=state.enter(`title${suffix}`),value2+=tracker.move(" "+quote),value2+=tracker.move(state.safe(node2.title,{before:value2,after:quote,...tracker.current()})),value2+=tracker.move(quote),subexit()),value2+=tracker.move(")"),exit2(),value2}__name(link,"link");function linkPeek(node2,_2,state){return formatLinkAsAutolink(node2,state)?"<":"["}__name(linkPeek,"linkPeek");linkReference.peek=linkReferencePeek;function linkReference(node2,_2,state,info){const type=node2.referenceType,exit2=state.enter("linkReference");let subexit=state.enter("label");const tracker=state.createTracker(info);let value2=tracker.move("[");const text2=state.containerPhrasing(node2,{before:value2,after:"]",...tracker.current()});value2+=tracker.move(text2+"]["),subexit();const stack=state.stack;state.stack=[],subexit=state.enter("reference");const reference=state.safe(state.associationId(node2),{before:value2,after:"]",...tracker.current()});return subexit(),state.stack=stack,exit2(),type==="full"||!text2||text2!==reference?value2+=tracker.move(reference+"]"):type==="shortcut"?value2=value2.slice(0,-1):value2+=tracker.move("]"),value2}__name(linkReference,"linkReference");function linkReferencePeek(){return"["}__name(linkReferencePeek,"linkReferencePeek");function checkBullet(state){const marker=state.options.bullet||"*";if(marker!=="*"&&marker!=="+"&&marker!=="-")throw new Error("Cannot serialize items with `"+marker+"` for `options.bullet`, expected `*`, `+`, or `-`");return marker}__name(checkBullet,"checkBullet");function checkBulletOther(state){const bullet=checkBullet(state),bulletOther=state.options.bulletOther;if(!bulletOther)return bullet==="*"?"-":"*";if(bulletOther!=="*"&&bulletOther!=="+"&&bulletOther!=="-")throw new Error("Cannot serialize items with `"+bulletOther+"` for `options.bulletOther`, expected `*`, `+`, or `-`");if(bulletOther===bullet)throw new Error("Expected `bullet` (`"+bullet+"`) and `bulletOther` (`"+bulletOther+"`) to be different");return bulletOther}__name(checkBulletOther,"checkBulletOther");function checkBulletOrdered(state){const marker=state.options.bulletOrdered||".";if(marker!=="."&&marker!==")")throw new Error("Cannot serialize items with `"+marker+"` for `options.bulletOrdered`, expected `.` or `)`");return marker}__name(checkBulletOrdered,"checkBulletOrdered");function checkRule(state){const marker=state.options.rule||"*";if(marker!=="*"&&marker!=="-"&&marker!=="_")throw new Error("Cannot serialize rules with `"+marker+"` for `options.rule`, expected `*`, `-`, or `_`");return marker}__name(checkRule,"checkRule");function list(node2,parent,state,info){const exit2=state.enter("list"),bulletCurrent=state.bulletCurrent;let bullet=node2.ordered?checkBulletOrdered(state):checkBullet(state);const bulletOther=node2.ordered?bullet==="."?")":".":checkBulletOther(state);let useDifferentMarker=parent&&state.bulletLastUsed?bullet===state.bulletLastUsed:!1;if(!node2.ordered){const firstListItem=node2.children?node2.children[0]:void 0;if((bullet==="*"||bullet==="-")&&firstListItem&&(!firstListItem.children||!firstListItem.children[0])&&state.stack[state.stack.length-1]==="list"&&state.stack[state.stack.length-2]==="listItem"&&state.stack[state.stack.length-3]==="list"&&state.stack[state.stack.length-4]==="listItem"&&state.indexStack[state.indexStack.length-1]===0&&state.indexStack[state.indexStack.length-2]===0&&state.indexStack[state.indexStack.length-3]===0&&(useDifferentMarker=!0),checkRule(state)===bullet&&firstListItem){let index2=-1;for(;++index2-1?parent.start:1)+(state.options.incrementListMarker===!1?0:parent.children.indexOf(node2))+bullet);let size2=bullet.length+1;(listItemIndent==="tab"||listItemIndent==="mixed"&&(parent&&parent.type==="list"&&parent.spread||node2.spread))&&(size2=Math.ceil(size2/4)*4);const tracker=state.createTracker(info);tracker.move(bullet+" ".repeat(size2-bullet.length)),tracker.shift(size2);const exit2=state.enter("listItem"),value2=state.indentLines(state.containerFlow(node2,tracker.current()),map2);return exit2(),value2;function map2(line,index2,blank){return index2?(blank?"":" ".repeat(size2))+line:(blank?bullet:bullet+" ".repeat(size2-bullet.length))+line}__name(map2,"map")}__name(listItem,"listItem");function paragraph(node2,_2,state,info){const exit2=state.enter("paragraph"),subexit=state.enter("phrasing"),value2=state.containerPhrasing(node2,info);return subexit(),exit2(),value2}__name(paragraph,"paragraph");const phrasing=convert(["break","delete","emphasis","footnote","footnoteReference","image","imageReference","inlineCode","inlineMath","link","linkReference","mdxJsxTextElement","mdxTextExpression","strong","text","textDirective"]);function root$3(node2,_2,state,info){return(node2.children.some(function(d){return phrasing(d)})?state.containerPhrasing:state.containerFlow).call(state,node2,info)}__name(root$3,"root$3");function checkStrong(state){const marker=state.options.strong||"*";if(marker!=="*"&&marker!=="_")throw new Error("Cannot serialize strong with `"+marker+"` for `options.strong`, expected `*`, or `_`");return marker}__name(checkStrong,"checkStrong");strong.peek=strongPeek;function strong(node2,_2,state,info){const marker=checkStrong(state),exit2=state.enter("strong"),tracker=state.createTracker(info),before=tracker.move(marker+marker);let between=tracker.move(state.containerPhrasing(node2,{after:marker,before,...tracker.current()}));const betweenHead=between.charCodeAt(0),open=encodeInfo(info.before.charCodeAt(info.before.length-1),betweenHead,marker);open.inside&&(between=encodeCharacterReference(betweenHead)+between.slice(1));const betweenTail=between.charCodeAt(between.length-1),close=encodeInfo(info.after.charCodeAt(0),betweenTail,marker);close.inside&&(between=between.slice(0,-1)+encodeCharacterReference(betweenTail));const after=tracker.move(marker+marker);return exit2(),state.attentionEncodeSurroundingInfo={after:close.outside,before:open.outside},before+between+after}__name(strong,"strong");function strongPeek(_2,_1,state){return state.options.strong||"*"}__name(strongPeek,"strongPeek");function text$4(node2,_2,state,info){return state.safe(node2.value,info)}__name(text$4,"text$4");function checkRuleRepetition(state){const repetition=state.options.ruleRepetition||3;if(repetition<3)throw new Error("Cannot serialize rules with repetition `"+repetition+"` for `options.ruleRepetition`, expected `3` or more");return repetition}__name(checkRuleRepetition,"checkRuleRepetition");function thematicBreak(_2,_1,state){const value2=(checkRule(state)+(state.options.ruleSpaces?" ":"")).repeat(checkRuleRepetition(state));return state.options.ruleSpaces?value2.slice(0,-1):value2}__name(thematicBreak,"thematicBreak");const handle={blockquote,break:hardBreak,code:code$1,definition,emphasis,hardBreak,heading,html,image,imageReference,inlineCode,link,linkReference,list,listItem,paragraph,root:root$3,strong,text:text$4,thematicBreak};function gfmTableFromMarkdown(){return{enter:{table:enterTable,tableData:enterCell,tableHeader:enterCell,tableRow:enterRow},exit:{codeText:exitCodeText,table:exitTable,tableData:exit,tableHeader:exit,tableRow:exit}}}__name(gfmTableFromMarkdown,"gfmTableFromMarkdown");function enterTable(token){const align=token._align;this.enter({type:"table",align:align.map(function(d){return d==="none"?null:d}),children:[]},token),this.data.inTable=!0}__name(enterTable,"enterTable");function exitTable(token){this.exit(token),this.data.inTable=void 0}__name(exitTable,"exitTable");function enterRow(token){this.enter({type:"tableRow",children:[]},token)}__name(enterRow,"enterRow");function exit(token){this.exit(token)}__name(exit,"exit");function enterCell(token){this.enter({type:"tableCell",children:[]},token)}__name(enterCell,"enterCell");function exitCodeText(token){let value2=this.resume();this.data.inTable&&(value2=value2.replace(/\\([\\|])/g,replace));const node2=this.stack[this.stack.length-1];node2.type,node2.value=value2,this.exit(token)}__name(exitCodeText,"exitCodeText");function replace($0,$1){return $1==="|"?$1:$0}__name(replace,"replace");function gfmTableToMarkdown(options){const settings=options||{},padding=settings.tableCellPadding,alignDelimiters=settings.tablePipeAlign,stringLength=settings.stringLength,around=padding?" ":"|";return{unsafe:[{character:"\r",inConstruct:"tableCell"},{character:` `,inConstruct:"tableCell"},{atBreak:!0,character:"|",after:"[ :-]"},{character:"|",inConstruct:"tableCell"},{atBreak:!0,character:":",after:"-"},{atBreak:!0,character:"-",after:"[:|-]"}],handlers:{inlineCode:inlineCodeWithTable,table:handleTable,tableCell:handleTableCell,tableRow:handleTableRow}};function handleTable(node2,_2,state,info){return serializeData(handleTableAsData(node2,state,info),node2.align)}function handleTableRow(node2,_2,state,info){const row=handleTableRowAsData(node2,state,info),value2=serializeData([row]);return value2.slice(0,value2.indexOf(` `))}function handleTableCell(node2,_2,state,info){const exit2=state.enter("tableCell"),subexit=state.enter("phrasing"),value2=state.containerPhrasing(node2,{...info,before:around,after:around});return subexit(),exit2(),value2}function serializeData(matrix,align){return markdownTable(matrix,{align,alignDelimiters,padding,stringLength})}function handleTableAsData(node2,state,info){const children2=node2.children;let index2=-1;const result=[],subexit=state.enter("table");for(;++index20&&!result&&(events[events.length-1][1]._gfmAutolinkLiteralWalkedInto=!0),result}__name(previousUnbalanced,"previousUnbalanced");const indent={tokenize:tokenizeIndent,partial:!0};function gfmFootnote(){return{document:{91:{name:"gfmFootnoteDefinition",tokenize:tokenizeDefinitionStart,continuation:{tokenize:tokenizeDefinitionContinuation},exit:gfmFootnoteDefinitionEnd}},text:{91:{name:"gfmFootnoteCall",tokenize:tokenizeGfmFootnoteCall},93:{name:"gfmPotentialFootnoteCall",add:"after",tokenize:tokenizePotentialGfmFootnoteCall,resolveTo:resolveToPotentialGfmFootnoteCall}}}}__name(gfmFootnote,"gfmFootnote");function tokenizePotentialGfmFootnoteCall(effects,ok2,nok){const self2=this;let index2=self2.events.length;const defined3=self2.parser.gfmFootnotes||(self2.parser.gfmFootnotes=[]);let labelStart;for(;index2--;){const token=self2.events[index2][1];if(token.type==="labelImage"){labelStart=token;break}if(token.type==="gfmFootnoteCall"||token.type==="labelLink"||token.type==="label"||token.type==="image"||token.type==="link")break}return start2;function start2(code2){if(!labelStart||!labelStart._balanced)return nok(code2);const id=normalizeIdentifier(self2.sliceSerialize({start:labelStart.end,end:self2.now()}));return id.codePointAt(0)!==94||!defined3.includes(id.slice(1))?nok(code2):(effects.enter("gfmFootnoteCallLabelMarker"),effects.consume(code2),effects.exit("gfmFootnoteCallLabelMarker"),ok2(code2))}}__name(tokenizePotentialGfmFootnoteCall,"tokenizePotentialGfmFootnoteCall");function resolveToPotentialGfmFootnoteCall(events,context){let index2=events.length;for(;index2--;)if(events[index2][1].type==="labelImage"&&events[index2][0]==="enter"){events[index2][1];break}events[index2+1][1].type="data",events[index2+3][1].type="gfmFootnoteCallLabelMarker";const call2={type:"gfmFootnoteCall",start:Object.assign({},events[index2+3][1].start),end:Object.assign({},events[events.length-1][1].end)},marker={type:"gfmFootnoteCallMarker",start:Object.assign({},events[index2+3][1].end),end:Object.assign({},events[index2+3][1].end)};marker.end.column++,marker.end.offset++,marker.end._bufferIndex++;const string2={type:"gfmFootnoteCallString",start:Object.assign({},marker.end),end:Object.assign({},events[events.length-1][1].start)},chunk={type:"chunkString",contentType:"string",start:Object.assign({},string2.start),end:Object.assign({},string2.end)},replacement=[events[index2+1],events[index2+2],["enter",call2,context],events[index2+3],events[index2+4],["enter",marker,context],["exit",marker,context],["enter",string2,context],["enter",chunk,context],["exit",chunk,context],["exit",string2,context],events[events.length-2],events[events.length-1],["exit",call2,context]];return events.splice(index2,events.length-index2+1,...replacement),events}__name(resolveToPotentialGfmFootnoteCall,"resolveToPotentialGfmFootnoteCall");function tokenizeGfmFootnoteCall(effects,ok2,nok){const self2=this,defined3=self2.parser.gfmFootnotes||(self2.parser.gfmFootnotes=[]);let size2=0,data;return start2;function start2(code2){return effects.enter("gfmFootnoteCall"),effects.enter("gfmFootnoteCallLabelMarker"),effects.consume(code2),effects.exit("gfmFootnoteCallLabelMarker"),callStart}function callStart(code2){return code2!==94?nok(code2):(effects.enter("gfmFootnoteCallMarker"),effects.consume(code2),effects.exit("gfmFootnoteCallMarker"),effects.enter("gfmFootnoteCallString"),effects.enter("chunkString").contentType="string",callData)}function callData(code2){if(size2>999||code2===93&&!data||code2===null||code2===91||markdownLineEndingOrSpace(code2))return nok(code2);if(code2===93){effects.exit("chunkString");const token=effects.exit("gfmFootnoteCallString");return defined3.includes(normalizeIdentifier(self2.sliceSerialize(token)))?(effects.enter("gfmFootnoteCallLabelMarker"),effects.consume(code2),effects.exit("gfmFootnoteCallLabelMarker"),effects.exit("gfmFootnoteCall"),ok2):nok(code2)}return markdownLineEndingOrSpace(code2)||(data=!0),size2++,effects.consume(code2),code2===92?callEscape:callData}function callEscape(code2){return code2===91||code2===92||code2===93?(effects.consume(code2),size2++,callData):callData(code2)}}__name(tokenizeGfmFootnoteCall,"tokenizeGfmFootnoteCall");function tokenizeDefinitionStart(effects,ok2,nok){const self2=this,defined3=self2.parser.gfmFootnotes||(self2.parser.gfmFootnotes=[]);let identifier,size2=0,data;return start2;function start2(code2){return effects.enter("gfmFootnoteDefinition")._container=!0,effects.enter("gfmFootnoteDefinitionLabel"),effects.enter("gfmFootnoteDefinitionLabelMarker"),effects.consume(code2),effects.exit("gfmFootnoteDefinitionLabelMarker"),labelAtMarker}function labelAtMarker(code2){return code2===94?(effects.enter("gfmFootnoteDefinitionMarker"),effects.consume(code2),effects.exit("gfmFootnoteDefinitionMarker"),effects.enter("gfmFootnoteDefinitionLabelString"),effects.enter("chunkString").contentType="string",labelInside):nok(code2)}function labelInside(code2){if(size2>999||code2===93&&!data||code2===null||code2===91||markdownLineEndingOrSpace(code2))return nok(code2);if(code2===93){effects.exit("chunkString");const token=effects.exit("gfmFootnoteDefinitionLabelString");return identifier=normalizeIdentifier(self2.sliceSerialize(token)),effects.enter("gfmFootnoteDefinitionLabelMarker"),effects.consume(code2),effects.exit("gfmFootnoteDefinitionLabelMarker"),effects.exit("gfmFootnoteDefinitionLabel"),labelAfter}return markdownLineEndingOrSpace(code2)||(data=!0),size2++,effects.consume(code2),code2===92?labelEscape:labelInside}function labelEscape(code2){return code2===91||code2===92||code2===93?(effects.consume(code2),size2++,labelInside):labelInside(code2)}function labelAfter(code2){return code2===58?(effects.enter("definitionMarker"),effects.consume(code2),effects.exit("definitionMarker"),defined3.includes(identifier)||defined3.push(identifier),factorySpace(effects,whitespaceAfter,"gfmFootnoteDefinitionWhitespace")):nok(code2)}function whitespaceAfter(code2){return ok2(code2)}}__name(tokenizeDefinitionStart,"tokenizeDefinitionStart");function tokenizeDefinitionContinuation(effects,ok2,nok){return effects.check(blankLine,ok2,effects.attempt(indent,ok2,nok))}__name(tokenizeDefinitionContinuation,"tokenizeDefinitionContinuation");function gfmFootnoteDefinitionEnd(effects){effects.exit("gfmFootnoteDefinition")}__name(gfmFootnoteDefinitionEnd,"gfmFootnoteDefinitionEnd");function tokenizeIndent(effects,ok2,nok){const self2=this;return factorySpace(effects,afterPrefix,"gfmFootnoteDefinitionIndent",5);function afterPrefix(code2){const tail=self2.events[self2.events.length-1];return tail&&tail[1].type==="gfmFootnoteDefinitionIndent"&&tail[2].sliceSerialize(tail[1],!0).length===4?ok2(code2):nok(code2)}}__name(tokenizeIndent,"tokenizeIndent");function gfmStrikethrough(options){let single=(options||{}).singleTilde;const tokenizer={name:"strikethrough",tokenize:tokenizeStrikethrough,resolveAll:resolveAllStrikethrough};return single==null&&(single=!0),{text:{126:tokenizer},insideSpan:{null:[tokenizer]},attentionMarkers:{null:[126]}};function resolveAllStrikethrough(events,context){let index2=-1;for(;++index21?nok(code2):(effects.consume(code2),size2++,more);if(size2<2&&!single)return nok(code2);const token=effects.exit("strikethroughSequenceTemporary"),after=classifyCharacter(code2);return token._open=!after||after===2&&!!before,token._close=!before||before===2&&!!after,ok2(code2)}}__name(tokenizeStrikethrough,"tokenizeStrikethrough")}__name(gfmStrikethrough,"gfmStrikethrough");const _EditMap=class _EditMap{constructor(){this.map=[]}add(index2,remove,add2){addImplementation(this,index2,remove,add2)}consume(events){if(this.map.sort(function(a2,b2){return a2[0]-b2[0]}),this.map.length===0)return;let index2=this.map.length;const vecs=[];for(;index2>0;)index2-=1,vecs.push(events.slice(this.map[index2][0]+this.map[index2][1]),this.map[index2][2]),events.length=this.map[index2][0];vecs.push(events.slice()),events.length=0;let slice=vecs.pop();for(;slice;){for(const element2 of slice)events.push(element2);slice=vecs.pop()}this.map.length=0}};__name(_EditMap,"EditMap");let EditMap=_EditMap;function addImplementation(editMap,at,remove,add2){let index2=0;if(!(remove===0&&add2.length===0)){for(;index2-1;){const type=self2.events[index2][1].type;if(type==="lineEnding"||type==="linePrefix")index2--;else break}const tail=index2>-1?self2.events[index2][1].type:null,next2=tail==="tableHead"||tail==="tableRow"?bodyRowStart:headRowBefore;return next2===bodyRowStart&&self2.parser.lazy[self2.now().line]?nok(code2):next2(code2)}function headRowBefore(code2){return effects.enter("tableHead"),effects.enter("tableRow"),headRowStart(code2)}function headRowStart(code2){return code2===124||(seen=!0,sizeB+=1),headRowBreak(code2)}function headRowBreak(code2){return code2===null?nok(code2):markdownLineEnding(code2)?sizeB>1?(sizeB=0,self2.interrupt=!0,effects.exit("tableRow"),effects.enter("lineEnding"),effects.consume(code2),effects.exit("lineEnding"),headDelimiterStart):nok(code2):markdownSpace(code2)?factorySpace(effects,headRowBreak,"whitespace")(code2):(sizeB+=1,seen&&(seen=!1,size2+=1),code2===124?(effects.enter("tableCellDivider"),effects.consume(code2),effects.exit("tableCellDivider"),seen=!0,headRowBreak):(effects.enter("data"),headRowData(code2)))}function headRowData(code2){return code2===null||code2===124||markdownLineEndingOrSpace(code2)?(effects.exit("data"),headRowBreak(code2)):(effects.consume(code2),code2===92?headRowEscape:headRowData)}function headRowEscape(code2){return code2===92||code2===124?(effects.consume(code2),headRowData):headRowData(code2)}function headDelimiterStart(code2){return self2.interrupt=!1,self2.parser.lazy[self2.now().line]?nok(code2):(effects.enter("tableDelimiterRow"),seen=!1,markdownSpace(code2)?factorySpace(effects,headDelimiterBefore,"linePrefix",self2.parser.constructs.disable.null.includes("codeIndented")?void 0:4)(code2):headDelimiterBefore(code2))}function headDelimiterBefore(code2){return code2===45||code2===58?headDelimiterValueBefore(code2):code2===124?(seen=!0,effects.enter("tableCellDivider"),effects.consume(code2),effects.exit("tableCellDivider"),headDelimiterCellBefore):headDelimiterNok(code2)}function headDelimiterCellBefore(code2){return markdownSpace(code2)?factorySpace(effects,headDelimiterValueBefore,"whitespace")(code2):headDelimiterValueBefore(code2)}function headDelimiterValueBefore(code2){return code2===58?(sizeB+=1,seen=!0,effects.enter("tableDelimiterMarker"),effects.consume(code2),effects.exit("tableDelimiterMarker"),headDelimiterLeftAlignmentAfter):code2===45?(sizeB+=1,headDelimiterLeftAlignmentAfter(code2)):code2===null||markdownLineEnding(code2)?headDelimiterCellAfter(code2):headDelimiterNok(code2)}function headDelimiterLeftAlignmentAfter(code2){return code2===45?(effects.enter("tableDelimiterFiller"),headDelimiterFiller(code2)):headDelimiterNok(code2)}function headDelimiterFiller(code2){return code2===45?(effects.consume(code2),headDelimiterFiller):code2===58?(seen=!0,effects.exit("tableDelimiterFiller"),effects.enter("tableDelimiterMarker"),effects.consume(code2),effects.exit("tableDelimiterMarker"),headDelimiterRightAlignmentAfter):(effects.exit("tableDelimiterFiller"),headDelimiterRightAlignmentAfter(code2))}function headDelimiterRightAlignmentAfter(code2){return markdownSpace(code2)?factorySpace(effects,headDelimiterCellAfter,"whitespace")(code2):headDelimiterCellAfter(code2)}function headDelimiterCellAfter(code2){return code2===124?headDelimiterBefore(code2):code2===null||markdownLineEnding(code2)?!seen||size2!==sizeB?headDelimiterNok(code2):(effects.exit("tableDelimiterRow"),effects.exit("tableHead"),ok2(code2)):headDelimiterNok(code2)}function headDelimiterNok(code2){return nok(code2)}function bodyRowStart(code2){return effects.enter("tableRow"),bodyRowBreak(code2)}function bodyRowBreak(code2){return code2===124?(effects.enter("tableCellDivider"),effects.consume(code2),effects.exit("tableCellDivider"),bodyRowBreak):code2===null||markdownLineEnding(code2)?(effects.exit("tableRow"),ok2(code2)):markdownSpace(code2)?factorySpace(effects,bodyRowBreak,"whitespace")(code2):(effects.enter("data"),bodyRowData(code2))}function bodyRowData(code2){return code2===null||code2===124||markdownLineEndingOrSpace(code2)?(effects.exit("data"),bodyRowBreak(code2)):(effects.consume(code2),code2===92?bodyRowEscape:bodyRowData)}function bodyRowEscape(code2){return code2===92||code2===124?(effects.consume(code2),bodyRowData):bodyRowData(code2)}}__name(tokenizeTable,"tokenizeTable");function resolveTable(events,context){let index2=-1,inFirstCellAwaitingPipe=!0,rowKind=0,lastCell=[0,0,0,0],cell=[0,0,0,0],afterHeadAwaitingFirstBodyRow=!1,lastTableEnd=0,currentTable,currentBody,currentCell;const map2=new EditMap;for(;++index2range3[2]+1){const a2=range3[2]+1,b2=range3[3]-range3[2]-1;map2.add(a2,b2,[])}}map2.add(range3[3]+1,0,[["exit",valueToken,context]])}return rowEnd!==void 0&&(previousCell.end=Object.assign({},getPoint(context.events,rowEnd)),map2.add(rowEnd,0,[["exit",previousCell,context]]),previousCell=void 0),previousCell}__name(flushCell,"flushCell");function flushTableEnd(map2,context,index2,table2,tableBody){const exits=[],related=getPoint(context.events,index2);tableBody&&(tableBody.end=Object.assign({},related),exits.push(["exit",tableBody,context])),table2.end=Object.assign({},related),exits.push(["exit",table2,context]),map2.add(index2+1,0,exits)}__name(flushTableEnd,"flushTableEnd");function getPoint(events,index2){const event=events[index2],side=event[0]==="enter"?"start":"end";return event[1][side]}__name(getPoint,"getPoint");const tasklistCheck={name:"tasklistCheck",tokenize:tokenizeTasklistCheck};function gfmTaskListItem(){return{text:{91:tasklistCheck}}}__name(gfmTaskListItem,"gfmTaskListItem");function tokenizeTasklistCheck(effects,ok2,nok){const self2=this;return open;function open(code2){return self2.previous!==null||!self2._gfmTasklistFirstContentOfListItem?nok(code2):(effects.enter("taskListCheck"),effects.enter("taskListCheckMarker"),effects.consume(code2),effects.exit("taskListCheckMarker"),inside)}function inside(code2){return markdownLineEndingOrSpace(code2)?(effects.enter("taskListCheckValueUnchecked"),effects.consume(code2),effects.exit("taskListCheckValueUnchecked"),close):code2===88||code2===120?(effects.enter("taskListCheckValueChecked"),effects.consume(code2),effects.exit("taskListCheckValueChecked"),close):nok(code2)}function close(code2){return code2===93?(effects.enter("taskListCheckMarker"),effects.consume(code2),effects.exit("taskListCheckMarker"),effects.exit("taskListCheck"),after):nok(code2)}function after(code2){return markdownLineEnding(code2)?ok2(code2):markdownSpace(code2)?effects.check({tokenize:spaceThenNonSpace},ok2,nok)(code2):nok(code2)}}__name(tokenizeTasklistCheck,"tokenizeTasklistCheck");function spaceThenNonSpace(effects,ok2,nok){return factorySpace(effects,after,"whitespace");function after(code2){return code2===null?nok(code2):ok2(code2)}}__name(spaceThenNonSpace,"spaceThenNonSpace");function gfm(options){return combineExtensions([gfmAutolinkLiteral(),gfmFootnote(),gfmStrikethrough(options),gfmTable(),gfmTaskListItem()])}__name(gfm,"gfm");const emptyOptions$1={};function remarkGfm(options){const self2=this,settings=options||emptyOptions$1,data=self2.data(),micromarkExtensions=data.micromarkExtensions||(data.micromarkExtensions=[]),fromMarkdownExtensions=data.fromMarkdownExtensions||(data.fromMarkdownExtensions=[]),toMarkdownExtensions=data.toMarkdownExtensions||(data.toMarkdownExtensions=[]);micromarkExtensions.push(gfm(settings)),fromMarkdownExtensions.push(gfmFromMarkdown()),toMarkdownExtensions.push(gfmToMarkdown(settings))}__name(remarkGfm,"remarkGfm");const search=/[#.]/g;function parseSelector(selector,defaultTagName){const value2=selector||"",props={};let start2=0,previous2,tagName;for(;start2-1&&offset2<=value2.length){let index2=0;for(;;){let end=indices[index2];if(end===void 0){const eol=next(value2,indices[index2-1]);end=eol===-1?value2.length+1:eol+1,indices[index2]=end}if(end>offset2)return{line:index2+1,column:offset2-(index2>0?indices[index2-1]:0)+1,offset:offset2};index2++}}}function toOffset(point2){if(point2&&typeof point2.line=="number"&&typeof point2.column=="number"&&!Number.isNaN(point2.line)&&!Number.isNaN(point2.column)){for(;indices.length1?indices[point2.line-2]:0)+point2.column-1;if(offset2=55296&&cp<=57343}__name(isSurrogate,"isSurrogate");function isSurrogatePair(cp){return cp>=56320&&cp<=57343}__name(isSurrogatePair,"isSurrogatePair");function getSurrogatePairCodePoint(cp1,cp2){return(cp1-55296)*1024+9216+cp2}__name(getSurrogatePairCodePoint,"getSurrogatePairCodePoint");function isControlCodePoint(cp){return cp!==32&&cp!==10&&cp!==13&&cp!==9&&cp!==12&&cp>=1&&cp<=31||cp>=127&&cp<=159}__name(isControlCodePoint,"isControlCodePoint");function isUndefinedCodePoint(cp){return cp>=64976&&cp<=65007||UNDEFINED_CODE_POINTS.has(cp)}__name(isUndefinedCodePoint,"isUndefinedCodePoint");var ERR;(function(ERR2){ERR2.controlCharacterInInputStream="control-character-in-input-stream",ERR2.noncharacterInInputStream="noncharacter-in-input-stream",ERR2.surrogateInInputStream="surrogate-in-input-stream",ERR2.nonVoidHtmlElementStartTagWithTrailingSolidus="non-void-html-element-start-tag-with-trailing-solidus",ERR2.endTagWithAttributes="end-tag-with-attributes",ERR2.endTagWithTrailingSolidus="end-tag-with-trailing-solidus",ERR2.unexpectedSolidusInTag="unexpected-solidus-in-tag",ERR2.unexpectedNullCharacter="unexpected-null-character",ERR2.unexpectedQuestionMarkInsteadOfTagName="unexpected-question-mark-instead-of-tag-name",ERR2.invalidFirstCharacterOfTagName="invalid-first-character-of-tag-name",ERR2.unexpectedEqualsSignBeforeAttributeName="unexpected-equals-sign-before-attribute-name",ERR2.missingEndTagName="missing-end-tag-name",ERR2.unexpectedCharacterInAttributeName="unexpected-character-in-attribute-name",ERR2.unknownNamedCharacterReference="unknown-named-character-reference",ERR2.missingSemicolonAfterCharacterReference="missing-semicolon-after-character-reference",ERR2.unexpectedCharacterAfterDoctypeSystemIdentifier="unexpected-character-after-doctype-system-identifier",ERR2.unexpectedCharacterInUnquotedAttributeValue="unexpected-character-in-unquoted-attribute-value",ERR2.eofBeforeTagName="eof-before-tag-name",ERR2.eofInTag="eof-in-tag",ERR2.missingAttributeValue="missing-attribute-value",ERR2.missingWhitespaceBetweenAttributes="missing-whitespace-between-attributes",ERR2.missingWhitespaceAfterDoctypePublicKeyword="missing-whitespace-after-doctype-public-keyword",ERR2.missingWhitespaceBetweenDoctypePublicAndSystemIdentifiers="missing-whitespace-between-doctype-public-and-system-identifiers",ERR2.missingWhitespaceAfterDoctypeSystemKeyword="missing-whitespace-after-doctype-system-keyword",ERR2.missingQuoteBeforeDoctypePublicIdentifier="missing-quote-before-doctype-public-identifier",ERR2.missingQuoteBeforeDoctypeSystemIdentifier="missing-quote-before-doctype-system-identifier",ERR2.missingDoctypePublicIdentifier="missing-doctype-public-identifier",ERR2.missingDoctypeSystemIdentifier="missing-doctype-system-identifier",ERR2.abruptDoctypePublicIdentifier="abrupt-doctype-public-identifier",ERR2.abruptDoctypeSystemIdentifier="abrupt-doctype-system-identifier",ERR2.cdataInHtmlContent="cdata-in-html-content",ERR2.incorrectlyOpenedComment="incorrectly-opened-comment",ERR2.eofInScriptHtmlCommentLikeText="eof-in-script-html-comment-like-text",ERR2.eofInDoctype="eof-in-doctype",ERR2.nestedComment="nested-comment",ERR2.abruptClosingOfEmptyComment="abrupt-closing-of-empty-comment",ERR2.eofInComment="eof-in-comment",ERR2.incorrectlyClosedComment="incorrectly-closed-comment",ERR2.eofInCdata="eof-in-cdata",ERR2.absenceOfDigitsInNumericCharacterReference="absence-of-digits-in-numeric-character-reference",ERR2.nullCharacterReference="null-character-reference",ERR2.surrogateCharacterReference="surrogate-character-reference",ERR2.characterReferenceOutsideUnicodeRange="character-reference-outside-unicode-range",ERR2.controlCharacterReference="control-character-reference",ERR2.noncharacterCharacterReference="noncharacter-character-reference",ERR2.missingWhitespaceBeforeDoctypeName="missing-whitespace-before-doctype-name",ERR2.missingDoctypeName="missing-doctype-name",ERR2.invalidCharacterSequenceAfterDoctypeName="invalid-character-sequence-after-doctype-name",ERR2.duplicateAttribute="duplicate-attribute",ERR2.nonConformingDoctype="non-conforming-doctype",ERR2.missingDoctype="missing-doctype",ERR2.misplacedDoctype="misplaced-doctype",ERR2.endTagWithoutMatchingOpenElement="end-tag-without-matching-open-element",ERR2.closingOfElementWithOpenChildElements="closing-of-element-with-open-child-elements",ERR2.disallowedContentInNoscriptInHead="disallowed-content-in-noscript-in-head",ERR2.openElementsLeftAfterEof="open-elements-left-after-eof",ERR2.abandonedHeadElementChild="abandoned-head-element-child",ERR2.misplacedStartTagForHeadElement="misplaced-start-tag-for-head-element",ERR2.nestedNoscriptInHead="nested-noscript-in-head",ERR2.eofInElementThatCanContainOnlyText="eof-in-element-that-can-contain-only-text"})(ERR||(ERR={}));const DEFAULT_BUFFER_WATERLINE=65536,_Preprocessor=class _Preprocessor{constructor(handler){this.handler=handler,this.html="",this.pos=-1,this.lastGapPos=-2,this.gapStack=[],this.skipNextNewLine=!1,this.lastChunkWritten=!1,this.endOfChunkHit=!1,this.bufferWaterline=DEFAULT_BUFFER_WATERLINE,this.isEol=!1,this.lineStartPos=0,this.droppedBufferSize=0,this.line=1,this.lastErrOffset=-1}get col(){return this.pos-this.lineStartPos+ +(this.lastGapPos!==this.pos)}get offset(){return this.droppedBufferSize+this.pos}getError(code2,cpOffset){const{line,col,offset:offset2}=this,startCol=col+cpOffset,startOffset=offset2+cpOffset;return{code:code2,startLine:line,endLine:line,startCol,endCol:startCol,startOffset,endOffset:startOffset}}_err(code2){this.handler.onParseError&&this.lastErrOffset!==this.offset&&(this.lastErrOffset=this.offset,this.handler.onParseError(this.getError(code2,0)))}_addGap(){this.gapStack.push(this.lastGapPos),this.lastGapPos=this.pos}_processSurrogate(cp){if(this.pos!==this.html.length-1){const nextCp=this.html.charCodeAt(this.pos+1);if(isSurrogatePair(nextCp))return this.pos++,this._addGap(),getSurrogatePairCodePoint(cp,nextCp)}else if(!this.lastChunkWritten)return this.endOfChunkHit=!0,CODE_POINTS.EOF;return this._err(ERR.surrogateInInputStream),cp}willDropParsedChunk(){return this.pos>this.bufferWaterline}dropParsedChunk(){this.willDropParsedChunk()&&(this.html=this.html.substring(this.pos),this.lineStartPos-=this.pos,this.droppedBufferSize+=this.pos,this.pos=0,this.lastGapPos=-2,this.gapStack.length=0)}write(chunk,isLastChunk){this.html.length>0?this.html+=chunk:this.html=chunk,this.endOfChunkHit=!1,this.lastChunkWritten=isLastChunk}insertHtmlAtCurrentPos(chunk){this.html=this.html.substring(0,this.pos+1)+chunk+this.html.substring(this.pos+1),this.endOfChunkHit=!1}startsWith(pattern,caseSensitive){if(this.pos+pattern.length>this.html.length)return this.endOfChunkHit=!this.lastChunkWritten,!1;if(caseSensitive)return this.html.startsWith(pattern,this.pos);for(let i2=0;i2=this.html.length)return this.endOfChunkHit=!this.lastChunkWritten,CODE_POINTS.EOF;const code2=this.html.charCodeAt(pos);return code2===CODE_POINTS.CARRIAGE_RETURN?CODE_POINTS.LINE_FEED:code2}advance(){if(this.pos++,this.isEol&&(this.isEol=!1,this.line++,this.lineStartPos=this.pos),this.pos>=this.html.length)return this.endOfChunkHit=!this.lastChunkWritten,CODE_POINTS.EOF;let cp=this.html.charCodeAt(this.pos);return cp===CODE_POINTS.CARRIAGE_RETURN?(this.isEol=!0,this.skipNextNewLine=!0,CODE_POINTS.LINE_FEED):cp===CODE_POINTS.LINE_FEED&&(this.isEol=!0,this.skipNextNewLine)?(this.line--,this.skipNextNewLine=!1,this._addGap(),this.advance()):(this.skipNextNewLine=!1,isSurrogate(cp)&&(cp=this._processSurrogate(cp)),this.handler.onParseError===null||cp>31&&cp<127||cp===CODE_POINTS.LINE_FEED||cp===CODE_POINTS.CARRIAGE_RETURN||cp>159&&cp<64976||this._checkForProblematicCharacters(cp),cp)}_checkForProblematicCharacters(cp){isControlCodePoint(cp)?this._err(ERR.controlCharacterInInputStream):isUndefinedCodePoint(cp)&&this._err(ERR.noncharacterInInputStream)}retreat(count2){for(this.pos-=count2;this.pos=0;i2--)if(token.attrs[i2].name===attrName)return token.attrs[i2].value;return null}__name(getTokenAttr,"getTokenAttr");const htmlDecodeTree=new Uint16Array('ᵁ<Õıʊҝջאٵ۞ޢߖࠏ੊ઑඡ๭༉༦჊ረዡᐕᒝᓃᓟᔥ\0\0\0\0\0\0ᕫᛍᦍᰒᷝ὾⁠↰⊍⏀⏻⑂⠤⤒ⴈ⹈⿎〖㊺㘹㞬㣾㨨㩱㫠㬮ࠀEMabcfglmnoprstu\\bfms„‹•˜¦³¹ÈÏlig耻Æ䃆P耻&䀦cute耻Á䃁reve;䄂Āiyx}rc耻Â䃂;䐐r;쀀𝔄rave耻À䃀pha;䎑acr;䄀d;橓Āgp¡on;䄄f;쀀𝔸plyFunction;恡ing耻Å䃅Ācs¾Ãr;쀀𝒜ign;扔ilde耻Ã䃃ml耻Ä䃄ЀaceforsuåûþėĜĢħĪĀcrêòkslash;或Ŷöø;櫧ed;挆y;䐑ƀcrtąċĔause;戵noullis;愬a;䎒r;쀀𝔅pf;쀀𝔹eve;䋘còēmpeq;扎܀HOacdefhilorsuōőŖƀƞƢƵƷƺǜȕɳɸɾcy;䐧PY耻©䂩ƀcpyŝŢźute;䄆Ā;iŧŨ拒talDifferentialD;慅leys;愭ȀaeioƉƎƔƘron;䄌dil耻Ç䃇rc;䄈nint;戰ot;䄊ĀdnƧƭilla;䂸terDot;䂷òſi;䎧rcleȀDMPTLJNjǑǖot;抙inus;抖lus;投imes;抗oĀcsǢǸkwiseContourIntegral;戲eCurlyĀDQȃȏoubleQuote;思uote;怙ȀlnpuȞȨɇɕonĀ;eȥȦ户;橴ƀgitȯȶȺruent;扡nt;戯ourIntegral;戮ĀfrɌɎ;愂oduct;成nterClockwiseContourIntegral;戳oss;樯cr;쀀𝒞pĀ;Cʄʅ拓ap;才րDJSZacefiosʠʬʰʴʸˋ˗ˡ˦̳ҍĀ;oŹʥtrahd;椑cy;䐂cy;䐅cy;䐏ƀgrsʿ˄ˇger;怡r;憡hv;櫤Āayː˕ron;䄎;䐔lĀ;t˝˞戇a;䎔r;쀀𝔇Āaf˫̧Ācm˰̢riticalȀADGT̖̜̀̆cute;䂴oŴ̋̍;䋙bleAcute;䋝rave;䁠ilde;䋜ond;拄ferentialD;慆Ѱ̽\0\0\0͔͂\0Ѕf;쀀𝔻ƀ;DE͈͉͍䂨ot;惜qual;扐blèCDLRUVͣͲ΂ϏϢϸontourIntegraìȹoɴ͹\0\0ͻ»͉nArrow;懓Āeo·ΤftƀARTΐΖΡrrow;懐ightArrow;懔eåˊngĀLRΫτeftĀARγιrrow;柸ightArrow;柺ightArrow;柹ightĀATϘϞrrow;懒ee;抨pɁϩ\0\0ϯrrow;懑ownArrow;懕erticalBar;戥ǹABLRTaВЪаўѿͼrrowƀ;BUНОТ憓ar;椓pArrow;懵reve;䌑eft˒к\0ц\0ѐightVector;楐eeVector;楞ectorĀ;Bљњ憽ar;楖ightǔѧ\0ѱeeVector;楟ectorĀ;BѺѻ懁ar;楗eeĀ;A҆҇护rrow;憧ĀctҒҗr;쀀𝒟rok;䄐ࠀNTacdfglmopqstuxҽӀӄӋӞӢӧӮӵԡԯԶՒ՝ՠեG;䅊H耻Ð䃐cute耻É䃉ƀaiyӒӗӜron;䄚rc耻Ê䃊;䐭ot;䄖r;쀀𝔈rave耻È䃈ement;戈ĀapӺӾcr;䄒tyɓԆ\0\0ԒmallSquare;旻erySmallSquare;斫ĀgpԦԪon;䄘f;쀀𝔼silon;䎕uĀaiԼՉlĀ;TՂՃ橵ilde;扂librium;懌Āci՗՚r;愰m;橳a;䎗ml耻Ë䃋Āipժկsts;戃onentialE;慇ʀcfiosօֈ֍ֲ׌y;䐤r;쀀𝔉lledɓ֗\0\0֣mallSquare;旼erySmallSquare;斪Ͱֺ\0ֿ\0\0ׄf;쀀𝔽All;戀riertrf;愱cò׋؀JTabcdfgorstר׬ׯ׺؀ؒؖ؛؝أ٬ٲcy;䐃耻>䀾mmaĀ;d׷׸䎓;䏜reve;䄞ƀeiy؇،ؐdil;䄢rc;䄜;䐓ot;䄠r;쀀𝔊;拙pf;쀀𝔾eater̀EFGLSTصلَٖٛ٦qualĀ;Lؾؿ扥ess;招ullEqual;执reater;檢ess;扷lantEqual;橾ilde;扳cr;쀀𝒢;扫ЀAacfiosuڅڋږڛڞڪھۊRDcy;䐪Āctڐڔek;䋇;䁞irc;䄤r;愌lbertSpace;愋ǰگ\0ڲf;愍izontalLine;攀Āctۃۅòکrok;䄦mpńېۘownHumðįqual;扏܀EJOacdfgmnostuۺ۾܃܇܎ܚܞܡܨ݄ݸދޏޕcy;䐕lig;䄲cy;䐁cute耻Í䃍Āiyܓܘrc耻Î䃎;䐘ot;䄰r;愑rave耻Ì䃌ƀ;apܠܯܿĀcgܴܷr;䄪inaryI;慈lieóϝǴ݉\0ݢĀ;eݍݎ戬Āgrݓݘral;戫section;拂isibleĀCTݬݲomma;恣imes;恢ƀgptݿރވon;䄮f;쀀𝕀a;䎙cr;愐ilde;䄨ǫޚ\0ޞcy;䐆l耻Ï䃏ʀcfosuެ޷޼߂ߐĀiyޱ޵rc;䄴;䐙r;쀀𝔍pf;쀀𝕁ǣ߇\0ߌr;쀀𝒥rcy;䐈kcy;䐄΀HJacfosߤߨ߽߬߱ࠂࠈcy;䐥cy;䐌ppa;䎚Āey߶߻dil;䄶;䐚r;쀀𝔎pf;쀀𝕂cr;쀀𝒦րJTaceflmostࠥࠩࠬࡐࡣ঳সে্਷ੇcy;䐉耻<䀼ʀcmnpr࠷࠼ࡁࡄࡍute;䄹bda;䎛g;柪lacetrf;愒r;憞ƀaeyࡗ࡜ࡡron;䄽dil;䄻;䐛Āfsࡨ॰tԀACDFRTUVarࡾࢩࢱࣦ࣠ࣼयज़ΐ४Ānrࢃ࢏gleBracket;柨rowƀ;BR࢙࢚࢞憐ar;懤ightArrow;懆eiling;挈oǵࢷ\0ࣃbleBracket;柦nǔࣈ\0࣒eeVector;楡ectorĀ;Bࣛࣜ懃ar;楙loor;挊ightĀAV࣯ࣵrrow;憔ector;楎Āerँगeƀ;AVउऊऐ抣rrow;憤ector;楚iangleƀ;BEतथऩ抲ar;槏qual;抴pƀDTVषूौownVector;楑eeVector;楠ectorĀ;Bॖॗ憿ar;楘ectorĀ;B॥०憼ar;楒ightáΜs̀EFGLSTॾঋকঝঢভqualGreater;拚ullEqual;扦reater;扶ess;檡lantEqual;橽ilde;扲r;쀀𝔏Ā;eঽা拘ftarrow;懚idot;䄿ƀnpw৔ਖਛgȀLRlr৞৷ਂਐeftĀAR০৬rrow;柵ightArrow;柷ightArrow;柶eftĀarγਊightáοightáϊf;쀀𝕃erĀLRਢਬeftArrow;憙ightArrow;憘ƀchtਾੀੂòࡌ;憰rok;䅁;扪Ѐacefiosuਗ਼੝੠੷੼અઋ઎p;椅y;䐜Ādl੥੯iumSpace;恟lintrf;愳r;쀀𝔐nusPlus;戓pf;쀀𝕄cò੶;䎜ҀJacefostuણધભીଔଙඑ඗ඞcy;䐊cute;䅃ƀaey઴હાron;䅇dil;䅅;䐝ƀgswે૰଎ativeƀMTV૓૟૨ediumSpace;怋hiĀcn૦૘ë૙eryThiî૙tedĀGL૸ଆreaterGreateòٳessLesóੈLine;䀊r;쀀𝔑ȀBnptଢନଷ଺reak;恠BreakingSpace;䂠f;愕ڀ;CDEGHLNPRSTV୕ୖ୪୼஡௫ఄ౞಄ದ೘ൡඅ櫬Āou୛୤ngruent;扢pCap;扭oubleVerticalBar;戦ƀlqxஃஊ஛ement;戉ualĀ;Tஒஓ扠ilde;쀀≂̸ists;戄reater΀;EFGLSTஶஷ஽௉௓௘௥扯qual;扱ullEqual;쀀≧̸reater;쀀≫̸ess;批lantEqual;쀀⩾̸ilde;扵umpń௲௽ownHump;쀀≎̸qual;쀀≏̸eĀfsఊధtTriangleƀ;BEచఛడ拪ar;쀀⧏̸qual;括s̀;EGLSTవశ఼ౄోౘ扮qual;扰reater;扸ess;쀀≪̸lantEqual;쀀⩽̸ilde;扴estedĀGL౨౹reaterGreater;쀀⪢̸essLess;쀀⪡̸recedesƀ;ESಒಓಛ技qual;쀀⪯̸lantEqual;拠ĀeiಫಹverseElement;戌ghtTriangleƀ;BEೋೌ೒拫ar;쀀⧐̸qual;拭ĀquೝഌuareSuĀbp೨೹setĀ;E೰ೳ쀀⊏̸qual;拢ersetĀ;Eഃആ쀀⊐̸qual;拣ƀbcpഓതൎsetĀ;Eഛഞ쀀⊂⃒qual;抈ceedsȀ;ESTലള഻െ抁qual;쀀⪰̸lantEqual;拡ilde;쀀≿̸ersetĀ;E൘൛쀀⊃⃒qual;抉ildeȀ;EFT൮൯൵ൿ扁qual;扄ullEqual;扇ilde;扉erticalBar;戤cr;쀀𝒩ilde耻Ñ䃑;䎝܀Eacdfgmoprstuvලෂ෉෕ෛ෠෧෼ขภยา฿ไlig;䅒cute耻Ó䃓Āiy෎ීrc耻Ô䃔;䐞blac;䅐r;쀀𝔒rave耻Ò䃒ƀaei෮ෲ෶cr;䅌ga;䎩cron;䎟pf;쀀𝕆enCurlyĀDQฎบoubleQuote;怜uote;怘;橔Āclวฬr;쀀𝒪ash耻Ø䃘iŬื฼de耻Õ䃕es;樷ml耻Ö䃖erĀBP๋๠Āar๐๓r;怾acĀek๚๜;揞et;掴arenthesis;揜Ҁacfhilors๿ງຊຏຒດຝະ໼rtialD;戂y;䐟r;쀀𝔓i;䎦;䎠usMinus;䂱Āipຢອncareplanåڝf;愙Ȁ;eio຺ູ໠໤檻cedesȀ;EST່້໏໚扺qual;檯lantEqual;扼ilde;找me;怳Ādp໩໮uct;戏ortionĀ;aȥ໹l;戝Āci༁༆r;쀀𝒫;䎨ȀUfos༑༖༛༟OT耻"䀢r;쀀𝔔pf;愚cr;쀀𝒬؀BEacefhiorsu༾གྷཇའཱིྦྷྪྭ႖ႩႴႾarr;椐G耻®䂮ƀcnrཎནབute;䅔g;柫rĀ;tཛྷཝ憠l;椖ƀaeyཧཬཱron;䅘dil;䅖;䐠Ā;vླྀཹ愜erseĀEUྂྙĀlq྇ྎement;戋uilibrium;懋pEquilibrium;楯r»ཹo;䎡ghtЀACDFTUVa࿁࿫࿳ဢဨၛႇϘĀnr࿆࿒gleBracket;柩rowƀ;BL࿜࿝࿡憒ar;懥eftArrow;懄eiling;按oǵ࿹\0စbleBracket;柧nǔည\0နeeVector;楝ectorĀ;Bဝသ懂ar;楕loor;挋Āerိ၃eƀ;AVဵံြ抢rrow;憦ector;楛iangleƀ;BEၐၑၕ抳ar;槐qual;抵pƀDTVၣၮၸownVector;楏eeVector;楜ectorĀ;Bႂႃ憾ar;楔ectorĀ;B႑႒懀ar;楓Āpuႛ႞f;愝ndImplies;楰ightarrow;懛ĀchႹႼr;愛;憱leDelayed;槴ڀHOacfhimoqstuფჱჷჽᄙᄞᅑᅖᅡᅧᆵᆻᆿĀCcჩხHcy;䐩y;䐨FTcy;䐬cute;䅚ʀ;aeiyᄈᄉᄎᄓᄗ檼ron;䅠dil;䅞rc;䅜;䐡r;쀀𝔖ortȀDLRUᄪᄴᄾᅉownArrow»ОeftArrow»࢚ightArrow»࿝pArrow;憑gma;䎣allCircle;战pf;쀀𝕊ɲᅭ\0\0ᅰt;戚areȀ;ISUᅻᅼᆉᆯ斡ntersection;抓uĀbpᆏᆞsetĀ;Eᆗᆘ抏qual;抑ersetĀ;Eᆨᆩ抐qual;抒nion;抔cr;쀀𝒮ar;拆ȀbcmpᇈᇛሉላĀ;sᇍᇎ拐etĀ;Eᇍᇕqual;抆ĀchᇠህeedsȀ;ESTᇭᇮᇴᇿ扻qual;檰lantEqual;扽ilde;承Tháྌ;我ƀ;esሒሓሣ拑rsetĀ;Eሜም抃qual;抇et»ሓրHRSacfhiorsሾቄ቉ቕ቞ቱቶኟዂወዑORN耻Þ䃞ADE;愢ĀHc቎ቒcy;䐋y;䐦Ābuቚቜ;䀉;䎤ƀaeyብቪቯron;䅤dil;䅢;䐢r;쀀𝔗Āeiቻ኉Dzኀ\0ኇefore;戴a;䎘Ācn኎ኘkSpace;쀀  Space;怉ldeȀ;EFTካኬኲኼ戼qual;扃ullEqual;扅ilde;扈pf;쀀𝕋ipleDot;惛Āctዖዛr;쀀𝒯rok;䅦ૡዷጎጚጦ\0ጬጱ\0\0\0\0\0ጸጽ፷ᎅ\0᏿ᐄᐊᐐĀcrዻጁute耻Ú䃚rĀ;oጇገ憟cir;楉rǣጓ\0጖y;䐎ve;䅬Āiyጞጣrc耻Û䃛;䐣blac;䅰r;쀀𝔘rave耻Ù䃙acr;䅪Ādiፁ፩erĀBPፈ፝Āarፍፐr;䁟acĀekፗፙ;揟et;掵arenthesis;揝onĀ;P፰፱拃lus;抎Āgp፻፿on;䅲f;쀀𝕌ЀADETadps᎕ᎮᎸᏄϨᏒᏗᏳrrowƀ;BDᅐᎠᎤar;椒ownArrow;懅ownArrow;憕quilibrium;楮eeĀ;AᏋᏌ报rrow;憥ownáϳerĀLRᏞᏨeftArrow;憖ightArrow;憗iĀ;lᏹᏺ䏒on;䎥ing;䅮cr;쀀𝒰ilde;䅨ml耻Ü䃜ҀDbcdefosvᐧᐬᐰᐳᐾᒅᒊᒐᒖash;披ar;櫫y;䐒ashĀ;lᐻᐼ抩;櫦Āerᑃᑅ;拁ƀbtyᑌᑐᑺar;怖Ā;iᑏᑕcalȀBLSTᑡᑥᑪᑴar;戣ine;䁼eparator;杘ilde;所ThinSpace;怊r;쀀𝔙pf;쀀𝕍cr;쀀𝒱dash;抪ʀcefosᒧᒬᒱᒶᒼirc;䅴dge;拀r;쀀𝔚pf;쀀𝕎cr;쀀𝒲Ȁfiosᓋᓐᓒᓘr;쀀𝔛;䎞pf;쀀𝕏cr;쀀𝒳ҀAIUacfosuᓱᓵᓹᓽᔄᔏᔔᔚᔠcy;䐯cy;䐇cy;䐮cute耻Ý䃝Āiyᔉᔍrc;䅶;䐫r;쀀𝔜pf;쀀𝕐cr;쀀𝒴ml;䅸ЀHacdefosᔵᔹᔿᕋᕏᕝᕠᕤcy;䐖cute;䅹Āayᕄᕉron;䅽;䐗ot;䅻Dzᕔ\0ᕛoWidtè૙a;䎖r;愨pf;愤cr;쀀𝒵௡ᖃᖊᖐ\0ᖰᖶᖿ\0\0\0\0ᗆᗛᗫᙟ᙭\0ᚕ᚛ᚲᚹ\0ᚾcute耻á䃡reve;䄃̀;Ediuyᖜᖝᖡᖣᖨᖭ戾;쀀∾̳;房rc耻â䃢te肻´̆;䐰lig耻æ䃦Ā;r²ᖺ;쀀𝔞rave耻à䃠ĀepᗊᗖĀfpᗏᗔsym;愵èᗓha;䎱ĀapᗟcĀclᗤᗧr;䄁g;樿ɤᗰ\0\0ᘊʀ;adsvᗺᗻᗿᘁᘇ戧nd;橕;橜lope;橘;橚΀;elmrszᘘᘙᘛᘞᘿᙏᙙ戠;榤e»ᘙsdĀ;aᘥᘦ戡ѡᘰᘲᘴᘶᘸᘺᘼᘾ;榨;榩;榪;榫;榬;榭;榮;榯tĀ;vᙅᙆ戟bĀ;dᙌᙍ抾;榝Āptᙔᙗh;戢»¹arr;捼Āgpᙣᙧon;䄅f;쀀𝕒΀;Eaeiop዁ᙻᙽᚂᚄᚇᚊ;橰cir;橯;扊d;手s;䀧roxĀ;e዁ᚒñᚃing耻å䃥ƀctyᚡᚦᚨr;쀀𝒶;䀪mpĀ;e዁ᚯñʈilde耻ã䃣ml耻ä䃤Āciᛂᛈoninôɲnt;樑ࠀNabcdefiklnoprsu᛭ᛱᜰ᜼ᝃᝈ᝸᝽០៦ᠹᡐᜍ᤽᥈ᥰot;櫭Ācrᛶ᜞kȀcepsᜀᜅᜍᜓong;扌psilon;䏶rime;怵imĀ;e᜚᜛戽q;拍Ŷᜢᜦee;抽edĀ;gᜬᜭ挅e»ᜭrkĀ;t፜᜷brk;掶Āoyᜁᝁ;䐱quo;怞ʀcmprtᝓ᝛ᝡᝤᝨausĀ;eĊĉptyv;榰séᜌnoõēƀahwᝯ᝱ᝳ;䎲;愶een;扬r;쀀𝔟g΀costuvwឍឝឳេ៕៛៞ƀaiuបពរðݠrc;旯p»፱ƀdptឤឨឭot;樀lus;樁imes;樂ɱឹ\0\0ើcup;樆ar;昅riangleĀdu៍្own;施p;斳plus;樄eåᑄåᒭarow;植ƀako៭ᠦᠵĀcn៲ᠣkƀlst៺֫᠂ozenge;槫riangleȀ;dlr᠒᠓᠘᠝斴own;斾eft;旂ight;斸k;搣Ʊᠫ\0ᠳƲᠯ\0ᠱ;斒;斑4;斓ck;斈ĀeoᠾᡍĀ;qᡃᡆ쀀=⃥uiv;쀀≡⃥t;挐Ȁptwxᡙᡞᡧᡬf;쀀𝕓Ā;tᏋᡣom»Ꮜtie;拈؀DHUVbdhmptuvᢅᢖᢪᢻᣗᣛᣬ᣿ᤅᤊᤐᤡȀLRlrᢎᢐᢒᢔ;敗;敔;敖;敓ʀ;DUduᢡᢢᢤᢦᢨ敐;敦;敩;敤;敧ȀLRlrᢳᢵᢷᢹ;敝;敚;敜;教΀;HLRhlrᣊᣋᣍᣏᣑᣓᣕ救;敬;散;敠;敫;敢;敟ox;槉ȀLRlrᣤᣦᣨᣪ;敕;敒;攐;攌ʀ;DUduڽ᣷᣹᣻᣽;敥;敨;攬;攴inus;抟lus;択imes;抠ȀLRlrᤙᤛᤝ᤟;敛;敘;攘;攔΀;HLRhlrᤰᤱᤳᤵᤷ᤻᤹攂;敪;敡;敞;攼;攤;攜Āevģ᥂bar耻¦䂦Ȁceioᥑᥖᥚᥠr;쀀𝒷mi;恏mĀ;e᜚᜜lƀ;bhᥨᥩᥫ䁜;槅sub;柈Ŭᥴ᥾lĀ;e᥹᥺怢t»᥺pƀ;Eeįᦅᦇ;檮Ā;qۜۛೡᦧ\0᧨ᨑᨕᨲ\0ᨷᩐ\0\0᪴\0\0᫁\0\0ᬡᬮ᭍᭒\0᯽\0ᰌƀcpr᦭ᦲ᧝ute;䄇̀;abcdsᦿᧀᧄ᧊᧕᧙戩nd;橄rcup;橉Āau᧏᧒p;橋p;橇ot;橀;쀀∩︀Āeo᧢᧥t;恁îړȀaeiu᧰᧻ᨁᨅǰ᧵\0᧸s;橍on;䄍dil耻ç䃧rc;䄉psĀ;sᨌᨍ橌m;橐ot;䄋ƀdmnᨛᨠᨦil肻¸ƭptyv;榲t脀¢;eᨭᨮ䂢räƲr;쀀𝔠ƀceiᨽᩀᩍy;䑇ckĀ;mᩇᩈ朓ark»ᩈ;䏇r΀;Ecefms᩟᩠ᩢᩫ᪤᪪᪮旋;槃ƀ;elᩩᩪᩭ䋆q;扗eɡᩴ\0\0᪈rrowĀlr᩼᪁eft;憺ight;憻ʀRSacd᪒᪔᪖᪚᪟»ཇ;擈st;抛irc;抚ash;抝nint;樐id;櫯cir;槂ubsĀ;u᪻᪼晣it»᪼ˬ᫇᫔᫺\0ᬊonĀ;eᫍᫎ䀺Ā;qÇÆɭ᫙\0\0᫢aĀ;t᫞᫟䀬;䁀ƀ;fl᫨᫩᫫戁îᅠeĀmx᫱᫶ent»᫩eóɍǧ᫾\0ᬇĀ;dኻᬂot;橭nôɆƀfryᬐᬔᬗ;쀀𝕔oäɔ脀©;sŕᬝr;愗Āaoᬥᬩrr;憵ss;朗Ācuᬲᬷr;쀀𝒸Ābpᬼ᭄Ā;eᭁᭂ櫏;櫑Ā;eᭉᭊ櫐;櫒dot;拯΀delprvw᭠᭬᭷ᮂᮬᯔ᯹arrĀlr᭨᭪;椸;椵ɰ᭲\0\0᭵r;拞c;拟arrĀ;p᭿ᮀ憶;椽̀;bcdosᮏᮐᮖᮡᮥᮨ截rcap;橈Āauᮛᮞp;橆p;橊ot;抍r;橅;쀀∪︀Ȁalrv᮵ᮿᯞᯣrrĀ;mᮼᮽ憷;椼yƀevwᯇᯔᯘqɰᯎ\0\0ᯒreã᭳uã᭵ee;拎edge;拏en耻¤䂤earrowĀlrᯮ᯳eft»ᮀight»ᮽeäᯝĀciᰁᰇoninôǷnt;戱lcty;挭ঀAHabcdefhijlorstuwz᰸᰻᰿ᱝᱩᱵᲊᲞᲬᲷ᳻᳿ᴍᵻᶑᶫᶻ᷆᷍rò΁ar;楥Ȁglrs᱈ᱍ᱒᱔ger;怠eth;愸òᄳhĀ;vᱚᱛ怐»ऊūᱡᱧarow;椏aã̕Āayᱮᱳron;䄏;䐴ƀ;ao̲ᱼᲄĀgrʿᲁr;懊tseq;橷ƀglmᲑᲔᲘ耻°䂰ta;䎴ptyv;榱ĀirᲣᲨsht;楿;쀀𝔡arĀlrᲳᲵ»ࣜ»သʀaegsv᳂͸᳖᳜᳠mƀ;oș᳊᳔ndĀ;ș᳑uit;晦amma;䏝in;拲ƀ;io᳧᳨᳸䃷de脀÷;o᳧ᳰntimes;拇nø᳷cy;䑒cɯᴆ\0\0ᴊrn;挞op;挍ʀlptuwᴘᴝᴢᵉᵕlar;䀤f;쀀𝕕ʀ;emps̋ᴭᴷᴽᵂqĀ;d͒ᴳot;扑inus;戸lus;戔quare;抡blebarwedgåúnƀadhᄮᵝᵧownarrowóᲃarpoonĀlrᵲᵶefôᲴighôᲶŢᵿᶅkaro÷གɯᶊ\0\0ᶎrn;挟op;挌ƀcotᶘᶣᶦĀryᶝᶡ;쀀𝒹;䑕l;槶rok;䄑Ādrᶰᶴot;拱iĀ;fᶺ᠖斿Āah᷀᷃ròЩaòྦangle;榦Āci᷒ᷕy;䑟grarr;柿ऀDacdefglmnopqrstuxḁḉḙḸոḼṉṡṾấắẽỡἪἷὄ὎὚ĀDoḆᴴoôᲉĀcsḎḔute耻é䃩ter;橮ȀaioyḢḧḱḶron;䄛rĀ;cḭḮ扖耻ê䃪lon;払;䑍ot;䄗ĀDrṁṅot;扒;쀀𝔢ƀ;rsṐṑṗ檚ave耻è䃨Ā;dṜṝ檖ot;檘Ȁ;ilsṪṫṲṴ檙nters;揧;愓Ā;dṹṺ檕ot;檗ƀapsẅẉẗcr;䄓tyƀ;svẒẓẕ戅et»ẓpĀ1;ẝẤijạả;怄;怅怃ĀgsẪẬ;䅋p;怂ĀgpẴẸon;䄙f;쀀𝕖ƀalsỄỎỒrĀ;sỊị拕l;槣us;橱iƀ;lvỚớở䎵on»ớ;䏵ȀcsuvỪỳἋἣĀioữḱrc»Ḯɩỹ\0\0ỻíՈantĀglἂἆtr»ṝess»Ṻƀaeiἒ἖Ἒls;䀽st;扟vĀ;DȵἠD;橸parsl;槥ĀDaἯἳot;打rr;楱ƀcdiἾὁỸr;愯oô͒ĀahὉὋ;䎷耻ð䃰Āmrὓὗl耻ë䃫o;悬ƀcipὡὤὧl;䀡sôծĀeoὬὴctatioîՙnentialåչৡᾒ\0ᾞ\0ᾡᾧ\0\0ῆῌ\0ΐ\0ῦῪ \0 ⁚llingdotseñṄy;䑄male;晀ƀilrᾭᾳ῁lig;耀ffiɩᾹ\0\0᾽g;耀ffig;耀ffl;쀀𝔣lig;耀filig;쀀fjƀaltῙ῜ῡt;晭ig;耀flns;斱of;䆒ǰ΅\0ῳf;쀀𝕗ĀakֿῷĀ;vῼ´拔;櫙artint;樍Āao‌⁕Ācs‑⁒ႉ‸⁅⁈\0⁐β•‥‧‪‬\0‮耻½䂽;慓耻¼䂼;慕;慙;慛Ƴ‴\0‶;慔;慖ʴ‾⁁\0\0⁃耻¾䂾;慗;慜5;慘ƶ⁌\0⁎;慚;慝8;慞l;恄wn;挢cr;쀀𝒻ࢀEabcdefgijlnorstv₂₉₟₥₰₴⃰⃵⃺⃿℃ℒℸ̗ℾ⅒↞Ā;lٍ₇;檌ƀcmpₐₕ₝ute;䇵maĀ;dₜ᳚䎳;檆reve;䄟Āiy₪₮rc;䄝;䐳ot;䄡Ȁ;lqsؾق₽⃉ƀ;qsؾٌ⃄lanô٥Ȁ;cdl٥⃒⃥⃕c;檩otĀ;o⃜⃝檀Ā;l⃢⃣檂;檄Ā;e⃪⃭쀀⋛︀s;檔r;쀀𝔤Ā;gٳ؛mel;愷cy;䑓Ȁ;Eajٚℌℎℐ;檒;檥;檤ȀEaesℛℝ℩ℴ;扩pĀ;p℣ℤ檊rox»ℤĀ;q℮ℯ檈Ā;q℮ℛim;拧pf;쀀𝕘Āci⅃ⅆr;愊mƀ;el٫ⅎ⅐;檎;檐茀>;cdlqr׮ⅠⅪⅮⅳⅹĀciⅥⅧ;檧r;橺ot;拗Par;榕uest;橼ʀadelsↄⅪ←ٖ↛ǰ↉\0↎proø₞r;楸qĀlqؿ↖lesó₈ií٫Āen↣↭rtneqq;쀀≩︀Å↪ԀAabcefkosy⇄⇇⇱⇵⇺∘∝∯≨≽ròΠȀilmr⇐⇔⇗⇛rsðᒄf»․ilôکĀdr⇠⇤cy;䑊ƀ;cwࣴ⇫⇯ir;楈;憭ar;意irc;䄥ƀalr∁∎∓rtsĀ;u∉∊晥it»∊lip;怦con;抹r;쀀𝔥sĀew∣∩arow;椥arow;椦ʀamopr∺∾≃≞≣rr;懿tht;戻kĀlr≉≓eftarrow;憩ightarrow;憪f;쀀𝕙bar;怕ƀclt≯≴≸r;쀀𝒽asè⇴rok;䄧Ābp⊂⊇ull;恃hen»ᱛૡ⊣\0⊪\0⊸⋅⋎\0⋕⋳\0\0⋸⌢⍧⍢⍿\0⎆⎪⎴cute耻í䃭ƀ;iyݱ⊰⊵rc耻î䃮;䐸Ācx⊼⊿y;䐵cl耻¡䂡ĀfrΟ⋉;쀀𝔦rave耻ì䃬Ȁ;inoܾ⋝⋩⋮Āin⋢⋦nt;樌t;戭fin;槜ta;愩lig;䄳ƀaop⋾⌚⌝ƀcgt⌅⌈⌗r;䄫ƀelpܟ⌏⌓inåގarôܠh;䄱f;抷ed;䆵ʀ;cfotӴ⌬⌱⌽⍁are;愅inĀ;t⌸⌹戞ie;槝doô⌙ʀ;celpݗ⍌⍐⍛⍡al;抺Āgr⍕⍙eróᕣã⍍arhk;樗rod;樼Ȁcgpt⍯⍲⍶⍻y;䑑on;䄯f;쀀𝕚a;䎹uest耻¿䂿Āci⎊⎏r;쀀𝒾nʀ;EdsvӴ⎛⎝⎡ӳ;拹ot;拵Ā;v⎦⎧拴;拳Ā;iݷ⎮lde;䄩ǫ⎸\0⎼cy;䑖l耻ï䃯̀cfmosu⏌⏗⏜⏡⏧⏵Āiy⏑⏕rc;䄵;䐹r;쀀𝔧ath;䈷pf;쀀𝕛ǣ⏬\0⏱r;쀀𝒿rcy;䑘kcy;䑔Ѐacfghjos␋␖␢␧␭␱␵␻ppaĀ;v␓␔䎺;䏰Āey␛␠dil;䄷;䐺r;쀀𝔨reen;䄸cy;䑅cy;䑜pf;쀀𝕜cr;쀀𝓀஀ABEHabcdefghjlmnoprstuv⑰⒁⒆⒍⒑┎┽╚▀♎♞♥♹♽⚚⚲⛘❝❨➋⟀⠁⠒ƀart⑷⑺⑼rò৆òΕail;椛arr;椎Ā;gঔ⒋;檋ar;楢ॣ⒥\0⒪\0⒱\0\0\0\0\0⒵Ⓔ\0ⓆⓈⓍ\0⓹ute;䄺mptyv;榴raîࡌbda;䎻gƀ;dlࢎⓁⓃ;榑åࢎ;檅uo耻«䂫rЀ;bfhlpst࢙ⓞⓦⓩ⓫⓮⓱⓵Ā;f࢝ⓣs;椟s;椝ë≒p;憫l;椹im;楳l;憢ƀ;ae⓿─┄檫il;椙Ā;s┉┊檭;쀀⪭︀ƀabr┕┙┝rr;椌rk;杲Āak┢┬cĀek┨┪;䁻;䁛Āes┱┳;榋lĀdu┹┻;榏;榍Ȁaeuy╆╋╖╘ron;䄾Ādi═╔il;䄼ìࢰâ┩;䐻Ȁcqrs╣╦╭╽a;椶uoĀ;rนᝆĀdu╲╷har;楧shar;楋h;憲ʀ;fgqs▋▌উ◳◿扤tʀahlrt▘▤▷◂◨rrowĀ;t࢙□aé⓶arpoonĀdu▯▴own»њp»०eftarrows;懇ightƀahs◍◖◞rrowĀ;sࣴࢧarpoonó྘quigarro÷⇰hreetimes;拋ƀ;qs▋ও◺lanôবʀ;cdgsব☊☍☝☨c;檨otĀ;o☔☕橿Ā;r☚☛檁;檃Ā;e☢☥쀀⋚︀s;檓ʀadegs☳☹☽♉♋pproøⓆot;拖qĀgq♃♅ôউgtò⒌ôছiíলƀilr♕࣡♚sht;楼;쀀𝔩Ā;Eজ♣;檑š♩♶rĀdu▲♮Ā;l॥♳;楪lk;斄cy;䑙ʀ;achtੈ⚈⚋⚑⚖rò◁orneòᴈard;楫ri;旺Āio⚟⚤dot;䅀ustĀ;a⚬⚭掰che»⚭ȀEaes⚻⚽⛉⛔;扨pĀ;p⛃⛄檉rox»⛄Ā;q⛎⛏檇Ā;q⛎⚻im;拦Ѐabnoptwz⛩⛴⛷✚✯❁❇❐Ānr⛮⛱g;柬r;懽rëࣁgƀlmr⛿✍✔eftĀar০✇ightá৲apsto;柼ightá৽parrowĀlr✥✩efô⓭ight;憬ƀafl✶✹✽r;榅;쀀𝕝us;樭imes;樴š❋❏st;戗áፎƀ;ef❗❘᠀旊nge»❘arĀ;l❤❥䀨t;榓ʀachmt❳❶❼➅➇ròࢨorneòᶌarĀ;d྘➃;業;怎ri;抿̀achiqt➘➝ੀ➢➮➻quo;怹r;쀀𝓁mƀ;egল➪➬;檍;檏Ābu┪➳oĀ;rฟ➹;怚rok;䅂萀<;cdhilqrࠫ⟒☹⟜⟠⟥⟪⟰Āci⟗⟙;檦r;橹reå◲mes;拉arr;楶uest;橻ĀPi⟵⟹ar;榖ƀ;ef⠀भ᠛旃rĀdu⠇⠍shar;楊har;楦Āen⠗⠡rtneqq;쀀≨︀Å⠞܀Dacdefhilnopsu⡀⡅⢂⢎⢓⢠⢥⢨⣚⣢⣤ઃ⣳⤂Dot;戺Ȁclpr⡎⡒⡣⡽r耻¯䂯Āet⡗⡙;時Ā;e⡞⡟朠se»⡟Ā;sျ⡨toȀ;dluျ⡳⡷⡻owîҌefôएðᏑker;斮Āoy⢇⢌mma;権;䐼ash;怔asuredangle»ᘦr;쀀𝔪o;愧ƀcdn⢯⢴⣉ro耻µ䂵Ȁ;acdᑤ⢽⣀⣄sôᚧir;櫰ot肻·Ƶusƀ;bd⣒ᤃ⣓戒Ā;uᴼ⣘;横ţ⣞⣡p;櫛ò−ðઁĀdp⣩⣮els;抧f;쀀𝕞Āct⣸⣽r;쀀𝓂pos»ᖝƀ;lm⤉⤊⤍䎼timap;抸ఀGLRVabcdefghijlmoprstuvw⥂⥓⥾⦉⦘⧚⧩⨕⨚⩘⩝⪃⪕⪤⪨⬄⬇⭄⭿⮮ⰴⱧⱼ⳩Āgt⥇⥋;쀀⋙̸Ā;v⥐௏쀀≫⃒ƀelt⥚⥲⥶ftĀar⥡⥧rrow;懍ightarrow;懎;쀀⋘̸Ā;v⥻ే쀀≪⃒ightarrow;懏ĀDd⦎⦓ash;抯ash;抮ʀbcnpt⦣⦧⦬⦱⧌la»˞ute;䅄g;쀀∠⃒ʀ;Eiop඄⦼⧀⧅⧈;쀀⩰̸d;쀀≋̸s;䅉roø඄urĀ;a⧓⧔普lĀ;s⧓ସdz⧟\0⧣p肻 ଷmpĀ;e௹ఀʀaeouy⧴⧾⨃⨐⨓ǰ⧹\0⧻;橃on;䅈dil;䅆ngĀ;dൾ⨊ot;쀀⩭̸p;橂;䐽ash;怓΀;Aadqsxஒ⨩⨭⨻⩁⩅⩐rr;懗rĀhr⨳⨶k;椤Ā;oᏲᏰot;쀀≐̸uiöୣĀei⩊⩎ar;椨í஘istĀ;s஠டr;쀀𝔫ȀEest௅⩦⩹⩼ƀ;qs஼⩭௡ƀ;qs஼௅⩴lanô௢ií௪Ā;rஶ⪁»ஷƀAap⪊⪍⪑rò⥱rr;憮ar;櫲ƀ;svྍ⪜ྌĀ;d⪡⪢拼;拺cy;䑚΀AEadest⪷⪺⪾⫂⫅⫶⫹rò⥦;쀀≦̸rr;憚r;急Ȁ;fqs఻⫎⫣⫯tĀar⫔⫙rro÷⫁ightarro÷⪐ƀ;qs఻⪺⫪lanôౕĀ;sౕ⫴»శiíౝĀ;rవ⫾iĀ;eచథiäඐĀpt⬌⬑f;쀀𝕟膀¬;in⬙⬚⬶䂬nȀ;Edvஉ⬤⬨⬮;쀀⋹̸ot;쀀⋵̸ǡஉ⬳⬵;拷;拶iĀ;vಸ⬼ǡಸ⭁⭃;拾;拽ƀaor⭋⭣⭩rȀ;ast୻⭕⭚⭟lleì୻l;쀀⫽⃥;쀀∂̸lint;樔ƀ;ceಒ⭰⭳uåಥĀ;cಘ⭸Ā;eಒ⭽ñಘȀAait⮈⮋⮝⮧rò⦈rrƀ;cw⮔⮕⮙憛;쀀⤳̸;쀀↝̸ghtarrow»⮕riĀ;eೋೖ΀chimpqu⮽⯍⯙⬄୸⯤⯯Ȁ;cerല⯆ഷ⯉uå൅;쀀𝓃ortɭ⬅\0\0⯖ará⭖mĀ;e൮⯟Ā;q൴൳suĀbp⯫⯭å೸åഋƀbcp⯶ⰑⰙȀ;Ees⯿ⰀഢⰄ抄;쀀⫅̸etĀ;eഛⰋqĀ;qണⰀcĀ;eലⰗñസȀ;EesⰢⰣൟⰧ抅;쀀⫆̸etĀ;e൘ⰮqĀ;qൠⰣȀgilrⰽⰿⱅⱇìௗlde耻ñ䃱çృiangleĀlrⱒⱜeftĀ;eచⱚñదightĀ;eೋⱥñ೗Ā;mⱬⱭ䎽ƀ;esⱴⱵⱹ䀣ro;愖p;怇ҀDHadgilrsⲏⲔⲙⲞⲣⲰⲶⳓⳣash;抭arr;椄p;쀀≍⃒ash;抬ĀetⲨⲬ;쀀≥⃒;쀀>⃒nfin;槞ƀAetⲽⳁⳅrr;椂;쀀≤⃒Ā;rⳊⳍ쀀<⃒ie;쀀⊴⃒ĀAtⳘⳜrr;椃rie;쀀⊵⃒im;쀀∼⃒ƀAan⳰⳴ⴂrr;懖rĀhr⳺⳽k;椣Ā;oᏧᏥear;椧ቓ᪕\0\0\0\0\0\0\0\0\0\0\0\0\0ⴭ\0ⴸⵈⵠⵥ⵲ⶄᬇ\0\0ⶍⶫ\0ⷈⷎ\0ⷜ⸙⸫⸾⹃Ācsⴱ᪗ute耻ó䃳ĀiyⴼⵅrĀ;c᪞ⵂ耻ô䃴;䐾ʀabios᪠ⵒⵗLjⵚlac;䅑v;樸old;榼lig;䅓Ācr⵩⵭ir;榿;쀀𝔬ͯ⵹\0\0⵼\0ⶂn;䋛ave耻ò䃲;槁Ābmⶈ෴ar;榵Ȁacitⶕ⶘ⶥⶨrò᪀Āir⶝ⶠr;榾oss;榻nå๒;槀ƀaeiⶱⶵⶹcr;䅍ga;䏉ƀcdnⷀⷅǍron;䎿;榶pf;쀀𝕠ƀaelⷔ⷗ǒr;榷rp;榹΀;adiosvⷪⷫⷮ⸈⸍⸐⸖戨rò᪆Ȁ;efmⷷⷸ⸂⸅橝rĀ;oⷾⷿ愴f»ⷿ耻ª䂪耻º䂺gof;抶r;橖lope;橗;橛ƀclo⸟⸡⸧ò⸁ash耻ø䃸l;折iŬⸯ⸴de耻õ䃵esĀ;aǛ⸺s;樶ml耻ö䃶bar;挽ૡ⹞\0⹽\0⺀⺝\0⺢⺹\0\0⻋ຜ\0⼓\0\0⼫⾼\0⿈rȀ;astЃ⹧⹲຅脀¶;l⹭⹮䂶leìЃɩ⹸\0\0⹻m;櫳;櫽y;䐿rʀcimpt⺋⺏⺓ᡥ⺗nt;䀥od;䀮il;怰enk;怱r;쀀𝔭ƀimo⺨⺰⺴Ā;v⺭⺮䏆;䏕maô੶ne;明ƀ;tv⺿⻀⻈䏀chfork»´;䏖Āau⻏⻟nĀck⻕⻝kĀ;h⇴⻛;愎ö⇴sҀ;abcdemst⻳⻴ᤈ⻹⻽⼄⼆⼊⼎䀫cir;樣ir;樢Āouᵀ⼂;樥;橲n肻±ຝim;樦wo;樧ƀipu⼙⼠⼥ntint;樕f;쀀𝕡nd耻£䂣Ԁ;Eaceinosu່⼿⽁⽄⽇⾁⾉⾒⽾⾶;檳p;檷uå໙Ā;c໎⽌̀;acens່⽙⽟⽦⽨⽾pproø⽃urlyeñ໙ñ໎ƀaes⽯⽶⽺pprox;檹qq;檵im;拨iíໟmeĀ;s⾈ຮ怲ƀEas⽸⾐⽺ð⽵ƀdfp໬⾙⾯ƀals⾠⾥⾪lar;挮ine;挒urf;挓Ā;t໻⾴ï໻rel;抰Āci⿀⿅r;쀀𝓅;䏈ncsp;怈̀fiopsu⿚⋢⿟⿥⿫⿱r;쀀𝔮pf;쀀𝕢rime;恗cr;쀀𝓆ƀaeo⿸〉〓tĀei⿾々rnionóڰnt;樖stĀ;e【】䀿ñἙô༔઀ABHabcdefhilmnoprstux぀けさすムㄎㄫㅇㅢㅲㆎ㈆㈕㈤㈩㉘㉮㉲㊐㊰㊷ƀartぇおがròႳòϝail;検aròᱥar;楤΀cdenqrtとふへみわゔヌĀeuねぱ;쀀∽̱te;䅕iãᅮmptyv;榳gȀ;del࿑らるろ;榒;榥å࿑uo耻»䂻rր;abcfhlpstw࿜ガクシスゼゾダッデナp;極Ā;f࿠ゴs;椠;椳s;椞ë≝ð✮l;楅im;楴l;憣;憝Āaiパフil;椚oĀ;nホボ戶aló༞ƀabrョリヮrò៥rk;杳ĀakンヽcĀekヹ・;䁽;䁝Āes㄂㄄;榌lĀduㄊㄌ;榎;榐Ȁaeuyㄗㄜㄧㄩron;䅙Ādiㄡㄥil;䅗ì࿲âヺ;䑀Ȁclqsㄴㄷㄽㅄa;椷dhar;楩uoĀ;rȎȍh;憳ƀacgㅎㅟངlȀ;ipsླྀㅘㅛႜnåႻarôྩt;断ƀilrㅩဣㅮsht;楽;쀀𝔯ĀaoㅷㆆrĀduㅽㅿ»ѻĀ;l႑ㆄ;楬Ā;vㆋㆌ䏁;䏱ƀgns㆕ㇹㇼht̀ahlrstㆤㆰ㇂㇘㇤㇮rrowĀ;t࿜ㆭaéトarpoonĀduㆻㆿowîㅾp»႒eftĀah㇊㇐rrowó࿪arpoonóՑightarrows;應quigarro÷ニhreetimes;拌g;䋚ingdotseñἲƀahm㈍㈐㈓rò࿪aòՑ;怏oustĀ;a㈞㈟掱che»㈟mid;櫮Ȁabpt㈲㈽㉀㉒Ānr㈷㈺g;柭r;懾rëဃƀafl㉇㉊㉎r;榆;쀀𝕣us;樮imes;樵Āap㉝㉧rĀ;g㉣㉤䀩t;榔olint;樒arò㇣Ȁachq㉻㊀Ⴜ㊅quo;怺r;쀀𝓇Ābu・㊊oĀ;rȔȓƀhir㊗㊛㊠reåㇸmes;拊iȀ;efl㊪ၙᠡ㊫方tri;槎luhar;楨;愞ൡ㋕㋛㋟㌬㌸㍱\0㍺㎤\0\0㏬㏰\0㐨㑈㑚㒭㒱㓊㓱\0㘖\0\0㘳cute;䅛quï➺Ԁ;Eaceinpsyᇭ㋳㋵㋿㌂㌋㌏㌟㌦㌩;檴ǰ㋺\0㋼;檸on;䅡uåᇾĀ;dᇳ㌇il;䅟rc;䅝ƀEas㌖㌘㌛;檶p;檺im;择olint;樓iíሄ;䑁otƀ;be㌴ᵇ㌵担;橦΀Aacmstx㍆㍊㍗㍛㍞㍣㍭rr;懘rĀhr㍐㍒ë∨Ā;oਸ਼਴t耻§䂧i;䀻war;椩mĀin㍩ðnuóñt;朶rĀ;o㍶⁕쀀𝔰Ȁacoy㎂㎆㎑㎠rp;景Āhy㎋㎏cy;䑉;䑈rtɭ㎙\0\0㎜iäᑤaraì⹯耻­䂭Āgm㎨㎴maƀ;fv㎱㎲㎲䏃;䏂Ѐ;deglnprካ㏅㏉㏎㏖㏞㏡㏦ot;橪Ā;q኱ኰĀ;E㏓㏔檞;檠Ā;E㏛㏜檝;檟e;扆lus;樤arr;楲aròᄽȀaeit㏸㐈㐏㐗Āls㏽㐄lsetmé㍪hp;樳parsl;槤Ādlᑣ㐔e;挣Ā;e㐜㐝檪Ā;s㐢㐣檬;쀀⪬︀ƀflp㐮㐳㑂tcy;䑌Ā;b㐸㐹䀯Ā;a㐾㐿槄r;挿f;쀀𝕤aĀdr㑍ЂesĀ;u㑔㑕晠it»㑕ƀcsu㑠㑹㒟Āau㑥㑯pĀ;sᆈ㑫;쀀⊓︀pĀ;sᆴ㑵;쀀⊔︀uĀbp㑿㒏ƀ;esᆗᆜ㒆etĀ;eᆗ㒍ñᆝƀ;esᆨᆭ㒖etĀ;eᆨ㒝ñᆮƀ;afᅻ㒦ְrť㒫ֱ»ᅼaròᅈȀcemt㒹㒾㓂㓅r;쀀𝓈tmîñiì㐕aræᆾĀar㓎㓕rĀ;f㓔ឿ昆Āan㓚㓭ightĀep㓣㓪psiloîỠhé⺯s»⡒ʀbcmnp㓻㕞ሉ㖋㖎Ҁ;Edemnprs㔎㔏㔑㔕㔞㔣㔬㔱㔶抂;櫅ot;檽Ā;dᇚ㔚ot;櫃ult;櫁ĀEe㔨㔪;櫋;把lus;檿arr;楹ƀeiu㔽㕒㕕tƀ;en㔎㕅㕋qĀ;qᇚ㔏eqĀ;q㔫㔨m;櫇Ābp㕚㕜;櫕;櫓c̀;acensᇭ㕬㕲㕹㕻㌦pproø㋺urlyeñᇾñᇳƀaes㖂㖈㌛pproø㌚qñ㌗g;晪ڀ123;Edehlmnps㖩㖬㖯ሜ㖲㖴㗀㗉㗕㗚㗟㗨㗭耻¹䂹耻²䂲耻³䂳;櫆Āos㖹㖼t;檾ub;櫘Ā;dሢ㗅ot;櫄sĀou㗏㗒l;柉b;櫗arr;楻ult;櫂ĀEe㗤㗦;櫌;抋lus;櫀ƀeiu㗴㘉㘌tƀ;enሜ㗼㘂qĀ;qሢ㖲eqĀ;q㗧㗤m;櫈Ābp㘑㘓;櫔;櫖ƀAan㘜㘠㘭rr;懙rĀhr㘦㘨ë∮Ā;oਫ਩war;椪lig耻ß䃟௡㙑㙝㙠ዎ㙳㙹\0㙾㛂\0\0\0\0\0㛛㜃\0㜉㝬\0\0\0㞇ɲ㙖\0\0㙛get;挖;䏄rë๟ƀaey㙦㙫㙰ron;䅥dil;䅣;䑂lrec;挕r;쀀𝔱Ȁeiko㚆㚝㚵㚼Dz㚋\0㚑eĀ4fኄኁaƀ;sv㚘㚙㚛䎸ym;䏑Ācn㚢㚲kĀas㚨㚮pproø዁im»ኬsðኞĀas㚺㚮ð዁rn耻þ䃾Ǭ̟㛆⋧es膀×;bd㛏㛐㛘䃗Ā;aᤏ㛕r;樱;樰ƀeps㛡㛣㜀á⩍Ȁ;bcf҆㛬㛰㛴ot;挶ir;櫱Ā;o㛹㛼쀀𝕥rk;櫚á㍢rime;怴ƀaip㜏㜒㝤dåቈ΀adempst㜡㝍㝀㝑㝗㝜㝟ngleʀ;dlqr㜰㜱㜶㝀㝂斵own»ᶻeftĀ;e⠀㜾ñम;扜ightĀ;e㊪㝋ñၚot;旬inus;樺lus;樹b;槍ime;樻ezium;揢ƀcht㝲㝽㞁Āry㝷㝻;쀀𝓉;䑆cy;䑛rok;䅧Āio㞋㞎xô᝷headĀlr㞗㞠eftarro÷ࡏightarrow»ཝऀAHabcdfghlmoprstuw㟐㟓㟗㟤㟰㟼㠎㠜㠣㠴㡑㡝㡫㢩㣌㣒㣪㣶ròϭar;楣Ācr㟜㟢ute耻ú䃺òᅐrǣ㟪\0㟭y;䑞ve;䅭Āiy㟵㟺rc耻û䃻;䑃ƀabh㠃㠆㠋ròᎭlac;䅱aòᏃĀir㠓㠘sht;楾;쀀𝔲rave耻ù䃹š㠧㠱rĀlr㠬㠮»ॗ»ႃlk;斀Āct㠹㡍ɯ㠿\0\0㡊rnĀ;e㡅㡆挜r»㡆op;挏ri;旸Āal㡖㡚cr;䅫肻¨͉Āgp㡢㡦on;䅳f;쀀𝕦̀adhlsuᅋ㡸㡽፲㢑㢠ownáᎳarpoonĀlr㢈㢌efô㠭ighô㠯iƀ;hl㢙㢚㢜䏅»ᏺon»㢚parrows;懈ƀcit㢰㣄㣈ɯ㢶\0\0㣁rnĀ;e㢼㢽挝r»㢽op;挎ng;䅯ri;旹cr;쀀𝓊ƀdir㣙㣝㣢ot;拰lde;䅩iĀ;f㜰㣨»᠓Āam㣯㣲rò㢨l耻ü䃼angle;榧ހABDacdeflnoprsz㤜㤟㤩㤭㦵㦸㦽㧟㧤㧨㧳㧹㧽㨁㨠ròϷarĀ;v㤦㤧櫨;櫩asèϡĀnr㤲㤷grt;榜΀eknprst㓣㥆㥋㥒㥝㥤㦖appá␕othinçẖƀhir㓫⻈㥙opô⾵Ā;hᎷ㥢ïㆍĀiu㥩㥭gmá㎳Ābp㥲㦄setneqĀ;q㥽㦀쀀⊊︀;쀀⫋︀setneqĀ;q㦏㦒쀀⊋︀;쀀⫌︀Āhr㦛㦟etá㚜iangleĀlr㦪㦯eft»थight»ၑy;䐲ash»ံƀelr㧄㧒㧗ƀ;beⷪ㧋㧏ar;抻q;扚lip;拮Ābt㧜ᑨaòᑩr;쀀𝔳tré㦮suĀbp㧯㧱»ജ»൙pf;쀀𝕧roð໻tré㦴Ācu㨆㨋r;쀀𝓋Ābp㨐㨘nĀEe㦀㨖»㥾nĀEe㦒㨞»㦐igzag;榚΀cefoprs㨶㨻㩖㩛㩔㩡㩪irc;䅵Ādi㩀㩑Ābg㩅㩉ar;機eĀ;qᗺ㩏;扙erp;愘r;쀀𝔴pf;쀀𝕨Ā;eᑹ㩦atèᑹcr;쀀𝓌ૣណ㪇\0㪋\0㪐㪛\0\0㪝㪨㪫㪯\0\0㫃㫎\0㫘ៜ៟tré៑r;쀀𝔵ĀAa㪔㪗ròσrò৶;䎾ĀAa㪡㪤ròθrò৫að✓is;拻ƀdptឤ㪵㪾Āfl㪺ឩ;쀀𝕩imåឲĀAa㫇㫊ròώròਁĀcq㫒ីr;쀀𝓍Āpt៖㫜ré។Ѐacefiosu㫰㫽㬈㬌㬑㬕㬛㬡cĀuy㫶㫻te耻ý䃽;䑏Āiy㬂㬆rc;䅷;䑋n耻¥䂥r;쀀𝔶cy;䑗pf;쀀𝕪cr;쀀𝓎Ācm㬦㬩y;䑎l耻ÿ䃿Ԁacdefhiosw㭂㭈㭔㭘㭤㭩㭭㭴㭺㮀cute;䅺Āay㭍㭒ron;䅾;䐷ot;䅼Āet㭝㭡træᕟa;䎶r;쀀𝔷cy;䐶grarr;懝pf;쀀𝕫cr;쀀𝓏Ājn㮅㮇;怍j;怌'.split("").map(c2=>c2.charCodeAt(0))),decodeMap=new Map([[0,65533],[128,8364],[130,8218],[131,402],[132,8222],[133,8230],[134,8224],[135,8225],[136,710],[137,8240],[138,352],[139,8249],[140,338],[142,381],[145,8216],[146,8217],[147,8220],[148,8221],[149,8226],[150,8211],[151,8212],[152,732],[153,8482],[154,353],[155,8250],[156,339],[158,382],[159,376]]);function replaceCodePoint(codePoint){var _a18;return codePoint>=55296&&codePoint<=57343||codePoint>1114111?65533:(_a18=decodeMap.get(codePoint))!==null&&_a18!==void 0?_a18:codePoint}__name(replaceCodePoint,"replaceCodePoint");var CharCodes;(function(CharCodes2){CharCodes2[CharCodes2.NUM=35]="NUM",CharCodes2[CharCodes2.SEMI=59]="SEMI",CharCodes2[CharCodes2.EQUALS=61]="EQUALS",CharCodes2[CharCodes2.ZERO=48]="ZERO",CharCodes2[CharCodes2.NINE=57]="NINE",CharCodes2[CharCodes2.LOWER_A=97]="LOWER_A",CharCodes2[CharCodes2.LOWER_F=102]="LOWER_F",CharCodes2[CharCodes2.LOWER_X=120]="LOWER_X",CharCodes2[CharCodes2.LOWER_Z=122]="LOWER_Z",CharCodes2[CharCodes2.UPPER_A=65]="UPPER_A",CharCodes2[CharCodes2.UPPER_F=70]="UPPER_F",CharCodes2[CharCodes2.UPPER_Z=90]="UPPER_Z"})(CharCodes||(CharCodes={}));const TO_LOWER_BIT=32;var BinTrieFlags;(function(BinTrieFlags2){BinTrieFlags2[BinTrieFlags2.VALUE_LENGTH=49152]="VALUE_LENGTH",BinTrieFlags2[BinTrieFlags2.BRANCH_LENGTH=16256]="BRANCH_LENGTH",BinTrieFlags2[BinTrieFlags2.JUMP_TABLE=127]="JUMP_TABLE"})(BinTrieFlags||(BinTrieFlags={}));function isNumber2(code2){return code2>=CharCodes.ZERO&&code2<=CharCodes.NINE}__name(isNumber2,"isNumber");function isHexadecimalCharacter(code2){return code2>=CharCodes.UPPER_A&&code2<=CharCodes.UPPER_F||code2>=CharCodes.LOWER_A&&code2<=CharCodes.LOWER_F}__name(isHexadecimalCharacter,"isHexadecimalCharacter");function isAsciiAlphaNumeric$1(code2){return code2>=CharCodes.UPPER_A&&code2<=CharCodes.UPPER_Z||code2>=CharCodes.LOWER_A&&code2<=CharCodes.LOWER_Z||isNumber2(code2)}__name(isAsciiAlphaNumeric$1,"isAsciiAlphaNumeric$1");function isEntityInAttributeInvalidEnd(code2){return code2===CharCodes.EQUALS||isAsciiAlphaNumeric$1(code2)}__name(isEntityInAttributeInvalidEnd,"isEntityInAttributeInvalidEnd");var EntityDecoderState;(function(EntityDecoderState2){EntityDecoderState2[EntityDecoderState2.EntityStart=0]="EntityStart",EntityDecoderState2[EntityDecoderState2.NumericStart=1]="NumericStart",EntityDecoderState2[EntityDecoderState2.NumericDecimal=2]="NumericDecimal",EntityDecoderState2[EntityDecoderState2.NumericHex=3]="NumericHex",EntityDecoderState2[EntityDecoderState2.NamedEntity=4]="NamedEntity"})(EntityDecoderState||(EntityDecoderState={}));var DecodingMode;(function(DecodingMode2){DecodingMode2[DecodingMode2.Legacy=0]="Legacy",DecodingMode2[DecodingMode2.Strict=1]="Strict",DecodingMode2[DecodingMode2.Attribute=2]="Attribute"})(DecodingMode||(DecodingMode={}));const _EntityDecoder=class _EntityDecoder{constructor(decodeTree,emitCodePoint,errors){this.decodeTree=decodeTree,this.emitCodePoint=emitCodePoint,this.errors=errors,this.state=EntityDecoderState.EntityStart,this.consumed=1,this.result=0,this.treeIndex=0,this.excess=1,this.decodeMode=DecodingMode.Strict}startEntity(decodeMode){this.decodeMode=decodeMode,this.state=EntityDecoderState.EntityStart,this.result=0,this.treeIndex=0,this.excess=1,this.consumed=1}write(input,offset2){switch(this.state){case EntityDecoderState.EntityStart:return input.charCodeAt(offset2)===CharCodes.NUM?(this.state=EntityDecoderState.NumericStart,this.consumed+=1,this.stateNumericStart(input,offset2+1)):(this.state=EntityDecoderState.NamedEntity,this.stateNamedEntity(input,offset2));case EntityDecoderState.NumericStart:return this.stateNumericStart(input,offset2);case EntityDecoderState.NumericDecimal:return this.stateNumericDecimal(input,offset2);case EntityDecoderState.NumericHex:return this.stateNumericHex(input,offset2);case EntityDecoderState.NamedEntity:return this.stateNamedEntity(input,offset2)}}stateNumericStart(input,offset2){return offset2>=input.length?-1:(input.charCodeAt(offset2)|TO_LOWER_BIT)===CharCodes.LOWER_X?(this.state=EntityDecoderState.NumericHex,this.consumed+=1,this.stateNumericHex(input,offset2+1)):(this.state=EntityDecoderState.NumericDecimal,this.stateNumericDecimal(input,offset2))}addToNumericResult(input,start2,end,base){if(start2!==end){const digitCount=end-start2;this.result=this.result*Math.pow(base,digitCount)+Number.parseInt(input.substr(start2,digitCount),base),this.consumed+=digitCount}}stateNumericHex(input,offset2){const startIndex=offset2;for(;offset2>14;for(;offset2>14,valueLength!==0){if(char===CharCodes.SEMI)return this.emitNamedEntityData(this.treeIndex,valueLength,this.consumed+this.excess);this.decodeMode!==DecodingMode.Strict&&(this.result=this.treeIndex,this.consumed+=this.excess,this.excess=0)}}return-1}emitNotTerminatedNamedEntity(){var _a18;const{result,decodeTree}=this,valueLength=(decodeTree[result]&BinTrieFlags.VALUE_LENGTH)>>14;return this.emitNamedEntityData(result,valueLength,this.consumed),(_a18=this.errors)===null||_a18===void 0||_a18.missingSemicolonAfterCharacterReference(),this.consumed}emitNamedEntityData(result,valueLength,consumed){const{decodeTree}=this;return this.emitCodePoint(valueLength===1?decodeTree[result]&~BinTrieFlags.VALUE_LENGTH:decodeTree[result+1],consumed),valueLength===3&&this.emitCodePoint(decodeTree[result+2],consumed),consumed}end(){var _a18;switch(this.state){case EntityDecoderState.NamedEntity:return this.result!==0&&(this.decodeMode!==DecodingMode.Attribute||this.result===this.treeIndex)?this.emitNotTerminatedNamedEntity():0;case EntityDecoderState.NumericDecimal:return this.emitNumericEntity(0,2);case EntityDecoderState.NumericHex:return this.emitNumericEntity(0,3);case EntityDecoderState.NumericStart:return(_a18=this.errors)===null||_a18===void 0||_a18.absenceOfDigitsInNumericCharacterReference(this.consumed),0;case EntityDecoderState.EntityStart:return 0}}};__name(_EntityDecoder,"EntityDecoder");let EntityDecoder=_EntityDecoder;function determineBranch(decodeTree,current,nodeIndex,char){const branchCount=(current&BinTrieFlags.BRANCH_LENGTH)>>7,jumpOffset=current&BinTrieFlags.JUMP_TABLE;if(branchCount===0)return jumpOffset!==0&&char===jumpOffset?nodeIndex:-1;if(jumpOffset){const value2=char-jumpOffset;return value2<0||value2>=branchCount?-1:decodeTree[nodeIndex+value2]-1}let lo=nodeIndex,hi=lo+branchCount-1;for(;lo<=hi;){const mid=lo+hi>>>1,midValue=decodeTree[mid];if(midValuechar)hi=mid-1;else return decodeTree[mid+branchCount]}return-1}__name(determineBranch,"determineBranch");var NS;(function(NS2){NS2.HTML="http://www.w3.org/1999/xhtml",NS2.MATHML="http://www.w3.org/1998/Math/MathML",NS2.SVG="http://www.w3.org/2000/svg",NS2.XLINK="http://www.w3.org/1999/xlink",NS2.XML="http://www.w3.org/XML/1998/namespace",NS2.XMLNS="http://www.w3.org/2000/xmlns/"})(NS||(NS={}));var ATTRS;(function(ATTRS2){ATTRS2.TYPE="type",ATTRS2.ACTION="action",ATTRS2.ENCODING="encoding",ATTRS2.PROMPT="prompt",ATTRS2.NAME="name",ATTRS2.COLOR="color",ATTRS2.FACE="face",ATTRS2.SIZE="size"})(ATTRS||(ATTRS={}));var DOCUMENT_MODE;(function(DOCUMENT_MODE2){DOCUMENT_MODE2.NO_QUIRKS="no-quirks",DOCUMENT_MODE2.QUIRKS="quirks",DOCUMENT_MODE2.LIMITED_QUIRKS="limited-quirks"})(DOCUMENT_MODE||(DOCUMENT_MODE={}));var TAG_NAMES;(function(TAG_NAMES2){TAG_NAMES2.A="a",TAG_NAMES2.ADDRESS="address",TAG_NAMES2.ANNOTATION_XML="annotation-xml",TAG_NAMES2.APPLET="applet",TAG_NAMES2.AREA="area",TAG_NAMES2.ARTICLE="article",TAG_NAMES2.ASIDE="aside",TAG_NAMES2.B="b",TAG_NAMES2.BASE="base",TAG_NAMES2.BASEFONT="basefont",TAG_NAMES2.BGSOUND="bgsound",TAG_NAMES2.BIG="big",TAG_NAMES2.BLOCKQUOTE="blockquote",TAG_NAMES2.BODY="body",TAG_NAMES2.BR="br",TAG_NAMES2.BUTTON="button",TAG_NAMES2.CAPTION="caption",TAG_NAMES2.CENTER="center",TAG_NAMES2.CODE="code",TAG_NAMES2.COL="col",TAG_NAMES2.COLGROUP="colgroup",TAG_NAMES2.DD="dd",TAG_NAMES2.DESC="desc",TAG_NAMES2.DETAILS="details",TAG_NAMES2.DIALOG="dialog",TAG_NAMES2.DIR="dir",TAG_NAMES2.DIV="div",TAG_NAMES2.DL="dl",TAG_NAMES2.DT="dt",TAG_NAMES2.EM="em",TAG_NAMES2.EMBED="embed",TAG_NAMES2.FIELDSET="fieldset",TAG_NAMES2.FIGCAPTION="figcaption",TAG_NAMES2.FIGURE="figure",TAG_NAMES2.FONT="font",TAG_NAMES2.FOOTER="footer",TAG_NAMES2.FOREIGN_OBJECT="foreignObject",TAG_NAMES2.FORM="form",TAG_NAMES2.FRAME="frame",TAG_NAMES2.FRAMESET="frameset",TAG_NAMES2.H1="h1",TAG_NAMES2.H2="h2",TAG_NAMES2.H3="h3",TAG_NAMES2.H4="h4",TAG_NAMES2.H5="h5",TAG_NAMES2.H6="h6",TAG_NAMES2.HEAD="head",TAG_NAMES2.HEADER="header",TAG_NAMES2.HGROUP="hgroup",TAG_NAMES2.HR="hr",TAG_NAMES2.HTML="html",TAG_NAMES2.I="i",TAG_NAMES2.IMG="img",TAG_NAMES2.IMAGE="image",TAG_NAMES2.INPUT="input",TAG_NAMES2.IFRAME="iframe",TAG_NAMES2.KEYGEN="keygen",TAG_NAMES2.LABEL="label",TAG_NAMES2.LI="li",TAG_NAMES2.LINK="link",TAG_NAMES2.LISTING="listing",TAG_NAMES2.MAIN="main",TAG_NAMES2.MALIGNMARK="malignmark",TAG_NAMES2.MARQUEE="marquee",TAG_NAMES2.MATH="math",TAG_NAMES2.MENU="menu",TAG_NAMES2.META="meta",TAG_NAMES2.MGLYPH="mglyph",TAG_NAMES2.MI="mi",TAG_NAMES2.MO="mo",TAG_NAMES2.MN="mn",TAG_NAMES2.MS="ms",TAG_NAMES2.MTEXT="mtext",TAG_NAMES2.NAV="nav",TAG_NAMES2.NOBR="nobr",TAG_NAMES2.NOFRAMES="noframes",TAG_NAMES2.NOEMBED="noembed",TAG_NAMES2.NOSCRIPT="noscript",TAG_NAMES2.OBJECT="object",TAG_NAMES2.OL="ol",TAG_NAMES2.OPTGROUP="optgroup",TAG_NAMES2.OPTION="option",TAG_NAMES2.P="p",TAG_NAMES2.PARAM="param",TAG_NAMES2.PLAINTEXT="plaintext",TAG_NAMES2.PRE="pre",TAG_NAMES2.RB="rb",TAG_NAMES2.RP="rp",TAG_NAMES2.RT="rt",TAG_NAMES2.RTC="rtc",TAG_NAMES2.RUBY="ruby",TAG_NAMES2.S="s",TAG_NAMES2.SCRIPT="script",TAG_NAMES2.SEARCH="search",TAG_NAMES2.SECTION="section",TAG_NAMES2.SELECT="select",TAG_NAMES2.SOURCE="source",TAG_NAMES2.SMALL="small",TAG_NAMES2.SPAN="span",TAG_NAMES2.STRIKE="strike",TAG_NAMES2.STRONG="strong",TAG_NAMES2.STYLE="style",TAG_NAMES2.SUB="sub",TAG_NAMES2.SUMMARY="summary",TAG_NAMES2.SUP="sup",TAG_NAMES2.TABLE="table",TAG_NAMES2.TBODY="tbody",TAG_NAMES2.TEMPLATE="template",TAG_NAMES2.TEXTAREA="textarea",TAG_NAMES2.TFOOT="tfoot",TAG_NAMES2.TD="td",TAG_NAMES2.TH="th",TAG_NAMES2.THEAD="thead",TAG_NAMES2.TITLE="title",TAG_NAMES2.TR="tr",TAG_NAMES2.TRACK="track",TAG_NAMES2.TT="tt",TAG_NAMES2.U="u",TAG_NAMES2.UL="ul",TAG_NAMES2.SVG="svg",TAG_NAMES2.VAR="var",TAG_NAMES2.WBR="wbr",TAG_NAMES2.XMP="xmp"})(TAG_NAMES||(TAG_NAMES={}));var TAG_ID;(function(TAG_ID2){TAG_ID2[TAG_ID2.UNKNOWN=0]="UNKNOWN",TAG_ID2[TAG_ID2.A=1]="A",TAG_ID2[TAG_ID2.ADDRESS=2]="ADDRESS",TAG_ID2[TAG_ID2.ANNOTATION_XML=3]="ANNOTATION_XML",TAG_ID2[TAG_ID2.APPLET=4]="APPLET",TAG_ID2[TAG_ID2.AREA=5]="AREA",TAG_ID2[TAG_ID2.ARTICLE=6]="ARTICLE",TAG_ID2[TAG_ID2.ASIDE=7]="ASIDE",TAG_ID2[TAG_ID2.B=8]="B",TAG_ID2[TAG_ID2.BASE=9]="BASE",TAG_ID2[TAG_ID2.BASEFONT=10]="BASEFONT",TAG_ID2[TAG_ID2.BGSOUND=11]="BGSOUND",TAG_ID2[TAG_ID2.BIG=12]="BIG",TAG_ID2[TAG_ID2.BLOCKQUOTE=13]="BLOCKQUOTE",TAG_ID2[TAG_ID2.BODY=14]="BODY",TAG_ID2[TAG_ID2.BR=15]="BR",TAG_ID2[TAG_ID2.BUTTON=16]="BUTTON",TAG_ID2[TAG_ID2.CAPTION=17]="CAPTION",TAG_ID2[TAG_ID2.CENTER=18]="CENTER",TAG_ID2[TAG_ID2.CODE=19]="CODE",TAG_ID2[TAG_ID2.COL=20]="COL",TAG_ID2[TAG_ID2.COLGROUP=21]="COLGROUP",TAG_ID2[TAG_ID2.DD=22]="DD",TAG_ID2[TAG_ID2.DESC=23]="DESC",TAG_ID2[TAG_ID2.DETAILS=24]="DETAILS",TAG_ID2[TAG_ID2.DIALOG=25]="DIALOG",TAG_ID2[TAG_ID2.DIR=26]="DIR",TAG_ID2[TAG_ID2.DIV=27]="DIV",TAG_ID2[TAG_ID2.DL=28]="DL",TAG_ID2[TAG_ID2.DT=29]="DT",TAG_ID2[TAG_ID2.EM=30]="EM",TAG_ID2[TAG_ID2.EMBED=31]="EMBED",TAG_ID2[TAG_ID2.FIELDSET=32]="FIELDSET",TAG_ID2[TAG_ID2.FIGCAPTION=33]="FIGCAPTION",TAG_ID2[TAG_ID2.FIGURE=34]="FIGURE",TAG_ID2[TAG_ID2.FONT=35]="FONT",TAG_ID2[TAG_ID2.FOOTER=36]="FOOTER",TAG_ID2[TAG_ID2.FOREIGN_OBJECT=37]="FOREIGN_OBJECT",TAG_ID2[TAG_ID2.FORM=38]="FORM",TAG_ID2[TAG_ID2.FRAME=39]="FRAME",TAG_ID2[TAG_ID2.FRAMESET=40]="FRAMESET",TAG_ID2[TAG_ID2.H1=41]="H1",TAG_ID2[TAG_ID2.H2=42]="H2",TAG_ID2[TAG_ID2.H3=43]="H3",TAG_ID2[TAG_ID2.H4=44]="H4",TAG_ID2[TAG_ID2.H5=45]="H5",TAG_ID2[TAG_ID2.H6=46]="H6",TAG_ID2[TAG_ID2.HEAD=47]="HEAD",TAG_ID2[TAG_ID2.HEADER=48]="HEADER",TAG_ID2[TAG_ID2.HGROUP=49]="HGROUP",TAG_ID2[TAG_ID2.HR=50]="HR",TAG_ID2[TAG_ID2.HTML=51]="HTML",TAG_ID2[TAG_ID2.I=52]="I",TAG_ID2[TAG_ID2.IMG=53]="IMG",TAG_ID2[TAG_ID2.IMAGE=54]="IMAGE",TAG_ID2[TAG_ID2.INPUT=55]="INPUT",TAG_ID2[TAG_ID2.IFRAME=56]="IFRAME",TAG_ID2[TAG_ID2.KEYGEN=57]="KEYGEN",TAG_ID2[TAG_ID2.LABEL=58]="LABEL",TAG_ID2[TAG_ID2.LI=59]="LI",TAG_ID2[TAG_ID2.LINK=60]="LINK",TAG_ID2[TAG_ID2.LISTING=61]="LISTING",TAG_ID2[TAG_ID2.MAIN=62]="MAIN",TAG_ID2[TAG_ID2.MALIGNMARK=63]="MALIGNMARK",TAG_ID2[TAG_ID2.MARQUEE=64]="MARQUEE",TAG_ID2[TAG_ID2.MATH=65]="MATH",TAG_ID2[TAG_ID2.MENU=66]="MENU",TAG_ID2[TAG_ID2.META=67]="META",TAG_ID2[TAG_ID2.MGLYPH=68]="MGLYPH",TAG_ID2[TAG_ID2.MI=69]="MI",TAG_ID2[TAG_ID2.MO=70]="MO",TAG_ID2[TAG_ID2.MN=71]="MN",TAG_ID2[TAG_ID2.MS=72]="MS",TAG_ID2[TAG_ID2.MTEXT=73]="MTEXT",TAG_ID2[TAG_ID2.NAV=74]="NAV",TAG_ID2[TAG_ID2.NOBR=75]="NOBR",TAG_ID2[TAG_ID2.NOFRAMES=76]="NOFRAMES",TAG_ID2[TAG_ID2.NOEMBED=77]="NOEMBED",TAG_ID2[TAG_ID2.NOSCRIPT=78]="NOSCRIPT",TAG_ID2[TAG_ID2.OBJECT=79]="OBJECT",TAG_ID2[TAG_ID2.OL=80]="OL",TAG_ID2[TAG_ID2.OPTGROUP=81]="OPTGROUP",TAG_ID2[TAG_ID2.OPTION=82]="OPTION",TAG_ID2[TAG_ID2.P=83]="P",TAG_ID2[TAG_ID2.PARAM=84]="PARAM",TAG_ID2[TAG_ID2.PLAINTEXT=85]="PLAINTEXT",TAG_ID2[TAG_ID2.PRE=86]="PRE",TAG_ID2[TAG_ID2.RB=87]="RB",TAG_ID2[TAG_ID2.RP=88]="RP",TAG_ID2[TAG_ID2.RT=89]="RT",TAG_ID2[TAG_ID2.RTC=90]="RTC",TAG_ID2[TAG_ID2.RUBY=91]="RUBY",TAG_ID2[TAG_ID2.S=92]="S",TAG_ID2[TAG_ID2.SCRIPT=93]="SCRIPT",TAG_ID2[TAG_ID2.SEARCH=94]="SEARCH",TAG_ID2[TAG_ID2.SECTION=95]="SECTION",TAG_ID2[TAG_ID2.SELECT=96]="SELECT",TAG_ID2[TAG_ID2.SOURCE=97]="SOURCE",TAG_ID2[TAG_ID2.SMALL=98]="SMALL",TAG_ID2[TAG_ID2.SPAN=99]="SPAN",TAG_ID2[TAG_ID2.STRIKE=100]="STRIKE",TAG_ID2[TAG_ID2.STRONG=101]="STRONG",TAG_ID2[TAG_ID2.STYLE=102]="STYLE",TAG_ID2[TAG_ID2.SUB=103]="SUB",TAG_ID2[TAG_ID2.SUMMARY=104]="SUMMARY",TAG_ID2[TAG_ID2.SUP=105]="SUP",TAG_ID2[TAG_ID2.TABLE=106]="TABLE",TAG_ID2[TAG_ID2.TBODY=107]="TBODY",TAG_ID2[TAG_ID2.TEMPLATE=108]="TEMPLATE",TAG_ID2[TAG_ID2.TEXTAREA=109]="TEXTAREA",TAG_ID2[TAG_ID2.TFOOT=110]="TFOOT",TAG_ID2[TAG_ID2.TD=111]="TD",TAG_ID2[TAG_ID2.TH=112]="TH",TAG_ID2[TAG_ID2.THEAD=113]="THEAD",TAG_ID2[TAG_ID2.TITLE=114]="TITLE",TAG_ID2[TAG_ID2.TR=115]="TR",TAG_ID2[TAG_ID2.TRACK=116]="TRACK",TAG_ID2[TAG_ID2.TT=117]="TT",TAG_ID2[TAG_ID2.U=118]="U",TAG_ID2[TAG_ID2.UL=119]="UL",TAG_ID2[TAG_ID2.SVG=120]="SVG",TAG_ID2[TAG_ID2.VAR=121]="VAR",TAG_ID2[TAG_ID2.WBR=122]="WBR",TAG_ID2[TAG_ID2.XMP=123]="XMP"})(TAG_ID||(TAG_ID={}));const TAG_NAME_TO_ID=new Map([[TAG_NAMES.A,TAG_ID.A],[TAG_NAMES.ADDRESS,TAG_ID.ADDRESS],[TAG_NAMES.ANNOTATION_XML,TAG_ID.ANNOTATION_XML],[TAG_NAMES.APPLET,TAG_ID.APPLET],[TAG_NAMES.AREA,TAG_ID.AREA],[TAG_NAMES.ARTICLE,TAG_ID.ARTICLE],[TAG_NAMES.ASIDE,TAG_ID.ASIDE],[TAG_NAMES.B,TAG_ID.B],[TAG_NAMES.BASE,TAG_ID.BASE],[TAG_NAMES.BASEFONT,TAG_ID.BASEFONT],[TAG_NAMES.BGSOUND,TAG_ID.BGSOUND],[TAG_NAMES.BIG,TAG_ID.BIG],[TAG_NAMES.BLOCKQUOTE,TAG_ID.BLOCKQUOTE],[TAG_NAMES.BODY,TAG_ID.BODY],[TAG_NAMES.BR,TAG_ID.BR],[TAG_NAMES.BUTTON,TAG_ID.BUTTON],[TAG_NAMES.CAPTION,TAG_ID.CAPTION],[TAG_NAMES.CENTER,TAG_ID.CENTER],[TAG_NAMES.CODE,TAG_ID.CODE],[TAG_NAMES.COL,TAG_ID.COL],[TAG_NAMES.COLGROUP,TAG_ID.COLGROUP],[TAG_NAMES.DD,TAG_ID.DD],[TAG_NAMES.DESC,TAG_ID.DESC],[TAG_NAMES.DETAILS,TAG_ID.DETAILS],[TAG_NAMES.DIALOG,TAG_ID.DIALOG],[TAG_NAMES.DIR,TAG_ID.DIR],[TAG_NAMES.DIV,TAG_ID.DIV],[TAG_NAMES.DL,TAG_ID.DL],[TAG_NAMES.DT,TAG_ID.DT],[TAG_NAMES.EM,TAG_ID.EM],[TAG_NAMES.EMBED,TAG_ID.EMBED],[TAG_NAMES.FIELDSET,TAG_ID.FIELDSET],[TAG_NAMES.FIGCAPTION,TAG_ID.FIGCAPTION],[TAG_NAMES.FIGURE,TAG_ID.FIGURE],[TAG_NAMES.FONT,TAG_ID.FONT],[TAG_NAMES.FOOTER,TAG_ID.FOOTER],[TAG_NAMES.FOREIGN_OBJECT,TAG_ID.FOREIGN_OBJECT],[TAG_NAMES.FORM,TAG_ID.FORM],[TAG_NAMES.FRAME,TAG_ID.FRAME],[TAG_NAMES.FRAMESET,TAG_ID.FRAMESET],[TAG_NAMES.H1,TAG_ID.H1],[TAG_NAMES.H2,TAG_ID.H2],[TAG_NAMES.H3,TAG_ID.H3],[TAG_NAMES.H4,TAG_ID.H4],[TAG_NAMES.H5,TAG_ID.H5],[TAG_NAMES.H6,TAG_ID.H6],[TAG_NAMES.HEAD,TAG_ID.HEAD],[TAG_NAMES.HEADER,TAG_ID.HEADER],[TAG_NAMES.HGROUP,TAG_ID.HGROUP],[TAG_NAMES.HR,TAG_ID.HR],[TAG_NAMES.HTML,TAG_ID.HTML],[TAG_NAMES.I,TAG_ID.I],[TAG_NAMES.IMG,TAG_ID.IMG],[TAG_NAMES.IMAGE,TAG_ID.IMAGE],[TAG_NAMES.INPUT,TAG_ID.INPUT],[TAG_NAMES.IFRAME,TAG_ID.IFRAME],[TAG_NAMES.KEYGEN,TAG_ID.KEYGEN],[TAG_NAMES.LABEL,TAG_ID.LABEL],[TAG_NAMES.LI,TAG_ID.LI],[TAG_NAMES.LINK,TAG_ID.LINK],[TAG_NAMES.LISTING,TAG_ID.LISTING],[TAG_NAMES.MAIN,TAG_ID.MAIN],[TAG_NAMES.MALIGNMARK,TAG_ID.MALIGNMARK],[TAG_NAMES.MARQUEE,TAG_ID.MARQUEE],[TAG_NAMES.MATH,TAG_ID.MATH],[TAG_NAMES.MENU,TAG_ID.MENU],[TAG_NAMES.META,TAG_ID.META],[TAG_NAMES.MGLYPH,TAG_ID.MGLYPH],[TAG_NAMES.MI,TAG_ID.MI],[TAG_NAMES.MO,TAG_ID.MO],[TAG_NAMES.MN,TAG_ID.MN],[TAG_NAMES.MS,TAG_ID.MS],[TAG_NAMES.MTEXT,TAG_ID.MTEXT],[TAG_NAMES.NAV,TAG_ID.NAV],[TAG_NAMES.NOBR,TAG_ID.NOBR],[TAG_NAMES.NOFRAMES,TAG_ID.NOFRAMES],[TAG_NAMES.NOEMBED,TAG_ID.NOEMBED],[TAG_NAMES.NOSCRIPT,TAG_ID.NOSCRIPT],[TAG_NAMES.OBJECT,TAG_ID.OBJECT],[TAG_NAMES.OL,TAG_ID.OL],[TAG_NAMES.OPTGROUP,TAG_ID.OPTGROUP],[TAG_NAMES.OPTION,TAG_ID.OPTION],[TAG_NAMES.P,TAG_ID.P],[TAG_NAMES.PARAM,TAG_ID.PARAM],[TAG_NAMES.PLAINTEXT,TAG_ID.PLAINTEXT],[TAG_NAMES.PRE,TAG_ID.PRE],[TAG_NAMES.RB,TAG_ID.RB],[TAG_NAMES.RP,TAG_ID.RP],[TAG_NAMES.RT,TAG_ID.RT],[TAG_NAMES.RTC,TAG_ID.RTC],[TAG_NAMES.RUBY,TAG_ID.RUBY],[TAG_NAMES.S,TAG_ID.S],[TAG_NAMES.SCRIPT,TAG_ID.SCRIPT],[TAG_NAMES.SEARCH,TAG_ID.SEARCH],[TAG_NAMES.SECTION,TAG_ID.SECTION],[TAG_NAMES.SELECT,TAG_ID.SELECT],[TAG_NAMES.SOURCE,TAG_ID.SOURCE],[TAG_NAMES.SMALL,TAG_ID.SMALL],[TAG_NAMES.SPAN,TAG_ID.SPAN],[TAG_NAMES.STRIKE,TAG_ID.STRIKE],[TAG_NAMES.STRONG,TAG_ID.STRONG],[TAG_NAMES.STYLE,TAG_ID.STYLE],[TAG_NAMES.SUB,TAG_ID.SUB],[TAG_NAMES.SUMMARY,TAG_ID.SUMMARY],[TAG_NAMES.SUP,TAG_ID.SUP],[TAG_NAMES.TABLE,TAG_ID.TABLE],[TAG_NAMES.TBODY,TAG_ID.TBODY],[TAG_NAMES.TEMPLATE,TAG_ID.TEMPLATE],[TAG_NAMES.TEXTAREA,TAG_ID.TEXTAREA],[TAG_NAMES.TFOOT,TAG_ID.TFOOT],[TAG_NAMES.TD,TAG_ID.TD],[TAG_NAMES.TH,TAG_ID.TH],[TAG_NAMES.THEAD,TAG_ID.THEAD],[TAG_NAMES.TITLE,TAG_ID.TITLE],[TAG_NAMES.TR,TAG_ID.TR],[TAG_NAMES.TRACK,TAG_ID.TRACK],[TAG_NAMES.TT,TAG_ID.TT],[TAG_NAMES.U,TAG_ID.U],[TAG_NAMES.UL,TAG_ID.UL],[TAG_NAMES.SVG,TAG_ID.SVG],[TAG_NAMES.VAR,TAG_ID.VAR],[TAG_NAMES.WBR,TAG_ID.WBR],[TAG_NAMES.XMP,TAG_ID.XMP]]);function getTagID(tagName){var _a18;return(_a18=TAG_NAME_TO_ID.get(tagName))!==null&&_a18!==void 0?_a18:TAG_ID.UNKNOWN}__name(getTagID,"getTagID");const $=TAG_ID,SPECIAL_ELEMENTS={[NS.HTML]:new Set([$.ADDRESS,$.APPLET,$.AREA,$.ARTICLE,$.ASIDE,$.BASE,$.BASEFONT,$.BGSOUND,$.BLOCKQUOTE,$.BODY,$.BR,$.BUTTON,$.CAPTION,$.CENTER,$.COL,$.COLGROUP,$.DD,$.DETAILS,$.DIR,$.DIV,$.DL,$.DT,$.EMBED,$.FIELDSET,$.FIGCAPTION,$.FIGURE,$.FOOTER,$.FORM,$.FRAME,$.FRAMESET,$.H1,$.H2,$.H3,$.H4,$.H5,$.H6,$.HEAD,$.HEADER,$.HGROUP,$.HR,$.HTML,$.IFRAME,$.IMG,$.INPUT,$.LI,$.LINK,$.LISTING,$.MAIN,$.MARQUEE,$.MENU,$.META,$.NAV,$.NOEMBED,$.NOFRAMES,$.NOSCRIPT,$.OBJECT,$.OL,$.P,$.PARAM,$.PLAINTEXT,$.PRE,$.SCRIPT,$.SECTION,$.SELECT,$.SOURCE,$.STYLE,$.SUMMARY,$.TABLE,$.TBODY,$.TD,$.TEMPLATE,$.TEXTAREA,$.TFOOT,$.TH,$.THEAD,$.TITLE,$.TR,$.TRACK,$.UL,$.WBR,$.XMP]),[NS.MATHML]:new Set([$.MI,$.MO,$.MN,$.MS,$.MTEXT,$.ANNOTATION_XML]),[NS.SVG]:new Set([$.TITLE,$.FOREIGN_OBJECT,$.DESC]),[NS.XLINK]:new Set,[NS.XML]:new Set,[NS.XMLNS]:new Set},NUMBERED_HEADERS=new Set([$.H1,$.H2,$.H3,$.H4,$.H5,$.H6]);TAG_NAMES.STYLE,TAG_NAMES.SCRIPT,TAG_NAMES.XMP,TAG_NAMES.IFRAME,TAG_NAMES.NOEMBED,TAG_NAMES.NOFRAMES,TAG_NAMES.PLAINTEXT;var State;(function(State2){State2[State2.DATA=0]="DATA",State2[State2.RCDATA=1]="RCDATA",State2[State2.RAWTEXT=2]="RAWTEXT",State2[State2.SCRIPT_DATA=3]="SCRIPT_DATA",State2[State2.PLAINTEXT=4]="PLAINTEXT",State2[State2.TAG_OPEN=5]="TAG_OPEN",State2[State2.END_TAG_OPEN=6]="END_TAG_OPEN",State2[State2.TAG_NAME=7]="TAG_NAME",State2[State2.RCDATA_LESS_THAN_SIGN=8]="RCDATA_LESS_THAN_SIGN",State2[State2.RCDATA_END_TAG_OPEN=9]="RCDATA_END_TAG_OPEN",State2[State2.RCDATA_END_TAG_NAME=10]="RCDATA_END_TAG_NAME",State2[State2.RAWTEXT_LESS_THAN_SIGN=11]="RAWTEXT_LESS_THAN_SIGN",State2[State2.RAWTEXT_END_TAG_OPEN=12]="RAWTEXT_END_TAG_OPEN",State2[State2.RAWTEXT_END_TAG_NAME=13]="RAWTEXT_END_TAG_NAME",State2[State2.SCRIPT_DATA_LESS_THAN_SIGN=14]="SCRIPT_DATA_LESS_THAN_SIGN",State2[State2.SCRIPT_DATA_END_TAG_OPEN=15]="SCRIPT_DATA_END_TAG_OPEN",State2[State2.SCRIPT_DATA_END_TAG_NAME=16]="SCRIPT_DATA_END_TAG_NAME",State2[State2.SCRIPT_DATA_ESCAPE_START=17]="SCRIPT_DATA_ESCAPE_START",State2[State2.SCRIPT_DATA_ESCAPE_START_DASH=18]="SCRIPT_DATA_ESCAPE_START_DASH",State2[State2.SCRIPT_DATA_ESCAPED=19]="SCRIPT_DATA_ESCAPED",State2[State2.SCRIPT_DATA_ESCAPED_DASH=20]="SCRIPT_DATA_ESCAPED_DASH",State2[State2.SCRIPT_DATA_ESCAPED_DASH_DASH=21]="SCRIPT_DATA_ESCAPED_DASH_DASH",State2[State2.SCRIPT_DATA_ESCAPED_LESS_THAN_SIGN=22]="SCRIPT_DATA_ESCAPED_LESS_THAN_SIGN",State2[State2.SCRIPT_DATA_ESCAPED_END_TAG_OPEN=23]="SCRIPT_DATA_ESCAPED_END_TAG_OPEN",State2[State2.SCRIPT_DATA_ESCAPED_END_TAG_NAME=24]="SCRIPT_DATA_ESCAPED_END_TAG_NAME",State2[State2.SCRIPT_DATA_DOUBLE_ESCAPE_START=25]="SCRIPT_DATA_DOUBLE_ESCAPE_START",State2[State2.SCRIPT_DATA_DOUBLE_ESCAPED=26]="SCRIPT_DATA_DOUBLE_ESCAPED",State2[State2.SCRIPT_DATA_DOUBLE_ESCAPED_DASH=27]="SCRIPT_DATA_DOUBLE_ESCAPED_DASH",State2[State2.SCRIPT_DATA_DOUBLE_ESCAPED_DASH_DASH=28]="SCRIPT_DATA_DOUBLE_ESCAPED_DASH_DASH",State2[State2.SCRIPT_DATA_DOUBLE_ESCAPED_LESS_THAN_SIGN=29]="SCRIPT_DATA_DOUBLE_ESCAPED_LESS_THAN_SIGN",State2[State2.SCRIPT_DATA_DOUBLE_ESCAPE_END=30]="SCRIPT_DATA_DOUBLE_ESCAPE_END",State2[State2.BEFORE_ATTRIBUTE_NAME=31]="BEFORE_ATTRIBUTE_NAME",State2[State2.ATTRIBUTE_NAME=32]="ATTRIBUTE_NAME",State2[State2.AFTER_ATTRIBUTE_NAME=33]="AFTER_ATTRIBUTE_NAME",State2[State2.BEFORE_ATTRIBUTE_VALUE=34]="BEFORE_ATTRIBUTE_VALUE",State2[State2.ATTRIBUTE_VALUE_DOUBLE_QUOTED=35]="ATTRIBUTE_VALUE_DOUBLE_QUOTED",State2[State2.ATTRIBUTE_VALUE_SINGLE_QUOTED=36]="ATTRIBUTE_VALUE_SINGLE_QUOTED",State2[State2.ATTRIBUTE_VALUE_UNQUOTED=37]="ATTRIBUTE_VALUE_UNQUOTED",State2[State2.AFTER_ATTRIBUTE_VALUE_QUOTED=38]="AFTER_ATTRIBUTE_VALUE_QUOTED",State2[State2.SELF_CLOSING_START_TAG=39]="SELF_CLOSING_START_TAG",State2[State2.BOGUS_COMMENT=40]="BOGUS_COMMENT",State2[State2.MARKUP_DECLARATION_OPEN=41]="MARKUP_DECLARATION_OPEN",State2[State2.COMMENT_START=42]="COMMENT_START",State2[State2.COMMENT_START_DASH=43]="COMMENT_START_DASH",State2[State2.COMMENT=44]="COMMENT",State2[State2.COMMENT_LESS_THAN_SIGN=45]="COMMENT_LESS_THAN_SIGN",State2[State2.COMMENT_LESS_THAN_SIGN_BANG=46]="COMMENT_LESS_THAN_SIGN_BANG",State2[State2.COMMENT_LESS_THAN_SIGN_BANG_DASH=47]="COMMENT_LESS_THAN_SIGN_BANG_DASH",State2[State2.COMMENT_LESS_THAN_SIGN_BANG_DASH_DASH=48]="COMMENT_LESS_THAN_SIGN_BANG_DASH_DASH",State2[State2.COMMENT_END_DASH=49]="COMMENT_END_DASH",State2[State2.COMMENT_END=50]="COMMENT_END",State2[State2.COMMENT_END_BANG=51]="COMMENT_END_BANG",State2[State2.DOCTYPE=52]="DOCTYPE",State2[State2.BEFORE_DOCTYPE_NAME=53]="BEFORE_DOCTYPE_NAME",State2[State2.DOCTYPE_NAME=54]="DOCTYPE_NAME",State2[State2.AFTER_DOCTYPE_NAME=55]="AFTER_DOCTYPE_NAME",State2[State2.AFTER_DOCTYPE_PUBLIC_KEYWORD=56]="AFTER_DOCTYPE_PUBLIC_KEYWORD",State2[State2.BEFORE_DOCTYPE_PUBLIC_IDENTIFIER=57]="BEFORE_DOCTYPE_PUBLIC_IDENTIFIER",State2[State2.DOCTYPE_PUBLIC_IDENTIFIER_DOUBLE_QUOTED=58]="DOCTYPE_PUBLIC_IDENTIFIER_DOUBLE_QUOTED",State2[State2.DOCTYPE_PUBLIC_IDENTIFIER_SINGLE_QUOTED=59]="DOCTYPE_PUBLIC_IDENTIFIER_SINGLE_QUOTED",State2[State2.AFTER_DOCTYPE_PUBLIC_IDENTIFIER=60]="AFTER_DOCTYPE_PUBLIC_IDENTIFIER",State2[State2.BETWEEN_DOCTYPE_PUBLIC_AND_SYSTEM_IDENTIFIERS=61]="BETWEEN_DOCTYPE_PUBLIC_AND_SYSTEM_IDENTIFIERS",State2[State2.AFTER_DOCTYPE_SYSTEM_KEYWORD=62]="AFTER_DOCTYPE_SYSTEM_KEYWORD",State2[State2.BEFORE_DOCTYPE_SYSTEM_IDENTIFIER=63]="BEFORE_DOCTYPE_SYSTEM_IDENTIFIER",State2[State2.DOCTYPE_SYSTEM_IDENTIFIER_DOUBLE_QUOTED=64]="DOCTYPE_SYSTEM_IDENTIFIER_DOUBLE_QUOTED",State2[State2.DOCTYPE_SYSTEM_IDENTIFIER_SINGLE_QUOTED=65]="DOCTYPE_SYSTEM_IDENTIFIER_SINGLE_QUOTED",State2[State2.AFTER_DOCTYPE_SYSTEM_IDENTIFIER=66]="AFTER_DOCTYPE_SYSTEM_IDENTIFIER",State2[State2.BOGUS_DOCTYPE=67]="BOGUS_DOCTYPE",State2[State2.CDATA_SECTION=68]="CDATA_SECTION",State2[State2.CDATA_SECTION_BRACKET=69]="CDATA_SECTION_BRACKET",State2[State2.CDATA_SECTION_END=70]="CDATA_SECTION_END",State2[State2.CHARACTER_REFERENCE=71]="CHARACTER_REFERENCE",State2[State2.AMBIGUOUS_AMPERSAND=72]="AMBIGUOUS_AMPERSAND"})(State||(State={}));const TokenizerMode={DATA:State.DATA,RCDATA:State.RCDATA,RAWTEXT:State.RAWTEXT,SCRIPT_DATA:State.SCRIPT_DATA,PLAINTEXT:State.PLAINTEXT,CDATA_SECTION:State.CDATA_SECTION};function isAsciiDigit(cp){return cp>=CODE_POINTS.DIGIT_0&&cp<=CODE_POINTS.DIGIT_9}__name(isAsciiDigit,"isAsciiDigit");function isAsciiUpper(cp){return cp>=CODE_POINTS.LATIN_CAPITAL_A&&cp<=CODE_POINTS.LATIN_CAPITAL_Z}__name(isAsciiUpper,"isAsciiUpper");function isAsciiLower(cp){return cp>=CODE_POINTS.LATIN_SMALL_A&&cp<=CODE_POINTS.LATIN_SMALL_Z}__name(isAsciiLower,"isAsciiLower");function isAsciiLetter(cp){return isAsciiLower(cp)||isAsciiUpper(cp)}__name(isAsciiLetter,"isAsciiLetter");function isAsciiAlphaNumeric(cp){return isAsciiLetter(cp)||isAsciiDigit(cp)}__name(isAsciiAlphaNumeric,"isAsciiAlphaNumeric");function toAsciiLower(cp){return cp+32}__name(toAsciiLower,"toAsciiLower");function isWhitespace(cp){return cp===CODE_POINTS.SPACE||cp===CODE_POINTS.LINE_FEED||cp===CODE_POINTS.TABULATION||cp===CODE_POINTS.FORM_FEED}__name(isWhitespace,"isWhitespace");function isScriptDataDoubleEscapeSequenceEnd(cp){return isWhitespace(cp)||cp===CODE_POINTS.SOLIDUS||cp===CODE_POINTS.GREATER_THAN_SIGN}__name(isScriptDataDoubleEscapeSequenceEnd,"isScriptDataDoubleEscapeSequenceEnd");function getErrorForNumericCharacterReference(code2){return code2===CODE_POINTS.NULL?ERR.nullCharacterReference:code2>1114111?ERR.characterReferenceOutsideUnicodeRange:isSurrogate(code2)?ERR.surrogateCharacterReference:isUndefinedCodePoint(code2)?ERR.noncharacterCharacterReference:isControlCodePoint(code2)||code2===CODE_POINTS.CARRIAGE_RETURN?ERR.controlCharacterReference:null}__name(getErrorForNumericCharacterReference,"getErrorForNumericCharacterReference");const _Tokenizer=class _Tokenizer{constructor(options,handler){this.options=options,this.handler=handler,this.paused=!1,this.inLoop=!1,this.inForeignNode=!1,this.lastStartTagName="",this.active=!1,this.state=State.DATA,this.returnState=State.DATA,this.entityStartPos=0,this.consumedAfterSnapshot=-1,this.currentCharacterToken=null,this.currentToken=null,this.currentAttr={name:"",value:""},this.preprocessor=new Preprocessor(handler),this.currentLocation=this.getCurrentLocation(-1),this.entityDecoder=new EntityDecoder(htmlDecodeTree,(cp,consumed)=>{this.preprocessor.pos=this.entityStartPos+consumed-1,this._flushCodePointConsumedAsCharacterReference(cp)},handler.onParseError?{missingSemicolonAfterCharacterReference:__name(()=>{this._err(ERR.missingSemicolonAfterCharacterReference,1)},"missingSemicolonAfterCharacterReference"),absenceOfDigitsInNumericCharacterReference:__name(consumed=>{this._err(ERR.absenceOfDigitsInNumericCharacterReference,this.entityStartPos-this.preprocessor.pos+consumed)},"absenceOfDigitsInNumericCharacterReference"),validateNumericCharacterReference:__name(code2=>{const error=getErrorForNumericCharacterReference(code2);error&&this._err(error,1)},"validateNumericCharacterReference")}:void 0)}_err(code2,cpOffset=0){var _a18,_b;(_b=(_a18=this.handler).onParseError)===null||_b===void 0||_b.call(_a18,this.preprocessor.getError(code2,cpOffset))}getCurrentLocation(offset2){return this.options.sourceCodeLocationInfo?{startLine:this.preprocessor.line,startCol:this.preprocessor.col-offset2,startOffset:this.preprocessor.offset-offset2,endLine:-1,endCol:-1,endOffset:-1}:null}_runParsingLoop(){if(!this.inLoop){for(this.inLoop=!0;this.active&&!this.paused;){this.consumedAfterSnapshot=0;const cp=this._consume();this._ensureHibernation()||this._callState(cp)}this.inLoop=!1}}pause(){this.paused=!0}resume(writeCallback){if(!this.paused)throw new Error("Parser was already resumed");this.paused=!1,!this.inLoop&&(this._runParsingLoop(),this.paused||writeCallback?.())}write(chunk,isLastChunk,writeCallback){this.active=!0,this.preprocessor.write(chunk,isLastChunk),this._runParsingLoop(),this.paused||writeCallback?.()}insertHtmlAtCurrentPos(chunk){this.active=!0,this.preprocessor.insertHtmlAtCurrentPos(chunk),this._runParsingLoop()}_ensureHibernation(){return this.preprocessor.endOfChunkHit?(this.preprocessor.retreat(this.consumedAfterSnapshot),this.consumedAfterSnapshot=0,this.active=!1,!0):!1}_consume(){return this.consumedAfterSnapshot++,this.preprocessor.advance()}_advanceBy(count2){this.consumedAfterSnapshot+=count2;for(let i2=0;i20&&this._err(ERR.endTagWithAttributes),ct.selfClosing&&this._err(ERR.endTagWithTrailingSolidus),this.handler.onEndTag(ct)),this.preprocessor.dropParsedChunk()}emitCurrentComment(ct){this.prepareToken(ct),this.handler.onComment(ct),this.preprocessor.dropParsedChunk()}emitCurrentDoctype(ct){this.prepareToken(ct),this.handler.onDoctype(ct),this.preprocessor.dropParsedChunk()}_emitCurrentCharacterToken(nextLocation){if(this.currentCharacterToken){switch(nextLocation&&this.currentCharacterToken.location&&(this.currentCharacterToken.location.endLine=nextLocation.startLine,this.currentCharacterToken.location.endCol=nextLocation.startCol,this.currentCharacterToken.location.endOffset=nextLocation.startOffset),this.currentCharacterToken.type){case TokenType.CHARACTER:{this.handler.onCharacter(this.currentCharacterToken);break}case TokenType.NULL_CHARACTER:{this.handler.onNullCharacter(this.currentCharacterToken);break}case TokenType.WHITESPACE_CHARACTER:{this.handler.onWhitespaceCharacter(this.currentCharacterToken);break}}this.currentCharacterToken=null}}_emitEOFToken(){const location2=this.getCurrentLocation(0);location2&&(location2.endLine=location2.startLine,location2.endCol=location2.startCol,location2.endOffset=location2.startOffset),this._emitCurrentCharacterToken(location2),this.handler.onEof({type:TokenType.EOF,location:location2}),this.active=!1}_appendCharToCurrentCharacterToken(type,ch){if(this.currentCharacterToken)if(this.currentCharacterToken.type===type){this.currentCharacterToken.chars+=ch;return}else this.currentLocation=this.getCurrentLocation(0),this._emitCurrentCharacterToken(this.currentLocation),this.preprocessor.dropParsedChunk();this._createCharacterToken(type,ch)}_emitCodePoint(cp){const type=isWhitespace(cp)?TokenType.WHITESPACE_CHARACTER:cp===CODE_POINTS.NULL?TokenType.NULL_CHARACTER:TokenType.CHARACTER;this._appendCharToCurrentCharacterToken(type,String.fromCodePoint(cp))}_emitChars(ch){this._appendCharToCurrentCharacterToken(TokenType.CHARACTER,ch)}_startCharacterReference(){this.returnState=this.state,this.state=State.CHARACTER_REFERENCE,this.entityStartPos=this.preprocessor.pos,this.entityDecoder.startEntity(this._isCharacterReferenceInAttribute()?DecodingMode.Attribute:DecodingMode.Legacy)}_isCharacterReferenceInAttribute(){return this.returnState===State.ATTRIBUTE_VALUE_DOUBLE_QUOTED||this.returnState===State.ATTRIBUTE_VALUE_SINGLE_QUOTED||this.returnState===State.ATTRIBUTE_VALUE_UNQUOTED}_flushCodePointConsumedAsCharacterReference(cp){this._isCharacterReferenceInAttribute()?this.currentAttr.value+=String.fromCodePoint(cp):this._emitCodePoint(cp)}_callState(cp){switch(this.state){case State.DATA:{this._stateData(cp);break}case State.RCDATA:{this._stateRcdata(cp);break}case State.RAWTEXT:{this._stateRawtext(cp);break}case State.SCRIPT_DATA:{this._stateScriptData(cp);break}case State.PLAINTEXT:{this._statePlaintext(cp);break}case State.TAG_OPEN:{this._stateTagOpen(cp);break}case State.END_TAG_OPEN:{this._stateEndTagOpen(cp);break}case State.TAG_NAME:{this._stateTagName(cp);break}case State.RCDATA_LESS_THAN_SIGN:{this._stateRcdataLessThanSign(cp);break}case State.RCDATA_END_TAG_OPEN:{this._stateRcdataEndTagOpen(cp);break}case State.RCDATA_END_TAG_NAME:{this._stateRcdataEndTagName(cp);break}case State.RAWTEXT_LESS_THAN_SIGN:{this._stateRawtextLessThanSign(cp);break}case State.RAWTEXT_END_TAG_OPEN:{this._stateRawtextEndTagOpen(cp);break}case State.RAWTEXT_END_TAG_NAME:{this._stateRawtextEndTagName(cp);break}case State.SCRIPT_DATA_LESS_THAN_SIGN:{this._stateScriptDataLessThanSign(cp);break}case State.SCRIPT_DATA_END_TAG_OPEN:{this._stateScriptDataEndTagOpen(cp);break}case State.SCRIPT_DATA_END_TAG_NAME:{this._stateScriptDataEndTagName(cp);break}case State.SCRIPT_DATA_ESCAPE_START:{this._stateScriptDataEscapeStart(cp);break}case State.SCRIPT_DATA_ESCAPE_START_DASH:{this._stateScriptDataEscapeStartDash(cp);break}case State.SCRIPT_DATA_ESCAPED:{this._stateScriptDataEscaped(cp);break}case State.SCRIPT_DATA_ESCAPED_DASH:{this._stateScriptDataEscapedDash(cp);break}case State.SCRIPT_DATA_ESCAPED_DASH_DASH:{this._stateScriptDataEscapedDashDash(cp);break}case State.SCRIPT_DATA_ESCAPED_LESS_THAN_SIGN:{this._stateScriptDataEscapedLessThanSign(cp);break}case State.SCRIPT_DATA_ESCAPED_END_TAG_OPEN:{this._stateScriptDataEscapedEndTagOpen(cp);break}case State.SCRIPT_DATA_ESCAPED_END_TAG_NAME:{this._stateScriptDataEscapedEndTagName(cp);break}case State.SCRIPT_DATA_DOUBLE_ESCAPE_START:{this._stateScriptDataDoubleEscapeStart(cp);break}case State.SCRIPT_DATA_DOUBLE_ESCAPED:{this._stateScriptDataDoubleEscaped(cp);break}case State.SCRIPT_DATA_DOUBLE_ESCAPED_DASH:{this._stateScriptDataDoubleEscapedDash(cp);break}case State.SCRIPT_DATA_DOUBLE_ESCAPED_DASH_DASH:{this._stateScriptDataDoubleEscapedDashDash(cp);break}case State.SCRIPT_DATA_DOUBLE_ESCAPED_LESS_THAN_SIGN:{this._stateScriptDataDoubleEscapedLessThanSign(cp);break}case State.SCRIPT_DATA_DOUBLE_ESCAPE_END:{this._stateScriptDataDoubleEscapeEnd(cp);break}case State.BEFORE_ATTRIBUTE_NAME:{this._stateBeforeAttributeName(cp);break}case State.ATTRIBUTE_NAME:{this._stateAttributeName(cp);break}case State.AFTER_ATTRIBUTE_NAME:{this._stateAfterAttributeName(cp);break}case State.BEFORE_ATTRIBUTE_VALUE:{this._stateBeforeAttributeValue(cp);break}case State.ATTRIBUTE_VALUE_DOUBLE_QUOTED:{this._stateAttributeValueDoubleQuoted(cp);break}case State.ATTRIBUTE_VALUE_SINGLE_QUOTED:{this._stateAttributeValueSingleQuoted(cp);break}case State.ATTRIBUTE_VALUE_UNQUOTED:{this._stateAttributeValueUnquoted(cp);break}case State.AFTER_ATTRIBUTE_VALUE_QUOTED:{this._stateAfterAttributeValueQuoted(cp);break}case State.SELF_CLOSING_START_TAG:{this._stateSelfClosingStartTag(cp);break}case State.BOGUS_COMMENT:{this._stateBogusComment(cp);break}case State.MARKUP_DECLARATION_OPEN:{this._stateMarkupDeclarationOpen(cp);break}case State.COMMENT_START:{this._stateCommentStart(cp);break}case State.COMMENT_START_DASH:{this._stateCommentStartDash(cp);break}case State.COMMENT:{this._stateComment(cp);break}case State.COMMENT_LESS_THAN_SIGN:{this._stateCommentLessThanSign(cp);break}case State.COMMENT_LESS_THAN_SIGN_BANG:{this._stateCommentLessThanSignBang(cp);break}case State.COMMENT_LESS_THAN_SIGN_BANG_DASH:{this._stateCommentLessThanSignBangDash(cp);break}case State.COMMENT_LESS_THAN_SIGN_BANG_DASH_DASH:{this._stateCommentLessThanSignBangDashDash(cp);break}case State.COMMENT_END_DASH:{this._stateCommentEndDash(cp);break}case State.COMMENT_END:{this._stateCommentEnd(cp);break}case State.COMMENT_END_BANG:{this._stateCommentEndBang(cp);break}case State.DOCTYPE:{this._stateDoctype(cp);break}case State.BEFORE_DOCTYPE_NAME:{this._stateBeforeDoctypeName(cp);break}case State.DOCTYPE_NAME:{this._stateDoctypeName(cp);break}case State.AFTER_DOCTYPE_NAME:{this._stateAfterDoctypeName(cp);break}case State.AFTER_DOCTYPE_PUBLIC_KEYWORD:{this._stateAfterDoctypePublicKeyword(cp);break}case State.BEFORE_DOCTYPE_PUBLIC_IDENTIFIER:{this._stateBeforeDoctypePublicIdentifier(cp);break}case State.DOCTYPE_PUBLIC_IDENTIFIER_DOUBLE_QUOTED:{this._stateDoctypePublicIdentifierDoubleQuoted(cp);break}case State.DOCTYPE_PUBLIC_IDENTIFIER_SINGLE_QUOTED:{this._stateDoctypePublicIdentifierSingleQuoted(cp);break}case State.AFTER_DOCTYPE_PUBLIC_IDENTIFIER:{this._stateAfterDoctypePublicIdentifier(cp);break}case State.BETWEEN_DOCTYPE_PUBLIC_AND_SYSTEM_IDENTIFIERS:{this._stateBetweenDoctypePublicAndSystemIdentifiers(cp);break}case State.AFTER_DOCTYPE_SYSTEM_KEYWORD:{this._stateAfterDoctypeSystemKeyword(cp);break}case State.BEFORE_DOCTYPE_SYSTEM_IDENTIFIER:{this._stateBeforeDoctypeSystemIdentifier(cp);break}case State.DOCTYPE_SYSTEM_IDENTIFIER_DOUBLE_QUOTED:{this._stateDoctypeSystemIdentifierDoubleQuoted(cp);break}case State.DOCTYPE_SYSTEM_IDENTIFIER_SINGLE_QUOTED:{this._stateDoctypeSystemIdentifierSingleQuoted(cp);break}case State.AFTER_DOCTYPE_SYSTEM_IDENTIFIER:{this._stateAfterDoctypeSystemIdentifier(cp);break}case State.BOGUS_DOCTYPE:{this._stateBogusDoctype(cp);break}case State.CDATA_SECTION:{this._stateCdataSection(cp);break}case State.CDATA_SECTION_BRACKET:{this._stateCdataSectionBracket(cp);break}case State.CDATA_SECTION_END:{this._stateCdataSectionEnd(cp);break}case State.CHARACTER_REFERENCE:{this._stateCharacterReference();break}case State.AMBIGUOUS_AMPERSAND:{this._stateAmbiguousAmpersand(cp);break}default:throw new Error("Unknown state")}}_stateData(cp){switch(cp){case CODE_POINTS.LESS_THAN_SIGN:{this.state=State.TAG_OPEN;break}case CODE_POINTS.AMPERSAND:{this._startCharacterReference();break}case CODE_POINTS.NULL:{this._err(ERR.unexpectedNullCharacter),this._emitCodePoint(cp);break}case CODE_POINTS.EOF:{this._emitEOFToken();break}default:this._emitCodePoint(cp)}}_stateRcdata(cp){switch(cp){case CODE_POINTS.AMPERSAND:{this._startCharacterReference();break}case CODE_POINTS.LESS_THAN_SIGN:{this.state=State.RCDATA_LESS_THAN_SIGN;break}case CODE_POINTS.NULL:{this._err(ERR.unexpectedNullCharacter),this._emitChars(REPLACEMENT_CHARACTER);break}case CODE_POINTS.EOF:{this._emitEOFToken();break}default:this._emitCodePoint(cp)}}_stateRawtext(cp){switch(cp){case CODE_POINTS.LESS_THAN_SIGN:{this.state=State.RAWTEXT_LESS_THAN_SIGN;break}case CODE_POINTS.NULL:{this._err(ERR.unexpectedNullCharacter),this._emitChars(REPLACEMENT_CHARACTER);break}case CODE_POINTS.EOF:{this._emitEOFToken();break}default:this._emitCodePoint(cp)}}_stateScriptData(cp){switch(cp){case CODE_POINTS.LESS_THAN_SIGN:{this.state=State.SCRIPT_DATA_LESS_THAN_SIGN;break}case CODE_POINTS.NULL:{this._err(ERR.unexpectedNullCharacter),this._emitChars(REPLACEMENT_CHARACTER);break}case CODE_POINTS.EOF:{this._emitEOFToken();break}default:this._emitCodePoint(cp)}}_statePlaintext(cp){switch(cp){case CODE_POINTS.NULL:{this._err(ERR.unexpectedNullCharacter),this._emitChars(REPLACEMENT_CHARACTER);break}case CODE_POINTS.EOF:{this._emitEOFToken();break}default:this._emitCodePoint(cp)}}_stateTagOpen(cp){if(isAsciiLetter(cp))this._createStartTagToken(),this.state=State.TAG_NAME,this._stateTagName(cp);else switch(cp){case CODE_POINTS.EXCLAMATION_MARK:{this.state=State.MARKUP_DECLARATION_OPEN;break}case CODE_POINTS.SOLIDUS:{this.state=State.END_TAG_OPEN;break}case CODE_POINTS.QUESTION_MARK:{this._err(ERR.unexpectedQuestionMarkInsteadOfTagName),this._createCommentToken(1),this.state=State.BOGUS_COMMENT,this._stateBogusComment(cp);break}case CODE_POINTS.EOF:{this._err(ERR.eofBeforeTagName),this._emitChars("<"),this._emitEOFToken();break}default:this._err(ERR.invalidFirstCharacterOfTagName),this._emitChars("<"),this.state=State.DATA,this._stateData(cp)}}_stateEndTagOpen(cp){if(isAsciiLetter(cp))this._createEndTagToken(),this.state=State.TAG_NAME,this._stateTagName(cp);else switch(cp){case CODE_POINTS.GREATER_THAN_SIGN:{this._err(ERR.missingEndTagName),this.state=State.DATA;break}case CODE_POINTS.EOF:{this._err(ERR.eofBeforeTagName),this._emitChars("");break}case CODE_POINTS.NULL:{this._err(ERR.unexpectedNullCharacter),this.state=State.SCRIPT_DATA_ESCAPED,this._emitChars(REPLACEMENT_CHARACTER);break}case CODE_POINTS.EOF:{this._err(ERR.eofInScriptHtmlCommentLikeText),this._emitEOFToken();break}default:this.state=State.SCRIPT_DATA_ESCAPED,this._emitCodePoint(cp)}}_stateScriptDataEscapedLessThanSign(cp){cp===CODE_POINTS.SOLIDUS?this.state=State.SCRIPT_DATA_ESCAPED_END_TAG_OPEN:isAsciiLetter(cp)?(this._emitChars("<"),this.state=State.SCRIPT_DATA_DOUBLE_ESCAPE_START,this._stateScriptDataDoubleEscapeStart(cp)):(this._emitChars("<"),this.state=State.SCRIPT_DATA_ESCAPED,this._stateScriptDataEscaped(cp))}_stateScriptDataEscapedEndTagOpen(cp){isAsciiLetter(cp)?(this.state=State.SCRIPT_DATA_ESCAPED_END_TAG_NAME,this._stateScriptDataEscapedEndTagName(cp)):(this._emitChars("");break}case CODE_POINTS.NULL:{this._err(ERR.unexpectedNullCharacter),this.state=State.SCRIPT_DATA_DOUBLE_ESCAPED,this._emitChars(REPLACEMENT_CHARACTER);break}case CODE_POINTS.EOF:{this._err(ERR.eofInScriptHtmlCommentLikeText),this._emitEOFToken();break}default:this.state=State.SCRIPT_DATA_DOUBLE_ESCAPED,this._emitCodePoint(cp)}}_stateScriptDataDoubleEscapedLessThanSign(cp){cp===CODE_POINTS.SOLIDUS?(this.state=State.SCRIPT_DATA_DOUBLE_ESCAPE_END,this._emitChars("/")):(this.state=State.SCRIPT_DATA_DOUBLE_ESCAPED,this._stateScriptDataDoubleEscaped(cp))}_stateScriptDataDoubleEscapeEnd(cp){if(this.preprocessor.startsWith(SEQUENCES.SCRIPT,!1)&&isScriptDataDoubleEscapeSequenceEnd(this.preprocessor.peek(SEQUENCES.SCRIPT.length))){this._emitCodePoint(cp);for(let i2=0;i20&&this._isInTemplate()&&this.tmplCount--,this.stackTop--,this._updateCurrentElement(),this.handler.onItemPop(popped,!0)}replace(oldElement,newElement){const idx=this._indexOf(oldElement);this.items[idx]=newElement,idx===this.stackTop&&(this.current=newElement)}insertAfter(referenceElement,newElement,newElementID){const insertionIdx=this._indexOf(referenceElement)+1;this.items.splice(insertionIdx,0,newElement),this.tagIDs.splice(insertionIdx,0,newElementID),this.stackTop++,insertionIdx===this.stackTop&&this._updateCurrentElement(),this.current&&this.currentTagId!==void 0&&this.handler.onItemPush(this.current,this.currentTagId,insertionIdx===this.stackTop)}popUntilTagNamePopped(tagName){let targetIdx=this.stackTop+1;do targetIdx=this.tagIDs.lastIndexOf(tagName,targetIdx-1);while(targetIdx>0&&this.treeAdapter.getNamespaceURI(this.items[targetIdx])!==NS.HTML);this.shortenToLength(Math.max(targetIdx,0))}shortenToLength(idx){for(;this.stackTop>=idx;){const popped=this.current;this.tmplCount>0&&this._isInTemplate()&&(this.tmplCount-=1),this.stackTop--,this._updateCurrentElement(),this.handler.onItemPop(popped,this.stackTop=0;i2--)if(tagNames.has(this.tagIDs[i2])&&this.treeAdapter.getNamespaceURI(this.items[i2])===namespace)return i2;return-1}clearBackTo(tagNames,targetNS){const idx=this._indexOfTagNames(tagNames,targetNS);this.shortenToLength(idx+1)}clearBackToTableContext(){this.clearBackTo(TABLE_CONTEXT,NS.HTML)}clearBackToTableBodyContext(){this.clearBackTo(TABLE_BODY_CONTEXT,NS.HTML)}clearBackToTableRowContext(){this.clearBackTo(TABLE_ROW_CONTEXT,NS.HTML)}remove(element2){const idx=this._indexOf(element2);idx>=0&&(idx===this.stackTop?this.pop():(this.items.splice(idx,1),this.tagIDs.splice(idx,1),this.stackTop--,this._updateCurrentElement(),this.handler.onItemPop(element2,!1)))}tryPeekProperlyNestedBodyElement(){return this.stackTop>=1&&this.tagIDs[1]===TAG_ID.BODY?this.items[1]:null}contains(element2){return this._indexOf(element2)>-1}getCommonAncestor(element2){const elementIdx=this._indexOf(element2)-1;return elementIdx>=0?this.items[elementIdx]:null}isRootHtmlElementCurrent(){return this.stackTop===0&&this.tagIDs[0]===TAG_ID.HTML}hasInDynamicScope(tagName,htmlScope){for(let i2=this.stackTop;i2>=0;i2--){const tn=this.tagIDs[i2];switch(this.treeAdapter.getNamespaceURI(this.items[i2])){case NS.HTML:{if(tn===tagName)return!0;if(htmlScope.has(tn))return!1;break}case NS.SVG:{if(SCOPING_ELEMENTS_SVG.has(tn))return!1;break}case NS.MATHML:{if(SCOPING_ELEMENTS_MATHML.has(tn))return!1;break}}}return!0}hasInScope(tagName){return this.hasInDynamicScope(tagName,SCOPING_ELEMENTS_HTML)}hasInListItemScope(tagName){return this.hasInDynamicScope(tagName,SCOPING_ELEMENTS_HTML_LIST)}hasInButtonScope(tagName){return this.hasInDynamicScope(tagName,SCOPING_ELEMENTS_HTML_BUTTON)}hasNumberedHeaderInScope(){for(let i2=this.stackTop;i2>=0;i2--){const tn=this.tagIDs[i2];switch(this.treeAdapter.getNamespaceURI(this.items[i2])){case NS.HTML:{if(NUMBERED_HEADERS.has(tn))return!0;if(SCOPING_ELEMENTS_HTML.has(tn))return!1;break}case NS.SVG:{if(SCOPING_ELEMENTS_SVG.has(tn))return!1;break}case NS.MATHML:{if(SCOPING_ELEMENTS_MATHML.has(tn))return!1;break}}}return!0}hasInTableScope(tagName){for(let i2=this.stackTop;i2>=0;i2--)if(this.treeAdapter.getNamespaceURI(this.items[i2])===NS.HTML)switch(this.tagIDs[i2]){case tagName:return!0;case TAG_ID.TABLE:case TAG_ID.HTML:return!1}return!0}hasTableBodyContextInTableScope(){for(let i2=this.stackTop;i2>=0;i2--)if(this.treeAdapter.getNamespaceURI(this.items[i2])===NS.HTML)switch(this.tagIDs[i2]){case TAG_ID.TBODY:case TAG_ID.THEAD:case TAG_ID.TFOOT:return!0;case TAG_ID.TABLE:case TAG_ID.HTML:return!1}return!0}hasInSelectScope(tagName){for(let i2=this.stackTop;i2>=0;i2--)if(this.treeAdapter.getNamespaceURI(this.items[i2])===NS.HTML)switch(this.tagIDs[i2]){case tagName:return!0;case TAG_ID.OPTION:case TAG_ID.OPTGROUP:break;default:return!1}return!0}generateImpliedEndTags(){for(;this.currentTagId!==void 0&&IMPLICIT_END_TAG_REQUIRED.has(this.currentTagId);)this.pop()}generateImpliedEndTagsThoroughly(){for(;this.currentTagId!==void 0&&IMPLICIT_END_TAG_REQUIRED_THOROUGHLY.has(this.currentTagId);)this.pop()}generateImpliedEndTagsWithExclusion(exclusionId){for(;this.currentTagId!==void 0&&this.currentTagId!==exclusionId&&IMPLICIT_END_TAG_REQUIRED_THOROUGHLY.has(this.currentTagId);)this.pop()}};__name(_OpenElementStack,"OpenElementStack");let OpenElementStack=_OpenElementStack;const NOAH_ARK_CAPACITY=3;var EntryType;(function(EntryType2){EntryType2[EntryType2.Marker=0]="Marker",EntryType2[EntryType2.Element=1]="Element"})(EntryType||(EntryType={}));const MARKER={type:EntryType.Marker},_FormattingElementList=class _FormattingElementList{constructor(treeAdapter){this.treeAdapter=treeAdapter,this.entries=[],this.bookmark=null}_getNoahArkConditionCandidates(newElement,neAttrs){const candidates=[],neAttrsLength=neAttrs.length,neTagName=this.treeAdapter.getTagName(newElement),neNamespaceURI=this.treeAdapter.getNamespaceURI(newElement);for(let i2=0;i2[neAttr.name,neAttr.value]));let validCandidates=0;for(let i2=0;i2neAttrsMap.get(cAttr.name)===cAttr.value)&&(validCandidates+=1,validCandidates>=NOAH_ARK_CAPACITY&&this.entries.splice(candidate.idx,1))}}insertMarker(){this.entries.unshift(MARKER)}pushElement(element2,token){this._ensureNoahArkCondition(element2),this.entries.unshift({type:EntryType.Element,element:element2,token})}insertElementAfterBookmark(element2,token){const bookmarkIdx=this.entries.indexOf(this.bookmark);this.entries.splice(bookmarkIdx,0,{type:EntryType.Element,element:element2,token})}removeEntry(entry){const entryIndex=this.entries.indexOf(entry);entryIndex!==-1&&this.entries.splice(entryIndex,1)}clearToLastMarker(){const markerIdx=this.entries.indexOf(MARKER);markerIdx===-1?this.entries.length=0:this.entries.splice(0,markerIdx+1)}getElementEntryInScopeWithTagName(tagName){const entry=this.entries.find(entry2=>entry2.type===EntryType.Marker||this.treeAdapter.getTagName(entry2.element)===tagName);return entry&&entry.type===EntryType.Element?entry:null}getElementEntry(element2){return this.entries.find(entry=>entry.type===EntryType.Element&&entry.element===element2)}};__name(_FormattingElementList,"FormattingElementList");let FormattingElementList=_FormattingElementList;const defaultTreeAdapter={createDocument(){return{nodeName:"#document",mode:DOCUMENT_MODE.NO_QUIRKS,childNodes:[]}},createDocumentFragment(){return{nodeName:"#document-fragment",childNodes:[]}},createElement(tagName,namespaceURI,attrs){return{nodeName:tagName,tagName,attrs,namespaceURI,childNodes:[],parentNode:null}},createCommentNode(data){return{nodeName:"#comment",data,parentNode:null}},createTextNode(value2){return{nodeName:"#text",value:value2,parentNode:null}},appendChild(parentNode,newNode){parentNode.childNodes.push(newNode),newNode.parentNode=parentNode},insertBefore(parentNode,newNode,referenceNode){const insertionIdx=parentNode.childNodes.indexOf(referenceNode);parentNode.childNodes.splice(insertionIdx,0,newNode),newNode.parentNode=parentNode},setTemplateContent(templateElement,contentElement){templateElement.content=contentElement},getTemplateContent(templateElement){return templateElement.content},setDocumentType(document2,name2,publicId,systemId){const doctypeNode=document2.childNodes.find(node2=>node2.nodeName==="#documentType");if(doctypeNode)doctypeNode.name=name2,doctypeNode.publicId=publicId,doctypeNode.systemId=systemId;else{const node2={nodeName:"#documentType",name:name2,publicId,systemId,parentNode:null};defaultTreeAdapter.appendChild(document2,node2)}},setDocumentMode(document2,mode){document2.mode=mode},getDocumentMode(document2){return document2.mode},detachNode(node2){if(node2.parentNode){const idx=node2.parentNode.childNodes.indexOf(node2);node2.parentNode.childNodes.splice(idx,1),node2.parentNode=null}},insertText(parentNode,text2){if(parentNode.childNodes.length>0){const prevNode=parentNode.childNodes[parentNode.childNodes.length-1];if(defaultTreeAdapter.isTextNode(prevNode)){prevNode.value+=text2;return}}defaultTreeAdapter.appendChild(parentNode,defaultTreeAdapter.createTextNode(text2))},insertTextBefore(parentNode,text2,referenceNode){const prevNode=parentNode.childNodes[parentNode.childNodes.indexOf(referenceNode)-1];prevNode&&defaultTreeAdapter.isTextNode(prevNode)?prevNode.value+=text2:defaultTreeAdapter.insertBefore(parentNode,defaultTreeAdapter.createTextNode(text2),referenceNode)},adoptAttributes(recipient,attrs){const recipientAttrsMap=new Set(recipient.attrs.map(attr=>attr.name));for(let j2=0;j2publicId.startsWith(prefix2))}__name(hasPrefix,"hasPrefix");function isConforming(token){return token.name===VALID_DOCTYPE_NAME&&token.publicId===null&&(token.systemId===null||token.systemId===VALID_SYSTEM_ID)}__name(isConforming,"isConforming");function getDocumentMode(token){if(token.name!==VALID_DOCTYPE_NAME)return DOCUMENT_MODE.QUIRKS;const{systemId}=token;if(systemId&&systemId.toLowerCase()===QUIRKS_MODE_SYSTEM_ID)return DOCUMENT_MODE.QUIRKS;let{publicId}=token;if(publicId!==null){if(publicId=publicId.toLowerCase(),QUIRKS_MODE_PUBLIC_IDS.has(publicId))return DOCUMENT_MODE.QUIRKS;let prefixes2=systemId===null?QUIRKS_MODE_NO_SYSTEM_ID_PUBLIC_ID_PREFIXES:QUIRKS_MODE_PUBLIC_ID_PREFIXES;if(hasPrefix(publicId,prefixes2))return DOCUMENT_MODE.QUIRKS;if(prefixes2=systemId===null?LIMITED_QUIRKS_PUBLIC_ID_PREFIXES:LIMITED_QUIRKS_WITH_SYSTEM_ID_PUBLIC_ID_PREFIXES,hasPrefix(publicId,prefixes2))return DOCUMENT_MODE.LIMITED_QUIRKS}return DOCUMENT_MODE.NO_QUIRKS}__name(getDocumentMode,"getDocumentMode");const MIME_TYPES={TEXT_HTML:"text/html",APPLICATION_XML:"application/xhtml+xml"},DEFINITION_URL_ATTR="definitionurl",ADJUSTED_DEFINITION_URL_ATTR="definitionURL",SVG_ATTRS_ADJUSTMENT_MAP=new Map(["attributeName","attributeType","baseFrequency","baseProfile","calcMode","clipPathUnits","diffuseConstant","edgeMode","filterUnits","glyphRef","gradientTransform","gradientUnits","kernelMatrix","kernelUnitLength","keyPoints","keySplines","keyTimes","lengthAdjust","limitingConeAngle","markerHeight","markerUnits","markerWidth","maskContentUnits","maskUnits","numOctaves","pathLength","patternContentUnits","patternTransform","patternUnits","pointsAtX","pointsAtY","pointsAtZ","preserveAlpha","preserveAspectRatio","primitiveUnits","refX","refY","repeatCount","repeatDur","requiredExtensions","requiredFeatures","specularConstant","specularExponent","spreadMethod","startOffset","stdDeviation","stitchTiles","surfaceScale","systemLanguage","tableValues","targetX","targetY","textLength","viewBox","viewTarget","xChannelSelector","yChannelSelector","zoomAndPan"].map(attr=>[attr.toLowerCase(),attr])),XML_ATTRS_ADJUSTMENT_MAP=new Map([["xlink:actuate",{prefix:"xlink",name:"actuate",namespace:NS.XLINK}],["xlink:arcrole",{prefix:"xlink",name:"arcrole",namespace:NS.XLINK}],["xlink:href",{prefix:"xlink",name:"href",namespace:NS.XLINK}],["xlink:role",{prefix:"xlink",name:"role",namespace:NS.XLINK}],["xlink:show",{prefix:"xlink",name:"show",namespace:NS.XLINK}],["xlink:title",{prefix:"xlink",name:"title",namespace:NS.XLINK}],["xlink:type",{prefix:"xlink",name:"type",namespace:NS.XLINK}],["xml:lang",{prefix:"xml",name:"lang",namespace:NS.XML}],["xml:space",{prefix:"xml",name:"space",namespace:NS.XML}],["xmlns",{prefix:"",name:"xmlns",namespace:NS.XMLNS}],["xmlns:xlink",{prefix:"xmlns",name:"xlink",namespace:NS.XMLNS}]]),SVG_TAG_NAMES_ADJUSTMENT_MAP=new Map(["altGlyph","altGlyphDef","altGlyphItem","animateColor","animateMotion","animateTransform","clipPath","feBlend","feColorMatrix","feComponentTransfer","feComposite","feConvolveMatrix","feDiffuseLighting","feDisplacementMap","feDistantLight","feFlood","feFuncA","feFuncB","feFuncG","feFuncR","feGaussianBlur","feImage","feMerge","feMergeNode","feMorphology","feOffset","fePointLight","feSpecularLighting","feSpotLight","feTile","feTurbulence","foreignObject","glyphRef","linearGradient","radialGradient","textPath"].map(tn=>[tn.toLowerCase(),tn])),EXITS_FOREIGN_CONTENT=new Set([TAG_ID.B,TAG_ID.BIG,TAG_ID.BLOCKQUOTE,TAG_ID.BODY,TAG_ID.BR,TAG_ID.CENTER,TAG_ID.CODE,TAG_ID.DD,TAG_ID.DIV,TAG_ID.DL,TAG_ID.DT,TAG_ID.EM,TAG_ID.EMBED,TAG_ID.H1,TAG_ID.H2,TAG_ID.H3,TAG_ID.H4,TAG_ID.H5,TAG_ID.H6,TAG_ID.HEAD,TAG_ID.HR,TAG_ID.I,TAG_ID.IMG,TAG_ID.LI,TAG_ID.LISTING,TAG_ID.MENU,TAG_ID.META,TAG_ID.NOBR,TAG_ID.OL,TAG_ID.P,TAG_ID.PRE,TAG_ID.RUBY,TAG_ID.S,TAG_ID.SMALL,TAG_ID.SPAN,TAG_ID.STRONG,TAG_ID.STRIKE,TAG_ID.SUB,TAG_ID.SUP,TAG_ID.TABLE,TAG_ID.TT,TAG_ID.U,TAG_ID.UL,TAG_ID.VAR]);function causesExit(startTagToken){const tn=startTagToken.tagID;return tn===TAG_ID.FONT&&startTagToken.attrs.some(({name:name2})=>name2===ATTRS.COLOR||name2===ATTRS.SIZE||name2===ATTRS.FACE)||EXITS_FOREIGN_CONTENT.has(tn)}__name(causesExit,"causesExit");function adjustTokenMathMLAttrs(token){for(let i2=0;i20&&this._setContextModes(node2,tid)}onItemPop(node2,isTop){var _a18,_b;if(this.options.sourceCodeLocationInfo&&this._setEndLocation(node2,this.currentToken),(_b=(_a18=this.treeAdapter).onItemPop)===null||_b===void 0||_b.call(_a18,node2,this.openElements.current),isTop){let current,currentTagId;this.openElements.stackTop===0&&this.fragmentContext?(current=this.fragmentContext,currentTagId=this.fragmentContextID):{current,currentTagId}=this.openElements,this._setContextModes(current,currentTagId)}}_setContextModes(current,tid){const isHTML=current===this.document||current&&this.treeAdapter.getNamespaceURI(current)===NS.HTML;this.currentNotInHTML=!isHTML,this.tokenizer.inForeignNode=!isHTML&¤t!==void 0&&tid!==void 0&&!this._isIntegrationPoint(tid,current)}_switchToTextParsing(currentToken,nextTokenizerState){this._insertElement(currentToken,NS.HTML),this.tokenizer.state=nextTokenizerState,this.originalInsertionMode=this.insertionMode,this.insertionMode=InsertionMode.TEXT}switchToPlaintextParsing(){this.insertionMode=InsertionMode.TEXT,this.originalInsertionMode=InsertionMode.IN_BODY,this.tokenizer.state=TokenizerMode.PLAINTEXT}_getAdjustedCurrentElement(){return this.openElements.stackTop===0&&this.fragmentContext?this.fragmentContext:this.openElements.current}_findFormInFragmentContext(){let node2=this.fragmentContext;for(;node2;){if(this.treeAdapter.getTagName(node2)===TAG_NAMES.FORM){this.formElement=node2;break}node2=this.treeAdapter.getParentNode(node2)}}_initTokenizerForFragmentParsing(){if(!(!this.fragmentContext||this.treeAdapter.getNamespaceURI(this.fragmentContext)!==NS.HTML))switch(this.fragmentContextID){case TAG_ID.TITLE:case TAG_ID.TEXTAREA:{this.tokenizer.state=TokenizerMode.RCDATA;break}case TAG_ID.STYLE:case TAG_ID.XMP:case TAG_ID.IFRAME:case TAG_ID.NOEMBED:case TAG_ID.NOFRAMES:case TAG_ID.NOSCRIPT:{this.tokenizer.state=TokenizerMode.RAWTEXT;break}case TAG_ID.SCRIPT:{this.tokenizer.state=TokenizerMode.SCRIPT_DATA;break}case TAG_ID.PLAINTEXT:{this.tokenizer.state=TokenizerMode.PLAINTEXT;break}}}_setDocumentType(token){const name2=token.name||"",publicId=token.publicId||"",systemId=token.systemId||"";if(this.treeAdapter.setDocumentType(this.document,name2,publicId,systemId),token.location){const docTypeNode=this.treeAdapter.getChildNodes(this.document).find(node2=>this.treeAdapter.isDocumentTypeNode(node2));docTypeNode&&this.treeAdapter.setNodeSourceCodeLocation(docTypeNode,token.location)}}_attachElementToTree(element2,location2){if(this.options.sourceCodeLocationInfo){const loc=location2&&{...location2,startTag:location2};this.treeAdapter.setNodeSourceCodeLocation(element2,loc)}if(this._shouldFosterParentOnInsertion())this._fosterParentElement(element2);else{const parent=this.openElements.currentTmplContentOrNode;this.treeAdapter.appendChild(parent??this.document,element2)}}_appendElement(token,namespaceURI){const element2=this.treeAdapter.createElement(token.tagName,namespaceURI,token.attrs);this._attachElementToTree(element2,token.location)}_insertElement(token,namespaceURI){const element2=this.treeAdapter.createElement(token.tagName,namespaceURI,token.attrs);this._attachElementToTree(element2,token.location),this.openElements.push(element2,token.tagID)}_insertFakeElement(tagName,tagID){const element2=this.treeAdapter.createElement(tagName,NS.HTML,[]);this._attachElementToTree(element2,null),this.openElements.push(element2,tagID)}_insertTemplate(token){const tmpl=this.treeAdapter.createElement(token.tagName,NS.HTML,token.attrs),content2=this.treeAdapter.createDocumentFragment();this.treeAdapter.setTemplateContent(tmpl,content2),this._attachElementToTree(tmpl,token.location),this.openElements.push(tmpl,token.tagID),this.options.sourceCodeLocationInfo&&this.treeAdapter.setNodeSourceCodeLocation(content2,null)}_insertFakeRootElement(){const element2=this.treeAdapter.createElement(TAG_NAMES.HTML,NS.HTML,[]);this.options.sourceCodeLocationInfo&&this.treeAdapter.setNodeSourceCodeLocation(element2,null),this.treeAdapter.appendChild(this.openElements.current,element2),this.openElements.push(element2,TAG_ID.HTML)}_appendCommentNode(token,parent){const commentNode=this.treeAdapter.createCommentNode(token.data);this.treeAdapter.appendChild(parent,commentNode),this.options.sourceCodeLocationInfo&&this.treeAdapter.setNodeSourceCodeLocation(commentNode,token.location)}_insertCharacters(token){let parent,beforeElement;if(this._shouldFosterParentOnInsertion()?({parent,beforeElement}=this._findFosterParentingLocation(),beforeElement?this.treeAdapter.insertTextBefore(parent,token.chars,beforeElement):this.treeAdapter.insertText(parent,token.chars)):(parent=this.openElements.currentTmplContentOrNode,this.treeAdapter.insertText(parent,token.chars)),!token.location)return;const siblings=this.treeAdapter.getChildNodes(parent),textNodeIdx=beforeElement?siblings.lastIndexOf(beforeElement):siblings.length,textNode=siblings[textNodeIdx-1];if(this.treeAdapter.getNodeSourceCodeLocation(textNode)){const{endLine,endCol,endOffset}=token.location;this.treeAdapter.updateNodeSourceCodeLocation(textNode,{endLine,endCol,endOffset})}else this.options.sourceCodeLocationInfo&&this.treeAdapter.setNodeSourceCodeLocation(textNode,token.location)}_adoptNodes(donor,recipient){for(let child=this.treeAdapter.getFirstChild(donor);child;child=this.treeAdapter.getFirstChild(donor))this.treeAdapter.detachNode(child),this.treeAdapter.appendChild(recipient,child)}_setEndLocation(element2,closingToken){if(this.treeAdapter.getNodeSourceCodeLocation(element2)&&closingToken.location){const ctLoc=closingToken.location,tn=this.treeAdapter.getTagName(element2),endLoc=closingToken.type===TokenType.END_TAG&&tn===closingToken.tagName?{endTag:{...ctLoc},endLine:ctLoc.endLine,endCol:ctLoc.endCol,endOffset:ctLoc.endOffset}:{endLine:ctLoc.startLine,endCol:ctLoc.startCol,endOffset:ctLoc.startOffset};this.treeAdapter.updateNodeSourceCodeLocation(element2,endLoc)}}shouldProcessStartTagTokenInForeignContent(token){if(!this.currentNotInHTML)return!1;let current,currentTagId;return this.openElements.stackTop===0&&this.fragmentContext?(current=this.fragmentContext,currentTagId=this.fragmentContextID):{current,currentTagId}=this.openElements,token.tagID===TAG_ID.SVG&&this.treeAdapter.getTagName(current)===TAG_NAMES.ANNOTATION_XML&&this.treeAdapter.getNamespaceURI(current)===NS.MATHML?!1:this.tokenizer.inForeignNode||(token.tagID===TAG_ID.MGLYPH||token.tagID===TAG_ID.MALIGNMARK)&¤tTagId!==void 0&&!this._isIntegrationPoint(currentTagId,current,NS.HTML)}_processToken(token){switch(token.type){case TokenType.CHARACTER:{this.onCharacter(token);break}case TokenType.NULL_CHARACTER:{this.onNullCharacter(token);break}case TokenType.COMMENT:{this.onComment(token);break}case TokenType.DOCTYPE:{this.onDoctype(token);break}case TokenType.START_TAG:{this._processStartTag(token);break}case TokenType.END_TAG:{this.onEndTag(token);break}case TokenType.EOF:{this.onEof(token);break}case TokenType.WHITESPACE_CHARACTER:{this.onWhitespaceCharacter(token);break}}}_isIntegrationPoint(tid,element2,foreignNS){const ns=this.treeAdapter.getNamespaceURI(element2),attrs=this.treeAdapter.getAttrList(element2);return isIntegrationPoint(tid,ns,attrs,foreignNS)}_reconstructActiveFormattingElements(){const listLength=this.activeFormattingElements.entries.length;if(listLength){const endIndex=this.activeFormattingElements.entries.findIndex(entry=>entry.type===EntryType.Marker||this.openElements.contains(entry.element)),unopenIdx=endIndex===-1?listLength-1:endIndex-1;for(let i2=unopenIdx;i2>=0;i2--){const entry=this.activeFormattingElements.entries[i2];this._insertElement(entry.token,this.treeAdapter.getNamespaceURI(entry.element)),entry.element=this.openElements.current}}}_closeTableCell(){this.openElements.generateImpliedEndTags(),this.openElements.popUntilTableCellPopped(),this.activeFormattingElements.clearToLastMarker(),this.insertionMode=InsertionMode.IN_ROW}_closePElement(){this.openElements.generateImpliedEndTagsWithExclusion(TAG_ID.P),this.openElements.popUntilTagNamePopped(TAG_ID.P)}_resetInsertionMode(){for(let i2=this.openElements.stackTop;i2>=0;i2--)switch(i2===0&&this.fragmentContext?this.fragmentContextID:this.openElements.tagIDs[i2]){case TAG_ID.TR:{this.insertionMode=InsertionMode.IN_ROW;return}case TAG_ID.TBODY:case TAG_ID.THEAD:case TAG_ID.TFOOT:{this.insertionMode=InsertionMode.IN_TABLE_BODY;return}case TAG_ID.CAPTION:{this.insertionMode=InsertionMode.IN_CAPTION;return}case TAG_ID.COLGROUP:{this.insertionMode=InsertionMode.IN_COLUMN_GROUP;return}case TAG_ID.TABLE:{this.insertionMode=InsertionMode.IN_TABLE;return}case TAG_ID.BODY:{this.insertionMode=InsertionMode.IN_BODY;return}case TAG_ID.FRAMESET:{this.insertionMode=InsertionMode.IN_FRAMESET;return}case TAG_ID.SELECT:{this._resetInsertionModeForSelect(i2);return}case TAG_ID.TEMPLATE:{this.insertionMode=this.tmplInsertionModeStack[0];return}case TAG_ID.HTML:{this.insertionMode=this.headElement?InsertionMode.AFTER_HEAD:InsertionMode.BEFORE_HEAD;return}case TAG_ID.TD:case TAG_ID.TH:{if(i2>0){this.insertionMode=InsertionMode.IN_CELL;return}break}case TAG_ID.HEAD:{if(i2>0){this.insertionMode=InsertionMode.IN_HEAD;return}break}}this.insertionMode=InsertionMode.IN_BODY}_resetInsertionModeForSelect(selectIdx){if(selectIdx>0)for(let i2=selectIdx-1;i2>0;i2--){const tn=this.openElements.tagIDs[i2];if(tn===TAG_ID.TEMPLATE)break;if(tn===TAG_ID.TABLE){this.insertionMode=InsertionMode.IN_SELECT_IN_TABLE;return}}this.insertionMode=InsertionMode.IN_SELECT}_isElementCausesFosterParenting(tn){return TABLE_STRUCTURE_TAGS.has(tn)}_shouldFosterParentOnInsertion(){return this.fosterParentingEnabled&&this.openElements.currentTagId!==void 0&&this._isElementCausesFosterParenting(this.openElements.currentTagId)}_findFosterParentingLocation(){for(let i2=this.openElements.stackTop;i2>=0;i2--){const openElement=this.openElements.items[i2];switch(this.openElements.tagIDs[i2]){case TAG_ID.TEMPLATE:{if(this.treeAdapter.getNamespaceURI(openElement)===NS.HTML)return{parent:this.treeAdapter.getTemplateContent(openElement),beforeElement:null};break}case TAG_ID.TABLE:{const parent=this.treeAdapter.getParentNode(openElement);return parent?{parent,beforeElement:openElement}:{parent:this.openElements.items[i2-1],beforeElement:null}}}}return{parent:this.openElements.items[0],beforeElement:null}}_fosterParentElement(element2){const location2=this._findFosterParentingLocation();location2.beforeElement?this.treeAdapter.insertBefore(location2.parent,element2,location2.beforeElement):this.treeAdapter.appendChild(location2.parent,element2)}_isSpecialElement(element2,id){const ns=this.treeAdapter.getNamespaceURI(element2);return SPECIAL_ELEMENTS[ns].has(id)}onCharacter(token){if(this.skipNextNewLine=!1,this.tokenizer.inForeignNode){characterInForeignContent(this,token);return}switch(this.insertionMode){case InsertionMode.INITIAL:{tokenInInitialMode(this,token);break}case InsertionMode.BEFORE_HTML:{tokenBeforeHtml(this,token);break}case InsertionMode.BEFORE_HEAD:{tokenBeforeHead(this,token);break}case InsertionMode.IN_HEAD:{tokenInHead(this,token);break}case InsertionMode.IN_HEAD_NO_SCRIPT:{tokenInHeadNoScript(this,token);break}case InsertionMode.AFTER_HEAD:{tokenAfterHead(this,token);break}case InsertionMode.IN_BODY:case InsertionMode.IN_CAPTION:case InsertionMode.IN_CELL:case InsertionMode.IN_TEMPLATE:{characterInBody(this,token);break}case InsertionMode.TEXT:case InsertionMode.IN_SELECT:case InsertionMode.IN_SELECT_IN_TABLE:{this._insertCharacters(token);break}case InsertionMode.IN_TABLE:case InsertionMode.IN_TABLE_BODY:case InsertionMode.IN_ROW:{characterInTable(this,token);break}case InsertionMode.IN_TABLE_TEXT:{characterInTableText(this,token);break}case InsertionMode.IN_COLUMN_GROUP:{tokenInColumnGroup(this,token);break}case InsertionMode.AFTER_BODY:{tokenAfterBody(this,token);break}case InsertionMode.AFTER_AFTER_BODY:{tokenAfterAfterBody(this,token);break}}}onNullCharacter(token){if(this.skipNextNewLine=!1,this.tokenizer.inForeignNode){nullCharacterInForeignContent(this,token);return}switch(this.insertionMode){case InsertionMode.INITIAL:{tokenInInitialMode(this,token);break}case InsertionMode.BEFORE_HTML:{tokenBeforeHtml(this,token);break}case InsertionMode.BEFORE_HEAD:{tokenBeforeHead(this,token);break}case InsertionMode.IN_HEAD:{tokenInHead(this,token);break}case InsertionMode.IN_HEAD_NO_SCRIPT:{tokenInHeadNoScript(this,token);break}case InsertionMode.AFTER_HEAD:{tokenAfterHead(this,token);break}case InsertionMode.TEXT:{this._insertCharacters(token);break}case InsertionMode.IN_TABLE:case InsertionMode.IN_TABLE_BODY:case InsertionMode.IN_ROW:{characterInTable(this,token);break}case InsertionMode.IN_COLUMN_GROUP:{tokenInColumnGroup(this,token);break}case InsertionMode.AFTER_BODY:{tokenAfterBody(this,token);break}case InsertionMode.AFTER_AFTER_BODY:{tokenAfterAfterBody(this,token);break}}}onComment(token){if(this.skipNextNewLine=!1,this.currentNotInHTML){appendComment(this,token);return}switch(this.insertionMode){case InsertionMode.INITIAL:case InsertionMode.BEFORE_HTML:case InsertionMode.BEFORE_HEAD:case InsertionMode.IN_HEAD:case InsertionMode.IN_HEAD_NO_SCRIPT:case InsertionMode.AFTER_HEAD:case InsertionMode.IN_BODY:case InsertionMode.IN_TABLE:case InsertionMode.IN_CAPTION:case InsertionMode.IN_COLUMN_GROUP:case InsertionMode.IN_TABLE_BODY:case InsertionMode.IN_ROW:case InsertionMode.IN_CELL:case InsertionMode.IN_SELECT:case InsertionMode.IN_SELECT_IN_TABLE:case InsertionMode.IN_TEMPLATE:case InsertionMode.IN_FRAMESET:case InsertionMode.AFTER_FRAMESET:{appendComment(this,token);break}case InsertionMode.IN_TABLE_TEXT:{tokenInTableText(this,token);break}case InsertionMode.AFTER_BODY:{appendCommentToRootHtmlElement(this,token);break}case InsertionMode.AFTER_AFTER_BODY:case InsertionMode.AFTER_AFTER_FRAMESET:{appendCommentToDocument(this,token);break}}}onDoctype(token){switch(this.skipNextNewLine=!1,this.insertionMode){case InsertionMode.INITIAL:{doctypeInInitialMode(this,token);break}case InsertionMode.BEFORE_HEAD:case InsertionMode.IN_HEAD:case InsertionMode.IN_HEAD_NO_SCRIPT:case InsertionMode.AFTER_HEAD:{this._err(token,ERR.misplacedDoctype);break}case InsertionMode.IN_TABLE_TEXT:{tokenInTableText(this,token);break}}}onStartTag(token){this.skipNextNewLine=!1,this.currentToken=token,this._processStartTag(token),token.selfClosing&&!token.ackSelfClosing&&this._err(token,ERR.nonVoidHtmlElementStartTagWithTrailingSolidus)}_processStartTag(token){this.shouldProcessStartTagTokenInForeignContent(token)?startTagInForeignContent(this,token):this._startTagOutsideForeignContent(token)}_startTagOutsideForeignContent(token){switch(this.insertionMode){case InsertionMode.INITIAL:{tokenInInitialMode(this,token);break}case InsertionMode.BEFORE_HTML:{startTagBeforeHtml(this,token);break}case InsertionMode.BEFORE_HEAD:{startTagBeforeHead(this,token);break}case InsertionMode.IN_HEAD:{startTagInHead(this,token);break}case InsertionMode.IN_HEAD_NO_SCRIPT:{startTagInHeadNoScript(this,token);break}case InsertionMode.AFTER_HEAD:{startTagAfterHead(this,token);break}case InsertionMode.IN_BODY:{startTagInBody(this,token);break}case InsertionMode.IN_TABLE:{startTagInTable(this,token);break}case InsertionMode.IN_TABLE_TEXT:{tokenInTableText(this,token);break}case InsertionMode.IN_CAPTION:{startTagInCaption(this,token);break}case InsertionMode.IN_COLUMN_GROUP:{startTagInColumnGroup(this,token);break}case InsertionMode.IN_TABLE_BODY:{startTagInTableBody(this,token);break}case InsertionMode.IN_ROW:{startTagInRow(this,token);break}case InsertionMode.IN_CELL:{startTagInCell(this,token);break}case InsertionMode.IN_SELECT:{startTagInSelect(this,token);break}case InsertionMode.IN_SELECT_IN_TABLE:{startTagInSelectInTable(this,token);break}case InsertionMode.IN_TEMPLATE:{startTagInTemplate(this,token);break}case InsertionMode.AFTER_BODY:{startTagAfterBody(this,token);break}case InsertionMode.IN_FRAMESET:{startTagInFrameset(this,token);break}case InsertionMode.AFTER_FRAMESET:{startTagAfterFrameset(this,token);break}case InsertionMode.AFTER_AFTER_BODY:{startTagAfterAfterBody(this,token);break}case InsertionMode.AFTER_AFTER_FRAMESET:{startTagAfterAfterFrameset(this,token);break}}}onEndTag(token){this.skipNextNewLine=!1,this.currentToken=token,this.currentNotInHTML?endTagInForeignContent(this,token):this._endTagOutsideForeignContent(token)}_endTagOutsideForeignContent(token){switch(this.insertionMode){case InsertionMode.INITIAL:{tokenInInitialMode(this,token);break}case InsertionMode.BEFORE_HTML:{endTagBeforeHtml(this,token);break}case InsertionMode.BEFORE_HEAD:{endTagBeforeHead(this,token);break}case InsertionMode.IN_HEAD:{endTagInHead(this,token);break}case InsertionMode.IN_HEAD_NO_SCRIPT:{endTagInHeadNoScript(this,token);break}case InsertionMode.AFTER_HEAD:{endTagAfterHead(this,token);break}case InsertionMode.IN_BODY:{endTagInBody(this,token);break}case InsertionMode.TEXT:{endTagInText(this,token);break}case InsertionMode.IN_TABLE:{endTagInTable(this,token);break}case InsertionMode.IN_TABLE_TEXT:{tokenInTableText(this,token);break}case InsertionMode.IN_CAPTION:{endTagInCaption(this,token);break}case InsertionMode.IN_COLUMN_GROUP:{endTagInColumnGroup(this,token);break}case InsertionMode.IN_TABLE_BODY:{endTagInTableBody(this,token);break}case InsertionMode.IN_ROW:{endTagInRow(this,token);break}case InsertionMode.IN_CELL:{endTagInCell(this,token);break}case InsertionMode.IN_SELECT:{endTagInSelect(this,token);break}case InsertionMode.IN_SELECT_IN_TABLE:{endTagInSelectInTable(this,token);break}case InsertionMode.IN_TEMPLATE:{endTagInTemplate(this,token);break}case InsertionMode.AFTER_BODY:{endTagAfterBody(this,token);break}case InsertionMode.IN_FRAMESET:{endTagInFrameset(this,token);break}case InsertionMode.AFTER_FRAMESET:{endTagAfterFrameset(this,token);break}case InsertionMode.AFTER_AFTER_BODY:{tokenAfterAfterBody(this,token);break}}}onEof(token){switch(this.insertionMode){case InsertionMode.INITIAL:{tokenInInitialMode(this,token);break}case InsertionMode.BEFORE_HTML:{tokenBeforeHtml(this,token);break}case InsertionMode.BEFORE_HEAD:{tokenBeforeHead(this,token);break}case InsertionMode.IN_HEAD:{tokenInHead(this,token);break}case InsertionMode.IN_HEAD_NO_SCRIPT:{tokenInHeadNoScript(this,token);break}case InsertionMode.AFTER_HEAD:{tokenAfterHead(this,token);break}case InsertionMode.IN_BODY:case InsertionMode.IN_TABLE:case InsertionMode.IN_CAPTION:case InsertionMode.IN_COLUMN_GROUP:case InsertionMode.IN_TABLE_BODY:case InsertionMode.IN_ROW:case InsertionMode.IN_CELL:case InsertionMode.IN_SELECT:case InsertionMode.IN_SELECT_IN_TABLE:{eofInBody(this,token);break}case InsertionMode.TEXT:{eofInText(this,token);break}case InsertionMode.IN_TABLE_TEXT:{tokenInTableText(this,token);break}case InsertionMode.IN_TEMPLATE:{eofInTemplate(this,token);break}case InsertionMode.AFTER_BODY:case InsertionMode.IN_FRAMESET:case InsertionMode.AFTER_FRAMESET:case InsertionMode.AFTER_AFTER_BODY:case InsertionMode.AFTER_AFTER_FRAMESET:{stopParsing(this,token);break}}}onWhitespaceCharacter(token){if(this.skipNextNewLine&&(this.skipNextNewLine=!1,token.chars.charCodeAt(0)===CODE_POINTS.LINE_FEED)){if(token.chars.length===1)return;token.chars=token.chars.substr(1)}if(this.tokenizer.inForeignNode){this._insertCharacters(token);return}switch(this.insertionMode){case InsertionMode.IN_HEAD:case InsertionMode.IN_HEAD_NO_SCRIPT:case InsertionMode.AFTER_HEAD:case InsertionMode.TEXT:case InsertionMode.IN_COLUMN_GROUP:case InsertionMode.IN_SELECT:case InsertionMode.IN_SELECT_IN_TABLE:case InsertionMode.IN_FRAMESET:case InsertionMode.AFTER_FRAMESET:{this._insertCharacters(token);break}case InsertionMode.IN_BODY:case InsertionMode.IN_CAPTION:case InsertionMode.IN_CELL:case InsertionMode.IN_TEMPLATE:case InsertionMode.AFTER_BODY:case InsertionMode.AFTER_AFTER_BODY:case InsertionMode.AFTER_AFTER_FRAMESET:{whitespaceCharacterInBody(this,token);break}case InsertionMode.IN_TABLE:case InsertionMode.IN_TABLE_BODY:case InsertionMode.IN_ROW:{characterInTable(this,token);break}case InsertionMode.IN_TABLE_TEXT:{whitespaceCharacterInTableText(this,token);break}}}};__name(_Parser,"Parser");let Parser=_Parser;function aaObtainFormattingElementEntry(p2,token){let formattingElementEntry=p2.activeFormattingElements.getElementEntryInScopeWithTagName(token.tagName);return formattingElementEntry?p2.openElements.contains(formattingElementEntry.element)?p2.openElements.hasInScope(token.tagID)||(formattingElementEntry=null):(p2.activeFormattingElements.removeEntry(formattingElementEntry),formattingElementEntry=null):genericEndTagInBody(p2,token),formattingElementEntry}__name(aaObtainFormattingElementEntry,"aaObtainFormattingElementEntry");function aaObtainFurthestBlock(p2,formattingElementEntry){let furthestBlock=null,idx=p2.openElements.stackTop;for(;idx>=0;idx--){const element2=p2.openElements.items[idx];if(element2===formattingElementEntry.element)break;p2._isSpecialElement(element2,p2.openElements.tagIDs[idx])&&(furthestBlock=element2)}return furthestBlock||(p2.openElements.shortenToLength(Math.max(idx,0)),p2.activeFormattingElements.removeEntry(formattingElementEntry)),furthestBlock}__name(aaObtainFurthestBlock,"aaObtainFurthestBlock");function aaInnerLoop(p2,furthestBlock,formattingElement){let lastElement=furthestBlock,nextElement=p2.openElements.getCommonAncestor(furthestBlock);for(let i2=0,element2=nextElement;element2!==formattingElement;i2++,element2=nextElement){nextElement=p2.openElements.getCommonAncestor(element2);const elementEntry=p2.activeFormattingElements.getElementEntry(element2),counterOverflow=elementEntry&&i2>=AA_INNER_LOOP_ITER;!elementEntry||counterOverflow?(counterOverflow&&p2.activeFormattingElements.removeEntry(elementEntry),p2.openElements.remove(element2)):(element2=aaRecreateElementFromEntry(p2,elementEntry),lastElement===furthestBlock&&(p2.activeFormattingElements.bookmark=elementEntry),p2.treeAdapter.detachNode(lastElement),p2.treeAdapter.appendChild(element2,lastElement),lastElement=element2)}return lastElement}__name(aaInnerLoop,"aaInnerLoop");function aaRecreateElementFromEntry(p2,elementEntry){const ns=p2.treeAdapter.getNamespaceURI(elementEntry.element),newElement=p2.treeAdapter.createElement(elementEntry.token.tagName,ns,elementEntry.token.attrs);return p2.openElements.replace(elementEntry.element,newElement),elementEntry.element=newElement,newElement}__name(aaRecreateElementFromEntry,"aaRecreateElementFromEntry");function aaInsertLastNodeInCommonAncestor(p2,commonAncestor,lastElement){const tn=p2.treeAdapter.getTagName(commonAncestor),tid=getTagID(tn);if(p2._isElementCausesFosterParenting(tid))p2._fosterParentElement(lastElement);else{const ns=p2.treeAdapter.getNamespaceURI(commonAncestor);tid===TAG_ID.TEMPLATE&&ns===NS.HTML&&(commonAncestor=p2.treeAdapter.getTemplateContent(commonAncestor)),p2.treeAdapter.appendChild(commonAncestor,lastElement)}}__name(aaInsertLastNodeInCommonAncestor,"aaInsertLastNodeInCommonAncestor");function aaReplaceFormattingElement(p2,furthestBlock,formattingElementEntry){const ns=p2.treeAdapter.getNamespaceURI(formattingElementEntry.element),{token}=formattingElementEntry,newElement=p2.treeAdapter.createElement(token.tagName,ns,token.attrs);p2._adoptNodes(furthestBlock,newElement),p2.treeAdapter.appendChild(furthestBlock,newElement),p2.activeFormattingElements.insertElementAfterBookmark(newElement,token),p2.activeFormattingElements.removeEntry(formattingElementEntry),p2.openElements.remove(formattingElementEntry.element),p2.openElements.insertAfter(furthestBlock,newElement,token.tagID)}__name(aaReplaceFormattingElement,"aaReplaceFormattingElement");function callAdoptionAgency(p2,token){for(let i2=0;i2=target;i2--)p2._setEndLocation(p2.openElements.items[i2],token);if(!p2.fragmentContext&&p2.openElements.stackTop>=0){const htmlElement=p2.openElements.items[0],htmlLocation=p2.treeAdapter.getNodeSourceCodeLocation(htmlElement);if(htmlLocation&&!htmlLocation.endTag&&(p2._setEndLocation(htmlElement,token),p2.openElements.stackTop>=1)){const bodyElement=p2.openElements.items[1],bodyLocation=p2.treeAdapter.getNodeSourceCodeLocation(bodyElement);bodyLocation&&!bodyLocation.endTag&&p2._setEndLocation(bodyElement,token)}}}}__name(stopParsing,"stopParsing");function doctypeInInitialMode(p2,token){p2._setDocumentType(token);const mode=token.forceQuirks?DOCUMENT_MODE.QUIRKS:getDocumentMode(token);isConforming(token)||p2._err(token,ERR.nonConformingDoctype),p2.treeAdapter.setDocumentMode(p2.document,mode),p2.insertionMode=InsertionMode.BEFORE_HTML}__name(doctypeInInitialMode,"doctypeInInitialMode");function tokenInInitialMode(p2,token){p2._err(token,ERR.missingDoctype,!0),p2.treeAdapter.setDocumentMode(p2.document,DOCUMENT_MODE.QUIRKS),p2.insertionMode=InsertionMode.BEFORE_HTML,p2._processToken(token)}__name(tokenInInitialMode,"tokenInInitialMode");function startTagBeforeHtml(p2,token){token.tagID===TAG_ID.HTML?(p2._insertElement(token,NS.HTML),p2.insertionMode=InsertionMode.BEFORE_HEAD):tokenBeforeHtml(p2,token)}__name(startTagBeforeHtml,"startTagBeforeHtml");function endTagBeforeHtml(p2,token){const tn=token.tagID;(tn===TAG_ID.HTML||tn===TAG_ID.HEAD||tn===TAG_ID.BODY||tn===TAG_ID.BR)&&tokenBeforeHtml(p2,token)}__name(endTagBeforeHtml,"endTagBeforeHtml");function tokenBeforeHtml(p2,token){p2._insertFakeRootElement(),p2.insertionMode=InsertionMode.BEFORE_HEAD,p2._processToken(token)}__name(tokenBeforeHtml,"tokenBeforeHtml");function startTagBeforeHead(p2,token){switch(token.tagID){case TAG_ID.HTML:{startTagInBody(p2,token);break}case TAG_ID.HEAD:{p2._insertElement(token,NS.HTML),p2.headElement=p2.openElements.current,p2.insertionMode=InsertionMode.IN_HEAD;break}default:tokenBeforeHead(p2,token)}}__name(startTagBeforeHead,"startTagBeforeHead");function endTagBeforeHead(p2,token){const tn=token.tagID;tn===TAG_ID.HEAD||tn===TAG_ID.BODY||tn===TAG_ID.HTML||tn===TAG_ID.BR?tokenBeforeHead(p2,token):p2._err(token,ERR.endTagWithoutMatchingOpenElement)}__name(endTagBeforeHead,"endTagBeforeHead");function tokenBeforeHead(p2,token){p2._insertFakeElement(TAG_NAMES.HEAD,TAG_ID.HEAD),p2.headElement=p2.openElements.current,p2.insertionMode=InsertionMode.IN_HEAD,p2._processToken(token)}__name(tokenBeforeHead,"tokenBeforeHead");function startTagInHead(p2,token){switch(token.tagID){case TAG_ID.HTML:{startTagInBody(p2,token);break}case TAG_ID.BASE:case TAG_ID.BASEFONT:case TAG_ID.BGSOUND:case TAG_ID.LINK:case TAG_ID.META:{p2._appendElement(token,NS.HTML),token.ackSelfClosing=!0;break}case TAG_ID.TITLE:{p2._switchToTextParsing(token,TokenizerMode.RCDATA);break}case TAG_ID.NOSCRIPT:{p2.options.scriptingEnabled?p2._switchToTextParsing(token,TokenizerMode.RAWTEXT):(p2._insertElement(token,NS.HTML),p2.insertionMode=InsertionMode.IN_HEAD_NO_SCRIPT);break}case TAG_ID.NOFRAMES:case TAG_ID.STYLE:{p2._switchToTextParsing(token,TokenizerMode.RAWTEXT);break}case TAG_ID.SCRIPT:{p2._switchToTextParsing(token,TokenizerMode.SCRIPT_DATA);break}case TAG_ID.TEMPLATE:{p2._insertTemplate(token),p2.activeFormattingElements.insertMarker(),p2.framesetOk=!1,p2.insertionMode=InsertionMode.IN_TEMPLATE,p2.tmplInsertionModeStack.unshift(InsertionMode.IN_TEMPLATE);break}case TAG_ID.HEAD:{p2._err(token,ERR.misplacedStartTagForHeadElement);break}default:tokenInHead(p2,token)}}__name(startTagInHead,"startTagInHead");function endTagInHead(p2,token){switch(token.tagID){case TAG_ID.HEAD:{p2.openElements.pop(),p2.insertionMode=InsertionMode.AFTER_HEAD;break}case TAG_ID.BODY:case TAG_ID.BR:case TAG_ID.HTML:{tokenInHead(p2,token);break}case TAG_ID.TEMPLATE:{templateEndTagInHead(p2,token);break}default:p2._err(token,ERR.endTagWithoutMatchingOpenElement)}}__name(endTagInHead,"endTagInHead");function templateEndTagInHead(p2,token){p2.openElements.tmplCount>0?(p2.openElements.generateImpliedEndTagsThoroughly(),p2.openElements.currentTagId!==TAG_ID.TEMPLATE&&p2._err(token,ERR.closingOfElementWithOpenChildElements),p2.openElements.popUntilTagNamePopped(TAG_ID.TEMPLATE),p2.activeFormattingElements.clearToLastMarker(),p2.tmplInsertionModeStack.shift(),p2._resetInsertionMode()):p2._err(token,ERR.endTagWithoutMatchingOpenElement)}__name(templateEndTagInHead,"templateEndTagInHead");function tokenInHead(p2,token){p2.openElements.pop(),p2.insertionMode=InsertionMode.AFTER_HEAD,p2._processToken(token)}__name(tokenInHead,"tokenInHead");function startTagInHeadNoScript(p2,token){switch(token.tagID){case TAG_ID.HTML:{startTagInBody(p2,token);break}case TAG_ID.BASEFONT:case TAG_ID.BGSOUND:case TAG_ID.HEAD:case TAG_ID.LINK:case TAG_ID.META:case TAG_ID.NOFRAMES:case TAG_ID.STYLE:{startTagInHead(p2,token);break}case TAG_ID.NOSCRIPT:{p2._err(token,ERR.nestedNoscriptInHead);break}default:tokenInHeadNoScript(p2,token)}}__name(startTagInHeadNoScript,"startTagInHeadNoScript");function endTagInHeadNoScript(p2,token){switch(token.tagID){case TAG_ID.NOSCRIPT:{p2.openElements.pop(),p2.insertionMode=InsertionMode.IN_HEAD;break}case TAG_ID.BR:{tokenInHeadNoScript(p2,token);break}default:p2._err(token,ERR.endTagWithoutMatchingOpenElement)}}__name(endTagInHeadNoScript,"endTagInHeadNoScript");function tokenInHeadNoScript(p2,token){const errCode=token.type===TokenType.EOF?ERR.openElementsLeftAfterEof:ERR.disallowedContentInNoscriptInHead;p2._err(token,errCode),p2.openElements.pop(),p2.insertionMode=InsertionMode.IN_HEAD,p2._processToken(token)}__name(tokenInHeadNoScript,"tokenInHeadNoScript");function startTagAfterHead(p2,token){switch(token.tagID){case TAG_ID.HTML:{startTagInBody(p2,token);break}case TAG_ID.BODY:{p2._insertElement(token,NS.HTML),p2.framesetOk=!1,p2.insertionMode=InsertionMode.IN_BODY;break}case TAG_ID.FRAMESET:{p2._insertElement(token,NS.HTML),p2.insertionMode=InsertionMode.IN_FRAMESET;break}case TAG_ID.BASE:case TAG_ID.BASEFONT:case TAG_ID.BGSOUND:case TAG_ID.LINK:case TAG_ID.META:case TAG_ID.NOFRAMES:case TAG_ID.SCRIPT:case TAG_ID.STYLE:case TAG_ID.TEMPLATE:case TAG_ID.TITLE:{p2._err(token,ERR.abandonedHeadElementChild),p2.openElements.push(p2.headElement,TAG_ID.HEAD),startTagInHead(p2,token),p2.openElements.remove(p2.headElement);break}case TAG_ID.HEAD:{p2._err(token,ERR.misplacedStartTagForHeadElement);break}default:tokenAfterHead(p2,token)}}__name(startTagAfterHead,"startTagAfterHead");function endTagAfterHead(p2,token){switch(token.tagID){case TAG_ID.BODY:case TAG_ID.HTML:case TAG_ID.BR:{tokenAfterHead(p2,token);break}case TAG_ID.TEMPLATE:{templateEndTagInHead(p2,token);break}default:p2._err(token,ERR.endTagWithoutMatchingOpenElement)}}__name(endTagAfterHead,"endTagAfterHead");function tokenAfterHead(p2,token){p2._insertFakeElement(TAG_NAMES.BODY,TAG_ID.BODY),p2.insertionMode=InsertionMode.IN_BODY,modeInBody(p2,token)}__name(tokenAfterHead,"tokenAfterHead");function modeInBody(p2,token){switch(token.type){case TokenType.CHARACTER:{characterInBody(p2,token);break}case TokenType.WHITESPACE_CHARACTER:{whitespaceCharacterInBody(p2,token);break}case TokenType.COMMENT:{appendComment(p2,token);break}case TokenType.START_TAG:{startTagInBody(p2,token);break}case TokenType.END_TAG:{endTagInBody(p2,token);break}case TokenType.EOF:{eofInBody(p2,token);break}}}__name(modeInBody,"modeInBody");function whitespaceCharacterInBody(p2,token){p2._reconstructActiveFormattingElements(),p2._insertCharacters(token)}__name(whitespaceCharacterInBody,"whitespaceCharacterInBody");function characterInBody(p2,token){p2._reconstructActiveFormattingElements(),p2._insertCharacters(token),p2.framesetOk=!1}__name(characterInBody,"characterInBody");function htmlStartTagInBody(p2,token){p2.openElements.tmplCount===0&&p2.treeAdapter.adoptAttributes(p2.openElements.items[0],token.attrs)}__name(htmlStartTagInBody,"htmlStartTagInBody");function bodyStartTagInBody(p2,token){const bodyElement=p2.openElements.tryPeekProperlyNestedBodyElement();bodyElement&&p2.openElements.tmplCount===0&&(p2.framesetOk=!1,p2.treeAdapter.adoptAttributes(bodyElement,token.attrs))}__name(bodyStartTagInBody,"bodyStartTagInBody");function framesetStartTagInBody(p2,token){const bodyElement=p2.openElements.tryPeekProperlyNestedBodyElement();p2.framesetOk&&bodyElement&&(p2.treeAdapter.detachNode(bodyElement),p2.openElements.popAllUpToHtmlElement(),p2._insertElement(token,NS.HTML),p2.insertionMode=InsertionMode.IN_FRAMESET)}__name(framesetStartTagInBody,"framesetStartTagInBody");function addressStartTagInBody(p2,token){p2.openElements.hasInButtonScope(TAG_ID.P)&&p2._closePElement(),p2._insertElement(token,NS.HTML)}__name(addressStartTagInBody,"addressStartTagInBody");function numberedHeaderStartTagInBody(p2,token){p2.openElements.hasInButtonScope(TAG_ID.P)&&p2._closePElement(),p2.openElements.currentTagId!==void 0&&NUMBERED_HEADERS.has(p2.openElements.currentTagId)&&p2.openElements.pop(),p2._insertElement(token,NS.HTML)}__name(numberedHeaderStartTagInBody,"numberedHeaderStartTagInBody");function preStartTagInBody(p2,token){p2.openElements.hasInButtonScope(TAG_ID.P)&&p2._closePElement(),p2._insertElement(token,NS.HTML),p2.skipNextNewLine=!0,p2.framesetOk=!1}__name(preStartTagInBody,"preStartTagInBody");function formStartTagInBody(p2,token){const inTemplate=p2.openElements.tmplCount>0;(!p2.formElement||inTemplate)&&(p2.openElements.hasInButtonScope(TAG_ID.P)&&p2._closePElement(),p2._insertElement(token,NS.HTML),inTemplate||(p2.formElement=p2.openElements.current))}__name(formStartTagInBody,"formStartTagInBody");function listItemStartTagInBody(p2,token){p2.framesetOk=!1;const tn=token.tagID;for(let i2=p2.openElements.stackTop;i2>=0;i2--){const elementId=p2.openElements.tagIDs[i2];if(tn===TAG_ID.LI&&elementId===TAG_ID.LI||(tn===TAG_ID.DD||tn===TAG_ID.DT)&&(elementId===TAG_ID.DD||elementId===TAG_ID.DT)){p2.openElements.generateImpliedEndTagsWithExclusion(elementId),p2.openElements.popUntilTagNamePopped(elementId);break}if(elementId!==TAG_ID.ADDRESS&&elementId!==TAG_ID.DIV&&elementId!==TAG_ID.P&&p2._isSpecialElement(p2.openElements.items[i2],elementId))break}p2.openElements.hasInButtonScope(TAG_ID.P)&&p2._closePElement(),p2._insertElement(token,NS.HTML)}__name(listItemStartTagInBody,"listItemStartTagInBody");function plaintextStartTagInBody(p2,token){p2.openElements.hasInButtonScope(TAG_ID.P)&&p2._closePElement(),p2._insertElement(token,NS.HTML),p2.tokenizer.state=TokenizerMode.PLAINTEXT}__name(plaintextStartTagInBody,"plaintextStartTagInBody");function buttonStartTagInBody(p2,token){p2.openElements.hasInScope(TAG_ID.BUTTON)&&(p2.openElements.generateImpliedEndTags(),p2.openElements.popUntilTagNamePopped(TAG_ID.BUTTON)),p2._reconstructActiveFormattingElements(),p2._insertElement(token,NS.HTML),p2.framesetOk=!1}__name(buttonStartTagInBody,"buttonStartTagInBody");function aStartTagInBody(p2,token){const activeElementEntry=p2.activeFormattingElements.getElementEntryInScopeWithTagName(TAG_NAMES.A);activeElementEntry&&(callAdoptionAgency(p2,token),p2.openElements.remove(activeElementEntry.element),p2.activeFormattingElements.removeEntry(activeElementEntry)),p2._reconstructActiveFormattingElements(),p2._insertElement(token,NS.HTML),p2.activeFormattingElements.pushElement(p2.openElements.current,token)}__name(aStartTagInBody,"aStartTagInBody");function bStartTagInBody(p2,token){p2._reconstructActiveFormattingElements(),p2._insertElement(token,NS.HTML),p2.activeFormattingElements.pushElement(p2.openElements.current,token)}__name(bStartTagInBody,"bStartTagInBody");function nobrStartTagInBody(p2,token){p2._reconstructActiveFormattingElements(),p2.openElements.hasInScope(TAG_ID.NOBR)&&(callAdoptionAgency(p2,token),p2._reconstructActiveFormattingElements()),p2._insertElement(token,NS.HTML),p2.activeFormattingElements.pushElement(p2.openElements.current,token)}__name(nobrStartTagInBody,"nobrStartTagInBody");function appletStartTagInBody(p2,token){p2._reconstructActiveFormattingElements(),p2._insertElement(token,NS.HTML),p2.activeFormattingElements.insertMarker(),p2.framesetOk=!1}__name(appletStartTagInBody,"appletStartTagInBody");function tableStartTagInBody(p2,token){p2.treeAdapter.getDocumentMode(p2.document)!==DOCUMENT_MODE.QUIRKS&&p2.openElements.hasInButtonScope(TAG_ID.P)&&p2._closePElement(),p2._insertElement(token,NS.HTML),p2.framesetOk=!1,p2.insertionMode=InsertionMode.IN_TABLE}__name(tableStartTagInBody,"tableStartTagInBody");function areaStartTagInBody(p2,token){p2._reconstructActiveFormattingElements(),p2._appendElement(token,NS.HTML),p2.framesetOk=!1,token.ackSelfClosing=!0}__name(areaStartTagInBody,"areaStartTagInBody");function isHiddenInput(token){const inputType=getTokenAttr(token,ATTRS.TYPE);return inputType!=null&&inputType.toLowerCase()===HIDDEN_INPUT_TYPE}__name(isHiddenInput,"isHiddenInput");function inputStartTagInBody(p2,token){p2._reconstructActiveFormattingElements(),p2._appendElement(token,NS.HTML),isHiddenInput(token)||(p2.framesetOk=!1),token.ackSelfClosing=!0}__name(inputStartTagInBody,"inputStartTagInBody");function paramStartTagInBody(p2,token){p2._appendElement(token,NS.HTML),token.ackSelfClosing=!0}__name(paramStartTagInBody,"paramStartTagInBody");function hrStartTagInBody(p2,token){p2.openElements.hasInButtonScope(TAG_ID.P)&&p2._closePElement(),p2._appendElement(token,NS.HTML),p2.framesetOk=!1,token.ackSelfClosing=!0}__name(hrStartTagInBody,"hrStartTagInBody");function imageStartTagInBody(p2,token){token.tagName=TAG_NAMES.IMG,token.tagID=TAG_ID.IMG,areaStartTagInBody(p2,token)}__name(imageStartTagInBody,"imageStartTagInBody");function textareaStartTagInBody(p2,token){p2._insertElement(token,NS.HTML),p2.skipNextNewLine=!0,p2.tokenizer.state=TokenizerMode.RCDATA,p2.originalInsertionMode=p2.insertionMode,p2.framesetOk=!1,p2.insertionMode=InsertionMode.TEXT}__name(textareaStartTagInBody,"textareaStartTagInBody");function xmpStartTagInBody(p2,token){p2.openElements.hasInButtonScope(TAG_ID.P)&&p2._closePElement(),p2._reconstructActiveFormattingElements(),p2.framesetOk=!1,p2._switchToTextParsing(token,TokenizerMode.RAWTEXT)}__name(xmpStartTagInBody,"xmpStartTagInBody");function iframeStartTagInBody(p2,token){p2.framesetOk=!1,p2._switchToTextParsing(token,TokenizerMode.RAWTEXT)}__name(iframeStartTagInBody,"iframeStartTagInBody");function rawTextStartTagInBody(p2,token){p2._switchToTextParsing(token,TokenizerMode.RAWTEXT)}__name(rawTextStartTagInBody,"rawTextStartTagInBody");function selectStartTagInBody(p2,token){p2._reconstructActiveFormattingElements(),p2._insertElement(token,NS.HTML),p2.framesetOk=!1,p2.insertionMode=p2.insertionMode===InsertionMode.IN_TABLE||p2.insertionMode===InsertionMode.IN_CAPTION||p2.insertionMode===InsertionMode.IN_TABLE_BODY||p2.insertionMode===InsertionMode.IN_ROW||p2.insertionMode===InsertionMode.IN_CELL?InsertionMode.IN_SELECT_IN_TABLE:InsertionMode.IN_SELECT}__name(selectStartTagInBody,"selectStartTagInBody");function optgroupStartTagInBody(p2,token){p2.openElements.currentTagId===TAG_ID.OPTION&&p2.openElements.pop(),p2._reconstructActiveFormattingElements(),p2._insertElement(token,NS.HTML)}__name(optgroupStartTagInBody,"optgroupStartTagInBody");function rbStartTagInBody(p2,token){p2.openElements.hasInScope(TAG_ID.RUBY)&&p2.openElements.generateImpliedEndTags(),p2._insertElement(token,NS.HTML)}__name(rbStartTagInBody,"rbStartTagInBody");function rtStartTagInBody(p2,token){p2.openElements.hasInScope(TAG_ID.RUBY)&&p2.openElements.generateImpliedEndTagsWithExclusion(TAG_ID.RTC),p2._insertElement(token,NS.HTML)}__name(rtStartTagInBody,"rtStartTagInBody");function mathStartTagInBody(p2,token){p2._reconstructActiveFormattingElements(),adjustTokenMathMLAttrs(token),adjustTokenXMLAttrs(token),token.selfClosing?p2._appendElement(token,NS.MATHML):p2._insertElement(token,NS.MATHML),token.ackSelfClosing=!0}__name(mathStartTagInBody,"mathStartTagInBody");function svgStartTagInBody(p2,token){p2._reconstructActiveFormattingElements(),adjustTokenSVGAttrs(token),adjustTokenXMLAttrs(token),token.selfClosing?p2._appendElement(token,NS.SVG):p2._insertElement(token,NS.SVG),token.ackSelfClosing=!0}__name(svgStartTagInBody,"svgStartTagInBody");function genericStartTagInBody(p2,token){p2._reconstructActiveFormattingElements(),p2._insertElement(token,NS.HTML)}__name(genericStartTagInBody,"genericStartTagInBody");function startTagInBody(p2,token){switch(token.tagID){case TAG_ID.I:case TAG_ID.S:case TAG_ID.B:case TAG_ID.U:case TAG_ID.EM:case TAG_ID.TT:case TAG_ID.BIG:case TAG_ID.CODE:case TAG_ID.FONT:case TAG_ID.SMALL:case TAG_ID.STRIKE:case TAG_ID.STRONG:{bStartTagInBody(p2,token);break}case TAG_ID.A:{aStartTagInBody(p2,token);break}case TAG_ID.H1:case TAG_ID.H2:case TAG_ID.H3:case TAG_ID.H4:case TAG_ID.H5:case TAG_ID.H6:{numberedHeaderStartTagInBody(p2,token);break}case TAG_ID.P:case TAG_ID.DL:case TAG_ID.OL:case TAG_ID.UL:case TAG_ID.DIV:case TAG_ID.DIR:case TAG_ID.NAV:case TAG_ID.MAIN:case TAG_ID.MENU:case TAG_ID.ASIDE:case TAG_ID.CENTER:case TAG_ID.FIGURE:case TAG_ID.FOOTER:case TAG_ID.HEADER:case TAG_ID.HGROUP:case TAG_ID.DIALOG:case TAG_ID.DETAILS:case TAG_ID.ADDRESS:case TAG_ID.ARTICLE:case TAG_ID.SEARCH:case TAG_ID.SECTION:case TAG_ID.SUMMARY:case TAG_ID.FIELDSET:case TAG_ID.BLOCKQUOTE:case TAG_ID.FIGCAPTION:{addressStartTagInBody(p2,token);break}case TAG_ID.LI:case TAG_ID.DD:case TAG_ID.DT:{listItemStartTagInBody(p2,token);break}case TAG_ID.BR:case TAG_ID.IMG:case TAG_ID.WBR:case TAG_ID.AREA:case TAG_ID.EMBED:case TAG_ID.KEYGEN:{areaStartTagInBody(p2,token);break}case TAG_ID.HR:{hrStartTagInBody(p2,token);break}case TAG_ID.RB:case TAG_ID.RTC:{rbStartTagInBody(p2,token);break}case TAG_ID.RT:case TAG_ID.RP:{rtStartTagInBody(p2,token);break}case TAG_ID.PRE:case TAG_ID.LISTING:{preStartTagInBody(p2,token);break}case TAG_ID.XMP:{xmpStartTagInBody(p2,token);break}case TAG_ID.SVG:{svgStartTagInBody(p2,token);break}case TAG_ID.HTML:{htmlStartTagInBody(p2,token);break}case TAG_ID.BASE:case TAG_ID.LINK:case TAG_ID.META:case TAG_ID.STYLE:case TAG_ID.TITLE:case TAG_ID.SCRIPT:case TAG_ID.BGSOUND:case TAG_ID.BASEFONT:case TAG_ID.TEMPLATE:{startTagInHead(p2,token);break}case TAG_ID.BODY:{bodyStartTagInBody(p2,token);break}case TAG_ID.FORM:{formStartTagInBody(p2,token);break}case TAG_ID.NOBR:{nobrStartTagInBody(p2,token);break}case TAG_ID.MATH:{mathStartTagInBody(p2,token);break}case TAG_ID.TABLE:{tableStartTagInBody(p2,token);break}case TAG_ID.INPUT:{inputStartTagInBody(p2,token);break}case TAG_ID.PARAM:case TAG_ID.TRACK:case TAG_ID.SOURCE:{paramStartTagInBody(p2,token);break}case TAG_ID.IMAGE:{imageStartTagInBody(p2,token);break}case TAG_ID.BUTTON:{buttonStartTagInBody(p2,token);break}case TAG_ID.APPLET:case TAG_ID.OBJECT:case TAG_ID.MARQUEE:{appletStartTagInBody(p2,token);break}case TAG_ID.IFRAME:{iframeStartTagInBody(p2,token);break}case TAG_ID.SELECT:{selectStartTagInBody(p2,token);break}case TAG_ID.OPTION:case TAG_ID.OPTGROUP:{optgroupStartTagInBody(p2,token);break}case TAG_ID.NOEMBED:case TAG_ID.NOFRAMES:{rawTextStartTagInBody(p2,token);break}case TAG_ID.FRAMESET:{framesetStartTagInBody(p2,token);break}case TAG_ID.TEXTAREA:{textareaStartTagInBody(p2,token);break}case TAG_ID.NOSCRIPT:{p2.options.scriptingEnabled?rawTextStartTagInBody(p2,token):genericStartTagInBody(p2,token);break}case TAG_ID.PLAINTEXT:{plaintextStartTagInBody(p2,token);break}case TAG_ID.COL:case TAG_ID.TH:case TAG_ID.TD:case TAG_ID.TR:case TAG_ID.HEAD:case TAG_ID.FRAME:case TAG_ID.TBODY:case TAG_ID.TFOOT:case TAG_ID.THEAD:case TAG_ID.CAPTION:case TAG_ID.COLGROUP:break;default:genericStartTagInBody(p2,token)}}__name(startTagInBody,"startTagInBody");function bodyEndTagInBody(p2,token){if(p2.openElements.hasInScope(TAG_ID.BODY)&&(p2.insertionMode=InsertionMode.AFTER_BODY,p2.options.sourceCodeLocationInfo)){const bodyElement=p2.openElements.tryPeekProperlyNestedBodyElement();bodyElement&&p2._setEndLocation(bodyElement,token)}}__name(bodyEndTagInBody,"bodyEndTagInBody");function htmlEndTagInBody(p2,token){p2.openElements.hasInScope(TAG_ID.BODY)&&(p2.insertionMode=InsertionMode.AFTER_BODY,endTagAfterBody(p2,token))}__name(htmlEndTagInBody,"htmlEndTagInBody");function addressEndTagInBody(p2,token){const tn=token.tagID;p2.openElements.hasInScope(tn)&&(p2.openElements.generateImpliedEndTags(),p2.openElements.popUntilTagNamePopped(tn))}__name(addressEndTagInBody,"addressEndTagInBody");function formEndTagInBody(p2){const inTemplate=p2.openElements.tmplCount>0,{formElement}=p2;inTemplate||(p2.formElement=null),(formElement||inTemplate)&&p2.openElements.hasInScope(TAG_ID.FORM)&&(p2.openElements.generateImpliedEndTags(),inTemplate?p2.openElements.popUntilTagNamePopped(TAG_ID.FORM):formElement&&p2.openElements.remove(formElement))}__name(formEndTagInBody,"formEndTagInBody");function pEndTagInBody(p2){p2.openElements.hasInButtonScope(TAG_ID.P)||p2._insertFakeElement(TAG_NAMES.P,TAG_ID.P),p2._closePElement()}__name(pEndTagInBody,"pEndTagInBody");function liEndTagInBody(p2){p2.openElements.hasInListItemScope(TAG_ID.LI)&&(p2.openElements.generateImpliedEndTagsWithExclusion(TAG_ID.LI),p2.openElements.popUntilTagNamePopped(TAG_ID.LI))}__name(liEndTagInBody,"liEndTagInBody");function ddEndTagInBody(p2,token){const tn=token.tagID;p2.openElements.hasInScope(tn)&&(p2.openElements.generateImpliedEndTagsWithExclusion(tn),p2.openElements.popUntilTagNamePopped(tn))}__name(ddEndTagInBody,"ddEndTagInBody");function numberedHeaderEndTagInBody(p2){p2.openElements.hasNumberedHeaderInScope()&&(p2.openElements.generateImpliedEndTags(),p2.openElements.popUntilNumberedHeaderPopped())}__name(numberedHeaderEndTagInBody,"numberedHeaderEndTagInBody");function appletEndTagInBody(p2,token){const tn=token.tagID;p2.openElements.hasInScope(tn)&&(p2.openElements.generateImpliedEndTags(),p2.openElements.popUntilTagNamePopped(tn),p2.activeFormattingElements.clearToLastMarker())}__name(appletEndTagInBody,"appletEndTagInBody");function brEndTagInBody(p2){p2._reconstructActiveFormattingElements(),p2._insertFakeElement(TAG_NAMES.BR,TAG_ID.BR),p2.openElements.pop(),p2.framesetOk=!1}__name(brEndTagInBody,"brEndTagInBody");function genericEndTagInBody(p2,token){const tn=token.tagName,tid=token.tagID;for(let i2=p2.openElements.stackTop;i2>0;i2--){const element2=p2.openElements.items[i2],elementId=p2.openElements.tagIDs[i2];if(tid===elementId&&(tid!==TAG_ID.UNKNOWN||p2.treeAdapter.getTagName(element2)===tn)){p2.openElements.generateImpliedEndTagsWithExclusion(tid),p2.openElements.stackTop>=i2&&p2.openElements.shortenToLength(i2);break}if(p2._isSpecialElement(element2,elementId))break}}__name(genericEndTagInBody,"genericEndTagInBody");function endTagInBody(p2,token){switch(token.tagID){case TAG_ID.A:case TAG_ID.B:case TAG_ID.I:case TAG_ID.S:case TAG_ID.U:case TAG_ID.EM:case TAG_ID.TT:case TAG_ID.BIG:case TAG_ID.CODE:case TAG_ID.FONT:case TAG_ID.NOBR:case TAG_ID.SMALL:case TAG_ID.STRIKE:case TAG_ID.STRONG:{callAdoptionAgency(p2,token);break}case TAG_ID.P:{pEndTagInBody(p2);break}case TAG_ID.DL:case TAG_ID.UL:case TAG_ID.OL:case TAG_ID.DIR:case TAG_ID.DIV:case TAG_ID.NAV:case TAG_ID.PRE:case TAG_ID.MAIN:case TAG_ID.MENU:case TAG_ID.ASIDE:case TAG_ID.BUTTON:case TAG_ID.CENTER:case TAG_ID.FIGURE:case TAG_ID.FOOTER:case TAG_ID.HEADER:case TAG_ID.HGROUP:case TAG_ID.DIALOG:case TAG_ID.ADDRESS:case TAG_ID.ARTICLE:case TAG_ID.DETAILS:case TAG_ID.SEARCH:case TAG_ID.SECTION:case TAG_ID.SUMMARY:case TAG_ID.LISTING:case TAG_ID.FIELDSET:case TAG_ID.BLOCKQUOTE:case TAG_ID.FIGCAPTION:{addressEndTagInBody(p2,token);break}case TAG_ID.LI:{liEndTagInBody(p2);break}case TAG_ID.DD:case TAG_ID.DT:{ddEndTagInBody(p2,token);break}case TAG_ID.H1:case TAG_ID.H2:case TAG_ID.H3:case TAG_ID.H4:case TAG_ID.H5:case TAG_ID.H6:{numberedHeaderEndTagInBody(p2);break}case TAG_ID.BR:{brEndTagInBody(p2);break}case TAG_ID.BODY:{bodyEndTagInBody(p2,token);break}case TAG_ID.HTML:{htmlEndTagInBody(p2,token);break}case TAG_ID.FORM:{formEndTagInBody(p2);break}case TAG_ID.APPLET:case TAG_ID.OBJECT:case TAG_ID.MARQUEE:{appletEndTagInBody(p2,token);break}case TAG_ID.TEMPLATE:{templateEndTagInHead(p2,token);break}default:genericEndTagInBody(p2,token)}}__name(endTagInBody,"endTagInBody");function eofInBody(p2,token){p2.tmplInsertionModeStack.length>0?eofInTemplate(p2,token):stopParsing(p2,token)}__name(eofInBody,"eofInBody");function endTagInText(p2,token){var _a18;token.tagID===TAG_ID.SCRIPT&&((_a18=p2.scriptHandler)===null||_a18===void 0||_a18.call(p2,p2.openElements.current)),p2.openElements.pop(),p2.insertionMode=p2.originalInsertionMode}__name(endTagInText,"endTagInText");function eofInText(p2,token){p2._err(token,ERR.eofInElementThatCanContainOnlyText),p2.openElements.pop(),p2.insertionMode=p2.originalInsertionMode,p2.onEof(token)}__name(eofInText,"eofInText");function characterInTable(p2,token){if(p2.openElements.currentTagId!==void 0&&TABLE_STRUCTURE_TAGS.has(p2.openElements.currentTagId))switch(p2.pendingCharacterTokens.length=0,p2.hasNonWhitespacePendingCharacterToken=!1,p2.originalInsertionMode=p2.insertionMode,p2.insertionMode=InsertionMode.IN_TABLE_TEXT,token.type){case TokenType.CHARACTER:{characterInTableText(p2,token);break}case TokenType.WHITESPACE_CHARACTER:{whitespaceCharacterInTableText(p2,token);break}}else tokenInTable(p2,token)}__name(characterInTable,"characterInTable");function captionStartTagInTable(p2,token){p2.openElements.clearBackToTableContext(),p2.activeFormattingElements.insertMarker(),p2._insertElement(token,NS.HTML),p2.insertionMode=InsertionMode.IN_CAPTION}__name(captionStartTagInTable,"captionStartTagInTable");function colgroupStartTagInTable(p2,token){p2.openElements.clearBackToTableContext(),p2._insertElement(token,NS.HTML),p2.insertionMode=InsertionMode.IN_COLUMN_GROUP}__name(colgroupStartTagInTable,"colgroupStartTagInTable");function colStartTagInTable(p2,token){p2.openElements.clearBackToTableContext(),p2._insertFakeElement(TAG_NAMES.COLGROUP,TAG_ID.COLGROUP),p2.insertionMode=InsertionMode.IN_COLUMN_GROUP,startTagInColumnGroup(p2,token)}__name(colStartTagInTable,"colStartTagInTable");function tbodyStartTagInTable(p2,token){p2.openElements.clearBackToTableContext(),p2._insertElement(token,NS.HTML),p2.insertionMode=InsertionMode.IN_TABLE_BODY}__name(tbodyStartTagInTable,"tbodyStartTagInTable");function tdStartTagInTable(p2,token){p2.openElements.clearBackToTableContext(),p2._insertFakeElement(TAG_NAMES.TBODY,TAG_ID.TBODY),p2.insertionMode=InsertionMode.IN_TABLE_BODY,startTagInTableBody(p2,token)}__name(tdStartTagInTable,"tdStartTagInTable");function tableStartTagInTable(p2,token){p2.openElements.hasInTableScope(TAG_ID.TABLE)&&(p2.openElements.popUntilTagNamePopped(TAG_ID.TABLE),p2._resetInsertionMode(),p2._processStartTag(token))}__name(tableStartTagInTable,"tableStartTagInTable");function inputStartTagInTable(p2,token){isHiddenInput(token)?p2._appendElement(token,NS.HTML):tokenInTable(p2,token),token.ackSelfClosing=!0}__name(inputStartTagInTable,"inputStartTagInTable");function formStartTagInTable(p2,token){!p2.formElement&&p2.openElements.tmplCount===0&&(p2._insertElement(token,NS.HTML),p2.formElement=p2.openElements.current,p2.openElements.pop())}__name(formStartTagInTable,"formStartTagInTable");function startTagInTable(p2,token){switch(token.tagID){case TAG_ID.TD:case TAG_ID.TH:case TAG_ID.TR:{tdStartTagInTable(p2,token);break}case TAG_ID.STYLE:case TAG_ID.SCRIPT:case TAG_ID.TEMPLATE:{startTagInHead(p2,token);break}case TAG_ID.COL:{colStartTagInTable(p2,token);break}case TAG_ID.FORM:{formStartTagInTable(p2,token);break}case TAG_ID.TABLE:{tableStartTagInTable(p2,token);break}case TAG_ID.TBODY:case TAG_ID.TFOOT:case TAG_ID.THEAD:{tbodyStartTagInTable(p2,token);break}case TAG_ID.INPUT:{inputStartTagInTable(p2,token);break}case TAG_ID.CAPTION:{captionStartTagInTable(p2,token);break}case TAG_ID.COLGROUP:{colgroupStartTagInTable(p2,token);break}default:tokenInTable(p2,token)}}__name(startTagInTable,"startTagInTable");function endTagInTable(p2,token){switch(token.tagID){case TAG_ID.TABLE:{p2.openElements.hasInTableScope(TAG_ID.TABLE)&&(p2.openElements.popUntilTagNamePopped(TAG_ID.TABLE),p2._resetInsertionMode());break}case TAG_ID.TEMPLATE:{templateEndTagInHead(p2,token);break}case TAG_ID.BODY:case TAG_ID.CAPTION:case TAG_ID.COL:case TAG_ID.COLGROUP:case TAG_ID.HTML:case TAG_ID.TBODY:case TAG_ID.TD:case TAG_ID.TFOOT:case TAG_ID.TH:case TAG_ID.THEAD:case TAG_ID.TR:break;default:tokenInTable(p2,token)}}__name(endTagInTable,"endTagInTable");function tokenInTable(p2,token){const savedFosterParentingState=p2.fosterParentingEnabled;p2.fosterParentingEnabled=!0,modeInBody(p2,token),p2.fosterParentingEnabled=savedFosterParentingState}__name(tokenInTable,"tokenInTable");function whitespaceCharacterInTableText(p2,token){p2.pendingCharacterTokens.push(token)}__name(whitespaceCharacterInTableText,"whitespaceCharacterInTableText");function characterInTableText(p2,token){p2.pendingCharacterTokens.push(token),p2.hasNonWhitespacePendingCharacterToken=!0}__name(characterInTableText,"characterInTableText");function tokenInTableText(p2,token){let i2=0;if(p2.hasNonWhitespacePendingCharacterToken)for(;i20&&p2.openElements.currentTagId===TAG_ID.OPTION&&p2.openElements.tagIDs[p2.openElements.stackTop-1]===TAG_ID.OPTGROUP&&p2.openElements.pop(),p2.openElements.currentTagId===TAG_ID.OPTGROUP&&p2.openElements.pop();break}case TAG_ID.OPTION:{p2.openElements.currentTagId===TAG_ID.OPTION&&p2.openElements.pop();break}case TAG_ID.SELECT:{p2.openElements.hasInSelectScope(TAG_ID.SELECT)&&(p2.openElements.popUntilTagNamePopped(TAG_ID.SELECT),p2._resetInsertionMode());break}case TAG_ID.TEMPLATE:{templateEndTagInHead(p2,token);break}}}__name(endTagInSelect,"endTagInSelect");function startTagInSelectInTable(p2,token){const tn=token.tagID;tn===TAG_ID.CAPTION||tn===TAG_ID.TABLE||tn===TAG_ID.TBODY||tn===TAG_ID.TFOOT||tn===TAG_ID.THEAD||tn===TAG_ID.TR||tn===TAG_ID.TD||tn===TAG_ID.TH?(p2.openElements.popUntilTagNamePopped(TAG_ID.SELECT),p2._resetInsertionMode(),p2._processStartTag(token)):startTagInSelect(p2,token)}__name(startTagInSelectInTable,"startTagInSelectInTable");function endTagInSelectInTable(p2,token){const tn=token.tagID;tn===TAG_ID.CAPTION||tn===TAG_ID.TABLE||tn===TAG_ID.TBODY||tn===TAG_ID.TFOOT||tn===TAG_ID.THEAD||tn===TAG_ID.TR||tn===TAG_ID.TD||tn===TAG_ID.TH?p2.openElements.hasInTableScope(tn)&&(p2.openElements.popUntilTagNamePopped(TAG_ID.SELECT),p2._resetInsertionMode(),p2.onEndTag(token)):endTagInSelect(p2,token)}__name(endTagInSelectInTable,"endTagInSelectInTable");function startTagInTemplate(p2,token){switch(token.tagID){case TAG_ID.BASE:case TAG_ID.BASEFONT:case TAG_ID.BGSOUND:case TAG_ID.LINK:case TAG_ID.META:case TAG_ID.NOFRAMES:case TAG_ID.SCRIPT:case TAG_ID.STYLE:case TAG_ID.TEMPLATE:case TAG_ID.TITLE:{startTagInHead(p2,token);break}case TAG_ID.CAPTION:case TAG_ID.COLGROUP:case TAG_ID.TBODY:case TAG_ID.TFOOT:case TAG_ID.THEAD:{p2.tmplInsertionModeStack[0]=InsertionMode.IN_TABLE,p2.insertionMode=InsertionMode.IN_TABLE,startTagInTable(p2,token);break}case TAG_ID.COL:{p2.tmplInsertionModeStack[0]=InsertionMode.IN_COLUMN_GROUP,p2.insertionMode=InsertionMode.IN_COLUMN_GROUP,startTagInColumnGroup(p2,token);break}case TAG_ID.TR:{p2.tmplInsertionModeStack[0]=InsertionMode.IN_TABLE_BODY,p2.insertionMode=InsertionMode.IN_TABLE_BODY,startTagInTableBody(p2,token);break}case TAG_ID.TD:case TAG_ID.TH:{p2.tmplInsertionModeStack[0]=InsertionMode.IN_ROW,p2.insertionMode=InsertionMode.IN_ROW,startTagInRow(p2,token);break}default:p2.tmplInsertionModeStack[0]=InsertionMode.IN_BODY,p2.insertionMode=InsertionMode.IN_BODY,startTagInBody(p2,token)}}__name(startTagInTemplate,"startTagInTemplate");function endTagInTemplate(p2,token){token.tagID===TAG_ID.TEMPLATE&&templateEndTagInHead(p2,token)}__name(endTagInTemplate,"endTagInTemplate");function eofInTemplate(p2,token){p2.openElements.tmplCount>0?(p2.openElements.popUntilTagNamePopped(TAG_ID.TEMPLATE),p2.activeFormattingElements.clearToLastMarker(),p2.tmplInsertionModeStack.shift(),p2._resetInsertionMode(),p2.onEof(token)):stopParsing(p2,token)}__name(eofInTemplate,"eofInTemplate");function startTagAfterBody(p2,token){token.tagID===TAG_ID.HTML?startTagInBody(p2,token):tokenAfterBody(p2,token)}__name(startTagAfterBody,"startTagAfterBody");function endTagAfterBody(p2,token){var _a18;if(token.tagID===TAG_ID.HTML){if(p2.fragmentContext||(p2.insertionMode=InsertionMode.AFTER_AFTER_BODY),p2.options.sourceCodeLocationInfo&&p2.openElements.tagIDs[0]===TAG_ID.HTML){p2._setEndLocation(p2.openElements.items[0],token);const bodyElement=p2.openElements.items[1];bodyElement&&!(!((_a18=p2.treeAdapter.getNodeSourceCodeLocation(bodyElement))===null||_a18===void 0)&&_a18.endTag)&&p2._setEndLocation(bodyElement,token)}}else tokenAfterBody(p2,token)}__name(endTagAfterBody,"endTagAfterBody");function tokenAfterBody(p2,token){p2.insertionMode=InsertionMode.IN_BODY,modeInBody(p2,token)}__name(tokenAfterBody,"tokenAfterBody");function startTagInFrameset(p2,token){switch(token.tagID){case TAG_ID.HTML:{startTagInBody(p2,token);break}case TAG_ID.FRAMESET:{p2._insertElement(token,NS.HTML);break}case TAG_ID.FRAME:{p2._appendElement(token,NS.HTML),token.ackSelfClosing=!0;break}case TAG_ID.NOFRAMES:{startTagInHead(p2,token);break}}}__name(startTagInFrameset,"startTagInFrameset");function endTagInFrameset(p2,token){token.tagID===TAG_ID.FRAMESET&&!p2.openElements.isRootHtmlElementCurrent()&&(p2.openElements.pop(),!p2.fragmentContext&&p2.openElements.currentTagId!==TAG_ID.FRAMESET&&(p2.insertionMode=InsertionMode.AFTER_FRAMESET))}__name(endTagInFrameset,"endTagInFrameset");function startTagAfterFrameset(p2,token){switch(token.tagID){case TAG_ID.HTML:{startTagInBody(p2,token);break}case TAG_ID.NOFRAMES:{startTagInHead(p2,token);break}}}__name(startTagAfterFrameset,"startTagAfterFrameset");function endTagAfterFrameset(p2,token){token.tagID===TAG_ID.HTML&&(p2.insertionMode=InsertionMode.AFTER_AFTER_FRAMESET)}__name(endTagAfterFrameset,"endTagAfterFrameset");function startTagAfterAfterBody(p2,token){token.tagID===TAG_ID.HTML?startTagInBody(p2,token):tokenAfterAfterBody(p2,token)}__name(startTagAfterAfterBody,"startTagAfterAfterBody");function tokenAfterAfterBody(p2,token){p2.insertionMode=InsertionMode.IN_BODY,modeInBody(p2,token)}__name(tokenAfterAfterBody,"tokenAfterAfterBody");function startTagAfterAfterFrameset(p2,token){switch(token.tagID){case TAG_ID.HTML:{startTagInBody(p2,token);break}case TAG_ID.NOFRAMES:{startTagInHead(p2,token);break}}}__name(startTagAfterAfterFrameset,"startTagAfterAfterFrameset");function nullCharacterInForeignContent(p2,token){token.chars=REPLACEMENT_CHARACTER,p2._insertCharacters(token)}__name(nullCharacterInForeignContent,"nullCharacterInForeignContent");function characterInForeignContent(p2,token){p2._insertCharacters(token),p2.framesetOk=!1}__name(characterInForeignContent,"characterInForeignContent");function popUntilHtmlOrIntegrationPoint(p2){for(;p2.treeAdapter.getNamespaceURI(p2.openElements.current)!==NS.HTML&&p2.openElements.currentTagId!==void 0&&!p2._isIntegrationPoint(p2.openElements.currentTagId,p2.openElements.current);)p2.openElements.pop()}__name(popUntilHtmlOrIntegrationPoint,"popUntilHtmlOrIntegrationPoint");function startTagInForeignContent(p2,token){if(causesExit(token))popUntilHtmlOrIntegrationPoint(p2),p2._startTagOutsideForeignContent(token);else{const current=p2._getAdjustedCurrentElement(),currentNs=p2.treeAdapter.getNamespaceURI(current);currentNs===NS.MATHML?adjustTokenMathMLAttrs(token):currentNs===NS.SVG&&(adjustTokenSVGTagName(token),adjustTokenSVGAttrs(token)),adjustTokenXMLAttrs(token),token.selfClosing?p2._appendElement(token,currentNs):p2._insertElement(token,currentNs),token.ackSelfClosing=!0}}__name(startTagInForeignContent,"startTagInForeignContent");function endTagInForeignContent(p2,token){if(token.tagID===TAG_ID.P||token.tagID===TAG_ID.BR){popUntilHtmlOrIntegrationPoint(p2),p2._endTagOutsideForeignContent(token);return}for(let i2=p2.openElements.stackTop;i2>0;i2--){const element2=p2.openElements.items[i2];if(p2.treeAdapter.getNamespaceURI(element2)===NS.HTML){p2._endTagOutsideForeignContent(token);break}const tagName=p2.treeAdapter.getTagName(element2);if(tagName.toLowerCase()===token.tagName){token.tagName=tagName,p2.openElements.shortenToLength(i2);break}}}__name(endTagInForeignContent,"endTagInForeignContent");TAG_NAMES.AREA,TAG_NAMES.BASE,TAG_NAMES.BASEFONT,TAG_NAMES.BGSOUND,TAG_NAMES.BR,TAG_NAMES.COL,TAG_NAMES.EMBED,TAG_NAMES.FRAME,TAG_NAMES.HR,TAG_NAMES.IMG,TAG_NAMES.INPUT,TAG_NAMES.KEYGEN,TAG_NAMES.LINK,TAG_NAMES.META,TAG_NAMES.PARAM,TAG_NAMES.SOURCE,TAG_NAMES.TRACK,TAG_NAMES.WBR;const gfmTagfilterExpression=/<(\/?)(iframe|noembed|noframes|plaintext|script|style|textarea|title|xmp)(?=[\t\n\f\r />])/gi,knownMdxNames=new Set(["mdxFlowExpression","mdxJsxFlowElement","mdxJsxTextElement","mdxTextExpression","mdxjsEsm"]),parseOptions={sourceCodeLocationInfo:!0,scriptingEnabled:!1};function raw(tree,options){const document2=documentMode(tree),one2=zwitch("type",{handlers:{root:root$1,element:element$1,text:text$1,comment:comment$1,doctype:doctype$1,raw:handleRaw},unknown}),state={parser:document2?new Parser(parseOptions):Parser.getFragmentParser(void 0,parseOptions),handle(node2){one2(node2,state)},stitches:!1,options:options||{}};one2(tree,state),resetTokenizer(state,pointStart());const p5=document2?state.parser.document:state.parser.getFragment(),result=fromParse5(p5,{file:state.options.file});return state.stitches&&visit(result,"comment",function(node2,index2,parent){const stitch2=node2;if(stitch2.value.stitch&&parent&&index2!==void 0){const siblings=parent.children;return siblings[index2]=stitch2.value.stitch,index2}}),result.type==="root"&&result.children.length===1&&result.children[0].type===tree.type?result.children[0]:result}__name(raw,"raw");function all(nodes,state){let index2=-1;if(nodes)for(;++index24&&(state.parser.tokenizer.state=0);const token={type:TokenType.CHARACTER,chars:node2.value,location:createParse5Location(node2)};resetTokenizer(state,pointStart(node2)),state.parser.currentToken=token,state.parser._processToken(state.parser.currentToken)}__name(text$1,"text$1");function doctype$1(node2,state){const token={type:TokenType.DOCTYPE,name:"html",forceQuirks:!1,publicId:"",systemId:"",location:createParse5Location(node2)};resetTokenizer(state,pointStart(node2)),state.parser.currentToken=token,state.parser._processToken(state.parser.currentToken)}__name(doctype$1,"doctype$1");function stitch(node2,state){state.stitches=!0;const clone2=cloneWithoutChildren(node2);if("children"in node2&&"children"in clone2){const fakeRoot=raw({type:"root",children:node2.children},state.options);clone2.children=fakeRoot.children}comment$1({type:"comment",value:{stitch:clone2}},state)}__name(stitch,"stitch");function comment$1(node2,state){const data=node2.value,token={type:TokenType.COMMENT,data,location:createParse5Location(node2)};resetTokenizer(state,pointStart(node2)),state.parser.currentToken=token,state.parser._processToken(state.parser.currentToken)}__name(comment$1,"comment$1");function handleRaw(node2,state){if(state.parser.tokenizer.preprocessor.html="",state.parser.tokenizer.preprocessor.pos=-1,state.parser.tokenizer.preprocessor.lastGapPos=-2,state.parser.tokenizer.preprocessor.gapStack=[],state.parser.tokenizer.preprocessor.skipNextNewLine=!1,state.parser.tokenizer.preprocessor.lastChunkWritten=!1,state.parser.tokenizer.preprocessor.endOfChunkHit=!1,state.parser.tokenizer.preprocessor.isEol=!1,setPoint(state,pointStart(node2)),state.parser.tokenizer.write(state.options.tagfilter?node2.value.replace(gfmTagfilterExpression,"<$1$2"):node2.value,!1),state.parser.tokenizer._runParsingLoop(),state.parser.tokenizer.state===72||state.parser.tokenizer.state===78){state.parser.tokenizer.preprocessor.lastChunkWritten=!0;const cp=state.parser.tokenizer._consume();state.parser.tokenizer._callState(cp)}}__name(handleRaw,"handleRaw");function unknown(node_,state){const node2=node_;if(state.options.passThrough&&state.options.passThrough.includes(node2.type))stitch(node2,state);else{let extra="";throw knownMdxNames.has(node2.type)&&(extra=". It looks like you are using MDX nodes with `hast-util-raw` (or `rehype-raw`). If you use this because you are using remark or rehype plugins that inject `'html'` nodes, then please raise an issue with that plugin, as its a bad and slow idea. If you use this because you are using markdown syntax, then you have to configure this utility (or plugin) to pass through these nodes (see `passThrough` in docs), but you can also migrate to use the MDX syntax"),new Error("Cannot compile `"+node2.type+"` node"+extra)}}__name(unknown,"unknown");function resetTokenizer(state,point2){setPoint(state,point2);const token=state.parser.tokenizer.currentCharacterToken;token&&token.location&&(token.location.endLine=state.parser.tokenizer.preprocessor.line,token.location.endCol=state.parser.tokenizer.preprocessor.col+1,token.location.endOffset=state.parser.tokenizer.preprocessor.offset+1,state.parser.currentToken=token,state.parser._processToken(state.parser.currentToken)),state.parser.tokenizer.paused=!1,state.parser.tokenizer.inLoop=!1,state.parser.tokenizer.active=!1,state.parser.tokenizer.returnState=TokenizerMode.DATA,state.parser.tokenizer.charRefCode=-1,state.parser.tokenizer.consumedAfterSnapshot=-1,state.parser.tokenizer.currentLocation=null,state.parser.tokenizer.currentCharacterToken=null,state.parser.tokenizer.currentToken=null,state.parser.tokenizer.currentAttr={name:"",value:""}}__name(resetTokenizer,"resetTokenizer");function setPoint(state,point2){if(point2&&point2.offset!==void 0){const location2={startLine:point2.line,startCol:point2.column,startOffset:point2.offset,endLine:-1,endCol:-1,endOffset:-1};state.parser.tokenizer.preprocessor.lineStartPos=-point2.column+1,state.parser.tokenizer.preprocessor.droppedBufferSize=point2.offset,state.parser.tokenizer.preprocessor.line=point2.line,state.parser.tokenizer.currentLocation=location2}}__name(setPoint,"setPoint");function startTag(node2,state){const tagName=node2.tagName.toLowerCase();if(state.parser.tokenizer.state===TokenizerMode.PLAINTEXT)return;resetTokenizer(state,pointStart(node2));const current=state.parser.openElements.current;let ns="namespaceURI"in current?current.namespaceURI:webNamespaces.html;ns===webNamespaces.html&&tagName==="svg"&&(ns=webNamespaces.svg);const result=toParse5({...node2,children:[]},{space:ns===webNamespaces.svg?"svg":"html"}),tag={type:TokenType.START_TAG,tagName,tagID:getTagID(tagName),selfClosing:!1,ackSelfClosing:!1,attrs:"attrs"in result?result.attrs:[],location:createParse5Location(node2)};state.parser.currentToken=tag,state.parser._processToken(state.parser.currentToken),state.parser.tokenizer.lastStartTagName=tagName}__name(startTag,"startTag");function endTag(node2,state){const tagName=node2.tagName.toLowerCase();if(!state.parser.tokenizer.inForeignNode&&htmlVoidElements.includes(tagName)||state.parser.tokenizer.state===TokenizerMode.PLAINTEXT)return;resetTokenizer(state,pointEnd(node2));const tag={type:TokenType.END_TAG,tagName,tagID:getTagID(tagName),selfClosing:!1,ackSelfClosing:!1,attrs:[],location:createParse5Location(node2)};state.parser.currentToken=tag,state.parser._processToken(state.parser.currentToken),tagName===state.parser.tokenizer.lastStartTagName&&(state.parser.tokenizer.state===TokenizerMode.RCDATA||state.parser.tokenizer.state===TokenizerMode.RAWTEXT||state.parser.tokenizer.state===TokenizerMode.SCRIPT_DATA)&&(state.parser.tokenizer.state=TokenizerMode.DATA)}__name(endTag,"endTag");function documentMode(node2){const head=node2.type==="root"?node2.children[0]:node2;return!!(head&&(head.type==="doctype"||head.type==="element"&&head.tagName.toLowerCase()==="html"))}__name(documentMode,"documentMode");function createParse5Location(node2){const start2=pointStart(node2)||{line:void 0,column:void 0,offset:void 0},end=pointEnd(node2)||{line:void 0,column:void 0,offset:void 0};return{startLine:start2.line,startCol:start2.column,startOffset:start2.offset,endLine:end.line,endCol:end.column,endOffset:end.offset}}__name(createParse5Location,"createParse5Location");function cloneWithoutChildren(node2){return"children"in node2?structuredClone$1({...node2,children:[]}):structuredClone$1(node2)}__name(cloneWithoutChildren,"cloneWithoutChildren");function rehypeRaw(options){return function(tree,file){return raw(tree,{...options,file})}}__name(rehypeRaw,"rehypeRaw");const aria=["ariaDescribedBy","ariaLabel","ariaLabelledBy"],defaultSchema={ancestors:{tbody:["table"],td:["table"],th:["table"],thead:["table"],tfoot:["table"],tr:["table"]},attributes:{a:[...aria,"dataFootnoteBackref","dataFootnoteRef",["className","data-footnote-backref"],"href"],blockquote:["cite"],code:[["className",/^language-./]],del:["cite"],div:["itemScope","itemType"],dl:[...aria],h2:[["className","sr-only"]],img:[...aria,"longDesc","src"],input:[["disabled",!0],["type","checkbox"]],ins:["cite"],li:[["className","task-list-item"]],ol:[...aria,["className","contains-task-list"]],q:["cite"],section:["dataFootnotes",["className","footnotes"]],source:["srcSet"],summary:[...aria],table:[...aria],ul:[...aria,["className","contains-task-list"]],"*":["abbr","accept","acceptCharset","accessKey","action","align","alt","axis","border","cellPadding","cellSpacing","char","charOff","charSet","checked","clear","colSpan","color","cols","compact","coords","dateTime","dir","encType","frame","hSpace","headers","height","hrefLang","htmlFor","id","isMap","itemProp","label","lang","maxLength","media","method","multiple","name","noHref","noShade","noWrap","open","prompt","readOnly","rev","rowSpan","rows","rules","scope","selected","shape","size","span","start","summary","tabIndex","title","useMap","vAlign","value","width"]},clobber:["ariaDescribedBy","ariaLabelledBy","id","name"],clobberPrefix:"user-content-",protocols:{cite:["http","https"],href:["http","https","irc","ircs","mailto","xmpp"],longDesc:["http","https"],src:["http","https"]},required:{input:{disabled:!0,type:"checkbox"}},strip:["script"],tagNames:["a","b","blockquote","br","code","dd","del","details","div","dl","dt","em","h1","h2","h3","h4","h5","h6","hr","i","img","input","ins","kbd","li","ol","p","picture","pre","q","rp","rt","ruby","s","samp","section","source","span","strike","strong","sub","summary","sup","table","tbody","td","tfoot","th","thead","tr","tt","ul","var"]},own={}.hasOwnProperty;function sanitize(node2,options){let result={type:"root",children:[]};const state={schema:options?{...defaultSchema,...options}:defaultSchema,stack:[]},replace2=transform(state,node2);return replace2&&(Array.isArray(replace2)?replace2.length===1?result=replace2[0]:result.children=replace2:result=replace2),result}__name(sanitize,"sanitize");function transform(state,node2){if(node2&&typeof node2=="object"){const unsafe=node2;switch(typeof unsafe.type=="string"?unsafe.type:""){case"comment":return comment(state,unsafe);case"doctype":return doctype(state,unsafe);case"element":return element(state,unsafe);case"root":return root(state,unsafe);case"text":return text(state,unsafe)}}}__name(transform,"transform");function comment(state,unsafe){if(state.schema.allowComments){const result=typeof unsafe.value=="string"?unsafe.value:"",index2=result.indexOf("-->"),node2={type:"comment",value:index2<0?result:result.slice(0,index2)};return patch(node2,unsafe),node2}}__name(comment,"comment");function doctype(state,unsafe){if(state.schema.allowDoctypes){const node2={type:"doctype"};return patch(node2,unsafe),node2}}__name(doctype,"doctype");function element(state,unsafe){const name2=typeof unsafe.tagName=="string"?unsafe.tagName:"";state.stack.push(name2);const content2=children(state,unsafe.children),properties_=properties(state,unsafe.properties);state.stack.pop();let safeElement=!1;if(name2&&name2!=="*"&&(!state.schema.tagNames||state.schema.tagNames.includes(name2))&&(safeElement=!0,state.schema.ancestors&&own.call(state.schema.ancestors,name2))){const ancestors=state.schema.ancestors[name2];let index2=-1;for(safeElement=!1;++index21){let ok2=!1,index2=0;for(;++index2-1&&colon>slash||questionMark>-1&&colon>questionMark||numberSign>-1&&colon>numberSign)return!0;let index2=-1;for(;++index24&&key.slice(0,4).toLowerCase()==="data")return dataDefault}__name(findDefinition,"findDefinition");function rehypeSanitize(options){return function(tree){return sanitize(tree,options)}}__name(rehypeSanitize,"rehypeSanitize");const Input=reactExports.forwardRef(({className,type,...props},ref)=>jsxRuntimeExports.jsx("input",{type,className:cn$2("flex h-10 w-full rounded-md border border-input bg-background px-3 py-2 text-sm ring-offset-background file:border-0 file:bg-transparent file:text-sm file:font-medium placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50",className),ref,...props}));Input.displayName="Input";const statuses=[{value:"Passed",label:"Passed",icon:CheckCircledIcon,variant:"success"},{value:"Failed",label:"Failed",icon:CrossCircledIcon,variant:"destructive"},{value:"Error",label:"Error",icon:CrossCircledIcon,variant:"destructive"},{value:"Investigate",label:"Investigate",icon:QuestionMarkCircledIcon,variant:"warning"},{value:"Skipped",label:"Skipped",icon:StopwatchIcon,variant:"secondary"},{value:"Planned",label:"Planned",icon:StopwatchIcon,variant:"secondary"}],impacts=[{label:"Critical",value:"Critical",icon:ExclamationTriangleIcon},{label:"High",value:"High",icon:ArrowUpIcon},{label:"Medium",value:"Medium",icon:ArrowRightIcon},{label:"Low",value:"Low",icon:ArrowDownIcon},{label:"Unranked",value:"Unranked",icon:MinusIcon}],badgeVariants=cva("inline-flex items-center rounded-full border px-2.5 py-0.5 text-xs font-semibold transition-colors focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2",{variants:{variant:{default:"border-transparent bg-primary text-primary-foreground hover:bg-primary/80",secondary:"border-transparent bg-secondary text-secondary-foreground hover:bg-secondary/80",destructive:"border-transparent bg-destructive text-destructive-foreground hover:bg-destructive/80",outline:"text-foreground",warning:"border-transparent bg-amber-100 text-amber-800 hover:bg-amber-200 dark:bg-amber-900 dark:text-amber-200",success:"border-transparent bg-green-600 text-white hover:bg-green-700 dark:bg-green-700 dark:text-green-100"}},defaultVariants:{variant:"default"}});function Badge({className,variant,...props}){return jsxRuntimeExports.jsx("div",{className:cn$2(badgeVariants({variant}),className),...props})}__name(Badge,"Badge");function StatusIcon({Item:Item3}){const status=statuses.find(status2=>status2.value===Item3.TestStatus);return status?jsxRuntimeExports.jsx("div",{className:"flex items-center",children:jsxRuntimeExports.jsx(Badge,{variant:status.variant,children:jsxRuntimeExports.jsx("span",{children:status.label})})}):null}__name(StatusIcon,"StatusIcon");function DataTable({columns:columns2,data,pillar}){const[sorting,setSorting]=reactExports.useState([{id:"TestRisk",desc:!1},{id:"TestStatus",desc:!1}]),[columnFilters,setColumnFilters]=reactExports.useState([]),[globalFilter,setGlobalFilter]=reactExports.useState(""),[selectedSfiPillars,setSelectedSfiPillars]=reactExports.useState([]),[selectedRisks,setSelectedRisks]=reactExports.useState([]),[selectedStatuses,setSelectedStatuses]=reactExports.useState([]),[columnVisibility,setColumnVisibility]=reactExports.useState({TestImpact:!1,TestImplementationCost:!1,TestId:!1,TestSfiPillar:!1,TestMinimumLicense:!1,TestCategory:pillar==="Devices"}),[rowSelection,setRowSelection]=reactExports.useState({}),pillarFilteredData=reactExports.useMemo(()=>pillar?data.filter(item=>item.TestPillar===pillar):data,[data,pillar]);reactExports.useEffect(()=>{setSelectedRisks(pillar==="Infrastructure"?["High"]:[])},[pillar]);const filteredData=reactExports.useMemo(()=>{let result=pillarFilteredData;return selectedSfiPillars.length>0&&(result=result.filter(item=>item.TestSfiPillar&&selectedSfiPillars.includes(item.TestSfiPillar))),selectedRisks.length>0&&(result=result.filter(item=>item.TestRisk&&selectedRisks.includes(item.TestRisk))),selectedStatuses.length>0?result=result.filter(item=>item.TestStatus&&selectedStatuses.includes(item.TestStatus)):result=result.filter(item=>item.TestStatus!=="Planned"),result},[pillarFilteredData,selectedSfiPillars,selectedRisks,selectedStatuses]),uniqueSfiPillars=reactExports.useMemo(()=>{const pillars=pillarFilteredData.map(item=>item.TestSfiPillar).filter(pillar2=>pillar2!=null);return Array.from(new Set(pillars)).sort()},[pillarFilteredData]),uniqueRisks=reactExports.useMemo(()=>{const risks=pillarFilteredData.map(item=>item.TestRisk).filter(risk=>risk!=null),uniqueRiskSet=Array.from(new Set(risks)),riskOrder=["Critical","High","Medium","Low","Unranked"];return uniqueRiskSet.sort((a2,b2)=>{const indexA=riskOrder.indexOf(a2),indexB=riskOrder.indexOf(b2);return indexA!==-1&&indexB!==-1?indexA-indexB:indexA!==-1?-1:indexB!==-1?1:a2.localeCompare(b2)})},[pillarFilteredData]),uniqueStatuses=reactExports.useMemo(()=>{const statuses2=pillarFilteredData.map(item=>item.TestStatus).filter(status=>status!=null),uniqueStatusSet=Array.from(new Set(statuses2)),statusOrder=["Passed","Failed","Planned"];return uniqueStatusSet.sort((a2,b2)=>{const indexA=statusOrder.indexOf(a2),indexB=statusOrder.indexOf(b2);return indexA!==-1&&indexB!==-1?indexA-indexB:indexA!==-1?-1:indexB!==-1?1:a2.localeCompare(b2)})},[pillarFilteredData]),getSfiPillarIcon=__name(pillar2=>pillar2.includes("Monitor and detect")?Eye:pillar2.includes("Protect engineering")?Wrench:pillar2.includes("Protect identities")?Lock:pillar2.includes("Protect tenants")?Building:pillar2.includes("Accelerate response")?Zap:Shield,"getSfiPillarIcon"),table2=useReactTable({data:filteredData,columns:columns2,enableRowSelection:!0,getCoreRowModel:getCoreRowModel(),onSortingChange:setSorting,getSortedRowModel:getSortedRowModel(),onGlobalFilterChange:setGlobalFilter,onColumnFiltersChange:setColumnFilters,getFilteredRowModel:getFilteredRowModel(),onColumnVisibilityChange:setColumnVisibility,onRowSelectionChange:__name(stateUpdater=>{setRowSelection({}),setRowSelection(stateUpdater)},"onRowSelectionChange"),state:{sorting,columnFilters,globalFilter,columnVisibility,rowSelection}}),[sheetOpen,setSheetOpen]=reactExports.useState(!1),[selectedRow,setSelectedRow]=reactExports.useState(null),mdRehypePlugins=selectedRow?.TestPillar==="Infrastructure"?[rehypeRaw,rehypeSanitize]:[];return jsxRuntimeExports.jsxs("div",{children:[jsxRuntimeExports.jsxs("div",{className:"flex items-center py-4 justify-between",children:[jsxRuntimeExports.jsxs("div",{className:"flex items-center gap-4",children:[jsxRuntimeExports.jsx(Input,{placeholder:"Search by name...",value:globalFilter??"",onChange:__name(e3=>table2.setGlobalFilter(String(e3.target.value)),"onChange"),className:"max-w-sm"}),jsxRuntimeExports.jsxs("div",{className:"flex items-center gap-1",children:[jsxRuntimeExports.jsx("span",{className:"text-xs font-medium text-muted-foreground mr-1",children:"Risk:"}),uniqueRisks.map(risk=>{const isSelected=selectedRisks.includes(risk),riskCount=data.filter(item=>item.TestRisk===risk).length;return jsxRuntimeExports.jsx(Button,{variant:isSelected?"default":"outline",size:"sm",onClick:__name(()=>{setSelectedRisks(isSelected?prev=>prev.filter(r2=>r2!==risk):prev=>[...prev,risk])},"onClick"),className:`text-xs h-6 px-3 py-1 rounded-full ${isSelected?"bg-purple-600 hover:bg-purple-700 text-white":"hover:bg-purple-50 hover:text-purple-700 hover:border-purple-300 dark:hover:bg-purple-950 dark:hover:text-purple-300"}`,title:`${risk} (${riskCount} tests)`,children:risk},risk)})]}),jsxRuntimeExports.jsxs("div",{className:"flex items-center gap-1",children:[jsxRuntimeExports.jsx("span",{className:"text-xs font-medium text-muted-foreground mr-1",children:"Status:"}),uniqueStatuses.map(status=>{const isSelected=selectedStatuses.includes(status),statusCount=data.filter(item=>item.TestStatus===status).length,getStatusColors=__name((status2,isSelected2)=>status2==="Passed"?isSelected2?"bg-green-600 hover:bg-green-700 text-white":"hover:bg-green-50 hover:text-green-700 hover:border-green-300 dark:hover:bg-green-950 dark:hover:text-green-300":status2==="Failed"?isSelected2?"bg-red-600 hover:bg-red-700 text-white":"hover:bg-red-50 hover:text-red-700 hover:border-red-300 dark:hover:bg-red-950 dark:hover:text-red-300":isSelected2?"bg-gray-600 hover:bg-gray-700 text-white":"hover:bg-gray-50 hover:text-gray-700 hover:border-gray-300 dark:hover:bg-gray-950 dark:hover:text-gray-300","getStatusColors");return jsxRuntimeExports.jsx(Button,{variant:isSelected?"default":"outline",size:"sm",onClick:__name(()=>{setSelectedStatuses(isSelected?prev=>prev.filter(s2=>s2!==status):prev=>[...prev,status])},"onClick"),className:`text-xs h-6 px-3 py-1 rounded-full ${getStatusColors(status,isSelected)}`,title:`${status} (${statusCount} tests)`,children:status},status)})]})]}),jsxRuntimeExports.jsx("div",{className:"flex items-center gap-4",children:jsxRuntimeExports.jsxs(DropdownMenu,{children:[jsxRuntimeExports.jsx(DropdownMenuTrigger,{asChild:!0,children:jsxRuntimeExports.jsx(Button,{variant:"outline",size:"sm",children:jsxRuntimeExports.jsx(Columns2,{className:"h-4 w-4"})})}),jsxRuntimeExports.jsx(DropdownMenuContent,{align:"end",children:table2.getAllColumns().filter(column=>column.getCanHide()).filter(column=>pillar==="Infrastructure"?!["TestImpact","TestImplementationCost","TestMinimumLicense"].includes(column.id):!0).map(column=>jsxRuntimeExports.jsx(DropdownMenuCheckboxItem,{className:"capitalize",checked:column.getIsVisible(),onCheckedChange:__name(value2=>column.toggleVisibility(!!value2),"onCheckedChange"),children:column.columnDef.meta?.label??column.id},column.id))})]})})]}),jsxRuntimeExports.jsxs("div",{className:"mb-4",children:[jsxRuntimeExports.jsxs("div",{className:"flex items-center justify-between mb-3",children:[jsxRuntimeExports.jsxs("div",{className:"flex items-center gap-2",children:[jsxRuntimeExports.jsx("span",{className:"text-sm font-medium",children:"Filter by SFI Pillar:"}),selectedSfiPillars.length>0&&jsxRuntimeExports.jsxs(Button,{variant:"ghost",size:"sm",onClick:__name(()=>setSelectedSfiPillars([]),"onClick"),className:"h-6 px-2 text-xs text-muted-foreground hover:text-foreground",children:["Clear All (",selectedSfiPillars.length,")"]})]}),jsxRuntimeExports.jsxs("div",{className:"flex items-center gap-4",children:[(selectedSfiPillars.length>0||selectedRisks.length>0||selectedStatuses.length>0)&&jsxRuntimeExports.jsx(Button,{variant:"ghost",size:"sm",onClick:__name(()=>{setSelectedSfiPillars([]),setSelectedRisks([]),setSelectedStatuses([])},"onClick"),className:"h-6 px-2 text-xs text-muted-foreground hover:text-foreground",children:"Clear All Filters"}),jsxRuntimeExports.jsxs("div",{className:"text-xs text-muted-foreground",children:["Showing ",filteredData.length," of ",pillarFilteredData.length," tests"]})]})]}),jsxRuntimeExports.jsx("div",{className:"flex flex-wrap gap-2",children:uniqueSfiPillars.map(pillar2=>{const isSelected=selectedSfiPillars.includes(pillar2),pillarCount=data.filter(item=>item.TestSfiPillar===pillar2).length,PillarIcon=getSfiPillarIcon(pillar2);return jsxRuntimeExports.jsxs(Button,{variant:isSelected?"default":"outline",size:"sm",onClick:__name(()=>{setSelectedSfiPillars(isSelected?prev=>prev.filter(p2=>p2!==pillar2):prev=>[...prev,pillar2])},"onClick"),className:`text-xs max-w-96 h-auto py-1 px-4 rounded-full ${isSelected?"bg-blue-600 hover:bg-blue-700 text-white":"hover:bg-blue-50 hover:text-blue-700 hover:border-blue-300 dark:hover:bg-blue-950 dark:hover:text-blue-300"}`,title:`${pillar2} (${pillarCount} tests)`,children:[jsxRuntimeExports.jsx(PillarIcon,{className:"mr-2 h-3 w-3 flex-shrink-0"}),jsxRuntimeExports.jsx("span",{className:"whitespace-normal text-left leading-tight",children:pillar2})]},pillar2)})})]}),jsxRuntimeExports.jsx("div",{className:"rounded-md border",children:jsxRuntimeExports.jsxs(Table,{children:[jsxRuntimeExports.jsx(TableHeader,{children:table2.getHeaderGroups().map(headerGroup=>jsxRuntimeExports.jsx(TableRow,{children:headerGroup.headers.map(header=>jsxRuntimeExports.jsx(TableHead,{children:header.isPlaceholder?null:flexRender(header.column.columnDef.header,header.getContext())},header.id))},headerGroup.id))}),jsxRuntimeExports.jsx(TableBody,{children:table2.getRowModel().rows?.length?table2.getRowModel().rows.map(row=>jsxRuntimeExports.jsx(TableRow,{className:"cursor-pointer","data-state":row.getIsSelected()&&"selected",onClick:__name(()=>{setSelectedRow(row.original),setSheetOpen(!0)},"onClick"),children:row.getVisibleCells().map(cell=>jsxRuntimeExports.jsx(TableCell,{children:flexRender(cell.column.columnDef.cell,cell.getContext())},cell.id))},row.id)):jsxRuntimeExports.jsx(TableRow,{children:jsxRuntimeExports.jsx(TableCell,{colSpan:columns2.length,className:"h-24 text-center",children:"No results."})})})]})}),jsxRuntimeExports.jsx(Sheet,{open:sheetOpen,onOpenChange:setSheetOpen,children:jsxRuntimeExports.jsxs(SheetContent,{side:"right",className:"md:min-w-[700px] lg:min-w-[900px] overflow-y-auto",allowMaximize:!0,children:[jsxRuntimeExports.jsx(SheetHeader,{children:jsxRuntimeExports.jsx(SheetTitle,{className:"text-2xl text-left",children:selectedRow?.TestTitle})}),jsxRuntimeExports.jsx("div",{className:"grid pt-10 gap-6",children:jsxRuntimeExports.jsx(Card,{children:jsxRuntimeExports.jsx(CardHeader,{children:jsxRuntimeExports.jsxs("div",{className:`mt-2 text-sm ${selectedRow?.TestPillar==="Infrastructure"?"flex flex-col gap-y-2":"grid grid-cols-3 gap-y-2"}`,children:[jsxRuntimeExports.jsxs("div",{className:"flex items-center gap-2",children:[jsxRuntimeExports.jsx(TriangleAlert,{className:"h-4 w-4 text-foreground"}),jsxRuntimeExports.jsx("span",{className:"font-semibold",children:"Risk:"}),jsxRuntimeExports.jsx("span",{children:selectedRow?.TestRisk??"N/A"})]}),selectedRow?.TestPillar!=="Infrastructure"&&jsxRuntimeExports.jsxs("div",{className:"flex items-center gap-2",children:[jsxRuntimeExports.jsx(Users,{className:"h-4 w-4 text-foreground"}),jsxRuntimeExports.jsx("span",{className:"font-semibold",children:"User Impact:"}),jsxRuntimeExports.jsx("span",{children:selectedRow?.TestImpact??"N/A"})]}),selectedRow?.TestPillar!=="Infrastructure"&&jsxRuntimeExports.jsxs("div",{className:"flex items-center gap-2",children:[jsxRuntimeExports.jsx(Settings,{className:"h-4 w-4 text-foreground"}),jsxRuntimeExports.jsx("span",{className:"font-semibold",children:"Implementation Effort:"}),jsxRuntimeExports.jsx("span",{children:selectedRow?.TestImplementationCost??"N/A"})]}),jsxRuntimeExports.jsxs("div",{className:"flex items-center gap-2",children:[jsxRuntimeExports.jsx(Hash,{className:"h-4 w-4 text-foreground"}),jsxRuntimeExports.jsx("span",{className:"font-semibold",children:"Test ID:"}),jsxRuntimeExports.jsx("span",{children:selectedRow?.TestId??"N/A"})]}),selectedRow?.TestPillar!=="Infrastructure"&&jsxRuntimeExports.jsxs("div",{className:"flex items-center gap-2",children:[jsxRuntimeExports.jsx(BadgeCheck,{className:"h-4 w-4 text-foreground"}),jsxRuntimeExports.jsx("span",{className:"font-semibold",children:"License:"}),jsxRuntimeExports.jsx("div",{className:"flex items-center gap-1 flex-wrap",children:selectedRow?.TestMinimumLicense&&Array.isArray(selectedRow.TestMinimumLicense)?selectedRow.TestMinimumLicense.map((license,index2)=>jsxRuntimeExports.jsx("span",{className:"px-2 py-0.5 text-xs font-medium bg-purple-100 text-purple-800 dark:bg-purple-900 dark:text-purple-200 rounded-md",children:license},index2)):jsxRuntimeExports.jsx("span",{children:selectedRow?.TestMinimumLicense??"N/A"})})]})]})})})}),jsxRuntimeExports.jsxs("div",{className:"grid pt-10 gap-6",children:[jsxRuntimeExports.jsxs(Card,{children:[jsxRuntimeExports.jsx(CardHeader,{children:jsxRuntimeExports.jsx(CardTitle,{children:jsxRuntimeExports.jsxs("div",{className:"flex",children:[jsxRuntimeExports.jsx("span",{className:"pr-3",children:" Test result → "}),jsxRuntimeExports.jsx(StatusIcon,{Item:selectedRow})]})})}),jsxRuntimeExports.jsx(CardContent,{children:jsxRuntimeExports.jsx(Markdown,{className:"prose max-w-fit dark:prose-invert",remarkPlugins:[remarkGfm],rehypePlugins:mdRehypePlugins,children:selectedRow?.TestResult})})]}),jsxRuntimeExports.jsxs(Card,{children:[jsxRuntimeExports.jsx(CardHeader,{children:jsxRuntimeExports.jsx(CardTitle,{children:"What was checked"})}),jsxRuntimeExports.jsx(CardContent,{children:jsxRuntimeExports.jsx(Markdown,{className:"prose max-w-fit dark:prose-invert",remarkPlugins:[remarkGfm],rehypePlugins:mdRehypePlugins,children:selectedRow?.TestDescription})})]})]})]})})]})}__name(DataTable,"DataTable");const RISK_ORDER={Critical:0,High:1,Medium:2,Low:3,Unranked:4},STATUS_ORDER={Failed:0,Passed:1,Skipped:2,Planned:3},columns=[{accessorKey:"TestId",header:__name(({column})=>jsxRuntimeExports.jsxs(Button,{variant:"ghost",onClick:__name(()=>column.toggleSorting(column.getIsSorted()==="asc"),"onClick"),children:["ID",jsxRuntimeExports.jsx(ArrowUpDown,{className:"ml-2 h-4 w-4"})]}),"header"),cell:__name(({row})=>{const id=row.getValue("TestId"),display=id&&id.length>5?id.slice(-5):id;return jsxRuntimeExports.jsx("span",{title:id,children:display})},"cell"),meta:{label:"ID"}},{accessorKey:"TestTitle",meta:{label:"Name"},header:__name(({column})=>jsxRuntimeExports.jsxs(Button,{variant:"ghost",onClick:__name(()=>column.toggleSorting(column.getIsSorted()==="asc"),"onClick"),children:["Name",jsxRuntimeExports.jsx(ArrowUpDown,{className:"ml-2 h-4 w-4"})]}),"header")},{accessorKey:"TestCategory",meta:{label:"Category"},header:__name(({column})=>jsxRuntimeExports.jsxs(Button,{variant:"ghost",onClick:__name(()=>column.toggleSorting(column.getIsSorted()==="asc"),"onClick"),children:["Category",jsxRuntimeExports.jsx(ArrowUpDown,{className:"ml-2 h-4 w-4"})]}),"header"),cell:__name(({row})=>{const category=row.getValue("TestCategory");return category?jsxRuntimeExports.jsx("div",{className:"flex items-center",children:jsxRuntimeExports.jsx("span",{children:category})}):jsxRuntimeExports.jsx("div",{className:"flex items-center",children:jsxRuntimeExports.jsx("span",{className:"text-muted-foreground",children:"N/A"})})},"cell")},{accessorKey:"TestSfiPillar",meta:{label:"SFI Pillar"},header:__name(({column})=>jsxRuntimeExports.jsxs(Button,{variant:"ghost",onClick:__name(()=>column.toggleSorting(column.getIsSorted()==="asc"),"onClick"),children:["SFI Pillar",jsxRuntimeExports.jsx(ArrowUpDown,{className:"ml-2 h-4 w-4"})]}),"header"),cell:__name(({row})=>{const sfiPillar=row.getValue("TestSfiPillar");return sfiPillar?jsxRuntimeExports.jsx("div",{className:"flex items-center",children:jsxRuntimeExports.jsx("span",{className:"px-2 py-1 text-xs font-medium bg-blue-100 text-blue-800 rounded-md",children:sfiPillar})}):jsxRuntimeExports.jsx("div",{className:"flex items-center",children:jsxRuntimeExports.jsx("span",{className:"text-muted-foreground",children:"N/A"})})},"cell")},{accessorKey:"TestMinimumLicense",meta:{label:"Minimum License"},header:__name(({column})=>jsxRuntimeExports.jsxs(Button,{variant:"ghost",onClick:__name(()=>column.toggleSorting(column.getIsSorted()==="asc"),"onClick"),children:["Min. License",jsxRuntimeExports.jsx(ArrowUpDown,{className:"ml-2 h-4 w-4"})]}),"header"),cell:__name(({row})=>{const licensesValue=row.getValue("TestMinimumLicense");if(!licensesValue)return jsxRuntimeExports.jsx("div",{className:"flex items-center",children:jsxRuntimeExports.jsx("span",{className:"text-muted-foreground",children:"N/A"})});const licenses=Array.isArray(licensesValue)?licensesValue:[licensesValue];return licenses.length===0?jsxRuntimeExports.jsx("div",{className:"flex items-center",children:jsxRuntimeExports.jsx("span",{className:"text-muted-foreground",children:"N/A"})}):jsxRuntimeExports.jsx("div",{className:"flex items-center gap-1 flex-wrap",children:licenses.map((license,index2)=>jsxRuntimeExports.jsx("span",{className:"px-2 py-1 text-xs font-medium bg-purple-100 text-purple-800 rounded-md",children:license},index2))})},"cell")},{accessorKey:"TestImpact",meta:{label:"User Impact"},header:__name(({column})=>jsxRuntimeExports.jsxs(Button,{variant:"ghost",onClick:__name(()=>column.toggleSorting(column.getIsSorted()==="asc"),"onClick"),children:["User Impact",jsxRuntimeExports.jsx(ArrowUpDown,{className:"ml-2 h-4 w-4"})]}),"header"),cell:__name(({row})=>{const impact=impacts.find(impact2=>impact2.value===row.getValue("TestImpact"));return impact?jsxRuntimeExports.jsx("div",{className:"flex items-center",children:jsxRuntimeExports.jsx("span",{children:impact.label})}):null},"cell")},{accessorKey:"TestImplementationCost",meta:{label:"Implementation Effort"},header:__name(({column})=>jsxRuntimeExports.jsxs(Button,{variant:"ghost",onClick:__name(()=>column.toggleSorting(column.getIsSorted()==="asc"),"onClick"),children:["Imp. Effort",jsxRuntimeExports.jsx(ArrowUpDown,{className:"ml-2 h-4 w-4"})]}),"header"),cell:__name(({row})=>{const impact=impacts.find(impact2=>impact2.value===row.getValue("TestImplementationCost"));return impact?jsxRuntimeExports.jsx("div",{className:"flex items-center",children:jsxRuntimeExports.jsx("span",{children:impact.label})}):null},"cell")},{accessorKey:"TestRisk",meta:{label:"Risk"},sortingFn:__name((rowA,rowB,columnId)=>{const a2=RISK_ORDER[rowA.getValue(columnId)]??Number.POSITIVE_INFINITY,b2=RISK_ORDER[rowB.getValue(columnId)]??Number.POSITIVE_INFINITY;return a2-b2},"sortingFn"),header:__name(({column})=>jsxRuntimeExports.jsxs(Button,{variant:"ghost",onClick:__name(()=>column.toggleSorting(column.getIsSorted()==="asc"),"onClick"),children:["Risk",jsxRuntimeExports.jsx(ArrowUpDown,{className:"ml-2 h-4 w-4"})]}),"header"),cell:__name(({row})=>{const impact=impacts.find(impact2=>impact2.value===row.getValue("TestRisk"));return impact?jsxRuntimeExports.jsxs("div",{className:"flex items-center",children:[impact.icon&&jsxRuntimeExports.jsx(impact.icon,{className:"mr-2 h-4 w-4 text-muted-foreground"}),jsxRuntimeExports.jsx("span",{children:impact.label})]}):null},"cell")},{accessorKey:"TestStatus",meta:{label:"Status"},sortingFn:__name((rowA,rowB,columnId)=>{const a2=STATUS_ORDER[rowA.getValue(columnId)]??3,b2=STATUS_ORDER[rowB.getValue(columnId)]??3;return a2-b2},"sortingFn"),header:__name(({column})=>jsxRuntimeExports.jsxs(Button,{variant:"ghost",onClick:__name(()=>column.toggleSorting(column.getIsSorted()==="asc"),"onClick"),children:["Status",jsxRuntimeExports.jsx(ArrowUpDown,{className:"ml-2 h-4 w-4"})]}),"header"),cell:__name(({row})=>jsxRuntimeExports.jsx(StatusIcon,{Item:row.original}),"cell")}];function Identity(){return jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment,{children:[jsxRuntimeExports.jsx(PageHeader,{children:jsxRuntimeExports.jsx(PageHeaderHeading,{children:"Identity"})}),jsxRuntimeExports.jsxs(Card,{children:[jsxRuntimeExports.jsxs(CardHeader,{children:[jsxRuntimeExports.jsx(CardTitle,{className:"mb-3",children:"Assessment results"}),jsxRuntimeExports.jsxs(CardDescription,{children:["The results presented below are based on the security principles detailed in the"," ",jsxRuntimeExports.jsx("a",{href:"https://learn.microsoft.com/en-us/entra/fundamentals/configure-security",target:"_blank",rel:"noopener noreferrer",className:"text-primary font-medium underline underline-offset-4 hover:underline",children:"Configuring Microsoft Entra for increased security"})," ","guide."]})]}),jsxRuntimeExports.jsx(CardContent,{className:"gap-4 px-4 pb-4 pt-1",children:jsxRuntimeExports.jsx(DataTable,{columns,data:reportData.Tests,pillar:"Identity"})})]})]})}__name(Identity,"Identity");var TABS_NAME="Tabs",[createTabsContext]=createContextScope$1(TABS_NAME,[createRovingFocusGroupScope]),useRovingFocusGroupScope=createRovingFocusGroupScope(),[TabsProvider,useTabsContext]=createTabsContext(TABS_NAME),Tabs$1=reactExports.forwardRef((props,forwardedRef)=>{const{__scopeTabs,value:valueProp,onValueChange,defaultValue,orientation="horizontal",dir,activationMode="automatic",...tabsProps}=props,direction=useDirection(dir),[value2,setValue]=useControllableState({prop:valueProp,onChange:onValueChange,defaultProp:defaultValue??"",caller:TABS_NAME});return jsxRuntimeExports.jsx(TabsProvider,{scope:__scopeTabs,baseId:useId(),value:value2,onValueChange:setValue,orientation,dir:direction,activationMode,children:jsxRuntimeExports.jsx(Primitive$2.div,{dir:direction,"data-orientation":orientation,...tabsProps,ref:forwardedRef})})});Tabs$1.displayName=TABS_NAME;var TAB_LIST_NAME="TabsList",TabsList$1=reactExports.forwardRef((props,forwardedRef)=>{const{__scopeTabs,loop:loop2=!0,...listProps}=props,context=useTabsContext(TAB_LIST_NAME,__scopeTabs),rovingFocusGroupScope=useRovingFocusGroupScope(__scopeTabs);return jsxRuntimeExports.jsx(Root$4,{asChild:!0,...rovingFocusGroupScope,orientation:context.orientation,dir:context.dir,loop:loop2,children:jsxRuntimeExports.jsx(Primitive$2.div,{role:"tablist","aria-orientation":context.orientation,...listProps,ref:forwardedRef})})});TabsList$1.displayName=TAB_LIST_NAME;var TRIGGER_NAME="TabsTrigger",TabsTrigger$1=reactExports.forwardRef((props,forwardedRef)=>{const{__scopeTabs,value:value2,disabled=!1,...triggerProps}=props,context=useTabsContext(TRIGGER_NAME,__scopeTabs),rovingFocusGroupScope=useRovingFocusGroupScope(__scopeTabs),triggerId=makeTriggerId(context.baseId,value2),contentId=makeContentId(context.baseId,value2),isSelected=value2===context.value;return jsxRuntimeExports.jsx(Item$1,{asChild:!0,...rovingFocusGroupScope,focusable:!disabled,active:isSelected,children:jsxRuntimeExports.jsx(Primitive$2.button,{type:"button",role:"tab","aria-selected":isSelected,"aria-controls":contentId,"data-state":isSelected?"active":"inactive","data-disabled":disabled?"":void 0,disabled,id:triggerId,...triggerProps,ref:forwardedRef,onMouseDown:composeEventHandlers(props.onMouseDown,event=>{!disabled&&event.button===0&&event.ctrlKey===!1?context.onValueChange(value2):event.preventDefault()}),onKeyDown:composeEventHandlers(props.onKeyDown,event=>{[" ","Enter"].includes(event.key)&&context.onValueChange(value2)}),onFocus:composeEventHandlers(props.onFocus,()=>{const isAutomaticActivation=context.activationMode!=="manual";!isSelected&&!disabled&&isAutomaticActivation&&context.onValueChange(value2)})})})});TabsTrigger$1.displayName=TRIGGER_NAME;var CONTENT_NAME="TabsContent",TabsContent$1=reactExports.forwardRef((props,forwardedRef)=>{const{__scopeTabs,value:value2,forceMount,children:children2,...contentProps}=props,context=useTabsContext(CONTENT_NAME,__scopeTabs),triggerId=makeTriggerId(context.baseId,value2),contentId=makeContentId(context.baseId,value2),isSelected=value2===context.value,isMountAnimationPreventedRef=reactExports.useRef(isSelected);return reactExports.useEffect(()=>{const rAF=requestAnimationFrame(()=>isMountAnimationPreventedRef.current=!1);return()=>cancelAnimationFrame(rAF)},[]),jsxRuntimeExports.jsx(Presence,{present:forceMount||isSelected,children:__name(({present})=>jsxRuntimeExports.jsx(Primitive$2.div,{"data-state":isSelected?"active":"inactive","data-orientation":context.orientation,role:"tabpanel","aria-labelledby":triggerId,hidden:!present,id:contentId,tabIndex:0,...contentProps,ref:forwardedRef,style:{...props.style,animationDuration:isMountAnimationPreventedRef.current?"0s":void 0},children:present&&children2}),"children")})});TabsContent$1.displayName=CONTENT_NAME;function makeTriggerId(baseId,value2){return`${baseId}-trigger-${value2}`}__name(makeTriggerId,"makeTriggerId");function makeContentId(baseId,value2){return`${baseId}-content-${value2}`}__name(makeContentId,"makeContentId");var Root2=Tabs$1,List=TabsList$1,Trigger=TabsTrigger$1,Content=TabsContent$1;const Tabs=Root2,TabsList=reactExports.forwardRef(({className,...props},ref)=>jsxRuntimeExports.jsx(List,{ref,className:cn$2("inline-flex h-10 items-center justify-center rounded-md bg-muted p-1 text-muted-foreground",className),...props}));TabsList.displayName=List.displayName;const TabsTrigger=reactExports.forwardRef(({className,...props},ref)=>jsxRuntimeExports.jsx(Trigger,{ref,className:cn$2("inline-flex items-center justify-center whitespace-nowrap rounded-sm px-3 py-1.5 text-sm font-medium ring-offset-background transition-all focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50 data-[state=active]:bg-background data-[state=active]:text-foreground data-[state=active]:shadow-sm",className),...props}));TabsTrigger.displayName=Trigger.displayName;const TabsContent=reactExports.forwardRef(({className,...props},ref)=>jsxRuntimeExports.jsx(Content,{ref,className:cn$2("mt-2 ring-offset-background focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2",className),...props}));TabsContent.displayName=Content.displayName;function DevicesConfig(){const enrollment=reportData.TenantInfo?.ConfigWindowsEnrollment,enrollmentRestrictions=reportData.TenantInfo?.ConfigDeviceEnrollmentRestriction,compliancePolicies=reportData.TenantInfo?.ConfigDeviceCompliancePolicies,appProtectionPolicies=reportData.TenantInfo?.ConfigDeviceAppProtectionPolicies;return jsxRuntimeExports.jsxs("div",{className:"p-4",children:[jsxRuntimeExports.jsx("h2",{className:"text-lg font-semibold mb-4",children:"Windows automatic enrollment"}),jsxRuntimeExports.jsx("p",{className:"text-sm text-gray-600 mb-4",children:"Configure Windows devices to enroll when they join or register with Azure Active Directory. We recommend setting this to all instead of selected groups and using enrollment restrictions to configure the intake of users."}),enrollment&&enrollment.length>0?jsxRuntimeExports.jsxs(Table,{children:[jsxRuntimeExports.jsx(TableHeader,{children:jsxRuntimeExports.jsxs(TableRow,{children:[jsxRuntimeExports.jsx(TableHead,{children:"Type"}),jsxRuntimeExports.jsx(TableHead,{children:"Policy Name"}),jsxRuntimeExports.jsx(TableHead,{children:"Applies To"}),jsxRuntimeExports.jsx(TableHead,{children:"Groups"})]})}),jsxRuntimeExports.jsx(TableBody,{children:enrollment.map((row,idx)=>jsxRuntimeExports.jsxs(TableRow,{children:[jsxRuntimeExports.jsx(TableCell,{children:row.Type}),jsxRuntimeExports.jsx(TableCell,{children:row.PolicyName}),jsxRuntimeExports.jsx(TableCell,{children:row.AppliesTo}),jsxRuntimeExports.jsx(TableCell,{children:row.Groups})]},idx))})]}):jsxRuntimeExports.jsx("p",{children:"No Windows enrollment configuration found."}),jsxRuntimeExports.jsx("h2",{className:"text-lg font-semibold mb-4 mt-8",children:"Enrollment device platform restrictions"}),jsxRuntimeExports.jsx("p",{className:"text-sm text-gray-600 mb-4",children:"Device enrollment restrictions let you restrict devices from enrolling in Intune based on certain device attributes. Device platform restrictions restrict devices based on device platform, version, manufacturer, or ownership type."}),enrollmentRestrictions&&enrollmentRestrictions.length>0?jsxRuntimeExports.jsxs(Table,{children:[jsxRuntimeExports.jsx(TableHeader,{children:jsxRuntimeExports.jsxs(TableRow,{children:[jsxRuntimeExports.jsx(TableHead,{children:"Platform"}),jsxRuntimeExports.jsx(TableHead,{children:"Priority"}),jsxRuntimeExports.jsx(TableHead,{children:"Name"}),jsxRuntimeExports.jsx(TableHead,{children:"MDM"}),jsxRuntimeExports.jsx(TableHead,{children:"Min Ver"}),jsxRuntimeExports.jsx(TableHead,{children:"Max Ver"}),jsxRuntimeExports.jsx(TableHead,{children:"Personally owned"}),jsxRuntimeExports.jsx(TableHead,{children:"Blocked manuf."}),jsxRuntimeExports.jsx(TableHead,{children:"Scope"}),jsxRuntimeExports.jsx(TableHead,{children:"Assigned to"})]})}),jsxRuntimeExports.jsx(TableBody,{children:enrollmentRestrictions.map((row,idx)=>jsxRuntimeExports.jsxs(TableRow,{children:[jsxRuntimeExports.jsx(TableCell,{children:row.Platform}),jsxRuntimeExports.jsx(TableCell,{children:row.Priority}),jsxRuntimeExports.jsx(TableCell,{children:row.Name}),jsxRuntimeExports.jsx(TableCell,{children:row.MDM}),jsxRuntimeExports.jsx(TableCell,{children:row.MinVer}),jsxRuntimeExports.jsx(TableCell,{children:row.MaxVer}),jsxRuntimeExports.jsx(TableCell,{children:row.PersonallyOwned}),jsxRuntimeExports.jsx(TableCell,{children:row.BlockedManufacturers}),jsxRuntimeExports.jsx(TableCell,{children:row.Scope}),jsxRuntimeExports.jsx(TableCell,{children:row.AssignedTo})]},idx))})]}):jsxRuntimeExports.jsx("p",{children:"No device enrollment restrictions found."}),jsxRuntimeExports.jsx("h2",{className:"text-lg font-semibold mb-4 mt-8",children:"Compliance policies"}),jsxRuntimeExports.jsx("p",{className:"text-sm text-gray-600 mb-4",children:"Device compliance policies define the rules and settings that devices must meet to be considered compliant. These policies help ensure that devices accessing organizational resources meet minimum security requirements."}),compliancePolicies&&compliancePolicies.length>0?jsxRuntimeExports.jsx("div",{className:"overflow-x-auto",children:jsxRuntimeExports.jsxs(Table,{children:[jsxRuntimeExports.jsx(TableHeader,{children:jsxRuntimeExports.jsxs(TableRow,{children:[jsxRuntimeExports.jsx(TableHead,{className:"font-semibold",children:"Setting"}),compliancePolicies.map((policy,idx)=>jsxRuntimeExports.jsx(TableHead,{className:"min-w-[150px]",children:policy.PolicyName},idx))]})}),jsxRuntimeExports.jsxs(TableBody,{children:[jsxRuntimeExports.jsxs(TableRow,{children:[jsxRuntimeExports.jsx(TableCell,{className:"font-medium",children:"Platform"}),compliancePolicies.map((policy,idx)=>jsxRuntimeExports.jsx(TableCell,{children:policy.Platform},idx))]}),jsxRuntimeExports.jsxs(TableRow,{children:[jsxRuntimeExports.jsx(TableCell,{className:"font-medium",children:"Defender ATP"}),compliancePolicies.map((policy,idx)=>jsxRuntimeExports.jsx(TableCell,{children:policy.DefenderForEndPoint},idx))]}),jsxRuntimeExports.jsxs(TableRow,{children:[jsxRuntimeExports.jsx(TableCell,{className:"font-medium",children:"Min OS Version"}),compliancePolicies.map((policy,idx)=>jsxRuntimeExports.jsx(TableCell,{children:policy.MinOsVersion},idx))]}),jsxRuntimeExports.jsxs(TableRow,{children:[jsxRuntimeExports.jsx(TableCell,{className:"font-medium",children:"Max OS Version"}),compliancePolicies.map((policy,idx)=>jsxRuntimeExports.jsx(TableCell,{children:policy.MaxOsVersion},idx))]}),jsxRuntimeExports.jsxs(TableRow,{children:[jsxRuntimeExports.jsx(TableCell,{className:"font-medium",children:"Require Password"}),compliancePolicies.map((policy,idx)=>jsxRuntimeExports.jsx(TableCell,{children:policy.RequirePswd},idx))]}),jsxRuntimeExports.jsxs(TableRow,{children:[jsxRuntimeExports.jsx(TableCell,{className:"font-medium",children:"Min Password Length"}),compliancePolicies.map((policy,idx)=>jsxRuntimeExports.jsx(TableCell,{children:policy.MinPswdLength},idx))]}),jsxRuntimeExports.jsxs(TableRow,{children:[jsxRuntimeExports.jsx(TableCell,{className:"font-medium",children:"Password Type"}),compliancePolicies.map((policy,idx)=>jsxRuntimeExports.jsx(TableCell,{children:policy.PasswordType},idx))]}),jsxRuntimeExports.jsxs(TableRow,{children:[jsxRuntimeExports.jsx(TableCell,{className:"font-medium",children:"Password Expiry Days"}),compliancePolicies.map((policy,idx)=>jsxRuntimeExports.jsx(TableCell,{children:policy.PswdExpiryDays},idx))]}),jsxRuntimeExports.jsxs(TableRow,{children:[jsxRuntimeExports.jsx(TableCell,{className:"font-medium",children:"Previous Passwords Blocked"}),compliancePolicies.map((policy,idx)=>jsxRuntimeExports.jsx(TableCell,{children:policy.CountOfPreviousPswdToBlock},idx))]}),jsxRuntimeExports.jsxs(TableRow,{children:[jsxRuntimeExports.jsx(TableCell,{className:"font-medium",children:"Max Inactivity Min"}),compliancePolicies.map((policy,idx)=>jsxRuntimeExports.jsx(TableCell,{children:policy.MaxInactivityMin},idx))]}),jsxRuntimeExports.jsxs(TableRow,{children:[jsxRuntimeExports.jsx(TableCell,{className:"font-medium",children:"Require Encryption"}),compliancePolicies.map((policy,idx)=>jsxRuntimeExports.jsx(TableCell,{children:policy.RequireEncryption},idx))]}),jsxRuntimeExports.jsxs(TableRow,{children:[jsxRuntimeExports.jsx(TableCell,{className:"font-medium",children:"Rooted/Jailbroken"}),compliancePolicies.map((policy,idx)=>jsxRuntimeExports.jsx(TableCell,{children:policy.RootedJailbrokenDevices},idx))]}),jsxRuntimeExports.jsxs(TableRow,{children:[jsxRuntimeExports.jsx(TableCell,{className:"font-medium",children:"Max Threat Level"}),compliancePolicies.map((policy,idx)=>jsxRuntimeExports.jsx(TableCell,{children:policy.MaxDeviceThreatLevel},idx))]}),jsxRuntimeExports.jsxs(TableRow,{children:[jsxRuntimeExports.jsx(TableCell,{className:"font-medium",children:"Require Firewall"}),compliancePolicies.map((policy,idx)=>jsxRuntimeExports.jsx(TableCell,{children:policy.RequireFirewall},idx))]}),jsxRuntimeExports.jsxs(TableRow,{children:[jsxRuntimeExports.jsx(TableCell,{className:"font-medium",children:"Push Notification Days"}),compliancePolicies.map((policy,idx)=>jsxRuntimeExports.jsx(TableCell,{children:policy.ActionForNoncomplianceDaysPushNotification},idx))]}),jsxRuntimeExports.jsxs(TableRow,{children:[jsxRuntimeExports.jsx(TableCell,{className:"font-medium",children:"Send Email Days"}),compliancePolicies.map((policy,idx)=>jsxRuntimeExports.jsx(TableCell,{children:policy.ActionForNoncomplianceDaysSendEmail},idx))]}),jsxRuntimeExports.jsxs(TableRow,{children:[jsxRuntimeExports.jsx(TableCell,{className:"font-medium",children:"Remote Lock Days"}),compliancePolicies.map((policy,idx)=>jsxRuntimeExports.jsx(TableCell,{children:policy.ActionForNoncomplianceDaysRemoteLock},idx))]}),jsxRuntimeExports.jsxs(TableRow,{children:[jsxRuntimeExports.jsx(TableCell,{className:"font-medium",children:"Block Days"}),compliancePolicies.map((policy,idx)=>jsxRuntimeExports.jsx(TableCell,{children:policy.ActionForNoncomplianceDaysBlock},idx))]}),jsxRuntimeExports.jsxs(TableRow,{children:[jsxRuntimeExports.jsx(TableCell,{className:"font-medium",children:"Retire Days"}),compliancePolicies.map((policy,idx)=>jsxRuntimeExports.jsx(TableCell,{children:policy.ActionForNoncomplianceDaysRetire},idx))]}),jsxRuntimeExports.jsxs(TableRow,{children:[jsxRuntimeExports.jsx(TableCell,{className:"font-medium",children:"Scope"}),compliancePolicies.map((policy,idx)=>jsxRuntimeExports.jsx(TableCell,{children:policy.Scope},idx))]})]})]})}):jsxRuntimeExports.jsx("p",{children:"No device compliance policies found."}),jsxRuntimeExports.jsx("h2",{className:"text-lg font-semibold mb-4 mt-8",children:"App protection policies"}),jsxRuntimeExports.jsx("p",{className:"text-sm text-gray-600 mb-4",children:`App protection policies (APP) are rules that ensure an organization's data remains safe or contained in a managed app. A policy can be a rule that is enforced when the user attempts to access or move "corporate" data, or a set of actions that are prohibited or monitored when the user is inside the app. A managed app is an app that has app protection policies applied to it, and can be managed by Intune.`}),appProtectionPolicies&&appProtectionPolicies.length>0?jsxRuntimeExports.jsx("div",{className:"overflow-x-auto",children:jsxRuntimeExports.jsxs(Table,{children:[jsxRuntimeExports.jsx(TableHeader,{children:jsxRuntimeExports.jsxs(TableRow,{children:[jsxRuntimeExports.jsx(TableHead,{className:"font-semibold",children:"Setting"}),appProtectionPolicies.map((policy,idx)=>jsxRuntimeExports.jsx(TableHead,{className:"min-w-[150px]",children:policy.Name},idx))]})}),jsxRuntimeExports.jsxs(TableBody,{children:[jsxRuntimeExports.jsxs(TableRow,{children:[jsxRuntimeExports.jsx(TableCell,{className:"font-medium",children:"Platform"}),appProtectionPolicies.map((policy,idx)=>jsxRuntimeExports.jsx(TableCell,{children:policy.Platform},idx))]}),jsxRuntimeExports.jsxs(TableRow,{children:[jsxRuntimeExports.jsx(TableCell,{className:"font-medium",children:"Public Apps"}),appProtectionPolicies.map((policy,idx)=>jsxRuntimeExports.jsx(TableCell,{children:policy.AppsPublic},idx))]}),jsxRuntimeExports.jsxs(TableRow,{children:[jsxRuntimeExports.jsx(TableCell,{className:"font-medium",children:"Custom Apps"}),appProtectionPolicies.map((policy,idx)=>jsxRuntimeExports.jsx(TableCell,{children:policy.AppsCustom},idx))]}),jsxRuntimeExports.jsxs(TableRow,{children:[jsxRuntimeExports.jsx(TableCell,{className:"font-medium",children:"Backup to Cloud"}),appProtectionPolicies.map((policy,idx)=>jsxRuntimeExports.jsx(TableCell,{children:policy.BackupOrgDataToICloudOrGoogle},idx))]}),jsxRuntimeExports.jsxs(TableRow,{children:[jsxRuntimeExports.jsx(TableCell,{className:"font-medium",children:"Send Data to Other Apps"}),appProtectionPolicies.map((policy,idx)=>jsxRuntimeExports.jsx(TableCell,{children:policy.SendOrgDataToOtherApps},idx))]}),jsxRuntimeExports.jsxs(TableRow,{children:[jsxRuntimeExports.jsx(TableCell,{className:"font-medium",children:"Apps to Exempt"}),appProtectionPolicies.map((policy,idx)=>jsxRuntimeExports.jsx(TableCell,{children:policy.AppsToExempt},idx))]}),jsxRuntimeExports.jsxs(TableRow,{children:[jsxRuntimeExports.jsx(TableCell,{className:"font-medium",children:"Save Copies"}),appProtectionPolicies.map((policy,idx)=>jsxRuntimeExports.jsx(TableCell,{children:policy.SaveCopiesOfOrgData},idx))]}),jsxRuntimeExports.jsxs(TableRow,{children:[jsxRuntimeExports.jsx(TableCell,{className:"font-medium",children:"Allow Save to Selected Services"}),appProtectionPolicies.map((policy,idx)=>jsxRuntimeExports.jsx(TableCell,{children:policy.AllowUserToSaveCopiesToSelectedServices},idx))]}),jsxRuntimeExports.jsxs(TableRow,{children:[jsxRuntimeExports.jsx(TableCell,{className:"font-medium",children:"Transfer Telecom Data To"}),appProtectionPolicies.map((policy,idx)=>jsxRuntimeExports.jsx(TableCell,{children:policy.DataProtectionTransferTelecommunicationDataTo},idx))]}),jsxRuntimeExports.jsxs(TableRow,{children:[jsxRuntimeExports.jsx(TableCell,{className:"font-medium",children:"Receive Data From Other Apps"}),appProtectionPolicies.map((policy,idx)=>jsxRuntimeExports.jsx(TableCell,{children:policy.DataProtectionReceiveDataFromOtherApps},idx))]}),jsxRuntimeExports.jsxs(TableRow,{children:[jsxRuntimeExports.jsx(TableCell,{className:"font-medium",children:"Rooted/Jailbroken Devices"}),appProtectionPolicies.map((policy,idx)=>jsxRuntimeExports.jsx(TableCell,{children:policy.ConditionalLaunchDeviceRootedJailbrokenDevices},idx))]}),jsxRuntimeExports.jsxs(TableRow,{children:[jsxRuntimeExports.jsx(TableCell,{className:"font-medium",children:"Scope"}),appProtectionPolicies.map((policy,idx)=>jsxRuntimeExports.jsx(TableCell,{children:policy.Scope},idx))]})]})]})}):jsxRuntimeExports.jsx("p",{children:"No app protection policies found."})]})}__name(DevicesConfig,"DevicesConfig");function Devices(){return jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment,{children:[jsxRuntimeExports.jsx(PageHeader,{children:jsxRuntimeExports.jsx(PageHeaderHeading,{children:"Devices"})}),jsxRuntimeExports.jsxs(Tabs,{defaultValue:"assessment",className:"w-full",children:[jsxRuntimeExports.jsxs(TabsList,{className:"grid w-full grid-cols-2",children:[jsxRuntimeExports.jsxs(TabsTrigger,{value:"assessment",className:"flex items-center gap-2",children:[jsxRuntimeExports.jsx(ChartColumn,{className:"h-4 w-4"}),"Assessment results"]}),jsxRuntimeExports.jsxs(TabsTrigger,{value:"config",className:"flex items-center gap-2",children:[jsxRuntimeExports.jsx(Settings,{className:"h-4 w-4"}),"Config"]})]}),jsxRuntimeExports.jsx(TabsContent,{value:"assessment",className:"space-y-4",children:jsxRuntimeExports.jsxs(Card,{children:[jsxRuntimeExports.jsxs(CardHeader,{children:[jsxRuntimeExports.jsx(CardTitle,{className:"mb-3",children:"Assessment results"}),jsxRuntimeExports.jsxs(CardDescription,{children:["The results presented below are based on the security principles detailed in the"," ",jsxRuntimeExports.jsx("a",{href:"https://learn.microsoft.com/intune/intune-service/protect/zero-trust-configure-security",target:"_blank",rel:"noopener noreferrer",className:"text-primary font-medium underline underline-offset-4 hover:underline",children:"Configuring Microsoft Intune for increased security"})," ","guide."]})]}),jsxRuntimeExports.jsx(CardContent,{className:"gap-4 px-4 pb-4 pt-1",children:jsxRuntimeExports.jsx(DataTable,{columns,data:reportData.Tests,pillar:"Devices"})})]})}),jsxRuntimeExports.jsx(TabsContent,{value:"config",className:"space-y-4",children:jsxRuntimeExports.jsxs(Card,{children:[jsxRuntimeExports.jsxs(CardHeader,{children:[jsxRuntimeExports.jsx(CardTitle,{className:"mb-3",children:"Device Configuration"}),jsxRuntimeExports.jsx(CardDescription,{children:"Device configuration settings and options."})]}),jsxRuntimeExports.jsx(CardContent,{className:"gap-4 px-4 pb-4 pt-1",children:jsxRuntimeExports.jsx(DevicesConfig,{})})]})})]})]})}__name(Devices,"Devices");function Apps(){return jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment,{children:[jsxRuntimeExports.jsx(PageHeader,{children:jsxRuntimeExports.jsx(PageHeaderHeading,{children:"Apps"})}),jsxRuntimeExports.jsx(Card,{children:jsxRuntimeExports.jsxs(CardHeader,{children:[jsxRuntimeExports.jsx(CardTitle,{children:"Coming soon"}),jsxRuntimeExports.jsx(CardDescription,{children:"He that can have patience can have what he will. - Benjamin Franklin"})]})})]})}__name(Apps,"Apps");function Network(){return jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment,{children:[jsxRuntimeExports.jsx(PageHeader,{children:jsxRuntimeExports.jsx(PageHeaderHeading,{children:"Network"})}),jsxRuntimeExports.jsxs(Card,{children:[jsxRuntimeExports.jsxs(CardHeader,{children:[jsxRuntimeExports.jsx(CardTitle,{className:"mb-3",children:"Assessment results"}),jsxRuntimeExports.jsxs(CardDescription,{children:["The results presented below are based on the security principles detailed in the"," ",jsxRuntimeExports.jsx("a",{href:"https://learn.microsoft.com/en-us/entra/fundamentals/configure-security",target:"_blank",rel:"noopener noreferrer",className:"text-primary font-medium underline underline-offset-4 hover:underline",children:"Configuring Microsoft Entra and Azure for increased security"})," ","guide."]})]}),jsxRuntimeExports.jsx(CardContent,{className:"gap-4 px-4 pb-4 pt-1",children:jsxRuntimeExports.jsx(DataTable,{columns,data:reportData.Tests,pillar:"Network"})})]})]})}__name(Network,"Network");function Infrastructure(){return jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment,{children:[jsxRuntimeExports.jsx(PageHeader,{children:jsxRuntimeExports.jsx(PageHeaderHeading,{children:"Infrastructure"})}),jsxRuntimeExports.jsxs(Card,{children:[jsxRuntimeExports.jsxs(CardHeader,{children:[jsxRuntimeExports.jsx(CardTitle,{className:"mb-3",children:"Assessment results"}),jsxRuntimeExports.jsx(CardDescription,{children:"The results presented below are based on Zero Trust security principles for infrastructure."})]}),jsxRuntimeExports.jsx(CardContent,{className:"gap-4 px-4 pb-4 pt-1",children:jsxRuntimeExports.jsx(DataTable,{columns,data:reportData.Tests,pillar:"Infrastructure"})})]})]})}__name(Infrastructure,"Infrastructure");function Data(){return jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment,{children:[jsxRuntimeExports.jsx(PageHeader,{children:jsxRuntimeExports.jsx(PageHeaderHeading,{children:"Data"})}),jsxRuntimeExports.jsxs(Card,{children:[jsxRuntimeExports.jsxs(CardHeader,{children:[jsxRuntimeExports.jsx(CardTitle,{className:"mb-3",children:"Assessment results"}),jsxRuntimeExports.jsxs(CardDescription,{children:["The results presented below are based on the security principles detailed in the"," ",jsxRuntimeExports.jsx("a",{href:"https://learn.microsoft.com/en-us/purview/configure-security",target:"_blank",rel:"noopener noreferrer",className:"text-primary font-medium underline underline-offset-4 hover:underline",children:"Configuring Microsoft Purview for increased security"})," ","guide."]})]}),jsxRuntimeExports.jsx(CardContent,{className:"gap-4 px-4 pb-4 pt-1",children:jsxRuntimeExports.jsx(DataTable,{columns,data:reportData.Tests,pillar:"Data"})})]})]})}__name(Data,"Data");function SecOps(){return jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment,{children:[jsxRuntimeExports.jsx(PageHeader,{children:jsxRuntimeExports.jsx(PageHeaderHeading,{children:"Security Operations"})}),jsxRuntimeExports.jsxs(Card,{children:[jsxRuntimeExports.jsxs(CardHeader,{children:[jsxRuntimeExports.jsx(CardTitle,{className:"mb-3",children:"Assessment results"}),jsxRuntimeExports.jsx(CardDescription,{children:"The results presented below are based on Zero Trust security principles for security operations."})]}),jsxRuntimeExports.jsx(CardContent,{className:"gap-4 px-4 pb-4 pt-1",children:jsxRuntimeExports.jsx(DataTable,{columns,data:reportData.Tests,pillar:"SecOps"})})]})]})}__name(SecOps,"SecOps");function AI(){return jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment,{children:[jsxRuntimeExports.jsx(PageHeader,{children:jsxRuntimeExports.jsx(PageHeaderHeading,{children:"AI"})}),jsxRuntimeExports.jsxs(Card,{children:[jsxRuntimeExports.jsxs(CardHeader,{children:[jsxRuntimeExports.jsx(CardTitle,{className:"mb-3",children:"Assessment results"}),jsxRuntimeExports.jsx(CardDescription,{children:"The results presented below are based on Zero Trust security principles for AI workloads."})]}),jsxRuntimeExports.jsx(CardContent,{className:"gap-4 px-4 pb-4 pt-1",children:jsxRuntimeExports.jsx(DataTable,{columns,data:reportData.Tests,pillar:"AI"})})]})]})}__name(AI,"AI");var define_global_default={basename:""};const router=createHashRouter([{path:"/",element:jsxRuntimeExports.jsx(Applayout,{}),children:[{path:"",element:jsxRuntimeExports.jsx(Dashboard,{})},{path:"identity",element:jsxRuntimeExports.jsx(Identity,{})},{path:"devices",element:jsxRuntimeExports.jsx(Devices,{})},{path:"apps",element:jsxRuntimeExports.jsx(Apps,{})},{path:"network",element:jsxRuntimeExports.jsx(Network,{})},{path:"infrastructure",element:jsxRuntimeExports.jsx(Infrastructure,{})},{path:"data",element:jsxRuntimeExports.jsx(Data,{})},{path:"secops",element:jsxRuntimeExports.jsx(SecOps,{})},{path:"ai",element:jsxRuntimeExports.jsx(AI,{})}]},{path:"*",element:jsxRuntimeExports.jsx(NoMatch,{})}],{basename:define_global_default.basename});function __insertCSS(code2){if(typeof document>"u")return;let head=document.head||document.getElementsByTagName("head")[0],style2=document.createElement("style");style2.type="text/css",head.appendChild(style2),style2.styleSheet?style2.styleSheet.cssText=code2:style2.appendChild(document.createTextNode(code2))}__name(__insertCSS,"__insertCSS");const getAsset=__name(type=>{switch(type){case"success":return SuccessIcon;case"info":return InfoIcon;case"warning":return WarningIcon;case"error":return ErrorIcon;default:return null}},"getAsset"),bars=Array(12).fill(0),Loader=__name(({visible,className})=>React.createElement("div",{className:["sonner-loading-wrapper",className].filter(Boolean).join(" "),"data-visible":visible},React.createElement("div",{className:"sonner-spinner"},bars.map((_2,i2)=>React.createElement("div",{className:"sonner-loading-bar",key:`spinner-bar-${i2}`})))),"Loader"),SuccessIcon=React.createElement("svg",{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 20 20",fill:"currentColor",height:"20",width:"20"},React.createElement("path",{fillRule:"evenodd",d:"M10 18a8 8 0 100-16 8 8 0 000 16zm3.857-9.809a.75.75 0 00-1.214-.882l-3.483 4.79-1.88-1.88a.75.75 0 10-1.06 1.061l2.5 2.5a.75.75 0 001.137-.089l4-5.5z",clipRule:"evenodd"})),WarningIcon=React.createElement("svg",{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 24 24",fill:"currentColor",height:"20",width:"20"},React.createElement("path",{fillRule:"evenodd",d:"M9.401 3.003c1.155-2 4.043-2 5.197 0l7.355 12.748c1.154 2-.29 4.5-2.599 4.5H4.645c-2.309 0-3.752-2.5-2.598-4.5L9.4 3.003zM12 8.25a.75.75 0 01.75.75v3.75a.75.75 0 01-1.5 0V9a.75.75 0 01.75-.75zm0 8.25a.75.75 0 100-1.5.75.75 0 000 1.5z",clipRule:"evenodd"})),InfoIcon=React.createElement("svg",{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 20 20",fill:"currentColor",height:"20",width:"20"},React.createElement("path",{fillRule:"evenodd",d:"M18 10a8 8 0 11-16 0 8 8 0 0116 0zm-7-4a1 1 0 11-2 0 1 1 0 012 0zM9 9a.75.75 0 000 1.5h.253a.25.25 0 01.244.304l-.459 2.066A1.75 1.75 0 0010.747 15H11a.75.75 0 000-1.5h-.253a.25.25 0 01-.244-.304l.459-2.066A1.75 1.75 0 009.253 9H9z",clipRule:"evenodd"})),ErrorIcon=React.createElement("svg",{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 20 20",fill:"currentColor",height:"20",width:"20"},React.createElement("path",{fillRule:"evenodd",d:"M18 10a8 8 0 11-16 0 8 8 0 0116 0zm-8-5a.75.75 0 01.75.75v4.5a.75.75 0 01-1.5 0v-4.5A.75.75 0 0110 5zm0 10a1 1 0 100-2 1 1 0 000 2z",clipRule:"evenodd"})),CloseIcon=React.createElement("svg",{xmlns:"http://www.w3.org/2000/svg",width:"12",height:"12",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"1.5",strokeLinecap:"round",strokeLinejoin:"round"},React.createElement("line",{x1:"18",y1:"6",x2:"6",y2:"18"}),React.createElement("line",{x1:"6",y1:"6",x2:"18",y2:"18"})),useIsDocumentHidden=__name(()=>{const[isDocumentHidden,setIsDocumentHidden]=React.useState(document.hidden);return React.useEffect(()=>{const callback=__name(()=>{setIsDocumentHidden(document.hidden)},"callback");return document.addEventListener("visibilitychange",callback),()=>window.removeEventListener("visibilitychange",callback)},[]),isDocumentHidden},"useIsDocumentHidden");let toastsCounter=1;const _Observer=class _Observer{constructor(){this.subscribe=subscriber=>(this.subscribers.push(subscriber),()=>{const index2=this.subscribers.indexOf(subscriber);this.subscribers.splice(index2,1)}),this.publish=data=>{this.subscribers.forEach(subscriber=>subscriber(data))},this.addToast=data=>{this.publish(data),this.toasts=[...this.toasts,data]},this.create=data=>{var _data_id;const{message,...rest}=data,id=typeof data?.id=="number"||((_data_id=data.id)==null?void 0:_data_id.length)>0?data.id:toastsCounter++,alreadyExists=this.toasts.find(toast2=>toast2.id===id),dismissible=data.dismissible===void 0?!0:data.dismissible;return this.dismissedToasts.has(id)&&this.dismissedToasts.delete(id),alreadyExists?this.toasts=this.toasts.map(toast2=>toast2.id===id?(this.publish({...toast2,...data,id,title:message}),{...toast2,...data,id,dismissible,title:message}):toast2):this.addToast({title:message,...rest,dismissible,id}),id},this.dismiss=id=>(id?(this.dismissedToasts.add(id),requestAnimationFrame(()=>this.subscribers.forEach(subscriber=>subscriber({id,dismiss:!0})))):this.toasts.forEach(toast2=>{this.subscribers.forEach(subscriber=>subscriber({id:toast2.id,dismiss:!0}))}),id),this.message=(message,data)=>this.create({...data,message}),this.error=(message,data)=>this.create({...data,message,type:"error"}),this.success=(message,data)=>this.create({...data,type:"success",message}),this.info=(message,data)=>this.create({...data,type:"info",message}),this.warning=(message,data)=>this.create({...data,type:"warning",message}),this.loading=(message,data)=>this.create({...data,type:"loading",message}),this.promise=(promise,data)=>{if(!data)return;let id;data.loading!==void 0&&(id=this.create({...data,promise,type:"loading",message:data.loading,description:typeof data.description!="function"?data.description:void 0}));const p2=Promise.resolve(promise instanceof Function?promise():promise);let shouldDismiss=id!==void 0,result;const originalPromise=p2.then(async response=>{if(result=["resolve",response],React.isValidElement(response))shouldDismiss=!1,this.create({id,type:"default",message:response});else if(isHttpResponse(response)&&!response.ok){shouldDismiss=!1;const promiseData=typeof data.error=="function"?await data.error(`HTTP error! status: ${response.status}`):data.error,description=typeof data.description=="function"?await data.description(`HTTP error! status: ${response.status}`):data.description,toastSettings=typeof promiseData=="object"&&!React.isValidElement(promiseData)?promiseData:{message:promiseData};this.create({id,type:"error",description,...toastSettings})}else if(response instanceof Error){shouldDismiss=!1;const promiseData=typeof data.error=="function"?await data.error(response):data.error,description=typeof data.description=="function"?await data.description(response):data.description,toastSettings=typeof promiseData=="object"&&!React.isValidElement(promiseData)?promiseData:{message:promiseData};this.create({id,type:"error",description,...toastSettings})}else if(data.success!==void 0){shouldDismiss=!1;const promiseData=typeof data.success=="function"?await data.success(response):data.success,description=typeof data.description=="function"?await data.description(response):data.description,toastSettings=typeof promiseData=="object"&&!React.isValidElement(promiseData)?promiseData:{message:promiseData};this.create({id,type:"success",description,...toastSettings})}}).catch(async error=>{if(result=["reject",error],data.error!==void 0){shouldDismiss=!1;const promiseData=typeof data.error=="function"?await data.error(error):data.error,description=typeof data.description=="function"?await data.description(error):data.description,toastSettings=typeof promiseData=="object"&&!React.isValidElement(promiseData)?promiseData:{message:promiseData};this.create({id,type:"error",description,...toastSettings})}}).finally(()=>{shouldDismiss&&(this.dismiss(id),id=void 0),data.finally==null||data.finally.call(data)}),unwrap=__name(()=>new Promise((resolve,reject)=>originalPromise.then(()=>result[0]==="reject"?reject(result[1]):resolve(result[1])).catch(reject)),"unwrap");return typeof id!="string"&&typeof id!="number"?{unwrap}:Object.assign(id,{unwrap})},this.custom=(jsx,data)=>{const id=data?.id||toastsCounter++;return this.create({jsx:jsx(id),id,...data}),id},this.getActiveToasts=()=>this.toasts.filter(toast2=>!this.dismissedToasts.has(toast2.id)),this.subscribers=[],this.toasts=[],this.dismissedToasts=new Set}};__name(_Observer,"Observer");let Observer=_Observer;const ToastState=new Observer,toastFunction=__name((message,data)=>{const id=data?.id||toastsCounter++;return ToastState.addToast({title:message,...data,id}),id},"toastFunction"),isHttpResponse=__name(data=>data&&typeof data=="object"&&"ok"in data&&typeof data.ok=="boolean"&&"status"in data&&typeof data.status=="number","isHttpResponse"),basicToast=toastFunction,getHistory=__name(()=>ToastState.toasts,"getHistory"),getToasts=__name(()=>ToastState.getActiveToasts(),"getToasts"),toast=Object.assign(basicToast,{success:ToastState.success,info:ToastState.info,warning:ToastState.warning,error:ToastState.error,custom:ToastState.custom,message:ToastState.message,promise:ToastState.promise,dismiss:ToastState.dismiss,loading:ToastState.loading},{getHistory,getToasts});__insertCSS("[data-sonner-toaster][dir=ltr],html[dir=ltr]{--toast-icon-margin-start:-3px;--toast-icon-margin-end:4px;--toast-svg-margin-start:-1px;--toast-svg-margin-end:0px;--toast-button-margin-start:auto;--toast-button-margin-end:0;--toast-close-button-start:0;--toast-close-button-end:unset;--toast-close-button-transform:translate(-35%, -35%)}[data-sonner-toaster][dir=rtl],html[dir=rtl]{--toast-icon-margin-start:4px;--toast-icon-margin-end:-3px;--toast-svg-margin-start:0px;--toast-svg-margin-end:-1px;--toast-button-margin-start:0;--toast-button-margin-end:auto;--toast-close-button-start:unset;--toast-close-button-end:0;--toast-close-button-transform:translate(35%, -35%)}[data-sonner-toaster]{position:fixed;width:var(--width);font-family:ui-sans-serif,system-ui,-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Helvetica Neue,Arial,Noto Sans,sans-serif,Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol,Noto Color Emoji;--gray1:hsl(0, 0%, 99%);--gray2:hsl(0, 0%, 97.3%);--gray3:hsl(0, 0%, 95.1%);--gray4:hsl(0, 0%, 93%);--gray5:hsl(0, 0%, 90.9%);--gray6:hsl(0, 0%, 88.7%);--gray7:hsl(0, 0%, 85.8%);--gray8:hsl(0, 0%, 78%);--gray9:hsl(0, 0%, 56.1%);--gray10:hsl(0, 0%, 52.3%);--gray11:hsl(0, 0%, 43.5%);--gray12:hsl(0, 0%, 9%);--border-radius:8px;box-sizing:border-box;padding:0;margin:0;list-style:none;outline:0;z-index:999999999;transition:transform .4s ease}@media (hover:none) and (pointer:coarse){[data-sonner-toaster][data-lifted=true]{transform:none}}[data-sonner-toaster][data-x-position=right]{right:var(--offset-right)}[data-sonner-toaster][data-x-position=left]{left:var(--offset-left)}[data-sonner-toaster][data-x-position=center]{left:50%;transform:translateX(-50%)}[data-sonner-toaster][data-y-position=top]{top:var(--offset-top)}[data-sonner-toaster][data-y-position=bottom]{bottom:var(--offset-bottom)}[data-sonner-toast]{--y:translateY(100%);--lift-amount:calc(var(--lift) * var(--gap));z-index:var(--z-index);position:absolute;opacity:0;transform:var(--y);touch-action:none;transition:transform .4s,opacity .4s,height .4s,box-shadow .2s;box-sizing:border-box;outline:0;overflow-wrap:anywhere}[data-sonner-toast][data-styled=true]{padding:16px;background:var(--normal-bg);border:1px solid var(--normal-border);color:var(--normal-text);border-radius:var(--border-radius);box-shadow:0 4px 12px rgba(0,0,0,.1);width:var(--width);font-size:13px;display:flex;align-items:center;gap:6px}[data-sonner-toast]:focus-visible{box-shadow:0 4px 12px rgba(0,0,0,.1),0 0 0 2px rgba(0,0,0,.2)}[data-sonner-toast][data-y-position=top]{top:0;--y:translateY(-100%);--lift:1;--lift-amount:calc(1 * var(--gap))}[data-sonner-toast][data-y-position=bottom]{bottom:0;--y:translateY(100%);--lift:-1;--lift-amount:calc(var(--lift) * var(--gap))}[data-sonner-toast][data-styled=true] [data-description]{font-weight:400;line-height:1.4;color:#3f3f3f}[data-rich-colors=true][data-sonner-toast][data-styled=true] [data-description]{color:inherit}[data-sonner-toaster][data-sonner-theme=dark] [data-description]{color:#e8e8e8}[data-sonner-toast][data-styled=true] [data-title]{font-weight:500;line-height:1.5;color:inherit}[data-sonner-toast][data-styled=true] [data-icon]{display:flex;height:16px;width:16px;position:relative;justify-content:flex-start;align-items:center;flex-shrink:0;margin-left:var(--toast-icon-margin-start);margin-right:var(--toast-icon-margin-end)}[data-sonner-toast][data-promise=true] [data-icon]>svg{opacity:0;transform:scale(.8);transform-origin:center;animation:sonner-fade-in .3s ease forwards}[data-sonner-toast][data-styled=true] [data-icon]>*{flex-shrink:0}[data-sonner-toast][data-styled=true] [data-icon] svg{margin-left:var(--toast-svg-margin-start);margin-right:var(--toast-svg-margin-end)}[data-sonner-toast][data-styled=true] [data-content]{display:flex;flex-direction:column;gap:2px}[data-sonner-toast][data-styled=true] [data-button]{border-radius:4px;padding-left:8px;padding-right:8px;height:24px;font-size:12px;color:var(--normal-bg);background:var(--normal-text);margin-left:var(--toast-button-margin-start);margin-right:var(--toast-button-margin-end);border:none;font-weight:500;cursor:pointer;outline:0;display:flex;align-items:center;flex-shrink:0;transition:opacity .4s,box-shadow .2s}[data-sonner-toast][data-styled=true] [data-button]:focus-visible{box-shadow:0 0 0 2px rgba(0,0,0,.4)}[data-sonner-toast][data-styled=true] [data-button]:first-of-type{margin-left:var(--toast-button-margin-start);margin-right:var(--toast-button-margin-end)}[data-sonner-toast][data-styled=true] [data-cancel]{color:var(--normal-text);background:rgba(0,0,0,.08)}[data-sonner-toaster][data-sonner-theme=dark] [data-sonner-toast][data-styled=true] [data-cancel]{background:rgba(255,255,255,.3)}[data-sonner-toast][data-styled=true] [data-close-button]{position:absolute;left:var(--toast-close-button-start);right:var(--toast-close-button-end);top:0;height:20px;width:20px;display:flex;justify-content:center;align-items:center;padding:0;color:var(--gray12);background:var(--normal-bg);border:1px solid var(--gray4);transform:var(--toast-close-button-transform);border-radius:50%;cursor:pointer;z-index:1;transition:opacity .1s,background .2s,border-color .2s}[data-sonner-toast][data-styled=true] [data-close-button]:focus-visible{box-shadow:0 4px 12px rgba(0,0,0,.1),0 0 0 2px rgba(0,0,0,.2)}[data-sonner-toast][data-styled=true] [data-disabled=true]{cursor:not-allowed}[data-sonner-toast][data-styled=true]:hover [data-close-button]:hover{background:var(--gray2);border-color:var(--gray5)}[data-sonner-toast][data-swiping=true]::before{content:'';position:absolute;left:-100%;right:-100%;height:100%;z-index:-1}[data-sonner-toast][data-y-position=top][data-swiping=true]::before{bottom:50%;transform:scaleY(3) translateY(50%)}[data-sonner-toast][data-y-position=bottom][data-swiping=true]::before{top:50%;transform:scaleY(3) translateY(-50%)}[data-sonner-toast][data-swiping=false][data-removed=true]::before{content:'';position:absolute;inset:0;transform:scaleY(2)}[data-sonner-toast][data-expanded=true]::after{content:'';position:absolute;left:0;height:calc(var(--gap) + 1px);bottom:100%;width:100%}[data-sonner-toast][data-mounted=true]{--y:translateY(0);opacity:1}[data-sonner-toast][data-expanded=false][data-front=false]{--scale:var(--toasts-before) * 0.05 + 1;--y:translateY(calc(var(--lift-amount) * var(--toasts-before))) scale(calc(-1 * var(--scale)));height:var(--front-toast-height)}[data-sonner-toast]>*{transition:opacity .4s}[data-sonner-toast][data-x-position=right]{right:0}[data-sonner-toast][data-x-position=left]{left:0}[data-sonner-toast][data-expanded=false][data-front=false][data-styled=true]>*{opacity:0}[data-sonner-toast][data-visible=false]{opacity:0;pointer-events:none}[data-sonner-toast][data-mounted=true][data-expanded=true]{--y:translateY(calc(var(--lift) * var(--offset)));height:var(--initial-height)}[data-sonner-toast][data-removed=true][data-front=true][data-swipe-out=false]{--y:translateY(calc(var(--lift) * -100%));opacity:0}[data-sonner-toast][data-removed=true][data-front=false][data-swipe-out=false][data-expanded=true]{--y:translateY(calc(var(--lift) * var(--offset) + var(--lift) * -100%));opacity:0}[data-sonner-toast][data-removed=true][data-front=false][data-swipe-out=false][data-expanded=false]{--y:translateY(40%);opacity:0;transition:transform .5s,opacity .2s}[data-sonner-toast][data-removed=true][data-front=false]::before{height:calc(var(--initial-height) + 20%)}[data-sonner-toast][data-swiping=true]{transform:var(--y) translateY(var(--swipe-amount-y,0)) translateX(var(--swipe-amount-x,0));transition:none}[data-sonner-toast][data-swiped=true]{user-select:none}[data-sonner-toast][data-swipe-out=true][data-y-position=bottom],[data-sonner-toast][data-swipe-out=true][data-y-position=top]{animation-duration:.2s;animation-timing-function:ease-out;animation-fill-mode:forwards}[data-sonner-toast][data-swipe-out=true][data-swipe-direction=left]{animation-name:swipe-out-left}[data-sonner-toast][data-swipe-out=true][data-swipe-direction=right]{animation-name:swipe-out-right}[data-sonner-toast][data-swipe-out=true][data-swipe-direction=up]{animation-name:swipe-out-up}[data-sonner-toast][data-swipe-out=true][data-swipe-direction=down]{animation-name:swipe-out-down}@keyframes swipe-out-left{from{transform:var(--y) translateX(var(--swipe-amount-x));opacity:1}to{transform:var(--y) translateX(calc(var(--swipe-amount-x) - 100%));opacity:0}}@keyframes swipe-out-right{from{transform:var(--y) translateX(var(--swipe-amount-x));opacity:1}to{transform:var(--y) translateX(calc(var(--swipe-amount-x) + 100%));opacity:0}}@keyframes swipe-out-up{from{transform:var(--y) translateY(var(--swipe-amount-y));opacity:1}to{transform:var(--y) translateY(calc(var(--swipe-amount-y) - 100%));opacity:0}}@keyframes swipe-out-down{from{transform:var(--y) translateY(var(--swipe-amount-y));opacity:1}to{transform:var(--y) translateY(calc(var(--swipe-amount-y) + 100%));opacity:0}}@media (max-width:600px){[data-sonner-toaster]{position:fixed;right:var(--mobile-offset-right);left:var(--mobile-offset-left);width:100%}[data-sonner-toaster][dir=rtl]{left:calc(var(--mobile-offset-left) * -1)}[data-sonner-toaster] [data-sonner-toast]{left:0;right:0;width:calc(100% - var(--mobile-offset-left) * 2)}[data-sonner-toaster][data-x-position=left]{left:var(--mobile-offset-left)}[data-sonner-toaster][data-y-position=bottom]{bottom:var(--mobile-offset-bottom)}[data-sonner-toaster][data-y-position=top]{top:var(--mobile-offset-top)}[data-sonner-toaster][data-x-position=center]{left:var(--mobile-offset-left);right:var(--mobile-offset-right);transform:none}}[data-sonner-toaster][data-sonner-theme=light]{--normal-bg:#fff;--normal-border:var(--gray4);--normal-text:var(--gray12);--success-bg:hsl(143, 85%, 96%);--success-border:hsl(145, 92%, 87%);--success-text:hsl(140, 100%, 27%);--info-bg:hsl(208, 100%, 97%);--info-border:hsl(221, 91%, 93%);--info-text:hsl(210, 92%, 45%);--warning-bg:hsl(49, 100%, 97%);--warning-border:hsl(49, 91%, 84%);--warning-text:hsl(31, 92%, 45%);--error-bg:hsl(359, 100%, 97%);--error-border:hsl(359, 100%, 94%);--error-text:hsl(360, 100%, 45%)}[data-sonner-toaster][data-sonner-theme=light] [data-sonner-toast][data-invert=true]{--normal-bg:#000;--normal-border:hsl(0, 0%, 20%);--normal-text:var(--gray1)}[data-sonner-toaster][data-sonner-theme=dark] [data-sonner-toast][data-invert=true]{--normal-bg:#fff;--normal-border:var(--gray3);--normal-text:var(--gray12)}[data-sonner-toaster][data-sonner-theme=dark]{--normal-bg:#000;--normal-bg-hover:hsl(0, 0%, 12%);--normal-border:hsl(0, 0%, 20%);--normal-border-hover:hsl(0, 0%, 25%);--normal-text:var(--gray1);--success-bg:hsl(150, 100%, 6%);--success-border:hsl(147, 100%, 12%);--success-text:hsl(150, 86%, 65%);--info-bg:hsl(215, 100%, 6%);--info-border:hsl(223, 43%, 17%);--info-text:hsl(216, 87%, 65%);--warning-bg:hsl(64, 100%, 6%);--warning-border:hsl(60, 100%, 9%);--warning-text:hsl(46, 87%, 65%);--error-bg:hsl(358, 76%, 10%);--error-border:hsl(357, 89%, 16%);--error-text:hsl(358, 100%, 81%)}[data-sonner-toaster][data-sonner-theme=dark] [data-sonner-toast] [data-close-button]{background:var(--normal-bg);border-color:var(--normal-border);color:var(--normal-text)}[data-sonner-toaster][data-sonner-theme=dark] [data-sonner-toast] [data-close-button]:hover{background:var(--normal-bg-hover);border-color:var(--normal-border-hover)}[data-rich-colors=true][data-sonner-toast][data-type=success]{background:var(--success-bg);border-color:var(--success-border);color:var(--success-text)}[data-rich-colors=true][data-sonner-toast][data-type=success] [data-close-button]{background:var(--success-bg);border-color:var(--success-border);color:var(--success-text)}[data-rich-colors=true][data-sonner-toast][data-type=info]{background:var(--info-bg);border-color:var(--info-border);color:var(--info-text)}[data-rich-colors=true][data-sonner-toast][data-type=info] [data-close-button]{background:var(--info-bg);border-color:var(--info-border);color:var(--info-text)}[data-rich-colors=true][data-sonner-toast][data-type=warning]{background:var(--warning-bg);border-color:var(--warning-border);color:var(--warning-text)}[data-rich-colors=true][data-sonner-toast][data-type=warning] [data-close-button]{background:var(--warning-bg);border-color:var(--warning-border);color:var(--warning-text)}[data-rich-colors=true][data-sonner-toast][data-type=error]{background:var(--error-bg);border-color:var(--error-border);color:var(--error-text)}[data-rich-colors=true][data-sonner-toast][data-type=error] [data-close-button]{background:var(--error-bg);border-color:var(--error-border);color:var(--error-text)}.sonner-loading-wrapper{--size:16px;height:var(--size);width:var(--size);position:absolute;inset:0;z-index:10}.sonner-loading-wrapper[data-visible=false]{transform-origin:center;animation:sonner-fade-out .2s ease forwards}.sonner-spinner{position:relative;top:50%;left:50%;height:var(--size);width:var(--size)}.sonner-loading-bar{animation:sonner-spin 1.2s linear infinite;background:var(--gray11);border-radius:6px;height:8%;left:-10%;position:absolute;top:-3.9%;width:24%}.sonner-loading-bar:first-child{animation-delay:-1.2s;transform:rotate(.0001deg) translate(146%)}.sonner-loading-bar:nth-child(2){animation-delay:-1.1s;transform:rotate(30deg) translate(146%)}.sonner-loading-bar:nth-child(3){animation-delay:-1s;transform:rotate(60deg) translate(146%)}.sonner-loading-bar:nth-child(4){animation-delay:-.9s;transform:rotate(90deg) translate(146%)}.sonner-loading-bar:nth-child(5){animation-delay:-.8s;transform:rotate(120deg) translate(146%)}.sonner-loading-bar:nth-child(6){animation-delay:-.7s;transform:rotate(150deg) translate(146%)}.sonner-loading-bar:nth-child(7){animation-delay:-.6s;transform:rotate(180deg) translate(146%)}.sonner-loading-bar:nth-child(8){animation-delay:-.5s;transform:rotate(210deg) translate(146%)}.sonner-loading-bar:nth-child(9){animation-delay:-.4s;transform:rotate(240deg) translate(146%)}.sonner-loading-bar:nth-child(10){animation-delay:-.3s;transform:rotate(270deg) translate(146%)}.sonner-loading-bar:nth-child(11){animation-delay:-.2s;transform:rotate(300deg) translate(146%)}.sonner-loading-bar:nth-child(12){animation-delay:-.1s;transform:rotate(330deg) translate(146%)}@keyframes sonner-fade-in{0%{opacity:0;transform:scale(.8)}100%{opacity:1;transform:scale(1)}}@keyframes sonner-fade-out{0%{opacity:1;transform:scale(1)}100%{opacity:0;transform:scale(.8)}}@keyframes sonner-spin{0%{opacity:1}100%{opacity:.15}}@media (prefers-reduced-motion){.sonner-loading-bar,[data-sonner-toast],[data-sonner-toast]>*{transition:none!important;animation:none!important}}.sonner-loader{position:absolute;top:50%;left:50%;transform:translate(-50%,-50%);transform-origin:center;transition:opacity .2s,transform .2s}.sonner-loader[data-visible=false]{opacity:0;transform:scale(.8) translate(-50%,-50%)}");function isAction(action){return action.label!==void 0}__name(isAction,"isAction");const VISIBLE_TOASTS_AMOUNT=3,VIEWPORT_OFFSET="24px",MOBILE_VIEWPORT_OFFSET="16px",TOAST_LIFETIME=4e3,TOAST_WIDTH=356,GAP=14,SWIPE_THRESHOLD=45,TIME_BEFORE_UNMOUNT=200;function cn(...classes){return classes.filter(Boolean).join(" ")}__name(cn,"cn");function getDefaultSwipeDirections(position2){const[y2,x2]=position2.split("-"),directions=[];return y2&&directions.push(y2),x2&&directions.push(x2),directions}__name(getDefaultSwipeDirections,"getDefaultSwipeDirections");const Toast=__name(props=>{var _toast_classNames,_toast_classNames1,_toast_classNames2,_toast_classNames3,_toast_classNames4,_toast_classNames5,_toast_classNames6,_toast_classNames7,_toast_classNames8;const{invert:ToasterInvert,toast:toast2,unstyled,interacting,setHeights,visibleToasts,heights,index:index2,toasts,expanded,removeToast,defaultRichColors,closeButton:closeButtonFromToaster,style:style2,cancelButtonStyle,actionButtonStyle,className="",descriptionClassName="",duration:durationFromToaster,position:position2,gap,expandByDefault,classNames,icons,closeButtonAriaLabel="Close toast"}=props,[swipeDirection,setSwipeDirection]=React.useState(null),[swipeOutDirection,setSwipeOutDirection]=React.useState(null),[mounted,setMounted]=React.useState(!1),[removed,setRemoved]=React.useState(!1),[swiping,setSwiping]=React.useState(!1),[swipeOut,setSwipeOut]=React.useState(!1),[isSwiped,setIsSwiped]=React.useState(!1),[offsetBeforeRemove,setOffsetBeforeRemove]=React.useState(0),[initialHeight,setInitialHeight]=React.useState(0),remainingTime=React.useRef(toast2.duration||durationFromToaster||TOAST_LIFETIME),dragStartTime=React.useRef(null),toastRef=React.useRef(null),isFront=index2===0,isVisible2=index2+1<=visibleToasts,toastType=toast2.type,dismissible=toast2.dismissible!==!1,toastClassname=toast2.className||"",toastDescriptionClassname=toast2.descriptionClassName||"",heightIndex=React.useMemo(()=>heights.findIndex(height=>height.toastId===toast2.id)||0,[heights,toast2.id]),closeButton=React.useMemo(()=>{var _toast_closeButton;return(_toast_closeButton=toast2.closeButton)!=null?_toast_closeButton:closeButtonFromToaster},[toast2.closeButton,closeButtonFromToaster]),duration=React.useMemo(()=>toast2.duration||durationFromToaster||TOAST_LIFETIME,[toast2.duration,durationFromToaster]),closeTimerStartTimeRef=React.useRef(0),offset2=React.useRef(0),lastCloseTimerStartTimeRef=React.useRef(0),pointerStartRef=React.useRef(null),[y2,x2]=position2.split("-"),toastsHeightBefore=React.useMemo(()=>heights.reduce((prev,curr,reducerIndex)=>reducerIndex>=heightIndex?prev:prev+curr.height,0),[heights,heightIndex]),isDocumentHidden=useIsDocumentHidden(),invert=toast2.invert||ToasterInvert,disabled=toastType==="loading";offset2.current=React.useMemo(()=>heightIndex*gap+toastsHeightBefore,[heightIndex,toastsHeightBefore]),React.useEffect(()=>{remainingTime.current=duration},[duration]),React.useEffect(()=>{setMounted(!0)},[]),React.useEffect(()=>{const toastNode=toastRef.current;if(toastNode){const height=toastNode.getBoundingClientRect().height;return setInitialHeight(height),setHeights(h2=>[{toastId:toast2.id,height,position:toast2.position},...h2]),()=>setHeights(h2=>h2.filter(height2=>height2.toastId!==toast2.id))}},[setHeights,toast2.id]),React.useLayoutEffect(()=>{if(!mounted)return;const toastNode=toastRef.current,originalHeight=toastNode.style.height;toastNode.style.height="auto";const newHeight=toastNode.getBoundingClientRect().height;toastNode.style.height=originalHeight,setInitialHeight(newHeight),setHeights(heights2=>heights2.find(height=>height.toastId===toast2.id)?heights2.map(height=>height.toastId===toast2.id?{...height,height:newHeight}:height):[{toastId:toast2.id,height:newHeight,position:toast2.position},...heights2])},[mounted,toast2.title,toast2.description,setHeights,toast2.id,toast2.jsx,toast2.action,toast2.cancel]);const deleteToast=React.useCallback(()=>{setRemoved(!0),setOffsetBeforeRemove(offset2.current),setHeights(h2=>h2.filter(height=>height.toastId!==toast2.id)),setTimeout(()=>{removeToast(toast2)},TIME_BEFORE_UNMOUNT)},[toast2,removeToast,setHeights,offset2]);React.useEffect(()=>{if(toast2.promise&&toastType==="loading"||toast2.duration===1/0||toast2.type==="loading")return;let timeoutId;return expanded||interacting||isDocumentHidden?__name(()=>{if(lastCloseTimerStartTimeRef.current{remainingTime.current!==1/0&&(closeTimerStartTimeRef.current=new Date().getTime(),timeoutId=setTimeout(()=>{toast2.onAutoClose==null||toast2.onAutoClose.call(toast2,toast2),deleteToast()},remainingTime.current))},"startTimer")(),()=>clearTimeout(timeoutId)},[expanded,interacting,toast2,toastType,isDocumentHidden,deleteToast]),React.useEffect(()=>{toast2.delete&&(deleteToast(),toast2.onDismiss==null||toast2.onDismiss.call(toast2,toast2))},[deleteToast,toast2.delete]);function getLoadingIcon(){var _toast_classNames9;if(icons?.loading){var _toast_classNames12;return React.createElement("div",{className:cn(classNames?.loader,toast2==null||(_toast_classNames12=toast2.classNames)==null?void 0:_toast_classNames12.loader,"sonner-loader"),"data-visible":toastType==="loading"},icons.loading)}return React.createElement(Loader,{className:cn(classNames?.loader,toast2==null||(_toast_classNames9=toast2.classNames)==null?void 0:_toast_classNames9.loader),visible:toastType==="loading"})}__name(getLoadingIcon,"getLoadingIcon");const icon=toast2.icon||icons?.[toastType]||getAsset(toastType);var _toast_richColors,_icons_close;return React.createElement("li",{tabIndex:0,ref:toastRef,className:cn(className,toastClassname,classNames?.toast,toast2==null||(_toast_classNames=toast2.classNames)==null?void 0:_toast_classNames.toast,classNames?.default,classNames?.[toastType],toast2==null||(_toast_classNames1=toast2.classNames)==null?void 0:_toast_classNames1[toastType]),"data-sonner-toast":"","data-rich-colors":(_toast_richColors=toast2.richColors)!=null?_toast_richColors:defaultRichColors,"data-styled":!(toast2.jsx||toast2.unstyled||unstyled),"data-mounted":mounted,"data-promise":!!toast2.promise,"data-swiped":isSwiped,"data-removed":removed,"data-visible":isVisible2,"data-y-position":y2,"data-x-position":x2,"data-index":index2,"data-front":isFront,"data-swiping":swiping,"data-dismissible":dismissible,"data-type":toastType,"data-invert":invert,"data-swipe-out":swipeOut,"data-swipe-direction":swipeOutDirection,"data-expanded":!!(expanded||expandByDefault&&mounted),"data-testid":toast2.testId,style:{"--index":index2,"--toasts-before":index2,"--z-index":toasts.length-index2,"--offset":`${removed?offsetBeforeRemove:offset2.current}px`,"--initial-height":expandByDefault?"auto":`${initialHeight}px`,...style2,...toast2.style},onDragEnd:__name(()=>{setSwiping(!1),setSwipeDirection(null),pointerStartRef.current=null},"onDragEnd"),onPointerDown:__name(event=>{event.button!==2&&(disabled||!dismissible||(dragStartTime.current=new Date,setOffsetBeforeRemove(offset2.current),event.target.setPointerCapture(event.pointerId),event.target.tagName!=="BUTTON"&&(setSwiping(!0),pointerStartRef.current={x:event.clientX,y:event.clientY})))},"onPointerDown"),onPointerUp:__name(()=>{var _toastRef_current,_toastRef_current1,_dragStartTime_current;if(swipeOut||!dismissible)return;pointerStartRef.current=null;const swipeAmountX=Number(((_toastRef_current=toastRef.current)==null?void 0:_toastRef_current.style.getPropertyValue("--swipe-amount-x").replace("px",""))||0),swipeAmountY=Number(((_toastRef_current1=toastRef.current)==null?void 0:_toastRef_current1.style.getPropertyValue("--swipe-amount-y").replace("px",""))||0),timeTaken=new Date().getTime()-((_dragStartTime_current=dragStartTime.current)==null?void 0:_dragStartTime_current.getTime()),swipeAmount=swipeDirection==="x"?swipeAmountX:swipeAmountY,velocity=Math.abs(swipeAmount)/timeTaken;if(Math.abs(swipeAmount)>=SWIPE_THRESHOLD||velocity>.11){setOffsetBeforeRemove(offset2.current),toast2.onDismiss==null||toast2.onDismiss.call(toast2,toast2),setSwipeOutDirection(swipeDirection==="x"?swipeAmountX>0?"right":"left":swipeAmountY>0?"down":"up"),deleteToast(),setSwipeOut(!0);return}else{var _toastRef_current2,_toastRef_current3;(_toastRef_current2=toastRef.current)==null||_toastRef_current2.style.setProperty("--swipe-amount-x","0px"),(_toastRef_current3=toastRef.current)==null||_toastRef_current3.style.setProperty("--swipe-amount-y","0px")}setIsSwiped(!1),setSwiping(!1),setSwipeDirection(null)},"onPointerUp"),onPointerMove:__name(event=>{var _window_getSelection,_toastRef_current,_toastRef_current1;if(!pointerStartRef.current||!dismissible||((_window_getSelection=window.getSelection())==null?void 0:_window_getSelection.toString().length)>0)return;const yDelta=event.clientY-pointerStartRef.current.y,xDelta=event.clientX-pointerStartRef.current.x;var _props_swipeDirections;const swipeDirections=(_props_swipeDirections=props.swipeDirections)!=null?_props_swipeDirections:getDefaultSwipeDirections(position2);!swipeDirection&&(Math.abs(xDelta)>1||Math.abs(yDelta)>1)&&setSwipeDirection(Math.abs(xDelta)>Math.abs(yDelta)?"x":"y");let swipeAmount={x:0,y:0};const getDampening=__name(delta=>1/(1.5+Math.abs(delta)/20),"getDampening");if(swipeDirection==="y"){if(swipeDirections.includes("top")||swipeDirections.includes("bottom"))if(swipeDirections.includes("top")&&yDelta<0||swipeDirections.includes("bottom")&&yDelta>0)swipeAmount.y=yDelta;else{const dampenedDelta=yDelta*getDampening(yDelta);swipeAmount.y=Math.abs(dampenedDelta)0)swipeAmount.x=xDelta;else{const dampenedDelta=xDelta*getDampening(xDelta);swipeAmount.x=Math.abs(dampenedDelta)0||Math.abs(swipeAmount.y)>0)&&setIsSwiped(!0),(_toastRef_current=toastRef.current)==null||_toastRef_current.style.setProperty("--swipe-amount-x",`${swipeAmount.x}px`),(_toastRef_current1=toastRef.current)==null||_toastRef_current1.style.setProperty("--swipe-amount-y",`${swipeAmount.y}px`)},"onPointerMove")},closeButton&&!toast2.jsx&&toastType!=="loading"?React.createElement("button",{"aria-label":closeButtonAriaLabel,"data-disabled":disabled,"data-close-button":!0,onClick:disabled||!dismissible?()=>{}:()=>{deleteToast(),toast2.onDismiss==null||toast2.onDismiss.call(toast2,toast2)},className:cn(classNames?.closeButton,toast2==null||(_toast_classNames2=toast2.classNames)==null?void 0:_toast_classNames2.closeButton)},(_icons_close=icons?.close)!=null?_icons_close:CloseIcon):null,(toastType||toast2.icon||toast2.promise)&&toast2.icon!==null&&(icons?.[toastType]!==null||toast2.icon)?React.createElement("div",{"data-icon":"",className:cn(classNames?.icon,toast2==null||(_toast_classNames3=toast2.classNames)==null?void 0:_toast_classNames3.icon)},toast2.promise||toast2.type==="loading"&&!toast2.icon?toast2.icon||getLoadingIcon():null,toast2.type!=="loading"?icon:null):null,React.createElement("div",{"data-content":"",className:cn(classNames?.content,toast2==null||(_toast_classNames4=toast2.classNames)==null?void 0:_toast_classNames4.content)},React.createElement("div",{"data-title":"",className:cn(classNames?.title,toast2==null||(_toast_classNames5=toast2.classNames)==null?void 0:_toast_classNames5.title)},toast2.jsx?toast2.jsx:typeof toast2.title=="function"?toast2.title():toast2.title),toast2.description?React.createElement("div",{"data-description":"",className:cn(descriptionClassName,toastDescriptionClassname,classNames?.description,toast2==null||(_toast_classNames6=toast2.classNames)==null?void 0:_toast_classNames6.description)},typeof toast2.description=="function"?toast2.description():toast2.description):null),React.isValidElement(toast2.cancel)?toast2.cancel:toast2.cancel&&isAction(toast2.cancel)?React.createElement("button",{"data-button":!0,"data-cancel":!0,style:toast2.cancelButtonStyle||cancelButtonStyle,onClick:__name(event=>{isAction(toast2.cancel)&&dismissible&&(toast2.cancel.onClick==null||toast2.cancel.onClick.call(toast2.cancel,event),deleteToast())},"onClick"),className:cn(classNames?.cancelButton,toast2==null||(_toast_classNames7=toast2.classNames)==null?void 0:_toast_classNames7.cancelButton)},toast2.cancel.label):null,React.isValidElement(toast2.action)?toast2.action:toast2.action&&isAction(toast2.action)?React.createElement("button",{"data-button":!0,"data-action":!0,style:toast2.actionButtonStyle||actionButtonStyle,onClick:__name(event=>{isAction(toast2.action)&&(toast2.action.onClick==null||toast2.action.onClick.call(toast2.action,event),!event.defaultPrevented&&deleteToast())},"onClick"),className:cn(classNames?.actionButton,toast2==null||(_toast_classNames8=toast2.classNames)==null?void 0:_toast_classNames8.actionButton)},toast2.action.label):null)},"Toast");function getDocumentDirection(){if(typeof window>"u"||typeof document>"u")return"ltr";const dirAttribute=document.documentElement.getAttribute("dir");return dirAttribute==="auto"||!dirAttribute?window.getComputedStyle(document.documentElement).direction:dirAttribute}__name(getDocumentDirection,"getDocumentDirection");function assignOffset(defaultOffset,mobileOffset){const styles={};return[defaultOffset,mobileOffset].forEach((offset2,index2)=>{const isMobile=index2===1,prefix2=isMobile?"--mobile-offset":"--offset",defaultValue=isMobile?MOBILE_VIEWPORT_OFFSET:VIEWPORT_OFFSET;function assignAll(offset3){["top","right","bottom","left"].forEach(key=>{styles[`${prefix2}-${key}`]=typeof offset3=="number"?`${offset3}px`:offset3})}__name(assignAll,"assignAll"),typeof offset2=="number"||typeof offset2=="string"?assignAll(offset2):typeof offset2=="object"?["top","right","bottom","left"].forEach(key=>{offset2[key]===void 0?styles[`${prefix2}-${key}`]=defaultValue:styles[`${prefix2}-${key}`]=typeof offset2[key]=="number"?`${offset2[key]}px`:offset2[key]}):assignAll(defaultValue)}),styles}__name(assignOffset,"assignOffset");const Toaster$1=React.forwardRef(__name(function(props,ref){const{id,invert,position:position2="bottom-right",hotkey=["altKey","KeyT"],expand,closeButton,className,offset:offset2,mobileOffset,theme="light",richColors,duration,style:style2,visibleToasts=VISIBLE_TOASTS_AMOUNT,toastOptions,dir=getDocumentDirection(),gap=GAP,icons,containerAriaLabel="Notifications"}=props,[toasts,setToasts]=React.useState([]),filteredToasts=React.useMemo(()=>id?toasts.filter(toast2=>toast2.toasterId===id):toasts.filter(toast2=>!toast2.toasterId),[toasts,id]),possiblePositions=React.useMemo(()=>Array.from(new Set([position2].concat(filteredToasts.filter(toast2=>toast2.position).map(toast2=>toast2.position)))),[filteredToasts,position2]),[heights,setHeights]=React.useState([]),[expanded,setExpanded]=React.useState(!1),[interacting,setInteracting]=React.useState(!1),[actualTheme,setActualTheme]=React.useState(theme!=="system"?theme:typeof window<"u"&&window.matchMedia&&window.matchMedia("(prefers-color-scheme: dark)").matches?"dark":"light"),listRef=React.useRef(null),hotkeyLabel=hotkey.join("+").replace(/Key/g,"").replace(/Digit/g,""),lastFocusedElementRef=React.useRef(null),isFocusWithinRef=React.useRef(!1),removeToast=React.useCallback(toastToRemove=>{setToasts(toasts2=>{var _toasts_find;return(_toasts_find=toasts2.find(toast2=>toast2.id===toastToRemove.id))!=null&&_toasts_find.delete||ToastState.dismiss(toastToRemove.id),toasts2.filter(({id:id2})=>id2!==toastToRemove.id)})},[]);return React.useEffect(()=>ToastState.subscribe(toast2=>{if(toast2.dismiss){requestAnimationFrame(()=>{setToasts(toasts2=>toasts2.map(t2=>t2.id===toast2.id?{...t2,delete:!0}:t2))});return}setTimeout(()=>{ReactDOM.flushSync(()=>{setToasts(toasts2=>{const indexOfExistingToast=toasts2.findIndex(t2=>t2.id===toast2.id);return indexOfExistingToast!==-1?[...toasts2.slice(0,indexOfExistingToast),{...toasts2[indexOfExistingToast],...toast2},...toasts2.slice(indexOfExistingToast+1)]:[toast2,...toasts2]})})})}),[toasts]),React.useEffect(()=>{if(theme!=="system"){setActualTheme(theme);return}if(theme==="system"&&(window.matchMedia&&window.matchMedia("(prefers-color-scheme: dark)").matches?setActualTheme("dark"):setActualTheme("light")),typeof window>"u")return;const darkMediaQuery=window.matchMedia("(prefers-color-scheme: dark)");try{darkMediaQuery.addEventListener("change",({matches})=>{setActualTheme(matches?"dark":"light")})}catch{darkMediaQuery.addListener(({matches})=>{try{setActualTheme(matches?"dark":"light")}catch(e3){console.error(e3)}})}},[theme]),React.useEffect(()=>{toasts.length<=1&&setExpanded(!1)},[toasts]),React.useEffect(()=>{const handleKeyDown=__name(event=>{var _listRef_current;if(hotkey.every(key=>event[key]||event.code===key)){var _listRef_current1;setExpanded(!0),(_listRef_current1=listRef.current)==null||_listRef_current1.focus()}event.code==="Escape"&&(document.activeElement===listRef.current||(_listRef_current=listRef.current)!=null&&_listRef_current.contains(document.activeElement))&&setExpanded(!1)},"handleKeyDown");return document.addEventListener("keydown",handleKeyDown),()=>document.removeEventListener("keydown",handleKeyDown)},[hotkey]),React.useEffect(()=>{if(listRef.current)return()=>{lastFocusedElementRef.current&&(lastFocusedElementRef.current.focus({preventScroll:!0}),lastFocusedElementRef.current=null,isFocusWithinRef.current=!1)}},[listRef.current]),React.createElement("section",{ref,"aria-label":`${containerAriaLabel} ${hotkeyLabel}`,tabIndex:-1,"aria-live":"polite","aria-relevant":"additions text","aria-atomic":"false",suppressHydrationWarning:!0},possiblePositions.map((position3,index2)=>{var _heights_;const[y2,x2]=position3.split("-");return filteredToasts.length?React.createElement("ol",{key:position3,dir:dir==="auto"?getDocumentDirection():dir,tabIndex:-1,ref:listRef,className,"data-sonner-toaster":!0,"data-sonner-theme":actualTheme,"data-y-position":y2,"data-x-position":x2,style:{"--front-toast-height":`${((_heights_=heights[0])==null?void 0:_heights_.height)||0}px`,"--width":`${TOAST_WIDTH}px`,"--gap":`${gap}px`,...style2,...assignOffset(offset2,mobileOffset)},onBlur:__name(event=>{isFocusWithinRef.current&&!event.currentTarget.contains(event.relatedTarget)&&(isFocusWithinRef.current=!1,lastFocusedElementRef.current&&(lastFocusedElementRef.current.focus({preventScroll:!0}),lastFocusedElementRef.current=null))},"onBlur"),onFocus:__name(event=>{event.target instanceof HTMLElement&&event.target.dataset.dismissible==="false"||isFocusWithinRef.current||(isFocusWithinRef.current=!0,lastFocusedElementRef.current=event.relatedTarget)},"onFocus"),onMouseEnter:__name(()=>setExpanded(!0),"onMouseEnter"),onMouseMove:__name(()=>setExpanded(!0),"onMouseMove"),onMouseLeave:__name(()=>{interacting||setExpanded(!1)},"onMouseLeave"),onDragEnd:__name(()=>setExpanded(!1),"onDragEnd"),onPointerDown:__name(event=>{event.target instanceof HTMLElement&&event.target.dataset.dismissible==="false"||setInteracting(!0)},"onPointerDown"),onPointerUp:__name(()=>setInteracting(!1),"onPointerUp")},filteredToasts.filter(toast2=>!toast2.position&&index2===0||toast2.position===position3).map((toast2,index3)=>{var _toastOptions_duration,_toastOptions_closeButton;return React.createElement(Toast,{key:toast2.id,icons,index:index3,toast:toast2,defaultRichColors:richColors,duration:(_toastOptions_duration=toastOptions?.duration)!=null?_toastOptions_duration:duration,className:toastOptions?.className,descriptionClassName:toastOptions?.descriptionClassName,invert,visibleToasts,closeButton:(_toastOptions_closeButton=toastOptions?.closeButton)!=null?_toastOptions_closeButton:closeButton,interacting,position:position3,style:toastOptions?.style,unstyled:toastOptions?.unstyled,classNames:toastOptions?.classNames,cancelButtonStyle:toastOptions?.cancelButtonStyle,actionButtonStyle:toastOptions?.actionButtonStyle,closeButtonAriaLabel:toastOptions?.closeButtonAriaLabel,removeToast,toasts:filteredToasts.filter(t2=>t2.position==toast2.position),heights:heights.filter(h2=>h2.position==toast2.position),setHeights,expandByDefault:expand,gap,expanded,swipeDirections:props.swipeDirections})})):null}))},"Toaster")),Toaster2=__name(({...props})=>{const{theme="system"}=reactExports.useContext(ThemeProviderContext);return jsxRuntimeExports.jsx(Toaster$1,{theme,className:"toaster group",icons:{success:jsxRuntimeExports.jsx(CircleCheck,{className:"size-4"}),info:jsxRuntimeExports.jsx(Info$1,{className:"size-4"}),warning:jsxRuntimeExports.jsx(TriangleAlert,{className:"size-4"}),error:jsxRuntimeExports.jsx(OctagonX,{className:"size-4"}),loading:jsxRuntimeExports.jsx(LoaderCircle,{className:"size-4 animate-spin"})},toastOptions:{classNames:{toast:"bg-background text-foreground border-border"}},style:{"--normal-bg":"hsl(var(--background))","--normal-text":"hsl(var(--foreground))","--normal-border":"hsl(var(--border))","--border-radius":"var(--radius)","--toast-icon-margin-start":"0","--toast-icon-margin-end":"12px"},...props})},"Toaster");function useDemoToast(){reactExports.useEffect(()=>{if(reportData.IsDemo){let toastId;const timer=setTimeout(()=>{toastId=toast.warning(jsxRuntimeExports.jsxs("div",{className:"flex flex-col gap-2 w-full",children:[jsxRuntimeExports.jsx("div",{className:"font-semibold break-words",children:"Microsoft Zero Trust Assessment Demo Report"}),jsxRuntimeExports.jsxs("div",{className:"text-sm text-muted-foreground flex flex-col gap-1 break-words",children:[jsxRuntimeExports.jsxs("div",{className:"break-words",children:["This is a demo of the report generated by the"," ",jsxRuntimeExports.jsx("a",{href:"https://aka.ms/ZeroTrust/Assessment",target:"_blank",rel:"noopener noreferrer",className:"underline hover:text-primary break-all",onClick:__name(e3=>e3.stopPropagation(),"onClick"),children:"Zero Trust Assessment"})," ","tool."]}),jsxRuntimeExports.jsxs("div",{className:"break-words",children:["The latest version of this demo report is available at"," ",jsxRuntimeExports.jsx("a",{href:"https://aka.ms/ZeroTrust/Demo",target:"_blank",rel:"noopener noreferrer",className:"underline hover:text-primary break-all",onClick:__name(e3=>e3.stopPropagation(),"onClick"),children:"aka.ms/ZeroTrust/Demo"}),"."]})]})]}),{duration:1/0,closeButton:!0,style:{minWidth:"min(600px, calc(100vw - 32px))",maxWidth:"calc(100vw - 32px)"},className:"break-words"});const handleClick=__name(e3=>{const target=e3.target;target.tagName==="A"&&target.closest("[data-sonner-toast]")||(toast.dismiss(toastId),document.removeEventListener("click",handleClick))},"handleClick");setTimeout(()=>{document.addEventListener("click",handleClick)},100)},500);return()=>{clearTimeout(timer),toastId&&toast.dismiss(toastId)}}},[])}__name(useDemoToast,"useDemoToast");function App(){return useDemoToast(),jsxRuntimeExports.jsxs(ThemeProvider,{defaultTheme:"system",children:[jsxRuntimeExports.jsx(RouterProvider,{router}),jsxRuntimeExports.jsx(Toaster2,{position:"top-center",richColors:!0})]})}__name(App,"App");ReactDOM$2.createRoot(document.getElementById("root")).render(jsxRuntimeExports.jsx(React.StrictMode,{children:jsxRuntimeExports.jsx(App,{})})); - +`,from);return lf===-1?cr:cr===-1||cr+1===lf?lf:cr=55296&&cp<=57343}__name(isSurrogate,"isSurrogate");function isSurrogatePair(cp){return cp>=56320&&cp<=57343}__name(isSurrogatePair,"isSurrogatePair");function getSurrogatePairCodePoint(cp1,cp2){return(cp1-55296)*1024+9216+cp2}__name(getSurrogatePairCodePoint,"getSurrogatePairCodePoint");function isControlCodePoint(cp){return cp!==32&&cp!==10&&cp!==13&&cp!==9&&cp!==12&&cp>=1&&cp<=31||cp>=127&&cp<=159}__name(isControlCodePoint,"isControlCodePoint");function isUndefinedCodePoint(cp){return cp>=64976&&cp<=65007||UNDEFINED_CODE_POINTS.has(cp)}__name(isUndefinedCodePoint,"isUndefinedCodePoint");var ERR;(function(ERR2){ERR2.controlCharacterInInputStream="control-character-in-input-stream",ERR2.noncharacterInInputStream="noncharacter-in-input-stream",ERR2.surrogateInInputStream="surrogate-in-input-stream",ERR2.nonVoidHtmlElementStartTagWithTrailingSolidus="non-void-html-element-start-tag-with-trailing-solidus",ERR2.endTagWithAttributes="end-tag-with-attributes",ERR2.endTagWithTrailingSolidus="end-tag-with-trailing-solidus",ERR2.unexpectedSolidusInTag="unexpected-solidus-in-tag",ERR2.unexpectedNullCharacter="unexpected-null-character",ERR2.unexpectedQuestionMarkInsteadOfTagName="unexpected-question-mark-instead-of-tag-name",ERR2.invalidFirstCharacterOfTagName="invalid-first-character-of-tag-name",ERR2.unexpectedEqualsSignBeforeAttributeName="unexpected-equals-sign-before-attribute-name",ERR2.missingEndTagName="missing-end-tag-name",ERR2.unexpectedCharacterInAttributeName="unexpected-character-in-attribute-name",ERR2.unknownNamedCharacterReference="unknown-named-character-reference",ERR2.missingSemicolonAfterCharacterReference="missing-semicolon-after-character-reference",ERR2.unexpectedCharacterAfterDoctypeSystemIdentifier="unexpected-character-after-doctype-system-identifier",ERR2.unexpectedCharacterInUnquotedAttributeValue="unexpected-character-in-unquoted-attribute-value",ERR2.eofBeforeTagName="eof-before-tag-name",ERR2.eofInTag="eof-in-tag",ERR2.missingAttributeValue="missing-attribute-value",ERR2.missingWhitespaceBetweenAttributes="missing-whitespace-between-attributes",ERR2.missingWhitespaceAfterDoctypePublicKeyword="missing-whitespace-after-doctype-public-keyword",ERR2.missingWhitespaceBetweenDoctypePublicAndSystemIdentifiers="missing-whitespace-between-doctype-public-and-system-identifiers",ERR2.missingWhitespaceAfterDoctypeSystemKeyword="missing-whitespace-after-doctype-system-keyword",ERR2.missingQuoteBeforeDoctypePublicIdentifier="missing-quote-before-doctype-public-identifier",ERR2.missingQuoteBeforeDoctypeSystemIdentifier="missing-quote-before-doctype-system-identifier",ERR2.missingDoctypePublicIdentifier="missing-doctype-public-identifier",ERR2.missingDoctypeSystemIdentifier="missing-doctype-system-identifier",ERR2.abruptDoctypePublicIdentifier="abrupt-doctype-public-identifier",ERR2.abruptDoctypeSystemIdentifier="abrupt-doctype-system-identifier",ERR2.cdataInHtmlContent="cdata-in-html-content",ERR2.incorrectlyOpenedComment="incorrectly-opened-comment",ERR2.eofInScriptHtmlCommentLikeText="eof-in-script-html-comment-like-text",ERR2.eofInDoctype="eof-in-doctype",ERR2.nestedComment="nested-comment",ERR2.abruptClosingOfEmptyComment="abrupt-closing-of-empty-comment",ERR2.eofInComment="eof-in-comment",ERR2.incorrectlyClosedComment="incorrectly-closed-comment",ERR2.eofInCdata="eof-in-cdata",ERR2.absenceOfDigitsInNumericCharacterReference="absence-of-digits-in-numeric-character-reference",ERR2.nullCharacterReference="null-character-reference",ERR2.surrogateCharacterReference="surrogate-character-reference",ERR2.characterReferenceOutsideUnicodeRange="character-reference-outside-unicode-range",ERR2.controlCharacterReference="control-character-reference",ERR2.noncharacterCharacterReference="noncharacter-character-reference",ERR2.missingWhitespaceBeforeDoctypeName="missing-whitespace-before-doctype-name",ERR2.missingDoctypeName="missing-doctype-name",ERR2.invalidCharacterSequenceAfterDoctypeName="invalid-character-sequence-after-doctype-name",ERR2.duplicateAttribute="duplicate-attribute",ERR2.nonConformingDoctype="non-conforming-doctype",ERR2.missingDoctype="missing-doctype",ERR2.misplacedDoctype="misplaced-doctype",ERR2.endTagWithoutMatchingOpenElement="end-tag-without-matching-open-element",ERR2.closingOfElementWithOpenChildElements="closing-of-element-with-open-child-elements",ERR2.disallowedContentInNoscriptInHead="disallowed-content-in-noscript-in-head",ERR2.openElementsLeftAfterEof="open-elements-left-after-eof",ERR2.abandonedHeadElementChild="abandoned-head-element-child",ERR2.misplacedStartTagForHeadElement="misplaced-start-tag-for-head-element",ERR2.nestedNoscriptInHead="nested-noscript-in-head",ERR2.eofInElementThatCanContainOnlyText="eof-in-element-that-can-contain-only-text"})(ERR||(ERR={}));const DEFAULT_BUFFER_WATERLINE=65536,_Preprocessor=class _Preprocessor{constructor(handler){this.handler=handler,this.html="",this.pos=-1,this.lastGapPos=-2,this.gapStack=[],this.skipNextNewLine=!1,this.lastChunkWritten=!1,this.endOfChunkHit=!1,this.bufferWaterline=DEFAULT_BUFFER_WATERLINE,this.isEol=!1,this.lineStartPos=0,this.droppedBufferSize=0,this.line=1,this.lastErrOffset=-1}get col(){return this.pos-this.lineStartPos+ +(this.lastGapPos!==this.pos)}get offset(){return this.droppedBufferSize+this.pos}getError(code2,cpOffset){const{line,col,offset:offset2}=this,startCol=col+cpOffset,startOffset=offset2+cpOffset;return{code:code2,startLine:line,endLine:line,startCol,endCol:startCol,startOffset,endOffset:startOffset}}_err(code2){this.handler.onParseError&&this.lastErrOffset!==this.offset&&(this.lastErrOffset=this.offset,this.handler.onParseError(this.getError(code2,0)))}_addGap(){this.gapStack.push(this.lastGapPos),this.lastGapPos=this.pos}_processSurrogate(cp){if(this.pos!==this.html.length-1){const nextCp=this.html.charCodeAt(this.pos+1);if(isSurrogatePair(nextCp))return this.pos++,this._addGap(),getSurrogatePairCodePoint(cp,nextCp)}else if(!this.lastChunkWritten)return this.endOfChunkHit=!0,CODE_POINTS.EOF;return this._err(ERR.surrogateInInputStream),cp}willDropParsedChunk(){return this.pos>this.bufferWaterline}dropParsedChunk(){this.willDropParsedChunk()&&(this.html=this.html.substring(this.pos),this.lineStartPos-=this.pos,this.droppedBufferSize+=this.pos,this.pos=0,this.lastGapPos=-2,this.gapStack.length=0)}write(chunk,isLastChunk){this.html.length>0?this.html+=chunk:this.html=chunk,this.endOfChunkHit=!1,this.lastChunkWritten=isLastChunk}insertHtmlAtCurrentPos(chunk){this.html=this.html.substring(0,this.pos+1)+chunk+this.html.substring(this.pos+1),this.endOfChunkHit=!1}startsWith(pattern,caseSensitive){if(this.pos+pattern.length>this.html.length)return this.endOfChunkHit=!this.lastChunkWritten,!1;if(caseSensitive)return this.html.startsWith(pattern,this.pos);for(let i2=0;i2=this.html.length)return this.endOfChunkHit=!this.lastChunkWritten,CODE_POINTS.EOF;const code2=this.html.charCodeAt(pos);return code2===CODE_POINTS.CARRIAGE_RETURN?CODE_POINTS.LINE_FEED:code2}advance(){if(this.pos++,this.isEol&&(this.isEol=!1,this.line++,this.lineStartPos=this.pos),this.pos>=this.html.length)return this.endOfChunkHit=!this.lastChunkWritten,CODE_POINTS.EOF;let cp=this.html.charCodeAt(this.pos);return cp===CODE_POINTS.CARRIAGE_RETURN?(this.isEol=!0,this.skipNextNewLine=!0,CODE_POINTS.LINE_FEED):cp===CODE_POINTS.LINE_FEED&&(this.isEol=!0,this.skipNextNewLine)?(this.line--,this.skipNextNewLine=!1,this._addGap(),this.advance()):(this.skipNextNewLine=!1,isSurrogate(cp)&&(cp=this._processSurrogate(cp)),this.handler.onParseError===null||cp>31&&cp<127||cp===CODE_POINTS.LINE_FEED||cp===CODE_POINTS.CARRIAGE_RETURN||cp>159&&cp<64976||this._checkForProblematicCharacters(cp),cp)}_checkForProblematicCharacters(cp){isControlCodePoint(cp)?this._err(ERR.controlCharacterInInputStream):isUndefinedCodePoint(cp)&&this._err(ERR.noncharacterInInputStream)}retreat(count2){for(this.pos-=count2;this.pos=0;i2--)if(token.attrs[i2].name===attrName)return token.attrs[i2].value;return null}__name(getTokenAttr,"getTokenAttr");const htmlDecodeTree=new Uint16Array('ᵁ<Õıʊҝջאٵ۞ޢߖࠏ੊ઑඡ๭༉༦჊ረዡᐕᒝᓃᓟᔥ\0\0\0\0\0\0ᕫᛍᦍᰒᷝ὾⁠↰⊍⏀⏻⑂⠤⤒ⴈ⹈⿎〖㊺㘹㞬㣾㨨㩱㫠㬮ࠀEMabcfglmnoprstu\\bfms„‹•˜¦³¹ÈÏlig耻Æ䃆P耻&䀦cute耻Á䃁reve;䄂Āiyx}rc耻Â䃂;䐐r;쀀𝔄rave耻À䃀pha;䎑acr;䄀d;橓Āgp¡on;䄄f;쀀𝔸plyFunction;恡ing耻Å䃅Ācs¾Ãr;쀀𝒜ign;扔ilde耻Ã䃃ml耻Ä䃄ЀaceforsuåûþėĜĢħĪĀcrêòkslash;或Ŷöø;櫧ed;挆y;䐑ƀcrtąċĔause;戵noullis;愬a;䎒r;쀀𝔅pf;쀀𝔹eve;䋘còēmpeq;扎܀HOacdefhilorsuōőŖƀƞƢƵƷƺǜȕɳɸɾcy;䐧PY耻©䂩ƀcpyŝŢźute;䄆Ā;iŧŨ拒talDifferentialD;慅leys;愭ȀaeioƉƎƔƘron;䄌dil耻Ç䃇rc;䄈nint;戰ot;䄊ĀdnƧƭilla;䂸terDot;䂷òſi;䎧rcleȀDMPTLJNjǑǖot;抙inus;抖lus;投imes;抗oĀcsǢǸkwiseContourIntegral;戲eCurlyĀDQȃȏoubleQuote;思uote;怙ȀlnpuȞȨɇɕonĀ;eȥȦ户;橴ƀgitȯȶȺruent;扡nt;戯ourIntegral;戮ĀfrɌɎ;愂oduct;成nterClockwiseContourIntegral;戳oss;樯cr;쀀𝒞pĀ;Cʄʅ拓ap;才րDJSZacefiosʠʬʰʴʸˋ˗ˡ˦̳ҍĀ;oŹʥtrahd;椑cy;䐂cy;䐅cy;䐏ƀgrsʿ˄ˇger;怡r;憡hv;櫤Āayː˕ron;䄎;䐔lĀ;t˝˞戇a;䎔r;쀀𝔇Āaf˫̧Ācm˰̢riticalȀADGT̖̜̀̆cute;䂴oŴ̋̍;䋙bleAcute;䋝rave;䁠ilde;䋜ond;拄ferentialD;慆Ѱ̽\0\0\0͔͂\0Ѕf;쀀𝔻ƀ;DE͈͉͍䂨ot;惜qual;扐blèCDLRUVͣͲ΂ϏϢϸontourIntegraìȹoɴ͹\0\0ͻ»͉nArrow;懓Āeo·ΤftƀARTΐΖΡrrow;懐ightArrow;懔eåˊngĀLRΫτeftĀARγιrrow;柸ightArrow;柺ightArrow;柹ightĀATϘϞrrow;懒ee;抨pɁϩ\0\0ϯrrow;懑ownArrow;懕erticalBar;戥ǹABLRTaВЪаўѿͼrrowƀ;BUНОТ憓ar;椓pArrow;懵reve;䌑eft˒к\0ц\0ѐightVector;楐eeVector;楞ectorĀ;Bљњ憽ar;楖ightǔѧ\0ѱeeVector;楟ectorĀ;BѺѻ懁ar;楗eeĀ;A҆҇护rrow;憧ĀctҒҗr;쀀𝒟rok;䄐ࠀNTacdfglmopqstuxҽӀӄӋӞӢӧӮӵԡԯԶՒ՝ՠեG;䅊H耻Ð䃐cute耻É䃉ƀaiyӒӗӜron;䄚rc耻Ê䃊;䐭ot;䄖r;쀀𝔈rave耻È䃈ement;戈ĀapӺӾcr;䄒tyɓԆ\0\0ԒmallSquare;旻erySmallSquare;斫ĀgpԦԪon;䄘f;쀀𝔼silon;䎕uĀaiԼՉlĀ;TՂՃ橵ilde;扂librium;懌Āci՗՚r;愰m;橳a;䎗ml耻Ë䃋Āipժկsts;戃onentialE;慇ʀcfiosօֈ֍ֲ׌y;䐤r;쀀𝔉lledɓ֗\0\0֣mallSquare;旼erySmallSquare;斪Ͱֺ\0ֿ\0\0ׄf;쀀𝔽All;戀riertrf;愱cò׋؀JTabcdfgorstר׬ׯ׺؀ؒؖ؛؝أ٬ٲcy;䐃耻>䀾mmaĀ;d׷׸䎓;䏜reve;䄞ƀeiy؇،ؐdil;䄢rc;䄜;䐓ot;䄠r;쀀𝔊;拙pf;쀀𝔾eater̀EFGLSTصلَٖٛ٦qualĀ;Lؾؿ扥ess;招ullEqual;执reater;檢ess;扷lantEqual;橾ilde;扳cr;쀀𝒢;扫ЀAacfiosuڅڋږڛڞڪھۊRDcy;䐪Āctڐڔek;䋇;䁞irc;䄤r;愌lbertSpace;愋ǰگ\0ڲf;愍izontalLine;攀Āctۃۅòکrok;䄦mpńېۘownHumðįqual;扏܀EJOacdfgmnostuۺ۾܃܇܎ܚܞܡܨ݄ݸދޏޕcy;䐕lig;䄲cy;䐁cute耻Í䃍Āiyܓܘrc耻Î䃎;䐘ot;䄰r;愑rave耻Ì䃌ƀ;apܠܯܿĀcgܴܷr;䄪inaryI;慈lieóϝǴ݉\0ݢĀ;eݍݎ戬Āgrݓݘral;戫section;拂isibleĀCTݬݲomma;恣imes;恢ƀgptݿރވon;䄮f;쀀𝕀a;䎙cr;愐ilde;䄨ǫޚ\0ޞcy;䐆l耻Ï䃏ʀcfosuެ޷޼߂ߐĀiyޱ޵rc;䄴;䐙r;쀀𝔍pf;쀀𝕁ǣ߇\0ߌr;쀀𝒥rcy;䐈kcy;䐄΀HJacfosߤߨ߽߬߱ࠂࠈcy;䐥cy;䐌ppa;䎚Āey߶߻dil;䄶;䐚r;쀀𝔎pf;쀀𝕂cr;쀀𝒦րJTaceflmostࠥࠩࠬࡐࡣ঳সে্਷ੇcy;䐉耻<䀼ʀcmnpr࠷࠼ࡁࡄࡍute;䄹bda;䎛g;柪lacetrf;愒r;憞ƀaeyࡗ࡜ࡡron;䄽dil;䄻;䐛Āfsࡨ॰tԀACDFRTUVarࡾࢩࢱࣦ࣠ࣼयज़ΐ४Ānrࢃ࢏gleBracket;柨rowƀ;BR࢙࢚࢞憐ar;懤ightArrow;懆eiling;挈oǵࢷ\0ࣃbleBracket;柦nǔࣈ\0࣒eeVector;楡ectorĀ;Bࣛࣜ懃ar;楙loor;挊ightĀAV࣯ࣵrrow;憔ector;楎Āerँगeƀ;AVउऊऐ抣rrow;憤ector;楚iangleƀ;BEतथऩ抲ar;槏qual;抴pƀDTVषूौownVector;楑eeVector;楠ectorĀ;Bॖॗ憿ar;楘ectorĀ;B॥०憼ar;楒ightáΜs̀EFGLSTॾঋকঝঢভqualGreater;拚ullEqual;扦reater;扶ess;檡lantEqual;橽ilde;扲r;쀀𝔏Ā;eঽা拘ftarrow;懚idot;䄿ƀnpw৔ਖਛgȀLRlr৞৷ਂਐeftĀAR০৬rrow;柵ightArrow;柷ightArrow;柶eftĀarγਊightáοightáϊf;쀀𝕃erĀLRਢਬeftArrow;憙ightArrow;憘ƀchtਾੀੂòࡌ;憰rok;䅁;扪Ѐacefiosuਗ਼੝੠੷੼અઋ઎p;椅y;䐜Ādl੥੯iumSpace;恟lintrf;愳r;쀀𝔐nusPlus;戓pf;쀀𝕄cò੶;䎜ҀJacefostuણધભીଔଙඑ඗ඞcy;䐊cute;䅃ƀaey઴હાron;䅇dil;䅅;䐝ƀgswે૰଎ativeƀMTV૓૟૨ediumSpace;怋hiĀcn૦૘ë૙eryThiî૙tedĀGL૸ଆreaterGreateòٳessLesóੈLine;䀊r;쀀𝔑ȀBnptଢନଷ଺reak;恠BreakingSpace;䂠f;愕ڀ;CDEGHLNPRSTV୕ୖ୪୼஡௫ఄ౞಄ದ೘ൡඅ櫬Āou୛୤ngruent;扢pCap;扭oubleVerticalBar;戦ƀlqxஃஊ஛ement;戉ualĀ;Tஒஓ扠ilde;쀀≂̸ists;戄reater΀;EFGLSTஶஷ஽௉௓௘௥扯qual;扱ullEqual;쀀≧̸reater;쀀≫̸ess;批lantEqual;쀀⩾̸ilde;扵umpń௲௽ownHump;쀀≎̸qual;쀀≏̸eĀfsఊధtTriangleƀ;BEచఛడ拪ar;쀀⧏̸qual;括s̀;EGLSTవశ఼ౄోౘ扮qual;扰reater;扸ess;쀀≪̸lantEqual;쀀⩽̸ilde;扴estedĀGL౨౹reaterGreater;쀀⪢̸essLess;쀀⪡̸recedesƀ;ESಒಓಛ技qual;쀀⪯̸lantEqual;拠ĀeiಫಹverseElement;戌ghtTriangleƀ;BEೋೌ೒拫ar;쀀⧐̸qual;拭ĀquೝഌuareSuĀbp೨೹setĀ;E೰ೳ쀀⊏̸qual;拢ersetĀ;Eഃആ쀀⊐̸qual;拣ƀbcpഓതൎsetĀ;Eഛഞ쀀⊂⃒qual;抈ceedsȀ;ESTലള഻െ抁qual;쀀⪰̸lantEqual;拡ilde;쀀≿̸ersetĀ;E൘൛쀀⊃⃒qual;抉ildeȀ;EFT൮൯൵ൿ扁qual;扄ullEqual;扇ilde;扉erticalBar;戤cr;쀀𝒩ilde耻Ñ䃑;䎝܀Eacdfgmoprstuvලෂ෉෕ෛ෠෧෼ขภยา฿ไlig;䅒cute耻Ó䃓Āiy෎ීrc耻Ô䃔;䐞blac;䅐r;쀀𝔒rave耻Ò䃒ƀaei෮ෲ෶cr;䅌ga;䎩cron;䎟pf;쀀𝕆enCurlyĀDQฎบoubleQuote;怜uote;怘;橔Āclวฬr;쀀𝒪ash耻Ø䃘iŬื฼de耻Õ䃕es;樷ml耻Ö䃖erĀBP๋๠Āar๐๓r;怾acĀek๚๜;揞et;掴arenthesis;揜Ҁacfhilors๿ງຊຏຒດຝະ໼rtialD;戂y;䐟r;쀀𝔓i;䎦;䎠usMinus;䂱Āipຢອncareplanåڝf;愙Ȁ;eio຺ູ໠໤檻cedesȀ;EST່້໏໚扺qual;檯lantEqual;扼ilde;找me;怳Ādp໩໮uct;戏ortionĀ;aȥ໹l;戝Āci༁༆r;쀀𝒫;䎨ȀUfos༑༖༛༟OT耻"䀢r;쀀𝔔pf;愚cr;쀀𝒬؀BEacefhiorsu༾གྷཇའཱིྦྷྪྭ႖ႩႴႾarr;椐G耻®䂮ƀcnrཎནབute;䅔g;柫rĀ;tཛྷཝ憠l;椖ƀaeyཧཬཱron;䅘dil;䅖;䐠Ā;vླྀཹ愜erseĀEUྂྙĀlq྇ྎement;戋uilibrium;懋pEquilibrium;楯r»ཹo;䎡ghtЀACDFTUVa࿁࿫࿳ဢဨၛႇϘĀnr࿆࿒gleBracket;柩rowƀ;BL࿜࿝࿡憒ar;懥eftArrow;懄eiling;按oǵ࿹\0စbleBracket;柧nǔည\0နeeVector;楝ectorĀ;Bဝသ懂ar;楕loor;挋Āerိ၃eƀ;AVဵံြ抢rrow;憦ector;楛iangleƀ;BEၐၑၕ抳ar;槐qual;抵pƀDTVၣၮၸownVector;楏eeVector;楜ectorĀ;Bႂႃ憾ar;楔ectorĀ;B႑႒懀ar;楓Āpuႛ႞f;愝ndImplies;楰ightarrow;懛ĀchႹႼr;愛;憱leDelayed;槴ڀHOacfhimoqstuფჱჷჽᄙᄞᅑᅖᅡᅧᆵᆻᆿĀCcჩხHcy;䐩y;䐨FTcy;䐬cute;䅚ʀ;aeiyᄈᄉᄎᄓᄗ檼ron;䅠dil;䅞rc;䅜;䐡r;쀀𝔖ortȀDLRUᄪᄴᄾᅉownArrow»ОeftArrow»࢚ightArrow»࿝pArrow;憑gma;䎣allCircle;战pf;쀀𝕊ɲᅭ\0\0ᅰt;戚areȀ;ISUᅻᅼᆉᆯ斡ntersection;抓uĀbpᆏᆞsetĀ;Eᆗᆘ抏qual;抑ersetĀ;Eᆨᆩ抐qual;抒nion;抔cr;쀀𝒮ar;拆ȀbcmpᇈᇛሉላĀ;sᇍᇎ拐etĀ;Eᇍᇕqual;抆ĀchᇠህeedsȀ;ESTᇭᇮᇴᇿ扻qual;檰lantEqual;扽ilde;承Tháྌ;我ƀ;esሒሓሣ拑rsetĀ;Eሜም抃qual;抇et»ሓրHRSacfhiorsሾቄ቉ቕ቞ቱቶኟዂወዑORN耻Þ䃞ADE;愢ĀHc቎ቒcy;䐋y;䐦Ābuቚቜ;䀉;䎤ƀaeyብቪቯron;䅤dil;䅢;䐢r;쀀𝔗Āeiቻ኉Dzኀ\0ኇefore;戴a;䎘Ācn኎ኘkSpace;쀀  Space;怉ldeȀ;EFTካኬኲኼ戼qual;扃ullEqual;扅ilde;扈pf;쀀𝕋ipleDot;惛Āctዖዛr;쀀𝒯rok;䅦ૡዷጎጚጦ\0ጬጱ\0\0\0\0\0ጸጽ፷ᎅ\0᏿ᐄᐊᐐĀcrዻጁute耻Ú䃚rĀ;oጇገ憟cir;楉rǣጓ\0጖y;䐎ve;䅬Āiyጞጣrc耻Û䃛;䐣blac;䅰r;쀀𝔘rave耻Ù䃙acr;䅪Ādiፁ፩erĀBPፈ፝Āarፍፐr;䁟acĀekፗፙ;揟et;掵arenthesis;揝onĀ;P፰፱拃lus;抎Āgp፻፿on;䅲f;쀀𝕌ЀADETadps᎕ᎮᎸᏄϨᏒᏗᏳrrowƀ;BDᅐᎠᎤar;椒ownArrow;懅ownArrow;憕quilibrium;楮eeĀ;AᏋᏌ报rrow;憥ownáϳerĀLRᏞᏨeftArrow;憖ightArrow;憗iĀ;lᏹᏺ䏒on;䎥ing;䅮cr;쀀𝒰ilde;䅨ml耻Ü䃜ҀDbcdefosvᐧᐬᐰᐳᐾᒅᒊᒐᒖash;披ar;櫫y;䐒ashĀ;lᐻᐼ抩;櫦Āerᑃᑅ;拁ƀbtyᑌᑐᑺar;怖Ā;iᑏᑕcalȀBLSTᑡᑥᑪᑴar;戣ine;䁼eparator;杘ilde;所ThinSpace;怊r;쀀𝔙pf;쀀𝕍cr;쀀𝒱dash;抪ʀcefosᒧᒬᒱᒶᒼirc;䅴dge;拀r;쀀𝔚pf;쀀𝕎cr;쀀𝒲Ȁfiosᓋᓐᓒᓘr;쀀𝔛;䎞pf;쀀𝕏cr;쀀𝒳ҀAIUacfosuᓱᓵᓹᓽᔄᔏᔔᔚᔠcy;䐯cy;䐇cy;䐮cute耻Ý䃝Āiyᔉᔍrc;䅶;䐫r;쀀𝔜pf;쀀𝕐cr;쀀𝒴ml;䅸ЀHacdefosᔵᔹᔿᕋᕏᕝᕠᕤcy;䐖cute;䅹Āayᕄᕉron;䅽;䐗ot;䅻Dzᕔ\0ᕛoWidtè૙a;䎖r;愨pf;愤cr;쀀𝒵௡ᖃᖊᖐ\0ᖰᖶᖿ\0\0\0\0ᗆᗛᗫᙟ᙭\0ᚕ᚛ᚲᚹ\0ᚾcute耻á䃡reve;䄃̀;Ediuyᖜᖝᖡᖣᖨᖭ戾;쀀∾̳;房rc耻â䃢te肻´̆;䐰lig耻æ䃦Ā;r²ᖺ;쀀𝔞rave耻à䃠ĀepᗊᗖĀfpᗏᗔsym;愵èᗓha;䎱ĀapᗟcĀclᗤᗧr;䄁g;樿ɤᗰ\0\0ᘊʀ;adsvᗺᗻᗿᘁᘇ戧nd;橕;橜lope;橘;橚΀;elmrszᘘᘙᘛᘞᘿᙏᙙ戠;榤e»ᘙsdĀ;aᘥᘦ戡ѡᘰᘲᘴᘶᘸᘺᘼᘾ;榨;榩;榪;榫;榬;榭;榮;榯tĀ;vᙅᙆ戟bĀ;dᙌᙍ抾;榝Āptᙔᙗh;戢»¹arr;捼Āgpᙣᙧon;䄅f;쀀𝕒΀;Eaeiop዁ᙻᙽᚂᚄᚇᚊ;橰cir;橯;扊d;手s;䀧roxĀ;e዁ᚒñᚃing耻å䃥ƀctyᚡᚦᚨr;쀀𝒶;䀪mpĀ;e዁ᚯñʈilde耻ã䃣ml耻ä䃤Āciᛂᛈoninôɲnt;樑ࠀNabcdefiklnoprsu᛭ᛱᜰ᜼ᝃᝈ᝸᝽០៦ᠹᡐᜍ᤽᥈ᥰot;櫭Ācrᛶ᜞kȀcepsᜀᜅᜍᜓong;扌psilon;䏶rime;怵imĀ;e᜚᜛戽q;拍Ŷᜢᜦee;抽edĀ;gᜬᜭ挅e»ᜭrkĀ;t፜᜷brk;掶Āoyᜁᝁ;䐱quo;怞ʀcmprtᝓ᝛ᝡᝤᝨausĀ;eĊĉptyv;榰séᜌnoõēƀahwᝯ᝱ᝳ;䎲;愶een;扬r;쀀𝔟g΀costuvwឍឝឳេ៕៛៞ƀaiuបពរðݠrc;旯p»፱ƀdptឤឨឭot;樀lus;樁imes;樂ɱឹ\0\0ើcup;樆ar;昅riangleĀdu៍្own;施p;斳plus;樄eåᑄåᒭarow;植ƀako៭ᠦᠵĀcn៲ᠣkƀlst៺֫᠂ozenge;槫riangleȀ;dlr᠒᠓᠘᠝斴own;斾eft;旂ight;斸k;搣Ʊᠫ\0ᠳƲᠯ\0ᠱ;斒;斑4;斓ck;斈ĀeoᠾᡍĀ;qᡃᡆ쀀=⃥uiv;쀀≡⃥t;挐Ȁptwxᡙᡞᡧᡬf;쀀𝕓Ā;tᏋᡣom»Ꮜtie;拈؀DHUVbdhmptuvᢅᢖᢪᢻᣗᣛᣬ᣿ᤅᤊᤐᤡȀLRlrᢎᢐᢒᢔ;敗;敔;敖;敓ʀ;DUduᢡᢢᢤᢦᢨ敐;敦;敩;敤;敧ȀLRlrᢳᢵᢷᢹ;敝;敚;敜;教΀;HLRhlrᣊᣋᣍᣏᣑᣓᣕ救;敬;散;敠;敫;敢;敟ox;槉ȀLRlrᣤᣦᣨᣪ;敕;敒;攐;攌ʀ;DUduڽ᣷᣹᣻᣽;敥;敨;攬;攴inus;抟lus;択imes;抠ȀLRlrᤙᤛᤝ᤟;敛;敘;攘;攔΀;HLRhlrᤰᤱᤳᤵᤷ᤻᤹攂;敪;敡;敞;攼;攤;攜Āevģ᥂bar耻¦䂦Ȁceioᥑᥖᥚᥠr;쀀𝒷mi;恏mĀ;e᜚᜜lƀ;bhᥨᥩᥫ䁜;槅sub;柈Ŭᥴ᥾lĀ;e᥹᥺怢t»᥺pƀ;Eeįᦅᦇ;檮Ā;qۜۛೡᦧ\0᧨ᨑᨕᨲ\0ᨷᩐ\0\0᪴\0\0᫁\0\0ᬡᬮ᭍᭒\0᯽\0ᰌƀcpr᦭ᦲ᧝ute;䄇̀;abcdsᦿᧀᧄ᧊᧕᧙戩nd;橄rcup;橉Āau᧏᧒p;橋p;橇ot;橀;쀀∩︀Āeo᧢᧥t;恁îړȀaeiu᧰᧻ᨁᨅǰ᧵\0᧸s;橍on;䄍dil耻ç䃧rc;䄉psĀ;sᨌᨍ橌m;橐ot;䄋ƀdmnᨛᨠᨦil肻¸ƭptyv;榲t脀¢;eᨭᨮ䂢räƲr;쀀𝔠ƀceiᨽᩀᩍy;䑇ckĀ;mᩇᩈ朓ark»ᩈ;䏇r΀;Ecefms᩟᩠ᩢᩫ᪤᪪᪮旋;槃ƀ;elᩩᩪᩭ䋆q;扗eɡᩴ\0\0᪈rrowĀlr᩼᪁eft;憺ight;憻ʀRSacd᪒᪔᪖᪚᪟»ཇ;擈st;抛irc;抚ash;抝nint;樐id;櫯cir;槂ubsĀ;u᪻᪼晣it»᪼ˬ᫇᫔᫺\0ᬊonĀ;eᫍᫎ䀺Ā;qÇÆɭ᫙\0\0᫢aĀ;t᫞᫟䀬;䁀ƀ;fl᫨᫩᫫戁îᅠeĀmx᫱᫶ent»᫩eóɍǧ᫾\0ᬇĀ;dኻᬂot;橭nôɆƀfryᬐᬔᬗ;쀀𝕔oäɔ脀©;sŕᬝr;愗Āaoᬥᬩrr;憵ss;朗Ācuᬲᬷr;쀀𝒸Ābpᬼ᭄Ā;eᭁᭂ櫏;櫑Ā;eᭉᭊ櫐;櫒dot;拯΀delprvw᭠᭬᭷ᮂᮬᯔ᯹arrĀlr᭨᭪;椸;椵ɰ᭲\0\0᭵r;拞c;拟arrĀ;p᭿ᮀ憶;椽̀;bcdosᮏᮐᮖᮡᮥᮨ截rcap;橈Āauᮛᮞp;橆p;橊ot;抍r;橅;쀀∪︀Ȁalrv᮵ᮿᯞᯣrrĀ;mᮼᮽ憷;椼yƀevwᯇᯔᯘqɰᯎ\0\0ᯒreã᭳uã᭵ee;拎edge;拏en耻¤䂤earrowĀlrᯮ᯳eft»ᮀight»ᮽeäᯝĀciᰁᰇoninôǷnt;戱lcty;挭ঀAHabcdefhijlorstuwz᰸᰻᰿ᱝᱩᱵᲊᲞᲬᲷ᳻᳿ᴍᵻᶑᶫᶻ᷆᷍rò΁ar;楥Ȁglrs᱈ᱍ᱒᱔ger;怠eth;愸òᄳhĀ;vᱚᱛ怐»ऊūᱡᱧarow;椏aã̕Āayᱮᱳron;䄏;䐴ƀ;ao̲ᱼᲄĀgrʿᲁr;懊tseq;橷ƀglmᲑᲔᲘ耻°䂰ta;䎴ptyv;榱ĀirᲣᲨsht;楿;쀀𝔡arĀlrᲳᲵ»ࣜ»သʀaegsv᳂͸᳖᳜᳠mƀ;oș᳊᳔ndĀ;ș᳑uit;晦amma;䏝in;拲ƀ;io᳧᳨᳸䃷de脀÷;o᳧ᳰntimes;拇nø᳷cy;䑒cɯᴆ\0\0ᴊrn;挞op;挍ʀlptuwᴘᴝᴢᵉᵕlar;䀤f;쀀𝕕ʀ;emps̋ᴭᴷᴽᵂqĀ;d͒ᴳot;扑inus;戸lus;戔quare;抡blebarwedgåúnƀadhᄮᵝᵧownarrowóᲃarpoonĀlrᵲᵶefôᲴighôᲶŢᵿᶅkaro÷གɯᶊ\0\0ᶎrn;挟op;挌ƀcotᶘᶣᶦĀryᶝᶡ;쀀𝒹;䑕l;槶rok;䄑Ādrᶰᶴot;拱iĀ;fᶺ᠖斿Āah᷀᷃ròЩaòྦangle;榦Āci᷒ᷕy;䑟grarr;柿ऀDacdefglmnopqrstuxḁḉḙḸոḼṉṡṾấắẽỡἪἷὄ὎὚ĀDoḆᴴoôᲉĀcsḎḔute耻é䃩ter;橮ȀaioyḢḧḱḶron;䄛rĀ;cḭḮ扖耻ê䃪lon;払;䑍ot;䄗ĀDrṁṅot;扒;쀀𝔢ƀ;rsṐṑṗ檚ave耻è䃨Ā;dṜṝ檖ot;檘Ȁ;ilsṪṫṲṴ檙nters;揧;愓Ā;dṹṺ檕ot;檗ƀapsẅẉẗcr;䄓tyƀ;svẒẓẕ戅et»ẓpĀ1;ẝẤijạả;怄;怅怃ĀgsẪẬ;䅋p;怂ĀgpẴẸon;䄙f;쀀𝕖ƀalsỄỎỒrĀ;sỊị拕l;槣us;橱iƀ;lvỚớở䎵on»ớ;䏵ȀcsuvỪỳἋἣĀioữḱrc»Ḯɩỹ\0\0ỻíՈantĀglἂἆtr»ṝess»Ṻƀaeiἒ἖Ἒls;䀽st;扟vĀ;DȵἠD;橸parsl;槥ĀDaἯἳot;打rr;楱ƀcdiἾὁỸr;愯oô͒ĀahὉὋ;䎷耻ð䃰Āmrὓὗl耻ë䃫o;悬ƀcipὡὤὧl;䀡sôծĀeoὬὴctatioîՙnentialåչৡᾒ\0ᾞ\0ᾡᾧ\0\0ῆῌ\0ΐ\0ῦῪ \0 ⁚llingdotseñṄy;䑄male;晀ƀilrᾭᾳ῁lig;耀ffiɩᾹ\0\0᾽g;耀ffig;耀ffl;쀀𝔣lig;耀filig;쀀fjƀaltῙ῜ῡt;晭ig;耀flns;斱of;䆒ǰ΅\0ῳf;쀀𝕗ĀakֿῷĀ;vῼ´拔;櫙artint;樍Āao‌⁕Ācs‑⁒ႉ‸⁅⁈\0⁐β•‥‧‪‬\0‮耻½䂽;慓耻¼䂼;慕;慙;慛Ƴ‴\0‶;慔;慖ʴ‾⁁\0\0⁃耻¾䂾;慗;慜5;慘ƶ⁌\0⁎;慚;慝8;慞l;恄wn;挢cr;쀀𝒻ࢀEabcdefgijlnorstv₂₉₟₥₰₴⃰⃵⃺⃿℃ℒℸ̗ℾ⅒↞Ā;lٍ₇;檌ƀcmpₐₕ₝ute;䇵maĀ;dₜ᳚䎳;檆reve;䄟Āiy₪₮rc;䄝;䐳ot;䄡Ȁ;lqsؾق₽⃉ƀ;qsؾٌ⃄lanô٥Ȁ;cdl٥⃒⃥⃕c;檩otĀ;o⃜⃝檀Ā;l⃢⃣檂;檄Ā;e⃪⃭쀀⋛︀s;檔r;쀀𝔤Ā;gٳ؛mel;愷cy;䑓Ȁ;Eajٚℌℎℐ;檒;檥;檤ȀEaesℛℝ℩ℴ;扩pĀ;p℣ℤ檊rox»ℤĀ;q℮ℯ檈Ā;q℮ℛim;拧pf;쀀𝕘Āci⅃ⅆr;愊mƀ;el٫ⅎ⅐;檎;檐茀>;cdlqr׮ⅠⅪⅮⅳⅹĀciⅥⅧ;檧r;橺ot;拗Par;榕uest;橼ʀadelsↄⅪ←ٖ↛ǰ↉\0↎proø₞r;楸qĀlqؿ↖lesó₈ií٫Āen↣↭rtneqq;쀀≩︀Å↪ԀAabcefkosy⇄⇇⇱⇵⇺∘∝∯≨≽ròΠȀilmr⇐⇔⇗⇛rsðᒄf»․ilôکĀdr⇠⇤cy;䑊ƀ;cwࣴ⇫⇯ir;楈;憭ar;意irc;䄥ƀalr∁∎∓rtsĀ;u∉∊晥it»∊lip;怦con;抹r;쀀𝔥sĀew∣∩arow;椥arow;椦ʀamopr∺∾≃≞≣rr;懿tht;戻kĀlr≉≓eftarrow;憩ightarrow;憪f;쀀𝕙bar;怕ƀclt≯≴≸r;쀀𝒽asè⇴rok;䄧Ābp⊂⊇ull;恃hen»ᱛૡ⊣\0⊪\0⊸⋅⋎\0⋕⋳\0\0⋸⌢⍧⍢⍿\0⎆⎪⎴cute耻í䃭ƀ;iyݱ⊰⊵rc耻î䃮;䐸Ācx⊼⊿y;䐵cl耻¡䂡ĀfrΟ⋉;쀀𝔦rave耻ì䃬Ȁ;inoܾ⋝⋩⋮Āin⋢⋦nt;樌t;戭fin;槜ta;愩lig;䄳ƀaop⋾⌚⌝ƀcgt⌅⌈⌗r;䄫ƀelpܟ⌏⌓inåގarôܠh;䄱f;抷ed;䆵ʀ;cfotӴ⌬⌱⌽⍁are;愅inĀ;t⌸⌹戞ie;槝doô⌙ʀ;celpݗ⍌⍐⍛⍡al;抺Āgr⍕⍙eróᕣã⍍arhk;樗rod;樼Ȁcgpt⍯⍲⍶⍻y;䑑on;䄯f;쀀𝕚a;䎹uest耻¿䂿Āci⎊⎏r;쀀𝒾nʀ;EdsvӴ⎛⎝⎡ӳ;拹ot;拵Ā;v⎦⎧拴;拳Ā;iݷ⎮lde;䄩ǫ⎸\0⎼cy;䑖l耻ï䃯̀cfmosu⏌⏗⏜⏡⏧⏵Āiy⏑⏕rc;䄵;䐹r;쀀𝔧ath;䈷pf;쀀𝕛ǣ⏬\0⏱r;쀀𝒿rcy;䑘kcy;䑔Ѐacfghjos␋␖␢␧␭␱␵␻ppaĀ;v␓␔䎺;䏰Āey␛␠dil;䄷;䐺r;쀀𝔨reen;䄸cy;䑅cy;䑜pf;쀀𝕜cr;쀀𝓀஀ABEHabcdefghjlmnoprstuv⑰⒁⒆⒍⒑┎┽╚▀♎♞♥♹♽⚚⚲⛘❝❨➋⟀⠁⠒ƀart⑷⑺⑼rò৆òΕail;椛arr;椎Ā;gঔ⒋;檋ar;楢ॣ⒥\0⒪\0⒱\0\0\0\0\0⒵Ⓔ\0ⓆⓈⓍ\0⓹ute;䄺mptyv;榴raîࡌbda;䎻gƀ;dlࢎⓁⓃ;榑åࢎ;檅uo耻«䂫rЀ;bfhlpst࢙ⓞⓦⓩ⓫⓮⓱⓵Ā;f࢝ⓣs;椟s;椝ë≒p;憫l;椹im;楳l;憢ƀ;ae⓿─┄檫il;椙Ā;s┉┊檭;쀀⪭︀ƀabr┕┙┝rr;椌rk;杲Āak┢┬cĀek┨┪;䁻;䁛Āes┱┳;榋lĀdu┹┻;榏;榍Ȁaeuy╆╋╖╘ron;䄾Ādi═╔il;䄼ìࢰâ┩;䐻Ȁcqrs╣╦╭╽a;椶uoĀ;rนᝆĀdu╲╷har;楧shar;楋h;憲ʀ;fgqs▋▌উ◳◿扤tʀahlrt▘▤▷◂◨rrowĀ;t࢙□aé⓶arpoonĀdu▯▴own»њp»०eftarrows;懇ightƀahs◍◖◞rrowĀ;sࣴࢧarpoonó྘quigarro÷⇰hreetimes;拋ƀ;qs▋ও◺lanôবʀ;cdgsব☊☍☝☨c;檨otĀ;o☔☕橿Ā;r☚☛檁;檃Ā;e☢☥쀀⋚︀s;檓ʀadegs☳☹☽♉♋pproøⓆot;拖qĀgq♃♅ôউgtò⒌ôছiíলƀilr♕࣡♚sht;楼;쀀𝔩Ā;Eজ♣;檑š♩♶rĀdu▲♮Ā;l॥♳;楪lk;斄cy;䑙ʀ;achtੈ⚈⚋⚑⚖rò◁orneòᴈard;楫ri;旺Āio⚟⚤dot;䅀ustĀ;a⚬⚭掰che»⚭ȀEaes⚻⚽⛉⛔;扨pĀ;p⛃⛄檉rox»⛄Ā;q⛎⛏檇Ā;q⛎⚻im;拦Ѐabnoptwz⛩⛴⛷✚✯❁❇❐Ānr⛮⛱g;柬r;懽rëࣁgƀlmr⛿✍✔eftĀar০✇ightá৲apsto;柼ightá৽parrowĀlr✥✩efô⓭ight;憬ƀafl✶✹✽r;榅;쀀𝕝us;樭imes;樴š❋❏st;戗áፎƀ;ef❗❘᠀旊nge»❘arĀ;l❤❥䀨t;榓ʀachmt❳❶❼➅➇ròࢨorneòᶌarĀ;d྘➃;業;怎ri;抿̀achiqt➘➝ੀ➢➮➻quo;怹r;쀀𝓁mƀ;egল➪➬;檍;檏Ābu┪➳oĀ;rฟ➹;怚rok;䅂萀<;cdhilqrࠫ⟒☹⟜⟠⟥⟪⟰Āci⟗⟙;檦r;橹reå◲mes;拉arr;楶uest;橻ĀPi⟵⟹ar;榖ƀ;ef⠀भ᠛旃rĀdu⠇⠍shar;楊har;楦Āen⠗⠡rtneqq;쀀≨︀Å⠞܀Dacdefhilnopsu⡀⡅⢂⢎⢓⢠⢥⢨⣚⣢⣤ઃ⣳⤂Dot;戺Ȁclpr⡎⡒⡣⡽r耻¯䂯Āet⡗⡙;時Ā;e⡞⡟朠se»⡟Ā;sျ⡨toȀ;dluျ⡳⡷⡻owîҌefôएðᏑker;斮Āoy⢇⢌mma;権;䐼ash;怔asuredangle»ᘦr;쀀𝔪o;愧ƀcdn⢯⢴⣉ro耻µ䂵Ȁ;acdᑤ⢽⣀⣄sôᚧir;櫰ot肻·Ƶusƀ;bd⣒ᤃ⣓戒Ā;uᴼ⣘;横ţ⣞⣡p;櫛ò−ðઁĀdp⣩⣮els;抧f;쀀𝕞Āct⣸⣽r;쀀𝓂pos»ᖝƀ;lm⤉⤊⤍䎼timap;抸ఀGLRVabcdefghijlmoprstuvw⥂⥓⥾⦉⦘⧚⧩⨕⨚⩘⩝⪃⪕⪤⪨⬄⬇⭄⭿⮮ⰴⱧⱼ⳩Āgt⥇⥋;쀀⋙̸Ā;v⥐௏쀀≫⃒ƀelt⥚⥲⥶ftĀar⥡⥧rrow;懍ightarrow;懎;쀀⋘̸Ā;v⥻ే쀀≪⃒ightarrow;懏ĀDd⦎⦓ash;抯ash;抮ʀbcnpt⦣⦧⦬⦱⧌la»˞ute;䅄g;쀀∠⃒ʀ;Eiop඄⦼⧀⧅⧈;쀀⩰̸d;쀀≋̸s;䅉roø඄urĀ;a⧓⧔普lĀ;s⧓ସdz⧟\0⧣p肻 ଷmpĀ;e௹ఀʀaeouy⧴⧾⨃⨐⨓ǰ⧹\0⧻;橃on;䅈dil;䅆ngĀ;dൾ⨊ot;쀀⩭̸p;橂;䐽ash;怓΀;Aadqsxஒ⨩⨭⨻⩁⩅⩐rr;懗rĀhr⨳⨶k;椤Ā;oᏲᏰot;쀀≐̸uiöୣĀei⩊⩎ar;椨í஘istĀ;s஠டr;쀀𝔫ȀEest௅⩦⩹⩼ƀ;qs஼⩭௡ƀ;qs஼௅⩴lanô௢ií௪Ā;rஶ⪁»ஷƀAap⪊⪍⪑rò⥱rr;憮ar;櫲ƀ;svྍ⪜ྌĀ;d⪡⪢拼;拺cy;䑚΀AEadest⪷⪺⪾⫂⫅⫶⫹rò⥦;쀀≦̸rr;憚r;急Ȁ;fqs఻⫎⫣⫯tĀar⫔⫙rro÷⫁ightarro÷⪐ƀ;qs఻⪺⫪lanôౕĀ;sౕ⫴»శiíౝĀ;rవ⫾iĀ;eచథiäඐĀpt⬌⬑f;쀀𝕟膀¬;in⬙⬚⬶䂬nȀ;Edvஉ⬤⬨⬮;쀀⋹̸ot;쀀⋵̸ǡஉ⬳⬵;拷;拶iĀ;vಸ⬼ǡಸ⭁⭃;拾;拽ƀaor⭋⭣⭩rȀ;ast୻⭕⭚⭟lleì୻l;쀀⫽⃥;쀀∂̸lint;樔ƀ;ceಒ⭰⭳uåಥĀ;cಘ⭸Ā;eಒ⭽ñಘȀAait⮈⮋⮝⮧rò⦈rrƀ;cw⮔⮕⮙憛;쀀⤳̸;쀀↝̸ghtarrow»⮕riĀ;eೋೖ΀chimpqu⮽⯍⯙⬄୸⯤⯯Ȁ;cerല⯆ഷ⯉uå൅;쀀𝓃ortɭ⬅\0\0⯖ará⭖mĀ;e൮⯟Ā;q൴൳suĀbp⯫⯭å೸åഋƀbcp⯶ⰑⰙȀ;Ees⯿ⰀഢⰄ抄;쀀⫅̸etĀ;eഛⰋqĀ;qണⰀcĀ;eലⰗñസȀ;EesⰢⰣൟⰧ抅;쀀⫆̸etĀ;e൘ⰮqĀ;qൠⰣȀgilrⰽⰿⱅⱇìௗlde耻ñ䃱çృiangleĀlrⱒⱜeftĀ;eచⱚñదightĀ;eೋⱥñ೗Ā;mⱬⱭ䎽ƀ;esⱴⱵⱹ䀣ro;愖p;怇ҀDHadgilrsⲏⲔⲙⲞⲣⲰⲶⳓⳣash;抭arr;椄p;쀀≍⃒ash;抬ĀetⲨⲬ;쀀≥⃒;쀀>⃒nfin;槞ƀAetⲽⳁⳅrr;椂;쀀≤⃒Ā;rⳊⳍ쀀<⃒ie;쀀⊴⃒ĀAtⳘⳜrr;椃rie;쀀⊵⃒im;쀀∼⃒ƀAan⳰⳴ⴂrr;懖rĀhr⳺⳽k;椣Ā;oᏧᏥear;椧ቓ᪕\0\0\0\0\0\0\0\0\0\0\0\0\0ⴭ\0ⴸⵈⵠⵥ⵲ⶄᬇ\0\0ⶍⶫ\0ⷈⷎ\0ⷜ⸙⸫⸾⹃Ācsⴱ᪗ute耻ó䃳ĀiyⴼⵅrĀ;c᪞ⵂ耻ô䃴;䐾ʀabios᪠ⵒⵗLjⵚlac;䅑v;樸old;榼lig;䅓Ācr⵩⵭ir;榿;쀀𝔬ͯ⵹\0\0⵼\0ⶂn;䋛ave耻ò䃲;槁Ābmⶈ෴ar;榵Ȁacitⶕ⶘ⶥⶨrò᪀Āir⶝ⶠr;榾oss;榻nå๒;槀ƀaeiⶱⶵⶹcr;䅍ga;䏉ƀcdnⷀⷅǍron;䎿;榶pf;쀀𝕠ƀaelⷔ⷗ǒr;榷rp;榹΀;adiosvⷪⷫⷮ⸈⸍⸐⸖戨rò᪆Ȁ;efmⷷⷸ⸂⸅橝rĀ;oⷾⷿ愴f»ⷿ耻ª䂪耻º䂺gof;抶r;橖lope;橗;橛ƀclo⸟⸡⸧ò⸁ash耻ø䃸l;折iŬⸯ⸴de耻õ䃵esĀ;aǛ⸺s;樶ml耻ö䃶bar;挽ૡ⹞\0⹽\0⺀⺝\0⺢⺹\0\0⻋ຜ\0⼓\0\0⼫⾼\0⿈rȀ;astЃ⹧⹲຅脀¶;l⹭⹮䂶leìЃɩ⹸\0\0⹻m;櫳;櫽y;䐿rʀcimpt⺋⺏⺓ᡥ⺗nt;䀥od;䀮il;怰enk;怱r;쀀𝔭ƀimo⺨⺰⺴Ā;v⺭⺮䏆;䏕maô੶ne;明ƀ;tv⺿⻀⻈䏀chfork»´;䏖Āau⻏⻟nĀck⻕⻝kĀ;h⇴⻛;愎ö⇴sҀ;abcdemst⻳⻴ᤈ⻹⻽⼄⼆⼊⼎䀫cir;樣ir;樢Āouᵀ⼂;樥;橲n肻±ຝim;樦wo;樧ƀipu⼙⼠⼥ntint;樕f;쀀𝕡nd耻£䂣Ԁ;Eaceinosu່⼿⽁⽄⽇⾁⾉⾒⽾⾶;檳p;檷uå໙Ā;c໎⽌̀;acens່⽙⽟⽦⽨⽾pproø⽃urlyeñ໙ñ໎ƀaes⽯⽶⽺pprox;檹qq;檵im;拨iíໟmeĀ;s⾈ຮ怲ƀEas⽸⾐⽺ð⽵ƀdfp໬⾙⾯ƀals⾠⾥⾪lar;挮ine;挒urf;挓Ā;t໻⾴ï໻rel;抰Āci⿀⿅r;쀀𝓅;䏈ncsp;怈̀fiopsu⿚⋢⿟⿥⿫⿱r;쀀𝔮pf;쀀𝕢rime;恗cr;쀀𝓆ƀaeo⿸〉〓tĀei⿾々rnionóڰnt;樖stĀ;e【】䀿ñἙô༔઀ABHabcdefhilmnoprstux぀けさすムㄎㄫㅇㅢㅲㆎ㈆㈕㈤㈩㉘㉮㉲㊐㊰㊷ƀartぇおがròႳòϝail;検aròᱥar;楤΀cdenqrtとふへみわゔヌĀeuねぱ;쀀∽̱te;䅕iãᅮmptyv;榳gȀ;del࿑らるろ;榒;榥å࿑uo耻»䂻rր;abcfhlpstw࿜ガクシスゼゾダッデナp;極Ā;f࿠ゴs;椠;椳s;椞ë≝ð✮l;楅im;楴l;憣;憝Āaiパフil;椚oĀ;nホボ戶aló༞ƀabrョリヮrò៥rk;杳ĀakンヽcĀekヹ・;䁽;䁝Āes㄂㄄;榌lĀduㄊㄌ;榎;榐Ȁaeuyㄗㄜㄧㄩron;䅙Ādiㄡㄥil;䅗ì࿲âヺ;䑀Ȁclqsㄴㄷㄽㅄa;椷dhar;楩uoĀ;rȎȍh;憳ƀacgㅎㅟངlȀ;ipsླྀㅘㅛႜnåႻarôྩt;断ƀilrㅩဣㅮsht;楽;쀀𝔯ĀaoㅷㆆrĀduㅽㅿ»ѻĀ;l႑ㆄ;楬Ā;vㆋㆌ䏁;䏱ƀgns㆕ㇹㇼht̀ahlrstㆤㆰ㇂㇘㇤㇮rrowĀ;t࿜ㆭaéトarpoonĀduㆻㆿowîㅾp»႒eftĀah㇊㇐rrowó࿪arpoonóՑightarrows;應quigarro÷ニhreetimes;拌g;䋚ingdotseñἲƀahm㈍㈐㈓rò࿪aòՑ;怏oustĀ;a㈞㈟掱che»㈟mid;櫮Ȁabpt㈲㈽㉀㉒Ānr㈷㈺g;柭r;懾rëဃƀafl㉇㉊㉎r;榆;쀀𝕣us;樮imes;樵Āap㉝㉧rĀ;g㉣㉤䀩t;榔olint;樒arò㇣Ȁachq㉻㊀Ⴜ㊅quo;怺r;쀀𝓇Ābu・㊊oĀ;rȔȓƀhir㊗㊛㊠reåㇸmes;拊iȀ;efl㊪ၙᠡ㊫方tri;槎luhar;楨;愞ൡ㋕㋛㋟㌬㌸㍱\0㍺㎤\0\0㏬㏰\0㐨㑈㑚㒭㒱㓊㓱\0㘖\0\0㘳cute;䅛quï➺Ԁ;Eaceinpsyᇭ㋳㋵㋿㌂㌋㌏㌟㌦㌩;檴ǰ㋺\0㋼;檸on;䅡uåᇾĀ;dᇳ㌇il;䅟rc;䅝ƀEas㌖㌘㌛;檶p;檺im;择olint;樓iíሄ;䑁otƀ;be㌴ᵇ㌵担;橦΀Aacmstx㍆㍊㍗㍛㍞㍣㍭rr;懘rĀhr㍐㍒ë∨Ā;oਸ਼਴t耻§䂧i;䀻war;椩mĀin㍩ðnuóñt;朶rĀ;o㍶⁕쀀𝔰Ȁacoy㎂㎆㎑㎠rp;景Āhy㎋㎏cy;䑉;䑈rtɭ㎙\0\0㎜iäᑤaraì⹯耻­䂭Āgm㎨㎴maƀ;fv㎱㎲㎲䏃;䏂Ѐ;deglnprካ㏅㏉㏎㏖㏞㏡㏦ot;橪Ā;q኱ኰĀ;E㏓㏔檞;檠Ā;E㏛㏜檝;檟e;扆lus;樤arr;楲aròᄽȀaeit㏸㐈㐏㐗Āls㏽㐄lsetmé㍪hp;樳parsl;槤Ādlᑣ㐔e;挣Ā;e㐜㐝檪Ā;s㐢㐣檬;쀀⪬︀ƀflp㐮㐳㑂tcy;䑌Ā;b㐸㐹䀯Ā;a㐾㐿槄r;挿f;쀀𝕤aĀdr㑍ЂesĀ;u㑔㑕晠it»㑕ƀcsu㑠㑹㒟Āau㑥㑯pĀ;sᆈ㑫;쀀⊓︀pĀ;sᆴ㑵;쀀⊔︀uĀbp㑿㒏ƀ;esᆗᆜ㒆etĀ;eᆗ㒍ñᆝƀ;esᆨᆭ㒖etĀ;eᆨ㒝ñᆮƀ;afᅻ㒦ְrť㒫ֱ»ᅼaròᅈȀcemt㒹㒾㓂㓅r;쀀𝓈tmîñiì㐕aræᆾĀar㓎㓕rĀ;f㓔ឿ昆Āan㓚㓭ightĀep㓣㓪psiloîỠhé⺯s»⡒ʀbcmnp㓻㕞ሉ㖋㖎Ҁ;Edemnprs㔎㔏㔑㔕㔞㔣㔬㔱㔶抂;櫅ot;檽Ā;dᇚ㔚ot;櫃ult;櫁ĀEe㔨㔪;櫋;把lus;檿arr;楹ƀeiu㔽㕒㕕tƀ;en㔎㕅㕋qĀ;qᇚ㔏eqĀ;q㔫㔨m;櫇Ābp㕚㕜;櫕;櫓c̀;acensᇭ㕬㕲㕹㕻㌦pproø㋺urlyeñᇾñᇳƀaes㖂㖈㌛pproø㌚qñ㌗g;晪ڀ123;Edehlmnps㖩㖬㖯ሜ㖲㖴㗀㗉㗕㗚㗟㗨㗭耻¹䂹耻²䂲耻³䂳;櫆Āos㖹㖼t;檾ub;櫘Ā;dሢ㗅ot;櫄sĀou㗏㗒l;柉b;櫗arr;楻ult;櫂ĀEe㗤㗦;櫌;抋lus;櫀ƀeiu㗴㘉㘌tƀ;enሜ㗼㘂qĀ;qሢ㖲eqĀ;q㗧㗤m;櫈Ābp㘑㘓;櫔;櫖ƀAan㘜㘠㘭rr;懙rĀhr㘦㘨ë∮Ā;oਫ਩war;椪lig耻ß䃟௡㙑㙝㙠ዎ㙳㙹\0㙾㛂\0\0\0\0\0㛛㜃\0㜉㝬\0\0\0㞇ɲ㙖\0\0㙛get;挖;䏄rë๟ƀaey㙦㙫㙰ron;䅥dil;䅣;䑂lrec;挕r;쀀𝔱Ȁeiko㚆㚝㚵㚼Dz㚋\0㚑eĀ4fኄኁaƀ;sv㚘㚙㚛䎸ym;䏑Ācn㚢㚲kĀas㚨㚮pproø዁im»ኬsðኞĀas㚺㚮ð዁rn耻þ䃾Ǭ̟㛆⋧es膀×;bd㛏㛐㛘䃗Ā;aᤏ㛕r;樱;樰ƀeps㛡㛣㜀á⩍Ȁ;bcf҆㛬㛰㛴ot;挶ir;櫱Ā;o㛹㛼쀀𝕥rk;櫚á㍢rime;怴ƀaip㜏㜒㝤dåቈ΀adempst㜡㝍㝀㝑㝗㝜㝟ngleʀ;dlqr㜰㜱㜶㝀㝂斵own»ᶻeftĀ;e⠀㜾ñम;扜ightĀ;e㊪㝋ñၚot;旬inus;樺lus;樹b;槍ime;樻ezium;揢ƀcht㝲㝽㞁Āry㝷㝻;쀀𝓉;䑆cy;䑛rok;䅧Āio㞋㞎xô᝷headĀlr㞗㞠eftarro÷ࡏightarrow»ཝऀAHabcdfghlmoprstuw㟐㟓㟗㟤㟰㟼㠎㠜㠣㠴㡑㡝㡫㢩㣌㣒㣪㣶ròϭar;楣Ācr㟜㟢ute耻ú䃺òᅐrǣ㟪\0㟭y;䑞ve;䅭Āiy㟵㟺rc耻û䃻;䑃ƀabh㠃㠆㠋ròᎭlac;䅱aòᏃĀir㠓㠘sht;楾;쀀𝔲rave耻ù䃹š㠧㠱rĀlr㠬㠮»ॗ»ႃlk;斀Āct㠹㡍ɯ㠿\0\0㡊rnĀ;e㡅㡆挜r»㡆op;挏ri;旸Āal㡖㡚cr;䅫肻¨͉Āgp㡢㡦on;䅳f;쀀𝕦̀adhlsuᅋ㡸㡽፲㢑㢠ownáᎳarpoonĀlr㢈㢌efô㠭ighô㠯iƀ;hl㢙㢚㢜䏅»ᏺon»㢚parrows;懈ƀcit㢰㣄㣈ɯ㢶\0\0㣁rnĀ;e㢼㢽挝r»㢽op;挎ng;䅯ri;旹cr;쀀𝓊ƀdir㣙㣝㣢ot;拰lde;䅩iĀ;f㜰㣨»᠓Āam㣯㣲rò㢨l耻ü䃼angle;榧ހABDacdeflnoprsz㤜㤟㤩㤭㦵㦸㦽㧟㧤㧨㧳㧹㧽㨁㨠ròϷarĀ;v㤦㤧櫨;櫩asèϡĀnr㤲㤷grt;榜΀eknprst㓣㥆㥋㥒㥝㥤㦖appá␕othinçẖƀhir㓫⻈㥙opô⾵Ā;hᎷ㥢ïㆍĀiu㥩㥭gmá㎳Ābp㥲㦄setneqĀ;q㥽㦀쀀⊊︀;쀀⫋︀setneqĀ;q㦏㦒쀀⊋︀;쀀⫌︀Āhr㦛㦟etá㚜iangleĀlr㦪㦯eft»थight»ၑy;䐲ash»ံƀelr㧄㧒㧗ƀ;beⷪ㧋㧏ar;抻q;扚lip;拮Ābt㧜ᑨaòᑩr;쀀𝔳tré㦮suĀbp㧯㧱»ജ»൙pf;쀀𝕧roð໻tré㦴Ācu㨆㨋r;쀀𝓋Ābp㨐㨘nĀEe㦀㨖»㥾nĀEe㦒㨞»㦐igzag;榚΀cefoprs㨶㨻㩖㩛㩔㩡㩪irc;䅵Ādi㩀㩑Ābg㩅㩉ar;機eĀ;qᗺ㩏;扙erp;愘r;쀀𝔴pf;쀀𝕨Ā;eᑹ㩦atèᑹcr;쀀𝓌ૣណ㪇\0㪋\0㪐㪛\0\0㪝㪨㪫㪯\0\0㫃㫎\0㫘ៜ៟tré៑r;쀀𝔵ĀAa㪔㪗ròσrò৶;䎾ĀAa㪡㪤ròθrò৫að✓is;拻ƀdptឤ㪵㪾Āfl㪺ឩ;쀀𝕩imåឲĀAa㫇㫊ròώròਁĀcq㫒ីr;쀀𝓍Āpt៖㫜ré។Ѐacefiosu㫰㫽㬈㬌㬑㬕㬛㬡cĀuy㫶㫻te耻ý䃽;䑏Āiy㬂㬆rc;䅷;䑋n耻¥䂥r;쀀𝔶cy;䑗pf;쀀𝕪cr;쀀𝓎Ācm㬦㬩y;䑎l耻ÿ䃿Ԁacdefhiosw㭂㭈㭔㭘㭤㭩㭭㭴㭺㮀cute;䅺Āay㭍㭒ron;䅾;䐷ot;䅼Āet㭝㭡træᕟa;䎶r;쀀𝔷cy;䐶grarr;懝pf;쀀𝕫cr;쀀𝓏Ājn㮅㮇;怍j;怌'.split("").map(c2=>c2.charCodeAt(0))),decodeMap=new Map([[0,65533],[128,8364],[130,8218],[131,402],[132,8222],[133,8230],[134,8224],[135,8225],[136,710],[137,8240],[138,352],[139,8249],[140,338],[142,381],[145,8216],[146,8217],[147,8220],[148,8221],[149,8226],[150,8211],[151,8212],[152,732],[153,8482],[154,353],[155,8250],[156,339],[158,382],[159,376]]);function replaceCodePoint(codePoint){var _a18;return codePoint>=55296&&codePoint<=57343||codePoint>1114111?65533:(_a18=decodeMap.get(codePoint))!==null&&_a18!==void 0?_a18:codePoint}__name(replaceCodePoint,"replaceCodePoint");var CharCodes;(function(CharCodes2){CharCodes2[CharCodes2.NUM=35]="NUM",CharCodes2[CharCodes2.SEMI=59]="SEMI",CharCodes2[CharCodes2.EQUALS=61]="EQUALS",CharCodes2[CharCodes2.ZERO=48]="ZERO",CharCodes2[CharCodes2.NINE=57]="NINE",CharCodes2[CharCodes2.LOWER_A=97]="LOWER_A",CharCodes2[CharCodes2.LOWER_F=102]="LOWER_F",CharCodes2[CharCodes2.LOWER_X=120]="LOWER_X",CharCodes2[CharCodes2.LOWER_Z=122]="LOWER_Z",CharCodes2[CharCodes2.UPPER_A=65]="UPPER_A",CharCodes2[CharCodes2.UPPER_F=70]="UPPER_F",CharCodes2[CharCodes2.UPPER_Z=90]="UPPER_Z"})(CharCodes||(CharCodes={}));const TO_LOWER_BIT=32;var BinTrieFlags;(function(BinTrieFlags2){BinTrieFlags2[BinTrieFlags2.VALUE_LENGTH=49152]="VALUE_LENGTH",BinTrieFlags2[BinTrieFlags2.BRANCH_LENGTH=16256]="BRANCH_LENGTH",BinTrieFlags2[BinTrieFlags2.JUMP_TABLE=127]="JUMP_TABLE"})(BinTrieFlags||(BinTrieFlags={}));function isNumber2(code2){return code2>=CharCodes.ZERO&&code2<=CharCodes.NINE}__name(isNumber2,"isNumber");function isHexadecimalCharacter(code2){return code2>=CharCodes.UPPER_A&&code2<=CharCodes.UPPER_F||code2>=CharCodes.LOWER_A&&code2<=CharCodes.LOWER_F}__name(isHexadecimalCharacter,"isHexadecimalCharacter");function isAsciiAlphaNumeric$1(code2){return code2>=CharCodes.UPPER_A&&code2<=CharCodes.UPPER_Z||code2>=CharCodes.LOWER_A&&code2<=CharCodes.LOWER_Z||isNumber2(code2)}__name(isAsciiAlphaNumeric$1,"isAsciiAlphaNumeric$1");function isEntityInAttributeInvalidEnd(code2){return code2===CharCodes.EQUALS||isAsciiAlphaNumeric$1(code2)}__name(isEntityInAttributeInvalidEnd,"isEntityInAttributeInvalidEnd");var EntityDecoderState;(function(EntityDecoderState2){EntityDecoderState2[EntityDecoderState2.EntityStart=0]="EntityStart",EntityDecoderState2[EntityDecoderState2.NumericStart=1]="NumericStart",EntityDecoderState2[EntityDecoderState2.NumericDecimal=2]="NumericDecimal",EntityDecoderState2[EntityDecoderState2.NumericHex=3]="NumericHex",EntityDecoderState2[EntityDecoderState2.NamedEntity=4]="NamedEntity"})(EntityDecoderState||(EntityDecoderState={}));var DecodingMode;(function(DecodingMode2){DecodingMode2[DecodingMode2.Legacy=0]="Legacy",DecodingMode2[DecodingMode2.Strict=1]="Strict",DecodingMode2[DecodingMode2.Attribute=2]="Attribute"})(DecodingMode||(DecodingMode={}));const _EntityDecoder=class _EntityDecoder{constructor(decodeTree,emitCodePoint,errors){this.decodeTree=decodeTree,this.emitCodePoint=emitCodePoint,this.errors=errors,this.state=EntityDecoderState.EntityStart,this.consumed=1,this.result=0,this.treeIndex=0,this.excess=1,this.decodeMode=DecodingMode.Strict}startEntity(decodeMode){this.decodeMode=decodeMode,this.state=EntityDecoderState.EntityStart,this.result=0,this.treeIndex=0,this.excess=1,this.consumed=1}write(input,offset2){switch(this.state){case EntityDecoderState.EntityStart:return input.charCodeAt(offset2)===CharCodes.NUM?(this.state=EntityDecoderState.NumericStart,this.consumed+=1,this.stateNumericStart(input,offset2+1)):(this.state=EntityDecoderState.NamedEntity,this.stateNamedEntity(input,offset2));case EntityDecoderState.NumericStart:return this.stateNumericStart(input,offset2);case EntityDecoderState.NumericDecimal:return this.stateNumericDecimal(input,offset2);case EntityDecoderState.NumericHex:return this.stateNumericHex(input,offset2);case EntityDecoderState.NamedEntity:return this.stateNamedEntity(input,offset2)}}stateNumericStart(input,offset2){return offset2>=input.length?-1:(input.charCodeAt(offset2)|TO_LOWER_BIT)===CharCodes.LOWER_X?(this.state=EntityDecoderState.NumericHex,this.consumed+=1,this.stateNumericHex(input,offset2+1)):(this.state=EntityDecoderState.NumericDecimal,this.stateNumericDecimal(input,offset2))}addToNumericResult(input,start2,end,base){if(start2!==end){const digitCount=end-start2;this.result=this.result*Math.pow(base,digitCount)+Number.parseInt(input.substr(start2,digitCount),base),this.consumed+=digitCount}}stateNumericHex(input,offset2){const startIndex=offset2;for(;offset2>14;for(;offset2>14,valueLength!==0){if(char===CharCodes.SEMI)return this.emitNamedEntityData(this.treeIndex,valueLength,this.consumed+this.excess);this.decodeMode!==DecodingMode.Strict&&(this.result=this.treeIndex,this.consumed+=this.excess,this.excess=0)}}return-1}emitNotTerminatedNamedEntity(){var _a18;const{result,decodeTree}=this,valueLength=(decodeTree[result]&BinTrieFlags.VALUE_LENGTH)>>14;return this.emitNamedEntityData(result,valueLength,this.consumed),(_a18=this.errors)===null||_a18===void 0||_a18.missingSemicolonAfterCharacterReference(),this.consumed}emitNamedEntityData(result,valueLength,consumed){const{decodeTree}=this;return this.emitCodePoint(valueLength===1?decodeTree[result]&~BinTrieFlags.VALUE_LENGTH:decodeTree[result+1],consumed),valueLength===3&&this.emitCodePoint(decodeTree[result+2],consumed),consumed}end(){var _a18;switch(this.state){case EntityDecoderState.NamedEntity:return this.result!==0&&(this.decodeMode!==DecodingMode.Attribute||this.result===this.treeIndex)?this.emitNotTerminatedNamedEntity():0;case EntityDecoderState.NumericDecimal:return this.emitNumericEntity(0,2);case EntityDecoderState.NumericHex:return this.emitNumericEntity(0,3);case EntityDecoderState.NumericStart:return(_a18=this.errors)===null||_a18===void 0||_a18.absenceOfDigitsInNumericCharacterReference(this.consumed),0;case EntityDecoderState.EntityStart:return 0}}};__name(_EntityDecoder,"EntityDecoder");let EntityDecoder=_EntityDecoder;function determineBranch(decodeTree,current,nodeIndex,char){const branchCount=(current&BinTrieFlags.BRANCH_LENGTH)>>7,jumpOffset=current&BinTrieFlags.JUMP_TABLE;if(branchCount===0)return jumpOffset!==0&&char===jumpOffset?nodeIndex:-1;if(jumpOffset){const value2=char-jumpOffset;return value2<0||value2>=branchCount?-1:decodeTree[nodeIndex+value2]-1}let lo=nodeIndex,hi=lo+branchCount-1;for(;lo<=hi;){const mid=lo+hi>>>1,midValue=decodeTree[mid];if(midValuechar)hi=mid-1;else return decodeTree[mid+branchCount]}return-1}__name(determineBranch,"determineBranch");var NS;(function(NS2){NS2.HTML="http://www.w3.org/1999/xhtml",NS2.MATHML="http://www.w3.org/1998/Math/MathML",NS2.SVG="http://www.w3.org/2000/svg",NS2.XLINK="http://www.w3.org/1999/xlink",NS2.XML="http://www.w3.org/XML/1998/namespace",NS2.XMLNS="http://www.w3.org/2000/xmlns/"})(NS||(NS={}));var ATTRS;(function(ATTRS2){ATTRS2.TYPE="type",ATTRS2.ACTION="action",ATTRS2.ENCODING="encoding",ATTRS2.PROMPT="prompt",ATTRS2.NAME="name",ATTRS2.COLOR="color",ATTRS2.FACE="face",ATTRS2.SIZE="size"})(ATTRS||(ATTRS={}));var DOCUMENT_MODE;(function(DOCUMENT_MODE2){DOCUMENT_MODE2.NO_QUIRKS="no-quirks",DOCUMENT_MODE2.QUIRKS="quirks",DOCUMENT_MODE2.LIMITED_QUIRKS="limited-quirks"})(DOCUMENT_MODE||(DOCUMENT_MODE={}));var TAG_NAMES;(function(TAG_NAMES2){TAG_NAMES2.A="a",TAG_NAMES2.ADDRESS="address",TAG_NAMES2.ANNOTATION_XML="annotation-xml",TAG_NAMES2.APPLET="applet",TAG_NAMES2.AREA="area",TAG_NAMES2.ARTICLE="article",TAG_NAMES2.ASIDE="aside",TAG_NAMES2.B="b",TAG_NAMES2.BASE="base",TAG_NAMES2.BASEFONT="basefont",TAG_NAMES2.BGSOUND="bgsound",TAG_NAMES2.BIG="big",TAG_NAMES2.BLOCKQUOTE="blockquote",TAG_NAMES2.BODY="body",TAG_NAMES2.BR="br",TAG_NAMES2.BUTTON="button",TAG_NAMES2.CAPTION="caption",TAG_NAMES2.CENTER="center",TAG_NAMES2.CODE="code",TAG_NAMES2.COL="col",TAG_NAMES2.COLGROUP="colgroup",TAG_NAMES2.DD="dd",TAG_NAMES2.DESC="desc",TAG_NAMES2.DETAILS="details",TAG_NAMES2.DIALOG="dialog",TAG_NAMES2.DIR="dir",TAG_NAMES2.DIV="div",TAG_NAMES2.DL="dl",TAG_NAMES2.DT="dt",TAG_NAMES2.EM="em",TAG_NAMES2.EMBED="embed",TAG_NAMES2.FIELDSET="fieldset",TAG_NAMES2.FIGCAPTION="figcaption",TAG_NAMES2.FIGURE="figure",TAG_NAMES2.FONT="font",TAG_NAMES2.FOOTER="footer",TAG_NAMES2.FOREIGN_OBJECT="foreignObject",TAG_NAMES2.FORM="form",TAG_NAMES2.FRAME="frame",TAG_NAMES2.FRAMESET="frameset",TAG_NAMES2.H1="h1",TAG_NAMES2.H2="h2",TAG_NAMES2.H3="h3",TAG_NAMES2.H4="h4",TAG_NAMES2.H5="h5",TAG_NAMES2.H6="h6",TAG_NAMES2.HEAD="head",TAG_NAMES2.HEADER="header",TAG_NAMES2.HGROUP="hgroup",TAG_NAMES2.HR="hr",TAG_NAMES2.HTML="html",TAG_NAMES2.I="i",TAG_NAMES2.IMG="img",TAG_NAMES2.IMAGE="image",TAG_NAMES2.INPUT="input",TAG_NAMES2.IFRAME="iframe",TAG_NAMES2.KEYGEN="keygen",TAG_NAMES2.LABEL="label",TAG_NAMES2.LI="li",TAG_NAMES2.LINK="link",TAG_NAMES2.LISTING="listing",TAG_NAMES2.MAIN="main",TAG_NAMES2.MALIGNMARK="malignmark",TAG_NAMES2.MARQUEE="marquee",TAG_NAMES2.MATH="math",TAG_NAMES2.MENU="menu",TAG_NAMES2.META="meta",TAG_NAMES2.MGLYPH="mglyph",TAG_NAMES2.MI="mi",TAG_NAMES2.MO="mo",TAG_NAMES2.MN="mn",TAG_NAMES2.MS="ms",TAG_NAMES2.MTEXT="mtext",TAG_NAMES2.NAV="nav",TAG_NAMES2.NOBR="nobr",TAG_NAMES2.NOFRAMES="noframes",TAG_NAMES2.NOEMBED="noembed",TAG_NAMES2.NOSCRIPT="noscript",TAG_NAMES2.OBJECT="object",TAG_NAMES2.OL="ol",TAG_NAMES2.OPTGROUP="optgroup",TAG_NAMES2.OPTION="option",TAG_NAMES2.P="p",TAG_NAMES2.PARAM="param",TAG_NAMES2.PLAINTEXT="plaintext",TAG_NAMES2.PRE="pre",TAG_NAMES2.RB="rb",TAG_NAMES2.RP="rp",TAG_NAMES2.RT="rt",TAG_NAMES2.RTC="rtc",TAG_NAMES2.RUBY="ruby",TAG_NAMES2.S="s",TAG_NAMES2.SCRIPT="script",TAG_NAMES2.SEARCH="search",TAG_NAMES2.SECTION="section",TAG_NAMES2.SELECT="select",TAG_NAMES2.SOURCE="source",TAG_NAMES2.SMALL="small",TAG_NAMES2.SPAN="span",TAG_NAMES2.STRIKE="strike",TAG_NAMES2.STRONG="strong",TAG_NAMES2.STYLE="style",TAG_NAMES2.SUB="sub",TAG_NAMES2.SUMMARY="summary",TAG_NAMES2.SUP="sup",TAG_NAMES2.TABLE="table",TAG_NAMES2.TBODY="tbody",TAG_NAMES2.TEMPLATE="template",TAG_NAMES2.TEXTAREA="textarea",TAG_NAMES2.TFOOT="tfoot",TAG_NAMES2.TD="td",TAG_NAMES2.TH="th",TAG_NAMES2.THEAD="thead",TAG_NAMES2.TITLE="title",TAG_NAMES2.TR="tr",TAG_NAMES2.TRACK="track",TAG_NAMES2.TT="tt",TAG_NAMES2.U="u",TAG_NAMES2.UL="ul",TAG_NAMES2.SVG="svg",TAG_NAMES2.VAR="var",TAG_NAMES2.WBR="wbr",TAG_NAMES2.XMP="xmp"})(TAG_NAMES||(TAG_NAMES={}));var TAG_ID;(function(TAG_ID2){TAG_ID2[TAG_ID2.UNKNOWN=0]="UNKNOWN",TAG_ID2[TAG_ID2.A=1]="A",TAG_ID2[TAG_ID2.ADDRESS=2]="ADDRESS",TAG_ID2[TAG_ID2.ANNOTATION_XML=3]="ANNOTATION_XML",TAG_ID2[TAG_ID2.APPLET=4]="APPLET",TAG_ID2[TAG_ID2.AREA=5]="AREA",TAG_ID2[TAG_ID2.ARTICLE=6]="ARTICLE",TAG_ID2[TAG_ID2.ASIDE=7]="ASIDE",TAG_ID2[TAG_ID2.B=8]="B",TAG_ID2[TAG_ID2.BASE=9]="BASE",TAG_ID2[TAG_ID2.BASEFONT=10]="BASEFONT",TAG_ID2[TAG_ID2.BGSOUND=11]="BGSOUND",TAG_ID2[TAG_ID2.BIG=12]="BIG",TAG_ID2[TAG_ID2.BLOCKQUOTE=13]="BLOCKQUOTE",TAG_ID2[TAG_ID2.BODY=14]="BODY",TAG_ID2[TAG_ID2.BR=15]="BR",TAG_ID2[TAG_ID2.BUTTON=16]="BUTTON",TAG_ID2[TAG_ID2.CAPTION=17]="CAPTION",TAG_ID2[TAG_ID2.CENTER=18]="CENTER",TAG_ID2[TAG_ID2.CODE=19]="CODE",TAG_ID2[TAG_ID2.COL=20]="COL",TAG_ID2[TAG_ID2.COLGROUP=21]="COLGROUP",TAG_ID2[TAG_ID2.DD=22]="DD",TAG_ID2[TAG_ID2.DESC=23]="DESC",TAG_ID2[TAG_ID2.DETAILS=24]="DETAILS",TAG_ID2[TAG_ID2.DIALOG=25]="DIALOG",TAG_ID2[TAG_ID2.DIR=26]="DIR",TAG_ID2[TAG_ID2.DIV=27]="DIV",TAG_ID2[TAG_ID2.DL=28]="DL",TAG_ID2[TAG_ID2.DT=29]="DT",TAG_ID2[TAG_ID2.EM=30]="EM",TAG_ID2[TAG_ID2.EMBED=31]="EMBED",TAG_ID2[TAG_ID2.FIELDSET=32]="FIELDSET",TAG_ID2[TAG_ID2.FIGCAPTION=33]="FIGCAPTION",TAG_ID2[TAG_ID2.FIGURE=34]="FIGURE",TAG_ID2[TAG_ID2.FONT=35]="FONT",TAG_ID2[TAG_ID2.FOOTER=36]="FOOTER",TAG_ID2[TAG_ID2.FOREIGN_OBJECT=37]="FOREIGN_OBJECT",TAG_ID2[TAG_ID2.FORM=38]="FORM",TAG_ID2[TAG_ID2.FRAME=39]="FRAME",TAG_ID2[TAG_ID2.FRAMESET=40]="FRAMESET",TAG_ID2[TAG_ID2.H1=41]="H1",TAG_ID2[TAG_ID2.H2=42]="H2",TAG_ID2[TAG_ID2.H3=43]="H3",TAG_ID2[TAG_ID2.H4=44]="H4",TAG_ID2[TAG_ID2.H5=45]="H5",TAG_ID2[TAG_ID2.H6=46]="H6",TAG_ID2[TAG_ID2.HEAD=47]="HEAD",TAG_ID2[TAG_ID2.HEADER=48]="HEADER",TAG_ID2[TAG_ID2.HGROUP=49]="HGROUP",TAG_ID2[TAG_ID2.HR=50]="HR",TAG_ID2[TAG_ID2.HTML=51]="HTML",TAG_ID2[TAG_ID2.I=52]="I",TAG_ID2[TAG_ID2.IMG=53]="IMG",TAG_ID2[TAG_ID2.IMAGE=54]="IMAGE",TAG_ID2[TAG_ID2.INPUT=55]="INPUT",TAG_ID2[TAG_ID2.IFRAME=56]="IFRAME",TAG_ID2[TAG_ID2.KEYGEN=57]="KEYGEN",TAG_ID2[TAG_ID2.LABEL=58]="LABEL",TAG_ID2[TAG_ID2.LI=59]="LI",TAG_ID2[TAG_ID2.LINK=60]="LINK",TAG_ID2[TAG_ID2.LISTING=61]="LISTING",TAG_ID2[TAG_ID2.MAIN=62]="MAIN",TAG_ID2[TAG_ID2.MALIGNMARK=63]="MALIGNMARK",TAG_ID2[TAG_ID2.MARQUEE=64]="MARQUEE",TAG_ID2[TAG_ID2.MATH=65]="MATH",TAG_ID2[TAG_ID2.MENU=66]="MENU",TAG_ID2[TAG_ID2.META=67]="META",TAG_ID2[TAG_ID2.MGLYPH=68]="MGLYPH",TAG_ID2[TAG_ID2.MI=69]="MI",TAG_ID2[TAG_ID2.MO=70]="MO",TAG_ID2[TAG_ID2.MN=71]="MN",TAG_ID2[TAG_ID2.MS=72]="MS",TAG_ID2[TAG_ID2.MTEXT=73]="MTEXT",TAG_ID2[TAG_ID2.NAV=74]="NAV",TAG_ID2[TAG_ID2.NOBR=75]="NOBR",TAG_ID2[TAG_ID2.NOFRAMES=76]="NOFRAMES",TAG_ID2[TAG_ID2.NOEMBED=77]="NOEMBED",TAG_ID2[TAG_ID2.NOSCRIPT=78]="NOSCRIPT",TAG_ID2[TAG_ID2.OBJECT=79]="OBJECT",TAG_ID2[TAG_ID2.OL=80]="OL",TAG_ID2[TAG_ID2.OPTGROUP=81]="OPTGROUP",TAG_ID2[TAG_ID2.OPTION=82]="OPTION",TAG_ID2[TAG_ID2.P=83]="P",TAG_ID2[TAG_ID2.PARAM=84]="PARAM",TAG_ID2[TAG_ID2.PLAINTEXT=85]="PLAINTEXT",TAG_ID2[TAG_ID2.PRE=86]="PRE",TAG_ID2[TAG_ID2.RB=87]="RB",TAG_ID2[TAG_ID2.RP=88]="RP",TAG_ID2[TAG_ID2.RT=89]="RT",TAG_ID2[TAG_ID2.RTC=90]="RTC",TAG_ID2[TAG_ID2.RUBY=91]="RUBY",TAG_ID2[TAG_ID2.S=92]="S",TAG_ID2[TAG_ID2.SCRIPT=93]="SCRIPT",TAG_ID2[TAG_ID2.SEARCH=94]="SEARCH",TAG_ID2[TAG_ID2.SECTION=95]="SECTION",TAG_ID2[TAG_ID2.SELECT=96]="SELECT",TAG_ID2[TAG_ID2.SOURCE=97]="SOURCE",TAG_ID2[TAG_ID2.SMALL=98]="SMALL",TAG_ID2[TAG_ID2.SPAN=99]="SPAN",TAG_ID2[TAG_ID2.STRIKE=100]="STRIKE",TAG_ID2[TAG_ID2.STRONG=101]="STRONG",TAG_ID2[TAG_ID2.STYLE=102]="STYLE",TAG_ID2[TAG_ID2.SUB=103]="SUB",TAG_ID2[TAG_ID2.SUMMARY=104]="SUMMARY",TAG_ID2[TAG_ID2.SUP=105]="SUP",TAG_ID2[TAG_ID2.TABLE=106]="TABLE",TAG_ID2[TAG_ID2.TBODY=107]="TBODY",TAG_ID2[TAG_ID2.TEMPLATE=108]="TEMPLATE",TAG_ID2[TAG_ID2.TEXTAREA=109]="TEXTAREA",TAG_ID2[TAG_ID2.TFOOT=110]="TFOOT",TAG_ID2[TAG_ID2.TD=111]="TD",TAG_ID2[TAG_ID2.TH=112]="TH",TAG_ID2[TAG_ID2.THEAD=113]="THEAD",TAG_ID2[TAG_ID2.TITLE=114]="TITLE",TAG_ID2[TAG_ID2.TR=115]="TR",TAG_ID2[TAG_ID2.TRACK=116]="TRACK",TAG_ID2[TAG_ID2.TT=117]="TT",TAG_ID2[TAG_ID2.U=118]="U",TAG_ID2[TAG_ID2.UL=119]="UL",TAG_ID2[TAG_ID2.SVG=120]="SVG",TAG_ID2[TAG_ID2.VAR=121]="VAR",TAG_ID2[TAG_ID2.WBR=122]="WBR",TAG_ID2[TAG_ID2.XMP=123]="XMP"})(TAG_ID||(TAG_ID={}));const TAG_NAME_TO_ID=new Map([[TAG_NAMES.A,TAG_ID.A],[TAG_NAMES.ADDRESS,TAG_ID.ADDRESS],[TAG_NAMES.ANNOTATION_XML,TAG_ID.ANNOTATION_XML],[TAG_NAMES.APPLET,TAG_ID.APPLET],[TAG_NAMES.AREA,TAG_ID.AREA],[TAG_NAMES.ARTICLE,TAG_ID.ARTICLE],[TAG_NAMES.ASIDE,TAG_ID.ASIDE],[TAG_NAMES.B,TAG_ID.B],[TAG_NAMES.BASE,TAG_ID.BASE],[TAG_NAMES.BASEFONT,TAG_ID.BASEFONT],[TAG_NAMES.BGSOUND,TAG_ID.BGSOUND],[TAG_NAMES.BIG,TAG_ID.BIG],[TAG_NAMES.BLOCKQUOTE,TAG_ID.BLOCKQUOTE],[TAG_NAMES.BODY,TAG_ID.BODY],[TAG_NAMES.BR,TAG_ID.BR],[TAG_NAMES.BUTTON,TAG_ID.BUTTON],[TAG_NAMES.CAPTION,TAG_ID.CAPTION],[TAG_NAMES.CENTER,TAG_ID.CENTER],[TAG_NAMES.CODE,TAG_ID.CODE],[TAG_NAMES.COL,TAG_ID.COL],[TAG_NAMES.COLGROUP,TAG_ID.COLGROUP],[TAG_NAMES.DD,TAG_ID.DD],[TAG_NAMES.DESC,TAG_ID.DESC],[TAG_NAMES.DETAILS,TAG_ID.DETAILS],[TAG_NAMES.DIALOG,TAG_ID.DIALOG],[TAG_NAMES.DIR,TAG_ID.DIR],[TAG_NAMES.DIV,TAG_ID.DIV],[TAG_NAMES.DL,TAG_ID.DL],[TAG_NAMES.DT,TAG_ID.DT],[TAG_NAMES.EM,TAG_ID.EM],[TAG_NAMES.EMBED,TAG_ID.EMBED],[TAG_NAMES.FIELDSET,TAG_ID.FIELDSET],[TAG_NAMES.FIGCAPTION,TAG_ID.FIGCAPTION],[TAG_NAMES.FIGURE,TAG_ID.FIGURE],[TAG_NAMES.FONT,TAG_ID.FONT],[TAG_NAMES.FOOTER,TAG_ID.FOOTER],[TAG_NAMES.FOREIGN_OBJECT,TAG_ID.FOREIGN_OBJECT],[TAG_NAMES.FORM,TAG_ID.FORM],[TAG_NAMES.FRAME,TAG_ID.FRAME],[TAG_NAMES.FRAMESET,TAG_ID.FRAMESET],[TAG_NAMES.H1,TAG_ID.H1],[TAG_NAMES.H2,TAG_ID.H2],[TAG_NAMES.H3,TAG_ID.H3],[TAG_NAMES.H4,TAG_ID.H4],[TAG_NAMES.H5,TAG_ID.H5],[TAG_NAMES.H6,TAG_ID.H6],[TAG_NAMES.HEAD,TAG_ID.HEAD],[TAG_NAMES.HEADER,TAG_ID.HEADER],[TAG_NAMES.HGROUP,TAG_ID.HGROUP],[TAG_NAMES.HR,TAG_ID.HR],[TAG_NAMES.HTML,TAG_ID.HTML],[TAG_NAMES.I,TAG_ID.I],[TAG_NAMES.IMG,TAG_ID.IMG],[TAG_NAMES.IMAGE,TAG_ID.IMAGE],[TAG_NAMES.INPUT,TAG_ID.INPUT],[TAG_NAMES.IFRAME,TAG_ID.IFRAME],[TAG_NAMES.KEYGEN,TAG_ID.KEYGEN],[TAG_NAMES.LABEL,TAG_ID.LABEL],[TAG_NAMES.LI,TAG_ID.LI],[TAG_NAMES.LINK,TAG_ID.LINK],[TAG_NAMES.LISTING,TAG_ID.LISTING],[TAG_NAMES.MAIN,TAG_ID.MAIN],[TAG_NAMES.MALIGNMARK,TAG_ID.MALIGNMARK],[TAG_NAMES.MARQUEE,TAG_ID.MARQUEE],[TAG_NAMES.MATH,TAG_ID.MATH],[TAG_NAMES.MENU,TAG_ID.MENU],[TAG_NAMES.META,TAG_ID.META],[TAG_NAMES.MGLYPH,TAG_ID.MGLYPH],[TAG_NAMES.MI,TAG_ID.MI],[TAG_NAMES.MO,TAG_ID.MO],[TAG_NAMES.MN,TAG_ID.MN],[TAG_NAMES.MS,TAG_ID.MS],[TAG_NAMES.MTEXT,TAG_ID.MTEXT],[TAG_NAMES.NAV,TAG_ID.NAV],[TAG_NAMES.NOBR,TAG_ID.NOBR],[TAG_NAMES.NOFRAMES,TAG_ID.NOFRAMES],[TAG_NAMES.NOEMBED,TAG_ID.NOEMBED],[TAG_NAMES.NOSCRIPT,TAG_ID.NOSCRIPT],[TAG_NAMES.OBJECT,TAG_ID.OBJECT],[TAG_NAMES.OL,TAG_ID.OL],[TAG_NAMES.OPTGROUP,TAG_ID.OPTGROUP],[TAG_NAMES.OPTION,TAG_ID.OPTION],[TAG_NAMES.P,TAG_ID.P],[TAG_NAMES.PARAM,TAG_ID.PARAM],[TAG_NAMES.PLAINTEXT,TAG_ID.PLAINTEXT],[TAG_NAMES.PRE,TAG_ID.PRE],[TAG_NAMES.RB,TAG_ID.RB],[TAG_NAMES.RP,TAG_ID.RP],[TAG_NAMES.RT,TAG_ID.RT],[TAG_NAMES.RTC,TAG_ID.RTC],[TAG_NAMES.RUBY,TAG_ID.RUBY],[TAG_NAMES.S,TAG_ID.S],[TAG_NAMES.SCRIPT,TAG_ID.SCRIPT],[TAG_NAMES.SEARCH,TAG_ID.SEARCH],[TAG_NAMES.SECTION,TAG_ID.SECTION],[TAG_NAMES.SELECT,TAG_ID.SELECT],[TAG_NAMES.SOURCE,TAG_ID.SOURCE],[TAG_NAMES.SMALL,TAG_ID.SMALL],[TAG_NAMES.SPAN,TAG_ID.SPAN],[TAG_NAMES.STRIKE,TAG_ID.STRIKE],[TAG_NAMES.STRONG,TAG_ID.STRONG],[TAG_NAMES.STYLE,TAG_ID.STYLE],[TAG_NAMES.SUB,TAG_ID.SUB],[TAG_NAMES.SUMMARY,TAG_ID.SUMMARY],[TAG_NAMES.SUP,TAG_ID.SUP],[TAG_NAMES.TABLE,TAG_ID.TABLE],[TAG_NAMES.TBODY,TAG_ID.TBODY],[TAG_NAMES.TEMPLATE,TAG_ID.TEMPLATE],[TAG_NAMES.TEXTAREA,TAG_ID.TEXTAREA],[TAG_NAMES.TFOOT,TAG_ID.TFOOT],[TAG_NAMES.TD,TAG_ID.TD],[TAG_NAMES.TH,TAG_ID.TH],[TAG_NAMES.THEAD,TAG_ID.THEAD],[TAG_NAMES.TITLE,TAG_ID.TITLE],[TAG_NAMES.TR,TAG_ID.TR],[TAG_NAMES.TRACK,TAG_ID.TRACK],[TAG_NAMES.TT,TAG_ID.TT],[TAG_NAMES.U,TAG_ID.U],[TAG_NAMES.UL,TAG_ID.UL],[TAG_NAMES.SVG,TAG_ID.SVG],[TAG_NAMES.VAR,TAG_ID.VAR],[TAG_NAMES.WBR,TAG_ID.WBR],[TAG_NAMES.XMP,TAG_ID.XMP]]);function getTagID(tagName){var _a18;return(_a18=TAG_NAME_TO_ID.get(tagName))!==null&&_a18!==void 0?_a18:TAG_ID.UNKNOWN}__name(getTagID,"getTagID");const $=TAG_ID,SPECIAL_ELEMENTS={[NS.HTML]:new Set([$.ADDRESS,$.APPLET,$.AREA,$.ARTICLE,$.ASIDE,$.BASE,$.BASEFONT,$.BGSOUND,$.BLOCKQUOTE,$.BODY,$.BR,$.BUTTON,$.CAPTION,$.CENTER,$.COL,$.COLGROUP,$.DD,$.DETAILS,$.DIR,$.DIV,$.DL,$.DT,$.EMBED,$.FIELDSET,$.FIGCAPTION,$.FIGURE,$.FOOTER,$.FORM,$.FRAME,$.FRAMESET,$.H1,$.H2,$.H3,$.H4,$.H5,$.H6,$.HEAD,$.HEADER,$.HGROUP,$.HR,$.HTML,$.IFRAME,$.IMG,$.INPUT,$.LI,$.LINK,$.LISTING,$.MAIN,$.MARQUEE,$.MENU,$.META,$.NAV,$.NOEMBED,$.NOFRAMES,$.NOSCRIPT,$.OBJECT,$.OL,$.P,$.PARAM,$.PLAINTEXT,$.PRE,$.SCRIPT,$.SECTION,$.SELECT,$.SOURCE,$.STYLE,$.SUMMARY,$.TABLE,$.TBODY,$.TD,$.TEMPLATE,$.TEXTAREA,$.TFOOT,$.TH,$.THEAD,$.TITLE,$.TR,$.TRACK,$.UL,$.WBR,$.XMP]),[NS.MATHML]:new Set([$.MI,$.MO,$.MN,$.MS,$.MTEXT,$.ANNOTATION_XML]),[NS.SVG]:new Set([$.TITLE,$.FOREIGN_OBJECT,$.DESC]),[NS.XLINK]:new Set,[NS.XML]:new Set,[NS.XMLNS]:new Set},NUMBERED_HEADERS=new Set([$.H1,$.H2,$.H3,$.H4,$.H5,$.H6]);TAG_NAMES.STYLE,TAG_NAMES.SCRIPT,TAG_NAMES.XMP,TAG_NAMES.IFRAME,TAG_NAMES.NOEMBED,TAG_NAMES.NOFRAMES,TAG_NAMES.PLAINTEXT;var State;(function(State2){State2[State2.DATA=0]="DATA",State2[State2.RCDATA=1]="RCDATA",State2[State2.RAWTEXT=2]="RAWTEXT",State2[State2.SCRIPT_DATA=3]="SCRIPT_DATA",State2[State2.PLAINTEXT=4]="PLAINTEXT",State2[State2.TAG_OPEN=5]="TAG_OPEN",State2[State2.END_TAG_OPEN=6]="END_TAG_OPEN",State2[State2.TAG_NAME=7]="TAG_NAME",State2[State2.RCDATA_LESS_THAN_SIGN=8]="RCDATA_LESS_THAN_SIGN",State2[State2.RCDATA_END_TAG_OPEN=9]="RCDATA_END_TAG_OPEN",State2[State2.RCDATA_END_TAG_NAME=10]="RCDATA_END_TAG_NAME",State2[State2.RAWTEXT_LESS_THAN_SIGN=11]="RAWTEXT_LESS_THAN_SIGN",State2[State2.RAWTEXT_END_TAG_OPEN=12]="RAWTEXT_END_TAG_OPEN",State2[State2.RAWTEXT_END_TAG_NAME=13]="RAWTEXT_END_TAG_NAME",State2[State2.SCRIPT_DATA_LESS_THAN_SIGN=14]="SCRIPT_DATA_LESS_THAN_SIGN",State2[State2.SCRIPT_DATA_END_TAG_OPEN=15]="SCRIPT_DATA_END_TAG_OPEN",State2[State2.SCRIPT_DATA_END_TAG_NAME=16]="SCRIPT_DATA_END_TAG_NAME",State2[State2.SCRIPT_DATA_ESCAPE_START=17]="SCRIPT_DATA_ESCAPE_START",State2[State2.SCRIPT_DATA_ESCAPE_START_DASH=18]="SCRIPT_DATA_ESCAPE_START_DASH",State2[State2.SCRIPT_DATA_ESCAPED=19]="SCRIPT_DATA_ESCAPED",State2[State2.SCRIPT_DATA_ESCAPED_DASH=20]="SCRIPT_DATA_ESCAPED_DASH",State2[State2.SCRIPT_DATA_ESCAPED_DASH_DASH=21]="SCRIPT_DATA_ESCAPED_DASH_DASH",State2[State2.SCRIPT_DATA_ESCAPED_LESS_THAN_SIGN=22]="SCRIPT_DATA_ESCAPED_LESS_THAN_SIGN",State2[State2.SCRIPT_DATA_ESCAPED_END_TAG_OPEN=23]="SCRIPT_DATA_ESCAPED_END_TAG_OPEN",State2[State2.SCRIPT_DATA_ESCAPED_END_TAG_NAME=24]="SCRIPT_DATA_ESCAPED_END_TAG_NAME",State2[State2.SCRIPT_DATA_DOUBLE_ESCAPE_START=25]="SCRIPT_DATA_DOUBLE_ESCAPE_START",State2[State2.SCRIPT_DATA_DOUBLE_ESCAPED=26]="SCRIPT_DATA_DOUBLE_ESCAPED",State2[State2.SCRIPT_DATA_DOUBLE_ESCAPED_DASH=27]="SCRIPT_DATA_DOUBLE_ESCAPED_DASH",State2[State2.SCRIPT_DATA_DOUBLE_ESCAPED_DASH_DASH=28]="SCRIPT_DATA_DOUBLE_ESCAPED_DASH_DASH",State2[State2.SCRIPT_DATA_DOUBLE_ESCAPED_LESS_THAN_SIGN=29]="SCRIPT_DATA_DOUBLE_ESCAPED_LESS_THAN_SIGN",State2[State2.SCRIPT_DATA_DOUBLE_ESCAPE_END=30]="SCRIPT_DATA_DOUBLE_ESCAPE_END",State2[State2.BEFORE_ATTRIBUTE_NAME=31]="BEFORE_ATTRIBUTE_NAME",State2[State2.ATTRIBUTE_NAME=32]="ATTRIBUTE_NAME",State2[State2.AFTER_ATTRIBUTE_NAME=33]="AFTER_ATTRIBUTE_NAME",State2[State2.BEFORE_ATTRIBUTE_VALUE=34]="BEFORE_ATTRIBUTE_VALUE",State2[State2.ATTRIBUTE_VALUE_DOUBLE_QUOTED=35]="ATTRIBUTE_VALUE_DOUBLE_QUOTED",State2[State2.ATTRIBUTE_VALUE_SINGLE_QUOTED=36]="ATTRIBUTE_VALUE_SINGLE_QUOTED",State2[State2.ATTRIBUTE_VALUE_UNQUOTED=37]="ATTRIBUTE_VALUE_UNQUOTED",State2[State2.AFTER_ATTRIBUTE_VALUE_QUOTED=38]="AFTER_ATTRIBUTE_VALUE_QUOTED",State2[State2.SELF_CLOSING_START_TAG=39]="SELF_CLOSING_START_TAG",State2[State2.BOGUS_COMMENT=40]="BOGUS_COMMENT",State2[State2.MARKUP_DECLARATION_OPEN=41]="MARKUP_DECLARATION_OPEN",State2[State2.COMMENT_START=42]="COMMENT_START",State2[State2.COMMENT_START_DASH=43]="COMMENT_START_DASH",State2[State2.COMMENT=44]="COMMENT",State2[State2.COMMENT_LESS_THAN_SIGN=45]="COMMENT_LESS_THAN_SIGN",State2[State2.COMMENT_LESS_THAN_SIGN_BANG=46]="COMMENT_LESS_THAN_SIGN_BANG",State2[State2.COMMENT_LESS_THAN_SIGN_BANG_DASH=47]="COMMENT_LESS_THAN_SIGN_BANG_DASH",State2[State2.COMMENT_LESS_THAN_SIGN_BANG_DASH_DASH=48]="COMMENT_LESS_THAN_SIGN_BANG_DASH_DASH",State2[State2.COMMENT_END_DASH=49]="COMMENT_END_DASH",State2[State2.COMMENT_END=50]="COMMENT_END",State2[State2.COMMENT_END_BANG=51]="COMMENT_END_BANG",State2[State2.DOCTYPE=52]="DOCTYPE",State2[State2.BEFORE_DOCTYPE_NAME=53]="BEFORE_DOCTYPE_NAME",State2[State2.DOCTYPE_NAME=54]="DOCTYPE_NAME",State2[State2.AFTER_DOCTYPE_NAME=55]="AFTER_DOCTYPE_NAME",State2[State2.AFTER_DOCTYPE_PUBLIC_KEYWORD=56]="AFTER_DOCTYPE_PUBLIC_KEYWORD",State2[State2.BEFORE_DOCTYPE_PUBLIC_IDENTIFIER=57]="BEFORE_DOCTYPE_PUBLIC_IDENTIFIER",State2[State2.DOCTYPE_PUBLIC_IDENTIFIER_DOUBLE_QUOTED=58]="DOCTYPE_PUBLIC_IDENTIFIER_DOUBLE_QUOTED",State2[State2.DOCTYPE_PUBLIC_IDENTIFIER_SINGLE_QUOTED=59]="DOCTYPE_PUBLIC_IDENTIFIER_SINGLE_QUOTED",State2[State2.AFTER_DOCTYPE_PUBLIC_IDENTIFIER=60]="AFTER_DOCTYPE_PUBLIC_IDENTIFIER",State2[State2.BETWEEN_DOCTYPE_PUBLIC_AND_SYSTEM_IDENTIFIERS=61]="BETWEEN_DOCTYPE_PUBLIC_AND_SYSTEM_IDENTIFIERS",State2[State2.AFTER_DOCTYPE_SYSTEM_KEYWORD=62]="AFTER_DOCTYPE_SYSTEM_KEYWORD",State2[State2.BEFORE_DOCTYPE_SYSTEM_IDENTIFIER=63]="BEFORE_DOCTYPE_SYSTEM_IDENTIFIER",State2[State2.DOCTYPE_SYSTEM_IDENTIFIER_DOUBLE_QUOTED=64]="DOCTYPE_SYSTEM_IDENTIFIER_DOUBLE_QUOTED",State2[State2.DOCTYPE_SYSTEM_IDENTIFIER_SINGLE_QUOTED=65]="DOCTYPE_SYSTEM_IDENTIFIER_SINGLE_QUOTED",State2[State2.AFTER_DOCTYPE_SYSTEM_IDENTIFIER=66]="AFTER_DOCTYPE_SYSTEM_IDENTIFIER",State2[State2.BOGUS_DOCTYPE=67]="BOGUS_DOCTYPE",State2[State2.CDATA_SECTION=68]="CDATA_SECTION",State2[State2.CDATA_SECTION_BRACKET=69]="CDATA_SECTION_BRACKET",State2[State2.CDATA_SECTION_END=70]="CDATA_SECTION_END",State2[State2.CHARACTER_REFERENCE=71]="CHARACTER_REFERENCE",State2[State2.AMBIGUOUS_AMPERSAND=72]="AMBIGUOUS_AMPERSAND"})(State||(State={}));const TokenizerMode={DATA:State.DATA,RCDATA:State.RCDATA,RAWTEXT:State.RAWTEXT,SCRIPT_DATA:State.SCRIPT_DATA,PLAINTEXT:State.PLAINTEXT,CDATA_SECTION:State.CDATA_SECTION};function isAsciiDigit(cp){return cp>=CODE_POINTS.DIGIT_0&&cp<=CODE_POINTS.DIGIT_9}__name(isAsciiDigit,"isAsciiDigit");function isAsciiUpper(cp){return cp>=CODE_POINTS.LATIN_CAPITAL_A&&cp<=CODE_POINTS.LATIN_CAPITAL_Z}__name(isAsciiUpper,"isAsciiUpper");function isAsciiLower(cp){return cp>=CODE_POINTS.LATIN_SMALL_A&&cp<=CODE_POINTS.LATIN_SMALL_Z}__name(isAsciiLower,"isAsciiLower");function isAsciiLetter(cp){return isAsciiLower(cp)||isAsciiUpper(cp)}__name(isAsciiLetter,"isAsciiLetter");function isAsciiAlphaNumeric(cp){return isAsciiLetter(cp)||isAsciiDigit(cp)}__name(isAsciiAlphaNumeric,"isAsciiAlphaNumeric");function toAsciiLower(cp){return cp+32}__name(toAsciiLower,"toAsciiLower");function isWhitespace(cp){return cp===CODE_POINTS.SPACE||cp===CODE_POINTS.LINE_FEED||cp===CODE_POINTS.TABULATION||cp===CODE_POINTS.FORM_FEED}__name(isWhitespace,"isWhitespace");function isScriptDataDoubleEscapeSequenceEnd(cp){return isWhitespace(cp)||cp===CODE_POINTS.SOLIDUS||cp===CODE_POINTS.GREATER_THAN_SIGN}__name(isScriptDataDoubleEscapeSequenceEnd,"isScriptDataDoubleEscapeSequenceEnd");function getErrorForNumericCharacterReference(code2){return code2===CODE_POINTS.NULL?ERR.nullCharacterReference:code2>1114111?ERR.characterReferenceOutsideUnicodeRange:isSurrogate(code2)?ERR.surrogateCharacterReference:isUndefinedCodePoint(code2)?ERR.noncharacterCharacterReference:isControlCodePoint(code2)||code2===CODE_POINTS.CARRIAGE_RETURN?ERR.controlCharacterReference:null}__name(getErrorForNumericCharacterReference,"getErrorForNumericCharacterReference");const _Tokenizer=class _Tokenizer{constructor(options,handler){this.options=options,this.handler=handler,this.paused=!1,this.inLoop=!1,this.inForeignNode=!1,this.lastStartTagName="",this.active=!1,this.state=State.DATA,this.returnState=State.DATA,this.entityStartPos=0,this.consumedAfterSnapshot=-1,this.currentCharacterToken=null,this.currentToken=null,this.currentAttr={name:"",value:""},this.preprocessor=new Preprocessor(handler),this.currentLocation=this.getCurrentLocation(-1),this.entityDecoder=new EntityDecoder(htmlDecodeTree,(cp,consumed)=>{this.preprocessor.pos=this.entityStartPos+consumed-1,this._flushCodePointConsumedAsCharacterReference(cp)},handler.onParseError?{missingSemicolonAfterCharacterReference:__name(()=>{this._err(ERR.missingSemicolonAfterCharacterReference,1)},"missingSemicolonAfterCharacterReference"),absenceOfDigitsInNumericCharacterReference:__name(consumed=>{this._err(ERR.absenceOfDigitsInNumericCharacterReference,this.entityStartPos-this.preprocessor.pos+consumed)},"absenceOfDigitsInNumericCharacterReference"),validateNumericCharacterReference:__name(code2=>{const error=getErrorForNumericCharacterReference(code2);error&&this._err(error,1)},"validateNumericCharacterReference")}:void 0)}_err(code2,cpOffset=0){var _a18,_b;(_b=(_a18=this.handler).onParseError)===null||_b===void 0||_b.call(_a18,this.preprocessor.getError(code2,cpOffset))}getCurrentLocation(offset2){return this.options.sourceCodeLocationInfo?{startLine:this.preprocessor.line,startCol:this.preprocessor.col-offset2,startOffset:this.preprocessor.offset-offset2,endLine:-1,endCol:-1,endOffset:-1}:null}_runParsingLoop(){if(!this.inLoop){for(this.inLoop=!0;this.active&&!this.paused;){this.consumedAfterSnapshot=0;const cp=this._consume();this._ensureHibernation()||this._callState(cp)}this.inLoop=!1}}pause(){this.paused=!0}resume(writeCallback){if(!this.paused)throw new Error("Parser was already resumed");this.paused=!1,!this.inLoop&&(this._runParsingLoop(),this.paused||writeCallback?.())}write(chunk,isLastChunk,writeCallback){this.active=!0,this.preprocessor.write(chunk,isLastChunk),this._runParsingLoop(),this.paused||writeCallback?.()}insertHtmlAtCurrentPos(chunk){this.active=!0,this.preprocessor.insertHtmlAtCurrentPos(chunk),this._runParsingLoop()}_ensureHibernation(){return this.preprocessor.endOfChunkHit?(this.preprocessor.retreat(this.consumedAfterSnapshot),this.consumedAfterSnapshot=0,this.active=!1,!0):!1}_consume(){return this.consumedAfterSnapshot++,this.preprocessor.advance()}_advanceBy(count2){this.consumedAfterSnapshot+=count2;for(let i2=0;i20&&this._err(ERR.endTagWithAttributes),ct.selfClosing&&this._err(ERR.endTagWithTrailingSolidus),this.handler.onEndTag(ct)),this.preprocessor.dropParsedChunk()}emitCurrentComment(ct){this.prepareToken(ct),this.handler.onComment(ct),this.preprocessor.dropParsedChunk()}emitCurrentDoctype(ct){this.prepareToken(ct),this.handler.onDoctype(ct),this.preprocessor.dropParsedChunk()}_emitCurrentCharacterToken(nextLocation){if(this.currentCharacterToken){switch(nextLocation&&this.currentCharacterToken.location&&(this.currentCharacterToken.location.endLine=nextLocation.startLine,this.currentCharacterToken.location.endCol=nextLocation.startCol,this.currentCharacterToken.location.endOffset=nextLocation.startOffset),this.currentCharacterToken.type){case TokenType.CHARACTER:{this.handler.onCharacter(this.currentCharacterToken);break}case TokenType.NULL_CHARACTER:{this.handler.onNullCharacter(this.currentCharacterToken);break}case TokenType.WHITESPACE_CHARACTER:{this.handler.onWhitespaceCharacter(this.currentCharacterToken);break}}this.currentCharacterToken=null}}_emitEOFToken(){const location2=this.getCurrentLocation(0);location2&&(location2.endLine=location2.startLine,location2.endCol=location2.startCol,location2.endOffset=location2.startOffset),this._emitCurrentCharacterToken(location2),this.handler.onEof({type:TokenType.EOF,location:location2}),this.active=!1}_appendCharToCurrentCharacterToken(type,ch){if(this.currentCharacterToken)if(this.currentCharacterToken.type===type){this.currentCharacterToken.chars+=ch;return}else this.currentLocation=this.getCurrentLocation(0),this._emitCurrentCharacterToken(this.currentLocation),this.preprocessor.dropParsedChunk();this._createCharacterToken(type,ch)}_emitCodePoint(cp){const type=isWhitespace(cp)?TokenType.WHITESPACE_CHARACTER:cp===CODE_POINTS.NULL?TokenType.NULL_CHARACTER:TokenType.CHARACTER;this._appendCharToCurrentCharacterToken(type,String.fromCodePoint(cp))}_emitChars(ch){this._appendCharToCurrentCharacterToken(TokenType.CHARACTER,ch)}_startCharacterReference(){this.returnState=this.state,this.state=State.CHARACTER_REFERENCE,this.entityStartPos=this.preprocessor.pos,this.entityDecoder.startEntity(this._isCharacterReferenceInAttribute()?DecodingMode.Attribute:DecodingMode.Legacy)}_isCharacterReferenceInAttribute(){return this.returnState===State.ATTRIBUTE_VALUE_DOUBLE_QUOTED||this.returnState===State.ATTRIBUTE_VALUE_SINGLE_QUOTED||this.returnState===State.ATTRIBUTE_VALUE_UNQUOTED}_flushCodePointConsumedAsCharacterReference(cp){this._isCharacterReferenceInAttribute()?this.currentAttr.value+=String.fromCodePoint(cp):this._emitCodePoint(cp)}_callState(cp){switch(this.state){case State.DATA:{this._stateData(cp);break}case State.RCDATA:{this._stateRcdata(cp);break}case State.RAWTEXT:{this._stateRawtext(cp);break}case State.SCRIPT_DATA:{this._stateScriptData(cp);break}case State.PLAINTEXT:{this._statePlaintext(cp);break}case State.TAG_OPEN:{this._stateTagOpen(cp);break}case State.END_TAG_OPEN:{this._stateEndTagOpen(cp);break}case State.TAG_NAME:{this._stateTagName(cp);break}case State.RCDATA_LESS_THAN_SIGN:{this._stateRcdataLessThanSign(cp);break}case State.RCDATA_END_TAG_OPEN:{this._stateRcdataEndTagOpen(cp);break}case State.RCDATA_END_TAG_NAME:{this._stateRcdataEndTagName(cp);break}case State.RAWTEXT_LESS_THAN_SIGN:{this._stateRawtextLessThanSign(cp);break}case State.RAWTEXT_END_TAG_OPEN:{this._stateRawtextEndTagOpen(cp);break}case State.RAWTEXT_END_TAG_NAME:{this._stateRawtextEndTagName(cp);break}case State.SCRIPT_DATA_LESS_THAN_SIGN:{this._stateScriptDataLessThanSign(cp);break}case State.SCRIPT_DATA_END_TAG_OPEN:{this._stateScriptDataEndTagOpen(cp);break}case State.SCRIPT_DATA_END_TAG_NAME:{this._stateScriptDataEndTagName(cp);break}case State.SCRIPT_DATA_ESCAPE_START:{this._stateScriptDataEscapeStart(cp);break}case State.SCRIPT_DATA_ESCAPE_START_DASH:{this._stateScriptDataEscapeStartDash(cp);break}case State.SCRIPT_DATA_ESCAPED:{this._stateScriptDataEscaped(cp);break}case State.SCRIPT_DATA_ESCAPED_DASH:{this._stateScriptDataEscapedDash(cp);break}case State.SCRIPT_DATA_ESCAPED_DASH_DASH:{this._stateScriptDataEscapedDashDash(cp);break}case State.SCRIPT_DATA_ESCAPED_LESS_THAN_SIGN:{this._stateScriptDataEscapedLessThanSign(cp);break}case State.SCRIPT_DATA_ESCAPED_END_TAG_OPEN:{this._stateScriptDataEscapedEndTagOpen(cp);break}case State.SCRIPT_DATA_ESCAPED_END_TAG_NAME:{this._stateScriptDataEscapedEndTagName(cp);break}case State.SCRIPT_DATA_DOUBLE_ESCAPE_START:{this._stateScriptDataDoubleEscapeStart(cp);break}case State.SCRIPT_DATA_DOUBLE_ESCAPED:{this._stateScriptDataDoubleEscaped(cp);break}case State.SCRIPT_DATA_DOUBLE_ESCAPED_DASH:{this._stateScriptDataDoubleEscapedDash(cp);break}case State.SCRIPT_DATA_DOUBLE_ESCAPED_DASH_DASH:{this._stateScriptDataDoubleEscapedDashDash(cp);break}case State.SCRIPT_DATA_DOUBLE_ESCAPED_LESS_THAN_SIGN:{this._stateScriptDataDoubleEscapedLessThanSign(cp);break}case State.SCRIPT_DATA_DOUBLE_ESCAPE_END:{this._stateScriptDataDoubleEscapeEnd(cp);break}case State.BEFORE_ATTRIBUTE_NAME:{this._stateBeforeAttributeName(cp);break}case State.ATTRIBUTE_NAME:{this._stateAttributeName(cp);break}case State.AFTER_ATTRIBUTE_NAME:{this._stateAfterAttributeName(cp);break}case State.BEFORE_ATTRIBUTE_VALUE:{this._stateBeforeAttributeValue(cp);break}case State.ATTRIBUTE_VALUE_DOUBLE_QUOTED:{this._stateAttributeValueDoubleQuoted(cp);break}case State.ATTRIBUTE_VALUE_SINGLE_QUOTED:{this._stateAttributeValueSingleQuoted(cp);break}case State.ATTRIBUTE_VALUE_UNQUOTED:{this._stateAttributeValueUnquoted(cp);break}case State.AFTER_ATTRIBUTE_VALUE_QUOTED:{this._stateAfterAttributeValueQuoted(cp);break}case State.SELF_CLOSING_START_TAG:{this._stateSelfClosingStartTag(cp);break}case State.BOGUS_COMMENT:{this._stateBogusComment(cp);break}case State.MARKUP_DECLARATION_OPEN:{this._stateMarkupDeclarationOpen(cp);break}case State.COMMENT_START:{this._stateCommentStart(cp);break}case State.COMMENT_START_DASH:{this._stateCommentStartDash(cp);break}case State.COMMENT:{this._stateComment(cp);break}case State.COMMENT_LESS_THAN_SIGN:{this._stateCommentLessThanSign(cp);break}case State.COMMENT_LESS_THAN_SIGN_BANG:{this._stateCommentLessThanSignBang(cp);break}case State.COMMENT_LESS_THAN_SIGN_BANG_DASH:{this._stateCommentLessThanSignBangDash(cp);break}case State.COMMENT_LESS_THAN_SIGN_BANG_DASH_DASH:{this._stateCommentLessThanSignBangDashDash(cp);break}case State.COMMENT_END_DASH:{this._stateCommentEndDash(cp);break}case State.COMMENT_END:{this._stateCommentEnd(cp);break}case State.COMMENT_END_BANG:{this._stateCommentEndBang(cp);break}case State.DOCTYPE:{this._stateDoctype(cp);break}case State.BEFORE_DOCTYPE_NAME:{this._stateBeforeDoctypeName(cp);break}case State.DOCTYPE_NAME:{this._stateDoctypeName(cp);break}case State.AFTER_DOCTYPE_NAME:{this._stateAfterDoctypeName(cp);break}case State.AFTER_DOCTYPE_PUBLIC_KEYWORD:{this._stateAfterDoctypePublicKeyword(cp);break}case State.BEFORE_DOCTYPE_PUBLIC_IDENTIFIER:{this._stateBeforeDoctypePublicIdentifier(cp);break}case State.DOCTYPE_PUBLIC_IDENTIFIER_DOUBLE_QUOTED:{this._stateDoctypePublicIdentifierDoubleQuoted(cp);break}case State.DOCTYPE_PUBLIC_IDENTIFIER_SINGLE_QUOTED:{this._stateDoctypePublicIdentifierSingleQuoted(cp);break}case State.AFTER_DOCTYPE_PUBLIC_IDENTIFIER:{this._stateAfterDoctypePublicIdentifier(cp);break}case State.BETWEEN_DOCTYPE_PUBLIC_AND_SYSTEM_IDENTIFIERS:{this._stateBetweenDoctypePublicAndSystemIdentifiers(cp);break}case State.AFTER_DOCTYPE_SYSTEM_KEYWORD:{this._stateAfterDoctypeSystemKeyword(cp);break}case State.BEFORE_DOCTYPE_SYSTEM_IDENTIFIER:{this._stateBeforeDoctypeSystemIdentifier(cp);break}case State.DOCTYPE_SYSTEM_IDENTIFIER_DOUBLE_QUOTED:{this._stateDoctypeSystemIdentifierDoubleQuoted(cp);break}case State.DOCTYPE_SYSTEM_IDENTIFIER_SINGLE_QUOTED:{this._stateDoctypeSystemIdentifierSingleQuoted(cp);break}case State.AFTER_DOCTYPE_SYSTEM_IDENTIFIER:{this._stateAfterDoctypeSystemIdentifier(cp);break}case State.BOGUS_DOCTYPE:{this._stateBogusDoctype(cp);break}case State.CDATA_SECTION:{this._stateCdataSection(cp);break}case State.CDATA_SECTION_BRACKET:{this._stateCdataSectionBracket(cp);break}case State.CDATA_SECTION_END:{this._stateCdataSectionEnd(cp);break}case State.CHARACTER_REFERENCE:{this._stateCharacterReference();break}case State.AMBIGUOUS_AMPERSAND:{this._stateAmbiguousAmpersand(cp);break}default:throw new Error("Unknown state")}}_stateData(cp){switch(cp){case CODE_POINTS.LESS_THAN_SIGN:{this.state=State.TAG_OPEN;break}case CODE_POINTS.AMPERSAND:{this._startCharacterReference();break}case CODE_POINTS.NULL:{this._err(ERR.unexpectedNullCharacter),this._emitCodePoint(cp);break}case CODE_POINTS.EOF:{this._emitEOFToken();break}default:this._emitCodePoint(cp)}}_stateRcdata(cp){switch(cp){case CODE_POINTS.AMPERSAND:{this._startCharacterReference();break}case CODE_POINTS.LESS_THAN_SIGN:{this.state=State.RCDATA_LESS_THAN_SIGN;break}case CODE_POINTS.NULL:{this._err(ERR.unexpectedNullCharacter),this._emitChars(REPLACEMENT_CHARACTER);break}case CODE_POINTS.EOF:{this._emitEOFToken();break}default:this._emitCodePoint(cp)}}_stateRawtext(cp){switch(cp){case CODE_POINTS.LESS_THAN_SIGN:{this.state=State.RAWTEXT_LESS_THAN_SIGN;break}case CODE_POINTS.NULL:{this._err(ERR.unexpectedNullCharacter),this._emitChars(REPLACEMENT_CHARACTER);break}case CODE_POINTS.EOF:{this._emitEOFToken();break}default:this._emitCodePoint(cp)}}_stateScriptData(cp){switch(cp){case CODE_POINTS.LESS_THAN_SIGN:{this.state=State.SCRIPT_DATA_LESS_THAN_SIGN;break}case CODE_POINTS.NULL:{this._err(ERR.unexpectedNullCharacter),this._emitChars(REPLACEMENT_CHARACTER);break}case CODE_POINTS.EOF:{this._emitEOFToken();break}default:this._emitCodePoint(cp)}}_statePlaintext(cp){switch(cp){case CODE_POINTS.NULL:{this._err(ERR.unexpectedNullCharacter),this._emitChars(REPLACEMENT_CHARACTER);break}case CODE_POINTS.EOF:{this._emitEOFToken();break}default:this._emitCodePoint(cp)}}_stateTagOpen(cp){if(isAsciiLetter(cp))this._createStartTagToken(),this.state=State.TAG_NAME,this._stateTagName(cp);else switch(cp){case CODE_POINTS.EXCLAMATION_MARK:{this.state=State.MARKUP_DECLARATION_OPEN;break}case CODE_POINTS.SOLIDUS:{this.state=State.END_TAG_OPEN;break}case CODE_POINTS.QUESTION_MARK:{this._err(ERR.unexpectedQuestionMarkInsteadOfTagName),this._createCommentToken(1),this.state=State.BOGUS_COMMENT,this._stateBogusComment(cp);break}case CODE_POINTS.EOF:{this._err(ERR.eofBeforeTagName),this._emitChars("<"),this._emitEOFToken();break}default:this._err(ERR.invalidFirstCharacterOfTagName),this._emitChars("<"),this.state=State.DATA,this._stateData(cp)}}_stateEndTagOpen(cp){if(isAsciiLetter(cp))this._createEndTagToken(),this.state=State.TAG_NAME,this._stateTagName(cp);else switch(cp){case CODE_POINTS.GREATER_THAN_SIGN:{this._err(ERR.missingEndTagName),this.state=State.DATA;break}case CODE_POINTS.EOF:{this._err(ERR.eofBeforeTagName),this._emitChars("");break}case CODE_POINTS.NULL:{this._err(ERR.unexpectedNullCharacter),this.state=State.SCRIPT_DATA_ESCAPED,this._emitChars(REPLACEMENT_CHARACTER);break}case CODE_POINTS.EOF:{this._err(ERR.eofInScriptHtmlCommentLikeText),this._emitEOFToken();break}default:this.state=State.SCRIPT_DATA_ESCAPED,this._emitCodePoint(cp)}}_stateScriptDataEscapedLessThanSign(cp){cp===CODE_POINTS.SOLIDUS?this.state=State.SCRIPT_DATA_ESCAPED_END_TAG_OPEN:isAsciiLetter(cp)?(this._emitChars("<"),this.state=State.SCRIPT_DATA_DOUBLE_ESCAPE_START,this._stateScriptDataDoubleEscapeStart(cp)):(this._emitChars("<"),this.state=State.SCRIPT_DATA_ESCAPED,this._stateScriptDataEscaped(cp))}_stateScriptDataEscapedEndTagOpen(cp){isAsciiLetter(cp)?(this.state=State.SCRIPT_DATA_ESCAPED_END_TAG_NAME,this._stateScriptDataEscapedEndTagName(cp)):(this._emitChars("");break}case CODE_POINTS.NULL:{this._err(ERR.unexpectedNullCharacter),this.state=State.SCRIPT_DATA_DOUBLE_ESCAPED,this._emitChars(REPLACEMENT_CHARACTER);break}case CODE_POINTS.EOF:{this._err(ERR.eofInScriptHtmlCommentLikeText),this._emitEOFToken();break}default:this.state=State.SCRIPT_DATA_DOUBLE_ESCAPED,this._emitCodePoint(cp)}}_stateScriptDataDoubleEscapedLessThanSign(cp){cp===CODE_POINTS.SOLIDUS?(this.state=State.SCRIPT_DATA_DOUBLE_ESCAPE_END,this._emitChars("/")):(this.state=State.SCRIPT_DATA_DOUBLE_ESCAPED,this._stateScriptDataDoubleEscaped(cp))}_stateScriptDataDoubleEscapeEnd(cp){if(this.preprocessor.startsWith(SEQUENCES.SCRIPT,!1)&&isScriptDataDoubleEscapeSequenceEnd(this.preprocessor.peek(SEQUENCES.SCRIPT.length))){this._emitCodePoint(cp);for(let i2=0;i20&&this._isInTemplate()&&this.tmplCount--,this.stackTop--,this._updateCurrentElement(),this.handler.onItemPop(popped,!0)}replace(oldElement,newElement){const idx=this._indexOf(oldElement);this.items[idx]=newElement,idx===this.stackTop&&(this.current=newElement)}insertAfter(referenceElement,newElement,newElementID){const insertionIdx=this._indexOf(referenceElement)+1;this.items.splice(insertionIdx,0,newElement),this.tagIDs.splice(insertionIdx,0,newElementID),this.stackTop++,insertionIdx===this.stackTop&&this._updateCurrentElement(),this.current&&this.currentTagId!==void 0&&this.handler.onItemPush(this.current,this.currentTagId,insertionIdx===this.stackTop)}popUntilTagNamePopped(tagName){let targetIdx=this.stackTop+1;do targetIdx=this.tagIDs.lastIndexOf(tagName,targetIdx-1);while(targetIdx>0&&this.treeAdapter.getNamespaceURI(this.items[targetIdx])!==NS.HTML);this.shortenToLength(Math.max(targetIdx,0))}shortenToLength(idx){for(;this.stackTop>=idx;){const popped=this.current;this.tmplCount>0&&this._isInTemplate()&&(this.tmplCount-=1),this.stackTop--,this._updateCurrentElement(),this.handler.onItemPop(popped,this.stackTop=0;i2--)if(tagNames.has(this.tagIDs[i2])&&this.treeAdapter.getNamespaceURI(this.items[i2])===namespace)return i2;return-1}clearBackTo(tagNames,targetNS){const idx=this._indexOfTagNames(tagNames,targetNS);this.shortenToLength(idx+1)}clearBackToTableContext(){this.clearBackTo(TABLE_CONTEXT,NS.HTML)}clearBackToTableBodyContext(){this.clearBackTo(TABLE_BODY_CONTEXT,NS.HTML)}clearBackToTableRowContext(){this.clearBackTo(TABLE_ROW_CONTEXT,NS.HTML)}remove(element2){const idx=this._indexOf(element2);idx>=0&&(idx===this.stackTop?this.pop():(this.items.splice(idx,1),this.tagIDs.splice(idx,1),this.stackTop--,this._updateCurrentElement(),this.handler.onItemPop(element2,!1)))}tryPeekProperlyNestedBodyElement(){return this.stackTop>=1&&this.tagIDs[1]===TAG_ID.BODY?this.items[1]:null}contains(element2){return this._indexOf(element2)>-1}getCommonAncestor(element2){const elementIdx=this._indexOf(element2)-1;return elementIdx>=0?this.items[elementIdx]:null}isRootHtmlElementCurrent(){return this.stackTop===0&&this.tagIDs[0]===TAG_ID.HTML}hasInDynamicScope(tagName,htmlScope){for(let i2=this.stackTop;i2>=0;i2--){const tn=this.tagIDs[i2];switch(this.treeAdapter.getNamespaceURI(this.items[i2])){case NS.HTML:{if(tn===tagName)return!0;if(htmlScope.has(tn))return!1;break}case NS.SVG:{if(SCOPING_ELEMENTS_SVG.has(tn))return!1;break}case NS.MATHML:{if(SCOPING_ELEMENTS_MATHML.has(tn))return!1;break}}}return!0}hasInScope(tagName){return this.hasInDynamicScope(tagName,SCOPING_ELEMENTS_HTML)}hasInListItemScope(tagName){return this.hasInDynamicScope(tagName,SCOPING_ELEMENTS_HTML_LIST)}hasInButtonScope(tagName){return this.hasInDynamicScope(tagName,SCOPING_ELEMENTS_HTML_BUTTON)}hasNumberedHeaderInScope(){for(let i2=this.stackTop;i2>=0;i2--){const tn=this.tagIDs[i2];switch(this.treeAdapter.getNamespaceURI(this.items[i2])){case NS.HTML:{if(NUMBERED_HEADERS.has(tn))return!0;if(SCOPING_ELEMENTS_HTML.has(tn))return!1;break}case NS.SVG:{if(SCOPING_ELEMENTS_SVG.has(tn))return!1;break}case NS.MATHML:{if(SCOPING_ELEMENTS_MATHML.has(tn))return!1;break}}}return!0}hasInTableScope(tagName){for(let i2=this.stackTop;i2>=0;i2--)if(this.treeAdapter.getNamespaceURI(this.items[i2])===NS.HTML)switch(this.tagIDs[i2]){case tagName:return!0;case TAG_ID.TABLE:case TAG_ID.HTML:return!1}return!0}hasTableBodyContextInTableScope(){for(let i2=this.stackTop;i2>=0;i2--)if(this.treeAdapter.getNamespaceURI(this.items[i2])===NS.HTML)switch(this.tagIDs[i2]){case TAG_ID.TBODY:case TAG_ID.THEAD:case TAG_ID.TFOOT:return!0;case TAG_ID.TABLE:case TAG_ID.HTML:return!1}return!0}hasInSelectScope(tagName){for(let i2=this.stackTop;i2>=0;i2--)if(this.treeAdapter.getNamespaceURI(this.items[i2])===NS.HTML)switch(this.tagIDs[i2]){case tagName:return!0;case TAG_ID.OPTION:case TAG_ID.OPTGROUP:break;default:return!1}return!0}generateImpliedEndTags(){for(;this.currentTagId!==void 0&&IMPLICIT_END_TAG_REQUIRED.has(this.currentTagId);)this.pop()}generateImpliedEndTagsThoroughly(){for(;this.currentTagId!==void 0&&IMPLICIT_END_TAG_REQUIRED_THOROUGHLY.has(this.currentTagId);)this.pop()}generateImpliedEndTagsWithExclusion(exclusionId){for(;this.currentTagId!==void 0&&this.currentTagId!==exclusionId&&IMPLICIT_END_TAG_REQUIRED_THOROUGHLY.has(this.currentTagId);)this.pop()}};__name(_OpenElementStack,"OpenElementStack");let OpenElementStack=_OpenElementStack;const NOAH_ARK_CAPACITY=3;var EntryType;(function(EntryType2){EntryType2[EntryType2.Marker=0]="Marker",EntryType2[EntryType2.Element=1]="Element"})(EntryType||(EntryType={}));const MARKER={type:EntryType.Marker},_FormattingElementList=class _FormattingElementList{constructor(treeAdapter){this.treeAdapter=treeAdapter,this.entries=[],this.bookmark=null}_getNoahArkConditionCandidates(newElement,neAttrs){const candidates=[],neAttrsLength=neAttrs.length,neTagName=this.treeAdapter.getTagName(newElement),neNamespaceURI=this.treeAdapter.getNamespaceURI(newElement);for(let i2=0;i2[neAttr.name,neAttr.value]));let validCandidates=0;for(let i2=0;i2neAttrsMap.get(cAttr.name)===cAttr.value)&&(validCandidates+=1,validCandidates>=NOAH_ARK_CAPACITY&&this.entries.splice(candidate.idx,1))}}insertMarker(){this.entries.unshift(MARKER)}pushElement(element2,token){this._ensureNoahArkCondition(element2),this.entries.unshift({type:EntryType.Element,element:element2,token})}insertElementAfterBookmark(element2,token){const bookmarkIdx=this.entries.indexOf(this.bookmark);this.entries.splice(bookmarkIdx,0,{type:EntryType.Element,element:element2,token})}removeEntry(entry){const entryIndex=this.entries.indexOf(entry);entryIndex!==-1&&this.entries.splice(entryIndex,1)}clearToLastMarker(){const markerIdx=this.entries.indexOf(MARKER);markerIdx===-1?this.entries.length=0:this.entries.splice(0,markerIdx+1)}getElementEntryInScopeWithTagName(tagName){const entry=this.entries.find(entry2=>entry2.type===EntryType.Marker||this.treeAdapter.getTagName(entry2.element)===tagName);return entry&&entry.type===EntryType.Element?entry:null}getElementEntry(element2){return this.entries.find(entry=>entry.type===EntryType.Element&&entry.element===element2)}};__name(_FormattingElementList,"FormattingElementList");let FormattingElementList=_FormattingElementList;const defaultTreeAdapter={createDocument(){return{nodeName:"#document",mode:DOCUMENT_MODE.NO_QUIRKS,childNodes:[]}},createDocumentFragment(){return{nodeName:"#document-fragment",childNodes:[]}},createElement(tagName,namespaceURI,attrs){return{nodeName:tagName,tagName,attrs,namespaceURI,childNodes:[],parentNode:null}},createCommentNode(data){return{nodeName:"#comment",data,parentNode:null}},createTextNode(value2){return{nodeName:"#text",value:value2,parentNode:null}},appendChild(parentNode,newNode){parentNode.childNodes.push(newNode),newNode.parentNode=parentNode},insertBefore(parentNode,newNode,referenceNode){const insertionIdx=parentNode.childNodes.indexOf(referenceNode);parentNode.childNodes.splice(insertionIdx,0,newNode),newNode.parentNode=parentNode},setTemplateContent(templateElement,contentElement){templateElement.content=contentElement},getTemplateContent(templateElement){return templateElement.content},setDocumentType(document2,name2,publicId,systemId){const doctypeNode=document2.childNodes.find(node2=>node2.nodeName==="#documentType");if(doctypeNode)doctypeNode.name=name2,doctypeNode.publicId=publicId,doctypeNode.systemId=systemId;else{const node2={nodeName:"#documentType",name:name2,publicId,systemId,parentNode:null};defaultTreeAdapter.appendChild(document2,node2)}},setDocumentMode(document2,mode){document2.mode=mode},getDocumentMode(document2){return document2.mode},detachNode(node2){if(node2.parentNode){const idx=node2.parentNode.childNodes.indexOf(node2);node2.parentNode.childNodes.splice(idx,1),node2.parentNode=null}},insertText(parentNode,text2){if(parentNode.childNodes.length>0){const prevNode=parentNode.childNodes[parentNode.childNodes.length-1];if(defaultTreeAdapter.isTextNode(prevNode)){prevNode.value+=text2;return}}defaultTreeAdapter.appendChild(parentNode,defaultTreeAdapter.createTextNode(text2))},insertTextBefore(parentNode,text2,referenceNode){const prevNode=parentNode.childNodes[parentNode.childNodes.indexOf(referenceNode)-1];prevNode&&defaultTreeAdapter.isTextNode(prevNode)?prevNode.value+=text2:defaultTreeAdapter.insertBefore(parentNode,defaultTreeAdapter.createTextNode(text2),referenceNode)},adoptAttributes(recipient,attrs){const recipientAttrsMap=new Set(recipient.attrs.map(attr=>attr.name));for(let j2=0;j2publicId.startsWith(prefix2))}__name(hasPrefix,"hasPrefix");function isConforming(token){return token.name===VALID_DOCTYPE_NAME&&token.publicId===null&&(token.systemId===null||token.systemId===VALID_SYSTEM_ID)}__name(isConforming,"isConforming");function getDocumentMode(token){if(token.name!==VALID_DOCTYPE_NAME)return DOCUMENT_MODE.QUIRKS;const{systemId}=token;if(systemId&&systemId.toLowerCase()===QUIRKS_MODE_SYSTEM_ID)return DOCUMENT_MODE.QUIRKS;let{publicId}=token;if(publicId!==null){if(publicId=publicId.toLowerCase(),QUIRKS_MODE_PUBLIC_IDS.has(publicId))return DOCUMENT_MODE.QUIRKS;let prefixes2=systemId===null?QUIRKS_MODE_NO_SYSTEM_ID_PUBLIC_ID_PREFIXES:QUIRKS_MODE_PUBLIC_ID_PREFIXES;if(hasPrefix(publicId,prefixes2))return DOCUMENT_MODE.QUIRKS;if(prefixes2=systemId===null?LIMITED_QUIRKS_PUBLIC_ID_PREFIXES:LIMITED_QUIRKS_WITH_SYSTEM_ID_PUBLIC_ID_PREFIXES,hasPrefix(publicId,prefixes2))return DOCUMENT_MODE.LIMITED_QUIRKS}return DOCUMENT_MODE.NO_QUIRKS}__name(getDocumentMode,"getDocumentMode");const MIME_TYPES={TEXT_HTML:"text/html",APPLICATION_XML:"application/xhtml+xml"},DEFINITION_URL_ATTR="definitionurl",ADJUSTED_DEFINITION_URL_ATTR="definitionURL",SVG_ATTRS_ADJUSTMENT_MAP=new Map(["attributeName","attributeType","baseFrequency","baseProfile","calcMode","clipPathUnits","diffuseConstant","edgeMode","filterUnits","glyphRef","gradientTransform","gradientUnits","kernelMatrix","kernelUnitLength","keyPoints","keySplines","keyTimes","lengthAdjust","limitingConeAngle","markerHeight","markerUnits","markerWidth","maskContentUnits","maskUnits","numOctaves","pathLength","patternContentUnits","patternTransform","patternUnits","pointsAtX","pointsAtY","pointsAtZ","preserveAlpha","preserveAspectRatio","primitiveUnits","refX","refY","repeatCount","repeatDur","requiredExtensions","requiredFeatures","specularConstant","specularExponent","spreadMethod","startOffset","stdDeviation","stitchTiles","surfaceScale","systemLanguage","tableValues","targetX","targetY","textLength","viewBox","viewTarget","xChannelSelector","yChannelSelector","zoomAndPan"].map(attr=>[attr.toLowerCase(),attr])),XML_ATTRS_ADJUSTMENT_MAP=new Map([["xlink:actuate",{prefix:"xlink",name:"actuate",namespace:NS.XLINK}],["xlink:arcrole",{prefix:"xlink",name:"arcrole",namespace:NS.XLINK}],["xlink:href",{prefix:"xlink",name:"href",namespace:NS.XLINK}],["xlink:role",{prefix:"xlink",name:"role",namespace:NS.XLINK}],["xlink:show",{prefix:"xlink",name:"show",namespace:NS.XLINK}],["xlink:title",{prefix:"xlink",name:"title",namespace:NS.XLINK}],["xlink:type",{prefix:"xlink",name:"type",namespace:NS.XLINK}],["xml:lang",{prefix:"xml",name:"lang",namespace:NS.XML}],["xml:space",{prefix:"xml",name:"space",namespace:NS.XML}],["xmlns",{prefix:"",name:"xmlns",namespace:NS.XMLNS}],["xmlns:xlink",{prefix:"xmlns",name:"xlink",namespace:NS.XMLNS}]]),SVG_TAG_NAMES_ADJUSTMENT_MAP=new Map(["altGlyph","altGlyphDef","altGlyphItem","animateColor","animateMotion","animateTransform","clipPath","feBlend","feColorMatrix","feComponentTransfer","feComposite","feConvolveMatrix","feDiffuseLighting","feDisplacementMap","feDistantLight","feFlood","feFuncA","feFuncB","feFuncG","feFuncR","feGaussianBlur","feImage","feMerge","feMergeNode","feMorphology","feOffset","fePointLight","feSpecularLighting","feSpotLight","feTile","feTurbulence","foreignObject","glyphRef","linearGradient","radialGradient","textPath"].map(tn=>[tn.toLowerCase(),tn])),EXITS_FOREIGN_CONTENT=new Set([TAG_ID.B,TAG_ID.BIG,TAG_ID.BLOCKQUOTE,TAG_ID.BODY,TAG_ID.BR,TAG_ID.CENTER,TAG_ID.CODE,TAG_ID.DD,TAG_ID.DIV,TAG_ID.DL,TAG_ID.DT,TAG_ID.EM,TAG_ID.EMBED,TAG_ID.H1,TAG_ID.H2,TAG_ID.H3,TAG_ID.H4,TAG_ID.H5,TAG_ID.H6,TAG_ID.HEAD,TAG_ID.HR,TAG_ID.I,TAG_ID.IMG,TAG_ID.LI,TAG_ID.LISTING,TAG_ID.MENU,TAG_ID.META,TAG_ID.NOBR,TAG_ID.OL,TAG_ID.P,TAG_ID.PRE,TAG_ID.RUBY,TAG_ID.S,TAG_ID.SMALL,TAG_ID.SPAN,TAG_ID.STRONG,TAG_ID.STRIKE,TAG_ID.SUB,TAG_ID.SUP,TAG_ID.TABLE,TAG_ID.TT,TAG_ID.U,TAG_ID.UL,TAG_ID.VAR]);function causesExit(startTagToken){const tn=startTagToken.tagID;return tn===TAG_ID.FONT&&startTagToken.attrs.some(({name:name2})=>name2===ATTRS.COLOR||name2===ATTRS.SIZE||name2===ATTRS.FACE)||EXITS_FOREIGN_CONTENT.has(tn)}__name(causesExit,"causesExit");function adjustTokenMathMLAttrs(token){for(let i2=0;i20&&this._setContextModes(node2,tid)}onItemPop(node2,isTop){var _a18,_b;if(this.options.sourceCodeLocationInfo&&this._setEndLocation(node2,this.currentToken),(_b=(_a18=this.treeAdapter).onItemPop)===null||_b===void 0||_b.call(_a18,node2,this.openElements.current),isTop){let current,currentTagId;this.openElements.stackTop===0&&this.fragmentContext?(current=this.fragmentContext,currentTagId=this.fragmentContextID):{current,currentTagId}=this.openElements,this._setContextModes(current,currentTagId)}}_setContextModes(current,tid){const isHTML=current===this.document||current&&this.treeAdapter.getNamespaceURI(current)===NS.HTML;this.currentNotInHTML=!isHTML,this.tokenizer.inForeignNode=!isHTML&¤t!==void 0&&tid!==void 0&&!this._isIntegrationPoint(tid,current)}_switchToTextParsing(currentToken,nextTokenizerState){this._insertElement(currentToken,NS.HTML),this.tokenizer.state=nextTokenizerState,this.originalInsertionMode=this.insertionMode,this.insertionMode=InsertionMode.TEXT}switchToPlaintextParsing(){this.insertionMode=InsertionMode.TEXT,this.originalInsertionMode=InsertionMode.IN_BODY,this.tokenizer.state=TokenizerMode.PLAINTEXT}_getAdjustedCurrentElement(){return this.openElements.stackTop===0&&this.fragmentContext?this.fragmentContext:this.openElements.current}_findFormInFragmentContext(){let node2=this.fragmentContext;for(;node2;){if(this.treeAdapter.getTagName(node2)===TAG_NAMES.FORM){this.formElement=node2;break}node2=this.treeAdapter.getParentNode(node2)}}_initTokenizerForFragmentParsing(){if(!(!this.fragmentContext||this.treeAdapter.getNamespaceURI(this.fragmentContext)!==NS.HTML))switch(this.fragmentContextID){case TAG_ID.TITLE:case TAG_ID.TEXTAREA:{this.tokenizer.state=TokenizerMode.RCDATA;break}case TAG_ID.STYLE:case TAG_ID.XMP:case TAG_ID.IFRAME:case TAG_ID.NOEMBED:case TAG_ID.NOFRAMES:case TAG_ID.NOSCRIPT:{this.tokenizer.state=TokenizerMode.RAWTEXT;break}case TAG_ID.SCRIPT:{this.tokenizer.state=TokenizerMode.SCRIPT_DATA;break}case TAG_ID.PLAINTEXT:{this.tokenizer.state=TokenizerMode.PLAINTEXT;break}}}_setDocumentType(token){const name2=token.name||"",publicId=token.publicId||"",systemId=token.systemId||"";if(this.treeAdapter.setDocumentType(this.document,name2,publicId,systemId),token.location){const docTypeNode=this.treeAdapter.getChildNodes(this.document).find(node2=>this.treeAdapter.isDocumentTypeNode(node2));docTypeNode&&this.treeAdapter.setNodeSourceCodeLocation(docTypeNode,token.location)}}_attachElementToTree(element2,location2){if(this.options.sourceCodeLocationInfo){const loc=location2&&{...location2,startTag:location2};this.treeAdapter.setNodeSourceCodeLocation(element2,loc)}if(this._shouldFosterParentOnInsertion())this._fosterParentElement(element2);else{const parent=this.openElements.currentTmplContentOrNode;this.treeAdapter.appendChild(parent??this.document,element2)}}_appendElement(token,namespaceURI){const element2=this.treeAdapter.createElement(token.tagName,namespaceURI,token.attrs);this._attachElementToTree(element2,token.location)}_insertElement(token,namespaceURI){const element2=this.treeAdapter.createElement(token.tagName,namespaceURI,token.attrs);this._attachElementToTree(element2,token.location),this.openElements.push(element2,token.tagID)}_insertFakeElement(tagName,tagID){const element2=this.treeAdapter.createElement(tagName,NS.HTML,[]);this._attachElementToTree(element2,null),this.openElements.push(element2,tagID)}_insertTemplate(token){const tmpl=this.treeAdapter.createElement(token.tagName,NS.HTML,token.attrs),content2=this.treeAdapter.createDocumentFragment();this.treeAdapter.setTemplateContent(tmpl,content2),this._attachElementToTree(tmpl,token.location),this.openElements.push(tmpl,token.tagID),this.options.sourceCodeLocationInfo&&this.treeAdapter.setNodeSourceCodeLocation(content2,null)}_insertFakeRootElement(){const element2=this.treeAdapter.createElement(TAG_NAMES.HTML,NS.HTML,[]);this.options.sourceCodeLocationInfo&&this.treeAdapter.setNodeSourceCodeLocation(element2,null),this.treeAdapter.appendChild(this.openElements.current,element2),this.openElements.push(element2,TAG_ID.HTML)}_appendCommentNode(token,parent){const commentNode=this.treeAdapter.createCommentNode(token.data);this.treeAdapter.appendChild(parent,commentNode),this.options.sourceCodeLocationInfo&&this.treeAdapter.setNodeSourceCodeLocation(commentNode,token.location)}_insertCharacters(token){let parent,beforeElement;if(this._shouldFosterParentOnInsertion()?({parent,beforeElement}=this._findFosterParentingLocation(),beforeElement?this.treeAdapter.insertTextBefore(parent,token.chars,beforeElement):this.treeAdapter.insertText(parent,token.chars)):(parent=this.openElements.currentTmplContentOrNode,this.treeAdapter.insertText(parent,token.chars)),!token.location)return;const siblings=this.treeAdapter.getChildNodes(parent),textNodeIdx=beforeElement?siblings.lastIndexOf(beforeElement):siblings.length,textNode=siblings[textNodeIdx-1];if(this.treeAdapter.getNodeSourceCodeLocation(textNode)){const{endLine,endCol,endOffset}=token.location;this.treeAdapter.updateNodeSourceCodeLocation(textNode,{endLine,endCol,endOffset})}else this.options.sourceCodeLocationInfo&&this.treeAdapter.setNodeSourceCodeLocation(textNode,token.location)}_adoptNodes(donor,recipient){for(let child=this.treeAdapter.getFirstChild(donor);child;child=this.treeAdapter.getFirstChild(donor))this.treeAdapter.detachNode(child),this.treeAdapter.appendChild(recipient,child)}_setEndLocation(element2,closingToken){if(this.treeAdapter.getNodeSourceCodeLocation(element2)&&closingToken.location){const ctLoc=closingToken.location,tn=this.treeAdapter.getTagName(element2),endLoc=closingToken.type===TokenType.END_TAG&&tn===closingToken.tagName?{endTag:{...ctLoc},endLine:ctLoc.endLine,endCol:ctLoc.endCol,endOffset:ctLoc.endOffset}:{endLine:ctLoc.startLine,endCol:ctLoc.startCol,endOffset:ctLoc.startOffset};this.treeAdapter.updateNodeSourceCodeLocation(element2,endLoc)}}shouldProcessStartTagTokenInForeignContent(token){if(!this.currentNotInHTML)return!1;let current,currentTagId;return this.openElements.stackTop===0&&this.fragmentContext?(current=this.fragmentContext,currentTagId=this.fragmentContextID):{current,currentTagId}=this.openElements,token.tagID===TAG_ID.SVG&&this.treeAdapter.getTagName(current)===TAG_NAMES.ANNOTATION_XML&&this.treeAdapter.getNamespaceURI(current)===NS.MATHML?!1:this.tokenizer.inForeignNode||(token.tagID===TAG_ID.MGLYPH||token.tagID===TAG_ID.MALIGNMARK)&¤tTagId!==void 0&&!this._isIntegrationPoint(currentTagId,current,NS.HTML)}_processToken(token){switch(token.type){case TokenType.CHARACTER:{this.onCharacter(token);break}case TokenType.NULL_CHARACTER:{this.onNullCharacter(token);break}case TokenType.COMMENT:{this.onComment(token);break}case TokenType.DOCTYPE:{this.onDoctype(token);break}case TokenType.START_TAG:{this._processStartTag(token);break}case TokenType.END_TAG:{this.onEndTag(token);break}case TokenType.EOF:{this.onEof(token);break}case TokenType.WHITESPACE_CHARACTER:{this.onWhitespaceCharacter(token);break}}}_isIntegrationPoint(tid,element2,foreignNS){const ns=this.treeAdapter.getNamespaceURI(element2),attrs=this.treeAdapter.getAttrList(element2);return isIntegrationPoint(tid,ns,attrs,foreignNS)}_reconstructActiveFormattingElements(){const listLength=this.activeFormattingElements.entries.length;if(listLength){const endIndex=this.activeFormattingElements.entries.findIndex(entry=>entry.type===EntryType.Marker||this.openElements.contains(entry.element)),unopenIdx=endIndex===-1?listLength-1:endIndex-1;for(let i2=unopenIdx;i2>=0;i2--){const entry=this.activeFormattingElements.entries[i2];this._insertElement(entry.token,this.treeAdapter.getNamespaceURI(entry.element)),entry.element=this.openElements.current}}}_closeTableCell(){this.openElements.generateImpliedEndTags(),this.openElements.popUntilTableCellPopped(),this.activeFormattingElements.clearToLastMarker(),this.insertionMode=InsertionMode.IN_ROW}_closePElement(){this.openElements.generateImpliedEndTagsWithExclusion(TAG_ID.P),this.openElements.popUntilTagNamePopped(TAG_ID.P)}_resetInsertionMode(){for(let i2=this.openElements.stackTop;i2>=0;i2--)switch(i2===0&&this.fragmentContext?this.fragmentContextID:this.openElements.tagIDs[i2]){case TAG_ID.TR:{this.insertionMode=InsertionMode.IN_ROW;return}case TAG_ID.TBODY:case TAG_ID.THEAD:case TAG_ID.TFOOT:{this.insertionMode=InsertionMode.IN_TABLE_BODY;return}case TAG_ID.CAPTION:{this.insertionMode=InsertionMode.IN_CAPTION;return}case TAG_ID.COLGROUP:{this.insertionMode=InsertionMode.IN_COLUMN_GROUP;return}case TAG_ID.TABLE:{this.insertionMode=InsertionMode.IN_TABLE;return}case TAG_ID.BODY:{this.insertionMode=InsertionMode.IN_BODY;return}case TAG_ID.FRAMESET:{this.insertionMode=InsertionMode.IN_FRAMESET;return}case TAG_ID.SELECT:{this._resetInsertionModeForSelect(i2);return}case TAG_ID.TEMPLATE:{this.insertionMode=this.tmplInsertionModeStack[0];return}case TAG_ID.HTML:{this.insertionMode=this.headElement?InsertionMode.AFTER_HEAD:InsertionMode.BEFORE_HEAD;return}case TAG_ID.TD:case TAG_ID.TH:{if(i2>0){this.insertionMode=InsertionMode.IN_CELL;return}break}case TAG_ID.HEAD:{if(i2>0){this.insertionMode=InsertionMode.IN_HEAD;return}break}}this.insertionMode=InsertionMode.IN_BODY}_resetInsertionModeForSelect(selectIdx){if(selectIdx>0)for(let i2=selectIdx-1;i2>0;i2--){const tn=this.openElements.tagIDs[i2];if(tn===TAG_ID.TEMPLATE)break;if(tn===TAG_ID.TABLE){this.insertionMode=InsertionMode.IN_SELECT_IN_TABLE;return}}this.insertionMode=InsertionMode.IN_SELECT}_isElementCausesFosterParenting(tn){return TABLE_STRUCTURE_TAGS.has(tn)}_shouldFosterParentOnInsertion(){return this.fosterParentingEnabled&&this.openElements.currentTagId!==void 0&&this._isElementCausesFosterParenting(this.openElements.currentTagId)}_findFosterParentingLocation(){for(let i2=this.openElements.stackTop;i2>=0;i2--){const openElement=this.openElements.items[i2];switch(this.openElements.tagIDs[i2]){case TAG_ID.TEMPLATE:{if(this.treeAdapter.getNamespaceURI(openElement)===NS.HTML)return{parent:this.treeAdapter.getTemplateContent(openElement),beforeElement:null};break}case TAG_ID.TABLE:{const parent=this.treeAdapter.getParentNode(openElement);return parent?{parent,beforeElement:openElement}:{parent:this.openElements.items[i2-1],beforeElement:null}}}}return{parent:this.openElements.items[0],beforeElement:null}}_fosterParentElement(element2){const location2=this._findFosterParentingLocation();location2.beforeElement?this.treeAdapter.insertBefore(location2.parent,element2,location2.beforeElement):this.treeAdapter.appendChild(location2.parent,element2)}_isSpecialElement(element2,id){const ns=this.treeAdapter.getNamespaceURI(element2);return SPECIAL_ELEMENTS[ns].has(id)}onCharacter(token){if(this.skipNextNewLine=!1,this.tokenizer.inForeignNode){characterInForeignContent(this,token);return}switch(this.insertionMode){case InsertionMode.INITIAL:{tokenInInitialMode(this,token);break}case InsertionMode.BEFORE_HTML:{tokenBeforeHtml(this,token);break}case InsertionMode.BEFORE_HEAD:{tokenBeforeHead(this,token);break}case InsertionMode.IN_HEAD:{tokenInHead(this,token);break}case InsertionMode.IN_HEAD_NO_SCRIPT:{tokenInHeadNoScript(this,token);break}case InsertionMode.AFTER_HEAD:{tokenAfterHead(this,token);break}case InsertionMode.IN_BODY:case InsertionMode.IN_CAPTION:case InsertionMode.IN_CELL:case InsertionMode.IN_TEMPLATE:{characterInBody(this,token);break}case InsertionMode.TEXT:case InsertionMode.IN_SELECT:case InsertionMode.IN_SELECT_IN_TABLE:{this._insertCharacters(token);break}case InsertionMode.IN_TABLE:case InsertionMode.IN_TABLE_BODY:case InsertionMode.IN_ROW:{characterInTable(this,token);break}case InsertionMode.IN_TABLE_TEXT:{characterInTableText(this,token);break}case InsertionMode.IN_COLUMN_GROUP:{tokenInColumnGroup(this,token);break}case InsertionMode.AFTER_BODY:{tokenAfterBody(this,token);break}case InsertionMode.AFTER_AFTER_BODY:{tokenAfterAfterBody(this,token);break}}}onNullCharacter(token){if(this.skipNextNewLine=!1,this.tokenizer.inForeignNode){nullCharacterInForeignContent(this,token);return}switch(this.insertionMode){case InsertionMode.INITIAL:{tokenInInitialMode(this,token);break}case InsertionMode.BEFORE_HTML:{tokenBeforeHtml(this,token);break}case InsertionMode.BEFORE_HEAD:{tokenBeforeHead(this,token);break}case InsertionMode.IN_HEAD:{tokenInHead(this,token);break}case InsertionMode.IN_HEAD_NO_SCRIPT:{tokenInHeadNoScript(this,token);break}case InsertionMode.AFTER_HEAD:{tokenAfterHead(this,token);break}case InsertionMode.TEXT:{this._insertCharacters(token);break}case InsertionMode.IN_TABLE:case InsertionMode.IN_TABLE_BODY:case InsertionMode.IN_ROW:{characterInTable(this,token);break}case InsertionMode.IN_COLUMN_GROUP:{tokenInColumnGroup(this,token);break}case InsertionMode.AFTER_BODY:{tokenAfterBody(this,token);break}case InsertionMode.AFTER_AFTER_BODY:{tokenAfterAfterBody(this,token);break}}}onComment(token){if(this.skipNextNewLine=!1,this.currentNotInHTML){appendComment(this,token);return}switch(this.insertionMode){case InsertionMode.INITIAL:case InsertionMode.BEFORE_HTML:case InsertionMode.BEFORE_HEAD:case InsertionMode.IN_HEAD:case InsertionMode.IN_HEAD_NO_SCRIPT:case InsertionMode.AFTER_HEAD:case InsertionMode.IN_BODY:case InsertionMode.IN_TABLE:case InsertionMode.IN_CAPTION:case InsertionMode.IN_COLUMN_GROUP:case InsertionMode.IN_TABLE_BODY:case InsertionMode.IN_ROW:case InsertionMode.IN_CELL:case InsertionMode.IN_SELECT:case InsertionMode.IN_SELECT_IN_TABLE:case InsertionMode.IN_TEMPLATE:case InsertionMode.IN_FRAMESET:case InsertionMode.AFTER_FRAMESET:{appendComment(this,token);break}case InsertionMode.IN_TABLE_TEXT:{tokenInTableText(this,token);break}case InsertionMode.AFTER_BODY:{appendCommentToRootHtmlElement(this,token);break}case InsertionMode.AFTER_AFTER_BODY:case InsertionMode.AFTER_AFTER_FRAMESET:{appendCommentToDocument(this,token);break}}}onDoctype(token){switch(this.skipNextNewLine=!1,this.insertionMode){case InsertionMode.INITIAL:{doctypeInInitialMode(this,token);break}case InsertionMode.BEFORE_HEAD:case InsertionMode.IN_HEAD:case InsertionMode.IN_HEAD_NO_SCRIPT:case InsertionMode.AFTER_HEAD:{this._err(token,ERR.misplacedDoctype);break}case InsertionMode.IN_TABLE_TEXT:{tokenInTableText(this,token);break}}}onStartTag(token){this.skipNextNewLine=!1,this.currentToken=token,this._processStartTag(token),token.selfClosing&&!token.ackSelfClosing&&this._err(token,ERR.nonVoidHtmlElementStartTagWithTrailingSolidus)}_processStartTag(token){this.shouldProcessStartTagTokenInForeignContent(token)?startTagInForeignContent(this,token):this._startTagOutsideForeignContent(token)}_startTagOutsideForeignContent(token){switch(this.insertionMode){case InsertionMode.INITIAL:{tokenInInitialMode(this,token);break}case InsertionMode.BEFORE_HTML:{startTagBeforeHtml(this,token);break}case InsertionMode.BEFORE_HEAD:{startTagBeforeHead(this,token);break}case InsertionMode.IN_HEAD:{startTagInHead(this,token);break}case InsertionMode.IN_HEAD_NO_SCRIPT:{startTagInHeadNoScript(this,token);break}case InsertionMode.AFTER_HEAD:{startTagAfterHead(this,token);break}case InsertionMode.IN_BODY:{startTagInBody(this,token);break}case InsertionMode.IN_TABLE:{startTagInTable(this,token);break}case InsertionMode.IN_TABLE_TEXT:{tokenInTableText(this,token);break}case InsertionMode.IN_CAPTION:{startTagInCaption(this,token);break}case InsertionMode.IN_COLUMN_GROUP:{startTagInColumnGroup(this,token);break}case InsertionMode.IN_TABLE_BODY:{startTagInTableBody(this,token);break}case InsertionMode.IN_ROW:{startTagInRow(this,token);break}case InsertionMode.IN_CELL:{startTagInCell(this,token);break}case InsertionMode.IN_SELECT:{startTagInSelect(this,token);break}case InsertionMode.IN_SELECT_IN_TABLE:{startTagInSelectInTable(this,token);break}case InsertionMode.IN_TEMPLATE:{startTagInTemplate(this,token);break}case InsertionMode.AFTER_BODY:{startTagAfterBody(this,token);break}case InsertionMode.IN_FRAMESET:{startTagInFrameset(this,token);break}case InsertionMode.AFTER_FRAMESET:{startTagAfterFrameset(this,token);break}case InsertionMode.AFTER_AFTER_BODY:{startTagAfterAfterBody(this,token);break}case InsertionMode.AFTER_AFTER_FRAMESET:{startTagAfterAfterFrameset(this,token);break}}}onEndTag(token){this.skipNextNewLine=!1,this.currentToken=token,this.currentNotInHTML?endTagInForeignContent(this,token):this._endTagOutsideForeignContent(token)}_endTagOutsideForeignContent(token){switch(this.insertionMode){case InsertionMode.INITIAL:{tokenInInitialMode(this,token);break}case InsertionMode.BEFORE_HTML:{endTagBeforeHtml(this,token);break}case InsertionMode.BEFORE_HEAD:{endTagBeforeHead(this,token);break}case InsertionMode.IN_HEAD:{endTagInHead(this,token);break}case InsertionMode.IN_HEAD_NO_SCRIPT:{endTagInHeadNoScript(this,token);break}case InsertionMode.AFTER_HEAD:{endTagAfterHead(this,token);break}case InsertionMode.IN_BODY:{endTagInBody(this,token);break}case InsertionMode.TEXT:{endTagInText(this,token);break}case InsertionMode.IN_TABLE:{endTagInTable(this,token);break}case InsertionMode.IN_TABLE_TEXT:{tokenInTableText(this,token);break}case InsertionMode.IN_CAPTION:{endTagInCaption(this,token);break}case InsertionMode.IN_COLUMN_GROUP:{endTagInColumnGroup(this,token);break}case InsertionMode.IN_TABLE_BODY:{endTagInTableBody(this,token);break}case InsertionMode.IN_ROW:{endTagInRow(this,token);break}case InsertionMode.IN_CELL:{endTagInCell(this,token);break}case InsertionMode.IN_SELECT:{endTagInSelect(this,token);break}case InsertionMode.IN_SELECT_IN_TABLE:{endTagInSelectInTable(this,token);break}case InsertionMode.IN_TEMPLATE:{endTagInTemplate(this,token);break}case InsertionMode.AFTER_BODY:{endTagAfterBody(this,token);break}case InsertionMode.IN_FRAMESET:{endTagInFrameset(this,token);break}case InsertionMode.AFTER_FRAMESET:{endTagAfterFrameset(this,token);break}case InsertionMode.AFTER_AFTER_BODY:{tokenAfterAfterBody(this,token);break}}}onEof(token){switch(this.insertionMode){case InsertionMode.INITIAL:{tokenInInitialMode(this,token);break}case InsertionMode.BEFORE_HTML:{tokenBeforeHtml(this,token);break}case InsertionMode.BEFORE_HEAD:{tokenBeforeHead(this,token);break}case InsertionMode.IN_HEAD:{tokenInHead(this,token);break}case InsertionMode.IN_HEAD_NO_SCRIPT:{tokenInHeadNoScript(this,token);break}case InsertionMode.AFTER_HEAD:{tokenAfterHead(this,token);break}case InsertionMode.IN_BODY:case InsertionMode.IN_TABLE:case InsertionMode.IN_CAPTION:case InsertionMode.IN_COLUMN_GROUP:case InsertionMode.IN_TABLE_BODY:case InsertionMode.IN_ROW:case InsertionMode.IN_CELL:case InsertionMode.IN_SELECT:case InsertionMode.IN_SELECT_IN_TABLE:{eofInBody(this,token);break}case InsertionMode.TEXT:{eofInText(this,token);break}case InsertionMode.IN_TABLE_TEXT:{tokenInTableText(this,token);break}case InsertionMode.IN_TEMPLATE:{eofInTemplate(this,token);break}case InsertionMode.AFTER_BODY:case InsertionMode.IN_FRAMESET:case InsertionMode.AFTER_FRAMESET:case InsertionMode.AFTER_AFTER_BODY:case InsertionMode.AFTER_AFTER_FRAMESET:{stopParsing(this,token);break}}}onWhitespaceCharacter(token){if(this.skipNextNewLine&&(this.skipNextNewLine=!1,token.chars.charCodeAt(0)===CODE_POINTS.LINE_FEED)){if(token.chars.length===1)return;token.chars=token.chars.substr(1)}if(this.tokenizer.inForeignNode){this._insertCharacters(token);return}switch(this.insertionMode){case InsertionMode.IN_HEAD:case InsertionMode.IN_HEAD_NO_SCRIPT:case InsertionMode.AFTER_HEAD:case InsertionMode.TEXT:case InsertionMode.IN_COLUMN_GROUP:case InsertionMode.IN_SELECT:case InsertionMode.IN_SELECT_IN_TABLE:case InsertionMode.IN_FRAMESET:case InsertionMode.AFTER_FRAMESET:{this._insertCharacters(token);break}case InsertionMode.IN_BODY:case InsertionMode.IN_CAPTION:case InsertionMode.IN_CELL:case InsertionMode.IN_TEMPLATE:case InsertionMode.AFTER_BODY:case InsertionMode.AFTER_AFTER_BODY:case InsertionMode.AFTER_AFTER_FRAMESET:{whitespaceCharacterInBody(this,token);break}case InsertionMode.IN_TABLE:case InsertionMode.IN_TABLE_BODY:case InsertionMode.IN_ROW:{characterInTable(this,token);break}case InsertionMode.IN_TABLE_TEXT:{whitespaceCharacterInTableText(this,token);break}}}};__name(_Parser,"Parser");let Parser=_Parser;function aaObtainFormattingElementEntry(p2,token){let formattingElementEntry=p2.activeFormattingElements.getElementEntryInScopeWithTagName(token.tagName);return formattingElementEntry?p2.openElements.contains(formattingElementEntry.element)?p2.openElements.hasInScope(token.tagID)||(formattingElementEntry=null):(p2.activeFormattingElements.removeEntry(formattingElementEntry),formattingElementEntry=null):genericEndTagInBody(p2,token),formattingElementEntry}__name(aaObtainFormattingElementEntry,"aaObtainFormattingElementEntry");function aaObtainFurthestBlock(p2,formattingElementEntry){let furthestBlock=null,idx=p2.openElements.stackTop;for(;idx>=0;idx--){const element2=p2.openElements.items[idx];if(element2===formattingElementEntry.element)break;p2._isSpecialElement(element2,p2.openElements.tagIDs[idx])&&(furthestBlock=element2)}return furthestBlock||(p2.openElements.shortenToLength(Math.max(idx,0)),p2.activeFormattingElements.removeEntry(formattingElementEntry)),furthestBlock}__name(aaObtainFurthestBlock,"aaObtainFurthestBlock");function aaInnerLoop(p2,furthestBlock,formattingElement){let lastElement=furthestBlock,nextElement=p2.openElements.getCommonAncestor(furthestBlock);for(let i2=0,element2=nextElement;element2!==formattingElement;i2++,element2=nextElement){nextElement=p2.openElements.getCommonAncestor(element2);const elementEntry=p2.activeFormattingElements.getElementEntry(element2),counterOverflow=elementEntry&&i2>=AA_INNER_LOOP_ITER;!elementEntry||counterOverflow?(counterOverflow&&p2.activeFormattingElements.removeEntry(elementEntry),p2.openElements.remove(element2)):(element2=aaRecreateElementFromEntry(p2,elementEntry),lastElement===furthestBlock&&(p2.activeFormattingElements.bookmark=elementEntry),p2.treeAdapter.detachNode(lastElement),p2.treeAdapter.appendChild(element2,lastElement),lastElement=element2)}return lastElement}__name(aaInnerLoop,"aaInnerLoop");function aaRecreateElementFromEntry(p2,elementEntry){const ns=p2.treeAdapter.getNamespaceURI(elementEntry.element),newElement=p2.treeAdapter.createElement(elementEntry.token.tagName,ns,elementEntry.token.attrs);return p2.openElements.replace(elementEntry.element,newElement),elementEntry.element=newElement,newElement}__name(aaRecreateElementFromEntry,"aaRecreateElementFromEntry");function aaInsertLastNodeInCommonAncestor(p2,commonAncestor,lastElement){const tn=p2.treeAdapter.getTagName(commonAncestor),tid=getTagID(tn);if(p2._isElementCausesFosterParenting(tid))p2._fosterParentElement(lastElement);else{const ns=p2.treeAdapter.getNamespaceURI(commonAncestor);tid===TAG_ID.TEMPLATE&&ns===NS.HTML&&(commonAncestor=p2.treeAdapter.getTemplateContent(commonAncestor)),p2.treeAdapter.appendChild(commonAncestor,lastElement)}}__name(aaInsertLastNodeInCommonAncestor,"aaInsertLastNodeInCommonAncestor");function aaReplaceFormattingElement(p2,furthestBlock,formattingElementEntry){const ns=p2.treeAdapter.getNamespaceURI(formattingElementEntry.element),{token}=formattingElementEntry,newElement=p2.treeAdapter.createElement(token.tagName,ns,token.attrs);p2._adoptNodes(furthestBlock,newElement),p2.treeAdapter.appendChild(furthestBlock,newElement),p2.activeFormattingElements.insertElementAfterBookmark(newElement,token),p2.activeFormattingElements.removeEntry(formattingElementEntry),p2.openElements.remove(formattingElementEntry.element),p2.openElements.insertAfter(furthestBlock,newElement,token.tagID)}__name(aaReplaceFormattingElement,"aaReplaceFormattingElement");function callAdoptionAgency(p2,token){for(let i2=0;i2=target;i2--)p2._setEndLocation(p2.openElements.items[i2],token);if(!p2.fragmentContext&&p2.openElements.stackTop>=0){const htmlElement=p2.openElements.items[0],htmlLocation=p2.treeAdapter.getNodeSourceCodeLocation(htmlElement);if(htmlLocation&&!htmlLocation.endTag&&(p2._setEndLocation(htmlElement,token),p2.openElements.stackTop>=1)){const bodyElement=p2.openElements.items[1],bodyLocation=p2.treeAdapter.getNodeSourceCodeLocation(bodyElement);bodyLocation&&!bodyLocation.endTag&&p2._setEndLocation(bodyElement,token)}}}}__name(stopParsing,"stopParsing");function doctypeInInitialMode(p2,token){p2._setDocumentType(token);const mode=token.forceQuirks?DOCUMENT_MODE.QUIRKS:getDocumentMode(token);isConforming(token)||p2._err(token,ERR.nonConformingDoctype),p2.treeAdapter.setDocumentMode(p2.document,mode),p2.insertionMode=InsertionMode.BEFORE_HTML}__name(doctypeInInitialMode,"doctypeInInitialMode");function tokenInInitialMode(p2,token){p2._err(token,ERR.missingDoctype,!0),p2.treeAdapter.setDocumentMode(p2.document,DOCUMENT_MODE.QUIRKS),p2.insertionMode=InsertionMode.BEFORE_HTML,p2._processToken(token)}__name(tokenInInitialMode,"tokenInInitialMode");function startTagBeforeHtml(p2,token){token.tagID===TAG_ID.HTML?(p2._insertElement(token,NS.HTML),p2.insertionMode=InsertionMode.BEFORE_HEAD):tokenBeforeHtml(p2,token)}__name(startTagBeforeHtml,"startTagBeforeHtml");function endTagBeforeHtml(p2,token){const tn=token.tagID;(tn===TAG_ID.HTML||tn===TAG_ID.HEAD||tn===TAG_ID.BODY||tn===TAG_ID.BR)&&tokenBeforeHtml(p2,token)}__name(endTagBeforeHtml,"endTagBeforeHtml");function tokenBeforeHtml(p2,token){p2._insertFakeRootElement(),p2.insertionMode=InsertionMode.BEFORE_HEAD,p2._processToken(token)}__name(tokenBeforeHtml,"tokenBeforeHtml");function startTagBeforeHead(p2,token){switch(token.tagID){case TAG_ID.HTML:{startTagInBody(p2,token);break}case TAG_ID.HEAD:{p2._insertElement(token,NS.HTML),p2.headElement=p2.openElements.current,p2.insertionMode=InsertionMode.IN_HEAD;break}default:tokenBeforeHead(p2,token)}}__name(startTagBeforeHead,"startTagBeforeHead");function endTagBeforeHead(p2,token){const tn=token.tagID;tn===TAG_ID.HEAD||tn===TAG_ID.BODY||tn===TAG_ID.HTML||tn===TAG_ID.BR?tokenBeforeHead(p2,token):p2._err(token,ERR.endTagWithoutMatchingOpenElement)}__name(endTagBeforeHead,"endTagBeforeHead");function tokenBeforeHead(p2,token){p2._insertFakeElement(TAG_NAMES.HEAD,TAG_ID.HEAD),p2.headElement=p2.openElements.current,p2.insertionMode=InsertionMode.IN_HEAD,p2._processToken(token)}__name(tokenBeforeHead,"tokenBeforeHead");function startTagInHead(p2,token){switch(token.tagID){case TAG_ID.HTML:{startTagInBody(p2,token);break}case TAG_ID.BASE:case TAG_ID.BASEFONT:case TAG_ID.BGSOUND:case TAG_ID.LINK:case TAG_ID.META:{p2._appendElement(token,NS.HTML),token.ackSelfClosing=!0;break}case TAG_ID.TITLE:{p2._switchToTextParsing(token,TokenizerMode.RCDATA);break}case TAG_ID.NOSCRIPT:{p2.options.scriptingEnabled?p2._switchToTextParsing(token,TokenizerMode.RAWTEXT):(p2._insertElement(token,NS.HTML),p2.insertionMode=InsertionMode.IN_HEAD_NO_SCRIPT);break}case TAG_ID.NOFRAMES:case TAG_ID.STYLE:{p2._switchToTextParsing(token,TokenizerMode.RAWTEXT);break}case TAG_ID.SCRIPT:{p2._switchToTextParsing(token,TokenizerMode.SCRIPT_DATA);break}case TAG_ID.TEMPLATE:{p2._insertTemplate(token),p2.activeFormattingElements.insertMarker(),p2.framesetOk=!1,p2.insertionMode=InsertionMode.IN_TEMPLATE,p2.tmplInsertionModeStack.unshift(InsertionMode.IN_TEMPLATE);break}case TAG_ID.HEAD:{p2._err(token,ERR.misplacedStartTagForHeadElement);break}default:tokenInHead(p2,token)}}__name(startTagInHead,"startTagInHead");function endTagInHead(p2,token){switch(token.tagID){case TAG_ID.HEAD:{p2.openElements.pop(),p2.insertionMode=InsertionMode.AFTER_HEAD;break}case TAG_ID.BODY:case TAG_ID.BR:case TAG_ID.HTML:{tokenInHead(p2,token);break}case TAG_ID.TEMPLATE:{templateEndTagInHead(p2,token);break}default:p2._err(token,ERR.endTagWithoutMatchingOpenElement)}}__name(endTagInHead,"endTagInHead");function templateEndTagInHead(p2,token){p2.openElements.tmplCount>0?(p2.openElements.generateImpliedEndTagsThoroughly(),p2.openElements.currentTagId!==TAG_ID.TEMPLATE&&p2._err(token,ERR.closingOfElementWithOpenChildElements),p2.openElements.popUntilTagNamePopped(TAG_ID.TEMPLATE),p2.activeFormattingElements.clearToLastMarker(),p2.tmplInsertionModeStack.shift(),p2._resetInsertionMode()):p2._err(token,ERR.endTagWithoutMatchingOpenElement)}__name(templateEndTagInHead,"templateEndTagInHead");function tokenInHead(p2,token){p2.openElements.pop(),p2.insertionMode=InsertionMode.AFTER_HEAD,p2._processToken(token)}__name(tokenInHead,"tokenInHead");function startTagInHeadNoScript(p2,token){switch(token.tagID){case TAG_ID.HTML:{startTagInBody(p2,token);break}case TAG_ID.BASEFONT:case TAG_ID.BGSOUND:case TAG_ID.HEAD:case TAG_ID.LINK:case TAG_ID.META:case TAG_ID.NOFRAMES:case TAG_ID.STYLE:{startTagInHead(p2,token);break}case TAG_ID.NOSCRIPT:{p2._err(token,ERR.nestedNoscriptInHead);break}default:tokenInHeadNoScript(p2,token)}}__name(startTagInHeadNoScript,"startTagInHeadNoScript");function endTagInHeadNoScript(p2,token){switch(token.tagID){case TAG_ID.NOSCRIPT:{p2.openElements.pop(),p2.insertionMode=InsertionMode.IN_HEAD;break}case TAG_ID.BR:{tokenInHeadNoScript(p2,token);break}default:p2._err(token,ERR.endTagWithoutMatchingOpenElement)}}__name(endTagInHeadNoScript,"endTagInHeadNoScript");function tokenInHeadNoScript(p2,token){const errCode=token.type===TokenType.EOF?ERR.openElementsLeftAfterEof:ERR.disallowedContentInNoscriptInHead;p2._err(token,errCode),p2.openElements.pop(),p2.insertionMode=InsertionMode.IN_HEAD,p2._processToken(token)}__name(tokenInHeadNoScript,"tokenInHeadNoScript");function startTagAfterHead(p2,token){switch(token.tagID){case TAG_ID.HTML:{startTagInBody(p2,token);break}case TAG_ID.BODY:{p2._insertElement(token,NS.HTML),p2.framesetOk=!1,p2.insertionMode=InsertionMode.IN_BODY;break}case TAG_ID.FRAMESET:{p2._insertElement(token,NS.HTML),p2.insertionMode=InsertionMode.IN_FRAMESET;break}case TAG_ID.BASE:case TAG_ID.BASEFONT:case TAG_ID.BGSOUND:case TAG_ID.LINK:case TAG_ID.META:case TAG_ID.NOFRAMES:case TAG_ID.SCRIPT:case TAG_ID.STYLE:case TAG_ID.TEMPLATE:case TAG_ID.TITLE:{p2._err(token,ERR.abandonedHeadElementChild),p2.openElements.push(p2.headElement,TAG_ID.HEAD),startTagInHead(p2,token),p2.openElements.remove(p2.headElement);break}case TAG_ID.HEAD:{p2._err(token,ERR.misplacedStartTagForHeadElement);break}default:tokenAfterHead(p2,token)}}__name(startTagAfterHead,"startTagAfterHead");function endTagAfterHead(p2,token){switch(token.tagID){case TAG_ID.BODY:case TAG_ID.HTML:case TAG_ID.BR:{tokenAfterHead(p2,token);break}case TAG_ID.TEMPLATE:{templateEndTagInHead(p2,token);break}default:p2._err(token,ERR.endTagWithoutMatchingOpenElement)}}__name(endTagAfterHead,"endTagAfterHead");function tokenAfterHead(p2,token){p2._insertFakeElement(TAG_NAMES.BODY,TAG_ID.BODY),p2.insertionMode=InsertionMode.IN_BODY,modeInBody(p2,token)}__name(tokenAfterHead,"tokenAfterHead");function modeInBody(p2,token){switch(token.type){case TokenType.CHARACTER:{characterInBody(p2,token);break}case TokenType.WHITESPACE_CHARACTER:{whitespaceCharacterInBody(p2,token);break}case TokenType.COMMENT:{appendComment(p2,token);break}case TokenType.START_TAG:{startTagInBody(p2,token);break}case TokenType.END_TAG:{endTagInBody(p2,token);break}case TokenType.EOF:{eofInBody(p2,token);break}}}__name(modeInBody,"modeInBody");function whitespaceCharacterInBody(p2,token){p2._reconstructActiveFormattingElements(),p2._insertCharacters(token)}__name(whitespaceCharacterInBody,"whitespaceCharacterInBody");function characterInBody(p2,token){p2._reconstructActiveFormattingElements(),p2._insertCharacters(token),p2.framesetOk=!1}__name(characterInBody,"characterInBody");function htmlStartTagInBody(p2,token){p2.openElements.tmplCount===0&&p2.treeAdapter.adoptAttributes(p2.openElements.items[0],token.attrs)}__name(htmlStartTagInBody,"htmlStartTagInBody");function bodyStartTagInBody(p2,token){const bodyElement=p2.openElements.tryPeekProperlyNestedBodyElement();bodyElement&&p2.openElements.tmplCount===0&&(p2.framesetOk=!1,p2.treeAdapter.adoptAttributes(bodyElement,token.attrs))}__name(bodyStartTagInBody,"bodyStartTagInBody");function framesetStartTagInBody(p2,token){const bodyElement=p2.openElements.tryPeekProperlyNestedBodyElement();p2.framesetOk&&bodyElement&&(p2.treeAdapter.detachNode(bodyElement),p2.openElements.popAllUpToHtmlElement(),p2._insertElement(token,NS.HTML),p2.insertionMode=InsertionMode.IN_FRAMESET)}__name(framesetStartTagInBody,"framesetStartTagInBody");function addressStartTagInBody(p2,token){p2.openElements.hasInButtonScope(TAG_ID.P)&&p2._closePElement(),p2._insertElement(token,NS.HTML)}__name(addressStartTagInBody,"addressStartTagInBody");function numberedHeaderStartTagInBody(p2,token){p2.openElements.hasInButtonScope(TAG_ID.P)&&p2._closePElement(),p2.openElements.currentTagId!==void 0&&NUMBERED_HEADERS.has(p2.openElements.currentTagId)&&p2.openElements.pop(),p2._insertElement(token,NS.HTML)}__name(numberedHeaderStartTagInBody,"numberedHeaderStartTagInBody");function preStartTagInBody(p2,token){p2.openElements.hasInButtonScope(TAG_ID.P)&&p2._closePElement(),p2._insertElement(token,NS.HTML),p2.skipNextNewLine=!0,p2.framesetOk=!1}__name(preStartTagInBody,"preStartTagInBody");function formStartTagInBody(p2,token){const inTemplate=p2.openElements.tmplCount>0;(!p2.formElement||inTemplate)&&(p2.openElements.hasInButtonScope(TAG_ID.P)&&p2._closePElement(),p2._insertElement(token,NS.HTML),inTemplate||(p2.formElement=p2.openElements.current))}__name(formStartTagInBody,"formStartTagInBody");function listItemStartTagInBody(p2,token){p2.framesetOk=!1;const tn=token.tagID;for(let i2=p2.openElements.stackTop;i2>=0;i2--){const elementId=p2.openElements.tagIDs[i2];if(tn===TAG_ID.LI&&elementId===TAG_ID.LI||(tn===TAG_ID.DD||tn===TAG_ID.DT)&&(elementId===TAG_ID.DD||elementId===TAG_ID.DT)){p2.openElements.generateImpliedEndTagsWithExclusion(elementId),p2.openElements.popUntilTagNamePopped(elementId);break}if(elementId!==TAG_ID.ADDRESS&&elementId!==TAG_ID.DIV&&elementId!==TAG_ID.P&&p2._isSpecialElement(p2.openElements.items[i2],elementId))break}p2.openElements.hasInButtonScope(TAG_ID.P)&&p2._closePElement(),p2._insertElement(token,NS.HTML)}__name(listItemStartTagInBody,"listItemStartTagInBody");function plaintextStartTagInBody(p2,token){p2.openElements.hasInButtonScope(TAG_ID.P)&&p2._closePElement(),p2._insertElement(token,NS.HTML),p2.tokenizer.state=TokenizerMode.PLAINTEXT}__name(plaintextStartTagInBody,"plaintextStartTagInBody");function buttonStartTagInBody(p2,token){p2.openElements.hasInScope(TAG_ID.BUTTON)&&(p2.openElements.generateImpliedEndTags(),p2.openElements.popUntilTagNamePopped(TAG_ID.BUTTON)),p2._reconstructActiveFormattingElements(),p2._insertElement(token,NS.HTML),p2.framesetOk=!1}__name(buttonStartTagInBody,"buttonStartTagInBody");function aStartTagInBody(p2,token){const activeElementEntry=p2.activeFormattingElements.getElementEntryInScopeWithTagName(TAG_NAMES.A);activeElementEntry&&(callAdoptionAgency(p2,token),p2.openElements.remove(activeElementEntry.element),p2.activeFormattingElements.removeEntry(activeElementEntry)),p2._reconstructActiveFormattingElements(),p2._insertElement(token,NS.HTML),p2.activeFormattingElements.pushElement(p2.openElements.current,token)}__name(aStartTagInBody,"aStartTagInBody");function bStartTagInBody(p2,token){p2._reconstructActiveFormattingElements(),p2._insertElement(token,NS.HTML),p2.activeFormattingElements.pushElement(p2.openElements.current,token)}__name(bStartTagInBody,"bStartTagInBody");function nobrStartTagInBody(p2,token){p2._reconstructActiveFormattingElements(),p2.openElements.hasInScope(TAG_ID.NOBR)&&(callAdoptionAgency(p2,token),p2._reconstructActiveFormattingElements()),p2._insertElement(token,NS.HTML),p2.activeFormattingElements.pushElement(p2.openElements.current,token)}__name(nobrStartTagInBody,"nobrStartTagInBody");function appletStartTagInBody(p2,token){p2._reconstructActiveFormattingElements(),p2._insertElement(token,NS.HTML),p2.activeFormattingElements.insertMarker(),p2.framesetOk=!1}__name(appletStartTagInBody,"appletStartTagInBody");function tableStartTagInBody(p2,token){p2.treeAdapter.getDocumentMode(p2.document)!==DOCUMENT_MODE.QUIRKS&&p2.openElements.hasInButtonScope(TAG_ID.P)&&p2._closePElement(),p2._insertElement(token,NS.HTML),p2.framesetOk=!1,p2.insertionMode=InsertionMode.IN_TABLE}__name(tableStartTagInBody,"tableStartTagInBody");function areaStartTagInBody(p2,token){p2._reconstructActiveFormattingElements(),p2._appendElement(token,NS.HTML),p2.framesetOk=!1,token.ackSelfClosing=!0}__name(areaStartTagInBody,"areaStartTagInBody");function isHiddenInput(token){const inputType=getTokenAttr(token,ATTRS.TYPE);return inputType!=null&&inputType.toLowerCase()===HIDDEN_INPUT_TYPE}__name(isHiddenInput,"isHiddenInput");function inputStartTagInBody(p2,token){p2._reconstructActiveFormattingElements(),p2._appendElement(token,NS.HTML),isHiddenInput(token)||(p2.framesetOk=!1),token.ackSelfClosing=!0}__name(inputStartTagInBody,"inputStartTagInBody");function paramStartTagInBody(p2,token){p2._appendElement(token,NS.HTML),token.ackSelfClosing=!0}__name(paramStartTagInBody,"paramStartTagInBody");function hrStartTagInBody(p2,token){p2.openElements.hasInButtonScope(TAG_ID.P)&&p2._closePElement(),p2._appendElement(token,NS.HTML),p2.framesetOk=!1,token.ackSelfClosing=!0}__name(hrStartTagInBody,"hrStartTagInBody");function imageStartTagInBody(p2,token){token.tagName=TAG_NAMES.IMG,token.tagID=TAG_ID.IMG,areaStartTagInBody(p2,token)}__name(imageStartTagInBody,"imageStartTagInBody");function textareaStartTagInBody(p2,token){p2._insertElement(token,NS.HTML),p2.skipNextNewLine=!0,p2.tokenizer.state=TokenizerMode.RCDATA,p2.originalInsertionMode=p2.insertionMode,p2.framesetOk=!1,p2.insertionMode=InsertionMode.TEXT}__name(textareaStartTagInBody,"textareaStartTagInBody");function xmpStartTagInBody(p2,token){p2.openElements.hasInButtonScope(TAG_ID.P)&&p2._closePElement(),p2._reconstructActiveFormattingElements(),p2.framesetOk=!1,p2._switchToTextParsing(token,TokenizerMode.RAWTEXT)}__name(xmpStartTagInBody,"xmpStartTagInBody");function iframeStartTagInBody(p2,token){p2.framesetOk=!1,p2._switchToTextParsing(token,TokenizerMode.RAWTEXT)}__name(iframeStartTagInBody,"iframeStartTagInBody");function rawTextStartTagInBody(p2,token){p2._switchToTextParsing(token,TokenizerMode.RAWTEXT)}__name(rawTextStartTagInBody,"rawTextStartTagInBody");function selectStartTagInBody(p2,token){p2._reconstructActiveFormattingElements(),p2._insertElement(token,NS.HTML),p2.framesetOk=!1,p2.insertionMode=p2.insertionMode===InsertionMode.IN_TABLE||p2.insertionMode===InsertionMode.IN_CAPTION||p2.insertionMode===InsertionMode.IN_TABLE_BODY||p2.insertionMode===InsertionMode.IN_ROW||p2.insertionMode===InsertionMode.IN_CELL?InsertionMode.IN_SELECT_IN_TABLE:InsertionMode.IN_SELECT}__name(selectStartTagInBody,"selectStartTagInBody");function optgroupStartTagInBody(p2,token){p2.openElements.currentTagId===TAG_ID.OPTION&&p2.openElements.pop(),p2._reconstructActiveFormattingElements(),p2._insertElement(token,NS.HTML)}__name(optgroupStartTagInBody,"optgroupStartTagInBody");function rbStartTagInBody(p2,token){p2.openElements.hasInScope(TAG_ID.RUBY)&&p2.openElements.generateImpliedEndTags(),p2._insertElement(token,NS.HTML)}__name(rbStartTagInBody,"rbStartTagInBody");function rtStartTagInBody(p2,token){p2.openElements.hasInScope(TAG_ID.RUBY)&&p2.openElements.generateImpliedEndTagsWithExclusion(TAG_ID.RTC),p2._insertElement(token,NS.HTML)}__name(rtStartTagInBody,"rtStartTagInBody");function mathStartTagInBody(p2,token){p2._reconstructActiveFormattingElements(),adjustTokenMathMLAttrs(token),adjustTokenXMLAttrs(token),token.selfClosing?p2._appendElement(token,NS.MATHML):p2._insertElement(token,NS.MATHML),token.ackSelfClosing=!0}__name(mathStartTagInBody,"mathStartTagInBody");function svgStartTagInBody(p2,token){p2._reconstructActiveFormattingElements(),adjustTokenSVGAttrs(token),adjustTokenXMLAttrs(token),token.selfClosing?p2._appendElement(token,NS.SVG):p2._insertElement(token,NS.SVG),token.ackSelfClosing=!0}__name(svgStartTagInBody,"svgStartTagInBody");function genericStartTagInBody(p2,token){p2._reconstructActiveFormattingElements(),p2._insertElement(token,NS.HTML)}__name(genericStartTagInBody,"genericStartTagInBody");function startTagInBody(p2,token){switch(token.tagID){case TAG_ID.I:case TAG_ID.S:case TAG_ID.B:case TAG_ID.U:case TAG_ID.EM:case TAG_ID.TT:case TAG_ID.BIG:case TAG_ID.CODE:case TAG_ID.FONT:case TAG_ID.SMALL:case TAG_ID.STRIKE:case TAG_ID.STRONG:{bStartTagInBody(p2,token);break}case TAG_ID.A:{aStartTagInBody(p2,token);break}case TAG_ID.H1:case TAG_ID.H2:case TAG_ID.H3:case TAG_ID.H4:case TAG_ID.H5:case TAG_ID.H6:{numberedHeaderStartTagInBody(p2,token);break}case TAG_ID.P:case TAG_ID.DL:case TAG_ID.OL:case TAG_ID.UL:case TAG_ID.DIV:case TAG_ID.DIR:case TAG_ID.NAV:case TAG_ID.MAIN:case TAG_ID.MENU:case TAG_ID.ASIDE:case TAG_ID.CENTER:case TAG_ID.FIGURE:case TAG_ID.FOOTER:case TAG_ID.HEADER:case TAG_ID.HGROUP:case TAG_ID.DIALOG:case TAG_ID.DETAILS:case TAG_ID.ADDRESS:case TAG_ID.ARTICLE:case TAG_ID.SEARCH:case TAG_ID.SECTION:case TAG_ID.SUMMARY:case TAG_ID.FIELDSET:case TAG_ID.BLOCKQUOTE:case TAG_ID.FIGCAPTION:{addressStartTagInBody(p2,token);break}case TAG_ID.LI:case TAG_ID.DD:case TAG_ID.DT:{listItemStartTagInBody(p2,token);break}case TAG_ID.BR:case TAG_ID.IMG:case TAG_ID.WBR:case TAG_ID.AREA:case TAG_ID.EMBED:case TAG_ID.KEYGEN:{areaStartTagInBody(p2,token);break}case TAG_ID.HR:{hrStartTagInBody(p2,token);break}case TAG_ID.RB:case TAG_ID.RTC:{rbStartTagInBody(p2,token);break}case TAG_ID.RT:case TAG_ID.RP:{rtStartTagInBody(p2,token);break}case TAG_ID.PRE:case TAG_ID.LISTING:{preStartTagInBody(p2,token);break}case TAG_ID.XMP:{xmpStartTagInBody(p2,token);break}case TAG_ID.SVG:{svgStartTagInBody(p2,token);break}case TAG_ID.HTML:{htmlStartTagInBody(p2,token);break}case TAG_ID.BASE:case TAG_ID.LINK:case TAG_ID.META:case TAG_ID.STYLE:case TAG_ID.TITLE:case TAG_ID.SCRIPT:case TAG_ID.BGSOUND:case TAG_ID.BASEFONT:case TAG_ID.TEMPLATE:{startTagInHead(p2,token);break}case TAG_ID.BODY:{bodyStartTagInBody(p2,token);break}case TAG_ID.FORM:{formStartTagInBody(p2,token);break}case TAG_ID.NOBR:{nobrStartTagInBody(p2,token);break}case TAG_ID.MATH:{mathStartTagInBody(p2,token);break}case TAG_ID.TABLE:{tableStartTagInBody(p2,token);break}case TAG_ID.INPUT:{inputStartTagInBody(p2,token);break}case TAG_ID.PARAM:case TAG_ID.TRACK:case TAG_ID.SOURCE:{paramStartTagInBody(p2,token);break}case TAG_ID.IMAGE:{imageStartTagInBody(p2,token);break}case TAG_ID.BUTTON:{buttonStartTagInBody(p2,token);break}case TAG_ID.APPLET:case TAG_ID.OBJECT:case TAG_ID.MARQUEE:{appletStartTagInBody(p2,token);break}case TAG_ID.IFRAME:{iframeStartTagInBody(p2,token);break}case TAG_ID.SELECT:{selectStartTagInBody(p2,token);break}case TAG_ID.OPTION:case TAG_ID.OPTGROUP:{optgroupStartTagInBody(p2,token);break}case TAG_ID.NOEMBED:case TAG_ID.NOFRAMES:{rawTextStartTagInBody(p2,token);break}case TAG_ID.FRAMESET:{framesetStartTagInBody(p2,token);break}case TAG_ID.TEXTAREA:{textareaStartTagInBody(p2,token);break}case TAG_ID.NOSCRIPT:{p2.options.scriptingEnabled?rawTextStartTagInBody(p2,token):genericStartTagInBody(p2,token);break}case TAG_ID.PLAINTEXT:{plaintextStartTagInBody(p2,token);break}case TAG_ID.COL:case TAG_ID.TH:case TAG_ID.TD:case TAG_ID.TR:case TAG_ID.HEAD:case TAG_ID.FRAME:case TAG_ID.TBODY:case TAG_ID.TFOOT:case TAG_ID.THEAD:case TAG_ID.CAPTION:case TAG_ID.COLGROUP:break;default:genericStartTagInBody(p2,token)}}__name(startTagInBody,"startTagInBody");function bodyEndTagInBody(p2,token){if(p2.openElements.hasInScope(TAG_ID.BODY)&&(p2.insertionMode=InsertionMode.AFTER_BODY,p2.options.sourceCodeLocationInfo)){const bodyElement=p2.openElements.tryPeekProperlyNestedBodyElement();bodyElement&&p2._setEndLocation(bodyElement,token)}}__name(bodyEndTagInBody,"bodyEndTagInBody");function htmlEndTagInBody(p2,token){p2.openElements.hasInScope(TAG_ID.BODY)&&(p2.insertionMode=InsertionMode.AFTER_BODY,endTagAfterBody(p2,token))}__name(htmlEndTagInBody,"htmlEndTagInBody");function addressEndTagInBody(p2,token){const tn=token.tagID;p2.openElements.hasInScope(tn)&&(p2.openElements.generateImpliedEndTags(),p2.openElements.popUntilTagNamePopped(tn))}__name(addressEndTagInBody,"addressEndTagInBody");function formEndTagInBody(p2){const inTemplate=p2.openElements.tmplCount>0,{formElement}=p2;inTemplate||(p2.formElement=null),(formElement||inTemplate)&&p2.openElements.hasInScope(TAG_ID.FORM)&&(p2.openElements.generateImpliedEndTags(),inTemplate?p2.openElements.popUntilTagNamePopped(TAG_ID.FORM):formElement&&p2.openElements.remove(formElement))}__name(formEndTagInBody,"formEndTagInBody");function pEndTagInBody(p2){p2.openElements.hasInButtonScope(TAG_ID.P)||p2._insertFakeElement(TAG_NAMES.P,TAG_ID.P),p2._closePElement()}__name(pEndTagInBody,"pEndTagInBody");function liEndTagInBody(p2){p2.openElements.hasInListItemScope(TAG_ID.LI)&&(p2.openElements.generateImpliedEndTagsWithExclusion(TAG_ID.LI),p2.openElements.popUntilTagNamePopped(TAG_ID.LI))}__name(liEndTagInBody,"liEndTagInBody");function ddEndTagInBody(p2,token){const tn=token.tagID;p2.openElements.hasInScope(tn)&&(p2.openElements.generateImpliedEndTagsWithExclusion(tn),p2.openElements.popUntilTagNamePopped(tn))}__name(ddEndTagInBody,"ddEndTagInBody");function numberedHeaderEndTagInBody(p2){p2.openElements.hasNumberedHeaderInScope()&&(p2.openElements.generateImpliedEndTags(),p2.openElements.popUntilNumberedHeaderPopped())}__name(numberedHeaderEndTagInBody,"numberedHeaderEndTagInBody");function appletEndTagInBody(p2,token){const tn=token.tagID;p2.openElements.hasInScope(tn)&&(p2.openElements.generateImpliedEndTags(),p2.openElements.popUntilTagNamePopped(tn),p2.activeFormattingElements.clearToLastMarker())}__name(appletEndTagInBody,"appletEndTagInBody");function brEndTagInBody(p2){p2._reconstructActiveFormattingElements(),p2._insertFakeElement(TAG_NAMES.BR,TAG_ID.BR),p2.openElements.pop(),p2.framesetOk=!1}__name(brEndTagInBody,"brEndTagInBody");function genericEndTagInBody(p2,token){const tn=token.tagName,tid=token.tagID;for(let i2=p2.openElements.stackTop;i2>0;i2--){const element2=p2.openElements.items[i2],elementId=p2.openElements.tagIDs[i2];if(tid===elementId&&(tid!==TAG_ID.UNKNOWN||p2.treeAdapter.getTagName(element2)===tn)){p2.openElements.generateImpliedEndTagsWithExclusion(tid),p2.openElements.stackTop>=i2&&p2.openElements.shortenToLength(i2);break}if(p2._isSpecialElement(element2,elementId))break}}__name(genericEndTagInBody,"genericEndTagInBody");function endTagInBody(p2,token){switch(token.tagID){case TAG_ID.A:case TAG_ID.B:case TAG_ID.I:case TAG_ID.S:case TAG_ID.U:case TAG_ID.EM:case TAG_ID.TT:case TAG_ID.BIG:case TAG_ID.CODE:case TAG_ID.FONT:case TAG_ID.NOBR:case TAG_ID.SMALL:case TAG_ID.STRIKE:case TAG_ID.STRONG:{callAdoptionAgency(p2,token);break}case TAG_ID.P:{pEndTagInBody(p2);break}case TAG_ID.DL:case TAG_ID.UL:case TAG_ID.OL:case TAG_ID.DIR:case TAG_ID.DIV:case TAG_ID.NAV:case TAG_ID.PRE:case TAG_ID.MAIN:case TAG_ID.MENU:case TAG_ID.ASIDE:case TAG_ID.BUTTON:case TAG_ID.CENTER:case TAG_ID.FIGURE:case TAG_ID.FOOTER:case TAG_ID.HEADER:case TAG_ID.HGROUP:case TAG_ID.DIALOG:case TAG_ID.ADDRESS:case TAG_ID.ARTICLE:case TAG_ID.DETAILS:case TAG_ID.SEARCH:case TAG_ID.SECTION:case TAG_ID.SUMMARY:case TAG_ID.LISTING:case TAG_ID.FIELDSET:case TAG_ID.BLOCKQUOTE:case TAG_ID.FIGCAPTION:{addressEndTagInBody(p2,token);break}case TAG_ID.LI:{liEndTagInBody(p2);break}case TAG_ID.DD:case TAG_ID.DT:{ddEndTagInBody(p2,token);break}case TAG_ID.H1:case TAG_ID.H2:case TAG_ID.H3:case TAG_ID.H4:case TAG_ID.H5:case TAG_ID.H6:{numberedHeaderEndTagInBody(p2);break}case TAG_ID.BR:{brEndTagInBody(p2);break}case TAG_ID.BODY:{bodyEndTagInBody(p2,token);break}case TAG_ID.HTML:{htmlEndTagInBody(p2,token);break}case TAG_ID.FORM:{formEndTagInBody(p2);break}case TAG_ID.APPLET:case TAG_ID.OBJECT:case TAG_ID.MARQUEE:{appletEndTagInBody(p2,token);break}case TAG_ID.TEMPLATE:{templateEndTagInHead(p2,token);break}default:genericEndTagInBody(p2,token)}}__name(endTagInBody,"endTagInBody");function eofInBody(p2,token){p2.tmplInsertionModeStack.length>0?eofInTemplate(p2,token):stopParsing(p2,token)}__name(eofInBody,"eofInBody");function endTagInText(p2,token){var _a18;token.tagID===TAG_ID.SCRIPT&&((_a18=p2.scriptHandler)===null||_a18===void 0||_a18.call(p2,p2.openElements.current)),p2.openElements.pop(),p2.insertionMode=p2.originalInsertionMode}__name(endTagInText,"endTagInText");function eofInText(p2,token){p2._err(token,ERR.eofInElementThatCanContainOnlyText),p2.openElements.pop(),p2.insertionMode=p2.originalInsertionMode,p2.onEof(token)}__name(eofInText,"eofInText");function characterInTable(p2,token){if(p2.openElements.currentTagId!==void 0&&TABLE_STRUCTURE_TAGS.has(p2.openElements.currentTagId))switch(p2.pendingCharacterTokens.length=0,p2.hasNonWhitespacePendingCharacterToken=!1,p2.originalInsertionMode=p2.insertionMode,p2.insertionMode=InsertionMode.IN_TABLE_TEXT,token.type){case TokenType.CHARACTER:{characterInTableText(p2,token);break}case TokenType.WHITESPACE_CHARACTER:{whitespaceCharacterInTableText(p2,token);break}}else tokenInTable(p2,token)}__name(characterInTable,"characterInTable");function captionStartTagInTable(p2,token){p2.openElements.clearBackToTableContext(),p2.activeFormattingElements.insertMarker(),p2._insertElement(token,NS.HTML),p2.insertionMode=InsertionMode.IN_CAPTION}__name(captionStartTagInTable,"captionStartTagInTable");function colgroupStartTagInTable(p2,token){p2.openElements.clearBackToTableContext(),p2._insertElement(token,NS.HTML),p2.insertionMode=InsertionMode.IN_COLUMN_GROUP}__name(colgroupStartTagInTable,"colgroupStartTagInTable");function colStartTagInTable(p2,token){p2.openElements.clearBackToTableContext(),p2._insertFakeElement(TAG_NAMES.COLGROUP,TAG_ID.COLGROUP),p2.insertionMode=InsertionMode.IN_COLUMN_GROUP,startTagInColumnGroup(p2,token)}__name(colStartTagInTable,"colStartTagInTable");function tbodyStartTagInTable(p2,token){p2.openElements.clearBackToTableContext(),p2._insertElement(token,NS.HTML),p2.insertionMode=InsertionMode.IN_TABLE_BODY}__name(tbodyStartTagInTable,"tbodyStartTagInTable");function tdStartTagInTable(p2,token){p2.openElements.clearBackToTableContext(),p2._insertFakeElement(TAG_NAMES.TBODY,TAG_ID.TBODY),p2.insertionMode=InsertionMode.IN_TABLE_BODY,startTagInTableBody(p2,token)}__name(tdStartTagInTable,"tdStartTagInTable");function tableStartTagInTable(p2,token){p2.openElements.hasInTableScope(TAG_ID.TABLE)&&(p2.openElements.popUntilTagNamePopped(TAG_ID.TABLE),p2._resetInsertionMode(),p2._processStartTag(token))}__name(tableStartTagInTable,"tableStartTagInTable");function inputStartTagInTable(p2,token){isHiddenInput(token)?p2._appendElement(token,NS.HTML):tokenInTable(p2,token),token.ackSelfClosing=!0}__name(inputStartTagInTable,"inputStartTagInTable");function formStartTagInTable(p2,token){!p2.formElement&&p2.openElements.tmplCount===0&&(p2._insertElement(token,NS.HTML),p2.formElement=p2.openElements.current,p2.openElements.pop())}__name(formStartTagInTable,"formStartTagInTable");function startTagInTable(p2,token){switch(token.tagID){case TAG_ID.TD:case TAG_ID.TH:case TAG_ID.TR:{tdStartTagInTable(p2,token);break}case TAG_ID.STYLE:case TAG_ID.SCRIPT:case TAG_ID.TEMPLATE:{startTagInHead(p2,token);break}case TAG_ID.COL:{colStartTagInTable(p2,token);break}case TAG_ID.FORM:{formStartTagInTable(p2,token);break}case TAG_ID.TABLE:{tableStartTagInTable(p2,token);break}case TAG_ID.TBODY:case TAG_ID.TFOOT:case TAG_ID.THEAD:{tbodyStartTagInTable(p2,token);break}case TAG_ID.INPUT:{inputStartTagInTable(p2,token);break}case TAG_ID.CAPTION:{captionStartTagInTable(p2,token);break}case TAG_ID.COLGROUP:{colgroupStartTagInTable(p2,token);break}default:tokenInTable(p2,token)}}__name(startTagInTable,"startTagInTable");function endTagInTable(p2,token){switch(token.tagID){case TAG_ID.TABLE:{p2.openElements.hasInTableScope(TAG_ID.TABLE)&&(p2.openElements.popUntilTagNamePopped(TAG_ID.TABLE),p2._resetInsertionMode());break}case TAG_ID.TEMPLATE:{templateEndTagInHead(p2,token);break}case TAG_ID.BODY:case TAG_ID.CAPTION:case TAG_ID.COL:case TAG_ID.COLGROUP:case TAG_ID.HTML:case TAG_ID.TBODY:case TAG_ID.TD:case TAG_ID.TFOOT:case TAG_ID.TH:case TAG_ID.THEAD:case TAG_ID.TR:break;default:tokenInTable(p2,token)}}__name(endTagInTable,"endTagInTable");function tokenInTable(p2,token){const savedFosterParentingState=p2.fosterParentingEnabled;p2.fosterParentingEnabled=!0,modeInBody(p2,token),p2.fosterParentingEnabled=savedFosterParentingState}__name(tokenInTable,"tokenInTable");function whitespaceCharacterInTableText(p2,token){p2.pendingCharacterTokens.push(token)}__name(whitespaceCharacterInTableText,"whitespaceCharacterInTableText");function characterInTableText(p2,token){p2.pendingCharacterTokens.push(token),p2.hasNonWhitespacePendingCharacterToken=!0}__name(characterInTableText,"characterInTableText");function tokenInTableText(p2,token){let i2=0;if(p2.hasNonWhitespacePendingCharacterToken)for(;i20&&p2.openElements.currentTagId===TAG_ID.OPTION&&p2.openElements.tagIDs[p2.openElements.stackTop-1]===TAG_ID.OPTGROUP&&p2.openElements.pop(),p2.openElements.currentTagId===TAG_ID.OPTGROUP&&p2.openElements.pop();break}case TAG_ID.OPTION:{p2.openElements.currentTagId===TAG_ID.OPTION&&p2.openElements.pop();break}case TAG_ID.SELECT:{p2.openElements.hasInSelectScope(TAG_ID.SELECT)&&(p2.openElements.popUntilTagNamePopped(TAG_ID.SELECT),p2._resetInsertionMode());break}case TAG_ID.TEMPLATE:{templateEndTagInHead(p2,token);break}}}__name(endTagInSelect,"endTagInSelect");function startTagInSelectInTable(p2,token){const tn=token.tagID;tn===TAG_ID.CAPTION||tn===TAG_ID.TABLE||tn===TAG_ID.TBODY||tn===TAG_ID.TFOOT||tn===TAG_ID.THEAD||tn===TAG_ID.TR||tn===TAG_ID.TD||tn===TAG_ID.TH?(p2.openElements.popUntilTagNamePopped(TAG_ID.SELECT),p2._resetInsertionMode(),p2._processStartTag(token)):startTagInSelect(p2,token)}__name(startTagInSelectInTable,"startTagInSelectInTable");function endTagInSelectInTable(p2,token){const tn=token.tagID;tn===TAG_ID.CAPTION||tn===TAG_ID.TABLE||tn===TAG_ID.TBODY||tn===TAG_ID.TFOOT||tn===TAG_ID.THEAD||tn===TAG_ID.TR||tn===TAG_ID.TD||tn===TAG_ID.TH?p2.openElements.hasInTableScope(tn)&&(p2.openElements.popUntilTagNamePopped(TAG_ID.SELECT),p2._resetInsertionMode(),p2.onEndTag(token)):endTagInSelect(p2,token)}__name(endTagInSelectInTable,"endTagInSelectInTable");function startTagInTemplate(p2,token){switch(token.tagID){case TAG_ID.BASE:case TAG_ID.BASEFONT:case TAG_ID.BGSOUND:case TAG_ID.LINK:case TAG_ID.META:case TAG_ID.NOFRAMES:case TAG_ID.SCRIPT:case TAG_ID.STYLE:case TAG_ID.TEMPLATE:case TAG_ID.TITLE:{startTagInHead(p2,token);break}case TAG_ID.CAPTION:case TAG_ID.COLGROUP:case TAG_ID.TBODY:case TAG_ID.TFOOT:case TAG_ID.THEAD:{p2.tmplInsertionModeStack[0]=InsertionMode.IN_TABLE,p2.insertionMode=InsertionMode.IN_TABLE,startTagInTable(p2,token);break}case TAG_ID.COL:{p2.tmplInsertionModeStack[0]=InsertionMode.IN_COLUMN_GROUP,p2.insertionMode=InsertionMode.IN_COLUMN_GROUP,startTagInColumnGroup(p2,token);break}case TAG_ID.TR:{p2.tmplInsertionModeStack[0]=InsertionMode.IN_TABLE_BODY,p2.insertionMode=InsertionMode.IN_TABLE_BODY,startTagInTableBody(p2,token);break}case TAG_ID.TD:case TAG_ID.TH:{p2.tmplInsertionModeStack[0]=InsertionMode.IN_ROW,p2.insertionMode=InsertionMode.IN_ROW,startTagInRow(p2,token);break}default:p2.tmplInsertionModeStack[0]=InsertionMode.IN_BODY,p2.insertionMode=InsertionMode.IN_BODY,startTagInBody(p2,token)}}__name(startTagInTemplate,"startTagInTemplate");function endTagInTemplate(p2,token){token.tagID===TAG_ID.TEMPLATE&&templateEndTagInHead(p2,token)}__name(endTagInTemplate,"endTagInTemplate");function eofInTemplate(p2,token){p2.openElements.tmplCount>0?(p2.openElements.popUntilTagNamePopped(TAG_ID.TEMPLATE),p2.activeFormattingElements.clearToLastMarker(),p2.tmplInsertionModeStack.shift(),p2._resetInsertionMode(),p2.onEof(token)):stopParsing(p2,token)}__name(eofInTemplate,"eofInTemplate");function startTagAfterBody(p2,token){token.tagID===TAG_ID.HTML?startTagInBody(p2,token):tokenAfterBody(p2,token)}__name(startTagAfterBody,"startTagAfterBody");function endTagAfterBody(p2,token){var _a18;if(token.tagID===TAG_ID.HTML){if(p2.fragmentContext||(p2.insertionMode=InsertionMode.AFTER_AFTER_BODY),p2.options.sourceCodeLocationInfo&&p2.openElements.tagIDs[0]===TAG_ID.HTML){p2._setEndLocation(p2.openElements.items[0],token);const bodyElement=p2.openElements.items[1];bodyElement&&!(!((_a18=p2.treeAdapter.getNodeSourceCodeLocation(bodyElement))===null||_a18===void 0)&&_a18.endTag)&&p2._setEndLocation(bodyElement,token)}}else tokenAfterBody(p2,token)}__name(endTagAfterBody,"endTagAfterBody");function tokenAfterBody(p2,token){p2.insertionMode=InsertionMode.IN_BODY,modeInBody(p2,token)}__name(tokenAfterBody,"tokenAfterBody");function startTagInFrameset(p2,token){switch(token.tagID){case TAG_ID.HTML:{startTagInBody(p2,token);break}case TAG_ID.FRAMESET:{p2._insertElement(token,NS.HTML);break}case TAG_ID.FRAME:{p2._appendElement(token,NS.HTML),token.ackSelfClosing=!0;break}case TAG_ID.NOFRAMES:{startTagInHead(p2,token);break}}}__name(startTagInFrameset,"startTagInFrameset");function endTagInFrameset(p2,token){token.tagID===TAG_ID.FRAMESET&&!p2.openElements.isRootHtmlElementCurrent()&&(p2.openElements.pop(),!p2.fragmentContext&&p2.openElements.currentTagId!==TAG_ID.FRAMESET&&(p2.insertionMode=InsertionMode.AFTER_FRAMESET))}__name(endTagInFrameset,"endTagInFrameset");function startTagAfterFrameset(p2,token){switch(token.tagID){case TAG_ID.HTML:{startTagInBody(p2,token);break}case TAG_ID.NOFRAMES:{startTagInHead(p2,token);break}}}__name(startTagAfterFrameset,"startTagAfterFrameset");function endTagAfterFrameset(p2,token){token.tagID===TAG_ID.HTML&&(p2.insertionMode=InsertionMode.AFTER_AFTER_FRAMESET)}__name(endTagAfterFrameset,"endTagAfterFrameset");function startTagAfterAfterBody(p2,token){token.tagID===TAG_ID.HTML?startTagInBody(p2,token):tokenAfterAfterBody(p2,token)}__name(startTagAfterAfterBody,"startTagAfterAfterBody");function tokenAfterAfterBody(p2,token){p2.insertionMode=InsertionMode.IN_BODY,modeInBody(p2,token)}__name(tokenAfterAfterBody,"tokenAfterAfterBody");function startTagAfterAfterFrameset(p2,token){switch(token.tagID){case TAG_ID.HTML:{startTagInBody(p2,token);break}case TAG_ID.NOFRAMES:{startTagInHead(p2,token);break}}}__name(startTagAfterAfterFrameset,"startTagAfterAfterFrameset");function nullCharacterInForeignContent(p2,token){token.chars=REPLACEMENT_CHARACTER,p2._insertCharacters(token)}__name(nullCharacterInForeignContent,"nullCharacterInForeignContent");function characterInForeignContent(p2,token){p2._insertCharacters(token),p2.framesetOk=!1}__name(characterInForeignContent,"characterInForeignContent");function popUntilHtmlOrIntegrationPoint(p2){for(;p2.treeAdapter.getNamespaceURI(p2.openElements.current)!==NS.HTML&&p2.openElements.currentTagId!==void 0&&!p2._isIntegrationPoint(p2.openElements.currentTagId,p2.openElements.current);)p2.openElements.pop()}__name(popUntilHtmlOrIntegrationPoint,"popUntilHtmlOrIntegrationPoint");function startTagInForeignContent(p2,token){if(causesExit(token))popUntilHtmlOrIntegrationPoint(p2),p2._startTagOutsideForeignContent(token);else{const current=p2._getAdjustedCurrentElement(),currentNs=p2.treeAdapter.getNamespaceURI(current);currentNs===NS.MATHML?adjustTokenMathMLAttrs(token):currentNs===NS.SVG&&(adjustTokenSVGTagName(token),adjustTokenSVGAttrs(token)),adjustTokenXMLAttrs(token),token.selfClosing?p2._appendElement(token,currentNs):p2._insertElement(token,currentNs),token.ackSelfClosing=!0}}__name(startTagInForeignContent,"startTagInForeignContent");function endTagInForeignContent(p2,token){if(token.tagID===TAG_ID.P||token.tagID===TAG_ID.BR){popUntilHtmlOrIntegrationPoint(p2),p2._endTagOutsideForeignContent(token);return}for(let i2=p2.openElements.stackTop;i2>0;i2--){const element2=p2.openElements.items[i2];if(p2.treeAdapter.getNamespaceURI(element2)===NS.HTML){p2._endTagOutsideForeignContent(token);break}const tagName=p2.treeAdapter.getTagName(element2);if(tagName.toLowerCase()===token.tagName){token.tagName=tagName,p2.openElements.shortenToLength(i2);break}}}__name(endTagInForeignContent,"endTagInForeignContent");TAG_NAMES.AREA,TAG_NAMES.BASE,TAG_NAMES.BASEFONT,TAG_NAMES.BGSOUND,TAG_NAMES.BR,TAG_NAMES.COL,TAG_NAMES.EMBED,TAG_NAMES.FRAME,TAG_NAMES.HR,TAG_NAMES.IMG,TAG_NAMES.INPUT,TAG_NAMES.KEYGEN,TAG_NAMES.LINK,TAG_NAMES.META,TAG_NAMES.PARAM,TAG_NAMES.SOURCE,TAG_NAMES.TRACK,TAG_NAMES.WBR;const gfmTagfilterExpression=/<(\/?)(iframe|noembed|noframes|plaintext|script|style|textarea|title|xmp)(?=[\t\n\f\r />])/gi,knownMdxNames=new Set(["mdxFlowExpression","mdxJsxFlowElement","mdxJsxTextElement","mdxTextExpression","mdxjsEsm"]),parseOptions={sourceCodeLocationInfo:!0,scriptingEnabled:!1};function raw(tree,options){const document2=documentMode(tree),one2=zwitch("type",{handlers:{root:root$1,element:element$1,text:text$1,comment:comment$1,doctype:doctype$1,raw:handleRaw},unknown}),state={parser:document2?new Parser(parseOptions):Parser.getFragmentParser(void 0,parseOptions),handle(node2){one2(node2,state)},stitches:!1,options:options||{}};one2(tree,state),resetTokenizer(state,pointStart());const p5=document2?state.parser.document:state.parser.getFragment(),result=fromParse5(p5,{file:state.options.file});return state.stitches&&visit(result,"comment",function(node2,index2,parent){const stitch2=node2;if(stitch2.value.stitch&&parent&&index2!==void 0){const siblings=parent.children;return siblings[index2]=stitch2.value.stitch,index2}}),result.type==="root"&&result.children.length===1&&result.children[0].type===tree.type?result.children[0]:result}__name(raw,"raw");function all(nodes,state){let index2=-1;if(nodes)for(;++index24&&(state.parser.tokenizer.state=0);const token={type:TokenType.CHARACTER,chars:node2.value,location:createParse5Location(node2)};resetTokenizer(state,pointStart(node2)),state.parser.currentToken=token,state.parser._processToken(state.parser.currentToken)}__name(text$1,"text$1");function doctype$1(node2,state){const token={type:TokenType.DOCTYPE,name:"html",forceQuirks:!1,publicId:"",systemId:"",location:createParse5Location(node2)};resetTokenizer(state,pointStart(node2)),state.parser.currentToken=token,state.parser._processToken(state.parser.currentToken)}__name(doctype$1,"doctype$1");function stitch(node2,state){state.stitches=!0;const clone2=cloneWithoutChildren(node2);if("children"in node2&&"children"in clone2){const fakeRoot=raw({type:"root",children:node2.children},state.options);clone2.children=fakeRoot.children}comment$1({type:"comment",value:{stitch:clone2}},state)}__name(stitch,"stitch");function comment$1(node2,state){const data=node2.value,token={type:TokenType.COMMENT,data,location:createParse5Location(node2)};resetTokenizer(state,pointStart(node2)),state.parser.currentToken=token,state.parser._processToken(state.parser.currentToken)}__name(comment$1,"comment$1");function handleRaw(node2,state){if(state.parser.tokenizer.preprocessor.html="",state.parser.tokenizer.preprocessor.pos=-1,state.parser.tokenizer.preprocessor.lastGapPos=-2,state.parser.tokenizer.preprocessor.gapStack=[],state.parser.tokenizer.preprocessor.skipNextNewLine=!1,state.parser.tokenizer.preprocessor.lastChunkWritten=!1,state.parser.tokenizer.preprocessor.endOfChunkHit=!1,state.parser.tokenizer.preprocessor.isEol=!1,setPoint(state,pointStart(node2)),state.parser.tokenizer.write(state.options.tagfilter?node2.value.replace(gfmTagfilterExpression,"<$1$2"):node2.value,!1),state.parser.tokenizer._runParsingLoop(),state.parser.tokenizer.state===72||state.parser.tokenizer.state===78){state.parser.tokenizer.preprocessor.lastChunkWritten=!0;const cp=state.parser.tokenizer._consume();state.parser.tokenizer._callState(cp)}}__name(handleRaw,"handleRaw");function unknown(node_,state){const node2=node_;if(state.options.passThrough&&state.options.passThrough.includes(node2.type))stitch(node2,state);else{let extra="";throw knownMdxNames.has(node2.type)&&(extra=". It looks like you are using MDX nodes with `hast-util-raw` (or `rehype-raw`). If you use this because you are using remark or rehype plugins that inject `'html'` nodes, then please raise an issue with that plugin, as its a bad and slow idea. If you use this because you are using markdown syntax, then you have to configure this utility (or plugin) to pass through these nodes (see `passThrough` in docs), but you can also migrate to use the MDX syntax"),new Error("Cannot compile `"+node2.type+"` node"+extra)}}__name(unknown,"unknown");function resetTokenizer(state,point2){setPoint(state,point2);const token=state.parser.tokenizer.currentCharacterToken;token&&token.location&&(token.location.endLine=state.parser.tokenizer.preprocessor.line,token.location.endCol=state.parser.tokenizer.preprocessor.col+1,token.location.endOffset=state.parser.tokenizer.preprocessor.offset+1,state.parser.currentToken=token,state.parser._processToken(state.parser.currentToken)),state.parser.tokenizer.paused=!1,state.parser.tokenizer.inLoop=!1,state.parser.tokenizer.active=!1,state.parser.tokenizer.returnState=TokenizerMode.DATA,state.parser.tokenizer.charRefCode=-1,state.parser.tokenizer.consumedAfterSnapshot=-1,state.parser.tokenizer.currentLocation=null,state.parser.tokenizer.currentCharacterToken=null,state.parser.tokenizer.currentToken=null,state.parser.tokenizer.currentAttr={name:"",value:""}}__name(resetTokenizer,"resetTokenizer");function setPoint(state,point2){if(point2&&point2.offset!==void 0){const location2={startLine:point2.line,startCol:point2.column,startOffset:point2.offset,endLine:-1,endCol:-1,endOffset:-1};state.parser.tokenizer.preprocessor.lineStartPos=-point2.column+1,state.parser.tokenizer.preprocessor.droppedBufferSize=point2.offset,state.parser.tokenizer.preprocessor.line=point2.line,state.parser.tokenizer.currentLocation=location2}}__name(setPoint,"setPoint");function startTag(node2,state){const tagName=node2.tagName.toLowerCase();if(state.parser.tokenizer.state===TokenizerMode.PLAINTEXT)return;resetTokenizer(state,pointStart(node2));const current=state.parser.openElements.current;let ns="namespaceURI"in current?current.namespaceURI:webNamespaces.html;ns===webNamespaces.html&&tagName==="svg"&&(ns=webNamespaces.svg);const result=toParse5({...node2,children:[]},{space:ns===webNamespaces.svg?"svg":"html"}),tag={type:TokenType.START_TAG,tagName,tagID:getTagID(tagName),selfClosing:!1,ackSelfClosing:!1,attrs:"attrs"in result?result.attrs:[],location:createParse5Location(node2)};state.parser.currentToken=tag,state.parser._processToken(state.parser.currentToken),state.parser.tokenizer.lastStartTagName=tagName}__name(startTag,"startTag");function endTag(node2,state){const tagName=node2.tagName.toLowerCase();if(!state.parser.tokenizer.inForeignNode&&htmlVoidElements.includes(tagName)||state.parser.tokenizer.state===TokenizerMode.PLAINTEXT)return;resetTokenizer(state,pointEnd(node2));const tag={type:TokenType.END_TAG,tagName,tagID:getTagID(tagName),selfClosing:!1,ackSelfClosing:!1,attrs:[],location:createParse5Location(node2)};state.parser.currentToken=tag,state.parser._processToken(state.parser.currentToken),tagName===state.parser.tokenizer.lastStartTagName&&(state.parser.tokenizer.state===TokenizerMode.RCDATA||state.parser.tokenizer.state===TokenizerMode.RAWTEXT||state.parser.tokenizer.state===TokenizerMode.SCRIPT_DATA)&&(state.parser.tokenizer.state=TokenizerMode.DATA)}__name(endTag,"endTag");function documentMode(node2){const head=node2.type==="root"?node2.children[0]:node2;return!!(head&&(head.type==="doctype"||head.type==="element"&&head.tagName.toLowerCase()==="html"))}__name(documentMode,"documentMode");function createParse5Location(node2){const start2=pointStart(node2)||{line:void 0,column:void 0,offset:void 0},end=pointEnd(node2)||{line:void 0,column:void 0,offset:void 0};return{startLine:start2.line,startCol:start2.column,startOffset:start2.offset,endLine:end.line,endCol:end.column,endOffset:end.offset}}__name(createParse5Location,"createParse5Location");function cloneWithoutChildren(node2){return"children"in node2?structuredClone$1({...node2,children:[]}):structuredClone$1(node2)}__name(cloneWithoutChildren,"cloneWithoutChildren");function rehypeRaw(options){return function(tree,file){return raw(tree,{...options,file})}}__name(rehypeRaw,"rehypeRaw");const aria=["ariaDescribedBy","ariaLabel","ariaLabelledBy"],defaultSchema={ancestors:{tbody:["table"],td:["table"],th:["table"],thead:["table"],tfoot:["table"],tr:["table"]},attributes:{a:[...aria,"dataFootnoteBackref","dataFootnoteRef",["className","data-footnote-backref"],"href"],blockquote:["cite"],code:[["className",/^language-./]],del:["cite"],div:["itemScope","itemType"],dl:[...aria],h2:[["className","sr-only"]],img:[...aria,"longDesc","src"],input:[["disabled",!0],["type","checkbox"]],ins:["cite"],li:[["className","task-list-item"]],ol:[...aria,["className","contains-task-list"]],q:["cite"],section:["dataFootnotes",["className","footnotes"]],source:["srcSet"],summary:[...aria],table:[...aria],ul:[...aria,["className","contains-task-list"]],"*":["abbr","accept","acceptCharset","accessKey","action","align","alt","axis","border","cellPadding","cellSpacing","char","charOff","charSet","checked","clear","colSpan","color","cols","compact","coords","dateTime","dir","encType","frame","hSpace","headers","height","hrefLang","htmlFor","id","isMap","itemProp","label","lang","maxLength","media","method","multiple","name","noHref","noShade","noWrap","open","prompt","readOnly","rev","rowSpan","rows","rules","scope","selected","shape","size","span","start","summary","tabIndex","title","useMap","vAlign","value","width"]},clobber:["ariaDescribedBy","ariaLabelledBy","id","name"],clobberPrefix:"user-content-",protocols:{cite:["http","https"],href:["http","https","irc","ircs","mailto","xmpp"],longDesc:["http","https"],src:["http","https"]},required:{input:{disabled:!0,type:"checkbox"}},strip:["script"],tagNames:["a","b","blockquote","br","code","dd","del","details","div","dl","dt","em","h1","h2","h3","h4","h5","h6","hr","i","img","input","ins","kbd","li","ol","p","picture","pre","q","rp","rt","ruby","s","samp","section","source","span","strike","strong","sub","summary","sup","table","tbody","td","tfoot","th","thead","tr","tt","ul","var"]},own={}.hasOwnProperty;function sanitize(node2,options){let result={type:"root",children:[]};const state={schema:options?{...defaultSchema,...options}:defaultSchema,stack:[]},replace2=transform(state,node2);return replace2&&(Array.isArray(replace2)?replace2.length===1?result=replace2[0]:result.children=replace2:result=replace2),result}__name(sanitize,"sanitize");function transform(state,node2){if(node2&&typeof node2=="object"){const unsafe=node2;switch(typeof unsafe.type=="string"?unsafe.type:""){case"comment":return comment(state,unsafe);case"doctype":return doctype(state,unsafe);case"element":return element(state,unsafe);case"root":return root(state,unsafe);case"text":return text(state,unsafe)}}}__name(transform,"transform");function comment(state,unsafe){if(state.schema.allowComments){const result=typeof unsafe.value=="string"?unsafe.value:"",index2=result.indexOf("-->"),node2={type:"comment",value:index2<0?result:result.slice(0,index2)};return patch(node2,unsafe),node2}}__name(comment,"comment");function doctype(state,unsafe){if(state.schema.allowDoctypes){const node2={type:"doctype"};return patch(node2,unsafe),node2}}__name(doctype,"doctype");function element(state,unsafe){const name2=typeof unsafe.tagName=="string"?unsafe.tagName:"";state.stack.push(name2);const content2=children(state,unsafe.children),properties_=properties(state,unsafe.properties);state.stack.pop();let safeElement=!1;if(name2&&name2!=="*"&&(!state.schema.tagNames||state.schema.tagNames.includes(name2))&&(safeElement=!0,state.schema.ancestors&&own.call(state.schema.ancestors,name2))){const ancestors=state.schema.ancestors[name2];let index2=-1;for(safeElement=!1;++index21){let ok2=!1,index2=0;for(;++index2-1&&colon>slash||questionMark>-1&&colon>questionMark||numberSign>-1&&colon>numberSign)return!0;let index2=-1;for(;++index24&&key.slice(0,4).toLowerCase()==="data")return dataDefault}__name(findDefinition,"findDefinition");function rehypeSanitize(options){return function(tree){return sanitize(tree,options)}}__name(rehypeSanitize,"rehypeSanitize");const Input=reactExports.forwardRef(({className,type,...props},ref)=>jsxRuntimeExports.jsx("input",{type,className:cn$2("flex h-10 w-full rounded-md border border-input bg-background px-3 py-2 text-sm ring-offset-background file:border-0 file:bg-transparent file:text-sm file:font-medium placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50",className),ref,...props}));Input.displayName="Input";const statuses=[{value:"Passed",label:"Passed",icon:CheckCircledIcon,variant:"success"},{value:"Failed",label:"Failed",icon:CrossCircledIcon,variant:"destructive"},{value:"Error",label:"Error",icon:CrossCircledIcon,variant:"destructive"},{value:"Investigate",label:"Investigate",icon:QuestionMarkCircledIcon,variant:"warning"},{value:"Skipped",label:"Skipped",icon:StopwatchIcon,variant:"secondary"},{value:"Planned",label:"Planned",icon:StopwatchIcon,variant:"secondary"}],impacts=[{label:"Critical",value:"Critical",icon:ExclamationTriangleIcon},{label:"High",value:"High",icon:ArrowUpIcon},{label:"Medium",value:"Medium",icon:ArrowRightIcon},{label:"Low",value:"Low",icon:ArrowDownIcon},{label:"Unranked",value:"Unranked",icon:MinusIcon}];function StatusIcon({Item:Item3}){const status=statuses.find(status2=>status2.value===Item3.TestStatus);return status?jsxRuntimeExports.jsx("div",{className:"flex items-center",children:jsxRuntimeExports.jsx(Badge,{variant:status.variant,children:jsxRuntimeExports.jsx("span",{children:status.label})})}):null}__name(StatusIcon,"StatusIcon");function DataTable({columns:columns2,data,pillar}){const riskLabel=pillar==="Infrastructure"?"Severity":"Risk",[sorting,setSorting]=reactExports.useState([{id:"TestRisk",desc:!1},{id:"TestStatus",desc:!1}]),[columnFilters,setColumnFilters]=reactExports.useState([]),[globalFilter,setGlobalFilter]=reactExports.useState(""),[selectedSfiPillars,setSelectedSfiPillars]=reactExports.useState([]),[selectedRisks,setSelectedRisks]=reactExports.useState([]),[selectedStatuses,setSelectedStatuses]=reactExports.useState([]),[showSkipped,setShowSkipped]=reactExports.useState(!1),[columnVisibility,setColumnVisibility]=reactExports.useState({TestImpact:!1,TestImplementationCost:!1,TestId:!1,TestSfiPillar:!1,TestMinimumLicense:!1,TestCategory:pillar==="Devices"}),[rowSelection,setRowSelection]=reactExports.useState({}),pillarFilteredData=reactExports.useMemo(()=>pillar?data.filter(item=>Array.isArray(item.TestPillar)?item.TestPillar.includes(pillar):item.TestPillar===pillar):data,[data,pillar]);reactExports.useEffect(()=>{setSelectedRisks([])},[pillar]);const filteredData=reactExports.useMemo(()=>{let result=pillarFilteredData;return selectedSfiPillars.length>0&&(result=result.filter(item=>item.TestSfiPillar&&selectedSfiPillars.includes(item.TestSfiPillar))),selectedRisks.length>0&&(result=result.filter(item=>item.TestRisk&&selectedRisks.includes(item.TestRisk))),selectedStatuses.length>0?result=result.filter(item=>item.TestStatus&&selectedStatuses.includes(item.TestStatus)):result=result.filter(item=>item.TestStatus!=="Planned"&&(showSkipped||item.TestStatus!=="Skipped")),result},[pillarFilteredData,selectedSfiPillars,selectedRisks,selectedStatuses,showSkipped]),hasSkippedTests=reactExports.useMemo(()=>{let result=pillarFilteredData;return selectedSfiPillars.length>0&&(result=result.filter(item=>item.TestSfiPillar&&selectedSfiPillars.includes(item.TestSfiPillar))),selectedRisks.length>0&&(result=result.filter(item=>item.TestRisk&&selectedRisks.includes(item.TestRisk))),result.some(item=>item.TestStatus==="Skipped")},[pillarFilteredData,selectedSfiPillars,selectedRisks]),uniqueSfiPillars=reactExports.useMemo(()=>{const pillars=pillarFilteredData.map(item=>item.TestSfiPillar).filter(pillar2=>pillar2!=null);return Array.from(new Set(pillars)).sort()},[pillarFilteredData]),uniqueRisks=reactExports.useMemo(()=>{const risks=pillarFilteredData.map(item=>item.TestRisk).filter(risk=>risk!=null),uniqueRiskSet=Array.from(new Set(risks)),riskOrder=["Critical","High","Medium","Low","Unranked"];return uniqueRiskSet.sort((a2,b2)=>{const indexA=riskOrder.indexOf(a2),indexB=riskOrder.indexOf(b2);return indexA!==-1&&indexB!==-1?indexA-indexB:indexA!==-1?-1:indexB!==-1?1:a2.localeCompare(b2)})},[pillarFilteredData]),uniqueStatuses=reactExports.useMemo(()=>{const statuses2=pillarFilteredData.map(item=>item.TestStatus).filter(status=>status!=null),uniqueStatusSet=Array.from(new Set(statuses2)),statusOrder=["Passed","Failed","Planned"];return uniqueStatusSet.sort((a2,b2)=>{const indexA=statusOrder.indexOf(a2),indexB=statusOrder.indexOf(b2);return indexA!==-1&&indexB!==-1?indexA-indexB:indexA!==-1?-1:indexB!==-1?1:a2.localeCompare(b2)})},[pillarFilteredData]),getSfiPillarIcon=__name(pillar2=>pillar2.includes("Monitor and detect")?Eye:pillar2.includes("Protect engineering")?Wrench:pillar2.includes("Protect identities")?Lock:pillar2.includes("Protect tenants")?Building:pillar2.includes("Accelerate response")?Zap:Shield,"getSfiPillarIcon"),table2=useReactTable({data:filteredData,columns:columns2,meta:{riskLabel},enableRowSelection:!0,getCoreRowModel:getCoreRowModel(),onSortingChange:setSorting,getSortedRowModel:getSortedRowModel(),onGlobalFilterChange:setGlobalFilter,onColumnFiltersChange:setColumnFilters,getFilteredRowModel:getFilteredRowModel(),onColumnVisibilityChange:setColumnVisibility,onRowSelectionChange:__name(stateUpdater=>{setRowSelection({}),setRowSelection(stateUpdater)},"onRowSelectionChange"),state:{sorting,columnFilters,globalFilter,columnVisibility,rowSelection}}),[sheetOpen,setSheetOpen]=reactExports.useState(!1),[selectedRow,setSelectedRow]=reactExports.useState(null),mdRehypePlugins=selectedRow?.TestPillar==="Infrastructure"?[rehypeRaw,rehypeSanitize]:[];return jsxRuntimeExports.jsxs("div",{children:[jsxRuntimeExports.jsxs("div",{className:"flex items-center py-4 justify-between",children:[jsxRuntimeExports.jsxs("div",{className:"flex items-center gap-4",children:[jsxRuntimeExports.jsx(Input,{placeholder:"Search by name...",value:globalFilter??"",onChange:__name(e3=>table2.setGlobalFilter(String(e3.target.value)),"onChange"),className:"max-w-sm"}),jsxRuntimeExports.jsxs("div",{className:"flex items-center gap-1",children:[jsxRuntimeExports.jsxs("span",{className:"text-xs font-medium text-muted-foreground mr-1",children:[riskLabel,":"]}),uniqueRisks.map(risk=>{const isSelected=selectedRisks.includes(risk),riskCount=data.filter(item=>item.TestRisk===risk).length;return jsxRuntimeExports.jsx(Button,{variant:isSelected?"default":"outline",size:"sm",onClick:__name(()=>{setSelectedRisks(isSelected?prev=>prev.filter(r2=>r2!==risk):prev=>[...prev,risk])},"onClick"),className:`text-xs h-6 px-3 py-1 rounded-full ${isSelected?"bg-purple-600 hover:bg-purple-700 text-white":"hover:bg-purple-50 hover:text-purple-700 hover:border-purple-300 dark:hover:bg-purple-950 dark:hover:text-purple-300"}`,title:`${risk} (${riskCount} tests)`,children:risk},risk)})]}),jsxRuntimeExports.jsxs("div",{className:"flex items-center gap-1",children:[jsxRuntimeExports.jsx("span",{className:"text-xs font-medium text-muted-foreground mr-1",children:"Status:"}),uniqueStatuses.map(status=>{const isSelected=selectedStatuses.includes(status),statusCount=data.filter(item=>item.TestStatus===status).length,getStatusColors=__name((status2,isSelected2)=>status2==="Passed"?isSelected2?"bg-green-600 hover:bg-green-700 text-white":"hover:bg-green-50 hover:text-green-700 hover:border-green-300 dark:hover:bg-green-950 dark:hover:text-green-300":status2==="Failed"?isSelected2?"bg-red-600 hover:bg-red-700 text-white":"hover:bg-red-50 hover:text-red-700 hover:border-red-300 dark:hover:bg-red-950 dark:hover:text-red-300":isSelected2?"bg-gray-600 hover:bg-gray-700 text-white":"hover:bg-gray-50 hover:text-gray-700 hover:border-gray-300 dark:hover:bg-gray-950 dark:hover:text-gray-300","getStatusColors");return jsxRuntimeExports.jsx(Button,{variant:isSelected?"default":"outline",size:"sm",onClick:__name(()=>{setSelectedStatuses(isSelected?prev=>prev.filter(s2=>s2!==status):prev=>[...prev,status])},"onClick"),className:`text-xs h-6 px-3 py-1 rounded-full ${getStatusColors(status,isSelected)}`,title:`${status} (${statusCount} tests)`,children:status},status)})]})]}),jsxRuntimeExports.jsx("div",{className:"flex items-center gap-4",children:jsxRuntimeExports.jsxs(DropdownMenu,{children:[jsxRuntimeExports.jsx(DropdownMenuTrigger,{asChild:!0,children:jsxRuntimeExports.jsx(Button,{variant:"outline",size:"sm",children:jsxRuntimeExports.jsx(Columns2,{className:"h-4 w-4"})})}),jsxRuntimeExports.jsx(DropdownMenuContent,{align:"end",children:table2.getAllColumns().filter(column=>column.getCanHide()).filter(column=>pillar==="Infrastructure"?!["TestImpact","TestImplementationCost","TestMinimumLicense"].includes(column.id):!0).map(column=>{const columnLabel=column.id==="TestRisk"?riskLabel:column.columnDef.meta?.label??column.id;return jsxRuntimeExports.jsx(DropdownMenuCheckboxItem,{className:"capitalize",checked:column.getIsVisible(),onCheckedChange:__name(value2=>column.toggleVisibility(!!value2),"onCheckedChange"),children:columnLabel},column.id)})})]})})]}),jsxRuntimeExports.jsxs("div",{className:"mb-4",children:[jsxRuntimeExports.jsxs("div",{className:"flex items-center justify-between mb-3",children:[jsxRuntimeExports.jsxs("div",{className:"flex items-center gap-2",children:[jsxRuntimeExports.jsx("span",{className:"text-sm font-medium",children:"Filter by SFI Pillar:"}),selectedSfiPillars.length>0&&jsxRuntimeExports.jsxs(Button,{variant:"ghost",size:"sm",onClick:__name(()=>setSelectedSfiPillars([]),"onClick"),className:"h-6 px-2 text-xs text-muted-foreground hover:text-foreground",children:["Clear All (",selectedSfiPillars.length,")"]})]}),jsxRuntimeExports.jsxs("div",{className:"flex flex-col items-end gap-1",children:[jsxRuntimeExports.jsxs("div",{className:"flex items-center gap-4",children:[(selectedSfiPillars.length>0||selectedRisks.length>0||selectedStatuses.length>0||showSkipped)&&jsxRuntimeExports.jsx(Button,{variant:"ghost",size:"sm",onClick:__name(()=>{setSelectedSfiPillars([]),setSelectedRisks([]),setSelectedStatuses([]),setShowSkipped(!1)},"onClick"),className:"h-6 px-2 text-xs text-muted-foreground hover:text-foreground",children:"Clear All Filters"}),jsxRuntimeExports.jsxs("div",{className:"text-xs text-muted-foreground",children:["Showing ",filteredData.length," of ",pillarFilteredData.length," tests"]})]}),hasSkippedTests&&jsxRuntimeExports.jsxs("label",{className:"flex items-center gap-2 cursor-pointer select-none w-fit",children:[jsxRuntimeExports.jsx("input",{type:"checkbox",checked:showSkipped,onChange:__name(e3=>setShowSkipped(e3.target.checked),"onChange"),className:"h-3.5 w-3.5 rounded border-gray-300 accent-gray-600 cursor-pointer"}),jsxRuntimeExports.jsx("span",{className:"text-xs text-muted-foreground",children:"Show skipped tests"})]})]})]}),jsxRuntimeExports.jsx("div",{className:"flex flex-wrap gap-2",children:uniqueSfiPillars.map(pillar2=>{const isSelected=selectedSfiPillars.includes(pillar2),pillarCount=data.filter(item=>item.TestSfiPillar===pillar2).length,PillarIcon=getSfiPillarIcon(pillar2);return jsxRuntimeExports.jsxs(Button,{variant:isSelected?"default":"outline",size:"sm",onClick:__name(()=>{setSelectedSfiPillars(isSelected?prev=>prev.filter(p2=>p2!==pillar2):prev=>[...prev,pillar2])},"onClick"),className:`text-xs max-w-96 h-auto py-1 px-4 rounded-full ${isSelected?"bg-blue-600 hover:bg-blue-700 text-white":"hover:bg-blue-50 hover:text-blue-700 hover:border-blue-300 dark:hover:bg-blue-950 dark:hover:text-blue-300"}`,title:`${pillar2} (${pillarCount} tests)`,children:[jsxRuntimeExports.jsx(PillarIcon,{className:"mr-2 h-3 w-3 flex-shrink-0"}),jsxRuntimeExports.jsx("span",{className:"whitespace-normal text-left leading-tight",children:pillar2})]},pillar2)})})]}),jsxRuntimeExports.jsx("div",{className:"rounded-md border",children:jsxRuntimeExports.jsxs(Table,{children:[jsxRuntimeExports.jsx(TableHeader,{children:table2.getHeaderGroups().map(headerGroup=>jsxRuntimeExports.jsx(TableRow,{children:headerGroup.headers.map(header=>jsxRuntimeExports.jsx(TableHead,{children:header.isPlaceholder?null:flexRender(header.column.columnDef.header,header.getContext())},header.id))},headerGroup.id))}),jsxRuntimeExports.jsx(TableBody,{children:table2.getRowModel().rows?.length?table2.getRowModel().rows.map(row=>jsxRuntimeExports.jsx(TableRow,{className:"cursor-pointer","data-state":row.getIsSelected()&&"selected",onClick:__name(()=>{setSelectedRow(row.original),setSheetOpen(!0)},"onClick"),children:row.getVisibleCells().map(cell=>jsxRuntimeExports.jsx(TableCell,{children:flexRender(cell.column.columnDef.cell,cell.getContext())},cell.id))},row.id)):jsxRuntimeExports.jsx(TableRow,{children:jsxRuntimeExports.jsx(TableCell,{colSpan:columns2.length,className:"h-24 text-center",children:"No results."})})})]})}),jsxRuntimeExports.jsx(Sheet,{open:sheetOpen,onOpenChange:setSheetOpen,children:jsxRuntimeExports.jsxs(SheetContent,{side:"right",className:"md:min-w-[700px] lg:min-w-[900px] overflow-y-auto",allowMaximize:!0,children:[jsxRuntimeExports.jsx(SheetHeader,{children:jsxRuntimeExports.jsx(SheetTitle,{className:"text-2xl text-left",children:selectedRow?.TestTitle})}),jsxRuntimeExports.jsx("div",{className:"grid pt-10 gap-6",children:jsxRuntimeExports.jsx(Card,{children:jsxRuntimeExports.jsx(CardHeader,{children:jsxRuntimeExports.jsxs("div",{className:`mt-2 text-sm ${selectedRow?.TestPillar==="Infrastructure"?"flex flex-col gap-y-2":"grid grid-cols-3 gap-y-2"}`,children:[jsxRuntimeExports.jsxs("div",{className:"flex items-center gap-2",children:[jsxRuntimeExports.jsx(TriangleAlert,{className:"h-4 w-4 text-foreground"}),jsxRuntimeExports.jsx("span",{className:"font-semibold",children:selectedRow?.TestPillar==="Infrastructure"?"Severity:":"Risk:"}),jsxRuntimeExports.jsx("span",{children:selectedRow?.TestRisk??"N/A"})]}),selectedRow?.TestPillar!=="Infrastructure"&&jsxRuntimeExports.jsxs("div",{className:"flex items-center gap-2",children:[jsxRuntimeExports.jsx(Users,{className:"h-4 w-4 text-foreground"}),jsxRuntimeExports.jsx("span",{className:"font-semibold",children:"User Impact:"}),jsxRuntimeExports.jsx("span",{children:selectedRow?.TestImpact??"N/A"})]}),selectedRow?.TestPillar!=="Infrastructure"&&jsxRuntimeExports.jsxs("div",{className:"flex items-center gap-2",children:[jsxRuntimeExports.jsx(Settings,{className:"h-4 w-4 text-foreground"}),jsxRuntimeExports.jsx("span",{className:"font-semibold",children:"Implementation Effort:"}),jsxRuntimeExports.jsx("span",{children:selectedRow?.TestImplementationCost??"N/A"})]}),jsxRuntimeExports.jsxs("div",{className:"flex items-center gap-2",children:[jsxRuntimeExports.jsx(Hash,{className:"h-4 w-4 text-foreground"}),jsxRuntimeExports.jsx("span",{className:"font-semibold",children:"Test ID:"}),jsxRuntimeExports.jsx("span",{children:selectedRow?.TestId??"N/A"})]}),selectedRow?.TestPillar!=="Infrastructure"&&jsxRuntimeExports.jsxs("div",{className:"flex items-center gap-2",children:[jsxRuntimeExports.jsx(BadgeCheck,{className:"h-4 w-4 text-foreground"}),jsxRuntimeExports.jsx("span",{className:"font-semibold",children:"License:"}),jsxRuntimeExports.jsx("div",{className:"flex items-center gap-1 flex-wrap",children:selectedRow?.TestMinimumLicense&&Array.isArray(selectedRow.TestMinimumLicense)?selectedRow.TestMinimumLicense.map((license,index2)=>jsxRuntimeExports.jsx("span",{className:"px-2 py-0.5 text-xs font-medium bg-purple-100 text-purple-800 dark:bg-purple-900 dark:text-purple-200 rounded-md",children:license},index2)):jsxRuntimeExports.jsx("span",{children:selectedRow?.TestMinimumLicense??"N/A"})})]})]})})})}),jsxRuntimeExports.jsxs("div",{className:"grid pt-10 gap-6",children:[jsxRuntimeExports.jsxs(Card,{children:[jsxRuntimeExports.jsx(CardHeader,{children:jsxRuntimeExports.jsx(CardTitle,{children:jsxRuntimeExports.jsxs("div",{className:"flex",children:[jsxRuntimeExports.jsx("span",{className:"pr-3",children:" Test result → "}),jsxRuntimeExports.jsx(StatusIcon,{Item:selectedRow})]})})}),jsxRuntimeExports.jsx(CardContent,{children:jsxRuntimeExports.jsx(Markdown,{className:"prose max-w-fit dark:prose-invert",remarkPlugins:[remarkGfm],rehypePlugins:mdRehypePlugins,children:selectedRow?.TestResult})})]}),jsxRuntimeExports.jsxs(Card,{children:[jsxRuntimeExports.jsx(CardHeader,{children:jsxRuntimeExports.jsx(CardTitle,{children:"What was checked"})}),jsxRuntimeExports.jsx(CardContent,{children:jsxRuntimeExports.jsx(Markdown,{className:"prose max-w-fit dark:prose-invert",remarkPlugins:[remarkGfm],rehypePlugins:mdRehypePlugins,children:selectedRow?.TestDescription})})]})]})]})})]})}__name(DataTable,"DataTable");const RISK_ORDER={Critical:0,High:1,Medium:2,Low:3,Unranked:4},STATUS_ORDER={Failed:0,Passed:1,Skipped:2,Planned:3},columns=[{accessorKey:"TestId",header:__name(({column})=>jsxRuntimeExports.jsxs(Button,{variant:"ghost",onClick:__name(()=>column.toggleSorting(column.getIsSorted()==="asc"),"onClick"),children:["ID",jsxRuntimeExports.jsx(ArrowUpDown,{className:"ml-2 h-4 w-4"})]}),"header"),cell:__name(({row})=>{const id=row.getValue("TestId"),display=id&&id.length>5?id.slice(-5):id;return jsxRuntimeExports.jsx("span",{title:id,children:display})},"cell"),meta:{label:"ID"}},{accessorKey:"TestTitle",meta:{label:"Name"},header:__name(({column})=>jsxRuntimeExports.jsxs(Button,{variant:"ghost",onClick:__name(()=>column.toggleSorting(column.getIsSorted()==="asc"),"onClick"),children:["Name",jsxRuntimeExports.jsx(ArrowUpDown,{className:"ml-2 h-4 w-4"})]}),"header")},{accessorKey:"TestCategory",meta:{label:"Category"},header:__name(({column})=>jsxRuntimeExports.jsxs(Button,{variant:"ghost",onClick:__name(()=>column.toggleSorting(column.getIsSorted()==="asc"),"onClick"),children:["Category",jsxRuntimeExports.jsx(ArrowUpDown,{className:"ml-2 h-4 w-4"})]}),"header"),cell:__name(({row})=>{const category=row.getValue("TestCategory");return category?jsxRuntimeExports.jsx("div",{className:"flex items-center",children:jsxRuntimeExports.jsx("span",{children:category})}):jsxRuntimeExports.jsx("div",{className:"flex items-center",children:jsxRuntimeExports.jsx("span",{className:"text-muted-foreground",children:"N/A"})})},"cell")},{accessorKey:"TestSfiPillar",meta:{label:"SFI Pillar"},header:__name(({column})=>jsxRuntimeExports.jsxs(Button,{variant:"ghost",onClick:__name(()=>column.toggleSorting(column.getIsSorted()==="asc"),"onClick"),children:["SFI Pillar",jsxRuntimeExports.jsx(ArrowUpDown,{className:"ml-2 h-4 w-4"})]}),"header"),cell:__name(({row})=>{const sfiPillar=row.getValue("TestSfiPillar");return sfiPillar?jsxRuntimeExports.jsx("div",{className:"flex items-center",children:jsxRuntimeExports.jsx("span",{className:"px-2 py-1 text-xs font-medium bg-blue-100 text-blue-800 rounded-md",children:sfiPillar})}):jsxRuntimeExports.jsx("div",{className:"flex items-center",children:jsxRuntimeExports.jsx("span",{className:"text-muted-foreground",children:"N/A"})})},"cell")},{accessorKey:"TestMinimumLicense",meta:{label:"Minimum License"},header:__name(({column})=>jsxRuntimeExports.jsxs(Button,{variant:"ghost",onClick:__name(()=>column.toggleSorting(column.getIsSorted()==="asc"),"onClick"),children:["Min. License",jsxRuntimeExports.jsx(ArrowUpDown,{className:"ml-2 h-4 w-4"})]}),"header"),cell:__name(({row})=>{const licensesValue=row.getValue("TestMinimumLicense");if(!licensesValue)return jsxRuntimeExports.jsx("div",{className:"flex items-center",children:jsxRuntimeExports.jsx("span",{className:"text-muted-foreground",children:"N/A"})});const licenses=Array.isArray(licensesValue)?licensesValue:[licensesValue];return licenses.length===0?jsxRuntimeExports.jsx("div",{className:"flex items-center",children:jsxRuntimeExports.jsx("span",{className:"text-muted-foreground",children:"N/A"})}):jsxRuntimeExports.jsx("div",{className:"flex items-center gap-1 flex-wrap",children:licenses.map((license,index2)=>jsxRuntimeExports.jsx("span",{className:"px-2 py-1 text-xs font-medium bg-purple-100 text-purple-800 rounded-md",children:license},index2))})},"cell")},{accessorKey:"TestImpact",meta:{label:"User Impact"},header:__name(({column})=>jsxRuntimeExports.jsxs(Button,{variant:"ghost",onClick:__name(()=>column.toggleSorting(column.getIsSorted()==="asc"),"onClick"),children:["User Impact",jsxRuntimeExports.jsx(ArrowUpDown,{className:"ml-2 h-4 w-4"})]}),"header"),cell:__name(({row})=>{const impact=impacts.find(impact2=>impact2.value===row.getValue("TestImpact"));return impact?jsxRuntimeExports.jsx("div",{className:"flex items-center",children:jsxRuntimeExports.jsx("span",{children:impact.label})}):null},"cell")},{accessorKey:"TestImplementationCost",meta:{label:"Implementation Effort"},header:__name(({column})=>jsxRuntimeExports.jsxs(Button,{variant:"ghost",onClick:__name(()=>column.toggleSorting(column.getIsSorted()==="asc"),"onClick"),children:["Imp. Effort",jsxRuntimeExports.jsx(ArrowUpDown,{className:"ml-2 h-4 w-4"})]}),"header"),cell:__name(({row})=>{const impact=impacts.find(impact2=>impact2.value===row.getValue("TestImplementationCost"));return impact?jsxRuntimeExports.jsx("div",{className:"flex items-center",children:jsxRuntimeExports.jsx("span",{children:impact.label})}):null},"cell")},{accessorKey:"TestRisk",meta:{label:"Risk"},sortingFn:__name((rowA,rowB,columnId)=>{const a2=RISK_ORDER[rowA.getValue(columnId)]??Number.POSITIVE_INFINITY,b2=RISK_ORDER[rowB.getValue(columnId)]??Number.POSITIVE_INFINITY;return a2-b2},"sortingFn"),header:__name(({column,table:table2})=>{const riskLabel=table2.options.meta?.riskLabel??"Risk";return jsxRuntimeExports.jsxs(Button,{variant:"ghost",onClick:__name(()=>column.toggleSorting(column.getIsSorted()==="asc"),"onClick"),children:[riskLabel,jsxRuntimeExports.jsx(ArrowUpDown,{className:"ml-2 h-4 w-4"})]})},"header"),cell:__name(({row})=>{const impact=impacts.find(impact2=>impact2.value===row.getValue("TestRisk"));return impact?jsxRuntimeExports.jsxs("div",{className:"flex items-center",children:[impact.icon&&jsxRuntimeExports.jsx(impact.icon,{className:"mr-2 h-4 w-4 text-muted-foreground"}),jsxRuntimeExports.jsx("span",{children:impact.label})]}):null},"cell")},{accessorKey:"TestStatus",meta:{label:"Status"},sortingFn:__name((rowA,rowB,columnId)=>{const a2=STATUS_ORDER[rowA.getValue(columnId)]??3,b2=STATUS_ORDER[rowB.getValue(columnId)]??3;return a2-b2},"sortingFn"),header:__name(({column})=>jsxRuntimeExports.jsxs(Button,{variant:"ghost",onClick:__name(()=>column.toggleSorting(column.getIsSorted()==="asc"),"onClick"),children:["Status",jsxRuntimeExports.jsx(ArrowUpDown,{className:"ml-2 h-4 w-4"})]}),"header"),cell:__name(({row})=>jsxRuntimeExports.jsx(StatusIcon,{Item:row.original}),"cell")}];function Identity(){return jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment,{children:[jsxRuntimeExports.jsx(PageHeader,{children:jsxRuntimeExports.jsx(PageHeaderHeading,{children:"Identity"})}),jsxRuntimeExports.jsxs(Card,{children:[jsxRuntimeExports.jsxs(CardHeader,{children:[jsxRuntimeExports.jsx(CardTitle,{className:"mb-3",children:"Assessment results"}),jsxRuntimeExports.jsxs(CardDescription,{children:["The results presented below are based on the security principles detailed in the"," ",jsxRuntimeExports.jsx("a",{href:"https://learn.microsoft.com/en-us/entra/fundamentals/configure-security",target:"_blank",rel:"noopener noreferrer",className:"text-primary font-medium underline underline-offset-4 hover:underline",children:"Configuring Microsoft Entra for increased security"})," ","guide."]})]}),jsxRuntimeExports.jsx(CardContent,{className:"gap-4 px-4 pb-4 pt-1",children:jsxRuntimeExports.jsx(DataTable,{columns,data:reportData.Tests,pillar:"Identity"})})]})]})}__name(Identity,"Identity");var TABS_NAME="Tabs",[createTabsContext]=createContextScope$1(TABS_NAME,[createRovingFocusGroupScope]),useRovingFocusGroupScope=createRovingFocusGroupScope(),[TabsProvider,useTabsContext]=createTabsContext(TABS_NAME),Tabs$1=reactExports.forwardRef((props,forwardedRef)=>{const{__scopeTabs,value:valueProp,onValueChange,defaultValue,orientation="horizontal",dir,activationMode="automatic",...tabsProps}=props,direction=useDirection(dir),[value2,setValue]=useControllableState({prop:valueProp,onChange:onValueChange,defaultProp:defaultValue??"",caller:TABS_NAME});return jsxRuntimeExports.jsx(TabsProvider,{scope:__scopeTabs,baseId:useId(),value:value2,onValueChange:setValue,orientation,dir:direction,activationMode,children:jsxRuntimeExports.jsx(Primitive$2.div,{dir:direction,"data-orientation":orientation,...tabsProps,ref:forwardedRef})})});Tabs$1.displayName=TABS_NAME;var TAB_LIST_NAME="TabsList",TabsList$1=reactExports.forwardRef((props,forwardedRef)=>{const{__scopeTabs,loop:loop2=!0,...listProps}=props,context=useTabsContext(TAB_LIST_NAME,__scopeTabs),rovingFocusGroupScope=useRovingFocusGroupScope(__scopeTabs);return jsxRuntimeExports.jsx(Root$4,{asChild:!0,...rovingFocusGroupScope,orientation:context.orientation,dir:context.dir,loop:loop2,children:jsxRuntimeExports.jsx(Primitive$2.div,{role:"tablist","aria-orientation":context.orientation,...listProps,ref:forwardedRef})})});TabsList$1.displayName=TAB_LIST_NAME;var TRIGGER_NAME="TabsTrigger",TabsTrigger$1=reactExports.forwardRef((props,forwardedRef)=>{const{__scopeTabs,value:value2,disabled=!1,...triggerProps}=props,context=useTabsContext(TRIGGER_NAME,__scopeTabs),rovingFocusGroupScope=useRovingFocusGroupScope(__scopeTabs),triggerId=makeTriggerId(context.baseId,value2),contentId=makeContentId(context.baseId,value2),isSelected=value2===context.value;return jsxRuntimeExports.jsx(Item$1,{asChild:!0,...rovingFocusGroupScope,focusable:!disabled,active:isSelected,children:jsxRuntimeExports.jsx(Primitive$2.button,{type:"button",role:"tab","aria-selected":isSelected,"aria-controls":contentId,"data-state":isSelected?"active":"inactive","data-disabled":disabled?"":void 0,disabled,id:triggerId,...triggerProps,ref:forwardedRef,onMouseDown:composeEventHandlers(props.onMouseDown,event=>{!disabled&&event.button===0&&event.ctrlKey===!1?context.onValueChange(value2):event.preventDefault()}),onKeyDown:composeEventHandlers(props.onKeyDown,event=>{[" ","Enter"].includes(event.key)&&context.onValueChange(value2)}),onFocus:composeEventHandlers(props.onFocus,()=>{const isAutomaticActivation=context.activationMode!=="manual";!isSelected&&!disabled&&isAutomaticActivation&&context.onValueChange(value2)})})})});TabsTrigger$1.displayName=TRIGGER_NAME;var CONTENT_NAME="TabsContent",TabsContent$1=reactExports.forwardRef((props,forwardedRef)=>{const{__scopeTabs,value:value2,forceMount,children:children2,...contentProps}=props,context=useTabsContext(CONTENT_NAME,__scopeTabs),triggerId=makeTriggerId(context.baseId,value2),contentId=makeContentId(context.baseId,value2),isSelected=value2===context.value,isMountAnimationPreventedRef=reactExports.useRef(isSelected);return reactExports.useEffect(()=>{const rAF=requestAnimationFrame(()=>isMountAnimationPreventedRef.current=!1);return()=>cancelAnimationFrame(rAF)},[]),jsxRuntimeExports.jsx(Presence,{present:forceMount||isSelected,children:__name(({present})=>jsxRuntimeExports.jsx(Primitive$2.div,{"data-state":isSelected?"active":"inactive","data-orientation":context.orientation,role:"tabpanel","aria-labelledby":triggerId,hidden:!present,id:contentId,tabIndex:0,...contentProps,ref:forwardedRef,style:{...props.style,animationDuration:isMountAnimationPreventedRef.current?"0s":void 0},children:present&&children2}),"children")})});TabsContent$1.displayName=CONTENT_NAME;function makeTriggerId(baseId,value2){return`${baseId}-trigger-${value2}`}__name(makeTriggerId,"makeTriggerId");function makeContentId(baseId,value2){return`${baseId}-content-${value2}`}__name(makeContentId,"makeContentId");var Root2=Tabs$1,List=TabsList$1,Trigger=TabsTrigger$1,Content=TabsContent$1;const Tabs=Root2,TabsList=reactExports.forwardRef(({className,...props},ref)=>jsxRuntimeExports.jsx(List,{ref,className:cn$2("inline-flex h-10 items-center justify-center rounded-md bg-muted p-1 text-muted-foreground",className),...props}));TabsList.displayName=List.displayName;const TabsTrigger=reactExports.forwardRef(({className,...props},ref)=>jsxRuntimeExports.jsx(Trigger,{ref,className:cn$2("inline-flex items-center justify-center whitespace-nowrap rounded-sm px-3 py-1.5 text-sm font-medium ring-offset-background transition-all focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50 data-[state=active]:bg-background data-[state=active]:text-foreground data-[state=active]:shadow-sm",className),...props}));TabsTrigger.displayName=Trigger.displayName;const TabsContent=reactExports.forwardRef(({className,...props},ref)=>jsxRuntimeExports.jsx(Content,{ref,className:cn$2("mt-2 ring-offset-background focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2",className),...props}));TabsContent.displayName=Content.displayName;function DevicesConfig(){const enrollment=reportData.TenantInfo?.ConfigWindowsEnrollment,enrollmentRestrictions=reportData.TenantInfo?.ConfigDeviceEnrollmentRestriction,compliancePolicies=reportData.TenantInfo?.ConfigDeviceCompliancePolicies,appProtectionPolicies=reportData.TenantInfo?.ConfigDeviceAppProtectionPolicies;return jsxRuntimeExports.jsxs("div",{className:"p-4",children:[jsxRuntimeExports.jsx("h2",{className:"text-lg font-semibold mb-4",children:"Windows automatic enrollment"}),jsxRuntimeExports.jsx("p",{className:"text-sm text-gray-600 mb-4",children:"Configure Windows devices to enroll when they join or register with Azure Active Directory. We recommend setting this to all instead of selected groups and using enrollment restrictions to configure the intake of users."}),enrollment&&enrollment.length>0?jsxRuntimeExports.jsxs(Table,{children:[jsxRuntimeExports.jsx(TableHeader,{children:jsxRuntimeExports.jsxs(TableRow,{children:[jsxRuntimeExports.jsx(TableHead,{children:"Type"}),jsxRuntimeExports.jsx(TableHead,{children:"Policy Name"}),jsxRuntimeExports.jsx(TableHead,{children:"Applies To"}),jsxRuntimeExports.jsx(TableHead,{children:"Groups"})]})}),jsxRuntimeExports.jsx(TableBody,{children:enrollment.map((row,idx)=>jsxRuntimeExports.jsxs(TableRow,{children:[jsxRuntimeExports.jsx(TableCell,{children:row.Type}),jsxRuntimeExports.jsx(TableCell,{children:row.PolicyName}),jsxRuntimeExports.jsx(TableCell,{children:row.AppliesTo}),jsxRuntimeExports.jsx(TableCell,{children:row.Groups})]},idx))})]}):jsxRuntimeExports.jsx("p",{children:"No Windows enrollment configuration found."}),jsxRuntimeExports.jsx("h2",{className:"text-lg font-semibold mb-4 mt-8",children:"Enrollment device platform restrictions"}),jsxRuntimeExports.jsx("p",{className:"text-sm text-gray-600 mb-4",children:"Device enrollment restrictions let you restrict devices from enrolling in Intune based on certain device attributes. Device platform restrictions restrict devices based on device platform, version, manufacturer, or ownership type."}),enrollmentRestrictions&&enrollmentRestrictions.length>0?jsxRuntimeExports.jsxs(Table,{children:[jsxRuntimeExports.jsx(TableHeader,{children:jsxRuntimeExports.jsxs(TableRow,{children:[jsxRuntimeExports.jsx(TableHead,{children:"Platform"}),jsxRuntimeExports.jsx(TableHead,{children:"Priority"}),jsxRuntimeExports.jsx(TableHead,{children:"Name"}),jsxRuntimeExports.jsx(TableHead,{children:"MDM"}),jsxRuntimeExports.jsx(TableHead,{children:"Min Ver"}),jsxRuntimeExports.jsx(TableHead,{children:"Max Ver"}),jsxRuntimeExports.jsx(TableHead,{children:"Personally owned"}),jsxRuntimeExports.jsx(TableHead,{children:"Blocked manuf."}),jsxRuntimeExports.jsx(TableHead,{children:"Scope"}),jsxRuntimeExports.jsx(TableHead,{children:"Assigned to"})]})}),jsxRuntimeExports.jsx(TableBody,{children:enrollmentRestrictions.map((row,idx)=>jsxRuntimeExports.jsxs(TableRow,{children:[jsxRuntimeExports.jsx(TableCell,{children:row.Platform}),jsxRuntimeExports.jsx(TableCell,{children:row.Priority}),jsxRuntimeExports.jsx(TableCell,{children:row.Name}),jsxRuntimeExports.jsx(TableCell,{children:row.MDM}),jsxRuntimeExports.jsx(TableCell,{children:row.MinVer}),jsxRuntimeExports.jsx(TableCell,{children:row.MaxVer}),jsxRuntimeExports.jsx(TableCell,{children:row.PersonallyOwned}),jsxRuntimeExports.jsx(TableCell,{children:row.BlockedManufacturers}),jsxRuntimeExports.jsx(TableCell,{children:row.Scope}),jsxRuntimeExports.jsx(TableCell,{children:row.AssignedTo})]},idx))})]}):jsxRuntimeExports.jsx("p",{children:"No device enrollment restrictions found."}),jsxRuntimeExports.jsx("h2",{className:"text-lg font-semibold mb-4 mt-8",children:"Compliance policies"}),jsxRuntimeExports.jsx("p",{className:"text-sm text-gray-600 mb-4",children:"Device compliance policies define the rules and settings that devices must meet to be considered compliant. These policies help ensure that devices accessing organizational resources meet minimum security requirements."}),compliancePolicies&&compliancePolicies.length>0?jsxRuntimeExports.jsx("div",{className:"overflow-x-auto",children:jsxRuntimeExports.jsxs(Table,{children:[jsxRuntimeExports.jsx(TableHeader,{children:jsxRuntimeExports.jsxs(TableRow,{children:[jsxRuntimeExports.jsx(TableHead,{className:"font-semibold",children:"Setting"}),compliancePolicies.map((policy,idx)=>jsxRuntimeExports.jsx(TableHead,{className:"min-w-[150px]",children:policy.PolicyName},idx))]})}),jsxRuntimeExports.jsxs(TableBody,{children:[jsxRuntimeExports.jsxs(TableRow,{children:[jsxRuntimeExports.jsx(TableCell,{className:"font-medium",children:"Platform"}),compliancePolicies.map((policy,idx)=>jsxRuntimeExports.jsx(TableCell,{children:policy.Platform},idx))]}),jsxRuntimeExports.jsxs(TableRow,{children:[jsxRuntimeExports.jsx(TableCell,{className:"font-medium",children:"Defender ATP"}),compliancePolicies.map((policy,idx)=>jsxRuntimeExports.jsx(TableCell,{children:policy.DefenderForEndPoint},idx))]}),jsxRuntimeExports.jsxs(TableRow,{children:[jsxRuntimeExports.jsx(TableCell,{className:"font-medium",children:"Min OS Version"}),compliancePolicies.map((policy,idx)=>jsxRuntimeExports.jsx(TableCell,{children:policy.MinOsVersion},idx))]}),jsxRuntimeExports.jsxs(TableRow,{children:[jsxRuntimeExports.jsx(TableCell,{className:"font-medium",children:"Max OS Version"}),compliancePolicies.map((policy,idx)=>jsxRuntimeExports.jsx(TableCell,{children:policy.MaxOsVersion},idx))]}),jsxRuntimeExports.jsxs(TableRow,{children:[jsxRuntimeExports.jsx(TableCell,{className:"font-medium",children:"Require Password"}),compliancePolicies.map((policy,idx)=>jsxRuntimeExports.jsx(TableCell,{children:policy.RequirePswd},idx))]}),jsxRuntimeExports.jsxs(TableRow,{children:[jsxRuntimeExports.jsx(TableCell,{className:"font-medium",children:"Min Password Length"}),compliancePolicies.map((policy,idx)=>jsxRuntimeExports.jsx(TableCell,{children:policy.MinPswdLength},idx))]}),jsxRuntimeExports.jsxs(TableRow,{children:[jsxRuntimeExports.jsx(TableCell,{className:"font-medium",children:"Password Type"}),compliancePolicies.map((policy,idx)=>jsxRuntimeExports.jsx(TableCell,{children:policy.PasswordType},idx))]}),jsxRuntimeExports.jsxs(TableRow,{children:[jsxRuntimeExports.jsx(TableCell,{className:"font-medium",children:"Password Expiry Days"}),compliancePolicies.map((policy,idx)=>jsxRuntimeExports.jsx(TableCell,{children:policy.PswdExpiryDays},idx))]}),jsxRuntimeExports.jsxs(TableRow,{children:[jsxRuntimeExports.jsx(TableCell,{className:"font-medium",children:"Previous Passwords Blocked"}),compliancePolicies.map((policy,idx)=>jsxRuntimeExports.jsx(TableCell,{children:policy.CountOfPreviousPswdToBlock},idx))]}),jsxRuntimeExports.jsxs(TableRow,{children:[jsxRuntimeExports.jsx(TableCell,{className:"font-medium",children:"Max Inactivity Min"}),compliancePolicies.map((policy,idx)=>jsxRuntimeExports.jsx(TableCell,{children:policy.MaxInactivityMin},idx))]}),jsxRuntimeExports.jsxs(TableRow,{children:[jsxRuntimeExports.jsx(TableCell,{className:"font-medium",children:"Require Encryption"}),compliancePolicies.map((policy,idx)=>jsxRuntimeExports.jsx(TableCell,{children:policy.RequireEncryption},idx))]}),jsxRuntimeExports.jsxs(TableRow,{children:[jsxRuntimeExports.jsx(TableCell,{className:"font-medium",children:"Rooted/Jailbroken"}),compliancePolicies.map((policy,idx)=>jsxRuntimeExports.jsx(TableCell,{children:policy.RootedJailbrokenDevices},idx))]}),jsxRuntimeExports.jsxs(TableRow,{children:[jsxRuntimeExports.jsx(TableCell,{className:"font-medium",children:"Max Threat Level"}),compliancePolicies.map((policy,idx)=>jsxRuntimeExports.jsx(TableCell,{children:policy.MaxDeviceThreatLevel},idx))]}),jsxRuntimeExports.jsxs(TableRow,{children:[jsxRuntimeExports.jsx(TableCell,{className:"font-medium",children:"Require Firewall"}),compliancePolicies.map((policy,idx)=>jsxRuntimeExports.jsx(TableCell,{children:policy.RequireFirewall},idx))]}),jsxRuntimeExports.jsxs(TableRow,{children:[jsxRuntimeExports.jsx(TableCell,{className:"font-medium",children:"Push Notification Days"}),compliancePolicies.map((policy,idx)=>jsxRuntimeExports.jsx(TableCell,{children:policy.ActionForNoncomplianceDaysPushNotification},idx))]}),jsxRuntimeExports.jsxs(TableRow,{children:[jsxRuntimeExports.jsx(TableCell,{className:"font-medium",children:"Send Email Days"}),compliancePolicies.map((policy,idx)=>jsxRuntimeExports.jsx(TableCell,{children:policy.ActionForNoncomplianceDaysSendEmail},idx))]}),jsxRuntimeExports.jsxs(TableRow,{children:[jsxRuntimeExports.jsx(TableCell,{className:"font-medium",children:"Remote Lock Days"}),compliancePolicies.map((policy,idx)=>jsxRuntimeExports.jsx(TableCell,{children:policy.ActionForNoncomplianceDaysRemoteLock},idx))]}),jsxRuntimeExports.jsxs(TableRow,{children:[jsxRuntimeExports.jsx(TableCell,{className:"font-medium",children:"Block Days"}),compliancePolicies.map((policy,idx)=>jsxRuntimeExports.jsx(TableCell,{children:policy.ActionForNoncomplianceDaysBlock},idx))]}),jsxRuntimeExports.jsxs(TableRow,{children:[jsxRuntimeExports.jsx(TableCell,{className:"font-medium",children:"Retire Days"}),compliancePolicies.map((policy,idx)=>jsxRuntimeExports.jsx(TableCell,{children:policy.ActionForNoncomplianceDaysRetire},idx))]}),jsxRuntimeExports.jsxs(TableRow,{children:[jsxRuntimeExports.jsx(TableCell,{className:"font-medium",children:"Scope"}),compliancePolicies.map((policy,idx)=>jsxRuntimeExports.jsx(TableCell,{children:policy.Scope},idx))]})]})]})}):jsxRuntimeExports.jsx("p",{children:"No device compliance policies found."}),jsxRuntimeExports.jsx("h2",{className:"text-lg font-semibold mb-4 mt-8",children:"App protection policies"}),jsxRuntimeExports.jsx("p",{className:"text-sm text-gray-600 mb-4",children:`App protection policies (APP) are rules that ensure an organization's data remains safe or contained in a managed app. A policy can be a rule that is enforced when the user attempts to access or move "corporate" data, or a set of actions that are prohibited or monitored when the user is inside the app. A managed app is an app that has app protection policies applied to it, and can be managed by Intune.`}),appProtectionPolicies&&appProtectionPolicies.length>0?jsxRuntimeExports.jsx("div",{className:"overflow-x-auto",children:jsxRuntimeExports.jsxs(Table,{children:[jsxRuntimeExports.jsx(TableHeader,{children:jsxRuntimeExports.jsxs(TableRow,{children:[jsxRuntimeExports.jsx(TableHead,{className:"font-semibold",children:"Setting"}),appProtectionPolicies.map((policy,idx)=>jsxRuntimeExports.jsx(TableHead,{className:"min-w-[150px]",children:policy.Name},idx))]})}),jsxRuntimeExports.jsxs(TableBody,{children:[jsxRuntimeExports.jsxs(TableRow,{children:[jsxRuntimeExports.jsx(TableCell,{className:"font-medium",children:"Platform"}),appProtectionPolicies.map((policy,idx)=>jsxRuntimeExports.jsx(TableCell,{children:policy.Platform},idx))]}),jsxRuntimeExports.jsxs(TableRow,{children:[jsxRuntimeExports.jsx(TableCell,{className:"font-medium",children:"Public Apps"}),appProtectionPolicies.map((policy,idx)=>jsxRuntimeExports.jsx(TableCell,{children:policy.AppsPublic},idx))]}),jsxRuntimeExports.jsxs(TableRow,{children:[jsxRuntimeExports.jsx(TableCell,{className:"font-medium",children:"Custom Apps"}),appProtectionPolicies.map((policy,idx)=>jsxRuntimeExports.jsx(TableCell,{children:policy.AppsCustom},idx))]}),jsxRuntimeExports.jsxs(TableRow,{children:[jsxRuntimeExports.jsx(TableCell,{className:"font-medium",children:"Backup to Cloud"}),appProtectionPolicies.map((policy,idx)=>jsxRuntimeExports.jsx(TableCell,{children:policy.BackupOrgDataToICloudOrGoogle},idx))]}),jsxRuntimeExports.jsxs(TableRow,{children:[jsxRuntimeExports.jsx(TableCell,{className:"font-medium",children:"Send Data to Other Apps"}),appProtectionPolicies.map((policy,idx)=>jsxRuntimeExports.jsx(TableCell,{children:policy.SendOrgDataToOtherApps},idx))]}),jsxRuntimeExports.jsxs(TableRow,{children:[jsxRuntimeExports.jsx(TableCell,{className:"font-medium",children:"Apps to Exempt"}),appProtectionPolicies.map((policy,idx)=>jsxRuntimeExports.jsx(TableCell,{children:policy.AppsToExempt},idx))]}),jsxRuntimeExports.jsxs(TableRow,{children:[jsxRuntimeExports.jsx(TableCell,{className:"font-medium",children:"Save Copies"}),appProtectionPolicies.map((policy,idx)=>jsxRuntimeExports.jsx(TableCell,{children:policy.SaveCopiesOfOrgData},idx))]}),jsxRuntimeExports.jsxs(TableRow,{children:[jsxRuntimeExports.jsx(TableCell,{className:"font-medium",children:"Allow Save to Selected Services"}),appProtectionPolicies.map((policy,idx)=>jsxRuntimeExports.jsx(TableCell,{children:policy.AllowUserToSaveCopiesToSelectedServices},idx))]}),jsxRuntimeExports.jsxs(TableRow,{children:[jsxRuntimeExports.jsx(TableCell,{className:"font-medium",children:"Transfer Telecom Data To"}),appProtectionPolicies.map((policy,idx)=>jsxRuntimeExports.jsx(TableCell,{children:policy.DataProtectionTransferTelecommunicationDataTo},idx))]}),jsxRuntimeExports.jsxs(TableRow,{children:[jsxRuntimeExports.jsx(TableCell,{className:"font-medium",children:"Receive Data From Other Apps"}),appProtectionPolicies.map((policy,idx)=>jsxRuntimeExports.jsx(TableCell,{children:policy.DataProtectionReceiveDataFromOtherApps},idx))]}),jsxRuntimeExports.jsxs(TableRow,{children:[jsxRuntimeExports.jsx(TableCell,{className:"font-medium",children:"Rooted/Jailbroken Devices"}),appProtectionPolicies.map((policy,idx)=>jsxRuntimeExports.jsx(TableCell,{children:policy.ConditionalLaunchDeviceRootedJailbrokenDevices},idx))]}),jsxRuntimeExports.jsxs(TableRow,{children:[jsxRuntimeExports.jsx(TableCell,{className:"font-medium",children:"Scope"}),appProtectionPolicies.map((policy,idx)=>jsxRuntimeExports.jsx(TableCell,{children:policy.Scope},idx))]})]})]})}):jsxRuntimeExports.jsx("p",{children:"No app protection policies found."})]})}__name(DevicesConfig,"DevicesConfig");function Devices(){return jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment,{children:[jsxRuntimeExports.jsx(PageHeader,{children:jsxRuntimeExports.jsx(PageHeaderHeading,{children:"Devices"})}),jsxRuntimeExports.jsxs(Tabs,{defaultValue:"assessment",className:"w-full",children:[jsxRuntimeExports.jsxs(TabsList,{className:"grid w-full grid-cols-2",children:[jsxRuntimeExports.jsxs(TabsTrigger,{value:"assessment",className:"flex items-center gap-2",children:[jsxRuntimeExports.jsx(ChartColumn,{className:"h-4 w-4"}),"Assessment results"]}),jsxRuntimeExports.jsxs(TabsTrigger,{value:"config",className:"flex items-center gap-2",children:[jsxRuntimeExports.jsx(Settings,{className:"h-4 w-4"}),"Config"]})]}),jsxRuntimeExports.jsx(TabsContent,{value:"assessment",className:"space-y-4",children:jsxRuntimeExports.jsxs(Card,{children:[jsxRuntimeExports.jsxs(CardHeader,{children:[jsxRuntimeExports.jsx(CardTitle,{className:"mb-3",children:"Assessment results"}),jsxRuntimeExports.jsxs(CardDescription,{children:["The results presented below are based on the security principles detailed in the"," ",jsxRuntimeExports.jsx("a",{href:"https://learn.microsoft.com/intune/intune-service/protect/zero-trust-configure-security",target:"_blank",rel:"noopener noreferrer",className:"text-primary font-medium underline underline-offset-4 hover:underline",children:"Configuring Microsoft Intune for increased security"})," ","guide."]})]}),jsxRuntimeExports.jsx(CardContent,{className:"gap-4 px-4 pb-4 pt-1",children:jsxRuntimeExports.jsx(DataTable,{columns,data:reportData.Tests,pillar:"Devices"})})]})}),jsxRuntimeExports.jsx(TabsContent,{value:"config",className:"space-y-4",children:jsxRuntimeExports.jsxs(Card,{children:[jsxRuntimeExports.jsxs(CardHeader,{children:[jsxRuntimeExports.jsx(CardTitle,{className:"mb-3",children:"Device Configuration"}),jsxRuntimeExports.jsx(CardDescription,{children:"Device configuration settings and options."})]}),jsxRuntimeExports.jsx(CardContent,{className:"gap-4 px-4 pb-4 pt-1",children:jsxRuntimeExports.jsx(DevicesConfig,{})})]})})]})]})}__name(Devices,"Devices");function Apps(){return jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment,{children:[jsxRuntimeExports.jsx(PageHeader,{children:jsxRuntimeExports.jsx(PageHeaderHeading,{children:"Apps"})}),jsxRuntimeExports.jsx(Card,{children:jsxRuntimeExports.jsxs(CardHeader,{children:[jsxRuntimeExports.jsx(CardTitle,{children:"Coming soon"}),jsxRuntimeExports.jsx(CardDescription,{children:"He that can have patience can have what he will. - Benjamin Franklin"})]})})]})}__name(Apps,"Apps");function Network(){return jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment,{children:[jsxRuntimeExports.jsx(PageHeader,{children:jsxRuntimeExports.jsx(PageHeaderHeading,{children:"Network"})}),jsxRuntimeExports.jsxs(Card,{children:[jsxRuntimeExports.jsxs(CardHeader,{children:[jsxRuntimeExports.jsx(CardTitle,{className:"mb-3",children:"Assessment results"}),jsxRuntimeExports.jsxs(CardDescription,{children:["The results presented below are based on the security principles detailed in the"," ",jsxRuntimeExports.jsx("a",{href:"https://learn.microsoft.com/en-us/entra/fundamentals/configure-security",target:"_blank",rel:"noopener noreferrer",className:"text-primary font-medium underline underline-offset-4 hover:underline",children:"Configuring Microsoft Entra and Azure for increased security"})," ","guide."]})]}),jsxRuntimeExports.jsx(CardContent,{className:"gap-4 px-4 pb-4 pt-1",children:jsxRuntimeExports.jsx(DataTable,{columns,data:reportData.Tests,pillar:"Network"})})]})]})}__name(Network,"Network");function Infrastructure(){return jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment,{children:[jsxRuntimeExports.jsx(PageHeader,{children:jsxRuntimeExports.jsx(PageHeaderHeading,{children:"Infrastructure"})}),jsxRuntimeExports.jsxs(Card,{children:[jsxRuntimeExports.jsxs(CardHeader,{children:[jsxRuntimeExports.jsx(CardTitle,{className:"mb-3",children:"Assessment results"}),jsxRuntimeExports.jsx(CardDescription,{children:"The results below are based on Microsoft Defender for Cloud recommendations identified in the scanned environment."})]}),jsxRuntimeExports.jsx(CardContent,{className:"gap-4 px-4 pb-4 pt-1",children:jsxRuntimeExports.jsx(DataTable,{columns,data:reportData.Tests,pillar:"Infrastructure"})})]})]})}__name(Infrastructure,"Infrastructure");function Data(){return jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment,{children:[jsxRuntimeExports.jsx(PageHeader,{children:jsxRuntimeExports.jsx(PageHeaderHeading,{children:"Data"})}),jsxRuntimeExports.jsxs(Card,{children:[jsxRuntimeExports.jsxs(CardHeader,{children:[jsxRuntimeExports.jsx(CardTitle,{className:"mb-3",children:"Assessment results"}),jsxRuntimeExports.jsxs(CardDescription,{children:["The results presented below are based on the security principles detailed in the"," ",jsxRuntimeExports.jsx("a",{href:"https://learn.microsoft.com/en-us/purview/configure-security",target:"_blank",rel:"noopener noreferrer",className:"text-primary font-medium underline underline-offset-4 hover:underline",children:"Configuring Microsoft Purview for increased security"})," ","guide."]})]}),jsxRuntimeExports.jsx(CardContent,{className:"gap-4 px-4 pb-4 pt-1",children:jsxRuntimeExports.jsx(DataTable,{columns,data:reportData.Tests,pillar:"Data"})})]})]})}__name(Data,"Data");function SecOps(){return jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment,{children:[jsxRuntimeExports.jsx(PageHeader,{children:jsxRuntimeExports.jsx(PageHeaderHeading,{children:"Security Operations"})}),jsxRuntimeExports.jsxs(Card,{children:[jsxRuntimeExports.jsxs(CardHeader,{children:[jsxRuntimeExports.jsx(CardTitle,{className:"mb-3",children:"Assessment results"}),jsxRuntimeExports.jsx(CardDescription,{children:"The results presented below are based on Zero Trust security principles for security operations."})]}),jsxRuntimeExports.jsx(CardContent,{className:"gap-4 px-4 pb-4 pt-1",children:jsxRuntimeExports.jsx(DataTable,{columns,data:reportData.Tests,pillar:"SecOps"})})]})]})}__name(SecOps,"SecOps");function AI(){return jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment,{children:[jsxRuntimeExports.jsx(PageHeader,{children:jsxRuntimeExports.jsx(PageHeaderHeading,{children:"AI"})}),jsxRuntimeExports.jsxs(Card,{children:[jsxRuntimeExports.jsxs(CardHeader,{children:[jsxRuntimeExports.jsx(CardTitle,{className:"mb-3",children:"Assessment results"}),jsxRuntimeExports.jsx(CardDescription,{children:"The results presented below are based on Zero Trust security principles for AI workloads."})]}),jsxRuntimeExports.jsx(CardContent,{className:"gap-4 px-4 pb-4 pt-1",children:jsxRuntimeExports.jsx(DataTable,{columns,data:reportData.Tests,pillar:"AI"})})]})]})}__name(AI,"AI");var define_global_default={basename:""};const router=createHashRouter([{path:"/",element:jsxRuntimeExports.jsx(Applayout,{}),children:[{path:"",element:jsxRuntimeExports.jsx(Dashboard,{})},{path:"identity",element:jsxRuntimeExports.jsx(Identity,{})},{path:"devices",element:jsxRuntimeExports.jsx(Devices,{})},{path:"apps",element:jsxRuntimeExports.jsx(Apps,{})},{path:"network",element:jsxRuntimeExports.jsx(Network,{})},{path:"infrastructure",element:jsxRuntimeExports.jsx(Infrastructure,{})},{path:"data",element:jsxRuntimeExports.jsx(Data,{})},{path:"secops",element:jsxRuntimeExports.jsx(SecOps,{})},{path:"ai",element:jsxRuntimeExports.jsx(AI,{})}]},{path:"*",element:jsxRuntimeExports.jsx(NoMatch,{})}],{basename:define_global_default.basename});function __insertCSS(code2){if(typeof document>"u")return;let head=document.head||document.getElementsByTagName("head")[0],style2=document.createElement("style");style2.type="text/css",head.appendChild(style2),style2.styleSheet?style2.styleSheet.cssText=code2:style2.appendChild(document.createTextNode(code2))}__name(__insertCSS,"__insertCSS");const getAsset=__name(type=>{switch(type){case"success":return SuccessIcon;case"info":return InfoIcon;case"warning":return WarningIcon;case"error":return ErrorIcon;default:return null}},"getAsset"),bars=Array(12).fill(0),Loader=__name(({visible,className})=>React.createElement("div",{className:["sonner-loading-wrapper",className].filter(Boolean).join(" "),"data-visible":visible},React.createElement("div",{className:"sonner-spinner"},bars.map((_2,i2)=>React.createElement("div",{className:"sonner-loading-bar",key:`spinner-bar-${i2}`})))),"Loader"),SuccessIcon=React.createElement("svg",{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 20 20",fill:"currentColor",height:"20",width:"20"},React.createElement("path",{fillRule:"evenodd",d:"M10 18a8 8 0 100-16 8 8 0 000 16zm3.857-9.809a.75.75 0 00-1.214-.882l-3.483 4.79-1.88-1.88a.75.75 0 10-1.06 1.061l2.5 2.5a.75.75 0 001.137-.089l4-5.5z",clipRule:"evenodd"})),WarningIcon=React.createElement("svg",{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 24 24",fill:"currentColor",height:"20",width:"20"},React.createElement("path",{fillRule:"evenodd",d:"M9.401 3.003c1.155-2 4.043-2 5.197 0l7.355 12.748c1.154 2-.29 4.5-2.599 4.5H4.645c-2.309 0-3.752-2.5-2.598-4.5L9.4 3.003zM12 8.25a.75.75 0 01.75.75v3.75a.75.75 0 01-1.5 0V9a.75.75 0 01.75-.75zm0 8.25a.75.75 0 100-1.5.75.75 0 000 1.5z",clipRule:"evenodd"})),InfoIcon=React.createElement("svg",{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 20 20",fill:"currentColor",height:"20",width:"20"},React.createElement("path",{fillRule:"evenodd",d:"M18 10a8 8 0 11-16 0 8 8 0 0116 0zm-7-4a1 1 0 11-2 0 1 1 0 012 0zM9 9a.75.75 0 000 1.5h.253a.25.25 0 01.244.304l-.459 2.066A1.75 1.75 0 0010.747 15H11a.75.75 0 000-1.5h-.253a.25.25 0 01-.244-.304l.459-2.066A1.75 1.75 0 009.253 9H9z",clipRule:"evenodd"})),ErrorIcon=React.createElement("svg",{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 20 20",fill:"currentColor",height:"20",width:"20"},React.createElement("path",{fillRule:"evenodd",d:"M18 10a8 8 0 11-16 0 8 8 0 0116 0zm-8-5a.75.75 0 01.75.75v4.5a.75.75 0 01-1.5 0v-4.5A.75.75 0 0110 5zm0 10a1 1 0 100-2 1 1 0 000 2z",clipRule:"evenodd"})),CloseIcon=React.createElement("svg",{xmlns:"http://www.w3.org/2000/svg",width:"12",height:"12",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"1.5",strokeLinecap:"round",strokeLinejoin:"round"},React.createElement("line",{x1:"18",y1:"6",x2:"6",y2:"18"}),React.createElement("line",{x1:"6",y1:"6",x2:"18",y2:"18"})),useIsDocumentHidden=__name(()=>{const[isDocumentHidden,setIsDocumentHidden]=React.useState(document.hidden);return React.useEffect(()=>{const callback=__name(()=>{setIsDocumentHidden(document.hidden)},"callback");return document.addEventListener("visibilitychange",callback),()=>window.removeEventListener("visibilitychange",callback)},[]),isDocumentHidden},"useIsDocumentHidden");let toastsCounter=1;const _Observer=class _Observer{constructor(){this.subscribe=subscriber=>(this.subscribers.push(subscriber),()=>{const index2=this.subscribers.indexOf(subscriber);this.subscribers.splice(index2,1)}),this.publish=data=>{this.subscribers.forEach(subscriber=>subscriber(data))},this.addToast=data=>{this.publish(data),this.toasts=[...this.toasts,data]},this.create=data=>{var _data_id;const{message,...rest}=data,id=typeof data?.id=="number"||((_data_id=data.id)==null?void 0:_data_id.length)>0?data.id:toastsCounter++,alreadyExists=this.toasts.find(toast2=>toast2.id===id),dismissible=data.dismissible===void 0?!0:data.dismissible;return this.dismissedToasts.has(id)&&this.dismissedToasts.delete(id),alreadyExists?this.toasts=this.toasts.map(toast2=>toast2.id===id?(this.publish({...toast2,...data,id,title:message}),{...toast2,...data,id,dismissible,title:message}):toast2):this.addToast({title:message,...rest,dismissible,id}),id},this.dismiss=id=>(id?(this.dismissedToasts.add(id),requestAnimationFrame(()=>this.subscribers.forEach(subscriber=>subscriber({id,dismiss:!0})))):this.toasts.forEach(toast2=>{this.subscribers.forEach(subscriber=>subscriber({id:toast2.id,dismiss:!0}))}),id),this.message=(message,data)=>this.create({...data,message}),this.error=(message,data)=>this.create({...data,message,type:"error"}),this.success=(message,data)=>this.create({...data,type:"success",message}),this.info=(message,data)=>this.create({...data,type:"info",message}),this.warning=(message,data)=>this.create({...data,type:"warning",message}),this.loading=(message,data)=>this.create({...data,type:"loading",message}),this.promise=(promise,data)=>{if(!data)return;let id;data.loading!==void 0&&(id=this.create({...data,promise,type:"loading",message:data.loading,description:typeof data.description!="function"?data.description:void 0}));const p2=Promise.resolve(promise instanceof Function?promise():promise);let shouldDismiss=id!==void 0,result;const originalPromise=p2.then(async response=>{if(result=["resolve",response],React.isValidElement(response))shouldDismiss=!1,this.create({id,type:"default",message:response});else if(isHttpResponse(response)&&!response.ok){shouldDismiss=!1;const promiseData=typeof data.error=="function"?await data.error(`HTTP error! status: ${response.status}`):data.error,description=typeof data.description=="function"?await data.description(`HTTP error! status: ${response.status}`):data.description,toastSettings=typeof promiseData=="object"&&!React.isValidElement(promiseData)?promiseData:{message:promiseData};this.create({id,type:"error",description,...toastSettings})}else if(response instanceof Error){shouldDismiss=!1;const promiseData=typeof data.error=="function"?await data.error(response):data.error,description=typeof data.description=="function"?await data.description(response):data.description,toastSettings=typeof promiseData=="object"&&!React.isValidElement(promiseData)?promiseData:{message:promiseData};this.create({id,type:"error",description,...toastSettings})}else if(data.success!==void 0){shouldDismiss=!1;const promiseData=typeof data.success=="function"?await data.success(response):data.success,description=typeof data.description=="function"?await data.description(response):data.description,toastSettings=typeof promiseData=="object"&&!React.isValidElement(promiseData)?promiseData:{message:promiseData};this.create({id,type:"success",description,...toastSettings})}}).catch(async error=>{if(result=["reject",error],data.error!==void 0){shouldDismiss=!1;const promiseData=typeof data.error=="function"?await data.error(error):data.error,description=typeof data.description=="function"?await data.description(error):data.description,toastSettings=typeof promiseData=="object"&&!React.isValidElement(promiseData)?promiseData:{message:promiseData};this.create({id,type:"error",description,...toastSettings})}}).finally(()=>{shouldDismiss&&(this.dismiss(id),id=void 0),data.finally==null||data.finally.call(data)}),unwrap=__name(()=>new Promise((resolve,reject)=>originalPromise.then(()=>result[0]==="reject"?reject(result[1]):resolve(result[1])).catch(reject)),"unwrap");return typeof id!="string"&&typeof id!="number"?{unwrap}:Object.assign(id,{unwrap})},this.custom=(jsx,data)=>{const id=data?.id||toastsCounter++;return this.create({jsx:jsx(id),id,...data}),id},this.getActiveToasts=()=>this.toasts.filter(toast2=>!this.dismissedToasts.has(toast2.id)),this.subscribers=[],this.toasts=[],this.dismissedToasts=new Set}};__name(_Observer,"Observer");let Observer=_Observer;const ToastState=new Observer,toastFunction=__name((message,data)=>{const id=data?.id||toastsCounter++;return ToastState.addToast({title:message,...data,id}),id},"toastFunction"),isHttpResponse=__name(data=>data&&typeof data=="object"&&"ok"in data&&typeof data.ok=="boolean"&&"status"in data&&typeof data.status=="number","isHttpResponse"),basicToast=toastFunction,getHistory=__name(()=>ToastState.toasts,"getHistory"),getToasts=__name(()=>ToastState.getActiveToasts(),"getToasts"),toast=Object.assign(basicToast,{success:ToastState.success,info:ToastState.info,warning:ToastState.warning,error:ToastState.error,custom:ToastState.custom,message:ToastState.message,promise:ToastState.promise,dismiss:ToastState.dismiss,loading:ToastState.loading},{getHistory,getToasts});__insertCSS("[data-sonner-toaster][dir=ltr],html[dir=ltr]{--toast-icon-margin-start:-3px;--toast-icon-margin-end:4px;--toast-svg-margin-start:-1px;--toast-svg-margin-end:0px;--toast-button-margin-start:auto;--toast-button-margin-end:0;--toast-close-button-start:0;--toast-close-button-end:unset;--toast-close-button-transform:translate(-35%, -35%)}[data-sonner-toaster][dir=rtl],html[dir=rtl]{--toast-icon-margin-start:4px;--toast-icon-margin-end:-3px;--toast-svg-margin-start:0px;--toast-svg-margin-end:-1px;--toast-button-margin-start:0;--toast-button-margin-end:auto;--toast-close-button-start:unset;--toast-close-button-end:0;--toast-close-button-transform:translate(35%, -35%)}[data-sonner-toaster]{position:fixed;width:var(--width);font-family:ui-sans-serif,system-ui,-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Helvetica Neue,Arial,Noto Sans,sans-serif,Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol,Noto Color Emoji;--gray1:hsl(0, 0%, 99%);--gray2:hsl(0, 0%, 97.3%);--gray3:hsl(0, 0%, 95.1%);--gray4:hsl(0, 0%, 93%);--gray5:hsl(0, 0%, 90.9%);--gray6:hsl(0, 0%, 88.7%);--gray7:hsl(0, 0%, 85.8%);--gray8:hsl(0, 0%, 78%);--gray9:hsl(0, 0%, 56.1%);--gray10:hsl(0, 0%, 52.3%);--gray11:hsl(0, 0%, 43.5%);--gray12:hsl(0, 0%, 9%);--border-radius:8px;box-sizing:border-box;padding:0;margin:0;list-style:none;outline:0;z-index:999999999;transition:transform .4s ease}@media (hover:none) and (pointer:coarse){[data-sonner-toaster][data-lifted=true]{transform:none}}[data-sonner-toaster][data-x-position=right]{right:var(--offset-right)}[data-sonner-toaster][data-x-position=left]{left:var(--offset-left)}[data-sonner-toaster][data-x-position=center]{left:50%;transform:translateX(-50%)}[data-sonner-toaster][data-y-position=top]{top:var(--offset-top)}[data-sonner-toaster][data-y-position=bottom]{bottom:var(--offset-bottom)}[data-sonner-toast]{--y:translateY(100%);--lift-amount:calc(var(--lift) * var(--gap));z-index:var(--z-index);position:absolute;opacity:0;transform:var(--y);touch-action:none;transition:transform .4s,opacity .4s,height .4s,box-shadow .2s;box-sizing:border-box;outline:0;overflow-wrap:anywhere}[data-sonner-toast][data-styled=true]{padding:16px;background:var(--normal-bg);border:1px solid var(--normal-border);color:var(--normal-text);border-radius:var(--border-radius);box-shadow:0 4px 12px rgba(0,0,0,.1);width:var(--width);font-size:13px;display:flex;align-items:center;gap:6px}[data-sonner-toast]:focus-visible{box-shadow:0 4px 12px rgba(0,0,0,.1),0 0 0 2px rgba(0,0,0,.2)}[data-sonner-toast][data-y-position=top]{top:0;--y:translateY(-100%);--lift:1;--lift-amount:calc(1 * var(--gap))}[data-sonner-toast][data-y-position=bottom]{bottom:0;--y:translateY(100%);--lift:-1;--lift-amount:calc(var(--lift) * var(--gap))}[data-sonner-toast][data-styled=true] [data-description]{font-weight:400;line-height:1.4;color:#3f3f3f}[data-rich-colors=true][data-sonner-toast][data-styled=true] [data-description]{color:inherit}[data-sonner-toaster][data-sonner-theme=dark] [data-description]{color:#e8e8e8}[data-sonner-toast][data-styled=true] [data-title]{font-weight:500;line-height:1.5;color:inherit}[data-sonner-toast][data-styled=true] [data-icon]{display:flex;height:16px;width:16px;position:relative;justify-content:flex-start;align-items:center;flex-shrink:0;margin-left:var(--toast-icon-margin-start);margin-right:var(--toast-icon-margin-end)}[data-sonner-toast][data-promise=true] [data-icon]>svg{opacity:0;transform:scale(.8);transform-origin:center;animation:sonner-fade-in .3s ease forwards}[data-sonner-toast][data-styled=true] [data-icon]>*{flex-shrink:0}[data-sonner-toast][data-styled=true] [data-icon] svg{margin-left:var(--toast-svg-margin-start);margin-right:var(--toast-svg-margin-end)}[data-sonner-toast][data-styled=true] [data-content]{display:flex;flex-direction:column;gap:2px}[data-sonner-toast][data-styled=true] [data-button]{border-radius:4px;padding-left:8px;padding-right:8px;height:24px;font-size:12px;color:var(--normal-bg);background:var(--normal-text);margin-left:var(--toast-button-margin-start);margin-right:var(--toast-button-margin-end);border:none;font-weight:500;cursor:pointer;outline:0;display:flex;align-items:center;flex-shrink:0;transition:opacity .4s,box-shadow .2s}[data-sonner-toast][data-styled=true] [data-button]:focus-visible{box-shadow:0 0 0 2px rgba(0,0,0,.4)}[data-sonner-toast][data-styled=true] [data-button]:first-of-type{margin-left:var(--toast-button-margin-start);margin-right:var(--toast-button-margin-end)}[data-sonner-toast][data-styled=true] [data-cancel]{color:var(--normal-text);background:rgba(0,0,0,.08)}[data-sonner-toaster][data-sonner-theme=dark] [data-sonner-toast][data-styled=true] [data-cancel]{background:rgba(255,255,255,.3)}[data-sonner-toast][data-styled=true] [data-close-button]{position:absolute;left:var(--toast-close-button-start);right:var(--toast-close-button-end);top:0;height:20px;width:20px;display:flex;justify-content:center;align-items:center;padding:0;color:var(--gray12);background:var(--normal-bg);border:1px solid var(--gray4);transform:var(--toast-close-button-transform);border-radius:50%;cursor:pointer;z-index:1;transition:opacity .1s,background .2s,border-color .2s}[data-sonner-toast][data-styled=true] [data-close-button]:focus-visible{box-shadow:0 4px 12px rgba(0,0,0,.1),0 0 0 2px rgba(0,0,0,.2)}[data-sonner-toast][data-styled=true] [data-disabled=true]{cursor:not-allowed}[data-sonner-toast][data-styled=true]:hover [data-close-button]:hover{background:var(--gray2);border-color:var(--gray5)}[data-sonner-toast][data-swiping=true]::before{content:'';position:absolute;left:-100%;right:-100%;height:100%;z-index:-1}[data-sonner-toast][data-y-position=top][data-swiping=true]::before{bottom:50%;transform:scaleY(3) translateY(50%)}[data-sonner-toast][data-y-position=bottom][data-swiping=true]::before{top:50%;transform:scaleY(3) translateY(-50%)}[data-sonner-toast][data-swiping=false][data-removed=true]::before{content:'';position:absolute;inset:0;transform:scaleY(2)}[data-sonner-toast][data-expanded=true]::after{content:'';position:absolute;left:0;height:calc(var(--gap) + 1px);bottom:100%;width:100%}[data-sonner-toast][data-mounted=true]{--y:translateY(0);opacity:1}[data-sonner-toast][data-expanded=false][data-front=false]{--scale:var(--toasts-before) * 0.05 + 1;--y:translateY(calc(var(--lift-amount) * var(--toasts-before))) scale(calc(-1 * var(--scale)));height:var(--front-toast-height)}[data-sonner-toast]>*{transition:opacity .4s}[data-sonner-toast][data-x-position=right]{right:0}[data-sonner-toast][data-x-position=left]{left:0}[data-sonner-toast][data-expanded=false][data-front=false][data-styled=true]>*{opacity:0}[data-sonner-toast][data-visible=false]{opacity:0;pointer-events:none}[data-sonner-toast][data-mounted=true][data-expanded=true]{--y:translateY(calc(var(--lift) * var(--offset)));height:var(--initial-height)}[data-sonner-toast][data-removed=true][data-front=true][data-swipe-out=false]{--y:translateY(calc(var(--lift) * -100%));opacity:0}[data-sonner-toast][data-removed=true][data-front=false][data-swipe-out=false][data-expanded=true]{--y:translateY(calc(var(--lift) * var(--offset) + var(--lift) * -100%));opacity:0}[data-sonner-toast][data-removed=true][data-front=false][data-swipe-out=false][data-expanded=false]{--y:translateY(40%);opacity:0;transition:transform .5s,opacity .2s}[data-sonner-toast][data-removed=true][data-front=false]::before{height:calc(var(--initial-height) + 20%)}[data-sonner-toast][data-swiping=true]{transform:var(--y) translateY(var(--swipe-amount-y,0)) translateX(var(--swipe-amount-x,0));transition:none}[data-sonner-toast][data-swiped=true]{user-select:none}[data-sonner-toast][data-swipe-out=true][data-y-position=bottom],[data-sonner-toast][data-swipe-out=true][data-y-position=top]{animation-duration:.2s;animation-timing-function:ease-out;animation-fill-mode:forwards}[data-sonner-toast][data-swipe-out=true][data-swipe-direction=left]{animation-name:swipe-out-left}[data-sonner-toast][data-swipe-out=true][data-swipe-direction=right]{animation-name:swipe-out-right}[data-sonner-toast][data-swipe-out=true][data-swipe-direction=up]{animation-name:swipe-out-up}[data-sonner-toast][data-swipe-out=true][data-swipe-direction=down]{animation-name:swipe-out-down}@keyframes swipe-out-left{from{transform:var(--y) translateX(var(--swipe-amount-x));opacity:1}to{transform:var(--y) translateX(calc(var(--swipe-amount-x) - 100%));opacity:0}}@keyframes swipe-out-right{from{transform:var(--y) translateX(var(--swipe-amount-x));opacity:1}to{transform:var(--y) translateX(calc(var(--swipe-amount-x) + 100%));opacity:0}}@keyframes swipe-out-up{from{transform:var(--y) translateY(var(--swipe-amount-y));opacity:1}to{transform:var(--y) translateY(calc(var(--swipe-amount-y) - 100%));opacity:0}}@keyframes swipe-out-down{from{transform:var(--y) translateY(var(--swipe-amount-y));opacity:1}to{transform:var(--y) translateY(calc(var(--swipe-amount-y) + 100%));opacity:0}}@media (max-width:600px){[data-sonner-toaster]{position:fixed;right:var(--mobile-offset-right);left:var(--mobile-offset-left);width:100%}[data-sonner-toaster][dir=rtl]{left:calc(var(--mobile-offset-left) * -1)}[data-sonner-toaster] [data-sonner-toast]{left:0;right:0;width:calc(100% - var(--mobile-offset-left) * 2)}[data-sonner-toaster][data-x-position=left]{left:var(--mobile-offset-left)}[data-sonner-toaster][data-y-position=bottom]{bottom:var(--mobile-offset-bottom)}[data-sonner-toaster][data-y-position=top]{top:var(--mobile-offset-top)}[data-sonner-toaster][data-x-position=center]{left:var(--mobile-offset-left);right:var(--mobile-offset-right);transform:none}}[data-sonner-toaster][data-sonner-theme=light]{--normal-bg:#fff;--normal-border:var(--gray4);--normal-text:var(--gray12);--success-bg:hsl(143, 85%, 96%);--success-border:hsl(145, 92%, 87%);--success-text:hsl(140, 100%, 27%);--info-bg:hsl(208, 100%, 97%);--info-border:hsl(221, 91%, 93%);--info-text:hsl(210, 92%, 45%);--warning-bg:hsl(49, 100%, 97%);--warning-border:hsl(49, 91%, 84%);--warning-text:hsl(31, 92%, 45%);--error-bg:hsl(359, 100%, 97%);--error-border:hsl(359, 100%, 94%);--error-text:hsl(360, 100%, 45%)}[data-sonner-toaster][data-sonner-theme=light] [data-sonner-toast][data-invert=true]{--normal-bg:#000;--normal-border:hsl(0, 0%, 20%);--normal-text:var(--gray1)}[data-sonner-toaster][data-sonner-theme=dark] [data-sonner-toast][data-invert=true]{--normal-bg:#fff;--normal-border:var(--gray3);--normal-text:var(--gray12)}[data-sonner-toaster][data-sonner-theme=dark]{--normal-bg:#000;--normal-bg-hover:hsl(0, 0%, 12%);--normal-border:hsl(0, 0%, 20%);--normal-border-hover:hsl(0, 0%, 25%);--normal-text:var(--gray1);--success-bg:hsl(150, 100%, 6%);--success-border:hsl(147, 100%, 12%);--success-text:hsl(150, 86%, 65%);--info-bg:hsl(215, 100%, 6%);--info-border:hsl(223, 43%, 17%);--info-text:hsl(216, 87%, 65%);--warning-bg:hsl(64, 100%, 6%);--warning-border:hsl(60, 100%, 9%);--warning-text:hsl(46, 87%, 65%);--error-bg:hsl(358, 76%, 10%);--error-border:hsl(357, 89%, 16%);--error-text:hsl(358, 100%, 81%)}[data-sonner-toaster][data-sonner-theme=dark] [data-sonner-toast] [data-close-button]{background:var(--normal-bg);border-color:var(--normal-border);color:var(--normal-text)}[data-sonner-toaster][data-sonner-theme=dark] [data-sonner-toast] [data-close-button]:hover{background:var(--normal-bg-hover);border-color:var(--normal-border-hover)}[data-rich-colors=true][data-sonner-toast][data-type=success]{background:var(--success-bg);border-color:var(--success-border);color:var(--success-text)}[data-rich-colors=true][data-sonner-toast][data-type=success] [data-close-button]{background:var(--success-bg);border-color:var(--success-border);color:var(--success-text)}[data-rich-colors=true][data-sonner-toast][data-type=info]{background:var(--info-bg);border-color:var(--info-border);color:var(--info-text)}[data-rich-colors=true][data-sonner-toast][data-type=info] [data-close-button]{background:var(--info-bg);border-color:var(--info-border);color:var(--info-text)}[data-rich-colors=true][data-sonner-toast][data-type=warning]{background:var(--warning-bg);border-color:var(--warning-border);color:var(--warning-text)}[data-rich-colors=true][data-sonner-toast][data-type=warning] [data-close-button]{background:var(--warning-bg);border-color:var(--warning-border);color:var(--warning-text)}[data-rich-colors=true][data-sonner-toast][data-type=error]{background:var(--error-bg);border-color:var(--error-border);color:var(--error-text)}[data-rich-colors=true][data-sonner-toast][data-type=error] [data-close-button]{background:var(--error-bg);border-color:var(--error-border);color:var(--error-text)}.sonner-loading-wrapper{--size:16px;height:var(--size);width:var(--size);position:absolute;inset:0;z-index:10}.sonner-loading-wrapper[data-visible=false]{transform-origin:center;animation:sonner-fade-out .2s ease forwards}.sonner-spinner{position:relative;top:50%;left:50%;height:var(--size);width:var(--size)}.sonner-loading-bar{animation:sonner-spin 1.2s linear infinite;background:var(--gray11);border-radius:6px;height:8%;left:-10%;position:absolute;top:-3.9%;width:24%}.sonner-loading-bar:first-child{animation-delay:-1.2s;transform:rotate(.0001deg) translate(146%)}.sonner-loading-bar:nth-child(2){animation-delay:-1.1s;transform:rotate(30deg) translate(146%)}.sonner-loading-bar:nth-child(3){animation-delay:-1s;transform:rotate(60deg) translate(146%)}.sonner-loading-bar:nth-child(4){animation-delay:-.9s;transform:rotate(90deg) translate(146%)}.sonner-loading-bar:nth-child(5){animation-delay:-.8s;transform:rotate(120deg) translate(146%)}.sonner-loading-bar:nth-child(6){animation-delay:-.7s;transform:rotate(150deg) translate(146%)}.sonner-loading-bar:nth-child(7){animation-delay:-.6s;transform:rotate(180deg) translate(146%)}.sonner-loading-bar:nth-child(8){animation-delay:-.5s;transform:rotate(210deg) translate(146%)}.sonner-loading-bar:nth-child(9){animation-delay:-.4s;transform:rotate(240deg) translate(146%)}.sonner-loading-bar:nth-child(10){animation-delay:-.3s;transform:rotate(270deg) translate(146%)}.sonner-loading-bar:nth-child(11){animation-delay:-.2s;transform:rotate(300deg) translate(146%)}.sonner-loading-bar:nth-child(12){animation-delay:-.1s;transform:rotate(330deg) translate(146%)}@keyframes sonner-fade-in{0%{opacity:0;transform:scale(.8)}100%{opacity:1;transform:scale(1)}}@keyframes sonner-fade-out{0%{opacity:1;transform:scale(1)}100%{opacity:0;transform:scale(.8)}}@keyframes sonner-spin{0%{opacity:1}100%{opacity:.15}}@media (prefers-reduced-motion){.sonner-loading-bar,[data-sonner-toast],[data-sonner-toast]>*{transition:none!important;animation:none!important}}.sonner-loader{position:absolute;top:50%;left:50%;transform:translate(-50%,-50%);transform-origin:center;transition:opacity .2s,transform .2s}.sonner-loader[data-visible=false]{opacity:0;transform:scale(.8) translate(-50%,-50%)}");function isAction(action){return action.label!==void 0}__name(isAction,"isAction");const VISIBLE_TOASTS_AMOUNT=3,VIEWPORT_OFFSET="24px",MOBILE_VIEWPORT_OFFSET="16px",TOAST_LIFETIME=4e3,TOAST_WIDTH=356,GAP=14,SWIPE_THRESHOLD=45,TIME_BEFORE_UNMOUNT=200;function cn(...classes){return classes.filter(Boolean).join(" ")}__name(cn,"cn");function getDefaultSwipeDirections(position2){const[y2,x2]=position2.split("-"),directions=[];return y2&&directions.push(y2),x2&&directions.push(x2),directions}__name(getDefaultSwipeDirections,"getDefaultSwipeDirections");const Toast=__name(props=>{var _toast_classNames,_toast_classNames1,_toast_classNames2,_toast_classNames3,_toast_classNames4,_toast_classNames5,_toast_classNames6,_toast_classNames7,_toast_classNames8;const{invert:ToasterInvert,toast:toast2,unstyled,interacting,setHeights,visibleToasts,heights,index:index2,toasts,expanded,removeToast,defaultRichColors,closeButton:closeButtonFromToaster,style:style2,cancelButtonStyle,actionButtonStyle,className="",descriptionClassName="",duration:durationFromToaster,position:position2,gap,expandByDefault,classNames,icons,closeButtonAriaLabel="Close toast"}=props,[swipeDirection,setSwipeDirection]=React.useState(null),[swipeOutDirection,setSwipeOutDirection]=React.useState(null),[mounted,setMounted]=React.useState(!1),[removed,setRemoved]=React.useState(!1),[swiping,setSwiping]=React.useState(!1),[swipeOut,setSwipeOut]=React.useState(!1),[isSwiped,setIsSwiped]=React.useState(!1),[offsetBeforeRemove,setOffsetBeforeRemove]=React.useState(0),[initialHeight,setInitialHeight]=React.useState(0),remainingTime=React.useRef(toast2.duration||durationFromToaster||TOAST_LIFETIME),dragStartTime=React.useRef(null),toastRef=React.useRef(null),isFront=index2===0,isVisible2=index2+1<=visibleToasts,toastType=toast2.type,dismissible=toast2.dismissible!==!1,toastClassname=toast2.className||"",toastDescriptionClassname=toast2.descriptionClassName||"",heightIndex=React.useMemo(()=>heights.findIndex(height=>height.toastId===toast2.id)||0,[heights,toast2.id]),closeButton=React.useMemo(()=>{var _toast_closeButton;return(_toast_closeButton=toast2.closeButton)!=null?_toast_closeButton:closeButtonFromToaster},[toast2.closeButton,closeButtonFromToaster]),duration=React.useMemo(()=>toast2.duration||durationFromToaster||TOAST_LIFETIME,[toast2.duration,durationFromToaster]),closeTimerStartTimeRef=React.useRef(0),offset2=React.useRef(0),lastCloseTimerStartTimeRef=React.useRef(0),pointerStartRef=React.useRef(null),[y2,x2]=position2.split("-"),toastsHeightBefore=React.useMemo(()=>heights.reduce((prev,curr,reducerIndex)=>reducerIndex>=heightIndex?prev:prev+curr.height,0),[heights,heightIndex]),isDocumentHidden=useIsDocumentHidden(),invert=toast2.invert||ToasterInvert,disabled=toastType==="loading";offset2.current=React.useMemo(()=>heightIndex*gap+toastsHeightBefore,[heightIndex,toastsHeightBefore]),React.useEffect(()=>{remainingTime.current=duration},[duration]),React.useEffect(()=>{setMounted(!0)},[]),React.useEffect(()=>{const toastNode=toastRef.current;if(toastNode){const height=toastNode.getBoundingClientRect().height;return setInitialHeight(height),setHeights(h2=>[{toastId:toast2.id,height,position:toast2.position},...h2]),()=>setHeights(h2=>h2.filter(height2=>height2.toastId!==toast2.id))}},[setHeights,toast2.id]),React.useLayoutEffect(()=>{if(!mounted)return;const toastNode=toastRef.current,originalHeight=toastNode.style.height;toastNode.style.height="auto";const newHeight=toastNode.getBoundingClientRect().height;toastNode.style.height=originalHeight,setInitialHeight(newHeight),setHeights(heights2=>heights2.find(height=>height.toastId===toast2.id)?heights2.map(height=>height.toastId===toast2.id?{...height,height:newHeight}:height):[{toastId:toast2.id,height:newHeight,position:toast2.position},...heights2])},[mounted,toast2.title,toast2.description,setHeights,toast2.id,toast2.jsx,toast2.action,toast2.cancel]);const deleteToast=React.useCallback(()=>{setRemoved(!0),setOffsetBeforeRemove(offset2.current),setHeights(h2=>h2.filter(height=>height.toastId!==toast2.id)),setTimeout(()=>{removeToast(toast2)},TIME_BEFORE_UNMOUNT)},[toast2,removeToast,setHeights,offset2]);React.useEffect(()=>{if(toast2.promise&&toastType==="loading"||toast2.duration===1/0||toast2.type==="loading")return;let timeoutId;return expanded||interacting||isDocumentHidden?__name(()=>{if(lastCloseTimerStartTimeRef.current{remainingTime.current!==1/0&&(closeTimerStartTimeRef.current=new Date().getTime(),timeoutId=setTimeout(()=>{toast2.onAutoClose==null||toast2.onAutoClose.call(toast2,toast2),deleteToast()},remainingTime.current))},"startTimer")(),()=>clearTimeout(timeoutId)},[expanded,interacting,toast2,toastType,isDocumentHidden,deleteToast]),React.useEffect(()=>{toast2.delete&&(deleteToast(),toast2.onDismiss==null||toast2.onDismiss.call(toast2,toast2))},[deleteToast,toast2.delete]);function getLoadingIcon(){var _toast_classNames9;if(icons?.loading){var _toast_classNames12;return React.createElement("div",{className:cn(classNames?.loader,toast2==null||(_toast_classNames12=toast2.classNames)==null?void 0:_toast_classNames12.loader,"sonner-loader"),"data-visible":toastType==="loading"},icons.loading)}return React.createElement(Loader,{className:cn(classNames?.loader,toast2==null||(_toast_classNames9=toast2.classNames)==null?void 0:_toast_classNames9.loader),visible:toastType==="loading"})}__name(getLoadingIcon,"getLoadingIcon");const icon=toast2.icon||icons?.[toastType]||getAsset(toastType);var _toast_richColors,_icons_close;return React.createElement("li",{tabIndex:0,ref:toastRef,className:cn(className,toastClassname,classNames?.toast,toast2==null||(_toast_classNames=toast2.classNames)==null?void 0:_toast_classNames.toast,classNames?.default,classNames?.[toastType],toast2==null||(_toast_classNames1=toast2.classNames)==null?void 0:_toast_classNames1[toastType]),"data-sonner-toast":"","data-rich-colors":(_toast_richColors=toast2.richColors)!=null?_toast_richColors:defaultRichColors,"data-styled":!(toast2.jsx||toast2.unstyled||unstyled),"data-mounted":mounted,"data-promise":!!toast2.promise,"data-swiped":isSwiped,"data-removed":removed,"data-visible":isVisible2,"data-y-position":y2,"data-x-position":x2,"data-index":index2,"data-front":isFront,"data-swiping":swiping,"data-dismissible":dismissible,"data-type":toastType,"data-invert":invert,"data-swipe-out":swipeOut,"data-swipe-direction":swipeOutDirection,"data-expanded":!!(expanded||expandByDefault&&mounted),"data-testid":toast2.testId,style:{"--index":index2,"--toasts-before":index2,"--z-index":toasts.length-index2,"--offset":`${removed?offsetBeforeRemove:offset2.current}px`,"--initial-height":expandByDefault?"auto":`${initialHeight}px`,...style2,...toast2.style},onDragEnd:__name(()=>{setSwiping(!1),setSwipeDirection(null),pointerStartRef.current=null},"onDragEnd"),onPointerDown:__name(event=>{event.button!==2&&(disabled||!dismissible||(dragStartTime.current=new Date,setOffsetBeforeRemove(offset2.current),event.target.setPointerCapture(event.pointerId),event.target.tagName!=="BUTTON"&&(setSwiping(!0),pointerStartRef.current={x:event.clientX,y:event.clientY})))},"onPointerDown"),onPointerUp:__name(()=>{var _toastRef_current,_toastRef_current1,_dragStartTime_current;if(swipeOut||!dismissible)return;pointerStartRef.current=null;const swipeAmountX=Number(((_toastRef_current=toastRef.current)==null?void 0:_toastRef_current.style.getPropertyValue("--swipe-amount-x").replace("px",""))||0),swipeAmountY=Number(((_toastRef_current1=toastRef.current)==null?void 0:_toastRef_current1.style.getPropertyValue("--swipe-amount-y").replace("px",""))||0),timeTaken=new Date().getTime()-((_dragStartTime_current=dragStartTime.current)==null?void 0:_dragStartTime_current.getTime()),swipeAmount=swipeDirection==="x"?swipeAmountX:swipeAmountY,velocity=Math.abs(swipeAmount)/timeTaken;if(Math.abs(swipeAmount)>=SWIPE_THRESHOLD||velocity>.11){setOffsetBeforeRemove(offset2.current),toast2.onDismiss==null||toast2.onDismiss.call(toast2,toast2),setSwipeOutDirection(swipeDirection==="x"?swipeAmountX>0?"right":"left":swipeAmountY>0?"down":"up"),deleteToast(),setSwipeOut(!0);return}else{var _toastRef_current2,_toastRef_current3;(_toastRef_current2=toastRef.current)==null||_toastRef_current2.style.setProperty("--swipe-amount-x","0px"),(_toastRef_current3=toastRef.current)==null||_toastRef_current3.style.setProperty("--swipe-amount-y","0px")}setIsSwiped(!1),setSwiping(!1),setSwipeDirection(null)},"onPointerUp"),onPointerMove:__name(event=>{var _window_getSelection,_toastRef_current,_toastRef_current1;if(!pointerStartRef.current||!dismissible||((_window_getSelection=window.getSelection())==null?void 0:_window_getSelection.toString().length)>0)return;const yDelta=event.clientY-pointerStartRef.current.y,xDelta=event.clientX-pointerStartRef.current.x;var _props_swipeDirections;const swipeDirections=(_props_swipeDirections=props.swipeDirections)!=null?_props_swipeDirections:getDefaultSwipeDirections(position2);!swipeDirection&&(Math.abs(xDelta)>1||Math.abs(yDelta)>1)&&setSwipeDirection(Math.abs(xDelta)>Math.abs(yDelta)?"x":"y");let swipeAmount={x:0,y:0};const getDampening=__name(delta=>1/(1.5+Math.abs(delta)/20),"getDampening");if(swipeDirection==="y"){if(swipeDirections.includes("top")||swipeDirections.includes("bottom"))if(swipeDirections.includes("top")&&yDelta<0||swipeDirections.includes("bottom")&&yDelta>0)swipeAmount.y=yDelta;else{const dampenedDelta=yDelta*getDampening(yDelta);swipeAmount.y=Math.abs(dampenedDelta)0)swipeAmount.x=xDelta;else{const dampenedDelta=xDelta*getDampening(xDelta);swipeAmount.x=Math.abs(dampenedDelta)0||Math.abs(swipeAmount.y)>0)&&setIsSwiped(!0),(_toastRef_current=toastRef.current)==null||_toastRef_current.style.setProperty("--swipe-amount-x",`${swipeAmount.x}px`),(_toastRef_current1=toastRef.current)==null||_toastRef_current1.style.setProperty("--swipe-amount-y",`${swipeAmount.y}px`)},"onPointerMove")},closeButton&&!toast2.jsx&&toastType!=="loading"?React.createElement("button",{"aria-label":closeButtonAriaLabel,"data-disabled":disabled,"data-close-button":!0,onClick:disabled||!dismissible?()=>{}:()=>{deleteToast(),toast2.onDismiss==null||toast2.onDismiss.call(toast2,toast2)},className:cn(classNames?.closeButton,toast2==null||(_toast_classNames2=toast2.classNames)==null?void 0:_toast_classNames2.closeButton)},(_icons_close=icons?.close)!=null?_icons_close:CloseIcon):null,(toastType||toast2.icon||toast2.promise)&&toast2.icon!==null&&(icons?.[toastType]!==null||toast2.icon)?React.createElement("div",{"data-icon":"",className:cn(classNames?.icon,toast2==null||(_toast_classNames3=toast2.classNames)==null?void 0:_toast_classNames3.icon)},toast2.promise||toast2.type==="loading"&&!toast2.icon?toast2.icon||getLoadingIcon():null,toast2.type!=="loading"?icon:null):null,React.createElement("div",{"data-content":"",className:cn(classNames?.content,toast2==null||(_toast_classNames4=toast2.classNames)==null?void 0:_toast_classNames4.content)},React.createElement("div",{"data-title":"",className:cn(classNames?.title,toast2==null||(_toast_classNames5=toast2.classNames)==null?void 0:_toast_classNames5.title)},toast2.jsx?toast2.jsx:typeof toast2.title=="function"?toast2.title():toast2.title),toast2.description?React.createElement("div",{"data-description":"",className:cn(descriptionClassName,toastDescriptionClassname,classNames?.description,toast2==null||(_toast_classNames6=toast2.classNames)==null?void 0:_toast_classNames6.description)},typeof toast2.description=="function"?toast2.description():toast2.description):null),React.isValidElement(toast2.cancel)?toast2.cancel:toast2.cancel&&isAction(toast2.cancel)?React.createElement("button",{"data-button":!0,"data-cancel":!0,style:toast2.cancelButtonStyle||cancelButtonStyle,onClick:__name(event=>{isAction(toast2.cancel)&&dismissible&&(toast2.cancel.onClick==null||toast2.cancel.onClick.call(toast2.cancel,event),deleteToast())},"onClick"),className:cn(classNames?.cancelButton,toast2==null||(_toast_classNames7=toast2.classNames)==null?void 0:_toast_classNames7.cancelButton)},toast2.cancel.label):null,React.isValidElement(toast2.action)?toast2.action:toast2.action&&isAction(toast2.action)?React.createElement("button",{"data-button":!0,"data-action":!0,style:toast2.actionButtonStyle||actionButtonStyle,onClick:__name(event=>{isAction(toast2.action)&&(toast2.action.onClick==null||toast2.action.onClick.call(toast2.action,event),!event.defaultPrevented&&deleteToast())},"onClick"),className:cn(classNames?.actionButton,toast2==null||(_toast_classNames8=toast2.classNames)==null?void 0:_toast_classNames8.actionButton)},toast2.action.label):null)},"Toast");function getDocumentDirection(){if(typeof window>"u"||typeof document>"u")return"ltr";const dirAttribute=document.documentElement.getAttribute("dir");return dirAttribute==="auto"||!dirAttribute?window.getComputedStyle(document.documentElement).direction:dirAttribute}__name(getDocumentDirection,"getDocumentDirection");function assignOffset(defaultOffset,mobileOffset){const styles={};return[defaultOffset,mobileOffset].forEach((offset2,index2)=>{const isMobile=index2===1,prefix2=isMobile?"--mobile-offset":"--offset",defaultValue=isMobile?MOBILE_VIEWPORT_OFFSET:VIEWPORT_OFFSET;function assignAll(offset3){["top","right","bottom","left"].forEach(key=>{styles[`${prefix2}-${key}`]=typeof offset3=="number"?`${offset3}px`:offset3})}__name(assignAll,"assignAll"),typeof offset2=="number"||typeof offset2=="string"?assignAll(offset2):typeof offset2=="object"?["top","right","bottom","left"].forEach(key=>{offset2[key]===void 0?styles[`${prefix2}-${key}`]=defaultValue:styles[`${prefix2}-${key}`]=typeof offset2[key]=="number"?`${offset2[key]}px`:offset2[key]}):assignAll(defaultValue)}),styles}__name(assignOffset,"assignOffset");const Toaster$1=React.forwardRef(__name(function(props,ref){const{id,invert,position:position2="bottom-right",hotkey=["altKey","KeyT"],expand,closeButton,className,offset:offset2,mobileOffset,theme="light",richColors,duration,style:style2,visibleToasts=VISIBLE_TOASTS_AMOUNT,toastOptions,dir=getDocumentDirection(),gap=GAP,icons,containerAriaLabel="Notifications"}=props,[toasts,setToasts]=React.useState([]),filteredToasts=React.useMemo(()=>id?toasts.filter(toast2=>toast2.toasterId===id):toasts.filter(toast2=>!toast2.toasterId),[toasts,id]),possiblePositions=React.useMemo(()=>Array.from(new Set([position2].concat(filteredToasts.filter(toast2=>toast2.position).map(toast2=>toast2.position)))),[filteredToasts,position2]),[heights,setHeights]=React.useState([]),[expanded,setExpanded]=React.useState(!1),[interacting,setInteracting]=React.useState(!1),[actualTheme,setActualTheme]=React.useState(theme!=="system"?theme:typeof window<"u"&&window.matchMedia&&window.matchMedia("(prefers-color-scheme: dark)").matches?"dark":"light"),listRef=React.useRef(null),hotkeyLabel=hotkey.join("+").replace(/Key/g,"").replace(/Digit/g,""),lastFocusedElementRef=React.useRef(null),isFocusWithinRef=React.useRef(!1),removeToast=React.useCallback(toastToRemove=>{setToasts(toasts2=>{var _toasts_find;return(_toasts_find=toasts2.find(toast2=>toast2.id===toastToRemove.id))!=null&&_toasts_find.delete||ToastState.dismiss(toastToRemove.id),toasts2.filter(({id:id2})=>id2!==toastToRemove.id)})},[]);return React.useEffect(()=>ToastState.subscribe(toast2=>{if(toast2.dismiss){requestAnimationFrame(()=>{setToasts(toasts2=>toasts2.map(t2=>t2.id===toast2.id?{...t2,delete:!0}:t2))});return}setTimeout(()=>{ReactDOM.flushSync(()=>{setToasts(toasts2=>{const indexOfExistingToast=toasts2.findIndex(t2=>t2.id===toast2.id);return indexOfExistingToast!==-1?[...toasts2.slice(0,indexOfExistingToast),{...toasts2[indexOfExistingToast],...toast2},...toasts2.slice(indexOfExistingToast+1)]:[toast2,...toasts2]})})})}),[toasts]),React.useEffect(()=>{if(theme!=="system"){setActualTheme(theme);return}if(theme==="system"&&(window.matchMedia&&window.matchMedia("(prefers-color-scheme: dark)").matches?setActualTheme("dark"):setActualTheme("light")),typeof window>"u")return;const darkMediaQuery=window.matchMedia("(prefers-color-scheme: dark)");try{darkMediaQuery.addEventListener("change",({matches})=>{setActualTheme(matches?"dark":"light")})}catch{darkMediaQuery.addListener(({matches})=>{try{setActualTheme(matches?"dark":"light")}catch(e3){console.error(e3)}})}},[theme]),React.useEffect(()=>{toasts.length<=1&&setExpanded(!1)},[toasts]),React.useEffect(()=>{const handleKeyDown=__name(event=>{var _listRef_current;if(hotkey.every(key=>event[key]||event.code===key)){var _listRef_current1;setExpanded(!0),(_listRef_current1=listRef.current)==null||_listRef_current1.focus()}event.code==="Escape"&&(document.activeElement===listRef.current||(_listRef_current=listRef.current)!=null&&_listRef_current.contains(document.activeElement))&&setExpanded(!1)},"handleKeyDown");return document.addEventListener("keydown",handleKeyDown),()=>document.removeEventListener("keydown",handleKeyDown)},[hotkey]),React.useEffect(()=>{if(listRef.current)return()=>{lastFocusedElementRef.current&&(lastFocusedElementRef.current.focus({preventScroll:!0}),lastFocusedElementRef.current=null,isFocusWithinRef.current=!1)}},[listRef.current]),React.createElement("section",{ref,"aria-label":`${containerAriaLabel} ${hotkeyLabel}`,tabIndex:-1,"aria-live":"polite","aria-relevant":"additions text","aria-atomic":"false",suppressHydrationWarning:!0},possiblePositions.map((position3,index2)=>{var _heights_;const[y2,x2]=position3.split("-");return filteredToasts.length?React.createElement("ol",{key:position3,dir:dir==="auto"?getDocumentDirection():dir,tabIndex:-1,ref:listRef,className,"data-sonner-toaster":!0,"data-sonner-theme":actualTheme,"data-y-position":y2,"data-x-position":x2,style:{"--front-toast-height":`${((_heights_=heights[0])==null?void 0:_heights_.height)||0}px`,"--width":`${TOAST_WIDTH}px`,"--gap":`${gap}px`,...style2,...assignOffset(offset2,mobileOffset)},onBlur:__name(event=>{isFocusWithinRef.current&&!event.currentTarget.contains(event.relatedTarget)&&(isFocusWithinRef.current=!1,lastFocusedElementRef.current&&(lastFocusedElementRef.current.focus({preventScroll:!0}),lastFocusedElementRef.current=null))},"onBlur"),onFocus:__name(event=>{event.target instanceof HTMLElement&&event.target.dataset.dismissible==="false"||isFocusWithinRef.current||(isFocusWithinRef.current=!0,lastFocusedElementRef.current=event.relatedTarget)},"onFocus"),onMouseEnter:__name(()=>setExpanded(!0),"onMouseEnter"),onMouseMove:__name(()=>setExpanded(!0),"onMouseMove"),onMouseLeave:__name(()=>{interacting||setExpanded(!1)},"onMouseLeave"),onDragEnd:__name(()=>setExpanded(!1),"onDragEnd"),onPointerDown:__name(event=>{event.target instanceof HTMLElement&&event.target.dataset.dismissible==="false"||setInteracting(!0)},"onPointerDown"),onPointerUp:__name(()=>setInteracting(!1),"onPointerUp")},filteredToasts.filter(toast2=>!toast2.position&&index2===0||toast2.position===position3).map((toast2,index3)=>{var _toastOptions_duration,_toastOptions_closeButton;return React.createElement(Toast,{key:toast2.id,icons,index:index3,toast:toast2,defaultRichColors:richColors,duration:(_toastOptions_duration=toastOptions?.duration)!=null?_toastOptions_duration:duration,className:toastOptions?.className,descriptionClassName:toastOptions?.descriptionClassName,invert,visibleToasts,closeButton:(_toastOptions_closeButton=toastOptions?.closeButton)!=null?_toastOptions_closeButton:closeButton,interacting,position:position3,style:toastOptions?.style,unstyled:toastOptions?.unstyled,classNames:toastOptions?.classNames,cancelButtonStyle:toastOptions?.cancelButtonStyle,actionButtonStyle:toastOptions?.actionButtonStyle,closeButtonAriaLabel:toastOptions?.closeButtonAriaLabel,removeToast,toasts:filteredToasts.filter(t2=>t2.position==toast2.position),heights:heights.filter(h2=>h2.position==toast2.position),setHeights,expandByDefault:expand,gap,expanded,swipeDirections:props.swipeDirections})})):null}))},"Toaster")),Toaster2=__name(({...props})=>{const{theme="system"}=reactExports.useContext(ThemeProviderContext);return jsxRuntimeExports.jsx(Toaster$1,{theme,className:"toaster group",icons:{success:jsxRuntimeExports.jsx(CircleCheck,{className:"size-4"}),info:jsxRuntimeExports.jsx(Info$1,{className:"size-4"}),warning:jsxRuntimeExports.jsx(TriangleAlert,{className:"size-4"}),error:jsxRuntimeExports.jsx(OctagonX,{className:"size-4"}),loading:jsxRuntimeExports.jsx(LoaderCircle,{className:"size-4 animate-spin"})},toastOptions:{classNames:{toast:"bg-background text-foreground border-border"}},style:{"--normal-bg":"hsl(var(--background))","--normal-text":"hsl(var(--foreground))","--normal-border":"hsl(var(--border))","--border-radius":"var(--radius)","--toast-icon-margin-start":"0","--toast-icon-margin-end":"12px"},...props})},"Toaster");function useDemoToast(){reactExports.useEffect(()=>{if(reportData.IsDemo){let toastId;const timer=setTimeout(()=>{toastId=toast.warning(jsxRuntimeExports.jsxs("div",{className:"flex flex-col gap-2 w-full",children:[jsxRuntimeExports.jsx("div",{className:"font-semibold break-words",children:"Microsoft Zero Trust Assessment Demo Report"}),jsxRuntimeExports.jsxs("div",{className:"text-sm text-muted-foreground flex flex-col gap-1 break-words",children:[jsxRuntimeExports.jsxs("div",{className:"break-words",children:["This is a demo of the report generated by the"," ",jsxRuntimeExports.jsx("a",{href:"https://aka.ms/ZeroTrust/Assessment",target:"_blank",rel:"noopener noreferrer",className:"underline hover:text-primary break-all",onClick:__name(e3=>e3.stopPropagation(),"onClick"),children:"Zero Trust Assessment"})," ","tool."]}),jsxRuntimeExports.jsxs("div",{className:"break-words",children:["The latest version of this demo report is available at"," ",jsxRuntimeExports.jsx("a",{href:"https://aka.ms/ZeroTrust/Demo",target:"_blank",rel:"noopener noreferrer",className:"underline hover:text-primary break-all",onClick:__name(e3=>e3.stopPropagation(),"onClick"),children:"aka.ms/ZeroTrust/Demo"}),"."]})]})]}),{duration:1/0,closeButton:!0,style:{minWidth:"min(600px, calc(100vw - 32px))",maxWidth:"calc(100vw - 32px)"},className:"break-words"});const handleClick=__name(e3=>{const target=e3.target;target.tagName==="A"&&target.closest("[data-sonner-toast]")||(toast.dismiss(toastId),document.removeEventListener("click",handleClick))},"handleClick");setTimeout(()=>{document.addEventListener("click",handleClick)},100)},500);return()=>{clearTimeout(timer),toastId&&toast.dismiss(toastId)}}},[])}__name(useDemoToast,"useDemoToast");function App(){return useDemoToast(),jsxRuntimeExports.jsxs(ThemeProvider,{defaultTheme:"system",children:[jsxRuntimeExports.jsx(RouterProvider,{router}),jsxRuntimeExports.jsx(Toaster2,{position:"top-center",richColors:!0})]})}__name(App,"App");ReactDOM$2.createRoot(document.getElementById("root")).render(jsxRuntimeExports.jsx(React.StrictMode,{children:jsxRuntimeExports.jsx(App,{})})); +
- + From d9b193e95dffd6691887b996243db328a5e31548 Mon Sep 17 00:00:00 2001 From: Anton Staykov Date: Fri, 12 Jun 2026 22:56:50 +0200 Subject: [PATCH 2/4] Bump module version to 2.4.0 --- src/powershell/ZeroTrustAssessment.psd1 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/powershell/ZeroTrustAssessment.psd1 b/src/powershell/ZeroTrustAssessment.psd1 index 0a17db3b03..32452d3a6e 100644 --- a/src/powershell/ZeroTrustAssessment.psd1 +++ b/src/powershell/ZeroTrustAssessment.psd1 @@ -12,7 +12,7 @@ RootModule = 'ZeroTrustAssessment.psm1' # Version number of this module. -ModuleVersion = '2.3.0' +ModuleVersion = '2.4.0' # Supported PSEditions CompatiblePSEditions = 'Core', 'Desktop' From ccf3572afb59406e334cdffe6a581b385268ff6b Mon Sep 17 00:00:00 2001 From: alflokken <123625426+alflokken@users.noreply.github.com> Date: Wed, 17 Jun 2026 17:28:45 +0200 Subject: [PATCH 3/4] Perf: batch Graph requests in guest and privileged-role tests --- .../tests/Test-Assessment.21818.ps1 | 58 ++++++-------- .../tests/Test-Assessment.21868.ps1 | 79 +++++++++++-------- .../tests/Test-Assessment.21877.ps1 | 32 ++++---- 3 files changed, 86 insertions(+), 83 deletions(-) diff --git a/src/powershell/tests/Test-Assessment.21818.ps1 b/src/powershell/tests/Test-Assessment.21818.ps1 index 5de4625248..f4c72cf4f7 100644 --- a/src/powershell/tests/Test-Assessment.21818.ps1 +++ b/src/powershell/tests/Test-Assessment.21818.ps1 @@ -100,47 +100,37 @@ ORDER BY rd.displayName; } ) - $notificationRules = @() - # This flag is used to control the flow of a loop, allowing the script to break out of the outer loop when set to $true. - $exitLoop = $false - $passed = $true - - # Query activation notification rules for administrators - # For each policy ID, retrieve notification rules for role activation events sent to administrators + # Build one request per (policy, rule) pair and fetch them all in batched calls Write-ZtProgress -Activity $activity -Status "Getting activation notification rules" - foreach ($policyAssignment in $resultsPolicyAssignments) { - $policyId = $policyAssignment.policyId - $roleDisplayName = $policyAssignment.roleDisplayName - + $ruleRequests = foreach ($policyAssignment in $resultsPolicyAssignments) { foreach ($ruleId in $notifications.ruleId) { - try { - $uri = "policies/roleManagementPolicies/$policyId/rules/$ruleId" - - $rule = Invoke-ZtGraphRequest -RelativeUri $uri -ApiVersion 'v1.0' -ErrorAction Stop - - if ($rule) { - $notificationRules += ($rule | Add-Member -MemberType NoteProperty -Name RoleDisplayName -Value $roleDisplayName -Force -PassThru) - - # TO-DO: When the performance of the API is improved, we can collect all rules and move the check outside the loop to determine if the test passes or fails. - # Check if isDefaultRecipientsEnabled is false and notificationRecipients is an empty array - if ($rule.isDefaultRecipientsEnabled -eq $false -and - ($null -eq $rule.notificationRecipients -or $rule.notificationRecipients.Count -eq 0)) { - $passed = $false - $exitLoop = $true - break # Exit inner loop if condition is met - } - } - } - catch { - Write-Error "Failed to retrieve rule $ruleId for policy $($policyId): $($_.Exception.Message)" + [PSCustomObject]@{ + PolicyId = $policyAssignment.policyId + RuleId = $ruleId + RoleDisplayName = $policyAssignment.roleDisplayName } } - if ($exitLoop) { - break # Exit outer loop if condition is met + } + + $notificationRules = @() + if ($ruleRequests) { + $ruleResults = Invoke-ZtGraphBatchRequest -Path "policies/roleManagementPolicies/{0}/rules/{1}" -ArgumentList $ruleRequests -Properties PolicyId, RuleId -Matched -ErrorAction SilentlyContinue + foreach ($result in $ruleResults) { + if (-not $result.Success -or -not $result.Result) { continue } + $rule = $result.Result | Select-Object -First 1 + $notificationRules += ($rule | Add-Member -MemberType NoteProperty -Name RoleDisplayName -Value $result.Argument.RoleDisplayName -Force -PassThru) } } + # A role is non-compliant when a notification rule has default recipients disabled and no + # additional recipients configured. + $failingRule = $notificationRules | Where-Object { + $_.isDefaultRecipientsEnabled -eq $false -and + ($null -eq $_.notificationRecipients -or $_.notificationRecipients.Count -eq 0) + } | Select-Object -First 1 + $passed = -not $failingRule + $testResultMarkdown = "" # Output the result of the check @@ -148,7 +138,7 @@ ORDER BY rd.displayName; $testResultMarkdown += "Role notifications are properly configured for privileged role.`n`n%TestResult%" } else { - $testResultMarkdown += "Role notifications are not properly configured.`n`nNote: To save time, this check stops when it finds the first role that does not have notifications. After fixing this role and all other roles, we recommend running the check again to verify.`n`n%TestResult%" + $testResultMarkdown += "Role notifications are not properly configured.`n`n%TestResult%" } # Build the detailed sections of the markdown diff --git a/src/powershell/tests/Test-Assessment.21868.ps1 b/src/powershell/tests/Test-Assessment.21868.ps1 index ae3549b142..8c7d06c5ee 100644 --- a/src/powershell/tests/Test-Assessment.21868.ps1 +++ b/src/powershell/tests/Test-Assessment.21868.ps1 @@ -41,12 +41,6 @@ function Test-Assessment-21868 { $allApp = Invoke-DatabaseQuery -Database $Database -Sql $sqlApp $allSP = Invoke-DatabaseQuery -Database $Database -Sql $sqlSP - $queryParameters = '$select=id,displayName,userPrincipalName' - - # Initialize lists for guest owners only - $guestAppOwners = [System.Collections.Generic.List[object]]::new() - $guestSpOwners = [System.Collections.Generic.List[object]]::new() - # Get all guest users first (more efficient than repeated queries) $sqlGuests = @" SELECT id, userPrincipalName, displayName @@ -61,34 +55,13 @@ WHERE userType = 'Guest' [void]$guestUserIds.Add($guest.id) } - # Filter owners to only include guests - foreach ($app in $allApp) { - $owners = Invoke-ZtGraphRequest -RelativeUri "applications/$($app.id)/owners/microsoft.graph.user?$queryParameters" -ApiVersion 'v1.0' - if ($owners) { - foreach ($owner in $owners) { - $owner | Add-Member -MemberType NoteProperty -Name 'appDisplayName' -Value $app.displayName -Force -PassThru | - Add-Member -MemberType NoteProperty -Name 'appObjectId' -Value $app.id -Force -PassThru | - Add-Member -MemberType NoteProperty -Name 'appId' -Value $app.appId -Force - if ($guestUserIds.Contains($owner.id)) { - $guestAppOwners.Add($owner) - } - } - } - } + Write-ZtProgress -Activity $activity -Status "Getting application owners" + $guestAppOwners = @(Get-GuestResourceOwner -Resources $allApp -ResourceType 'applications' -GuestUserIds $guestUserIds ` + -DisplayNameProperty 'appDisplayName' -ObjectIdProperty 'appObjectId' -AppIdProperty 'appId') - foreach ($sp in $allSP) { - $owners = Invoke-ZtGraphRequest -RelativeUri "servicePrincipals/$($sp.id)/owners/microsoft.graph.user?$queryParameters" -ApiVersion 'v1.0' - if ($owners) { - foreach ($owner in $owners) { - $owner | Add-Member -MemberType NoteProperty -Name 'spDisplayName' -Value $sp.displayName -Force -PassThru | - Add-Member -MemberType NoteProperty -Name 'spObjectId' -Value $sp.id -Force -PassThru | - Add-Member -MemberType NoteProperty -Name 'spAppId' -Value $sp.appId -Force - if ($guestUserIds.Contains($owner.id)) { - $guestSpOwners.Add($owner) - } - } - } - } + Write-ZtProgress -Activity $activity -Status "Getting service principal owners" + $guestSpOwners = @(Get-GuestResourceOwner -Resources $allSP -ResourceType 'servicePrincipals' -GuestUserIds $guestUserIds ` + -DisplayNameProperty 'spDisplayName' -ObjectIdProperty 'spObjectId' -AppIdProperty 'spAppId') $hasGuestAppOwners = $guestAppOwners.Count -gt 0 $hasGuestSpOwners = $guestSpOwners.Count -gt 0 @@ -179,3 +152,43 @@ WHERE userType = 'Guest' Add-ZtTestResultDetail @params } + +function Get-GuestResourceOwner { + [CmdletBinding()] + param ( + [object[]] $Resources, + + [string] $ResourceType, + + [System.Collections.Generic.HashSet[string]] $GuestUserIds, + + [string] $DisplayNameProperty, + + [string] $ObjectIdProperty, + + [string] $AppIdProperty + ) + + $guestOwners = [System.Collections.Generic.List[object]]::new() + if (-not $Resources) { return $guestOwners } + + $resourceById = @{} + foreach ($resource in $Resources) { $resourceById[$resource.id] = $resource } + + $ownerPath = "$ResourceType/{0}/owners/microsoft.graph.user?`$select=id,displayName,userPrincipalName" + $ownerResults = Invoke-ZtGraphBatchRequest -Path $ownerPath -ArgumentList $Resources.id -Matched -ErrorAction SilentlyContinue + + foreach ($result in $ownerResults) { + if (-not $result.Success) { continue } + $resource = $resourceById[$result.Argument] + foreach ($owner in $result.Result) { + if (-not $GuestUserIds.Contains($owner.id)) { continue } + $owner | Add-Member -NotePropertyName $DisplayNameProperty -NotePropertyValue $resource.displayName -Force + $owner | Add-Member -NotePropertyName $ObjectIdProperty -NotePropertyValue $resource.id -Force + $owner | Add-Member -NotePropertyName $AppIdProperty -NotePropertyValue $resource.appId -Force + $guestOwners.Add($owner) + } + } + + return $guestOwners +} diff --git a/src/powershell/tests/Test-Assessment.21877.ps1 b/src/powershell/tests/Test-Assessment.21877.ps1 index 82eec56e51..eb0a4da524 100644 --- a/src/powershell/tests/Test-Assessment.21877.ps1 +++ b/src/powershell/tests/Test-Assessment.21877.ps1 @@ -62,23 +62,23 @@ WHERE userType = 'Guest' $guestsWithoutSponsors = [System.Collections.Generic.List[object]]::new() $guestsWithSponsorsCount = 0 - foreach ($guest in $guestUsers) { - try { - # Get the sponsors for the guest user - $guestUserWithSponsors = Invoke-ZtGraphRequest -RelativeUri "users/$($guest.id)?`$expand=sponsors" -ApiVersion 'v1.0' - - # Check if guest has sponsors - if ($guestUserWithSponsors.sponsors -and $guestUserWithSponsors.sponsors.Count -gt 0) { - $guestsWithSponsorsCount++ - } - else { - $guestsWithoutSponsors.Add($guestUserWithSponsors) - } + $guestById = @{} + foreach ($guest in $guestUsers) { $guestById[$guest.id] = $guest } + + $sponsorResults = Invoke-ZtGraphBatchRequest -Path "users/{0}?`$expand=sponsors" -ArgumentList $guestUsers.id -Matched -ErrorAction SilentlyContinue + + foreach ($result in $sponsorResults) { + if (-not $result.Success) { + $guestsWithoutSponsors.Add($guestById[$result.Argument]) + continue + } + + $guestUserWithSponsors = $result.Result | Select-Object -First 1 + if ($guestUserWithSponsors.sponsors -and $guestUserWithSponsors.sponsors.Count -gt 0) { + $guestsWithSponsorsCount++ } - catch { - Write-PSFMessage "Failed to get sponsors for guest $($guest.userPrincipalName): $($_.Exception.Message)" -Level Verbose - # Treat as guest without sponsor if API call fails - $guestsWithoutSponsors.Add($guest) + else { + $guestsWithoutSponsors.Add($guestUserWithSponsors) } } From 6c9118b08c69a57122562a58b23ef24dcc887f72 Mon Sep 17 00:00:00 2001 From: alflokken <123625426+alflokken@users.noreply.github.com> Date: Wed, 17 Jun 2026 18:23:16 +0200 Subject: [PATCH 4/4] Address review: null-safe sponsor list (21877); List accumulator (21818) --- .../tests/Test-Assessment.21818.ps1 | 4 ++-- .../tests/Test-Assessment.21877.ps1 | 24 +++++++------------ 2 files changed, 10 insertions(+), 18 deletions(-) diff --git a/src/powershell/tests/Test-Assessment.21818.ps1 b/src/powershell/tests/Test-Assessment.21818.ps1 index f4c72cf4f7..5824e381cf 100644 --- a/src/powershell/tests/Test-Assessment.21818.ps1 +++ b/src/powershell/tests/Test-Assessment.21818.ps1 @@ -113,13 +113,13 @@ ORDER BY rd.displayName; } } - $notificationRules = @() + $notificationRules = [System.Collections.Generic.List[object]]::new() if ($ruleRequests) { $ruleResults = Invoke-ZtGraphBatchRequest -Path "policies/roleManagementPolicies/{0}/rules/{1}" -ArgumentList $ruleRequests -Properties PolicyId, RuleId -Matched -ErrorAction SilentlyContinue foreach ($result in $ruleResults) { if (-not $result.Success -or -not $result.Result) { continue } $rule = $result.Result | Select-Object -First 1 - $notificationRules += ($rule | Add-Member -MemberType NoteProperty -Name RoleDisplayName -Value $result.Argument.RoleDisplayName -Force -PassThru) + $notificationRules.Add(($rule | Add-Member -MemberType NoteProperty -Name RoleDisplayName -Value $result.Argument.RoleDisplayName -Force -PassThru)) } } diff --git a/src/powershell/tests/Test-Assessment.21877.ps1 b/src/powershell/tests/Test-Assessment.21877.ps1 index eb0a4da524..a9a26ec194 100644 --- a/src/powershell/tests/Test-Assessment.21877.ps1 +++ b/src/powershell/tests/Test-Assessment.21877.ps1 @@ -58,30 +58,22 @@ WHERE userType = 'Guest' Write-ZtProgress -Activity $activity -Status "Checking sponsors for $totalGuestCount guest users" - # Process guests and check sponsors efficiently - $guestsWithoutSponsors = [System.Collections.Generic.List[object]]::new() - $guestsWithSponsorsCount = 0 - - $guestById = @{} - foreach ($guest in $guestUsers) { $guestById[$guest.id] = $guest } + # Collect the IDs of guests with a confirmed sponsor. Anything not confirmed (a failed or empty + # lookup) falls through to "without sponsor" by deriving that list from the original guest set. + $sponsoredIds = [System.Collections.Generic.HashSet[string]]::new() $sponsorResults = Invoke-ZtGraphBatchRequest -Path "users/{0}?`$expand=sponsors" -ArgumentList $guestUsers.id -Matched -ErrorAction SilentlyContinue foreach ($result in $sponsorResults) { - if (-not $result.Success) { - $guestsWithoutSponsors.Add($guestById[$result.Argument]) - continue - } - + if (-not $result.Success) { continue } $guestUserWithSponsors = $result.Result | Select-Object -First 1 - if ($guestUserWithSponsors.sponsors -and $guestUserWithSponsors.sponsors.Count -gt 0) { - $guestsWithSponsorsCount++ - } - else { - $guestsWithoutSponsors.Add($guestUserWithSponsors) + if ($guestUserWithSponsors.sponsors.Count -gt 0) { + [void]$sponsoredIds.Add($guestUserWithSponsors.id) } } + $guestsWithSponsorsCount = $sponsoredIds.Count + $guestsWithoutSponsors = @($guestUsers | Where-Object { -not $sponsoredIds.Contains($_.id) }) $guestsWithoutSponsorsCount = $guestsWithoutSponsors.Count $passed = $guestsWithoutSponsorsCount -eq 0