@nice2dev/ui-security 1.1.10 → 1.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +70 -0
- package/README.md +0 -6
- package/dist/index.cjs +2 -2
- package/dist/index.mjs +6 -6
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,75 @@
|
|
|
1
1
|
# @nice2dev/ui-security — Changelog
|
|
2
2
|
|
|
3
|
+
## 1.2.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- 3a4939d: 1.2.0 — the API cleanup announced for this version, dictionaries per language by default, and
|
|
8
|
+
three new controls. **Breaking:** every removal has a replacement, listed name by name in
|
|
9
|
+
`documentation/omniverk/OMNIVERK_UPGRADE_1.2.0.md`.
|
|
10
|
+
|
|
11
|
+
**Removed (breaking).** All 118 `@deprecated` names: the aliases without the `Nice` prefix in
|
|
12
|
+
`ui-audio`, `ui-graphics` and `ui-3d`; `NiceBarcodeGenerator` (→ `NiceBarcode`), `NiceFloorPlanCanvas`
|
|
13
|
+
(→ `NiceSpatialEditor` in `@nice2dev/ui-buildings`), the v2 props and types of `NiceTopNav`,
|
|
14
|
+
`NiceProgress.showLabel`, `NiceCountryPicker.showDialCode` / `showFlag`, `type` on
|
|
15
|
+
`NiceDateTimePicker` / `NiceDateRangeBox` (→ `dateFormatPreset`); `ZoneOccupancy` in
|
|
16
|
+
`ui-buildings` and `events`, the `SmartHome*` types; the icon variant `flat` (→ `cutout`) and
|
|
17
|
+
`NiceIconEditor` (→ `NiceVectorEditor`); `NiceSizeLegacy`; the `snapGrid` module of `ui-diagrams` (→
|
|
18
|
+
`@nice2dev/spatial-core`); the opt-in stylesheet `@nice2dev/ui/css/legacy-bg-text-aliases.css`, which
|
|
19
|
+
formed an alias cycle with `style.css`. Props that were accepted and never read — 19 on
|
|
20
|
+
`NiceModuleGrid`, and more on `NiceAutocomplete`, `NiceTaskInbox`, `NiceConsentBanner`, the
|
|
21
|
+
building and communication controls, four `ui-audio` panels and `NiceStreamDashboard` — are gone
|
|
22
|
+
from the types. `NiceResourceAllocation` in `ui-erp` is `NiceCapacityPlanner` (the one in `ui`
|
|
23
|
+
keeps its name); `NiceGenericPlayerStageVisualizer` (→ `NiceStageVisualizer`) and
|
|
24
|
+
`NiceCubeBrowserProps` are removed. The `@nice2dev/ui/overlays` entry calls its modal, drawer,
|
|
25
|
+
bottom sheet and context menu `NiceOverlayModal`, `NiceOverlayDrawer`, `NiceOverlayBottomSheet` and
|
|
26
|
+
`NiceOverlayContextMenu`: the old names belonged to different components of `@nice2dev/ui`.
|
|
27
|
+
|
|
28
|
+
**Dictionaries per language.** `NiceI18nProvider` loads only the language in use, with `import()`
|
|
29
|
+
(it was `NiceI18nLazyProvider` in 1.1.10, which stays as the same component); the controls show their
|
|
30
|
+
built-in English until it arrives — `await loadNiceDictionary(lang)` before the first render to start
|
|
31
|
+
in the language. Nothing on the main entry of `@nice2dev/i18n` imports a dictionary any more:
|
|
32
|
+
`NICE_I18N_DICTIONARIES`, `createTranslator`, `NICE_I18N_VARIANTS` / `resolvePlVariant` and the
|
|
33
|
+
translation tooling moved to the new entry `@nice2dev/i18n/all`, and `@nice2dev/ui-core` no longer
|
|
34
|
+
re-exports the dictionary map. `@nice2dev/ui` with what it bundles: 1283 kB → 952 kB gzip loaded up
|
|
35
|
+
front. The `ui-audio` controls read the app's `NiceI18nProvider` now; their own provider overrides it.
|
|
36
|
+
|
|
37
|
+
**New controls.** `NiceRecurrenceEditor`, `NiceStopwatch`, `NiceCountdownTimer` (`@nice2dev/ui`) and
|
|
38
|
+
`NicePasswordGenerator` (`@nice2dev/auth`), plus `recurrenceDates()` and `generatePassword()`.
|
|
39
|
+
`NiceScheduler` honours a weekly rule's `byDay`, which it ignored.
|
|
40
|
+
|
|
41
|
+
**Visible changes.** The palette meets WCAG AA for text on every fill: darker fills in the light
|
|
42
|
+
theme, dark text on the fills of the dark theme (new `--nice-text-on-success` / `-error` / `-info` /
|
|
43
|
+
`-accent` / `-warning`; `NiceThemeText` takes `onSuccess`, `onError`, `onInfo`, `onWarning`). Mobile
|
|
44
|
+
and platform panels follow the app theme instead of `prefers-color-scheme`. Swipes in
|
|
45
|
+
`NiceSwipeActions`, `NiceTouchTable` and `NiceMobileCalendar` work with a mouse and a pen. The
|
|
46
|
+
`ui-forms` editors have the intended spacing (it was four times too large). `NiceMAM`,
|
|
47
|
+
`NiceTranscoder`, `NiceVideoAnnotator` and `NiceStreamDashboard` use `nice-`-prefixed BEM classes.
|
|
48
|
+
|
|
49
|
+
**Fixes.** Controls that invented results ask the host instead: `NiceIntegrationHub`,
|
|
50
|
+
`NiceMLStudio` (`onExperimentRun` may return metrics), `NiceRemoteManagement`
|
|
51
|
+
(`onCaptureScreenshot`), `NicePoseDetector` (`detector`), `NiceBatchScannerProvider`,
|
|
52
|
+
`NiceCacheStrategies`; `NiceLowCodeStudio` accepts dropped components. Controls that did nothing
|
|
53
|
+
work or say why they are off: `NiceStreamDashboard` adds sources, sends chat and runs the chosen
|
|
54
|
+
transition (new `onAddPlatform`, `onSendChatMessage`, `onTransition`, `onScreenshot`,
|
|
55
|
+
`onOpenAudioMixer`, `onOpenSettings`; `receiveChatMessage` feeds incoming chat), `NiceMLStudio`
|
|
56
|
+
downloads through `onModelDownload`, `NiceETLBuilder` saves through `onSave` (its Save button had
|
|
57
|
+
no handler), `NiceTranscoder` makes jobs of picked and dropped files, `NiceAutomationEditor` offers
|
|
58
|
+
the trigger types its model has. Texts of about fifty components go
|
|
59
|
+
through `t()` in six languages, among them the AI data grid, chart and form builders, the ML
|
|
60
|
+
studio, the report designer, the song picker, `NiceProtocolConfig`, `NiceETLBuilder` and
|
|
61
|
+
`NiceInlineHelp` — every key the controls pass to `t()` now has a dictionary entry, so none of
|
|
62
|
+
them stays English under another language; `NiceDataGridAI` sorts on a query in any language, not
|
|
63
|
+
only in English. `NiceWindow`, `NiceConsole`, `NiceFileManager` and `NiceGitManager` no longer
|
|
64
|
+
crash when `accessMode` switches to or from `'hidden'`. Ids come from `createId()` (`@nice2dev/ui-core`), so nothing throws
|
|
65
|
+
outside a secure context as `crypto.randomUUID()` did on plain http. `ui-3d` runs on three r183
|
|
66
|
+
without its deprecation warnings. `NiceRemoteManagement` calls the handlers of the latest render.
|
|
67
|
+
The AI hint popover and the `ui-platform` panels follow the app theme, not the system's or a
|
|
68
|
+
`.dark` class on the host. `NiceCommandPalette` has styles and its search filters;
|
|
69
|
+
`NiceTimeoutFeedback` starts its clock; `NiceOfflineBanner` takes `online`; Monaco's workers in
|
|
70
|
+
`NiceCodeEditor` load; the `ui-audio` panels that used Bootstrap classes use Nice controls; colours
|
|
71
|
+
that reached a canvas as `var(…)` (karaoke lanes and notes) are resolved first.
|
|
72
|
+
|
|
3
73
|
## 1.1.10
|
|
4
74
|
|
|
5
75
|
### Patch Changes
|
package/README.md
CHANGED
|
@@ -29,12 +29,6 @@ This package ships unstyled component logic. Import the shared CSS bundle once a
|
|
|
29
29
|
import '@nice2dev/ui/style.css';
|
|
30
30
|
```
|
|
31
31
|
|
|
32
|
-
Optional: opt into the legacy shorthand token aliases (`--bg-*`, `--text-*`, `--border-*`, ...) when migrating from a custom design-token system:
|
|
33
|
-
|
|
34
|
-
```tsx
|
|
35
|
-
import '@nice2dev/ui/css/legacy-bg-text-aliases.css';
|
|
36
|
-
```
|
|
37
|
-
|
|
38
32
|
## License
|
|
39
33
|
|
|
40
34
|
MIT © NiceToDev
|
package/dist/index.cjs
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const n=require("react/jsx-runtime"),h=require("react"),Oe={low:.7,medium:.8,high:.85,critical:.95},qe={matchThreshold:.85,timeout:3e4,maxRetries:3,livenessDetection:!0,verifyEndpoint:"",authToken:"",showFeedback:!0,hapticFeedback:!0,locale:"en",securityLevel:"high",antiSpoofing:!0};function oe(e){const t={...qe,...e};return e!=null&&e.matchThreshold||(t.matchThreshold=Oe[t.securityLevel]),t}async function ce(e){const t=new TextEncoder().encode(e),r=await crypto.subtle.digest("SHA-256",t);return Array.from(new Uint8Array(r)).map(s=>s.toString(16).padStart(2,"0")).join("")}function de(e=8){const t=new Uint8Array(e);return crypto.getRandomValues(t),Array.from(t).map(r=>r.toString(36).padStart(2,"0")).join("").slice(0,e)}function Ke(e){const t=new Uint32Array(1);return crypto.getRandomValues(t),t[0]%e}function Ge(e,t){return Math.sqrt((e.x-t.x)**2+(e.y-t.y)**2)}async function le(e="user"){return navigator.mediaDevices.getUserMedia({video:{facingMode:e,width:{ideal:1280},height:{ideal:720}},audio:!1})}function se(e,t,r){const s=t??e.videoWidth,a=r??e.videoHeight,i=document.createElement("canvas");i.width=s,i.height=a;const o=i.getContext("2d");o.drawImage(e,0,0,s,a);const c=o.getImageData(0,0,s,a);return{canvas:i,ctx:o,imageData:c}}function ne(e){const t=new Uint8Array(e.width*e.height),r=e.data;for(let s=0;s<t.length;s++){const a=s*4;t[s]=Math.round(.299*r[a]+.587*r[a+1]+.114*r[a+2])}return t}function Ae(e,t,r){const s=new Uint8Array(t*r),a=[1,2,1,2,4,2,1,2,1],i=16;for(let o=1;o<r-1;o++)for(let c=1;c<t-1;c++){let m=0,x=0;for(let y=-1;y<=1;y++)for(let v=-1;v<=1;v++)m+=e[(o+y)*t+(c+v)]*a[x++];s[o*t+c]=Math.round(m/i)}return s}function Je(e,t,r){const s=new Uint8Array(t*r);for(let a=1;a<r-1;a++)for(let i=1;i<t-1;i++){const o=-e[(a-1)*t+(i-1)]+e[(a-1)*t+(i+1)]+-2*e[a*t+(i-1)]+2*e[a*t+(i+1)]+-e[(a+1)*t+(i-1)]+e[(a+1)*t+(i+1)],c=-e[(a-1)*t+(i-1)]-2*e[(a-1)*t+i]-e[(a-1)*t+(i+1)]+e[(a+1)*t+(i-1)]+2*e[(a+1)*t+i]+e[(a+1)*t+(i+1)];s[a*t+i]=Math.min(255,Math.round(Math.sqrt(o*o+c*c)))}return s}function Ye(e){const t=new Array(256).fill(0);for(const x of e)t[x]++;const r=e.length;let s=0;for(let x=0;x<256;x++)s+=x*t[x];let a=0,i=0,o=0,c=0;for(let x=0;x<256;x++){if(i+=t[x],i===0)continue;const y=r-i;if(y===0)break;a+=x*t[x];const v=a/i,A=(s-a)/y,p=i*y*(v-A)**2;p>o&&(o=p,c=x)}const m=new Uint8Array(e.length);for(let x=0;x<e.length;x++)m[x]=e[x]>c?255:0;return{threshold:c,binary:m}}function je(e,t=.3){var g;const r=e.width,s=e.height,a=ne(e),i=Ae(a,r,s),o=Je(i,r,s),{binary:c}=Ye(o),m=[],x=[],y=[];for(let k=2;k<s-2;k++)for(let u=2;u<r-2;u++){if(c[k*r+u]===0)continue;const S=[c[(k-1)*r+u],c[(k-1)*r+(u+1)],c[k*r+(u+1)],c[(k+1)*r+(u+1)],c[(k+1)*r+u],c[(k+1)*r+(u-1)],c[k*r+(u-1)],c[(k-1)*r+(u-1)]];let l=0;for(let B=0;B<8;B++){const H=S[B]>0?1:0,K=S[(B+1)%8]>0?1:0;l+=Math.abs(H-K)}l/=2;let f=0,z=0;for(let B=-2;B<=2;B++)for(let H=-2;H<=2;H++)f+=o[(k+B)*r+(u+H)],z++;const O=f/z/255;if(O<t)continue;const G=Math.atan2(a[(k+1)*r+u]-a[(k-1)*r+u],a[k*r+(u+1)]-a[k*r+(u-1)]);l===1?m.push({x:u/r,y:k/s,angle:G,type:"ending",quality:O}):l===3&&m.push({x:u/r,y:k/s,angle:G,type:"bifurcation",quality:O})}m.sort((k,u)=>u.quality-k.quality);const v=m.slice(0,120);if(v.length>5){const k=v.reduce((S,l)=>S+l.x,0)/v.length,u=v.reduce((S,l)=>S+l.y,0)/v.length;x.push({x:k,y:u})}const A=v.length,p=v.filter(k=>k.type==="ending").length,D=v.filter(k=>k.type==="bifurcation").length/(p+1);let b="loop-right";D>1.5?b="whorl":D<.5?b="arch":((g=x[0])==null?void 0:g.x)<.45&&(b="loop-left");const T=v.length>20?v.reduce((k,u)=>k+u.quality,0)/v.length:0;return{minutiae:v,corePoints:x,deltaPoints:y,ridgeCount:A,patternType:b,quality:T}}function Te(e,t){if(e.minutiae.length<5||t.minutiae.length<5)return 0;let r=0;const s=.05,a=.5,i=new Set;for(const c of e.minutiae){let m=1/0,x=-1;for(let y=0;y<t.minutiae.length;y++){if(i.has(y))continue;const v=t.minutiae[y];if(c.type!==v.type)continue;const A=Ge(c,v),p=Math.abs(c.angle-v.angle);A<s&&p<a&&A<m&&(m=A,x=y)}x>=0&&(r++,i.add(x))}const o=Math.min(e.minutiae.length,t.minutiae.length);return o>0?r/o:0}async function Ce(e,t){const r=JSON.stringify(e),s=await ce(r);return{id:`fp_${Date.now()}_${de()}`,method:"fingerprint",templateData:btoa(r),enrolled:Date.now(),label:t,hash:s}}function Ie(e){return JSON.parse(atob(e.templateData))}function Re(e,t="left"){const r=e.width,s=e.height,a=ne(e),i=Ae(a,r,s);let o={cx:r/2,cy:s/2,r:Math.min(r,s)*.08,score:1/0};for(let I=Math.round(s*.3);I<Math.round(s*.7);I+=2)for(let D=Math.round(r*.3);D<Math.round(r*.7);D+=2)for(let b=Math.round(Math.min(r,s)*.04);b<Math.round(Math.min(r,s)*.15);b+=2){let T=0,g=0;for(let l=0;l<Math.PI*2;l+=.3){const f=Math.round(D+b*Math.cos(l)),z=Math.round(I+b*Math.sin(l));f>=0&&f<r&&z>=0&&z<s&&(T+=i[z*r+f],g++)}const k=g>0?T/g:255,u=i[I*r+D],S=k*.5+u*.5;S<o.score&&(o={cx:D,cy:I,r:b,score:S})}const c=o.r*3,m={cx:o.cx,cy:o.cy,r:Math.min(c,Math.min(r,s)*.4)},x=256,y=[];for(let I=0;I<x;I++){const D=I/x*Math.PI*2,b=o.r+(m.r-o.r)*.5,T=Math.round(o.cx+b*Math.cos(D)),g=Math.round(o.cy+b*Math.sin(D));if(T>=0&&T<r&&g>=0&&g<s){const k=Math.round(o.cx+b*Math.cos(D+.1)),u=Math.round(o.cy+b*Math.sin(D+.1)),S=i[g*r+T],l=k>=0&&k<r&&u>=0&&u<s?i[u*r+k]:S;y.push(S>l?1:0)}else y.push(0)}const v=y.join(""),A=Math.PI*o.r**2,p=Math.min(1,Math.max(0,A/(r*s)*100));return{irisCode:v,pupil:o,iris:m,quality:p,eye:t}}function De(e,t){if(!e.irisCode||!t.irisCode)return 0;const r=Math.min(e.irisCode.length,t.irisCode.length);if(r===0)return 0;let s=0,a=r;for(let o=-8;o<=8;o++){let c=0;for(let m=0;m<r;m++){const x=(m+o+r)%r;e.irisCode[m]!==t.irisCode[x]&&c++}c<a&&(a=c)}s=a;const i=s/r;return Math.max(0,1-i*2.5)}async function Me(e,t){const r=JSON.stringify(e),s=await ce(r);return{id:`iris_${Date.now()}_${de()}`,method:"iris",templateData:btoa(r),enrolled:Date.now(),label:t,hash:s}}function Pe(e){return JSON.parse(atob(e.templateData))}function ae(e){const t=e.width,r=e.height,s=e.data,a=new Uint8Array(t*r);for(let u=0;u<t*r;u++){const S=u*4,l=s[S],f=s[S+1],z=s[S+2],O=.299*l+.587*f+.114*z,G=128-.169*l-.331*f+.5*z,B=128+.5*l-.419*f-.081*z;G>=77&&G<=127&&B>=133&&B<=173&&O>80&&(a[u]=1)}let i=t,o=r,c=0,m=0,x=0;for(let u=0;u<r;u++)for(let S=0;S<t;S++)a[u*t+S]&&(x++,S<i&&(i=S),S>c&&(c=S),u<o&&(o=u),u>m&&(m=u));const y=c-i,v=m-o;if(y<t*.1||v<r*.1)return null;const A={x:i,y:o,width:y,height:v},p=[],I=ne(e),D=Math.max(1,Math.floor(y/8)),b=Math.max(1,Math.floor(v/16));for(let u=0;u<16;u++)for(let S=0;S<8;S++){const l=i+S*D+Math.floor(D/2),f=o+u*b+Math.floor(b/2);l<t&&f<r?p.push(I[f*t+l]/255):p.push(0)}const T=[],g={x:i+y/2,y:o+v/2};for(let u=0;u<68;u++){const S=u/68*Math.PI*2,l=y*.4*Math.cos(S),f=v*.45*Math.sin(S);T.push({x:(g.x+l)/t,y:(g.y+f)/r})}const k=Math.min(1,x/(y*v)*2);return{embedding:p,boundingBox:A,landmarks:T,headPose:{yaw:0,pitch:0,roll:0},quality:k}}function he(e,t){if(e.embedding.length!==t.embedding.length)return 0;let r=0,s=0,a=0;for(let o=0;o<e.embedding.length;o++)r+=e.embedding[o]*t.embedding[o],s+=e.embedding[o]**2,a+=t.embedding[o]**2;const i=Math.sqrt(s)*Math.sqrt(a);return i>0?(r/i+1)/2:0}function Ee(e,t){const r=ae(e),s=ae(t);return!r||!s?{similarity:0,cameraFeatures:r,refFeatures:s}:{similarity:he(r,s),cameraFeatures:r,refFeatures:s}}async function Fe(e,t){const r=JSON.stringify(e),s=await ce(r);return{id:`face_${Date.now()}_${de()}`,method:"face",templateData:btoa(r),enrolled:Date.now(),label:t,hash:s}}function Ne(e){return JSON.parse(atob(e.templateData))}function Ze(){const e=["blink","smile","turn-left","turn-right","nod","raise-eyebrows"],t=e[Ke(e.length)];return{type:t,instruction:{blink:"Please blink your eyes",smile:"Please smile","turn-left":"Please turn your head left","turn-right":"Please turn your head right",nod:"Please nod your head","raise-eyebrows":"Please raise your eyebrows"}[t],completed:!1,confidence:0}}function fe(e,t=.02){if(e.length<2)return{isLive:!1,confidence:0,motionScore:0};let r=0;for(let o=1;o<e.length;o++){const c=ne(e[o-1]),m=ne(e[o]);let x=0;for(let y=0;y<c.length;y++)x+=Math.abs(c[y]-m[y]);r+=x/(c.length*255)}const s=r/(e.length-1),a=s>t,i=Math.min(1,s/(t*3));return{isLive:a,confidence:i,motionScore:s}}function ye(){return{userAgent:navigator.userAgent,platform:navigator.platform,language:navigator.language,screenResolution:[screen.width,screen.height],timezone:Intl.DateTimeFormat().resolvedOptions().timeZone,touchSupport:"ontouchstart"in window||navigator.maxTouchPoints>0,hardwareConcurrency:navigator.hardwareConcurrency??0}}async function ie(){const e=ye(),t=JSON.stringify(e);return ce(t)}function pe(){return typeof window<"u"&&!!window.PublicKeyCredential}async function ze(){if(!pe())return!1;try{return await PublicKeyCredential.isUserVerifyingPlatformAuthenticatorAvailable()}catch{return!1}}async function Le(e){const t={rp:{name:e.rpName,id:e.rpId},user:{id:new TextEncoder().encode(e.userId),name:e.userName,displayName:e.userDisplayName},challenge:e.challenge,pubKeyCredParams:[{alg:-7,type:"public-key"},{alg:-257,type:"public-key"}],authenticatorSelection:{authenticatorAttachment:"platform",userVerification:"required",residentKey:"preferred"},timeout:e.timeout??6e4,attestation:"none"};return await navigator.credentials.create({publicKey:t})}async function $e(e){const t={rpId:e.rpId,challenge:e.challenge,allowCredentials:e.allowCredentials,userVerification:"required",timeout:e.timeout??6e4};return await navigator.credentials.get({publicKey:t})}async function ue(e,t,r){const s={"Content-Type":"application/json"};r&&(s.Authorization=`Bearer ${r}`);const a=await fetch(e,{method:"POST",headers:s,body:JSON.stringify(t)});return a.ok?a.json():{verified:!1,message:`Server error: ${a.status}`}}function V(e,t){var o;const r=e.trim().match(/^var\(\s*([^,\s)]+)\s*(?:,\s*(.+))?\)$/);if(!r)return e;const s=(o=r[2])==null?void 0:o.trim();if(typeof document>"u"||typeof getComputedStyle>"u")return s?V(s):e;const a=typeof Element<"u"&&t instanceof Element&&t.isConnected?t:document.documentElement,i=getComputedStyle(a).getPropertyValue(r[1]).trim();return i||(s?V(s,t):e)}const Xe=(e,t)=>t,Be=h.createContext(Xe),Qe=({t:e,children:t})=>n.jsx(Be.Provider,{value:e,children:t});function Q(){return{t:h.useContext(Be)}}const Ve={sm:200,md:280,lg:380},et=e=>{const{mode:t,enrolledTemplates:r=[],fingerPosition:s="right-index",onEnroll:a,onVerify:i,onStatusChange:o,onError:c,className:m,size:x="md",label:y,showQuality:v=!0,showMinutiae:A=!1,instructionText:p,cameraFacing:I="environment",...D}=e,{t:b}=Q(),T=oe(D),g=Ve[x],k=h.useRef(null),u=h.useRef(null),S=h.useRef(null),[l,f]=h.useState("idle"),[z,O]=h.useState(0),[G,B]=h.useState(null),[H,K]=h.useState(0),[_,L]=h.useState(""),$=h.useCallback(P=>{f(P),o==null||o(P)},[o]),E=h.useCallback(async()=>{try{const P=await le(I);S.current=P,k.current&&(k.current.srcObject=P,await k.current.play()),$("idle"),L(b("security.fingerprint.placeFingerPrompt","Place your finger on the scanner"))}catch(P){c==null||c(P instanceof Error?P:new Error(String(P))),L(b("security.fingerprint.cameraError","Camera access denied")),$("error")}},[I,b,$,c]),q=h.useCallback(()=>{var P;(P=S.current)==null||P.getTracks().forEach(R=>R.stop()),S.current=null},[]);h.useEffect(()=>(E(),q),[E,q]);const W=h.useCallback(async()=>{if(!(!k.current||l==="processing"||l==="success")){$("scanning"),L(b("security.fingerprint.scanning","Scanning…"));try{const{imageData:P}=se(k.current);$("processing"),L(b("security.fingerprint.processing","Processing fingerprint…"));const R=je(P);if(B(R),O(R.quality),R.quality<.2){L(b("security.fingerprint.lowQuality","Low quality — try again")),$("idle");return}if(t==="enroll"){const F=await Ce(R,y??s);a==null||a(F,R),L(b("security.fingerprint.enrolled","Fingerprint enrolled successfully")),$("success")}else{let F=0;for(const d of r){const j=Ie(d),N=Te(R,j);N>F&&(F=N)}const C=F>=T.matchThreshold,w={success:C,confidence:F,method:"fingerprint",timestamp:Date.now(),duration:0,payload:btoa(JSON.stringify(R))};if(C&&T.verifyEndpoint){const d=await ie(),j=await ue(T.verifyEndpoint,{method:"fingerprint",templateData:w.payload,matchScore:F,deviceFingerprint:d},T.authToken);w.success=j.verified}w.success?(L(b("security.fingerprint.verified","Fingerprint verified")),$("success")):(K(d=>d+1),H+1>=T.maxRetries?(L(b("security.fingerprint.maxAttempts","Maximum attempts reached")),$("failure")):(L(b("security.fingerprint.noMatch","No match — try again")),$("idle"))),i==null||i(w)}}catch(P){c==null||c(P instanceof Error?P:new Error(String(P))),L(b("security.fingerprint.error","Scan error — try again")),$("error")}}},[l,t,r,T,b,$,a,i,c,y,s,H]);h.useEffect(()=>{if(!A||!G||!u.current)return;const P=u.current.getContext("2d");if(!P)return;P.clearRect(0,0,g,g);const R=V("var(--nice-success, #10b981)",P.canvas),F=V("var(--nice-warning, #f59e0b)",P.canvas);G.minutiae.forEach(C=>{P.beginPath(),P.arc(C.x*g,C.y*g,2,0,Math.PI*2),P.fillStyle=C.type==="ending"?R:F,P.fill(),P.beginPath(),P.moveTo(C.x*g,C.y*g),P.lineTo(C.x*g+Math.cos(C.angle)*8,C.y*g+Math.sin(C.angle)*8),P.strokeStyle=P.fillStyle,P.lineWidth=1,P.stroke()})},[G,A,g]);const Z=l==="success"?"var(--security-success)":l==="failure"||l==="error"?"var(--security-error)":l==="scanning"||l==="processing"?"var(--security-biometric)":"var(--security-border)";return n.jsxs("div",{className:m,style:{display:"inline-flex",flexDirection:"column",alignItems:"center",gap:12},children:[y&&n.jsx("div",{style:{fontSize:14,fontWeight:600,color:"var(--security-text)"},children:y}),n.jsxs("div",{style:{width:g,height:g,position:"relative",borderRadius:"var(--security-radius-lg)",overflow:"hidden",border:`3px solid ${Z}`,boxShadow:l==="scanning"?`0 0 20px ${Z}`:"var(--security-shadow)",transition:"border-color 0.3s, box-shadow 0.3s"},children:[n.jsx("video",{ref:k,style:{width:"100%",height:"100%",objectFit:"cover"},playsInline:!0,muted:!0}),A&&n.jsx("canvas",{ref:u,width:g,height:g,style:{position:"absolute",inset:0,pointerEvents:"none"}}),n.jsxs("svg",{viewBox:"0 0 100 100",style:{position:"absolute",inset:0,width:"100%",height:"100%",pointerEvents:"none",opacity:.3},children:[n.jsx("ellipse",{cx:"50",cy:"50",rx:"28",ry:"38",fill:"none",stroke:"white",strokeWidth:"1",strokeDasharray:"4 3"}),n.jsx("ellipse",{cx:"50",cy:"50",rx:"20",ry:"28",fill:"none",stroke:"white",strokeWidth:"0.5",strokeDasharray:"2 3"})]}),(l==="scanning"||l==="processing")&&n.jsx("div",{style:{position:"absolute",inset:0,display:"flex",alignItems:"center",justifyContent:"center",background:"var(--nice-overlay-30, rgba(0, 0, 0, 0.3))"},children:n.jsx("div",{style:{width:60,height:60,borderRadius:"50%",border:"3px solid transparent",borderTopColor:Z,animation:"spin 0.8s linear infinite"}})})]}),v&&z>0&&n.jsx("div",{style:{width:g,height:4,background:"var(--security-bg-panel)",borderRadius:2,overflow:"hidden"},children:n.jsx("div",{style:{width:`${z*100}%`,height:"100%",background:z>.6?"var(--security-success)":z>.3?"var(--security-warning)":"var(--security-error)",transition:"width 0.3s"}})}),n.jsx("div",{style:{fontSize:13,color:"var(--security-text-secondary)",textAlign:"center",minHeight:20},children:p??_}),l!=="success"&&l!=="failure"&&n.jsx("button",{onClick:W,disabled:l==="scanning"||l==="processing",style:{padding:"10px 24px",fontSize:14,fontWeight:600,background:"var(--security-biometric)",color:"var(--nice-text-on-primary, #fff)",border:"none",borderRadius:"var(--security-radius)",cursor:"pointer",opacity:l==="scanning"||l==="processing"?.6:1},children:t==="enroll"?b("security.fingerprint.captureBtn","Capture Fingerprint"):b("security.fingerprint.verifyBtn","Verify Fingerprint")}),(l==="failure"||l==="error")&&n.jsx("button",{onClick:()=>{K(0),$("idle"),L("")},style:{padding:"8px 20px",fontSize:13,background:"var(--security-bg-panel)",color:"var(--security-text)",border:"1px solid var(--security-border)",borderRadius:"var(--security-radius)",cursor:"pointer"},children:b("security.common.retry","Try Again")}),n.jsx("style",{children:"@keyframes spin { to { transform: rotate(360deg); } }"})]})},tt={sm:220,md:300,lg:400},rt=e=>{const{mode:t,enrolledTemplates:r=[],eye:s="right",onEnroll:a,onVerify:i,onStatusChange:o,onError:c,className:m,size:x="md",label:y,showQuality:v=!0,showSegmentation:A=!0,showGuide:p=!0,instructionText:I,...D}=e,{t:b}=Q(),T=oe(D),g=tt[x],k=h.useRef(null),u=h.useRef(null),S=h.useRef(null),l=h.useRef([]),[f,z]=h.useState("idle"),[O,G]=h.useState(0),[B,H]=h.useState(null),[K,_]=h.useState(0),[L,$]=h.useState(""),E=h.useCallback(R=>{z(R),o==null||o(R)},[o]),q=h.useCallback(async()=>{try{const R=await le("user");S.current=R,k.current&&(k.current.srcObject=R,await k.current.play()),E("idle"),$(b("security.iris.alignEyePrompt","Align your eye with the circle"))}catch(R){c==null||c(R instanceof Error?R:new Error(String(R))),$(b("security.iris.cameraError","Camera access denied")),E("error")}},[b,E,c]),W=h.useCallback(()=>{var R;(R=S.current)==null||R.getTracks().forEach(F=>F.stop()),S.current=null},[]);h.useEffect(()=>(q(),W),[q,W]);const Z=h.useCallback(async()=>{if(!(!k.current||f==="processing"||f==="success")){E("scanning"),$(b("security.iris.scanning","Scanning iris…"));try{const R=[];for(let w=0;w<5;w++){const{imageData:d}=se(k.current);R.push(d),await new Promise(j=>setTimeout(j,200))}if(l.current=R,T.livenessDetection&&!fe(R).isLive){$(b("security.iris.notLive","Liveness check failed — please blink or move slightly")),E("idle");return}E("processing"),$(b("security.iris.processing","Processing iris pattern…"));const F=R[R.length-1],C=Re(F,s==="both"?"left":s);if(!C){$(b("security.iris.noIrisDetected","No iris detected — adjust position")),E("idle");return}if(H(C),G(C.quality),C.quality<.1){$(b("security.iris.lowQuality","Low quality — move closer")),E("idle");return}if(A&&u.current){const w=u.current.getContext("2d");if(w){w.clearRect(0,0,g,g);const d=g/F.width,j=g/F.height;w.beginPath(),w.arc(C.pupil.cx*d,C.pupil.cy*j,C.pupil.r*d,0,Math.PI*2),w.strokeStyle=V("var(--nice-danger, #ef4444)",w.canvas),w.lineWidth=2,w.stroke(),w.beginPath(),w.arc(C.iris.cx*d,C.iris.cy*j,C.iris.r*d,0,Math.PI*2),w.strokeStyle=V("var(--nice-primary, #3b82f6)",w.canvas),w.lineWidth=2,w.stroke()}}if(t==="enroll"){const w=await Me(C,y??`${s} eye`);a==null||a(w,C),$(b("security.iris.enrolled","Iris enrolled successfully")),E("success")}else{let w=0;for(const N of r){const M=Pe(N),U=De(C,M);U>w&&(w=U)}const d=w>=T.matchThreshold,j={success:d,confidence:w,method:"iris",timestamp:Date.now(),duration:0,livenessPassed:T.livenessDetection?!0:void 0,payload:btoa(JSON.stringify(C))};if(d&&T.verifyEndpoint){const N=await ie(),M=await ue(T.verifyEndpoint,{method:"iris",templateData:j.payload,matchScore:w,deviceFingerprint:N},T.authToken);j.success=M.verified}j.success?($(b("security.iris.verified","Iris verified")),E("success")):(_(N=>N+1),K+1>=T.maxRetries?($(b("security.iris.maxAttempts","Maximum attempts reached")),E("failure")):($(b("security.iris.noMatch","No match — try again")),E("idle"))),i==null||i(j)}}catch(R){c==null||c(R instanceof Error?R:new Error(String(R))),$(b("security.iris.error","Scan error")),E("error")}}},[f,t,r,T,b,E,a,i,c,y,s,K,A,g]),P=f==="success"?"var(--security-success)":f==="failure"||f==="error"?"var(--security-error)":f==="scanning"||f==="processing"?"var(--security-biometric)":"var(--security-border)";return n.jsxs("div",{className:m,style:{display:"inline-flex",flexDirection:"column",alignItems:"center",gap:12},children:[y&&n.jsx("div",{style:{fontSize:14,fontWeight:600,color:"var(--security-text)"},children:y}),n.jsxs("div",{style:{width:g,height:g,position:"relative",borderRadius:"50%",overflow:"hidden",border:`3px solid ${P}`,boxShadow:f==="scanning"?`0 0 30px ${P}`:"var(--security-shadow)",transition:"border-color 0.3s, box-shadow 0.3s"},children:[n.jsx("video",{ref:k,style:{width:"100%",height:"100%",objectFit:"cover"},playsInline:!0,muted:!0}),A&&n.jsx("canvas",{ref:u,width:g,height:g,style:{position:"absolute",inset:0,pointerEvents:"none"}}),p&&f==="idle"&&n.jsxs("svg",{viewBox:"0 0 100 100",style:{position:"absolute",inset:0,width:"100%",height:"100%",pointerEvents:"none",opacity:.4},children:[n.jsx("circle",{cx:"50",cy:"50",r:"35",fill:"none",stroke:"white",strokeWidth:"1",strokeDasharray:"5 3"}),n.jsx("circle",{cx:"50",cy:"50",r:"15",fill:"none",stroke:"white",strokeWidth:"0.5",strokeDasharray:"3 3"}),n.jsx("line",{x1:"50",y1:"10",x2:"50",y2:"25",stroke:"white",strokeWidth:"0.5",opacity:"0.5"}),n.jsx("line",{x1:"50",y1:"75",x2:"50",y2:"90",stroke:"white",strokeWidth:"0.5",opacity:"0.5"}),n.jsx("line",{x1:"10",y1:"50",x2:"25",y2:"50",stroke:"white",strokeWidth:"0.5",opacity:"0.5"}),n.jsx("line",{x1:"75",y1:"50",x2:"90",y2:"50",stroke:"white",strokeWidth:"0.5",opacity:"0.5"})]}),(f==="scanning"||f==="processing")&&n.jsx("div",{style:{position:"absolute",inset:0,display:"flex",alignItems:"center",justifyContent:"center",background:"var(--nice-overlay-20, rgba(0, 0, 0, 0.2))"},children:n.jsx("div",{style:{width:g*.7,height:3,background:P,animation:"irisLineAnim 1.5s ease-in-out infinite",position:"absolute",opacity:.7}})})]}),n.jsx("div",{style:{fontSize:11,color:"var(--security-text-muted)",textTransform:"uppercase",letterSpacing:1},children:s==="both"?b("security.iris.bothEyes","Both eyes"):s==="left"?b("security.iris.leftEye","Left eye"):b("security.iris.rightEye","Right eye")}),v&&O>0&&n.jsx("div",{style:{width:g*.6,height:4,background:"var(--security-bg-panel)",borderRadius:2,overflow:"hidden"},children:n.jsx("div",{style:{width:`${Math.min(100,O*300)}%`,height:"100%",background:O>.3?"var(--security-success)":O>.1?"var(--security-warning)":"var(--security-error)",transition:"width 0.3s"}})}),n.jsx("div",{style:{fontSize:13,color:"var(--security-text-secondary)",textAlign:"center",minHeight:20},children:I??L}),f!=="success"&&f!=="failure"&&n.jsx("button",{onClick:Z,disabled:f==="scanning"||f==="processing",style:{padding:"10px 24px",fontSize:14,fontWeight:600,background:"var(--security-biometric)",color:"var(--nice-text-on-primary, #fff)",border:"none",borderRadius:"var(--security-radius)",cursor:"pointer",opacity:f==="scanning"||f==="processing"?.6:1},children:t==="enroll"?b("security.iris.captureBtn","Capture Iris"):b("security.iris.verifyBtn","Verify Iris")}),(f==="failure"||f==="error")&&n.jsx("button",{onClick:()=>{_(0),E("idle"),$("")},style:{padding:"8px 20px",fontSize:13,background:"var(--security-bg-panel)",color:"var(--security-text)",border:"1px solid var(--security-border)",borderRadius:"var(--security-radius)",cursor:"pointer"},children:b("security.common.retry","Try Again")}),n.jsx("style",{children:`
|
|
1
|
+
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const n=require("react/jsx-runtime"),h=require("react"),Oe={low:.7,medium:.8,high:.85,critical:.95},qe={matchThreshold:.85,timeout:3e4,maxRetries:3,livenessDetection:!0,verifyEndpoint:"",authToken:"",showFeedback:!0,hapticFeedback:!0,locale:"en",securityLevel:"high",antiSpoofing:!0};function oe(e){const t={...qe,...e};return e!=null&&e.matchThreshold||(t.matchThreshold=Oe[t.securityLevel]),t}async function ce(e){const t=new TextEncoder().encode(e),r=await crypto.subtle.digest("SHA-256",t);return Array.from(new Uint8Array(r)).map(s=>s.toString(16).padStart(2,"0")).join("")}function de(e=8){const t=new Uint8Array(e);return crypto.getRandomValues(t),Array.from(t).map(r=>r.toString(36).padStart(2,"0")).join("").slice(0,e)}function Ke(e){const t=new Uint32Array(1);return crypto.getRandomValues(t),t[0]%e}function Ge(e,t){return Math.sqrt((e.x-t.x)**2+(e.y-t.y)**2)}async function le(e="user"){return navigator.mediaDevices.getUserMedia({video:{facingMode:e,width:{ideal:1280},height:{ideal:720}},audio:!1})}function se(e,t,r){const s=t??e.videoWidth,a=r??e.videoHeight,i=document.createElement("canvas");i.width=s,i.height=a;const o=i.getContext("2d");o.drawImage(e,0,0,s,a);const c=o.getImageData(0,0,s,a);return{canvas:i,ctx:o,imageData:c}}function ne(e){const t=new Uint8Array(e.width*e.height),r=e.data;for(let s=0;s<t.length;s++){const a=s*4;t[s]=Math.round(.299*r[a]+.587*r[a+1]+.114*r[a+2])}return t}function Ae(e,t,r){const s=new Uint8Array(t*r),a=[1,2,1,2,4,2,1,2,1],i=16;for(let o=1;o<r-1;o++)for(let c=1;c<t-1;c++){let m=0,x=0;for(let y=-1;y<=1;y++)for(let v=-1;v<=1;v++)m+=e[(o+y)*t+(c+v)]*a[x++];s[o*t+c]=Math.round(m/i)}return s}function Je(e,t,r){const s=new Uint8Array(t*r);for(let a=1;a<r-1;a++)for(let i=1;i<t-1;i++){const o=-e[(a-1)*t+(i-1)]+e[(a-1)*t+(i+1)]+-2*e[a*t+(i-1)]+2*e[a*t+(i+1)]+-e[(a+1)*t+(i-1)]+e[(a+1)*t+(i+1)],c=-e[(a-1)*t+(i-1)]-2*e[(a-1)*t+i]-e[(a-1)*t+(i+1)]+e[(a+1)*t+(i-1)]+2*e[(a+1)*t+i]+e[(a+1)*t+(i+1)];s[a*t+i]=Math.min(255,Math.round(Math.sqrt(o*o+c*c)))}return s}function Ye(e){const t=new Array(256).fill(0);for(const x of e)t[x]++;const r=e.length;let s=0;for(let x=0;x<256;x++)s+=x*t[x];let a=0,i=0,o=0,c=0;for(let x=0;x<256;x++){if(i+=t[x],i===0)continue;const y=r-i;if(y===0)break;a+=x*t[x];const v=a/i,A=(s-a)/y,p=i*y*(v-A)**2;p>o&&(o=p,c=x)}const m=new Uint8Array(e.length);for(let x=0;x<e.length;x++)m[x]=e[x]>c?255:0;return{threshold:c,binary:m}}function je(e,t=.3){var g;const r=e.width,s=e.height,a=ne(e),i=Ae(a,r,s),o=Je(i,r,s),{binary:c}=Ye(o),m=[],x=[],y=[];for(let k=2;k<s-2;k++)for(let u=2;u<r-2;u++){if(c[k*r+u]===0)continue;const S=[c[(k-1)*r+u],c[(k-1)*r+(u+1)],c[k*r+(u+1)],c[(k+1)*r+(u+1)],c[(k+1)*r+u],c[(k+1)*r+(u-1)],c[k*r+(u-1)],c[(k-1)*r+(u-1)]];let l=0;for(let B=0;B<8;B++){const H=S[B]>0?1:0,K=S[(B+1)%8]>0?1:0;l+=Math.abs(H-K)}l/=2;let f=0,z=0;for(let B=-2;B<=2;B++)for(let H=-2;H<=2;H++)f+=o[(k+B)*r+(u+H)],z++;const O=f/z/255;if(O<t)continue;const G=Math.atan2(a[(k+1)*r+u]-a[(k-1)*r+u],a[k*r+(u+1)]-a[k*r+(u-1)]);l===1?m.push({x:u/r,y:k/s,angle:G,type:"ending",quality:O}):l===3&&m.push({x:u/r,y:k/s,angle:G,type:"bifurcation",quality:O})}m.sort((k,u)=>u.quality-k.quality);const v=m.slice(0,120);if(v.length>5){const k=v.reduce((S,l)=>S+l.x,0)/v.length,u=v.reduce((S,l)=>S+l.y,0)/v.length;x.push({x:k,y:u})}const A=v.length,p=v.filter(k=>k.type==="ending").length,D=v.filter(k=>k.type==="bifurcation").length/(p+1);let b="loop-right";D>1.5?b="whorl":D<.5?b="arch":((g=x[0])==null?void 0:g.x)<.45&&(b="loop-left");const T=v.length>20?v.reduce((k,u)=>k+u.quality,0)/v.length:0;return{minutiae:v,corePoints:x,deltaPoints:y,ridgeCount:A,patternType:b,quality:T}}function Te(e,t){if(e.minutiae.length<5||t.minutiae.length<5)return 0;let r=0;const s=.05,a=.5,i=new Set;for(const c of e.minutiae){let m=1/0,x=-1;for(let y=0;y<t.minutiae.length;y++){if(i.has(y))continue;const v=t.minutiae[y];if(c.type!==v.type)continue;const A=Ge(c,v),p=Math.abs(c.angle-v.angle);A<s&&p<a&&A<m&&(m=A,x=y)}x>=0&&(r++,i.add(x))}const o=Math.min(e.minutiae.length,t.minutiae.length);return o>0?r/o:0}async function Ce(e,t){const r=JSON.stringify(e),s=await ce(r);return{id:`fp_${Date.now()}_${de()}`,method:"fingerprint",templateData:btoa(r),enrolled:Date.now(),label:t,hash:s}}function Ie(e){return JSON.parse(atob(e.templateData))}function Re(e,t="left"){const r=e.width,s=e.height,a=ne(e),i=Ae(a,r,s);let o={cx:r/2,cy:s/2,r:Math.min(r,s)*.08,score:1/0};for(let I=Math.round(s*.3);I<Math.round(s*.7);I+=2)for(let D=Math.round(r*.3);D<Math.round(r*.7);D+=2)for(let b=Math.round(Math.min(r,s)*.04);b<Math.round(Math.min(r,s)*.15);b+=2){let T=0,g=0;for(let l=0;l<Math.PI*2;l+=.3){const f=Math.round(D+b*Math.cos(l)),z=Math.round(I+b*Math.sin(l));f>=0&&f<r&&z>=0&&z<s&&(T+=i[z*r+f],g++)}const k=g>0?T/g:255,u=i[I*r+D],S=k*.5+u*.5;S<o.score&&(o={cx:D,cy:I,r:b,score:S})}const c=o.r*3,m={cx:o.cx,cy:o.cy,r:Math.min(c,Math.min(r,s)*.4)},x=256,y=[];for(let I=0;I<x;I++){const D=I/x*Math.PI*2,b=o.r+(m.r-o.r)*.5,T=Math.round(o.cx+b*Math.cos(D)),g=Math.round(o.cy+b*Math.sin(D));if(T>=0&&T<r&&g>=0&&g<s){const k=Math.round(o.cx+b*Math.cos(D+.1)),u=Math.round(o.cy+b*Math.sin(D+.1)),S=i[g*r+T],l=k>=0&&k<r&&u>=0&&u<s?i[u*r+k]:S;y.push(S>l?1:0)}else y.push(0)}const v=y.join(""),A=Math.PI*o.r**2,p=Math.min(1,Math.max(0,A/(r*s)*100));return{irisCode:v,pupil:o,iris:m,quality:p,eye:t}}function De(e,t){if(!e.irisCode||!t.irisCode)return 0;const r=Math.min(e.irisCode.length,t.irisCode.length);if(r===0)return 0;let s=0,a=r;for(let o=-8;o<=8;o++){let c=0;for(let m=0;m<r;m++){const x=(m+o+r)%r;e.irisCode[m]!==t.irisCode[x]&&c++}c<a&&(a=c)}s=a;const i=s/r;return Math.max(0,1-i*2.5)}async function Me(e,t){const r=JSON.stringify(e),s=await ce(r);return{id:`iris_${Date.now()}_${de()}`,method:"iris",templateData:btoa(r),enrolled:Date.now(),label:t,hash:s}}function Pe(e){return JSON.parse(atob(e.templateData))}function ae(e){const t=e.width,r=e.height,s=e.data,a=new Uint8Array(t*r);for(let u=0;u<t*r;u++){const S=u*4,l=s[S],f=s[S+1],z=s[S+2],O=.299*l+.587*f+.114*z,G=128-.169*l-.331*f+.5*z,B=128+.5*l-.419*f-.081*z;G>=77&&G<=127&&B>=133&&B<=173&&O>80&&(a[u]=1)}let i=t,o=r,c=0,m=0,x=0;for(let u=0;u<r;u++)for(let S=0;S<t;S++)a[u*t+S]&&(x++,S<i&&(i=S),S>c&&(c=S),u<o&&(o=u),u>m&&(m=u));const y=c-i,v=m-o;if(y<t*.1||v<r*.1)return null;const A={x:i,y:o,width:y,height:v},p=[],I=ne(e),D=Math.max(1,Math.floor(y/8)),b=Math.max(1,Math.floor(v/16));for(let u=0;u<16;u++)for(let S=0;S<8;S++){const l=i+S*D+Math.floor(D/2),f=o+u*b+Math.floor(b/2);l<t&&f<r?p.push(I[f*t+l]/255):p.push(0)}const T=[],g={x:i+y/2,y:o+v/2};for(let u=0;u<68;u++){const S=u/68*Math.PI*2,l=y*.4*Math.cos(S),f=v*.45*Math.sin(S);T.push({x:(g.x+l)/t,y:(g.y+f)/r})}const k=Math.min(1,x/(y*v)*2);return{embedding:p,boundingBox:A,landmarks:T,headPose:{yaw:0,pitch:0,roll:0},quality:k}}function he(e,t){if(e.embedding.length!==t.embedding.length)return 0;let r=0,s=0,a=0;for(let o=0;o<e.embedding.length;o++)r+=e.embedding[o]*t.embedding[o],s+=e.embedding[o]**2,a+=t.embedding[o]**2;const i=Math.sqrt(s)*Math.sqrt(a);return i>0?(r/i+1)/2:0}function Ee(e,t){const r=ae(e),s=ae(t);return!r||!s?{similarity:0,cameraFeatures:r,refFeatures:s}:{similarity:he(r,s),cameraFeatures:r,refFeatures:s}}async function Fe(e,t){const r=JSON.stringify(e),s=await ce(r);return{id:`face_${Date.now()}_${de()}`,method:"face",templateData:btoa(r),enrolled:Date.now(),label:t,hash:s}}function Ne(e){return JSON.parse(atob(e.templateData))}function Ze(){const e=["blink","smile","turn-left","turn-right","nod","raise-eyebrows"],t=e[Ke(e.length)];return{type:t,instruction:{blink:"Please blink your eyes",smile:"Please smile","turn-left":"Please turn your head left","turn-right":"Please turn your head right",nod:"Please nod your head","raise-eyebrows":"Please raise your eyebrows"}[t],completed:!1,confidence:0}}function fe(e,t=.02){if(e.length<2)return{isLive:!1,confidence:0,motionScore:0};let r=0;for(let o=1;o<e.length;o++){const c=ne(e[o-1]),m=ne(e[o]);let x=0;for(let y=0;y<c.length;y++)x+=Math.abs(c[y]-m[y]);r+=x/(c.length*255)}const s=r/(e.length-1),a=s>t,i=Math.min(1,s/(t*3));return{isLive:a,confidence:i,motionScore:s}}function ye(){return{userAgent:navigator.userAgent,platform:navigator.platform,language:navigator.language,screenResolution:[screen.width,screen.height],timezone:Intl.DateTimeFormat().resolvedOptions().timeZone,touchSupport:"ontouchstart"in window||navigator.maxTouchPoints>0,hardwareConcurrency:navigator.hardwareConcurrency??0}}async function ie(){const e=ye(),t=JSON.stringify(e);return ce(t)}function pe(){return typeof window<"u"&&!!window.PublicKeyCredential}async function ze(){if(!pe())return!1;try{return await PublicKeyCredential.isUserVerifyingPlatformAuthenticatorAvailable()}catch{return!1}}async function Le(e){const t={rp:{name:e.rpName,id:e.rpId},user:{id:new TextEncoder().encode(e.userId),name:e.userName,displayName:e.userDisplayName},challenge:e.challenge,pubKeyCredParams:[{alg:-7,type:"public-key"},{alg:-257,type:"public-key"}],authenticatorSelection:{authenticatorAttachment:"platform",userVerification:"required",residentKey:"preferred"},timeout:e.timeout??6e4,attestation:"none"};return await navigator.credentials.create({publicKey:t})}async function $e(e){const t={rpId:e.rpId,challenge:e.challenge,allowCredentials:e.allowCredentials,userVerification:"required",timeout:e.timeout??6e4};return await navigator.credentials.get({publicKey:t})}async function ue(e,t,r){const s={"Content-Type":"application/json"};r&&(s.Authorization=`Bearer ${r}`);const a=await fetch(e,{method:"POST",headers:s,body:JSON.stringify(t)});return a.ok?a.json():{verified:!1,message:`Server error: ${a.status}`}}function V(e,t){var o;const r=e.trim().match(/^var\(\s*([^,\s)]+)\s*(?:,\s*(.+))?\)$/);if(!r)return e;const s=(o=r[2])==null?void 0:o.trim();if(typeof document>"u"||typeof getComputedStyle>"u")return s?V(s):e;const a=typeof Element<"u"&&t instanceof Element&&t.isConnected?t:document.documentElement,i=getComputedStyle(a).getPropertyValue(r[1]).trim();return i||(s?V(s,t):e)}const Xe=(e,t)=>t,Be=h.createContext(Xe),Qe=({t:e,children:t})=>n.jsx(Be.Provider,{value:e,children:t});function Q(){return{t:h.useContext(Be)}}const Ve={sm:200,md:280,lg:380},et=e=>{const{mode:t,enrolledTemplates:r=[],fingerPosition:s="right-index",onEnroll:a,onVerify:i,onStatusChange:o,onError:c,className:m,size:x="md",label:y,showQuality:v=!0,showMinutiae:A=!1,instructionText:p,cameraFacing:I="environment",...D}=e,{t:b}=Q(),T=oe(D),g=Ve[x],k=h.useRef(null),u=h.useRef(null),S=h.useRef(null),[l,f]=h.useState("idle"),[z,O]=h.useState(0),[G,B]=h.useState(null),[H,K]=h.useState(0),[_,L]=h.useState(""),$=h.useCallback(P=>{f(P),o==null||o(P)},[o]),E=h.useCallback(async()=>{try{const P=await le(I);S.current=P,k.current&&(k.current.srcObject=P,await k.current.play()),$("idle"),L(b("security.fingerprint.placeFingerPrompt","Place your finger on the scanner"))}catch(P){c==null||c(P instanceof Error?P:new Error(String(P))),L(b("security.fingerprint.cameraError","Camera access denied")),$("error")}},[I,b,$,c]),q=h.useCallback(()=>{var P;(P=S.current)==null||P.getTracks().forEach(R=>R.stop()),S.current=null},[]);h.useEffect(()=>(E(),q),[E,q]);const W=h.useCallback(async()=>{if(!(!k.current||l==="processing"||l==="success")){$("scanning"),L(b("security.fingerprint.scanning","Scanning…"));try{const{imageData:P}=se(k.current);$("processing"),L(b("security.fingerprint.processing","Processing fingerprint…"));const R=je(P);if(B(R),O(R.quality),R.quality<.2){L(b("security.fingerprint.lowQuality","Low quality — try again")),$("idle");return}if(t==="enroll"){const F=await Ce(R,y??s);a==null||a(F,R),L(b("security.fingerprint.enrolled","Fingerprint enrolled successfully")),$("success")}else{let F=0;for(const d of r){const j=Ie(d),N=Te(R,j);N>F&&(F=N)}const C=F>=T.matchThreshold,w={success:C,confidence:F,method:"fingerprint",timestamp:Date.now(),duration:0,payload:btoa(JSON.stringify(R))};if(C&&T.verifyEndpoint){const d=await ie(),j=await ue(T.verifyEndpoint,{method:"fingerprint",templateData:w.payload,matchScore:F,deviceFingerprint:d},T.authToken);w.success=j.verified}w.success?(L(b("security.fingerprint.verified","Fingerprint verified")),$("success")):(K(d=>d+1),H+1>=T.maxRetries?(L(b("security.fingerprint.maxAttempts","Maximum attempts reached")),$("failure")):(L(b("security.fingerprint.noMatch","No match — try again")),$("idle"))),i==null||i(w)}}catch(P){c==null||c(P instanceof Error?P:new Error(String(P))),L(b("security.fingerprint.error","Scan error — try again")),$("error")}}},[l,t,r,T,b,$,a,i,c,y,s,H]);h.useEffect(()=>{if(!A||!G||!u.current)return;const P=u.current.getContext("2d");if(!P)return;P.clearRect(0,0,g,g);const R=V("var(--nice-success, #10b981)",P.canvas),F=V("var(--nice-warning, #f59e0b)",P.canvas);G.minutiae.forEach(C=>{P.beginPath(),P.arc(C.x*g,C.y*g,2,0,Math.PI*2),P.fillStyle=C.type==="ending"?R:F,P.fill(),P.beginPath(),P.moveTo(C.x*g,C.y*g),P.lineTo(C.x*g+Math.cos(C.angle)*8,C.y*g+Math.sin(C.angle)*8),P.strokeStyle=P.fillStyle,P.lineWidth=1,P.stroke()})},[G,A,g]);const Z=l==="success"?"var(--security-success)":l==="failure"||l==="error"?"var(--security-error)":l==="scanning"||l==="processing"?"var(--security-biometric)":"var(--security-border)";return n.jsxs("div",{className:m,style:{display:"inline-flex",flexDirection:"column",alignItems:"center",gap:12},children:[y&&n.jsx("div",{style:{fontSize:14,fontWeight:600,color:"var(--security-text)"},children:y}),n.jsxs("div",{style:{width:g,height:g,position:"relative",borderRadius:"var(--security-radius-lg)",overflow:"hidden",border:`3px solid ${Z}`,boxShadow:l==="scanning"?`0 0 20px ${Z}`:"var(--security-shadow)",transition:"border-color 0.3s, box-shadow 0.3s"},children:[n.jsx("video",{ref:k,style:{width:"100%",height:"100%",objectFit:"cover"},playsInline:!0,muted:!0}),A&&n.jsx("canvas",{ref:u,width:g,height:g,style:{position:"absolute",inset:0,pointerEvents:"none"}}),n.jsxs("svg",{viewBox:"0 0 100 100",style:{position:"absolute",inset:0,width:"100%",height:"100%",pointerEvents:"none",opacity:.3},children:[n.jsx("ellipse",{cx:"50",cy:"50",rx:"28",ry:"38",fill:"none",stroke:"white",strokeWidth:"1",strokeDasharray:"4 3"}),n.jsx("ellipse",{cx:"50",cy:"50",rx:"20",ry:"28",fill:"none",stroke:"white",strokeWidth:"0.5",strokeDasharray:"2 3"})]}),(l==="scanning"||l==="processing")&&n.jsx("div",{style:{position:"absolute",inset:0,display:"flex",alignItems:"center",justifyContent:"center",background:"var(--nice-overlay-30, rgba(0, 0, 0, 0.3))"},children:n.jsx("div",{style:{width:60,height:60,borderRadius:"50%",border:"3px solid transparent",borderTopColor:Z,animation:"spin 0.8s linear infinite"}})})]}),v&&z>0&&n.jsx("div",{style:{width:g,height:4,background:"var(--security-bg-panel)",borderRadius:2,overflow:"hidden"},children:n.jsx("div",{style:{width:`${z*100}%`,height:"100%",background:z>.6?"var(--security-success)":z>.3?"var(--security-warning)":"var(--security-error)",transition:"width 0.3s"}})}),n.jsx("div",{style:{fontSize:13,color:"var(--security-text-secondary)",textAlign:"center",minHeight:20},children:p??_}),l!=="success"&&l!=="failure"&&n.jsx("button",{onClick:W,disabled:l==="scanning"||l==="processing",style:{padding:"10px 24px",fontSize:14,fontWeight:600,background:"var(--security-biometric)",color:"var(--nice-color-white, #fff)",border:"none",borderRadius:"var(--security-radius)",cursor:"pointer",opacity:l==="scanning"||l==="processing"?.6:1},children:t==="enroll"?b("security.fingerprint.captureBtn","Capture Fingerprint"):b("security.fingerprint.verifyBtn","Verify Fingerprint")}),(l==="failure"||l==="error")&&n.jsx("button",{onClick:()=>{K(0),$("idle"),L("")},style:{padding:"8px 20px",fontSize:13,background:"var(--security-bg-panel)",color:"var(--security-text)",border:"1px solid var(--security-border)",borderRadius:"var(--security-radius)",cursor:"pointer"},children:b("security.common.retry","Try Again")}),n.jsx("style",{children:"@keyframes spin { to { transform: rotate(360deg); } }"})]})},tt={sm:220,md:300,lg:400},rt=e=>{const{mode:t,enrolledTemplates:r=[],eye:s="right",onEnroll:a,onVerify:i,onStatusChange:o,onError:c,className:m,size:x="md",label:y,showQuality:v=!0,showSegmentation:A=!0,showGuide:p=!0,instructionText:I,...D}=e,{t:b}=Q(),T=oe(D),g=tt[x],k=h.useRef(null),u=h.useRef(null),S=h.useRef(null),l=h.useRef([]),[f,z]=h.useState("idle"),[O,G]=h.useState(0),[B,H]=h.useState(null),[K,_]=h.useState(0),[L,$]=h.useState(""),E=h.useCallback(R=>{z(R),o==null||o(R)},[o]),q=h.useCallback(async()=>{try{const R=await le("user");S.current=R,k.current&&(k.current.srcObject=R,await k.current.play()),E("idle"),$(b("security.iris.alignEyePrompt","Align your eye with the circle"))}catch(R){c==null||c(R instanceof Error?R:new Error(String(R))),$(b("security.iris.cameraError","Camera access denied")),E("error")}},[b,E,c]),W=h.useCallback(()=>{var R;(R=S.current)==null||R.getTracks().forEach(F=>F.stop()),S.current=null},[]);h.useEffect(()=>(q(),W),[q,W]);const Z=h.useCallback(async()=>{if(!(!k.current||f==="processing"||f==="success")){E("scanning"),$(b("security.iris.scanning","Scanning iris…"));try{const R=[];for(let w=0;w<5;w++){const{imageData:d}=se(k.current);R.push(d),await new Promise(j=>setTimeout(j,200))}if(l.current=R,T.livenessDetection&&!fe(R).isLive){$(b("security.iris.notLive","Liveness check failed — please blink or move slightly")),E("idle");return}E("processing"),$(b("security.iris.processing","Processing iris pattern…"));const F=R[R.length-1],C=Re(F,s==="both"?"left":s);if(!C){$(b("security.iris.noIrisDetected","No iris detected — adjust position")),E("idle");return}if(H(C),G(C.quality),C.quality<.1){$(b("security.iris.lowQuality","Low quality — move closer")),E("idle");return}if(A&&u.current){const w=u.current.getContext("2d");if(w){w.clearRect(0,0,g,g);const d=g/F.width,j=g/F.height;w.beginPath(),w.arc(C.pupil.cx*d,C.pupil.cy*j,C.pupil.r*d,0,Math.PI*2),w.strokeStyle=V("var(--nice-danger, #ef4444)",w.canvas),w.lineWidth=2,w.stroke(),w.beginPath(),w.arc(C.iris.cx*d,C.iris.cy*j,C.iris.r*d,0,Math.PI*2),w.strokeStyle=V("var(--nice-primary, #3b82f6)",w.canvas),w.lineWidth=2,w.stroke()}}if(t==="enroll"){const w=await Me(C,y??`${s} eye`);a==null||a(w,C),$(b("security.iris.enrolled","Iris enrolled successfully")),E("success")}else{let w=0;for(const N of r){const M=Pe(N),U=De(C,M);U>w&&(w=U)}const d=w>=T.matchThreshold,j={success:d,confidence:w,method:"iris",timestamp:Date.now(),duration:0,livenessPassed:T.livenessDetection?!0:void 0,payload:btoa(JSON.stringify(C))};if(d&&T.verifyEndpoint){const N=await ie(),M=await ue(T.verifyEndpoint,{method:"iris",templateData:j.payload,matchScore:w,deviceFingerprint:N},T.authToken);j.success=M.verified}j.success?($(b("security.iris.verified","Iris verified")),E("success")):(_(N=>N+1),K+1>=T.maxRetries?($(b("security.iris.maxAttempts","Maximum attempts reached")),E("failure")):($(b("security.iris.noMatch","No match — try again")),E("idle"))),i==null||i(j)}}catch(R){c==null||c(R instanceof Error?R:new Error(String(R))),$(b("security.iris.error","Scan error")),E("error")}}},[f,t,r,T,b,E,a,i,c,y,s,K,A,g]),P=f==="success"?"var(--security-success)":f==="failure"||f==="error"?"var(--security-error)":f==="scanning"||f==="processing"?"var(--security-biometric)":"var(--security-border)";return n.jsxs("div",{className:m,style:{display:"inline-flex",flexDirection:"column",alignItems:"center",gap:12},children:[y&&n.jsx("div",{style:{fontSize:14,fontWeight:600,color:"var(--security-text)"},children:y}),n.jsxs("div",{style:{width:g,height:g,position:"relative",borderRadius:"50%",overflow:"hidden",border:`3px solid ${P}`,boxShadow:f==="scanning"?`0 0 30px ${P}`:"var(--security-shadow)",transition:"border-color 0.3s, box-shadow 0.3s"},children:[n.jsx("video",{ref:k,style:{width:"100%",height:"100%",objectFit:"cover"},playsInline:!0,muted:!0}),A&&n.jsx("canvas",{ref:u,width:g,height:g,style:{position:"absolute",inset:0,pointerEvents:"none"}}),p&&f==="idle"&&n.jsxs("svg",{viewBox:"0 0 100 100",style:{position:"absolute",inset:0,width:"100%",height:"100%",pointerEvents:"none",opacity:.4},children:[n.jsx("circle",{cx:"50",cy:"50",r:"35",fill:"none",stroke:"white",strokeWidth:"1",strokeDasharray:"5 3"}),n.jsx("circle",{cx:"50",cy:"50",r:"15",fill:"none",stroke:"white",strokeWidth:"0.5",strokeDasharray:"3 3"}),n.jsx("line",{x1:"50",y1:"10",x2:"50",y2:"25",stroke:"white",strokeWidth:"0.5",opacity:"0.5"}),n.jsx("line",{x1:"50",y1:"75",x2:"50",y2:"90",stroke:"white",strokeWidth:"0.5",opacity:"0.5"}),n.jsx("line",{x1:"10",y1:"50",x2:"25",y2:"50",stroke:"white",strokeWidth:"0.5",opacity:"0.5"}),n.jsx("line",{x1:"75",y1:"50",x2:"90",y2:"50",stroke:"white",strokeWidth:"0.5",opacity:"0.5"})]}),(f==="scanning"||f==="processing")&&n.jsx("div",{style:{position:"absolute",inset:0,display:"flex",alignItems:"center",justifyContent:"center",background:"var(--nice-overlay-20, rgba(0, 0, 0, 0.2))"},children:n.jsx("div",{style:{width:g*.7,height:3,background:P,animation:"irisLineAnim 1.5s ease-in-out infinite",position:"absolute",opacity:.7}})})]}),n.jsx("div",{style:{fontSize:11,color:"var(--security-text-muted)",textTransform:"uppercase",letterSpacing:1},children:s==="both"?b("security.iris.bothEyes","Both eyes"):s==="left"?b("security.iris.leftEye","Left eye"):b("security.iris.rightEye","Right eye")}),v&&O>0&&n.jsx("div",{style:{width:g*.6,height:4,background:"var(--security-bg-panel)",borderRadius:2,overflow:"hidden"},children:n.jsx("div",{style:{width:`${Math.min(100,O*300)}%`,height:"100%",background:O>.3?"var(--security-success)":O>.1?"var(--security-warning)":"var(--security-error)",transition:"width 0.3s"}})}),n.jsx("div",{style:{fontSize:13,color:"var(--security-text-secondary)",textAlign:"center",minHeight:20},children:I??L}),f!=="success"&&f!=="failure"&&n.jsx("button",{onClick:Z,disabled:f==="scanning"||f==="processing",style:{padding:"10px 24px",fontSize:14,fontWeight:600,background:"var(--security-biometric)",color:"var(--nice-color-white, #fff)",border:"none",borderRadius:"var(--security-radius)",cursor:"pointer",opacity:f==="scanning"||f==="processing"?.6:1},children:t==="enroll"?b("security.iris.captureBtn","Capture Iris"):b("security.iris.verifyBtn","Verify Iris")}),(f==="failure"||f==="error")&&n.jsx("button",{onClick:()=>{_(0),E("idle"),$("")},style:{padding:"8px 20px",fontSize:13,background:"var(--security-bg-panel)",color:"var(--security-text)",border:"1px solid var(--security-border)",borderRadius:"var(--security-radius)",cursor:"pointer"},children:b("security.common.retry","Try Again")}),n.jsx("style",{children:`
|
|
2
2
|
@keyframes irisLineAnim {
|
|
3
3
|
0%, 100% { transform: translateY(-${g*.3}px); opacity: 0.3; }
|
|
4
4
|
50% { transform: translateY(${g*.3}px); opacity: 0.8; }
|
|
5
5
|
}
|
|
6
|
-
`})]})},st={sm:240,md:320,lg:440},nt=e=>{const{mode:t,enrolledTemplates:r=[],referencePhoto:s,onEnroll:a,onVerify:i,onStatusChange:o,onError:c,className:m,size:x="md",label:y,showQuality:v=!0,showBoundingBox:A=!0,livenessSteps:p=1,showReference:I=!0,instructionText:D,...b}=e,{t:T}=Q(),g=oe(b),k=st[x],u=h.useRef(null),S=h.useRef(null),l=h.useRef(null),[f,z]=h.useState("idle"),[O,G]=h.useState(0),[B,H]=h.useState(0),[K,_]=h.useState(""),[L,$]=h.useState(null),[E,q]=h.useState(0),W=h.useCallback(w=>{z(w),o==null||o(w)},[o]),Z=h.useCallback(async()=>{try{const w=await le("user");l.current=w,u.current&&(u.current.srcObject=w,await u.current.play()),W("idle"),_(T("security.face.lookAtCamera","Look at the camera"))}catch(w){c==null||c(w instanceof Error?w:new Error(String(w))),_(T("security.face.cameraError","Camera access denied")),W("error")}},[T,W,c]),P=h.useCallback(()=>{var w;(w=l.current)==null||w.getTracks().forEach(d=>d.stop()),l.current=null},[]);h.useEffect(()=>(Z(),P),[Z,P]);const R=h.useCallback(w=>{var ee,ve,xe;const d=(ee=S.current)==null?void 0:ee.getContext("2d");if(!d)return;const j=S.current.width,N=S.current.height;if(d.clearRect(0,0,j,N),!w||!A)return;const M=w.boundingBox,U=j/(((ve=u.current)==null?void 0:ve.videoWidth)??j),J=N/(((xe=u.current)==null?void 0:xe.videoHeight)??N);d.strokeStyle=V(f==="success"?"var(--nice-success, #10b981)":"var(--nice-primary, #3b82f6)",d.canvas),d.lineWidth=2,d.setLineDash([6,4]),d.strokeRect(M.x*U,M.y*J,M.width*U,M.height*J),d.setLineDash([]);const X=[[M.x*U,M.y*J],[(M.x+M.width)*U,M.y*J],[M.x*U,(M.y+M.height)*J],[(M.x+M.width)*U,(M.y+M.height)*J]],Y=12;d.lineWidth=3;for(const[te,re]of X)d.beginPath(),d.moveTo(te===M.x*U?te:te-Y,re),d.lineTo(te,re),d.lineTo(te,re===M.y*J?re+Y:re-Y),d.stroke()},[A,f]),F=h.useCallback(async()=>{if(!(!u.current||f==="processing"||f==="success")){W("scanning"),_(T("security.face.scanning","Scanning face…"));try{if(g.livenessDetection){const j=[];for(let M=0;M<8;M++)j.push(se(u.current).imageData),await new Promise(U=>setTimeout(U,200));if(!fe(j).isLive){_(T("security.face.notLive","Liveness check failed — move naturally")),W("idle");return}}W("processing"),_(T("security.face.processing","Analysing face…"));const{imageData:w}=se(u.current);if(t==="compare"&&s){const j=typeof s=="string"?await it(s):at(s),{similarity:N,cameraFeatures:M,refFeatures:U}=Ee(w,j);q(N),G((M==null?void 0:M.quality)??0),R(M);const X={success:N>=g.matchThreshold,confidence:N,method:"face",timestamp:Date.now(),duration:0,livenessPassed:g.livenessDetection};X.success?(_(T("security.face.matchFound",`Match: ${(N*100).toFixed(0)}%`)),W("success")):(H(Y=>Y+1),B+1>=g.maxRetries?(_(T("security.face.maxAttempts","Maximum attempts reached")),W("failure")):(_(T("security.face.noMatch","No match — try again")),W("idle"))),i==null||i(X);return}const d=ae(w);if(!d){_(T("security.face.noFaceDetected","No face detected")),W("idle");return}if(G(d.quality),R(d),t==="enroll"){const j=await Fe(d,y??"face");a==null||a(j,d),_(T("security.face.enrolled","Face enrolled successfully")),W("success")}else{let j=0;for(const U of r){const J=Ne(U),X=he(d,J);X>j&&(j=X)}q(j);const N=j>=g.matchThreshold,M={success:N,confidence:j,method:"face",timestamp:Date.now(),duration:0,livenessPassed:g.livenessDetection};if(N&&g.verifyEndpoint){const U=await ie(),J=await ue(g.verifyEndpoint,{method:"face",templateData:btoa(JSON.stringify(d)),matchScore:j,deviceFingerprint:U},g.authToken);M.success=J.verified}M.success?(_(T("security.face.verified","Face verified")),W("success")):(H(U=>U+1),B+1>=g.maxRetries?(_(T("security.face.maxAttempts","Maximum attempts reached")),W("failure")):(_(T("security.face.noMatch","No match — try again")),W("idle"))),i==null||i(M)}}catch(w){c==null||c(w instanceof Error?w:new Error(String(w))),_(T("security.face.error","Error — try again")),W("error")}}},[f,t,r,s,g,T,W,a,i,c,y,B,R]),C=f==="success"?"var(--security-success)":f==="failure"||f==="error"?"var(--security-error)":f==="scanning"||f==="processing"?"var(--security-biometric)":"var(--security-border)";return n.jsxs("div",{className:m,style:{display:"inline-flex",flexDirection:"column",alignItems:"center",gap:12},children:[y&&n.jsx("div",{style:{fontSize:14,fontWeight:600,color:"var(--security-text)"},children:y}),n.jsxs("div",{style:{display:"flex",gap:16,alignItems:"center"},children:[n.jsxs("div",{style:{width:k,height:k*.75,position:"relative",borderRadius:"var(--security-radius-lg)",overflow:"hidden",border:`3px solid ${C}`,boxShadow:f==="scanning"?`0 0 20px ${C}`:"var(--security-shadow)",transition:"border-color 0.3s, box-shadow 0.3s"},children:[n.jsx("video",{ref:u,style:{width:"100%",height:"100%",objectFit:"cover",transform:"scaleX(-1)"},playsInline:!0,muted:!0}),n.jsx("canvas",{ref:S,width:k,height:k*.75,style:{position:"absolute",inset:0,pointerEvents:"none",transform:"scaleX(-1)"}}),n.jsx("svg",{viewBox:"0 0 100 75",style:{position:"absolute",inset:0,width:"100%",height:"100%",pointerEvents:"none",opacity:.3},children:n.jsx("ellipse",{cx:"50",cy:"37",rx:"22",ry:"30",fill:"none",stroke:"white",strokeWidth:"0.8",strokeDasharray:"4 3"})}),(f==="scanning"||f==="processing")&&n.jsx("div",{style:{position:"absolute",inset:0,background:"var(--nice-overlay-15, rgba(0, 0, 0, 0.15))",display:"flex",alignItems:"center",justifyContent:"center"},children:n.jsx("div",{style:{width:50,height:50,borderRadius:"50%",border:"3px solid transparent",borderTopColor:C,animation:"spin 0.8s linear infinite"}})})]}),t==="compare"&&I&&s&&n.jsxs("div",{style:{width:k*.4,height:k*.5,borderRadius:"var(--security-radius)",overflow:"hidden",border:"2px solid var(--security-border)"},children:[n.jsx("img",{src:typeof s=="string"?s:void 0,alt:T("security.face.referenceAlt","Reference"),style:{width:"100%",height:"100%",objectFit:"cover"}}),n.jsx("div",{style:{textAlign:"center",fontSize:10,padding:4,color:"var(--security-text-muted)",background:"var(--security-bg-panel)"},children:T("security.face.reference","Reference")})]})]}),E>0&&n.jsxs("div",{style:{display:"flex",alignItems:"center",gap:8,fontSize:13},children:[n.jsxs("span",{style:{color:"var(--security-text-secondary)"},children:[T("security.face.confidence","Confidence"),":"]}),n.jsx("div",{style:{width:100,height:6,background:"var(--security-bg-panel)",borderRadius:3,overflow:"hidden"},children:n.jsx("div",{style:{width:`${E*100}%`,height:"100%",background:E>=g.matchThreshold?"var(--security-success)":"var(--security-warning)"}})}),n.jsxs("span",{style:{fontWeight:600,color:E>=g.matchThreshold?"var(--security-success)":"var(--security-warning)"},children:[(E*100).toFixed(0),"%"]})]}),n.jsx("div",{style:{fontSize:13,color:"var(--security-text-secondary)",textAlign:"center",minHeight:20},children:D??K}),f!=="success"&&f!=="failure"&&n.jsx("button",{onClick:F,disabled:f==="scanning"||f==="processing",style:{padding:"10px 24px",fontSize:14,fontWeight:600,background:"var(--security-biometric)",color:"var(--nice-text-on-primary, #fff)",border:"none",borderRadius:"var(--security-radius)",cursor:"pointer",opacity:f==="scanning"||f==="processing"?.6:1},children:t==="enroll"?T("security.face.captureBtn","Capture Face"):t==="compare"?T("security.face.compareBtn","Compare"):T("security.face.verifyBtn","Verify Face")}),(f==="failure"||f==="error")&&n.jsx("button",{onClick:()=>{H(0),q(0),W("idle"),_("")},style:{padding:"8px 20px",fontSize:13,background:"var(--security-bg-panel)",color:"var(--security-text)",border:"1px solid var(--security-border)",borderRadius:"var(--security-radius)",cursor:"pointer"},children:T("security.common.retry","Try Again")}),n.jsx("style",{children:"@keyframes spin { to { transform: rotate(360deg); } }"})]})};async function it(e){return new Promise((t,r)=>{const s=new Image;s.crossOrigin="anonymous",s.onload=()=>{const a=document.createElement("canvas");a.width=s.naturalWidth,a.height=s.naturalHeight;const i=a.getContext("2d");i.drawImage(s,0,0),t(i.getImageData(0,0,a.width,a.height))},s.onerror=()=>r(new Error("Failed to load reference image")),s.src=e})}function at(e){const t=document.createElement("canvas");t.width=e.naturalWidth||e.width,t.height=e.naturalHeight||e.height;const r=t.getContext("2d");return r.drawImage(e,0,0),r.getImageData(0,0,t.width,t.height)}const ot=4,ct=5,lt=3e4,ut=e=>{const{length:t=ot,scramble:r=!1,showDigits:s=!1,maxAttempts:a=ct,lockoutDuration:i=lt,keySize:o=64,haptic:c=!0,keyLabels:m,expectedHash:x,expectedPin:y,mode:v="verify",onComplete:A,onVerify:p,onStatusChange:I,onError:D,showBiometricFallback:b=!1,onBiometricFallback:T,label:g,className:k}=e,{t:u}=Q(),[S,l]=h.useState([]),[f,z]=h.useState("idle"),[O,G]=h.useState(0),[B,H]=h.useState(0),[K,_]=h.useState(null),L=h.useRef(void 0),$=h.useMemo(()=>{const F=["1","2","3","4","5","6","7","8","9","","0","back"];if(!r)return F;const C=["0","1","2","3","4","5","6","7","8","9"];for(let w=C.length-1;w>0;w--){const d=new Uint32Array(1);crypto.getRandomValues(d);const j=d[0]%(w+1);[C[w],C[j]]=[C[j],C[w]]}return[C[0],C[1],C[2],C[3],C[4],C[5],C[6],C[7],C[8],"",C[9],"back"]},[r,f]),E=h.useCallback(F=>{z(F),I==null||I(F)},[I]);h.useEffect(()=>{if(!(B<=Date.now()))return L.current=setInterval(()=>{Date.now()>=B&&(clearInterval(L.current),E("idle"),G(0),l([]))},500),()=>clearInterval(L.current)},[B,E]);const q=B>Date.now(),W=h.useCallback(()=>{c&&navigator.vibrate&&navigator.vibrate(20)},[c]),Z=h.useCallback(async F=>{if(q||f==="success")return;if(W(),F==="back"){l(j=>j.slice(0,-1));return}if(F==="")return;const C=[...S,F];if(l(C),C.length<t)return;const w=C.join("");if(E("processing"),v==="set"){if(K===null){_(w),l([]),E("idle");return}if(K!==w){_(null),l([]),E("failure"),setTimeout(()=>E("idle"),1200);return}A==null||A(w),E("success");return}let d=!1;if(x){const j=new TextEncoder,N=await crypto.subtle.digest("SHA-256",j.encode(w));d=Array.from(new Uint8Array(N)).map(U=>U.toString(16).padStart(2,"0")).join("")===x}else if(y)d=w===y;else{A==null||A(w),E("success");return}if(d)E("success"),p==null||p({success:!0,confidence:1,method:"pin",timestamp:Date.now(),duration:0}),A==null||A(w);else{const j=O+1;if(G(j),j>=a){const N=Date.now()+i;H(N),E("failure"),D==null||D(new Error("Too many failed PIN attempts"))}else E("failure"),setTimeout(()=>{E("idle"),l([])},800);p==null||p({success:!1,confidence:0,method:"pin",timestamp:Date.now(),duration:0})}},[S,t,q,f,v,K,x,y,O,a,i,W,E,A,p,D]),P=Math.max(0,Math.ceil((B-Date.now())/1e3)),R=f==="success"?"var(--security-success)":f==="failure"?"var(--security-error)":"var(--security-border)";return n.jsxs("div",{className:k,style:{display:"inline-flex",flexDirection:"column",alignItems:"center",gap:16,fontFamily:"var(--security-font)",color:"var(--security-text)"},children:[g&&n.jsx("div",{style:{fontSize:14,fontWeight:600},children:g}),n.jsx("div",{style:{fontSize:13,color:"var(--security-text-secondary)",minHeight:18,textAlign:"center"},children:q?u("security.pin.locked",`Locked — try again in ${P}s`):v==="set"&&K!==null?u("security.pin.confirm","Confirm your PIN"):v==="set"?u("security.pin.setNew","Enter a new PIN"):u("security.pin.enter","Enter your PIN")}),n.jsx("div",{style:{display:"flex",gap:12},children:Array.from({length:t},(F,C)=>n.jsx("div",{style:{width:16,height:16,borderRadius:"50%",border:`2px solid ${R}`,background:C<S.length?R:"transparent",transition:"background 0.15s, border-color 0.15s"}},C))}),n.jsx("div",{style:{display:"grid",gridTemplateColumns:`repeat(3, ${o}px)`,gap:10,opacity:q?.4:1,pointerEvents:q?"none":"auto"},children:$.map((F,C)=>{if(F==="")return n.jsx("div",{},C);const w=F==="back";return n.jsx("button",{onClick:()=>Z(F),disabled:q||f==="success","aria-label":w?"Backspace":F,style:{width:o,height:o,borderRadius:"var(--security-key-border-radius, 50%)",border:"1px solid var(--security-key-border, var(--security-border))",background:"var(--security-key-bg, var(--security-bg-panel))",color:"var(--security-key-text, var(--security-text))",fontSize:w?20:22,fontWeight:600,cursor:"pointer",display:"flex",alignItems:"center",justifyContent:"center",transition:"background 0.1s, transform 0.1s",userSelect:"none"},onMouseDown:d=>{d.currentTarget.style.transform="scale(0.92)"},onMouseUp:d=>{d.currentTarget.style.transform=""},onMouseLeave:d=>{d.currentTarget.style.transform=""},children:w?"⌫":(m==null?void 0:m[F])??F},C)})}),S.length>0&&f!=="success"&&n.jsx("button",{onClick:()=>l([]),style:{fontSize:12,background:"none",border:"none",color:"var(--security-text-secondary)",cursor:"pointer",textDecoration:"underline"},children:u("security.pin.clear","Clear")}),b&&n.jsx("button",{onClick:T,style:{fontSize:13,padding:"8px 16px",background:"none",border:"1px solid var(--security-border)",borderRadius:"var(--security-radius)",color:"var(--security-biometric)",cursor:"pointer"},children:u("security.pin.biometricFallback","Use biometrics instead")}),O>0&&f!=="success"&&!q&&n.jsx("div",{style:{fontSize:11,color:"var(--security-warning)"},children:u("security.pin.attempts",`${O}/${a} attempts`)})]})},dt=3,ht=4,ft=5,yt=14,pt=e=>{const{gridSize:t=dt,minLength:r=ht,showTrail:s=!0,showError:a=!0,maxAttempts:i=ft,dotSize:o=yt,trailColor:c,mode:m="verify",expectedHash:x,expectedPattern:y,onComplete:v,onVerify:A,onStatusChange:p,onError:I,label:D,className:b,canvasSize:T}=e,{t:g}=Q(),k=h.useRef(null),[u,S]=h.useState([]),[l,f]=h.useState(!1),[z,O]=h.useState("idle"),[G,B]=h.useState(0),[H,K]=h.useState(null),[_,L]=h.useState(null),$=T??t*80,E=$/t,q=h.useCallback(d=>{O(d),p==null||p(d)},[p]),W=h.useCallback(()=>{const d=[];for(let j=0;j<t;j++)for(let N=0;N<t;N++)d.push({x:N*E+E/2,y:j*E+E/2});return d},[t,E]),Z=h.useCallback(d=>{const j=k.current.getBoundingClientRect(),N="touches"in d?d.touches[0].clientX:d.clientX,M="touches"in d?d.touches[0].clientY:d.clientY;return{x:N-j.left,y:M-j.top}},[]),P=h.useCallback((d,j)=>{const N=W(),M=E*.38;for(let U=0;U<N.length;U++){const J=N[U].x-d,X=N[U].y-j;if(J*J+X*X<M*M)return U}return-1},[W,E]),R=h.useCallback(()=>{var X;const d=(X=k.current)==null?void 0:X.getContext("2d");if(!d)return;d.clearRect(0,0,$,$);const j=W(),N=z==="failure",M=d.canvas,U=V(N&&a?"var(--security-error)":c??"var(--security-biometric)",M),J=V("var(--security-border)",M);for(let Y=0;Y<j.length;Y++){const ee=u.includes(Y);d.beginPath(),d.arc(j[Y].x,j[Y].y,ee?o*.75:o*.5,0,Math.PI*2),d.fillStyle=ee?U:J,d.fill(),ee&&(d.beginPath(),d.arc(j[Y].x,j[Y].y,o*1.2,0,Math.PI*2),d.strokeStyle=U,d.lineWidth=1.5,d.globalAlpha=.3,d.stroke(),d.globalAlpha=1)}if(s&&u.length>1){d.beginPath(),d.moveTo(j[u[0]].x,j[u[0]].y);for(let Y=1;Y<u.length;Y++)d.lineTo(j[u[Y]].x,j[u[Y]].y);l&&_&&d.lineTo(_.x,_.y),d.strokeStyle=U,d.lineWidth=3,d.lineCap="round",d.lineJoin="round",d.globalAlpha=.5,d.stroke(),d.globalAlpha=1}else s&&u.length===1&&l&&_&&(d.beginPath(),d.moveTo(j[u[0]].x,j[u[0]].y),d.lineTo(_.x,_.y),d.strokeStyle=V(c??"var(--security-biometric)",M),d.lineWidth=3,d.globalAlpha=.4,d.stroke(),d.globalAlpha=1)},[$,W,o,u,l,_,z,s,a,c]);h.useEffect(()=>{R()},[R]);const F=h.useCallback(d=>{if(z==="success"||z==="failure")return;d.preventDefault();const{x:j,y:N}=Z(d),M=P(j,N);M>=0&&(f(!0),S([M]),L({x:j,y:N}))},[z,Z,P]),C=h.useCallback(d=>{if(!l)return;d.preventDefault();const{x:j,y:N}=Z(d);L({x:j,y:N});const M=P(j,N);M>=0&&!u.includes(M)&&S(U=>[...U,M])},[l,Z,P,u]),w=h.useCallback(async()=>{if(!l)return;if(f(!1),L(null),u.length<r){S([]);return}const d=u.join(",");if(m==="set"){if(H===null){K([...u]),S([]);return}if(H.join(",")!==d){K(null),q("failure"),setTimeout(()=>{q("idle"),S([])},800);return}v==null||v([...u]),q("success");return}q("processing");let j=!1;if(x){const N=new TextEncoder,M=await crypto.subtle.digest("SHA-256",N.encode(d));j=Array.from(new Uint8Array(M)).map(J=>J.toString(16).padStart(2,"0")).join("")===x}else if(y)j=d===y;else{v==null||v([...u]),q("success");return}if(j)q("success"),A==null||A({success:!0,confidence:1,method:"pattern",timestamp:Date.now(),duration:0}),v==null||v([...u]);else{const N=G+1;B(N),q("failure"),N>=i&&(I==null||I(new Error("Too many failed pattern attempts"))),setTimeout(()=>{q("idle"),S([])},900),A==null||A({success:!1,confidence:0,method:"pattern",timestamp:Date.now(),duration:0})}},[l,u,r,m,H,x,y,G,i,q,v,A,I]);return n.jsxs("div",{className:b,style:{display:"inline-flex",flexDirection:"column",alignItems:"center",gap:12,fontFamily:"var(--security-font)",color:"var(--security-text)"},children:[D&&n.jsx("div",{style:{fontSize:14,fontWeight:600},children:D}),n.jsx("div",{style:{fontSize:13,color:"var(--security-text-secondary)",minHeight:18,textAlign:"center"},children:z==="success"?g("security.pattern.success","Pattern accepted"):z==="failure"?g("security.pattern.wrong","Wrong pattern"):m==="set"&&H!==null?g("security.pattern.confirm","Draw pattern again to confirm"):m==="set"?g("security.pattern.setNew","Draw a new pattern"):g("security.pattern.draw","Draw your pattern")}),n.jsx("canvas",{ref:k,width:$,height:$,style:{touchAction:"none",borderRadius:"var(--security-radius-lg)",background:"var(--security-bg-panel)",border:`1px solid ${z==="failure"?"var(--security-error)":"var(--security-border)"}`,cursor:"pointer",transition:"border-color 0.3s"},onMouseDown:F,onMouseMove:C,onMouseUp:w,onMouseLeave:w,onTouchStart:F,onTouchMove:C,onTouchEnd:w}),(z==="failure"||z==="success")&&n.jsx("button",{onClick:()=>{S([]),B(0),K(null),q("idle")},style:{fontSize:13,padding:"6px 16px",background:"var(--security-bg-panel)",border:"1px solid var(--security-border)",borderRadius:"var(--security-radius)",color:"var(--security-text)",cursor:"pointer"},children:g("security.common.retry","Try Again")}),G>0&&z!=="success"&&n.jsx("div",{style:{fontSize:11,color:"var(--security-warning)"},children:g("security.pattern.attempts",`${G}/${i} attempts`)})]})},gt={sm:"8px 16px",md:"12px 24px",lg:"14px 32px"},mt={sm:13,md:14,lg:16},vt=e=>{const{mode:t,credentialIds:r=[],challenge:s,rpName:a=window.location.hostname,rpId:i=window.location.hostname,user:o,attestation:c="none",authenticatorAttachment:m,residentKey:x="preferred",userVerification:y="preferred",onRegister:v,onAuthenticate:A,onVerify:p,onStatusChange:I,onError:D,label:b,className:T,variant:g="primary",size:k="md",fullWidth:u=!1,icon:S}=e,{t:l}=Q(),[f,z]=h.useState("idle"),[O,G]=h.useState(!0),[B,H]=h.useState(!1),K=h.useCallback(R=>{z(R),I==null||I(R)},[I]);h.useEffect(()=>{G(pe()),ze().then(H)},[]);const _=h.useCallback(()=>{if(s){const R=atob(s.replace(/-/g,"+").replace(/_/g,"/")),F=new Uint8Array(R.length);for(let C=0;C<R.length;C++)F[C]=R.charCodeAt(C);return F.buffer}return crypto.getRandomValues(new Uint8Array(32)).buffer},[s]),L=h.useCallback(async()=>{if(!O){D==null||D(new Error("WebAuthn not available"));return}K("processing");try{if(t==="register"){const R=(o==null?void 0:o.id)??crypto.getRandomValues(new Uint8Array(16)),F=(o==null?void 0:o.name)??"user",C=(o==null?void 0:o.displayName)??F,w=_(),d=await Le({rpName:a,rpId:i,userId:typeof R=="string"?R:Array.from(R).join(""),userName:F,userDisplayName:C,challenge:w});K("success"),d&&(v==null||v(d)),p==null||p({success:!0,confidence:1,method:"webauthn",timestamp:Date.now(),duration:0})}else{const R=await $e({rpId:i,challenge:_(),allowCredentials:r==null?void 0:r.map(F=>({id:new TextEncoder().encode(F),type:"public-key"}))});K("success"),R&&(A==null||A(R)),p==null||p({success:!0,confidence:1,method:"webauthn",timestamp:Date.now(),duration:0})}}catch(R){const F=R instanceof Error?R:new Error(String(R));F.name==="NotAllowedError"?K("idle"):(K("error"),D==null||D(F),p==null||p({success:!1,confidence:0,method:"webauthn",timestamp:Date.now(),duration:0}))}},[O,t,r,o,a,i,c,m,x,y,_,K,v,A,p,D]),$=t==="register"?B?l("security.webauthn.registerPasskey","Register Passkey"):l("security.webauthn.register","Register Security Key"):B?l("security.webauthn.signInPasskey","Sign in with Passkey"):l("security.webauthn.signIn","Sign in with Security Key"),E=b??$,q={primary:"var(--security-biometric)",outline:"transparent",ghost:"transparent"},W={primary:"none",outline:"2px solid var(--security-biometric)",ghost:"none"},Z={primary:"var(--nice-text-on-primary, #fff)",outline:"var(--security-biometric)",ghost:"var(--security-biometric)"},P=!O||f==="processing"||f==="success";return n.jsxs("div",{className:T,style:{display:u?"block":"inline-block",textAlign:"center"},children:[n.jsxs("button",{onClick:L,disabled:P,style:{width:u?"100%":"auto",padding:gt[k],fontSize:mt[k],fontWeight:600,fontFamily:"var(--security-font)",background:q[g],color:Z[g],border:W[g],borderRadius:"var(--security-radius)",cursor:P?"not-allowed":"pointer",opacity:P?.6:1,display:"inline-flex",alignItems:"center",justifyContent:"center",gap:8,transition:"opacity 0.2s, transform 0.1s"},children:[f==="processing"&&n.jsx("span",{style:{display:"inline-block",width:16,height:16,borderRadius:"50%",border:"2px solid transparent",borderTopColor:"currentColor",animation:"spin 0.6s linear infinite"}}),f==="success"&&n.jsx("span",{"aria-hidden":"true",style:{display:"inline-block",width:"0.3em",height:"0.6em",marginBottom:"0.15em",borderRight:"0.12em solid currentColor",borderBottom:"0.12em solid currentColor",transform:"rotate(45deg)"}}),S&&f!=="processing"&&f!=="success"&&S,E]}),!O&&n.jsx("div",{style:{fontSize:11,marginTop:6,color:"var(--security-warning)"},children:l("security.webauthn.notAvailable","WebAuthn is not supported in this browser")}),f==="error"&&n.jsx("div",{style:{fontSize:11,marginTop:6,color:"var(--security-error)"},children:l("security.webauthn.error","Authentication failed — try again")}),n.jsx("style",{children:"@keyframes spin { to { transform: rotate(360deg); } }"})]})},xt=e=>e>=80?"var(--security-error)":e>=50?"var(--security-warning)":"var(--security-success)",bt=({entries:e,pageSize:t=20,showExport:r=!0,filterMethods:s,onEntryClick:a,className:i,label:o})=>{const{t:c}=Q(),[m,x]=h.useState("all"),[y,v]=h.useState("all"),[A,p]=h.useState(0),I=h.useMemo(()=>{let l=[...e];return m!=="all"&&(l=l.filter(f=>f.method===m)),y!=="all"&&(l=l.filter(f=>f.status===y)),l.sort((f,z)=>z.timestamp-f.timestamp),l},[e,m,y]),D=Math.max(1,Math.ceil(I.length/t)),b=I.slice(A*t,(A+1)*t),T=h.useMemo(()=>s||Array.from(new Set(e.map(l=>l.method))),[e,s]),g=h.useMemo(()=>Array.from(new Set(e.map(l=>l.status))),[e]),k=h.useCallback(()=>{const l=new Blob([JSON.stringify(I,null,2)],{type:"application/json"}),f=URL.createObjectURL(l),z=document.createElement("a");z.href=f,z.download=`security-audit-${new Date().toISOString().slice(0,10)}.json`,z.click(),URL.revokeObjectURL(f)},[I]),u=l=>new Date(l).toLocaleString(),S={padding:"8px 12px",borderBottom:"1px solid var(--security-border)",fontSize:13,whiteSpace:"nowrap"};return n.jsxs("div",{className:i,style:{fontFamily:"var(--security-font)",color:"var(--security-text)",background:"var(--security-bg)",borderRadius:"var(--security-radius-lg)",border:"1px solid var(--security-border)",overflow:"hidden"},children:[n.jsxs("div",{style:{display:"flex",alignItems:"center",justifyContent:"space-between",padding:"12px 16px",background:"var(--security-bg-panel)",borderBottom:"1px solid var(--security-border)"},children:[n.jsx("div",{style:{fontWeight:600,fontSize:15},children:o??c("security.audit.title","Security Audit Log")}),n.jsxs("div",{style:{display:"flex",gap:8,alignItems:"center"},children:[n.jsxs("select",{value:m,onChange:l=>{x(l.target.value),p(0)},style:be,children:[n.jsx("option",{value:"all",children:c("security.audit.allMethods","All methods")}),T.map(l=>n.jsx("option",{value:l,children:l},l))]}),n.jsxs("select",{value:y,onChange:l=>{v(l.target.value),p(0)},style:be,children:[n.jsx("option",{value:"all",children:c("security.audit.allStatuses","All statuses")}),g.map(l=>n.jsx("option",{value:l,children:l},l))]}),r&&n.jsx("button",{onClick:k,style:wt,title:c("security.audit.exportJson","Export JSON"),children:"JSON"})]})]}),n.jsx("div",{style:{overflowX:"auto"},children:n.jsxs("table",{style:{width:"100%",borderCollapse:"collapse"},children:[n.jsx("thead",{children:n.jsxs("tr",{style:{background:"var(--security-bg-panel)",fontSize:12,color:"var(--security-text-secondary)",textTransform:"uppercase",letterSpacing:.5},children:[n.jsx("th",{style:{...S,textAlign:"left"},children:c("security.audit.time","Time")}),n.jsx("th",{style:{...S,textAlign:"left"},children:c("security.audit.action","Action")}),n.jsx("th",{style:{...S,textAlign:"center"},children:c("security.audit.method","Method")}),n.jsx("th",{style:{...S,textAlign:"center"},children:c("security.audit.status","Status")}),n.jsx("th",{style:{...S,textAlign:"center"},children:c("security.audit.risk","Risk")}),n.jsx("th",{style:{...S,textAlign:"left"},children:c("security.audit.device","Device")})]})}),n.jsxs("tbody",{children:[b.length===0&&n.jsx("tr",{children:n.jsx("td",{colSpan:6,style:{...S,textAlign:"center",color:"var(--security-text-muted)",padding:24},children:c("security.audit.noEntries","No entries to show")})}),b.map(l=>n.jsxs("tr",{onClick:()=>a==null?void 0:a(l),style:{cursor:a?"pointer":"default"},onMouseEnter:f=>{f.currentTarget.style.background="var(--security-bg-panel)"},onMouseLeave:f=>{f.currentTarget.style.background=""},children:[n.jsx("td",{style:S,children:u(l.timestamp)}),n.jsx("td",{style:S,children:l.action}),n.jsx("td",{style:{...S,textAlign:"center"},children:n.jsx("span",{style:{padding:"2px 8px",borderRadius:12,fontSize:11,fontWeight:600,background:"var(--security-bg-panel)",border:"1px solid var(--security-border)"},children:l.method})}),n.jsx("td",{style:{...S,textAlign:"center"},children:l.status}),n.jsx("td",{style:{...S,textAlign:"center"},children:l.riskScore!=null&&n.jsx("span",{style:{color:xt(l.riskScore),fontWeight:600},children:l.riskScore})}),n.jsx("td",{style:{...S,maxWidth:200,overflow:"hidden",textOverflow:"ellipsis"},children:l.device??"—"})]},l.id))]})]})}),D>1&&n.jsxs("div",{style:{display:"flex",justifyContent:"center",alignItems:"center",gap:12,padding:"10px 16px",fontSize:13,color:"var(--security-text-secondary)",borderTop:"1px solid var(--security-border)"},children:[n.jsxs("button",{disabled:A===0,onClick:()=>p(A-1),style:we,children:["← ",c("security.audit.prev","Prev")]}),n.jsxs("span",{children:[A+1," / ",D]}),n.jsxs("button",{disabled:A>=D-1,onClick:()=>p(A+1),style:we,children:[c("security.audit.next","Next")," →"]})]}),n.jsx("div",{style:{padding:"6px 16px",fontSize:11,color:"var(--security-text-muted)",textAlign:"right"},children:c("security.audit.total",`${I.length} entries`)})]})},be={fontSize:12,padding:"4px 8px",background:"var(--security-bg)",color:"var(--security-text)",border:"1px solid var(--security-border)",borderRadius:"var(--security-radius)"},wt={background:"none",border:"1px solid var(--security-border)",borderRadius:"var(--security-radius)",padding:"4px 8px",cursor:"pointer",fontSize:16},we={background:"none",border:"none",cursor:"pointer",color:"var(--security-biometric)",fontWeight:600,fontSize:13},Se={display:"inline-block",width:"0.3em",height:"0.6em",margin:"0 0.35em 0.15em 0.1em",borderRight:"0.12em solid currentColor",borderBottom:"0.12em solid currentColor",transform:"rotate(45deg)"},St=({options:e,requiredCount:t=1,onSelect:r,onComplete:s,className:a,label:i,layout:o="grid"})=>{const{t:c}=Q(),m=e.filter(y=>y.verified).length,x=m>=t;return n.jsxs("div",{className:a,style:{fontFamily:"var(--security-font)",color:"var(--security-text)",display:"flex",flexDirection:"column",gap:16},children:[i&&n.jsx("div",{style:{fontSize:15,fontWeight:600},children:i}),t>1&&n.jsx("div",{style:{fontSize:13,color:"var(--security-text-secondary)"},children:c("security.mfa.progress",`Verified ${m} of ${t} required`)}),n.jsx("div",{style:{display:o==="grid"?"grid":"flex",gridTemplateColumns:o==="grid"?"repeat(auto-fill, minmax(140px, 1fr))":void 0,flexDirection:o==="list"?"column":void 0,gap:12},children:e.map(y=>{const v=y.verified??!1,A=y.disabled||x;return n.jsxs("button",{onClick:()=>!A&&!v&&(r==null?void 0:r(y.method)),disabled:A||v,style:{display:"flex",flexDirection:o==="grid"?"column":"row",alignItems:"center",gap:o==="grid"?8:12,padding:o==="grid"?"20px 16px":"12px 16px",background:v?"rgba(16,185,129,0.08)":"var(--security-bg-panel)",border:`2px solid ${v?"var(--security-success)":"var(--security-border)"}`,borderRadius:"var(--security-radius-lg)",cursor:A||v?"default":"pointer",opacity:A&&!v?.5:1,transition:"border-color 0.2s, background 0.2s",textAlign:o==="grid"?"center":"left"},children:[n.jsx("span",{style:{fontSize:28},children:v?n.jsx("span",{"aria-label":"verified",style:{...Se,color:"var(--security-success)"}}):y.icon}),n.jsxs("div",{children:[n.jsx("div",{style:{fontSize:14,fontWeight:600,color:"var(--security-text)"},children:y.label??y.method}),y.description&&n.jsx("div",{style:{fontSize:11,color:"var(--security-text-muted)",marginTop:2},children:y.description})]})]},y.method)})}),x&&n.jsxs("div",{style:{textAlign:"center",fontSize:14,fontWeight:600,color:"var(--security-success)",padding:8},children:[n.jsx("span",{"aria-hidden":"true",style:Se}),c("security.mfa.complete","All factors verified")]})]})},kt=({sessions:e,onRevoke:t,onRevokeAll:r,onTrust:s,className:a,label:i,showRevokeAll:o=!0})=>{const{t:c}=Q(),[m,x]=h.useState(new Set),y=h.useMemo(()=>[...e].sort((p,I)=>(I.current?1:0)-(p.current?1:0)||I.lastActive-p.lastActive),[e]),v=p=>{const I=new Date(p),b=Date.now()-p;return b<6e4?c("security.session.justNow","Just now"):b<36e5?`${Math.floor(b/6e4)}m ago`:b<864e5?`${Math.floor(b/36e5)}h ago`:I.toLocaleDateString()},A=p=>{x(I=>new Set(I).add(p)),t==null||t(p)};return n.jsxs("div",{className:a,style:{fontFamily:"var(--security-font)",color:"var(--security-text)",background:"var(--security-bg)",borderRadius:"var(--security-radius-lg)",border:"1px solid var(--security-border)",overflow:"hidden"},children:[n.jsxs("div",{style:{display:"flex",alignItems:"center",justifyContent:"space-between",padding:"12px 16px",background:"var(--security-bg-panel)",borderBottom:"1px solid var(--security-border)"},children:[n.jsx("div",{style:{fontSize:15,fontWeight:600},children:i??c("security.session.title","Active Sessions")}),o&&e.length>1&&n.jsx("button",{onClick:r,style:{fontSize:12,padding:"4px 12px",background:"none",border:"1px solid var(--security-error)",borderRadius:"var(--security-radius)",color:"var(--security-error)",cursor:"pointer"},children:c("security.session.revokeAll","Revoke all others")})]}),n.jsxs("div",{children:[y.map(p=>n.jsxs("div",{style:{display:"flex",alignItems:"center",justifyContent:"space-between",padding:"12px 16px",borderBottom:"1px solid var(--security-border)",opacity:m.has(p.id)?.5:1,background:p.current?"rgba(59,130,246,0.04)":void 0},children:[n.jsxs("div",{style:{display:"flex",gap:12,alignItems:"center"},children:[n.jsx("span",{style:{fontSize:10,fontWeight:600,textTransform:"uppercase",color:"var(--security-text-muted)",minWidth:48},children:p.device.toLowerCase().includes("mobile")?c("security.session.mobile","Mobile"):c("security.session.desktop","Desktop")}),n.jsxs("div",{children:[n.jsxs("div",{style:{fontSize:14,fontWeight:500},children:[p.device,p.current&&n.jsx("span",{style:{marginLeft:8,fontSize:10,padding:"1px 6px",background:"var(--security-biometric)",color:"var(--nice-text-on-primary, #fff)",borderRadius:8},children:c("security.session.current","Current")}),p.trusted&&n.jsx("span",{style:{marginLeft:6,fontSize:10,padding:"1px 6px",background:"var(--nice-success-bg, #ecfdf5)",color:"var(--nice-success-text, #065f46)",borderRadius:8},children:c("security.session.trusted","Trusted")})]}),n.jsx("div",{style:{fontSize:12,color:"var(--security-text-muted)",marginTop:2},children:[p.browser,p.os,p.location].filter(Boolean).join(" · ")}),n.jsxs("div",{style:{fontSize:11,color:"var(--security-text-muted)",marginTop:1},children:[c("security.session.lastActive","Last active"),":"," ",v(p.lastActive)]})]})]}),n.jsxs("div",{style:{display:"flex",gap:6},children:[s&&!p.current&&n.jsx("button",{onClick:()=>s(p.id,!p.trusted),style:{fontSize:11,padding:"4px 8px",background:"none",border:"1px solid var(--security-border)",borderRadius:"var(--security-radius)",cursor:"pointer",color:"var(--security-text-secondary)"},children:p.trusted?c("security.session.untrust","Untrust"):c("security.session.trust","Trust")}),!p.current&&n.jsx("button",{onClick:()=>A(p.id),disabled:m.has(p.id),style:{fontSize:11,padding:"4px 10px",background:"none",border:"1px solid var(--security-error)",borderRadius:"var(--security-radius)",cursor:"pointer",color:"var(--security-error)"},children:c("security.session.revoke","Revoke")})]})]},p.id)),e.length===0&&n.jsx("div",{style:{padding:24,textAlign:"center",color:"var(--security-text-muted)",fontSize:13},children:c("security.session.noSessions","No active sessions")})]})]})},At=({trustScore:e,onScoreComputed:t,trustThreshold:r=60,showFactors:s=!0,showFingerprint:a=!1,className:i,label:o})=>{const{t:c}=Q(),[m,x]=h.useState(e??null),[y,v]=h.useState(!e),A=h.useCallback(async()=>{var I;v(!0);try{const D=ye(),b=await ie(),T=[];let g=50;D.platform&&!D.platform.includes("Linux")&&(T.push({name:"Known platform",score:5,description:"Running on a recognized platform",weight:.05}),g+=5),navigator.cookieEnabled&&(T.push({name:"Cookies enabled",score:5,description:"Browser cookies are enabled",weight:.05}),g+=5),D.screenResolution[0]>=360&&D.screenResolution[1]>=640&&(T.push({name:"Standard resolution",score:5,description:"Screen resolution within normal range",weight:.05}),g+=5),typeof window<"u"&&window.isSecureContext&&(T.push({name:"Secure context",score:10,description:"Running in HTTPS secure context",weight:.1}),g+=10),((I=navigator.languages)==null?void 0:I.length)>0&&(T.push({name:"Language configured",score:5,description:"Browser language is set",weight:.05}),g+=5),D.touchSupport&&(T.push({name:"Touch device",score:5,description:"Touch input is supported",weight:.05}),g+=5);try{const l=document.createElement("canvas").getContext("webgl");l&&l.getExtension("WEBGL_debug_renderer_info")&&(T.push({name:"Hardware GPU",score:10,description:"Hardware GPU detected",weight:.1}),g+=10)}catch{}navigator.credentials&&(T.push({name:"Credential API",score:5,description:"Credential Management API available",weight:.05}),g+=5),g=Math.min(100,Math.max(0,g));const k=Date.now(),u={score:g,factors:T,trusted:g>=r,firstSeen:k,lastSeen:k,fingerprint:b};x(u),t==null||t(u)}finally{v(!1)}},[r,t]);h.useEffect(()=>{e||A()},[e,A]),h.useEffect(()=>{e&&x(e)},[e]);const p=m?m.score>=80?"var(--security-success)":m.score>=50?"var(--security-warning)":"var(--security-error)":"var(--security-text-muted)";return n.jsxs("div",{className:i,style:{fontFamily:"var(--security-font)",color:"var(--security-text)",background:"var(--security-bg-panel)",borderRadius:"var(--security-radius-lg)",border:"1px solid var(--security-border)",padding:20,display:"flex",flexDirection:"column",gap:14,alignItems:"center"},children:[n.jsx("div",{style:{fontSize:15,fontWeight:600},children:o??c("security.trust.title","Device Trust")}),y?n.jsx("div",{style:{fontSize:13,color:"var(--security-text-muted)"},children:c("security.trust.computing","Analysing device…")}):m?n.jsxs(n.Fragment,{children:[n.jsxs("div",{style:{position:"relative",width:100,height:100},children:[n.jsxs("svg",{viewBox:"0 0 36 36",style:{width:"100%",height:"100%",transform:"rotate(-90deg)"},children:[n.jsx("circle",{cx:"18",cy:"18",r:"15.9",fill:"none",stroke:"var(--security-border)",strokeWidth:"2.5"}),n.jsx("circle",{cx:"18",cy:"18",r:"15.9",fill:"none",stroke:p,strokeWidth:"2.5",strokeDasharray:`${m.score}, 100`,strokeLinecap:"round"})]}),n.jsxs("div",{style:{position:"absolute",inset:0,display:"flex",flexDirection:"column",alignItems:"center",justifyContent:"center"},children:[n.jsx("span",{style:{fontSize:24,fontWeight:700,color:p},children:m.score}),n.jsx("span",{style:{fontSize:10,color:"var(--security-text-muted)"},children:"/100"})]})]}),n.jsx("div",{style:{fontSize:14,fontWeight:600,color:m.trusted?"var(--security-success)":"var(--security-warning)"},children:m.trusted?c("security.trust.trusted","Device Trusted"):c("security.trust.untrusted","Low Trust Score")}),s&&m.factors.length>0&&n.jsxs("div",{style:{width:"100%",fontSize:12},children:[n.jsxs("div",{style:{fontWeight:600,marginBottom:6,color:"var(--security-text-secondary)"},children:[c("security.trust.factors","Contributing factors"),":"]}),n.jsx("ul",{style:{margin:0,paddingLeft:18,color:"var(--security-text-muted)"},children:m.factors.map((I,D)=>n.jsx("li",{style:{marginBottom:2},children:I.name},D))})]}),a&&m.fingerprint&&n.jsx("div",{style:{fontSize:10,color:"var(--security-text-muted)",wordBreak:"break-all",textAlign:"center",maxWidth:280,fontFamily:"monospace"},children:m.fingerprint})]}):null]})};function jt(e){if(!e)return 0;let t=0;return e.length>=8&&t++,e.length>=12&&t++,/[a-z]/.test(e)&&/[A-Z]/.test(e)&&t++,/\d/.test(e)&&t++,/[^a-zA-Z0-9]/.test(e)&&t++,/(.)\1{3,}/.test(e)&&t--,Math.max(0,Math.min(4,t))}const Tt=["Very weak","Weak","Fair","Strong","Very strong"],ke=["var(--nice-danger, #ef4444)","var(--nice-warning, #f97316)","var(--nice-warning, #eab308)","var(--nice-success, #22c55e)","var(--nice-success, #10b981)"],Ct=({mode:e="verify",expectedHash:t,minStrength:r=2,minLength:s=8,onComplete:a,onVerify:i,onStatusChange:o,onError:c,label:m,placeholder:x,className:y,showStrength:v=!0,maxAttempts:A=5})=>{const{t:p}=Q(),[I,D]=h.useState(""),[b,T]=h.useState(""),[g,k]=h.useState(!1),[u,S]=h.useState("idle"),[l,f]=h.useState(0),[z,O]=h.useState(""),G=h.useRef(null),B=jt(I),H=h.useCallback(L=>{S(L),o==null||o(L)},[o]),K=h.useCallback(async()=>{if(O(""),H("processing"),e==="set"){if(I.length<s){O(p("security.passphrase.tooShort",`Minimum ${s} characters`)),H("idle");return}if(B<r){O(p("security.passphrase.tooWeak","Passphrase is too weak")),H("idle");return}if(I!==b){O(p("security.passphrase.noMatch","Passphrases do not match")),H("failure"),setTimeout(()=>H("idle"),1e3);return}a==null||a(I),H("success");return}if(t){const L=new TextEncoder,$=await crypto.subtle.digest("SHA-256",L.encode(I));if(Array.from(new Uint8Array($)).map(W=>W.toString(16).padStart(2,"0")).join("")===t)H("success"),i==null||i({success:!0,confidence:1,method:"passphrase",timestamp:Date.now(),duration:0}),a==null||a(I);else{const W=l+1;f(W),W>=A?(H("failure"),c==null||c(new Error("Too many failed attempts"))):(O(p("security.passphrase.incorrect","Incorrect passphrase")),H("idle")),i==null||i({success:!1,confidence:0,method:"passphrase",timestamp:Date.now(),duration:0})}}else a==null||a(I),H("success")},[I,b,e,t,B,r,s,l,A,p,H,a,i,c]),_={width:"100%",padding:"10px 14px",fontSize:14,background:"var(--security-bg)",color:"var(--security-text)",border:`1px solid ${u==="failure"?"var(--security-error)":"var(--security-border)"}`,borderRadius:"var(--security-radius)",boxSizing:"border-box",fontFamily:"var(--security-font)"};return n.jsxs("div",{className:y,style:{display:"flex",flexDirection:"column",gap:10,maxWidth:340,fontFamily:"var(--security-font)",color:"var(--security-text)"},children:[m&&n.jsx("label",{style:{fontSize:14,fontWeight:600},children:m}),n.jsxs("div",{style:{position:"relative"},children:[n.jsx("input",{ref:G,type:g?"text":"password",value:I,onChange:L=>D(L.target.value),placeholder:x??p("security.passphrase.placeholder","Enter passphrase"),style:_,disabled:u==="success",onKeyDown:L=>L.key==="Enter"&&K()}),n.jsx("button",{type:"button",onClick:()=>k(!g),style:{position:"absolute",right:8,top:"50%",transform:"translateY(-50%)",background:"none",border:"none",cursor:"pointer",fontSize:16,color:"var(--security-text-muted)"},tabIndex:-1,children:g?p("security.passphrase.hide","Hide"):p("security.passphrase.show","Show")})]}),e==="set"&&v&&I.length>0&&n.jsxs("div",{children:[n.jsx("div",{style:{display:"flex",gap:3,height:4},children:[0,1,2,3].map(L=>n.jsx("div",{style:{flex:1,borderRadius:2,background:L<B?ke[B]:"var(--security-border)",transition:"background 0.2s"}},L))}),n.jsx("div",{style:{fontSize:11,marginTop:4,color:ke[B]},children:p(`security.passphrase.strength${B}`,Tt[B])})]}),e==="set"&&n.jsx("input",{type:g?"text":"password",value:b,onChange:L=>T(L.target.value),placeholder:p("security.passphrase.confirmPlaceholder","Confirm passphrase"),style:_,disabled:u==="success",onKeyDown:L=>L.key==="Enter"&&K(),onPaste:L=>L.preventDefault()}),z&&n.jsx("div",{style:{fontSize:12,color:"var(--security-error)"},children:z}),n.jsx("button",{onClick:K,disabled:!I||u==="processing"||u==="success",style:{padding:"10px 20px",fontSize:14,fontWeight:600,background:u==="success"?"var(--security-success)":"var(--security-biometric)",color:"var(--nice-text-on-primary, #fff)",border:"none",borderRadius:"var(--security-radius)",cursor:u==="success"?"default":"pointer",opacity:!I||u==="processing"?.6:1},children:u==="success"?p("security.passphrase.accepted","Accepted"):e==="set"?p("security.passphrase.setBtn","Set Passphrase"):p("security.passphrase.verifyBtn","Verify")}),l>0&&u!=="success"&&n.jsx("div",{style:{fontSize:11,color:"var(--security-warning)"},children:p("security.passphrase.attempts",`${l}/${A} attempts`)})]})};function It(e){const t=[],r={defaultSrc:"default-src",scriptSrc:"script-src",styleSrc:"style-src",imgSrc:"img-src",fontSrc:"font-src",connectSrc:"connect-src",frameSrc:"frame-src",objectSrc:"object-src",mediaSrc:"media-src",workerSrc:"worker-src",childSrc:"child-src",formAction:"form-action",frameAncestors:"frame-ancestors",baseUri:"base-uri",reportUri:"report-uri",reportTo:"report-to",upgradeInsecureRequests:"upgrade-insecure-requests",blockAllMixedContent:"block-all-mixed-content"};return Object.entries(e.directives).forEach(([s,a])=>{const i=r[s];if(i){if(typeof a=="boolean")a&&t.push(i);else if(typeof a=="string")t.push(`${i} ${a}`);else if(Array.isArray(a)){let o=a;e.nonce&&(s==="scriptSrc"||s==="styleSrc")&&(o=[...o,`'nonce-${e.nonce}'`]),t.push(`${i} ${o.join(" ")}`)}}}),t.join("; ")}function Rt(e){const t="'self'";return{defaultSrc:[t],scriptSrc:[t],styleSrc:[t,"'unsafe-inline'"],imgSrc:[t,"data:","blob:",e==null?void 0:e.cdnDomain].filter(Boolean),fontSrc:[t,"data:",e==null?void 0:e.cdnDomain].filter(Boolean),connectSrc:[t,e==null?void 0:e.apiDomain,"wss:"].filter(Boolean),frameSrc:["'none'"],objectSrc:["'none'"],baseUri:[t],formAction:[t],frameAncestors:["'none'"],upgradeInsecureRequests:!0,reportUri:e==null?void 0:e.reportUri}}function Dt(){return typeof crypto<"u"&&crypto.randomUUID?crypto.randomUUID().replace(/-/g,""):Math.random().toString(36).substring(2)+Date.now().toString(36)}const Mt={"&":"&","<":"<",">":">",'"':""","'":"'","/":"/","`":"`","=":"="};function _e(e){return e.replace(/[&<>"'`=/]/g,t=>Mt[t]||t)}function Pt(e,t){let r=_e(e);return t!=null&&t.maxLength&&r.length>t.maxLength&&(r=r.substring(0,t.maxLength)),r}function Et(e){if(!e)return null;try{const t=new URL(e);return!["http:","https:","mailto:","tel:"].includes(t.protocol)||e.toLowerCase().includes("javascript:")?null:t.toString()}catch{return null}}function Ft(e){const t=["script","iframe","object","embed","form"];let r=e;t.forEach(i=>{const o=new RegExp(`<${i}[^>]*>.*?</${i}>`,"gi");r=r.replace(o,"");const c=new RegExp(`<${i}[^>]*/>`,"gi");r=r.replace(c,"")});const s=/\s+on\w+\s*=/gi;r=r.replace(s," data-removed=");const a=/javascript:/gi;return r=r.replace(a,""),r}function Nt(e,t){let r=e;if(t!=null&&t.allowedTags){const s=/<\/?([a-z][a-z0-9]*)[^>]*>/gi;r=r.replace(s,(a,i)=>t.allowedTags.includes(i.toLowerCase())?a:"")}return r=r.replace(/\s+on\w+\s*=/gi," data-removed="),r=r.replace(/javascript:/gi,""),{__html:r}}const ge={headerName:"X-CSRF-Token",cookieName:"XSRF-TOKEN",fieldName:"_csrf"};function zt(){if(typeof crypto<"u"){const e=new Uint8Array(32);return crypto.getRandomValues(e),Array.from(e,t=>t.toString(16).padStart(2,"0")).join("")}return Math.random().toString(36).substring(2)+Date.now().toString(36)}function me(e=ge.cookieName){if(typeof document>"u")return null;const t=document.cookie.match(new RegExp(`(^| )${e}=([^;]+)`));return t?decodeURIComponent(t[2]):null}function Lt(e=ge){return async function(r,s={}){const a=me(e.cookieName);a||console.warn("CSRF token not found");const i=new Headers(s.headers);return a&&e.headerName&&i.set(e.headerName,a),fetch(r,{...s,headers:i})}}function $t(e=ge){const t=me(e.cookieName);return{token:t,inputProps:{type:"hidden",name:e.fieldName,value:t||""},headerName:e.headerName}}function We(e){const t=new Map,r=e.keyGenerator||(i=>i.url);function s(i){const o=r(i),c=Date.now();let m=t.get(o);(!m||c>m.resetAt)&&(m={count:0,resetAt:c+e.windowMs}),m.count++,t.set(o,m);const x=m.count<=e.maxRequests,y=Math.max(0,e.maxRequests-m.count);return{allowed:x,remaining:y,resetAt:m.resetAt}}function a(i){i?t.delete(i):t.clear()}return{checkLimit:s,reset:a}}function Bt(e){const t=We(e);return{checkAndFetch:async(s,a)=>{const i=t.checkLimit({url:s,method:a==null?void 0:a.method});if(!i.allowed){const o=Math.ceil((i.resetAt-Date.now())/1e3);throw new Error(`Rate limit exceeded. Retry after ${o} seconds.`)}return fetch(s,a)},checkLimit:t.checkLimit,reset:t.reset}}function He(e,t){const r=[];if(t.allowedTypes&&t.allowedTypes.length>0&&(t.allowedTypes.includes(e.type)||r.push(`File type '${e.type}' is not allowed. Allowed types: ${t.allowedTypes.join(", ")}`)),t.maxSize&&e.size>t.maxSize){const i=(t.maxSize/1048576).toFixed(2),o=(e.size/(1024*1024)).toFixed(2);r.push(`File size (${o}MB) exceeds maximum allowed size (${i}MB)`)}const s=[".exe",".bat",".cmd",".sh",".ps1",".vbs",".js",".jar"],a=e.name.toLowerCase();for(const i of s)if(a.includes(i+".")||a.endsWith(i)){r.push(`File extension '${i}' is not allowed`);break}return{valid:r.length===0,errors:r,file:r.length===0?e:void 0}}function _t(e,t){const r=[],s=[],a=[];t.maxFiles&&e.length>t.maxFiles&&r.push(`Too many files. Maximum allowed: ${t.maxFiles}`);const i=e.reduce((o,c)=>o+c.size,0);if(t.maxTotalSize&&i>t.maxTotalSize){const o=(t.maxTotalSize/1048576).toFixed(2),c=(i/(1024*1024)).toFixed(2);r.push(`Total file size (${c}MB) exceeds maximum (${o}MB)`)}return e.forEach(o=>{const c=He(o,t);c.valid?s.push(o):a.push({file:o,errors:c.errors})}),{valid:r.length===0&&a.length===0,errors:[...r,...a.flatMap(o=>o.errors)],validFiles:s,invalidFiles:a}}async function Wt(e,t){const r=new FormData;r.append("file",e);try{const s=await fetch(t,{method:"POST",body:r});if(!s.ok)throw new Error("Virus scan failed");return await s.json()}catch(s){return console.error("Virus scan error:",s),{clean:!1,threat:"Scan failed"}}}function Ue(){if(typeof localStorage>"u")return null;const e=localStorage.getItem("nice2dev_consent");if(!e)return null;try{return JSON.parse(e)}catch{return null}}function Ht(e){typeof localStorage>"u"||localStorage.setItem("nice2dev_consent",JSON.stringify({...e,necessary:!0,timestamp:new Date().toISOString()}))}function Ut(e){const t=Ue();return t?t[e]===!0:!1}function Ot(e){if(typeof document>"u")return;document.cookie.split(";").forEach(r=>{const[s]=r.trim().split("=");e.includes(s)||(document.cookie=`${s}=; expires=Thu, 01 Jan 1970 00:00:00 UTC; path=/;`)})}async function qt(e,t,r=fetch){const s={exportDate:new Date().toISOString(),userId:e};return await Promise.all(Object.entries(t).map(async([a,i])=>{try{const o=await r(i);o.ok&&(s[a]=await o.json())}catch(o){console.error(`Failed to fetch ${a} data:`,o),s[a]={error:"Failed to retrieve data"}}})),s}async function Kt(e,t,r=fetch){try{const s=await r(t,{method:"DELETE",headers:{"Content-Type":"application/json"},body:JSON.stringify({userId:e,timestamp:new Date().toISOString()})});return s.ok?{success:!0,confirmationId:(await s.json()).confirmationId}:{success:!1,error:"Deletion request failed"}}catch(s){return{success:!1,error:String(s)}}}function Gt(e,t){var s;const r={...e,id:((s=crypto.randomUUID)==null?void 0:s.call(crypto))||Math.random().toString(36),timestamp:new Date};return t&&fetch(t,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(r)}).catch(console.error),process.env.NODE_ENV==="development"&&console.warn("[HIPAA] PHI Access:",r),r}function Jt(e){let t=null,r=null,s=Date.now();const a=e.timeoutMinutes*60*1e3,i=e.warningBeforeMs||6e4;function o(){s=Date.now(),t&&clearTimeout(t),r&&clearTimeout(r),e.onWarning&&(r=setTimeout(()=>{var y;const x=a-(Date.now()-s);(y=e.onWarning)==null||y.call(e,x)},a-i)),t=setTimeout(e.onTimeout,a)}function c(){t&&clearTimeout(t),r&&clearTimeout(r)}function m(){return Math.max(0,a-(Date.now()-s))}return o(),typeof window<"u"&&["mousedown","keypress","touchstart","scroll"].forEach(y=>{window.addEventListener(y,o,{passive:!0})}),{resetTimer:o,destroy:c,getTimeRemaining:m}}function Yt(e,t){const r=o=>{const c=o.replace("#",""),m=parseInt(c.substr(0,2),16)/255,x=parseInt(c.substr(2,2),16)/255,y=parseInt(c.substr(4,2),16)/255,v=A=>A<=.03928?A/12.92:Math.pow((A+.055)/1.055,2.4);return .2126*v(m)+.7152*v(x)+.0722*v(y)},s=r(e),a=r(t),i=(Math.max(s,a)+.05)/(Math.min(s,a)+.05);return{ratio:Math.round(i*100)/100,passesAA:i>=4.5,passesAAA:i>=7,passesAALarge:i>=3,passesAAALarge:i>=4.5}}function Zt(e){var r,s,a;if(e.getAttribute("aria-label"))return!0;const t=e.getAttribute("aria-labelledby");if(t){const i=document.getElementById(t);if((r=i==null?void 0:i.textContent)!=null&&r.trim())return!0}if(e.id){const i=document.querySelector(`label[for="${e.id}"]`);if((s=i==null?void 0:i.textContent)!=null&&s.trim())return!0}return!!((a=e.textContent)!=null&&a.trim()||e.getAttribute("title")||e.placeholder)}function Xt(e){const r=(e||document.body).querySelectorAll("h1, h2, h3, h4, h5, h6"),s=[];let a=0,i=!1;return r.forEach(o=>{const c=parseInt(o.tagName[1]);c===1&&(i&&s.push({level:c,element:o,issue:"Multiple H1 elements found"}),i=!0),c>a+1&&a!==0&&s.push({level:c,element:o,issue:`Skipped heading level: H${a} to H${c}`}),a=c}),!i&&r.length>0&&s.push({level:0,element:r[0],issue:"Missing H1 element"}),{valid:s.length===0,issues:s}}function Qt(e){const t=[];let r=null;const s=e.batchSize||10,a=e.flushInterval||5e3;async function i(){if(t.length===0)return;const x=t.splice(0,s);try{await fetch(e.endpoint,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({entries:x})})}catch(y){console.error("Failed to send audit logs:",y),t.unshift(...x)}}function o(){r||(r=setTimeout(()=>{r=null,i()},a))}function c(x){var v;const y={...x,id:((v=crypto.randomUUID)==null?void 0:v.call(crypto))||Math.random().toString(36),timestamp:new Date,userAgent:e.includeUserAgent&&typeof navigator<"u"?navigator.userAgent:void 0};t.push(y),t.length>=s?i():o()}function m(){r&&clearTimeout(r),i()}return{log:c,flush:i,destroy:m}}function Vt(){return[{controlId:"CC6.1",name:"Logical and Physical Access Controls",category:"security",status:"in_progress",lastAssessed:new Date},{controlId:"CC6.2",name:"User Registration and Authorization",category:"security",status:"in_progress",lastAssessed:new Date},{controlId:"CC6.3",name:"Access Control Removal",category:"security",status:"in_progress",lastAssessed:new Date},{controlId:"A1.1",name:"System Capacity",category:"availability",status:"in_progress",lastAssessed:new Date},{controlId:"A1.2",name:"Backup and Recovery",category:"availability",status:"in_progress",lastAssessed:new Date},{controlId:"C1.1",name:"Confidential Information Classification",category:"confidentiality",status:"in_progress",lastAssessed:new Date},{controlId:"C1.2",name:"Confidential Information Disposal",category:"confidentiality",status:"in_progress",lastAssessed:new Date},{controlId:"P1.1",name:"Privacy Notice",category:"privacy",status:"in_progress",lastAssessed:new Date},{controlId:"P2.1",name:"Consent",category:"privacy",status:"in_progress",lastAssessed:new Date},{controlId:"P3.1",name:"Collection",category:"privacy",status:"in_progress",lastAssessed:new Date}]}const er={hardcodedSecrets:[{pattern:/password\s*[:=]\s*["'][^"']+["']/gi,name:"Hardcoded password"},{pattern:/api[_-]?key\s*[:=]\s*["'][^"']+["']/gi,name:"Hardcoded API key"},{pattern:/secret\s*[:=]\s*["'][^"']+["']/gi,name:"Hardcoded secret"},{pattern:/token\s*[:=]\s*["'][^"']+["']/gi,name:"Hardcoded token"}],sqlInjection:[{pattern:/execute\s*\(\s*["'`].*\$\{/gi,name:"Potential SQL injection (template literal)"},{pattern:/query\s*\(\s*["'`].*\+/gi,name:"Potential SQL injection (string concatenation)"}],xss:[{pattern:/dangerouslySetInnerHTML/g,name:"dangerouslySetInnerHTML usage"},{pattern:/innerHTML\s*=/g,name:"innerHTML assignment"},{pattern:/document\.write\s*\(/g,name:"document.write usage"},{pattern:/eval\s*\(/g,name:"eval usage"}],insecureFunctions:[{pattern:/Math\.random\s*\(\)/g,name:"Insecure random (use crypto)"},{pattern:/new Function\s*\(/g,name:"Function constructor (code injection risk)"},{pattern:/setTimeout\s*\(\s*["']/g,name:"setTimeout with string (code injection)"},{pattern:/setInterval\s*\(\s*["']/g,name:"setInterval with string (code injection)"}],infoExposure:[{pattern:/console\.(log|info|warn|error)\s*\(/g,name:"Console logging (remove in production)"},{pattern:/debugger/g,name:"Debugger statement"},{pattern:/TODO.*password/gi,name:"TODO mentioning password"}]};function tr(){return`# .github/workflows/sast.yml
|
|
6
|
+
`})]})},st={sm:240,md:320,lg:440},nt=e=>{const{mode:t,enrolledTemplates:r=[],referencePhoto:s,onEnroll:a,onVerify:i,onStatusChange:o,onError:c,className:m,size:x="md",label:y,showQuality:v=!0,showBoundingBox:A=!0,livenessSteps:p=1,showReference:I=!0,instructionText:D,...b}=e,{t:T}=Q(),g=oe(b),k=st[x],u=h.useRef(null),S=h.useRef(null),l=h.useRef(null),[f,z]=h.useState("idle"),[O,G]=h.useState(0),[B,H]=h.useState(0),[K,_]=h.useState(""),[L,$]=h.useState(null),[E,q]=h.useState(0),W=h.useCallback(w=>{z(w),o==null||o(w)},[o]),Z=h.useCallback(async()=>{try{const w=await le("user");l.current=w,u.current&&(u.current.srcObject=w,await u.current.play()),W("idle"),_(T("security.face.lookAtCamera","Look at the camera"))}catch(w){c==null||c(w instanceof Error?w:new Error(String(w))),_(T("security.face.cameraError","Camera access denied")),W("error")}},[T,W,c]),P=h.useCallback(()=>{var w;(w=l.current)==null||w.getTracks().forEach(d=>d.stop()),l.current=null},[]);h.useEffect(()=>(Z(),P),[Z,P]);const R=h.useCallback(w=>{var ee,ve,xe;const d=(ee=S.current)==null?void 0:ee.getContext("2d");if(!d)return;const j=S.current.width,N=S.current.height;if(d.clearRect(0,0,j,N),!w||!A)return;const M=w.boundingBox,U=j/(((ve=u.current)==null?void 0:ve.videoWidth)??j),J=N/(((xe=u.current)==null?void 0:xe.videoHeight)??N);d.strokeStyle=V(f==="success"?"var(--nice-success, #10b981)":"var(--nice-primary, #3b82f6)",d.canvas),d.lineWidth=2,d.setLineDash([6,4]),d.strokeRect(M.x*U,M.y*J,M.width*U,M.height*J),d.setLineDash([]);const X=[[M.x*U,M.y*J],[(M.x+M.width)*U,M.y*J],[M.x*U,(M.y+M.height)*J],[(M.x+M.width)*U,(M.y+M.height)*J]],Y=12;d.lineWidth=3;for(const[te,re]of X)d.beginPath(),d.moveTo(te===M.x*U?te:te-Y,re),d.lineTo(te,re),d.lineTo(te,re===M.y*J?re+Y:re-Y),d.stroke()},[A,f]),F=h.useCallback(async()=>{if(!(!u.current||f==="processing"||f==="success")){W("scanning"),_(T("security.face.scanning","Scanning face…"));try{if(g.livenessDetection){const j=[];for(let M=0;M<8;M++)j.push(se(u.current).imageData),await new Promise(U=>setTimeout(U,200));if(!fe(j).isLive){_(T("security.face.notLive","Liveness check failed — move naturally")),W("idle");return}}W("processing"),_(T("security.face.processing","Analysing face…"));const{imageData:w}=se(u.current);if(t==="compare"&&s){const j=typeof s=="string"?await it(s):at(s),{similarity:N,cameraFeatures:M,refFeatures:U}=Ee(w,j);q(N),G((M==null?void 0:M.quality)??0),R(M);const X={success:N>=g.matchThreshold,confidence:N,method:"face",timestamp:Date.now(),duration:0,livenessPassed:g.livenessDetection};X.success?(_(T("security.face.matchFound",`Match: ${(N*100).toFixed(0)}%`)),W("success")):(H(Y=>Y+1),B+1>=g.maxRetries?(_(T("security.face.maxAttempts","Maximum attempts reached")),W("failure")):(_(T("security.face.noMatch","No match — try again")),W("idle"))),i==null||i(X);return}const d=ae(w);if(!d){_(T("security.face.noFaceDetected","No face detected")),W("idle");return}if(G(d.quality),R(d),t==="enroll"){const j=await Fe(d,y??"face");a==null||a(j,d),_(T("security.face.enrolled","Face enrolled successfully")),W("success")}else{let j=0;for(const U of r){const J=Ne(U),X=he(d,J);X>j&&(j=X)}q(j);const N=j>=g.matchThreshold,M={success:N,confidence:j,method:"face",timestamp:Date.now(),duration:0,livenessPassed:g.livenessDetection};if(N&&g.verifyEndpoint){const U=await ie(),J=await ue(g.verifyEndpoint,{method:"face",templateData:btoa(JSON.stringify(d)),matchScore:j,deviceFingerprint:U},g.authToken);M.success=J.verified}M.success?(_(T("security.face.verified","Face verified")),W("success")):(H(U=>U+1),B+1>=g.maxRetries?(_(T("security.face.maxAttempts","Maximum attempts reached")),W("failure")):(_(T("security.face.noMatch","No match — try again")),W("idle"))),i==null||i(M)}}catch(w){c==null||c(w instanceof Error?w:new Error(String(w))),_(T("security.face.error","Error — try again")),W("error")}}},[f,t,r,s,g,T,W,a,i,c,y,B,R]),C=f==="success"?"var(--security-success)":f==="failure"||f==="error"?"var(--security-error)":f==="scanning"||f==="processing"?"var(--security-biometric)":"var(--security-border)";return n.jsxs("div",{className:m,style:{display:"inline-flex",flexDirection:"column",alignItems:"center",gap:12},children:[y&&n.jsx("div",{style:{fontSize:14,fontWeight:600,color:"var(--security-text)"},children:y}),n.jsxs("div",{style:{display:"flex",gap:16,alignItems:"center"},children:[n.jsxs("div",{style:{width:k,height:k*.75,position:"relative",borderRadius:"var(--security-radius-lg)",overflow:"hidden",border:`3px solid ${C}`,boxShadow:f==="scanning"?`0 0 20px ${C}`:"var(--security-shadow)",transition:"border-color 0.3s, box-shadow 0.3s"},children:[n.jsx("video",{ref:u,style:{width:"100%",height:"100%",objectFit:"cover",transform:"scaleX(-1)"},playsInline:!0,muted:!0}),n.jsx("canvas",{ref:S,width:k,height:k*.75,style:{position:"absolute",inset:0,pointerEvents:"none",transform:"scaleX(-1)"}}),n.jsx("svg",{viewBox:"0 0 100 75",style:{position:"absolute",inset:0,width:"100%",height:"100%",pointerEvents:"none",opacity:.3},children:n.jsx("ellipse",{cx:"50",cy:"37",rx:"22",ry:"30",fill:"none",stroke:"white",strokeWidth:"0.8",strokeDasharray:"4 3"})}),(f==="scanning"||f==="processing")&&n.jsx("div",{style:{position:"absolute",inset:0,background:"var(--nice-overlay-15, rgba(0, 0, 0, 0.15))",display:"flex",alignItems:"center",justifyContent:"center"},children:n.jsx("div",{style:{width:50,height:50,borderRadius:"50%",border:"3px solid transparent",borderTopColor:C,animation:"spin 0.8s linear infinite"}})})]}),t==="compare"&&I&&s&&n.jsxs("div",{style:{width:k*.4,height:k*.5,borderRadius:"var(--security-radius)",overflow:"hidden",border:"2px solid var(--security-border)"},children:[n.jsx("img",{src:typeof s=="string"?s:void 0,alt:T("security.face.referenceAlt","Reference"),style:{width:"100%",height:"100%",objectFit:"cover"}}),n.jsx("div",{style:{textAlign:"center",fontSize:10,padding:4,color:"var(--security-text-muted)",background:"var(--security-bg-panel)"},children:T("security.face.reference","Reference")})]})]}),E>0&&n.jsxs("div",{style:{display:"flex",alignItems:"center",gap:8,fontSize:13},children:[n.jsxs("span",{style:{color:"var(--security-text-secondary)"},children:[T("security.face.confidence","Confidence"),":"]}),n.jsx("div",{style:{width:100,height:6,background:"var(--security-bg-panel)",borderRadius:3,overflow:"hidden"},children:n.jsx("div",{style:{width:`${E*100}%`,height:"100%",background:E>=g.matchThreshold?"var(--security-success)":"var(--security-warning)"}})}),n.jsxs("span",{style:{fontWeight:600,color:E>=g.matchThreshold?"var(--security-success)":"var(--security-warning)"},children:[(E*100).toFixed(0),"%"]})]}),n.jsx("div",{style:{fontSize:13,color:"var(--security-text-secondary)",textAlign:"center",minHeight:20},children:D??K}),f!=="success"&&f!=="failure"&&n.jsx("button",{onClick:F,disabled:f==="scanning"||f==="processing",style:{padding:"10px 24px",fontSize:14,fontWeight:600,background:"var(--security-biometric)",color:"var(--nice-color-white, #fff)",border:"none",borderRadius:"var(--security-radius)",cursor:"pointer",opacity:f==="scanning"||f==="processing"?.6:1},children:t==="enroll"?T("security.face.captureBtn","Capture Face"):t==="compare"?T("security.face.compareBtn","Compare"):T("security.face.verifyBtn","Verify Face")}),(f==="failure"||f==="error")&&n.jsx("button",{onClick:()=>{H(0),q(0),W("idle"),_("")},style:{padding:"8px 20px",fontSize:13,background:"var(--security-bg-panel)",color:"var(--security-text)",border:"1px solid var(--security-border)",borderRadius:"var(--security-radius)",cursor:"pointer"},children:T("security.common.retry","Try Again")}),n.jsx("style",{children:"@keyframes spin { to { transform: rotate(360deg); } }"})]})};async function it(e){return new Promise((t,r)=>{const s=new Image;s.crossOrigin="anonymous",s.onload=()=>{const a=document.createElement("canvas");a.width=s.naturalWidth,a.height=s.naturalHeight;const i=a.getContext("2d");i.drawImage(s,0,0),t(i.getImageData(0,0,a.width,a.height))},s.onerror=()=>r(new Error("Failed to load reference image")),s.src=e})}function at(e){const t=document.createElement("canvas");t.width=e.naturalWidth||e.width,t.height=e.naturalHeight||e.height;const r=t.getContext("2d");return r.drawImage(e,0,0),r.getImageData(0,0,t.width,t.height)}const ot=4,ct=5,lt=3e4,ut=e=>{const{length:t=ot,scramble:r=!1,showDigits:s=!1,maxAttempts:a=ct,lockoutDuration:i=lt,keySize:o=64,haptic:c=!0,keyLabels:m,expectedHash:x,expectedPin:y,mode:v="verify",onComplete:A,onVerify:p,onStatusChange:I,onError:D,showBiometricFallback:b=!1,onBiometricFallback:T,label:g,className:k}=e,{t:u}=Q(),[S,l]=h.useState([]),[f,z]=h.useState("idle"),[O,G]=h.useState(0),[B,H]=h.useState(0),[K,_]=h.useState(null),L=h.useRef(void 0),$=h.useMemo(()=>{const F=["1","2","3","4","5","6","7","8","9","","0","back"];if(!r)return F;const C=["0","1","2","3","4","5","6","7","8","9"];for(let w=C.length-1;w>0;w--){const d=new Uint32Array(1);crypto.getRandomValues(d);const j=d[0]%(w+1);[C[w],C[j]]=[C[j],C[w]]}return[C[0],C[1],C[2],C[3],C[4],C[5],C[6],C[7],C[8],"",C[9],"back"]},[r,f]),E=h.useCallback(F=>{z(F),I==null||I(F)},[I]);h.useEffect(()=>{if(!(B<=Date.now()))return L.current=setInterval(()=>{Date.now()>=B&&(clearInterval(L.current),E("idle"),G(0),l([]))},500),()=>clearInterval(L.current)},[B,E]);const q=B>Date.now(),W=h.useCallback(()=>{c&&navigator.vibrate&&navigator.vibrate(20)},[c]),Z=h.useCallback(async F=>{if(q||f==="success")return;if(W(),F==="back"){l(j=>j.slice(0,-1));return}if(F==="")return;const C=[...S,F];if(l(C),C.length<t)return;const w=C.join("");if(E("processing"),v==="set"){if(K===null){_(w),l([]),E("idle");return}if(K!==w){_(null),l([]),E("failure"),setTimeout(()=>E("idle"),1200);return}A==null||A(w),E("success");return}let d=!1;if(x){const j=new TextEncoder,N=await crypto.subtle.digest("SHA-256",j.encode(w));d=Array.from(new Uint8Array(N)).map(U=>U.toString(16).padStart(2,"0")).join("")===x}else if(y)d=w===y;else{A==null||A(w),E("success");return}if(d)E("success"),p==null||p({success:!0,confidence:1,method:"pin",timestamp:Date.now(),duration:0}),A==null||A(w);else{const j=O+1;if(G(j),j>=a){const N=Date.now()+i;H(N),E("failure"),D==null||D(new Error("Too many failed PIN attempts"))}else E("failure"),setTimeout(()=>{E("idle"),l([])},800);p==null||p({success:!1,confidence:0,method:"pin",timestamp:Date.now(),duration:0})}},[S,t,q,f,v,K,x,y,O,a,i,W,E,A,p,D]),P=Math.max(0,Math.ceil((B-Date.now())/1e3)),R=f==="success"?"var(--security-success)":f==="failure"?"var(--security-error)":"var(--security-border)";return n.jsxs("div",{className:k,style:{display:"inline-flex",flexDirection:"column",alignItems:"center",gap:16,fontFamily:"var(--security-font)",color:"var(--security-text)"},children:[g&&n.jsx("div",{style:{fontSize:14,fontWeight:600},children:g}),n.jsx("div",{style:{fontSize:13,color:"var(--security-text-secondary)",minHeight:18,textAlign:"center"},children:q?u("security.pin.locked",`Locked — try again in ${P}s`):v==="set"&&K!==null?u("security.pin.confirm","Confirm your PIN"):v==="set"?u("security.pin.setNew","Enter a new PIN"):u("security.pin.enter","Enter your PIN")}),n.jsx("div",{style:{display:"flex",gap:12},children:Array.from({length:t},(F,C)=>n.jsx("div",{style:{width:16,height:16,borderRadius:"50%",border:`2px solid ${R}`,background:C<S.length?R:"transparent",transition:"background 0.15s, border-color 0.15s"}},C))}),n.jsx("div",{style:{display:"grid",gridTemplateColumns:`repeat(3, ${o}px)`,gap:10,opacity:q?.4:1,pointerEvents:q?"none":"auto"},children:$.map((F,C)=>{if(F==="")return n.jsx("div",{},C);const w=F==="back";return n.jsx("button",{onClick:()=>Z(F),disabled:q||f==="success","aria-label":w?"Backspace":F,style:{width:o,height:o,borderRadius:"var(--security-key-border-radius, 50%)",border:"1px solid var(--security-key-border, var(--security-border))",background:"var(--security-key-bg, var(--security-bg-panel))",color:"var(--security-key-text, var(--security-text))",fontSize:w?20:22,fontWeight:600,cursor:"pointer",display:"flex",alignItems:"center",justifyContent:"center",transition:"background 0.1s, transform 0.1s",userSelect:"none"},onMouseDown:d=>{d.currentTarget.style.transform="scale(0.92)"},onMouseUp:d=>{d.currentTarget.style.transform=""},onMouseLeave:d=>{d.currentTarget.style.transform=""},children:w?"⌫":(m==null?void 0:m[F])??F},C)})}),S.length>0&&f!=="success"&&n.jsx("button",{onClick:()=>l([]),style:{fontSize:12,background:"none",border:"none",color:"var(--security-text-secondary)",cursor:"pointer",textDecoration:"underline"},children:u("security.pin.clear","Clear")}),b&&n.jsx("button",{onClick:T,style:{fontSize:13,padding:"8px 16px",background:"none",border:"1px solid var(--security-border)",borderRadius:"var(--security-radius)",color:"var(--security-biometric)",cursor:"pointer"},children:u("security.pin.biometricFallback","Use biometrics instead")}),O>0&&f!=="success"&&!q&&n.jsx("div",{style:{fontSize:11,color:"var(--security-warning)"},children:u("security.pin.attempts",`${O}/${a} attempts`)})]})},dt=3,ht=4,ft=5,yt=14,pt=e=>{const{gridSize:t=dt,minLength:r=ht,showTrail:s=!0,showError:a=!0,maxAttempts:i=ft,dotSize:o=yt,trailColor:c,mode:m="verify",expectedHash:x,expectedPattern:y,onComplete:v,onVerify:A,onStatusChange:p,onError:I,label:D,className:b,canvasSize:T}=e,{t:g}=Q(),k=h.useRef(null),[u,S]=h.useState([]),[l,f]=h.useState(!1),[z,O]=h.useState("idle"),[G,B]=h.useState(0),[H,K]=h.useState(null),[_,L]=h.useState(null),$=T??t*80,E=$/t,q=h.useCallback(d=>{O(d),p==null||p(d)},[p]),W=h.useCallback(()=>{const d=[];for(let j=0;j<t;j++)for(let N=0;N<t;N++)d.push({x:N*E+E/2,y:j*E+E/2});return d},[t,E]),Z=h.useCallback(d=>{const j=k.current.getBoundingClientRect(),N="touches"in d?d.touches[0].clientX:d.clientX,M="touches"in d?d.touches[0].clientY:d.clientY;return{x:N-j.left,y:M-j.top}},[]),P=h.useCallback((d,j)=>{const N=W(),M=E*.38;for(let U=0;U<N.length;U++){const J=N[U].x-d,X=N[U].y-j;if(J*J+X*X<M*M)return U}return-1},[W,E]),R=h.useCallback(()=>{var X;const d=(X=k.current)==null?void 0:X.getContext("2d");if(!d)return;d.clearRect(0,0,$,$);const j=W(),N=z==="failure",M=d.canvas,U=V(N&&a?"var(--security-error)":c??"var(--security-biometric)",M),J=V("var(--security-border)",M);for(let Y=0;Y<j.length;Y++){const ee=u.includes(Y);d.beginPath(),d.arc(j[Y].x,j[Y].y,ee?o*.75:o*.5,0,Math.PI*2),d.fillStyle=ee?U:J,d.fill(),ee&&(d.beginPath(),d.arc(j[Y].x,j[Y].y,o*1.2,0,Math.PI*2),d.strokeStyle=U,d.lineWidth=1.5,d.globalAlpha=.3,d.stroke(),d.globalAlpha=1)}if(s&&u.length>1){d.beginPath(),d.moveTo(j[u[0]].x,j[u[0]].y);for(let Y=1;Y<u.length;Y++)d.lineTo(j[u[Y]].x,j[u[Y]].y);l&&_&&d.lineTo(_.x,_.y),d.strokeStyle=U,d.lineWidth=3,d.lineCap="round",d.lineJoin="round",d.globalAlpha=.5,d.stroke(),d.globalAlpha=1}else s&&u.length===1&&l&&_&&(d.beginPath(),d.moveTo(j[u[0]].x,j[u[0]].y),d.lineTo(_.x,_.y),d.strokeStyle=V(c??"var(--security-biometric)",M),d.lineWidth=3,d.globalAlpha=.4,d.stroke(),d.globalAlpha=1)},[$,W,o,u,l,_,z,s,a,c]);h.useEffect(()=>{R()},[R]);const F=h.useCallback(d=>{if(z==="success"||z==="failure")return;d.preventDefault();const{x:j,y:N}=Z(d),M=P(j,N);M>=0&&(f(!0),S([M]),L({x:j,y:N}))},[z,Z,P]),C=h.useCallback(d=>{if(!l)return;d.preventDefault();const{x:j,y:N}=Z(d);L({x:j,y:N});const M=P(j,N);M>=0&&!u.includes(M)&&S(U=>[...U,M])},[l,Z,P,u]),w=h.useCallback(async()=>{if(!l)return;if(f(!1),L(null),u.length<r){S([]);return}const d=u.join(",");if(m==="set"){if(H===null){K([...u]),S([]);return}if(H.join(",")!==d){K(null),q("failure"),setTimeout(()=>{q("idle"),S([])},800);return}v==null||v([...u]),q("success");return}q("processing");let j=!1;if(x){const N=new TextEncoder,M=await crypto.subtle.digest("SHA-256",N.encode(d));j=Array.from(new Uint8Array(M)).map(J=>J.toString(16).padStart(2,"0")).join("")===x}else if(y)j=d===y;else{v==null||v([...u]),q("success");return}if(j)q("success"),A==null||A({success:!0,confidence:1,method:"pattern",timestamp:Date.now(),duration:0}),v==null||v([...u]);else{const N=G+1;B(N),q("failure"),N>=i&&(I==null||I(new Error("Too many failed pattern attempts"))),setTimeout(()=>{q("idle"),S([])},900),A==null||A({success:!1,confidence:0,method:"pattern",timestamp:Date.now(),duration:0})}},[l,u,r,m,H,x,y,G,i,q,v,A,I]);return n.jsxs("div",{className:b,style:{display:"inline-flex",flexDirection:"column",alignItems:"center",gap:12,fontFamily:"var(--security-font)",color:"var(--security-text)"},children:[D&&n.jsx("div",{style:{fontSize:14,fontWeight:600},children:D}),n.jsx("div",{style:{fontSize:13,color:"var(--security-text-secondary)",minHeight:18,textAlign:"center"},children:z==="success"?g("security.pattern.success","Pattern accepted"):z==="failure"?g("security.pattern.wrong","Wrong pattern"):m==="set"&&H!==null?g("security.pattern.confirm","Draw pattern again to confirm"):m==="set"?g("security.pattern.setNew","Draw a new pattern"):g("security.pattern.draw","Draw your pattern")}),n.jsx("canvas",{ref:k,width:$,height:$,style:{touchAction:"none",borderRadius:"var(--security-radius-lg)",background:"var(--security-bg-panel)",border:`1px solid ${z==="failure"?"var(--security-error)":"var(--security-border)"}`,cursor:"pointer",transition:"border-color 0.3s"},onMouseDown:F,onMouseMove:C,onMouseUp:w,onMouseLeave:w,onTouchStart:F,onTouchMove:C,onTouchEnd:w}),(z==="failure"||z==="success")&&n.jsx("button",{onClick:()=>{S([]),B(0),K(null),q("idle")},style:{fontSize:13,padding:"6px 16px",background:"var(--security-bg-panel)",border:"1px solid var(--security-border)",borderRadius:"var(--security-radius)",color:"var(--security-text)",cursor:"pointer"},children:g("security.common.retry","Try Again")}),G>0&&z!=="success"&&n.jsx("div",{style:{fontSize:11,color:"var(--security-warning)"},children:g("security.pattern.attempts",`${G}/${i} attempts`)})]})},gt={sm:"8px 16px",md:"12px 24px",lg:"14px 32px"},mt={sm:13,md:14,lg:16},vt=e=>{const{mode:t,credentialIds:r=[],challenge:s,rpName:a=window.location.hostname,rpId:i=window.location.hostname,user:o,attestation:c="none",authenticatorAttachment:m,residentKey:x="preferred",userVerification:y="preferred",onRegister:v,onAuthenticate:A,onVerify:p,onStatusChange:I,onError:D,label:b,className:T,variant:g="primary",size:k="md",fullWidth:u=!1,icon:S}=e,{t:l}=Q(),[f,z]=h.useState("idle"),[O,G]=h.useState(!0),[B,H]=h.useState(!1),K=h.useCallback(R=>{z(R),I==null||I(R)},[I]);h.useEffect(()=>{G(pe()),ze().then(H)},[]);const _=h.useCallback(()=>{if(s){const R=atob(s.replace(/-/g,"+").replace(/_/g,"/")),F=new Uint8Array(R.length);for(let C=0;C<R.length;C++)F[C]=R.charCodeAt(C);return F.buffer}return crypto.getRandomValues(new Uint8Array(32)).buffer},[s]),L=h.useCallback(async()=>{if(!O){D==null||D(new Error("WebAuthn not available"));return}K("processing");try{if(t==="register"){const R=(o==null?void 0:o.id)??crypto.getRandomValues(new Uint8Array(16)),F=(o==null?void 0:o.name)??"user",C=(o==null?void 0:o.displayName)??F,w=_(),d=await Le({rpName:a,rpId:i,userId:typeof R=="string"?R:Array.from(R).join(""),userName:F,userDisplayName:C,challenge:w});K("success"),d&&(v==null||v(d)),p==null||p({success:!0,confidence:1,method:"webauthn",timestamp:Date.now(),duration:0})}else{const R=await $e({rpId:i,challenge:_(),allowCredentials:r==null?void 0:r.map(F=>({id:new TextEncoder().encode(F),type:"public-key"}))});K("success"),R&&(A==null||A(R)),p==null||p({success:!0,confidence:1,method:"webauthn",timestamp:Date.now(),duration:0})}}catch(R){const F=R instanceof Error?R:new Error(String(R));F.name==="NotAllowedError"?K("idle"):(K("error"),D==null||D(F),p==null||p({success:!1,confidence:0,method:"webauthn",timestamp:Date.now(),duration:0}))}},[O,t,r,o,a,i,c,m,x,y,_,K,v,A,p,D]),$=t==="register"?B?l("security.webauthn.registerPasskey","Register Passkey"):l("security.webauthn.register","Register Security Key"):B?l("security.webauthn.signInPasskey","Sign in with Passkey"):l("security.webauthn.signIn","Sign in with Security Key"),E=b??$,q={primary:"var(--security-biometric)",outline:"transparent",ghost:"transparent"},W={primary:"none",outline:"2px solid var(--security-biometric)",ghost:"none"},Z={primary:"var(--nice-color-white, #fff)",outline:"var(--security-biometric)",ghost:"var(--security-biometric)"},P=!O||f==="processing"||f==="success";return n.jsxs("div",{className:T,style:{display:u?"block":"inline-block",textAlign:"center"},children:[n.jsxs("button",{onClick:L,disabled:P,style:{width:u?"100%":"auto",padding:gt[k],fontSize:mt[k],fontWeight:600,fontFamily:"var(--security-font)",background:q[g],color:Z[g],border:W[g],borderRadius:"var(--security-radius)",cursor:P?"not-allowed":"pointer",opacity:P?.6:1,display:"inline-flex",alignItems:"center",justifyContent:"center",gap:8,transition:"opacity 0.2s, transform 0.1s"},children:[f==="processing"&&n.jsx("span",{style:{display:"inline-block",width:16,height:16,borderRadius:"50%",border:"2px solid transparent",borderTopColor:"currentColor",animation:"spin 0.6s linear infinite"}}),f==="success"&&n.jsx("span",{"aria-hidden":"true",style:{display:"inline-block",width:"0.3em",height:"0.6em",marginBottom:"0.15em",borderRight:"0.12em solid currentColor",borderBottom:"0.12em solid currentColor",transform:"rotate(45deg)"}}),S&&f!=="processing"&&f!=="success"&&S,E]}),!O&&n.jsx("div",{style:{fontSize:11,marginTop:6,color:"var(--security-warning)"},children:l("security.webauthn.notAvailable","WebAuthn is not supported in this browser")}),f==="error"&&n.jsx("div",{style:{fontSize:11,marginTop:6,color:"var(--security-error)"},children:l("security.webauthn.error","Authentication failed — try again")}),n.jsx("style",{children:"@keyframes spin { to { transform: rotate(360deg); } }"})]})},xt=e=>e>=80?"var(--security-error)":e>=50?"var(--security-warning)":"var(--security-success)",bt=({entries:e,pageSize:t=20,showExport:r=!0,filterMethods:s,onEntryClick:a,className:i,label:o})=>{const{t:c}=Q(),[m,x]=h.useState("all"),[y,v]=h.useState("all"),[A,p]=h.useState(0),I=h.useMemo(()=>{let l=[...e];return m!=="all"&&(l=l.filter(f=>f.method===m)),y!=="all"&&(l=l.filter(f=>f.status===y)),l.sort((f,z)=>z.timestamp-f.timestamp),l},[e,m,y]),D=Math.max(1,Math.ceil(I.length/t)),b=I.slice(A*t,(A+1)*t),T=h.useMemo(()=>s||Array.from(new Set(e.map(l=>l.method))),[e,s]),g=h.useMemo(()=>Array.from(new Set(e.map(l=>l.status))),[e]),k=h.useCallback(()=>{const l=new Blob([JSON.stringify(I,null,2)],{type:"application/json"}),f=URL.createObjectURL(l),z=document.createElement("a");z.href=f,z.download=`security-audit-${new Date().toISOString().slice(0,10)}.json`,z.click(),URL.revokeObjectURL(f)},[I]),u=l=>new Date(l).toLocaleString(),S={padding:"8px 12px",borderBottom:"1px solid var(--security-border)",fontSize:13,whiteSpace:"nowrap"};return n.jsxs("div",{className:i,style:{fontFamily:"var(--security-font)",color:"var(--security-text)",background:"var(--security-bg)",borderRadius:"var(--security-radius-lg)",border:"1px solid var(--security-border)",overflow:"hidden"},children:[n.jsxs("div",{style:{display:"flex",alignItems:"center",justifyContent:"space-between",padding:"12px 16px",background:"var(--security-bg-panel)",borderBottom:"1px solid var(--security-border)"},children:[n.jsx("div",{style:{fontWeight:600,fontSize:15},children:o??c("security.audit.title","Security Audit Log")}),n.jsxs("div",{style:{display:"flex",gap:8,alignItems:"center"},children:[n.jsxs("select",{value:m,onChange:l=>{x(l.target.value),p(0)},style:be,children:[n.jsx("option",{value:"all",children:c("security.audit.allMethods","All methods")}),T.map(l=>n.jsx("option",{value:l,children:l},l))]}),n.jsxs("select",{value:y,onChange:l=>{v(l.target.value),p(0)},style:be,children:[n.jsx("option",{value:"all",children:c("security.audit.allStatuses","All statuses")}),g.map(l=>n.jsx("option",{value:l,children:l},l))]}),r&&n.jsx("button",{onClick:k,style:wt,title:c("security.audit.exportJson","Export JSON"),children:"JSON"})]})]}),n.jsx("div",{style:{overflowX:"auto"},children:n.jsxs("table",{style:{width:"100%",borderCollapse:"collapse"},children:[n.jsx("thead",{children:n.jsxs("tr",{style:{background:"var(--security-bg-panel)",fontSize:12,color:"var(--security-text-secondary)",textTransform:"uppercase",letterSpacing:.5},children:[n.jsx("th",{style:{...S,textAlign:"left"},children:c("security.audit.time","Time")}),n.jsx("th",{style:{...S,textAlign:"left"},children:c("security.audit.action","Action")}),n.jsx("th",{style:{...S,textAlign:"center"},children:c("security.audit.method","Method")}),n.jsx("th",{style:{...S,textAlign:"center"},children:c("security.audit.status","Status")}),n.jsx("th",{style:{...S,textAlign:"center"},children:c("security.audit.risk","Risk")}),n.jsx("th",{style:{...S,textAlign:"left"},children:c("security.audit.device","Device")})]})}),n.jsxs("tbody",{children:[b.length===0&&n.jsx("tr",{children:n.jsx("td",{colSpan:6,style:{...S,textAlign:"center",color:"var(--security-text-muted)",padding:24},children:c("security.audit.noEntries","No entries to show")})}),b.map(l=>n.jsxs("tr",{onClick:()=>a==null?void 0:a(l),style:{cursor:a?"pointer":"default"},onMouseEnter:f=>{f.currentTarget.style.background="var(--security-bg-panel)"},onMouseLeave:f=>{f.currentTarget.style.background=""},children:[n.jsx("td",{style:S,children:u(l.timestamp)}),n.jsx("td",{style:S,children:l.action}),n.jsx("td",{style:{...S,textAlign:"center"},children:n.jsx("span",{style:{padding:"2px 8px",borderRadius:12,fontSize:11,fontWeight:600,background:"var(--security-bg-panel)",border:"1px solid var(--security-border)"},children:l.method})}),n.jsx("td",{style:{...S,textAlign:"center"},children:l.status}),n.jsx("td",{style:{...S,textAlign:"center"},children:l.riskScore!=null&&n.jsx("span",{style:{color:xt(l.riskScore),fontWeight:600},children:l.riskScore})}),n.jsx("td",{style:{...S,maxWidth:200,overflow:"hidden",textOverflow:"ellipsis"},children:l.device??"—"})]},l.id))]})]})}),D>1&&n.jsxs("div",{style:{display:"flex",justifyContent:"center",alignItems:"center",gap:12,padding:"10px 16px",fontSize:13,color:"var(--security-text-secondary)",borderTop:"1px solid var(--security-border)"},children:[n.jsxs("button",{disabled:A===0,onClick:()=>p(A-1),style:we,children:["← ",c("security.audit.prev","Prev")]}),n.jsxs("span",{children:[A+1," / ",D]}),n.jsxs("button",{disabled:A>=D-1,onClick:()=>p(A+1),style:we,children:[c("security.audit.next","Next")," →"]})]}),n.jsx("div",{style:{padding:"6px 16px",fontSize:11,color:"var(--security-text-muted)",textAlign:"right"},children:c("security.audit.total",`${I.length} entries`)})]})},be={fontSize:12,padding:"4px 8px",background:"var(--security-bg)",color:"var(--security-text)",border:"1px solid var(--security-border)",borderRadius:"var(--security-radius)"},wt={background:"none",border:"1px solid var(--security-border)",borderRadius:"var(--security-radius)",padding:"4px 8px",cursor:"pointer",fontSize:16},we={background:"none",border:"none",cursor:"pointer",color:"var(--security-biometric)",fontWeight:600,fontSize:13},Se={display:"inline-block",width:"0.3em",height:"0.6em",margin:"0 0.35em 0.15em 0.1em",borderRight:"0.12em solid currentColor",borderBottom:"0.12em solid currentColor",transform:"rotate(45deg)"},St=({options:e,requiredCount:t=1,onSelect:r,onComplete:s,className:a,label:i,layout:o="grid"})=>{const{t:c}=Q(),m=e.filter(y=>y.verified).length,x=m>=t;return n.jsxs("div",{className:a,style:{fontFamily:"var(--security-font)",color:"var(--security-text)",display:"flex",flexDirection:"column",gap:16},children:[i&&n.jsx("div",{style:{fontSize:15,fontWeight:600},children:i}),t>1&&n.jsx("div",{style:{fontSize:13,color:"var(--security-text-secondary)"},children:c("security.mfa.progress",`Verified ${m} of ${t} required`)}),n.jsx("div",{style:{display:o==="grid"?"grid":"flex",gridTemplateColumns:o==="grid"?"repeat(auto-fill, minmax(140px, 1fr))":void 0,flexDirection:o==="list"?"column":void 0,gap:12},children:e.map(y=>{const v=y.verified??!1,A=y.disabled||x;return n.jsxs("button",{onClick:()=>!A&&!v&&(r==null?void 0:r(y.method)),disabled:A||v,style:{display:"flex",flexDirection:o==="grid"?"column":"row",alignItems:"center",gap:o==="grid"?8:12,padding:o==="grid"?"20px 16px":"12px 16px",background:v?"rgba(16,185,129,0.08)":"var(--security-bg-panel)",border:`2px solid ${v?"var(--security-success)":"var(--security-border)"}`,borderRadius:"var(--security-radius-lg)",cursor:A||v?"default":"pointer",opacity:A&&!v?.5:1,transition:"border-color 0.2s, background 0.2s",textAlign:o==="grid"?"center":"left"},children:[n.jsx("span",{style:{fontSize:28},children:v?n.jsx("span",{"aria-label":"verified",style:{...Se,color:"var(--security-success)"}}):y.icon}),n.jsxs("div",{children:[n.jsx("div",{style:{fontSize:14,fontWeight:600,color:"var(--security-text)"},children:y.label??y.method}),y.description&&n.jsx("div",{style:{fontSize:11,color:"var(--security-text-muted)",marginTop:2},children:y.description})]})]},y.method)})}),x&&n.jsxs("div",{style:{textAlign:"center",fontSize:14,fontWeight:600,color:"var(--security-success)",padding:8},children:[n.jsx("span",{"aria-hidden":"true",style:Se}),c("security.mfa.complete","All factors verified")]})]})},kt=({sessions:e,onRevoke:t,onRevokeAll:r,onTrust:s,className:a,label:i,showRevokeAll:o=!0})=>{const{t:c}=Q(),[m,x]=h.useState(new Set),y=h.useMemo(()=>[...e].sort((p,I)=>(I.current?1:0)-(p.current?1:0)||I.lastActive-p.lastActive),[e]),v=p=>{const I=new Date(p),b=Date.now()-p;return b<6e4?c("security.session.justNow","Just now"):b<36e5?`${Math.floor(b/6e4)}m ago`:b<864e5?`${Math.floor(b/36e5)}h ago`:I.toLocaleDateString()},A=p=>{x(I=>new Set(I).add(p)),t==null||t(p)};return n.jsxs("div",{className:a,style:{fontFamily:"var(--security-font)",color:"var(--security-text)",background:"var(--security-bg)",borderRadius:"var(--security-radius-lg)",border:"1px solid var(--security-border)",overflow:"hidden"},children:[n.jsxs("div",{style:{display:"flex",alignItems:"center",justifyContent:"space-between",padding:"12px 16px",background:"var(--security-bg-panel)",borderBottom:"1px solid var(--security-border)"},children:[n.jsx("div",{style:{fontSize:15,fontWeight:600},children:i??c("security.session.title","Active Sessions")}),o&&e.length>1&&n.jsx("button",{onClick:r,style:{fontSize:12,padding:"4px 12px",background:"none",border:"1px solid var(--security-error)",borderRadius:"var(--security-radius)",color:"var(--security-error)",cursor:"pointer"},children:c("security.session.revokeAll","Revoke all others")})]}),n.jsxs("div",{children:[y.map(p=>n.jsxs("div",{style:{display:"flex",alignItems:"center",justifyContent:"space-between",padding:"12px 16px",borderBottom:"1px solid var(--security-border)",opacity:m.has(p.id)?.5:1,background:p.current?"rgba(59,130,246,0.04)":void 0},children:[n.jsxs("div",{style:{display:"flex",gap:12,alignItems:"center"},children:[n.jsx("span",{style:{fontSize:10,fontWeight:600,textTransform:"uppercase",color:"var(--security-text-muted)",minWidth:48},children:p.device.toLowerCase().includes("mobile")?c("security.session.mobile","Mobile"):c("security.session.desktop","Desktop")}),n.jsxs("div",{children:[n.jsxs("div",{style:{fontSize:14,fontWeight:500},children:[p.device,p.current&&n.jsx("span",{style:{marginLeft:8,fontSize:10,padding:"1px 6px",background:"var(--security-biometric)",color:"var(--nice-color-white, #fff)",borderRadius:8},children:c("security.session.current","Current")}),p.trusted&&n.jsx("span",{style:{marginLeft:6,fontSize:10,padding:"1px 6px",background:"var(--nice-success-bg, #ecfdf5)",color:"var(--nice-success-text, #065f46)",borderRadius:8},children:c("security.session.trusted","Trusted")})]}),n.jsx("div",{style:{fontSize:12,color:"var(--security-text-muted)",marginTop:2},children:[p.browser,p.os,p.location].filter(Boolean).join(" · ")}),n.jsxs("div",{style:{fontSize:11,color:"var(--security-text-muted)",marginTop:1},children:[c("security.session.lastActive","Last active"),":"," ",v(p.lastActive)]})]})]}),n.jsxs("div",{style:{display:"flex",gap:6},children:[s&&!p.current&&n.jsx("button",{onClick:()=>s(p.id,!p.trusted),style:{fontSize:11,padding:"4px 8px",background:"none",border:"1px solid var(--security-border)",borderRadius:"var(--security-radius)",cursor:"pointer",color:"var(--security-text-secondary)"},children:p.trusted?c("security.session.untrust","Untrust"):c("security.session.trust","Trust")}),!p.current&&n.jsx("button",{onClick:()=>A(p.id),disabled:m.has(p.id),style:{fontSize:11,padding:"4px 10px",background:"none",border:"1px solid var(--security-error)",borderRadius:"var(--security-radius)",cursor:"pointer",color:"var(--security-error)"},children:c("security.session.revoke","Revoke")})]})]},p.id)),e.length===0&&n.jsx("div",{style:{padding:24,textAlign:"center",color:"var(--security-text-muted)",fontSize:13},children:c("security.session.noSessions","No active sessions")})]})]})},At=({trustScore:e,onScoreComputed:t,trustThreshold:r=60,showFactors:s=!0,showFingerprint:a=!1,className:i,label:o})=>{const{t:c}=Q(),[m,x]=h.useState(e??null),[y,v]=h.useState(!e),A=h.useCallback(async()=>{var I;v(!0);try{const D=ye(),b=await ie(),T=[];let g=50;D.platform&&!D.platform.includes("Linux")&&(T.push({name:"Known platform",score:5,description:"Running on a recognized platform",weight:.05}),g+=5),navigator.cookieEnabled&&(T.push({name:"Cookies enabled",score:5,description:"Browser cookies are enabled",weight:.05}),g+=5),D.screenResolution[0]>=360&&D.screenResolution[1]>=640&&(T.push({name:"Standard resolution",score:5,description:"Screen resolution within normal range",weight:.05}),g+=5),typeof window<"u"&&window.isSecureContext&&(T.push({name:"Secure context",score:10,description:"Running in HTTPS secure context",weight:.1}),g+=10),((I=navigator.languages)==null?void 0:I.length)>0&&(T.push({name:"Language configured",score:5,description:"Browser language is set",weight:.05}),g+=5),D.touchSupport&&(T.push({name:"Touch device",score:5,description:"Touch input is supported",weight:.05}),g+=5);try{const l=document.createElement("canvas").getContext("webgl");l&&l.getExtension("WEBGL_debug_renderer_info")&&(T.push({name:"Hardware GPU",score:10,description:"Hardware GPU detected",weight:.1}),g+=10)}catch{}navigator.credentials&&(T.push({name:"Credential API",score:5,description:"Credential Management API available",weight:.05}),g+=5),g=Math.min(100,Math.max(0,g));const k=Date.now(),u={score:g,factors:T,trusted:g>=r,firstSeen:k,lastSeen:k,fingerprint:b};x(u),t==null||t(u)}finally{v(!1)}},[r,t]);h.useEffect(()=>{e||A()},[e,A]),h.useEffect(()=>{e&&x(e)},[e]);const p=m?m.score>=80?"var(--security-success)":m.score>=50?"var(--security-warning)":"var(--security-error)":"var(--security-text-muted)";return n.jsxs("div",{className:i,style:{fontFamily:"var(--security-font)",color:"var(--security-text)",background:"var(--security-bg-panel)",borderRadius:"var(--security-radius-lg)",border:"1px solid var(--security-border)",padding:20,display:"flex",flexDirection:"column",gap:14,alignItems:"center"},children:[n.jsx("div",{style:{fontSize:15,fontWeight:600},children:o??c("security.trust.title","Device Trust")}),y?n.jsx("div",{style:{fontSize:13,color:"var(--security-text-muted)"},children:c("security.trust.computing","Analysing device…")}):m?n.jsxs(n.Fragment,{children:[n.jsxs("div",{style:{position:"relative",width:100,height:100},children:[n.jsxs("svg",{viewBox:"0 0 36 36",style:{width:"100%",height:"100%",transform:"rotate(-90deg)"},children:[n.jsx("circle",{cx:"18",cy:"18",r:"15.9",fill:"none",stroke:"var(--security-border)",strokeWidth:"2.5"}),n.jsx("circle",{cx:"18",cy:"18",r:"15.9",fill:"none",stroke:p,strokeWidth:"2.5",strokeDasharray:`${m.score}, 100`,strokeLinecap:"round"})]}),n.jsxs("div",{style:{position:"absolute",inset:0,display:"flex",flexDirection:"column",alignItems:"center",justifyContent:"center"},children:[n.jsx("span",{style:{fontSize:24,fontWeight:700,color:p},children:m.score}),n.jsx("span",{style:{fontSize:10,color:"var(--security-text-muted)"},children:"/100"})]})]}),n.jsx("div",{style:{fontSize:14,fontWeight:600,color:m.trusted?"var(--security-success)":"var(--security-warning)"},children:m.trusted?c("security.trust.trusted","Device Trusted"):c("security.trust.untrusted","Low Trust Score")}),s&&m.factors.length>0&&n.jsxs("div",{style:{width:"100%",fontSize:12},children:[n.jsxs("div",{style:{fontWeight:600,marginBottom:6,color:"var(--security-text-secondary)"},children:[c("security.trust.factors","Contributing factors"),":"]}),n.jsx("ul",{style:{margin:0,paddingLeft:18,color:"var(--security-text-muted)"},children:m.factors.map((I,D)=>n.jsx("li",{style:{marginBottom:2},children:I.name},D))})]}),a&&m.fingerprint&&n.jsx("div",{style:{fontSize:10,color:"var(--security-text-muted)",wordBreak:"break-all",textAlign:"center",maxWidth:280,fontFamily:"monospace"},children:m.fingerprint})]}):null]})};function jt(e){if(!e)return 0;let t=0;return e.length>=8&&t++,e.length>=12&&t++,/[a-z]/.test(e)&&/[A-Z]/.test(e)&&t++,/\d/.test(e)&&t++,/[^a-zA-Z0-9]/.test(e)&&t++,/(.)\1{3,}/.test(e)&&t--,Math.max(0,Math.min(4,t))}const Tt=["Very weak","Weak","Fair","Strong","Very strong"],ke=["var(--nice-danger, #ef4444)","var(--nice-warning, #f97316)","var(--nice-warning, #eab308)","var(--nice-success, #22c55e)","var(--nice-success, #10b981)"],Ct=({mode:e="verify",expectedHash:t,minStrength:r=2,minLength:s=8,onComplete:a,onVerify:i,onStatusChange:o,onError:c,label:m,placeholder:x,className:y,showStrength:v=!0,maxAttempts:A=5})=>{const{t:p}=Q(),[I,D]=h.useState(""),[b,T]=h.useState(""),[g,k]=h.useState(!1),[u,S]=h.useState("idle"),[l,f]=h.useState(0),[z,O]=h.useState(""),G=h.useRef(null),B=jt(I),H=h.useCallback(L=>{S(L),o==null||o(L)},[o]),K=h.useCallback(async()=>{if(O(""),H("processing"),e==="set"){if(I.length<s){O(p("security.passphrase.tooShort",`Minimum ${s} characters`)),H("idle");return}if(B<r){O(p("security.passphrase.tooWeak","Passphrase is too weak")),H("idle");return}if(I!==b){O(p("security.passphrase.noMatch","Passphrases do not match")),H("failure"),setTimeout(()=>H("idle"),1e3);return}a==null||a(I),H("success");return}if(t){const L=new TextEncoder,$=await crypto.subtle.digest("SHA-256",L.encode(I));if(Array.from(new Uint8Array($)).map(W=>W.toString(16).padStart(2,"0")).join("")===t)H("success"),i==null||i({success:!0,confidence:1,method:"passphrase",timestamp:Date.now(),duration:0}),a==null||a(I);else{const W=l+1;f(W),W>=A?(H("failure"),c==null||c(new Error("Too many failed attempts"))):(O(p("security.passphrase.incorrect","Incorrect passphrase")),H("idle")),i==null||i({success:!1,confidence:0,method:"passphrase",timestamp:Date.now(),duration:0})}}else a==null||a(I),H("success")},[I,b,e,t,B,r,s,l,A,p,H,a,i,c]),_={width:"100%",padding:"10px 14px",fontSize:14,background:"var(--security-bg)",color:"var(--security-text)",border:`1px solid ${u==="failure"?"var(--security-error)":"var(--security-border)"}`,borderRadius:"var(--security-radius)",boxSizing:"border-box",fontFamily:"var(--security-font)"};return n.jsxs("div",{className:y,style:{display:"flex",flexDirection:"column",gap:10,maxWidth:340,fontFamily:"var(--security-font)",color:"var(--security-text)"},children:[m&&n.jsx("label",{style:{fontSize:14,fontWeight:600},children:m}),n.jsxs("div",{style:{position:"relative"},children:[n.jsx("input",{ref:G,type:g?"text":"password",value:I,onChange:L=>D(L.target.value),placeholder:x??p("security.passphrase.placeholder","Enter passphrase"),style:_,disabled:u==="success",onKeyDown:L=>L.key==="Enter"&&K()}),n.jsx("button",{type:"button",onClick:()=>k(!g),style:{position:"absolute",right:8,top:"50%",transform:"translateY(-50%)",background:"none",border:"none",cursor:"pointer",fontSize:16,color:"var(--security-text-muted)"},tabIndex:-1,children:g?p("security.passphrase.hide","Hide"):p("security.passphrase.show","Show")})]}),e==="set"&&v&&I.length>0&&n.jsxs("div",{children:[n.jsx("div",{style:{display:"flex",gap:3,height:4},children:[0,1,2,3].map(L=>n.jsx("div",{style:{flex:1,borderRadius:2,background:L<B?ke[B]:"var(--security-border)",transition:"background 0.2s"}},L))}),n.jsx("div",{style:{fontSize:11,marginTop:4,color:ke[B]},children:p(`security.passphrase.strength${B}`,Tt[B])})]}),e==="set"&&n.jsx("input",{type:g?"text":"password",value:b,onChange:L=>T(L.target.value),placeholder:p("security.passphrase.confirmPlaceholder","Confirm passphrase"),style:_,disabled:u==="success",onKeyDown:L=>L.key==="Enter"&&K(),onPaste:L=>L.preventDefault()}),z&&n.jsx("div",{style:{fontSize:12,color:"var(--security-error)"},children:z}),n.jsx("button",{onClick:K,disabled:!I||u==="processing"||u==="success",style:{padding:"10px 20px",fontSize:14,fontWeight:600,background:u==="success"?"var(--security-success)":"var(--security-biometric)",color:"var(--nice-color-white, #fff)",border:"none",borderRadius:"var(--security-radius)",cursor:u==="success"?"default":"pointer",opacity:!I||u==="processing"?.6:1},children:u==="success"?p("security.passphrase.accepted","Accepted"):e==="set"?p("security.passphrase.setBtn","Set Passphrase"):p("security.passphrase.verifyBtn","Verify")}),l>0&&u!=="success"&&n.jsx("div",{style:{fontSize:11,color:"var(--security-warning)"},children:p("security.passphrase.attempts",`${l}/${A} attempts`)})]})};function It(e){const t=[],r={defaultSrc:"default-src",scriptSrc:"script-src",styleSrc:"style-src",imgSrc:"img-src",fontSrc:"font-src",connectSrc:"connect-src",frameSrc:"frame-src",objectSrc:"object-src",mediaSrc:"media-src",workerSrc:"worker-src",childSrc:"child-src",formAction:"form-action",frameAncestors:"frame-ancestors",baseUri:"base-uri",reportUri:"report-uri",reportTo:"report-to",upgradeInsecureRequests:"upgrade-insecure-requests",blockAllMixedContent:"block-all-mixed-content"};return Object.entries(e.directives).forEach(([s,a])=>{const i=r[s];if(i){if(typeof a=="boolean")a&&t.push(i);else if(typeof a=="string")t.push(`${i} ${a}`);else if(Array.isArray(a)){let o=a;e.nonce&&(s==="scriptSrc"||s==="styleSrc")&&(o=[...o,`'nonce-${e.nonce}'`]),t.push(`${i} ${o.join(" ")}`)}}}),t.join("; ")}function Rt(e){const t="'self'";return{defaultSrc:[t],scriptSrc:[t],styleSrc:[t,"'unsafe-inline'"],imgSrc:[t,"data:","blob:",e==null?void 0:e.cdnDomain].filter(Boolean),fontSrc:[t,"data:",e==null?void 0:e.cdnDomain].filter(Boolean),connectSrc:[t,e==null?void 0:e.apiDomain,"wss:"].filter(Boolean),frameSrc:["'none'"],objectSrc:["'none'"],baseUri:[t],formAction:[t],frameAncestors:["'none'"],upgradeInsecureRequests:!0,reportUri:e==null?void 0:e.reportUri}}function Dt(){return typeof crypto<"u"&&crypto.randomUUID?crypto.randomUUID().replace(/-/g,""):Math.random().toString(36).substring(2)+Date.now().toString(36)}const Mt={"&":"&","<":"<",">":">",'"':""","'":"'","/":"/","`":"`","=":"="};function _e(e){return e.replace(/[&<>"'`=/]/g,t=>Mt[t]||t)}function Pt(e,t){let r=_e(e);return t!=null&&t.maxLength&&r.length>t.maxLength&&(r=r.substring(0,t.maxLength)),r}function Et(e){if(!e)return null;try{const t=new URL(e);return!["http:","https:","mailto:","tel:"].includes(t.protocol)||e.toLowerCase().includes("javascript:")?null:t.toString()}catch{return null}}function Ft(e){const t=["script","iframe","object","embed","form"];let r=e;t.forEach(i=>{const o=new RegExp(`<${i}[^>]*>.*?</${i}>`,"gi");r=r.replace(o,"");const c=new RegExp(`<${i}[^>]*/>`,"gi");r=r.replace(c,"")});const s=/\s+on\w+\s*=/gi;r=r.replace(s," data-removed=");const a=/javascript:/gi;return r=r.replace(a,""),r}function Nt(e,t){let r=e;if(t!=null&&t.allowedTags){const s=/<\/?([a-z][a-z0-9]*)[^>]*>/gi;r=r.replace(s,(a,i)=>t.allowedTags.includes(i.toLowerCase())?a:"")}return r=r.replace(/\s+on\w+\s*=/gi," data-removed="),r=r.replace(/javascript:/gi,""),{__html:r}}const ge={headerName:"X-CSRF-Token",cookieName:"XSRF-TOKEN",fieldName:"_csrf"};function zt(){if(typeof crypto<"u"){const e=new Uint8Array(32);return crypto.getRandomValues(e),Array.from(e,t=>t.toString(16).padStart(2,"0")).join("")}return Math.random().toString(36).substring(2)+Date.now().toString(36)}function me(e=ge.cookieName){if(typeof document>"u")return null;const t=document.cookie.match(new RegExp(`(^| )${e}=([^;]+)`));return t?decodeURIComponent(t[2]):null}function Lt(e=ge){return async function(r,s={}){const a=me(e.cookieName);a||console.warn("CSRF token not found");const i=new Headers(s.headers);return a&&e.headerName&&i.set(e.headerName,a),fetch(r,{...s,headers:i})}}function $t(e=ge){const t=me(e.cookieName);return{token:t,inputProps:{type:"hidden",name:e.fieldName,value:t||""},headerName:e.headerName}}function We(e){const t=new Map,r=e.keyGenerator||(i=>i.url);function s(i){const o=r(i),c=Date.now();let m=t.get(o);(!m||c>m.resetAt)&&(m={count:0,resetAt:c+e.windowMs}),m.count++,t.set(o,m);const x=m.count<=e.maxRequests,y=Math.max(0,e.maxRequests-m.count);return{allowed:x,remaining:y,resetAt:m.resetAt}}function a(i){i?t.delete(i):t.clear()}return{checkLimit:s,reset:a}}function Bt(e){const t=We(e);return{checkAndFetch:async(s,a)=>{const i=t.checkLimit({url:s,method:a==null?void 0:a.method});if(!i.allowed){const o=Math.ceil((i.resetAt-Date.now())/1e3);throw new Error(`Rate limit exceeded. Retry after ${o} seconds.`)}return fetch(s,a)},checkLimit:t.checkLimit,reset:t.reset}}function He(e,t){const r=[];if(t.allowedTypes&&t.allowedTypes.length>0&&(t.allowedTypes.includes(e.type)||r.push(`File type '${e.type}' is not allowed. Allowed types: ${t.allowedTypes.join(", ")}`)),t.maxSize&&e.size>t.maxSize){const i=(t.maxSize/1048576).toFixed(2),o=(e.size/(1024*1024)).toFixed(2);r.push(`File size (${o}MB) exceeds maximum allowed size (${i}MB)`)}const s=[".exe",".bat",".cmd",".sh",".ps1",".vbs",".js",".jar"],a=e.name.toLowerCase();for(const i of s)if(a.includes(i+".")||a.endsWith(i)){r.push(`File extension '${i}' is not allowed`);break}return{valid:r.length===0,errors:r,file:r.length===0?e:void 0}}function _t(e,t){const r=[],s=[],a=[];t.maxFiles&&e.length>t.maxFiles&&r.push(`Too many files. Maximum allowed: ${t.maxFiles}`);const i=e.reduce((o,c)=>o+c.size,0);if(t.maxTotalSize&&i>t.maxTotalSize){const o=(t.maxTotalSize/1048576).toFixed(2),c=(i/(1024*1024)).toFixed(2);r.push(`Total file size (${c}MB) exceeds maximum (${o}MB)`)}return e.forEach(o=>{const c=He(o,t);c.valid?s.push(o):a.push({file:o,errors:c.errors})}),{valid:r.length===0&&a.length===0,errors:[...r,...a.flatMap(o=>o.errors)],validFiles:s,invalidFiles:a}}async function Wt(e,t){const r=new FormData;r.append("file",e);try{const s=await fetch(t,{method:"POST",body:r});if(!s.ok)throw new Error("Virus scan failed");return await s.json()}catch(s){return console.error("Virus scan error:",s),{clean:!1,threat:"Scan failed"}}}function Ue(){if(typeof localStorage>"u")return null;const e=localStorage.getItem("nice2dev_consent");if(!e)return null;try{return JSON.parse(e)}catch{return null}}function Ht(e){typeof localStorage>"u"||localStorage.setItem("nice2dev_consent",JSON.stringify({...e,necessary:!0,timestamp:new Date().toISOString()}))}function Ut(e){const t=Ue();return t?t[e]===!0:!1}function Ot(e){if(typeof document>"u")return;document.cookie.split(";").forEach(r=>{const[s]=r.trim().split("=");e.includes(s)||(document.cookie=`${s}=; expires=Thu, 01 Jan 1970 00:00:00 UTC; path=/;`)})}async function qt(e,t,r=fetch){const s={exportDate:new Date().toISOString(),userId:e};return await Promise.all(Object.entries(t).map(async([a,i])=>{try{const o=await r(i);o.ok&&(s[a]=await o.json())}catch(o){console.error(`Failed to fetch ${a} data:`,o),s[a]={error:"Failed to retrieve data"}}})),s}async function Kt(e,t,r=fetch){try{const s=await r(t,{method:"DELETE",headers:{"Content-Type":"application/json"},body:JSON.stringify({userId:e,timestamp:new Date().toISOString()})});return s.ok?{success:!0,confirmationId:(await s.json()).confirmationId}:{success:!1,error:"Deletion request failed"}}catch(s){return{success:!1,error:String(s)}}}function Gt(e,t){var s;const r={...e,id:((s=crypto.randomUUID)==null?void 0:s.call(crypto))||Math.random().toString(36),timestamp:new Date};return t&&fetch(t,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(r)}).catch(console.error),process.env.NODE_ENV==="development"&&console.warn("[HIPAA] PHI Access:",r),r}function Jt(e){let t=null,r=null,s=Date.now();const a=e.timeoutMinutes*60*1e3,i=e.warningBeforeMs||6e4;function o(){s=Date.now(),t&&clearTimeout(t),r&&clearTimeout(r),e.onWarning&&(r=setTimeout(()=>{var y;const x=a-(Date.now()-s);(y=e.onWarning)==null||y.call(e,x)},a-i)),t=setTimeout(e.onTimeout,a)}function c(){t&&clearTimeout(t),r&&clearTimeout(r)}function m(){return Math.max(0,a-(Date.now()-s))}return o(),typeof window<"u"&&["mousedown","keypress","touchstart","scroll"].forEach(y=>{window.addEventListener(y,o,{passive:!0})}),{resetTimer:o,destroy:c,getTimeRemaining:m}}function Yt(e,t){const r=o=>{const c=o.replace("#",""),m=parseInt(c.substr(0,2),16)/255,x=parseInt(c.substr(2,2),16)/255,y=parseInt(c.substr(4,2),16)/255,v=A=>A<=.03928?A/12.92:Math.pow((A+.055)/1.055,2.4);return .2126*v(m)+.7152*v(x)+.0722*v(y)},s=r(e),a=r(t),i=(Math.max(s,a)+.05)/(Math.min(s,a)+.05);return{ratio:Math.round(i*100)/100,passesAA:i>=4.5,passesAAA:i>=7,passesAALarge:i>=3,passesAAALarge:i>=4.5}}function Zt(e){var r,s,a;if(e.getAttribute("aria-label"))return!0;const t=e.getAttribute("aria-labelledby");if(t){const i=document.getElementById(t);if((r=i==null?void 0:i.textContent)!=null&&r.trim())return!0}if(e.id){const i=document.querySelector(`label[for="${e.id}"]`);if((s=i==null?void 0:i.textContent)!=null&&s.trim())return!0}return!!((a=e.textContent)!=null&&a.trim()||e.getAttribute("title")||e.placeholder)}function Xt(e){const r=(e||document.body).querySelectorAll("h1, h2, h3, h4, h5, h6"),s=[];let a=0,i=!1;return r.forEach(o=>{const c=parseInt(o.tagName[1]);c===1&&(i&&s.push({level:c,element:o,issue:"Multiple H1 elements found"}),i=!0),c>a+1&&a!==0&&s.push({level:c,element:o,issue:`Skipped heading level: H${a} to H${c}`}),a=c}),!i&&r.length>0&&s.push({level:0,element:r[0],issue:"Missing H1 element"}),{valid:s.length===0,issues:s}}function Qt(e){const t=[];let r=null;const s=e.batchSize||10,a=e.flushInterval||5e3;async function i(){if(t.length===0)return;const x=t.splice(0,s);try{await fetch(e.endpoint,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({entries:x})})}catch(y){console.error("Failed to send audit logs:",y),t.unshift(...x)}}function o(){r||(r=setTimeout(()=>{r=null,i()},a))}function c(x){var v;const y={...x,id:((v=crypto.randomUUID)==null?void 0:v.call(crypto))||Math.random().toString(36),timestamp:new Date,userAgent:e.includeUserAgent&&typeof navigator<"u"?navigator.userAgent:void 0};t.push(y),t.length>=s?i():o()}function m(){r&&clearTimeout(r),i()}return{log:c,flush:i,destroy:m}}function Vt(){return[{controlId:"CC6.1",name:"Logical and Physical Access Controls",category:"security",status:"in_progress",lastAssessed:new Date},{controlId:"CC6.2",name:"User Registration and Authorization",category:"security",status:"in_progress",lastAssessed:new Date},{controlId:"CC6.3",name:"Access Control Removal",category:"security",status:"in_progress",lastAssessed:new Date},{controlId:"A1.1",name:"System Capacity",category:"availability",status:"in_progress",lastAssessed:new Date},{controlId:"A1.2",name:"Backup and Recovery",category:"availability",status:"in_progress",lastAssessed:new Date},{controlId:"C1.1",name:"Confidential Information Classification",category:"confidentiality",status:"in_progress",lastAssessed:new Date},{controlId:"C1.2",name:"Confidential Information Disposal",category:"confidentiality",status:"in_progress",lastAssessed:new Date},{controlId:"P1.1",name:"Privacy Notice",category:"privacy",status:"in_progress",lastAssessed:new Date},{controlId:"P2.1",name:"Consent",category:"privacy",status:"in_progress",lastAssessed:new Date},{controlId:"P3.1",name:"Collection",category:"privacy",status:"in_progress",lastAssessed:new Date}]}const er={hardcodedSecrets:[{pattern:/password\s*[:=]\s*["'][^"']+["']/gi,name:"Hardcoded password"},{pattern:/api[_-]?key\s*[:=]\s*["'][^"']+["']/gi,name:"Hardcoded API key"},{pattern:/secret\s*[:=]\s*["'][^"']+["']/gi,name:"Hardcoded secret"},{pattern:/token\s*[:=]\s*["'][^"']+["']/gi,name:"Hardcoded token"}],sqlInjection:[{pattern:/execute\s*\(\s*["'`].*\$\{/gi,name:"Potential SQL injection (template literal)"},{pattern:/query\s*\(\s*["'`].*\+/gi,name:"Potential SQL injection (string concatenation)"}],xss:[{pattern:/dangerouslySetInnerHTML/g,name:"dangerouslySetInnerHTML usage"},{pattern:/innerHTML\s*=/g,name:"innerHTML assignment"},{pattern:/document\.write\s*\(/g,name:"document.write usage"},{pattern:/eval\s*\(/g,name:"eval usage"}],insecureFunctions:[{pattern:/Math\.random\s*\(\)/g,name:"Insecure random (use crypto)"},{pattern:/new Function\s*\(/g,name:"Function constructor (code injection risk)"},{pattern:/setTimeout\s*\(\s*["']/g,name:"setTimeout with string (code injection)"},{pattern:/setInterval\s*\(\s*["']/g,name:"setInterval with string (code injection)"}],infoExposure:[{pattern:/console\.(log|info|warn|error)\s*\(/g,name:"Console logging (remove in production)"},{pattern:/debugger/g,name:"Debugger statement"},{pattern:/TODO.*password/gi,name:"TODO mentioning password"}]};function tr(){return`# .github/workflows/sast.yml
|
|
7
7
|
name: Security Scan (SAST)
|
|
8
8
|
|
|
9
9
|
on:
|
package/dist/index.mjs
CHANGED
|
@@ -708,7 +708,7 @@ const tt = { sm: 200, md: 280, lg: 380 }, Ct = (e) => {
|
|
|
708
708
|
fontSize: 14,
|
|
709
709
|
fontWeight: 600,
|
|
710
710
|
background: "var(--security-biometric)",
|
|
711
|
-
color: "var(--nice-
|
|
711
|
+
color: "var(--nice-color-white, #fff)",
|
|
712
712
|
border: "none",
|
|
713
713
|
borderRadius: "var(--security-radius)",
|
|
714
714
|
cursor: "pointer",
|
|
@@ -1040,7 +1040,7 @@ const tt = { sm: 200, md: 280, lg: 380 }, Ct = (e) => {
|
|
|
1040
1040
|
fontSize: 14,
|
|
1041
1041
|
fontWeight: 600,
|
|
1042
1042
|
background: "var(--security-biometric)",
|
|
1043
|
-
color: "var(--nice-
|
|
1043
|
+
color: "var(--nice-color-white, #fff)",
|
|
1044
1044
|
border: "none",
|
|
1045
1045
|
borderRadius: "var(--security-radius)",
|
|
1046
1046
|
cursor: "pointer",
|
|
@@ -1431,7 +1431,7 @@ const tt = { sm: 200, md: 280, lg: 380 }, Ct = (e) => {
|
|
|
1431
1431
|
fontSize: 14,
|
|
1432
1432
|
fontWeight: 600,
|
|
1433
1433
|
background: "var(--security-biometric)",
|
|
1434
|
-
color: "var(--nice-
|
|
1434
|
+
color: "var(--nice-color-white, #fff)",
|
|
1435
1435
|
border: "none",
|
|
1436
1436
|
borderRadius: "var(--security-radius)",
|
|
1437
1437
|
cursor: "pointer",
|
|
@@ -2103,7 +2103,7 @@ const ot = 4, at = 5, ct = 3e4, Pt = (e) => {
|
|
|
2103
2103
|
ghost: "none"
|
|
2104
2104
|
}, Q = {
|
|
2105
2105
|
// Label on the brand-coloured button: the on-primary text token, not a surface token.
|
|
2106
|
-
primary: "var(--nice-
|
|
2106
|
+
primary: "var(--nice-color-white, #fff)",
|
|
2107
2107
|
outline: "var(--security-biometric)",
|
|
2108
2108
|
ghost: "var(--security-biometric)"
|
|
2109
2109
|
}, E = !q || h === "processing" || h === "success";
|
|
@@ -2627,7 +2627,7 @@ const ot = 4, at = 5, ct = 3e4, Pt = (e) => {
|
|
|
2627
2627
|
fontSize: 10,
|
|
2628
2628
|
padding: "1px 6px",
|
|
2629
2629
|
background: "var(--security-biometric)",
|
|
2630
|
-
color: "var(--nice-
|
|
2630
|
+
color: "var(--nice-color-white, #fff)",
|
|
2631
2631
|
borderRadius: 8
|
|
2632
2632
|
},
|
|
2633
2633
|
children: a("security.session.current", "Current")
|
|
@@ -3099,7 +3099,7 @@ const vt = ["Very weak", "Weak", "Fair", "Strong", "Very strong"], ke = [
|
|
|
3099
3099
|
fontSize: 14,
|
|
3100
3100
|
fontWeight: 600,
|
|
3101
3101
|
background: u === "success" ? "var(--security-success)" : "var(--security-biometric)",
|
|
3102
|
-
color: "var(--nice-
|
|
3102
|
+
color: "var(--nice-color-white, #fff)",
|
|
3103
3103
|
border: "none",
|
|
3104
3104
|
borderRadius: "var(--security-radius)",
|
|
3105
3105
|
cursor: u === "success" ? "default" : "pointer",
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@nice2dev/ui-security",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.2.0",
|
|
4
4
|
"description": "Nice2Dev Security — Biometric authentication (fingerprint, iris, face), security keypads, PIN entry, pattern lock, liveness detection for React. Frontend-first with optional backend verification.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.cjs",
|