secure-ui-components 0.2.8 → 0.3.1

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.
Files changed (54) hide show
  1. package/README.md +23 -25
  2. package/dist/components/secure-card/secure-card.d.ts.map +1 -1
  3. package/dist/components/secure-card/secure-card.js +1 -1
  4. package/dist/components/secure-card/secure-card.js.map +1 -1
  5. package/dist/components/secure-datetime/secure-datetime.js +1 -1
  6. package/dist/components/secure-datetime/secure-datetime.js.map +1 -1
  7. package/dist/components/secure-file-upload/secure-file-upload.js +1 -1
  8. package/dist/components/secure-form/secure-form.d.ts +1 -108
  9. package/dist/components/secure-form/secure-form.d.ts.map +1 -1
  10. package/dist/components/secure-form/secure-form.js +1 -33
  11. package/dist/components/secure-form/secure-form.js.map +1 -1
  12. package/dist/components/secure-input/secure-input.d.ts +0 -110
  13. package/dist/components/secure-input/secure-input.d.ts.map +1 -1
  14. package/dist/components/secure-input/secure-input.js +1 -30
  15. package/dist/components/secure-input/secure-input.js.map +1 -1
  16. package/dist/components/secure-password-confirm/secure-password-confirm.d.ts +0 -1
  17. package/dist/components/secure-password-confirm/secure-password-confirm.d.ts.map +1 -1
  18. package/dist/components/secure-password-confirm/secure-password-confirm.js +1 -1
  19. package/dist/components/secure-password-confirm/secure-password-confirm.js.map +1 -1
  20. package/dist/components/secure-select/secure-select.d.ts +2 -132
  21. package/dist/components/secure-select/secure-select.d.ts.map +1 -1
  22. package/dist/components/secure-select/secure-select.js +1 -38
  23. package/dist/components/secure-select/secure-select.js.map +1 -1
  24. package/dist/components/secure-submit-button/secure-submit-button.d.ts +0 -46
  25. package/dist/components/secure-submit-button/secure-submit-button.d.ts.map +1 -1
  26. package/dist/components/secure-submit-button/secure-submit-button.js +1 -22
  27. package/dist/components/secure-submit-button/secure-submit-button.js.map +1 -1
  28. package/dist/components/secure-table/secure-table.d.ts +0 -51
  29. package/dist/components/secure-table/secure-table.d.ts.map +1 -1
  30. package/dist/components/secure-table/secure-table.js +25 -25
  31. package/dist/components/secure-table/secure-table.js.map +1 -1
  32. package/dist/components/secure-textarea/secure-textarea.d.ts +0 -104
  33. package/dist/components/secure-textarea/secure-textarea.d.ts.map +1 -1
  34. package/dist/components/secure-textarea/secure-textarea.js +1 -30
  35. package/dist/components/secure-textarea/secure-textarea.js.map +1 -1
  36. package/dist/core/base-component.d.ts +8 -129
  37. package/dist/core/base-component.d.ts.map +1 -1
  38. package/dist/core/base-component.js +1 -18
  39. package/dist/core/base-component.js.map +1 -1
  40. package/dist/core/security-config.d.ts +6 -70
  41. package/dist/core/security-config.d.ts.map +1 -1
  42. package/dist/core/security-config.js +1 -16
  43. package/dist/core/security-config.js.map +1 -1
  44. package/dist/core/types.d.ts +32 -28
  45. package/dist/core/types.d.ts.map +1 -1
  46. package/dist/core/types.js +0 -5
  47. package/dist/core/types.js.map +1 -1
  48. package/dist/index.d.ts +2 -9
  49. package/dist/index.d.ts.map +1 -1
  50. package/dist/index.js +1 -6
  51. package/dist/index.js.map +1 -1
  52. package/dist/package.json +1 -1
  53. package/dist/secure-ui.bundle.js +16 -209
  54. package/package.json +1 -5
@@ -1,30 +1,30 @@
1
- var c=Object.freeze({PUBLIC:"public",AUTHENTICATED:"authenticated",SENSITIVE:"sensitive",CRITICAL:"critical"}),S=Object.freeze({[c.PUBLIC]:Object.freeze({name:"Public",level:1,validation:Object.freeze({required:!1,strict:!1,maxLength:5e3,pattern:null,sanitizeHtml:!0}),masking:Object.freeze({enabled:!1,character:"\u2022",partial:!1}),storage:Object.freeze({allowAutocomplete:!0,allowCache:!0,allowHistory:!0}),audit:Object.freeze({logAccess:!1,logChanges:!1,logSubmission:!1,includeMetadata:!1}),rateLimit:Object.freeze({enabled:!1,maxAttempts:0,windowMs:0})}),[c.AUTHENTICATED]:Object.freeze({name:"Authenticated",level:2,validation:Object.freeze({required:!0,strict:!1,maxLength:1e3,pattern:null,sanitizeHtml:!0}),masking:Object.freeze({enabled:!1,character:"\u2022",partial:!1}),storage:Object.freeze({allowAutocomplete:!0,allowCache:!1,allowHistory:!1}),audit:Object.freeze({logAccess:!1,logChanges:!0,logSubmission:!0,includeMetadata:!0}),rateLimit:Object.freeze({enabled:!1,maxAttempts:0,windowMs:0})}),[c.SENSITIVE]:Object.freeze({name:"Sensitive",level:3,validation:Object.freeze({required:!0,strict:!0,maxLength:500,pattern:null,sanitizeHtml:!0}),masking:Object.freeze({enabled:!0,character:"\u2022",partial:!0}),storage:Object.freeze({allowAutocomplete:!1,allowCache:!1,allowHistory:!1}),audit:Object.freeze({logAccess:!0,logChanges:!0,logSubmission:!0,includeMetadata:!0}),rateLimit:Object.freeze({enabled:!0,maxAttempts:10,windowMs:6e4})}),[c.CRITICAL]:Object.freeze({name:"Critical",level:4,validation:Object.freeze({required:!0,strict:!0,maxLength:256,pattern:null,sanitizeHtml:!0}),masking:Object.freeze({enabled:!0,character:"\u2022",partial:!1}),storage:Object.freeze({allowAutocomplete:!1,allowCache:!1,allowHistory:!1}),audit:Object.freeze({logAccess:!0,logChanges:!0,logSubmission:!0,includeMetadata:!0}),rateLimit:Object.freeze({enabled:!0,maxAttempts:5,windowMs:6e4})})});function g(l){return!l||!S[l]?(console.warn(`Invalid security tier "${l}", defaulting to CRITICAL`),S[c.CRITICAL]):S[l]}function _(l){return Object.values(c).includes(l)}function O(l,e){let t=g(l),i=g(e);return Math.sign(t.level-i.level)}function W(l,e){return O(l,e)>=0?l:e}var Z=Object.freeze({[c.PUBLIC]:Object.freeze({"default-src":["'self'"],"script-src":["'self'"],"style-src":["'self'"]}),[c.AUTHENTICATED]:Object.freeze({"default-src":["'self'"],"script-src":["'self'"],"style-src":["'self'"],"form-action":["'self'"]}),[c.SENSITIVE]:Object.freeze({"default-src":["'self'"],"script-src":["'self'"],"style-src":["'self'"],"form-action":["'self'"],"frame-ancestors":["'none'"],"upgrade-insecure-requests":[]}),[c.CRITICAL]:Object.freeze({"default-src":["'self'"],"script-src":["'self'"],"style-src":["'self'"],"form-action":["'self'"],"frame-ancestors":["'none'"],"upgrade-insecure-requests":[],"block-all-mixed-content":[],"base-uri":["'none'"]})}),G=Object.freeze({"X-Content-Type-Options":"nosniff","X-Frame-Options":"DENY","X-XSS-Protection":"1; mode=block","Referrer-Policy":"strict-origin-when-cross-origin","Permissions-Policy":"geolocation=(), microphone=(), camera=()"});var p=class l extends HTMLElement{static#e=1e3;static#s={"script-tag":"Script injection blocked","js-protocol":"JavaScript protocol blocked","event-handler":"Event handler injection blocked","html-injection":"HTML element injection blocked","css-expression":"CSS expression injection blocked",vbscript:"VBScript injection blocked","data-uri-html":"Data URI injection blocked","template-syntax":"Template injection blocked"};static#i=[{id:"script-tag",pattern:/<script[\s>/]/i},{id:"js-protocol",pattern:/javascript\s*:/i},{id:"event-handler",pattern:/\bon\w+\s*=/i},{id:"html-injection",pattern:/<\s*(img|svg|iframe|object|embed|link|meta|base)[^>]*/i},{id:"css-expression",pattern:/expression\s*\(/i},{id:"vbscript",pattern:/vbscript\s*:/i},{id:"data-uri-html",pattern:/data:\s*text\/html/i},{id:"template-syntax",pattern:/\{\{[\s\S]*?\}\}/}];#r=c.CRITICAL;#t;#n;#a=[];#o={attempts:0,windowStart:Date.now()};#u=!1;#c={focusAt:null,firstKeystrokeAt:null,blurAt:null,keyCount:0,correctionCount:0,pasteDetected:!1,autofillDetected:!1,focusCount:0,blurWithoutChange:0,lastInputLength:0};constructor(){super(),this.#n=this.attachShadow({mode:"closed"}),this.#t=g(this.#r)}static get observedAttributes(){return["security-tier","disabled","readonly","threat-feedback"]}connectedCallback(){this.#u||(this.#h(),this.#u=!0)}#h(){this.initializeSecurity(),this.#d()}initializeSecurity(){let e=this.getAttribute("security-tier");e&&_(e)&&(this.#r=e),this.#t=g(this.#r),this.#l("component_initialized",{tier:this.#r,timestamp:new Date().toISOString()})}attributeChangedCallback(e,t,i){if(e==="security-tier"&&this.#u){console.warn(`Security tier cannot be changed after initialization. Attempted change from "${t}" to "${i}" blocked.`),t!==null&&this.setAttribute("security-tier",t);return}this.#u&&this.handleAttributeChange(e,t,i)}handleAttributeChange(e,t,i){}#d(){this.#n.innerHTML="",this.addComponentStyles(":host { display: block; box-sizing: border-box; font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif; font-size: 14px; line-height: 1.5; } :host([hidden]) { display: none; } * { box-sizing: border-box; } .hidden { display: none; } .security-badge { display: inline-block; padding: var(--secure-ui-badge-padding, 2px 6px); margin-left: var(--secure-ui-space-2, 0.5rem); font-size: var(--secure-ui-badge-font-size, 0.6875rem); font-weight: var(--secure-ui-font-weight-semibold, 600); border-radius: var(--secure-ui-badge-border-radius, 0.25rem); text-transform: uppercase; background-color: var(--secure-ui-color-bg-tertiary); color: var(--secure-ui-color-text-secondary); border: var(--secure-ui-border-width-thin, 1px) solid var(--secure-ui-color-border); }");let e=this.render();e&&this.#n.appendChild(e)}getBaseStylesheetUrl(){return":host { display: block; box-sizing: border-box; font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif; font-size: 14px; line-height: 1.5; } :host([hidden]) { display: none; } * { box-sizing: border-box; } .hidden { display: none; } .security-badge { display: inline-block; padding: var(--secure-ui-badge-padding, 2px 6px); margin-left: var(--secure-ui-space-2, 0.5rem); font-size: var(--secure-ui-badge-font-size, 0.6875rem); font-weight: var(--secure-ui-font-weight-semibold, 600); border-radius: var(--secure-ui-badge-border-radius, 0.25rem); text-transform: uppercase; background-color: var(--secure-ui-color-bg-tertiary); color: var(--secure-ui-color-text-secondary); border: var(--secure-ui-border-width-thin, 1px) solid var(--secure-ui-color-border); }"}addComponentStyles(e){if(e.includes("{")){let t=new CSSStyleSheet;t.replaceSync(e),this.#n.adoptedStyleSheets=[...this.#n.adoptedStyleSheets,t]}else{let t=document.createElement("link");t.rel="stylesheet",t.href=e,this.#n.appendChild(t)}}sanitizeValue(e){if(typeof e!="string")return"";let t=document.createElement("div");return t.textContent=e,t.innerHTML}validateInput(e,t={}){let i=[],r=this.#t;(t.required!==void 0?t.required:r.validation.required)&&(!e||e.trim().length===0)&&i.push("This field is required");let n=t.maxLength||r.validation.maxLength;e&&e.length>n&&i.push(`Value exceeds maximum length of ${n}`);let a=t.minLength||0;e&&e.length<a&&i.push(`Value must be at least ${a} characters`);let o=t.pattern||r.validation.pattern;return o&&e&&!o.test(e)&&i.push("Value does not match required format"),r.validation.strict&&i.length>0&&this.#l("validation_failed",{errors:i,valueLength:e?e.length:0}),{valid:i.length===0,errors:i}}checkRateLimit(){if(!this.#t.rateLimit.enabled)return{allowed:!0,retryAfter:0};let e=Date.now(),t=this.#t.rateLimit.windowMs;if(e-this.#o.windowStart>t&&(this.#o.attempts=0,this.#o.windowStart=e),this.#o.attempts>=this.#t.rateLimit.maxAttempts){let i=t-(e-this.#o.windowStart);return this.#l("rate_limit_exceeded",{attempts:this.#o.attempts,retryAfter:i}),{allowed:!1,retryAfter:i}}return this.#o.attempts++,{allowed:!0,retryAfter:0}}#l(e,t={}){let i=this.#t.audit;if(!(e.includes("access")&&i.logAccess||e.includes("change")&&i.logChanges||e.includes("submit")&&i.logSubmission||e.includes("initialized")||e.includes("rate_limit")||e.includes("validation")||e.includes("threat")))return;let s={event:e,tier:this.#r,timestamp:new Date().toISOString(),...t};i.includeMetadata&&(s.userAgent=navigator.userAgent,s.language=navigator.language),this.#a.length>=l.#e&&this.#a.shift(),this.#a.push(s),this.dispatchEvent(new CustomEvent("secure-audit",{detail:s,bubbles:!0,composed:!0}))}get shadowRoot(){return this.#n}get securityTier(){return this.#r}get config(){return this.#t}getAuditLog(){return[...this.#a]}clearAuditLog(){this.#a=[]}audit(e,t){this.#l(e,t)}detectInjection(e,t){for(let{id:i,pattern:r}of l.#i)if(r.test(e)){this.audit("threat_detected",{fieldName:t,patternId:i,threatType:"injection"}),this.dispatchEvent(new CustomEvent("secure-threat-detected",{detail:{fieldName:t,threatType:"injection",patternId:i,tier:this.securityTier,timestamp:Date.now()},bubbles:!0,composed:!0})),this.hasAttribute("threat-feedback")&&this.showThreatFeedback(i);return}this.hasAttribute("threat-feedback")&&this.clearThreatFeedback()}showThreatFeedback(e){}clearThreatFeedback(){}getThreatLabel(e){return l.#s[e]??`Injection blocked: ${e}`}rerender(){this.#d()}recordTelemetryFocus(){let e=this.#c;e.focusAt=Date.now(),e.blurAt=null,e.focusCount++;let t=this.shadowRoot.querySelector('input:not([type="hidden"]), textarea, select');e.lastInputLength=t?t.value.length:0}recordTelemetryInput(e){let t=this.#c,i=Date.now();t.firstKeystrokeAt===null&&(t.firstKeystrokeAt=i);let s=e.inputType??"";s==="insertFromPaste"||s==="insertFromPasteAsQuotation"?t.pasteDetected=!0:s==="insertReplacementText"?t.autofillDetected=!0:s.startsWith("delete")||s==="historyUndo"||s==="historyRedo"?t.correctionCount++:t.keyCount++;let n=e.target;n&&(t.lastInputLength=n.value.length)}recordTelemetryBlur(){let e=this.#c;e.blurAt=Date.now();let t=this.shadowRoot.querySelector('input:not([type="hidden"]), textarea, select');(t?t.value.length:0)===e.lastInputLength&&e.keyCount===0&&!e.pasteDetected&&e.blurWithoutChange++}getFieldTelemetry(){let e=this.#c,t=e.focusAt??Date.now(),i=e.firstKeystrokeAt,r=e.blurAt??Date.now(),s=i!==null?i-t:0,n=i!==null?r-i:0,a=n/1e3,o=a>0?e.keyCount/a:0;return{dwell:s,completionTime:n,velocity:Math.round(o*100)/100,corrections:e.correctionCount,pasteDetected:e.pasteDetected,autofillDetected:e.autofillDetected,focusCount:e.focusCount,blurWithoutChange:e.blurWithoutChange}}#p(){this.#c={focusAt:null,firstKeystrokeAt:null,blurAt:null,keyCount:0,correctionCount:0,pasteDetected:!1,autofillDetected:!1,focusCount:0,blurWithoutChange:0,lastInputLength:0}}disconnectedCallback(){this.#o={attempts:0,windowStart:Date.now()},this.#p(),this.#t.audit.logAccess&&this.#l("component_disconnected",{timestamp:new Date().toISOString()})}};var k=class extends p{#e=null;#s=null;#i=null;#r=null;#t="";#n=!1;#a=null;#o=`secure-input-${Math.random().toString(36).substring(2,11)}`;static get observedAttributes(){return[...super.observedAttributes,"name","type","label","placeholder","required","pattern","minlength","maxlength","autocomplete","value"]}constructor(){super()}render(){let e=document.createDocumentFragment(),t=document.createElement("div");t.className="input-container",t.setAttribute("part","container");let i=this.getAttribute("label");i&&(this.#s=document.createElement("label"),this.#s.htmlFor=this.#o,this.#s.textContent=this.sanitizeValue(i),this.#s.setAttribute("part","label"),t.appendChild(this.#s));let r=document.createElement("div");return r.className="input-wrapper",r.setAttribute("part","wrapper"),this.#e=document.createElement("input"),this.#e.id=this.#o,this.#e.className="input-field",this.#e.setAttribute("part","input"),this.#d(),this.#l(),r.appendChild(this.#e),t.appendChild(r),this.#i=document.createElement("div"),this.#i.className="error-container hidden",this.#i.setAttribute("role","alert"),this.#i.setAttribute("part","error"),this.#i.id=`${this.#o}-error`,t.appendChild(this.#i),this.#r=document.createElement("div"),this.#r.className="threat-container hidden",this.#r.setAttribute("role","alert"),this.#r.setAttribute("part","threat"),this.#r.id=`${this.#o}-threat`,t.appendChild(this.#r),this.#u(),this.#h(),this.addComponentStyles(this.#x()),e.appendChild(t),e}#u(){let e=this.getAttribute("name");!e||this.closest("secure-form")||(this.#a=document.createElement("input"),this.#a.type="hidden",this.#a.name=e,this.#a.value=this.#t||"",this.appendChild(this.#a))}#c(){this.#a&&(this.#a.value=this.#t||"")}#h(){this.querySelectorAll("input, textarea, select").forEach(t=>{if(t===this.#a)return;let i=t;i.removeAttribute("required"),i.removeAttribute("name"),i.removeAttribute("minlength"),i.removeAttribute("maxlength"),i.removeAttribute("pattern"),i.setAttribute("tabindex","-1"),i.setAttribute("aria-hidden","true")})}#d(){let e=this.config,t=this.getAttribute("name");t&&(this.#e.name=this.sanitizeValue(t)),!this.getAttribute("label")&&t&&this.#e.setAttribute("aria-label",this.sanitizeValue(t)),this.#e.setAttribute("aria-describedby",`${this.#o}-error`);let i=this.getAttribute("type")||"text";this.#e.type=i;let r=this.getAttribute("placeholder");r&&(this.#e.placeholder=this.sanitizeValue(r)),(this.hasAttribute("required")||e.validation.required)&&(this.#e.required=!0,this.#e.setAttribute("aria-required","true"));let s=this.getAttribute("pattern");s&&(this.#e.pattern=s);let n=this.getAttribute("minlength");n&&(this.#e.minLength=parseInt(n,10));let a=this.getAttribute("maxlength")||e.validation.maxLength;if(a&&(this.#e.maxLength=parseInt(String(a),10)),e.storage.allowAutocomplete){let d=this.getAttribute("autocomplete")||"on";this.#e.autocomplete=d}else this.#e.autocomplete="off",this.#e.type==="password"&&(this.#e.autocomplete="new-password");this.hasAttribute("disabled")&&(this.#e.disabled=!0),this.hasAttribute("readonly")&&(this.#e.readOnly=!0);let o=this.getAttribute("value");o&&this.#E(o);let u=new Set(["email","url","tel"]);e.masking.enabled&&this.#e.type!=="password"&&!u.has(this.#e.type)&&(this.#n=!0)}#l(){this.#e.addEventListener("focus",()=>{this.recordTelemetryFocus(),this.audit("input_focused",{name:this.#e.name})}),this.#e.addEventListener("input",e=>{this.recordTelemetryInput(e),this.#p(e)}),this.#e.addEventListener("blur",()=>{this.recordTelemetryBlur(),this.#m(),this.audit("input_blurred",{name:this.#e.name,hasValue:this.#t.length>0})}),this.#e.addEventListener("change",()=>{this.audit("input_changed",{name:this.#e.name,valueLength:this.#t.length})})}#p(e){if(this.#n&&this.#e.type!=="password"){let t=e,i=t.inputType,r=t.data||"",s=this.#e.value,n=this.#e.selectionStart||0;if(i==="deleteContentBackward")n<this.#t.length&&(this.#t=this.#t.substring(0,n)+this.#t.substring(n+1));else if(i==="deleteContentForward")this.#t=this.#t.substring(0,n)+this.#t.substring(n+1);else if(i==="insertText")this.#t=this.#t.substring(0,n-r.length)+r+this.#t.substring(n-r.length);else if(i==="insertFromPaste")r&&(this.#t=this.#t.substring(0,n-r.length)+r+this.#t.substring(n-r.length));else{let o=this.#t.length,u=s.length;if(u>o){let d=u-o,h=n-d;this.#t=this.#t.substring(0,h)+s.substring(h,n)+this.#t.substring(h)}else u<o&&(this.#t=this.#t.substring(0,n)+this.#t.substring(n+(o-u)))}let a=this.#b(this.#t);this.#e.value=a,this.#e.setSelectionRange(n,n)}else this.#t=this.#e.value;this.detectInjection(this.#t,this.#e.name),this.#v(),this.#c(),this.dispatchEvent(new CustomEvent("secure-input",{detail:{name:this.#e.name,value:this.#t,masked:this.#n,tier:this.securityTier},bubbles:!0,composed:!0}))}#b(e){let t=this.config,i=t.masking.character;if(!t.masking.partial||this.securityTier===c.CRITICAL||e.length<=4)return i.repeat(e.length);let r=i.repeat(e.length-4),s=e.slice(-4);return r+s}#f(e){if(!this.#e||this.#e.type!=="password"||!e||e.length===0)return null;let t=this.securityTier;if(t==="critical"){if(e.length<8)return"Password must be at least 8 characters";if(!/[a-z]/.test(e))return"Password must include a lowercase letter";if(!/[A-Z]/.test(e))return"Password must include an uppercase letter";if(!/[0-9]/.test(e))return"Password must include a number";if(!/[^a-zA-Z0-9]/.test(e))return"Password must include a special character"}else if(t==="sensitive"){if(e.length<8)return"Password must be at least 8 characters";if(!/[a-z]/.test(e))return"Password must include a lowercase letter";if(!/[A-Z]/.test(e))return"Password must include an uppercase letter";if(!/[0-9]/.test(e))return"Password must include a number"}else if(t==="authenticated"&&e.length<6)return"Password must be at least 6 characters";return null}#y(e){if(!this.#e||this.#e.type!=="number"||!e||e.length===0)return null;let t=Number(e);if(!Number.isFinite(t))return"Value must be a valid number";if(!e.includes(".")&&!Number.isSafeInteger(t))return"Value exceeds safe integer range";let i=this.getAttribute("min"),r=this.getAttribute("max");if(i!==null){let s=Number(i);if(Number.isFinite(s)&&t<s)return`Value must be at least ${s}`}if(r!==null){let s=Number(r);if(Number.isFinite(s)&&t>s)return`Value must be at most ${s}`}return null}#m(){let e=this.checkRateLimit();if(!e.allowed){this.#g(`Too many attempts. Please wait ${Math.ceil(e.retryAfter/1e3)} seconds.`);return}let t=this.getAttribute("pattern"),i=this.getAttribute("minlength"),r=this.getAttribute("maxlength"),s=null;if(t)try{s=new RegExp(t)}catch{}let n=this.validateInput(this.#t,{required:this.hasAttribute("required")||this.config.validation.required,pattern:s,minLength:i?parseInt(i,10):0,maxLength:r?parseInt(r,10):this.config.validation.maxLength});if(!n.valid){this.#g(n.errors.join(", "));return}let a=this.#f(this.#t);if(a){this.#g(a);return}let o=this.#y(this.#t);if(o){this.#g(o);return}if(this.#e&&this.#t){let u,d;if(this.#n){let h=this.#e.value;this.#e.value=this.#t,u=this.#e.checkValidity(),d=this.#e.validationMessage,this.#e.value=h}else u=this.#e.checkValidity(),d=this.#e.validationMessage;if(!u){this.#g(d);return}}}#g(e){this.#i.textContent=e,this.#i.offsetHeight,this.#i.classList.remove("hidden"),this.#e.classList.add("error"),this.#e.setAttribute("aria-invalid","true")}#v(){this.#i.classList.add("hidden"),this.#i.addEventListener("transitionend",()=>{this.#i.classList.contains("hidden")&&(this.#i.textContent="")},{once:!0}),this.#e.classList.remove("error"),this.#e.removeAttribute("aria-invalid")}#E(e){this.#t=e,this.#n&&this.#e.type!=="password"?this.#e.value=this.#b(e):this.#e.value=e,this.#c()}#x(){return".input-container { margin-bottom: var(--secure-ui-form-gap); font-family: var(--secure-ui-font-family-base); } label { display: flex; align-items: flex-end; margin-bottom: var(--secure-ui-form-label-margin-bottom); font-size: var(--secure-ui-label-font-size); font-weight: var(--secure-ui-label-font-weight); color: var(--secure-ui-label-color); } .label-suffix { font-weight: var(--secure-ui-font-weight-normal); color: var(--secure-ui-color-text-secondary); font-size: var(--secure-ui-font-size-xs); margin-left: var(--secure-ui-space-1); } .security-badge { display: inline-block; padding: var(--secure-ui-badge-padding); margin-left: var(--secure-ui-space-2); font-size: var(--secure-ui-badge-font-size); font-weight: var(--secure-ui-font-weight-semibold); border-radius: var(--secure-ui-badge-border-radius); text-transform: uppercase; background-color: var(--secure-ui-color-bg-tertiary); color: var(--secure-ui-color-text-secondary); border: var(--secure-ui-border-width-thin) solid var(--secure-ui-color-border); } .input-wrapper { position: relative; } .input-field { width: 100%; height: var(--secure-ui-input-height); padding: var(--secure-ui-input-padding-y) var(--secure-ui-input-padding-x); font-family: var(--secure-ui-font-family-base); font-size: var(--secure-ui-input-font-size); line-height: var(--secure-ui-line-height-normal); color: var(--secure-ui-input-text-color); background-color: var(--secure-ui-input-bg); border: var(--secure-ui-input-border-width) solid var(--secure-ui-input-border-color); border-radius: var(--secure-ui-input-border-radius); transition: all var(--secure-ui-transition-base) var(--secure-ui-transition-ease-in-out); box-sizing: border-box; } .input-field::placeholder { color: var(--secure-ui-input-placeholder-color); } .input-field:hover:not(:disabled) { border-color: var(--secure-ui-input-border-color-hover); } .input-field:focus { outline: none; border-color: var(--secure-ui-input-border-color-focus); box-shadow: var(--secure-ui-shadow-focus); } .input-field.error { border-color: var(--secure-ui-color-error) !important; } .input-field.error:focus { box-shadow: var(--secure-ui-shadow-focus-error); } .input-field:disabled { background-color: var(--secure-ui-input-disabled-bg); cursor: not-allowed; opacity: var(--secure-ui-input-disabled-opacity); } .input-field:read-only:not(:disabled) { background-color: var(--secure-ui-color-bg-secondary); cursor: default; } .error-container { position: absolute; margin-top: var(--secure-ui-form-error-margin-top); font-size: var(--secure-ui-error-font-size); color: var(--secure-ui-error-color); line-height: var(--secure-ui-line-height-normal); overflow: hidden; max-height: 40px; opacity: 1; transform: translateY(0); transition: all 0.5s ease-in-out; } .error-container.hidden { max-height: 0; opacity: 0; transform: translateY(-4px); margin-top: 0; transition: all 0.2s ease-in-out; } @media (prefers-reduced-motion: reduce) { .input-field, .error-container, .threat-container { transition: none !important; } } .threat-container { margin-top: var(--secure-ui-form-error-margin-top); font-size: var(--secure-ui-error-font-size); color: var(--secure-ui-color-warning); line-height: var(--secure-ui-line-height-normal); overflow: hidden; max-height: 40px; opacity: 1; transform: translateY(0); transition: all 0.5s ease-in-out; display: flex; align-items: center; gap: var(--secure-ui-space-1, 4px); flex-wrap: wrap; } .threat-container.hidden { max-height: 0; opacity: 0; transform: translateY(-4px); margin-top: 0; transition: all 0.2s ease-in-out; } .threat-message { flex: 1; min-width: 0; } .threat-badge { display: inline-block; padding: var(--secure-ui-badge-padding); font-size: var(--secure-ui-badge-font-size); font-weight: var(--secure-ui-font-weight-semibold); border-radius: var(--secure-ui-badge-border-radius); background-color: color-mix(in srgb, var(--secure-ui-color-warning) 12%, transparent); color: var(--secure-ui-color-warning); border: var(--secure-ui-border-width-thin) solid currentColor; font-family: var(--secure-ui-font-family-mono, monospace); white-space: nowrap; } .input-field.threat { border-color: var(--secure-ui-color-warning) !important; } .input-field.threat:focus { box-shadow: 0 0 0 3px color-mix(in srgb, var(--secure-ui-color-warning) 25%, transparent); } .input-field:-webkit-autofill { -webkit-box-shadow: 0 0 0 1000px var(--secure-ui-input-bg) inset; -webkit-text-fill-color: var(--secure-ui-input-text-color); }"}handleAttributeChange(e,t,i){if(this.#e)switch(e){case"disabled":this.#e.disabled=this.hasAttribute("disabled");break;case"readonly":this.#e.readOnly=this.hasAttribute("readonly");break;case"value":i!==this.#t&&this.#E(i||"");break}}get value(){return this.#t}set value(e){this.#E(e||"")}get name(){return this.#e?this.#e.name:""}get valid(){let e=this.getAttribute("pattern"),t=this.getAttribute("minlength"),i=this.getAttribute("maxlength"),r=null;if(e)try{r=new RegExp(e)}catch{}if(!this.validateInput(this.#t,{required:this.hasAttribute("required")||this.config.validation.required,pattern:r,minLength:t?parseInt(t,10):0,maxLength:i?parseInt(i,10):this.config.validation.maxLength}).valid||this.#f(this.#t)!==null||this.#y(this.#t)!==null)return!1;if(this.#e&&this.#t){let n;if(this.#n){let a=this.#e.value;this.#e.value=this.#t,n=this.#e.checkValidity(),this.#e.value=a}else n=this.#e.checkValidity();if(!n)return!1}return!0}focus(){this.#e&&this.#e.focus()}blur(){this.#e&&this.#e.blur()}showThreatFeedback(e){if(!this.#r||!this.#e)return;this.#r.textContent="";let t=document.createElement("span");t.className="threat-message",t.textContent=this.getThreatLabel(e);let i=document.createElement("span");i.className="threat-badge",i.textContent=e,this.#r.appendChild(t),this.#r.appendChild(i),this.#r.offsetHeight,this.#r.classList.remove("hidden"),this.#e.classList.add("threat"),this.#e.setAttribute("aria-invalid","true")}clearThreatFeedback(){!this.#r||!this.#e||(this.#r.classList.add("hidden"),this.#r.addEventListener("transitionend",()=>{this.#r.classList.contains("hidden")&&(this.#r.textContent="")},{once:!0}),this.#e.classList.remove("threat"),this.#e.removeAttribute("aria-invalid"))}disconnectedCallback(){super.disconnectedCallback(),this.#t="",this.#e&&(this.#e.value="")}};customElements.define("secure-input",k);var z=class extends p{#e=null;#s=null;#i=null;#r=null;#t=null;#n=`secure-textarea-${Math.random().toString(36).substring(2,11)}`;static get observedAttributes(){return[...super.observedAttributes,"name","label","placeholder","required","minlength","maxlength","rows","cols","wrap","value"]}constructor(){super()}render(){let e=document.createDocumentFragment(),t=document.createElement("div");t.className="textarea-container",t.setAttribute("part","container");let i=this.getAttribute("label");i&&(this.#s=document.createElement("label"),this.#s.htmlFor=this.#n,this.#s.textContent=this.sanitizeValue(i),this.#s.setAttribute("part","label"),t.appendChild(this.#s));let r=document.createElement("div");return r.className="textarea-wrapper",r.setAttribute("part","wrapper"),this.#e=document.createElement("textarea"),this.#e.id=this.#n,this.#e.className="textarea-field",this.#e.setAttribute("part","textarea"),this.#a(),this.#o(),r.appendChild(this.#e),t.appendChild(r),this.#t=document.createElement("span"),this.#t.className="char-count",this.#c(),t.appendChild(this.#t),this.#i=document.createElement("div"),this.#i.className="error-container hidden",this.#i.setAttribute("role","alert"),this.#i.setAttribute("part","error"),this.#i.id=`${this.#n}-error`,t.appendChild(this.#i),this.#r=document.createElement("div"),this.#r.className="threat-container hidden",this.#r.setAttribute("role","alert"),this.#r.setAttribute("part","threat"),this.#r.id=`${this.#n}-threat`,t.appendChild(this.#r),this.addComponentStyles(this.#p()),e.appendChild(t),e}#a(){let e=this.config,t=this.getAttribute("name");t&&(this.#e.name=this.sanitizeValue(t)),!this.getAttribute("label")&&t&&this.#e.setAttribute("aria-label",this.sanitizeValue(t)),this.#e.setAttribute("aria-describedby",`${this.#n}-error`);let i=this.getAttribute("placeholder");i&&(this.#e.placeholder=this.sanitizeValue(i)),(this.hasAttribute("required")||e.validation.required)&&(this.#e.required=!0,this.#e.setAttribute("aria-required","true"));let r=this.getAttribute("minlength");r&&(this.#e.minLength=parseInt(r,10));let s=this.getAttribute("maxlength")||e.validation.maxLength;s&&(this.#e.maxLength=parseInt(String(s),10));let n=this.getAttribute("rows")||3;this.#e.rows=parseInt(String(n),10);let a=this.getAttribute("cols");a&&(this.#e.cols=parseInt(a,10));let o=this.getAttribute("wrap")||"soft";if(this.#e.wrap=o,e.storage.allowAutocomplete){let d=this.getAttribute("autocomplete")||"on";this.#e.autocomplete=d}else this.#e.autocomplete="off";this.hasAttribute("disabled")&&(this.#e.disabled=!0),this.hasAttribute("readonly")&&(this.#e.readOnly=!0);let u=this.getAttribute("value");u&&(this.#e.value=u)}#o(){this.#e.addEventListener("focus",()=>{this.recordTelemetryFocus(),this.audit("textarea_focused",{name:this.#e.name})}),this.#e.addEventListener("input",e=>{this.recordTelemetryInput(e),this.#u(e)}),this.#e.addEventListener("blur",()=>{this.recordTelemetryBlur(),this.#h(),this.audit("textarea_blurred",{name:this.#e.name,hasValue:this.#e.value.length>0})}),this.#e.addEventListener("change",()=>{this.audit("textarea_changed",{name:this.#e.name,valueLength:this.#e.value.length})})}#u(e){this.detectInjection(this.#e.value,this.#e.name),this.#c(),this.#l(),this.dispatchEvent(new CustomEvent("secure-textarea",{detail:{name:this.#e.name,value:this.#e.value,tier:this.securityTier},bubbles:!0,composed:!0}))}#c(){let e=this.#e.value.length,t=this.#e.maxLength;t>0?(this.#t.textContent=`${e} / ${t}`,e>t*.9?this.#t.classList.add("warning"):this.#t.classList.remove("warning")):this.#t.textContent=`${e}`}#h(){let e=this.checkRateLimit();if(!e.allowed){this.#d(`Too many attempts. Please wait ${Math.ceil(e.retryAfter/1e3)} seconds.`);return}let t=this.getAttribute("minlength"),i=this.getAttribute("maxlength"),r=this.validateInput(this.#e.value,{required:this.hasAttribute("required")||this.config.validation.required,minLength:t?parseInt(t,10):0,maxLength:i?parseInt(i,10):this.config.validation.maxLength});r.valid||this.#d(r.errors.join(", "))}#d(e){this.#i.textContent=e,this.#i.offsetHeight,this.#i.classList.remove("hidden"),this.#e.classList.add("error"),this.#e.setAttribute("aria-invalid","true")}#l(){this.#i.classList.add("hidden"),this.#i.addEventListener("transitionend",()=>{this.#i.classList.contains("hidden")&&(this.#i.textContent="")},{once:!0}),this.#e.classList.remove("error"),this.#e.removeAttribute("aria-invalid")}#p(){return'.textarea-container { margin-bottom: var(--secure-ui-form-gap); font-family: var(--secure-ui-font-family-base); } label { display: block; margin-bottom: var(--secure-ui-form-label-margin-bottom); font-size: var(--secure-ui-label-font-size); font-weight: var(--secure-ui-label-font-weight); color: var(--secure-ui-label-color); } .label-suffix { font-weight: var(--secure-ui-font-weight-normal); color: var(--secure-ui-color-text-secondary); font-size: var(--secure-ui-font-size-xs); margin-left: var(--secure-ui-space-1); } .security-badge { display: inline-block; padding: var(--secure-ui-badge-padding); margin-left: var(--secure-ui-space-2); font-size: var(--secure-ui-badge-font-size); font-weight: var(--secure-ui-font-weight-semibold); border-radius: var(--secure-ui-badge-border-radius); text-transform: uppercase; background-color: var(--secure-ui-color-bg-tertiary); color: var(--secure-ui-color-text-secondary); border: var(--secure-ui-border-width-thin) solid var(--secure-ui-color-border); } .textarea-wrapper { position: relative; } .textarea-field { width: 100%; min-height: var(--secure-ui-textarea-min-height); padding: var(--secure-ui-textarea-padding); font-family: var(--secure-ui-font-family-base); font-size: var(--secure-ui-input-font-size); line-height: var(--secure-ui-line-height-normal); color: var(--secure-ui-input-text-color); background-color: var(--secure-ui-input-bg); border: var(--secure-ui-input-border-width) solid var(--secure-ui-input-border-color); border-radius: var(--secure-ui-input-border-radius); transition: all var(--secure-ui-transition-base) var(--secure-ui-transition-ease-in-out); resize: vertical; box-sizing: border-box; } .textarea-field::placeholder { color: var(--secure-ui-input-placeholder-color); } .textarea-field:hover:not(:disabled) { border-color: var(--secure-ui-input-border-color-hover); } .textarea-field:focus { outline: none; border-color: var(--secure-ui-input-border-color-focus); box-shadow: var(--secure-ui-shadow-focus); } .textarea-field.error { border-color: var(--secure-ui-color-error); } .textarea-field.error:focus { box-shadow: var(--secure-ui-shadow-focus-error); } .textarea-field:read-only:not(:disabled) { background-color: var(--secure-ui-color-bg-secondary); cursor: default; resize: none; } .textarea-field:disabled { background-color: var(--secure-ui-input-disabled-bg); cursor: not-allowed; opacity: var(--secure-ui-input-disabled-opacity); } .char-count { display: block; margin-top: var(--secure-ui-space-1); font-size: var(--secure-ui-font-size-xs); color: var(--secure-ui-color-text-secondary); text-align: right; } .char-count.warning { color: var(--secure-ui-color-warning); font-weight: var(--secure-ui-font-weight-medium); } .error-container { margin-top: var(--secure-ui-form-error-margin-top); font-size: var(--secure-ui-error-font-size); color: var(--secure-ui-error-color); line-height: var(--secure-ui-line-height-normal); overflow: hidden; max-height: 40px; opacity: 1; transform: translateY(0); transition: opacity 0.2s ease-out, transform 0.2s ease-out, max-height 0.2s ease-out, margin-top 0.2s ease-out; } .error-container.hidden { max-height: 0; opacity: 0; transform: translateY(-4px); margin-top: 0; } @media (prefers-reduced-motion: reduce) { .textarea-field, .error-container, .threat-container { transition: none !important; } } .threat-container { margin-top: var(--secure-ui-form-error-margin-top); font-size: var(--secure-ui-error-font-size); color: var(--secure-ui-color-warning); line-height: var(--secure-ui-line-height-normal); overflow: hidden; max-height: 40px; opacity: 1; transform: translateY(0); transition: opacity 0.2s ease-out, transform 0.2s ease-out, max-height 0.2s ease-out, margin-top 0.2s ease-out; display: flex; align-items: center; gap: var(--secure-ui-space-1, 4px); flex-wrap: wrap; } .threat-container.hidden { max-height: 0; opacity: 0; transform: translateY(-4px); margin-top: 0; } .threat-message { flex: 1; min-width: 0; } .threat-badge { display: inline-block; padding: var(--secure-ui-badge-padding); font-size: var(--secure-ui-badge-font-size); font-weight: var(--secure-ui-font-weight-semibold); border-radius: var(--secure-ui-badge-border-radius); background-color: color-mix(in srgb, var(--secure-ui-color-warning) 12%, transparent); color: var(--secure-ui-color-warning); border: var(--secure-ui-border-width-thin) solid currentColor; font-family: var(--secure-ui-font-family-mono, monospace); white-space: nowrap; } .textarea-field.threat { border-color: var(--secure-ui-color-warning) !important; } .textarea-field.threat:focus { box-shadow: 0 0 0 3px color-mix(in srgb, var(--secure-ui-color-warning) 25%, transparent); } :host([security-tier="authenticated"]) .textarea-field { border-color: var(--secure-ui-tier-authenticated); } :host([security-tier="sensitive"]) .textarea-field { border-color: var(--secure-ui-tier-sensitive); } :host([security-tier="critical"]) .textarea-field { border-color: var(--secure-ui-tier-critical); }'}handleAttributeChange(e,t,i){if(this.#e)switch(e){case"disabled":this.#e.disabled=this.hasAttribute("disabled");break;case"readonly":this.#e.readOnly=this.hasAttribute("readonly");break;case"value":i!==this.#e.value&&(this.#e.value=i||"",this.#c());break}}get value(){return this.#e?this.#e.value:""}set value(e){this.#e&&(this.#e.value=e||"",this.#c())}get name(){return this.#e?this.#e.name:""}get valid(){let e=this.getAttribute("minlength"),t=this.getAttribute("maxlength");return this.validateInput(this.#e.value,{required:this.hasAttribute("required")||this.config.validation.required,minLength:e?parseInt(e,10):0,maxLength:t?parseInt(t,10):this.config.validation.maxLength}).valid}focus(){this.#e&&this.#e.focus()}blur(){this.#e&&this.#e.blur()}showThreatFeedback(e){if(!this.#r||!this.#e)return;this.#r.textContent="";let t=document.createElement("span");t.className="threat-message",t.textContent=this.getThreatLabel(e);let i=document.createElement("span");i.className="threat-badge",i.textContent=e,this.#r.appendChild(t),this.#r.appendChild(i),this.#r.offsetHeight,this.#r.classList.remove("hidden"),this.#e.classList.add("threat"),this.#e.setAttribute("aria-invalid","true")}clearThreatFeedback(){!this.#r||!this.#e||(this.#r.classList.add("hidden"),this.#r.addEventListener("transitionend",()=>{this.#r.classList.contains("hidden")&&(this.#r.textContent="")},{once:!0}),this.#e.classList.remove("threat"),this.#e.removeAttribute("aria-invalid"))}disconnectedCallback(){super.disconnectedCallback(),this.#e&&(this.#e.value="")}};customElements.define("secure-textarea",z);var I=class extends p{#e=null;#s=null;#i=null;#r=`secure-select-${Math.random().toString(36).substring(2,11)}`;#t=new Set;#n=!1;#a=!1;static get observedAttributes(){return[...super.observedAttributes,"name","label","required","multiple","size","value"]}constructor(){super()}render(){let e=document.createDocumentFragment(),t=document.createElement("div");t.className="select-container",t.setAttribute("part","container"),this.#a=this.hasAttribute("multiple");let i=this.getAttribute("label");i&&(this.#s=document.createElement("label"),this.#s.htmlFor=this.#r,this.#s.textContent=this.sanitizeValue(i),this.#s.setAttribute("part","label"),t.appendChild(this.#s));let r=document.createElement("div");return r.className="select-wrapper",r.setAttribute("part","wrapper"),this.#e=document.createElement("select"),this.#e.id=this.#r,this.#e.className="select-field",this.#e.setAttribute("part","select"),this.#o(),this.#c(),queueMicrotask(()=>{this.#u()}),r.appendChild(this.#e),t.appendChild(r),this.#i=document.createElement("div"),this.#i.className="error-container hidden",this.#i.setAttribute("role","alert"),this.#i.setAttribute("part","error"),this.#i.id=`${this.#r}-error`,t.appendChild(this.#i),this.addComponentStyles(this.#b()),e.appendChild(t),e}#o(){let e=this.config,t=this.getAttribute("name");t&&(this.#e.name=this.sanitizeValue(t)),!this.getAttribute("label")&&t&&this.#e.setAttribute("aria-label",this.sanitizeValue(t)),this.#e.setAttribute("aria-describedby",`${this.#r}-error`),(this.hasAttribute("required")||e.validation.required)&&(this.#e.required=!0,this.#e.setAttribute("aria-required","true")),this.hasAttribute("multiple")&&(this.#e.multiple=!0);let i=this.getAttribute("size");i&&(this.#e.size=parseInt(i,10)),this.hasAttribute("disabled")&&(this.#e.disabled=!0),e.storage.allowAutocomplete||(this.#e.autocomplete="off")}#u(){if(this.#n)return;this.#n=!0;let e=Array.from(this.querySelectorAll("option"));if(e.length===0)return;let t=[];if(e.forEach(i=>{let r=document.createElement("option"),s=i.getAttribute("value")||"";r.value=this.sanitizeValue(s),this.#t.add(r.value),r.textContent=this.sanitizeValue(i.textContent||""),i.hasAttribute("selected")&&(r.selected=!0,t.push(r.value)),i.hasAttribute("disabled")&&(r.disabled=!0),this.#e.appendChild(r)}),!this.#a){let i=this.getAttribute("value");i?this.#e.value=i:t.length>0&&(this.#e.value=t[0])}}#c(){this.#e.addEventListener("focus",()=>{this.recordTelemetryFocus(),this.audit("select_focused",{name:this.#e.name})}),this.#e.addEventListener("change",e=>{this.recordTelemetryInput(e),this.#h(e)}),this.#e.addEventListener("blur",()=>{this.recordTelemetryBlur(),this.#d(),this.audit("select_blurred",{name:this.#e.name,hasValue:this.#a?this.#e.selectedOptions.length>0:this.#e.value.length>0})})}#h(e){if(this.#a){let t=Array.from(this.#e.selectedOptions).map(r=>r.value),i=t.filter(r=>r&&!this.#t.has(r));if(i.length>0){this.#l("Invalid option selected"),this.audit("invalid_option_detected",{name:this.#e.name,attemptedValues:i});return}this.#p(),this.audit("select_changed",{name:this.#e.name,values:t}),this.dispatchEvent(new CustomEvent("secure-select",{detail:{name:this.#e.name,value:t,tier:this.securityTier},bubbles:!0,composed:!0}))}else{let t=this.#e.value;if(t&&!this.#t.has(t)){this.#l("Invalid option selected"),this.audit("invalid_option_detected",{name:this.#e.name,attemptedValue:t}),this.#e.value="";return}this.#p(),this.audit("select_changed",{name:this.#e.name,value:t}),this.dispatchEvent(new CustomEvent("secure-select",{detail:{name:this.#e.name,value:t,tier:this.securityTier},bubbles:!0,composed:!0}))}}#d(){let e=this.checkRateLimit();if(!e.allowed){this.#l(`Too many attempts. Please wait ${Math.ceil(e.retryAfter/1e3)} seconds.`);return}let t=this.hasAttribute("required")||this.config.validation.required;if(this.#a){let i=Array.from(this.#e.selectedOptions).map(s=>s.value).filter(s=>s!=="");if(t&&i.length===0){this.#l("Please select at least one option");return}if(i.filter(s=>!this.#t.has(s)).length>0){this.#l("Invalid option selected");return}}else{if(t&&!this.#e.value){this.#l("Please select an option");return}let i=this.#e.value;if(i&&!this.#t.has(i)){this.#l("Invalid option selected");return}}}#l(e){this.#i.textContent=e,this.#i.offsetHeight,this.#i.classList.remove("hidden"),this.#e.classList.add("error"),this.#e.setAttribute("aria-invalid","true")}#p(){this.#i.classList.add("hidden"),this.#i.addEventListener("transitionend",()=>{this.#i.classList.contains("hidden")&&(this.#i.textContent="")},{once:!0}),this.#e.classList.remove("error"),this.#e.removeAttribute("aria-invalid")}#b(){return'.select-container { margin-bottom: var(--secure-ui-form-gap); font-family: var(--secure-ui-font-family-base); } label { display: block; margin-bottom: var(--secure-ui-form-label-margin-bottom); font-size: var(--secure-ui-label-font-size); font-weight: var(--secure-ui-label-font-weight); color: var(--secure-ui-label-color); } .label-suffix { font-weight: var(--secure-ui-font-weight-normal); color: var(--secure-ui-color-text-secondary); font-size: var(--secure-ui-font-size-xs); margin-left: var(--secure-ui-space-1); } .security-badge { display: inline-block; padding: var(--secure-ui-badge-padding); margin-left: var(--secure-ui-space-2); font-size: var(--secure-ui-badge-font-size); font-weight: var(--secure-ui-font-weight-semibold); border-radius: var(--secure-ui-badge-border-radius); text-transform: uppercase; background-color: var(--secure-ui-color-bg-tertiary); color: var(--secure-ui-color-text-secondary); border: var(--secure-ui-border-width-thin) solid var(--secure-ui-color-border); } .select-wrapper { position: relative; } .select-field { width: 100%; height: var(--secure-ui-select-height); padding: var(--secure-ui-select-padding); font-family: var(--secure-ui-font-family-base); font-size: var(--secure-ui-input-font-size); line-height: var(--secure-ui-line-height-normal); color: var(--secure-ui-select-color); background-color: var(--secure-ui-select-background-color); border: var(--secure-ui-input-border-width) solid var(--secure-ui-input-border-color); border-radius: var(--secure-ui-input-border-radius); transition: all var(--secure-ui-transition-base) var(--secure-ui-transition-ease-in-out); cursor: pointer; box-sizing: border-box; } .select-field, ::picker(select) { appearance: base-select; border-radius: .25rem; } .select-field::picker-icon { color: #999999; transition: 0.2s rotate; } .select-field:open::picker-icon { rotate: 180deg; } .select-field option { display: flex; justify-content: flex-start; color: var(--secure-ui-select-color); background-color: var(--secure-ui-select-background-color); padding: .5rem; } .select-field option:hover { box-shadow: 0px 0px 4px 0px var(--secure-ui-input-border-color) inset; transition: all 0.2s ease-in-out; } .select-field option:first-of-type { border-top-left-radius: none; border-top-right-radius: none; } .select-field option:last-of-type { border-bottom-left-radius: none; border-bottom-right-radius: none; } .select-field option:nth-of-type(odd) { } .select-field option:checked { font-weight: bold; } .select-field option::checkmark { order: 1; margin-left: auto; content: "\u2713"; } .select-field option + option { border-top: 1px solid var(--secure-ui-input-border-color); } .select-field:hover:not(:disabled) { border-color: var(--secure-ui-input-border-color-hover); } .select-field:focus { outline: none; border-color: var(--secure-ui-input-border-color-focus); box-shadow: var(--secure-ui-shadow-focus); } .select-field.error { border-color: var(--secure-ui-color-error); } .select-field.error:focus { box-shadow: var(--secure-ui-shadow-focus-error); } .select-field:disabled { background-color: var(--secure-ui-input-disabled-bg); cursor: not-allowed; opacity: var(--secure-ui-input-disabled-opacity); } .select-field[multiple] { height: auto; min-height: calc(var(--secure-ui-select-height) * 2); padding: var(--secure-ui-space-2); } .error-container { position: absolute; margin-top: var(--secure-ui-form-error-margin-top); font-size: var(--secure-ui-error-font-size); color: var(--secure-ui-error-color); line-height: var(--secure-ui-line-height-normal); overflow: hidden; max-height: 40px; opacity: 1; transform: translateY(0); transition: opacity 0.2s ease-out, transform 0.2s ease-out, max-height 0.2s ease-out, margin-top 0.2s ease-out; } .error-container.hidden { max-height: 0; opacity: 0; transform: translateY(-4px); margin-top: 0; } @media (prefers-reduced-motion: reduce) { .select-field, .error-container { transition: none !important; } }'}handleAttributeChange(e,t,i){if(this.#e)switch(e){case"disabled":this.#e.disabled=this.hasAttribute("disabled");break;case"value":i!==this.#e.value&&(this.#e.value=i||"");break}}get value(){return this.#e?this.#a?Array.from(this.#e.selectedOptions).map(e=>e.value).filter(e=>e!=="").join(", "):this.#e.value:""}set value(e){if(this.#e)if(this.#a){let t=e.split(",").map(i=>i.trim()).filter(i=>i!=="");Array.from(this.#e.options).forEach(i=>{i.selected=!1}),t.forEach(i=>{if(this.#t.has(i)){let r=Array.from(this.#e.options).find(s=>s.value===i);r&&(r.selected=!0)}})}else this.#t.has(e)&&(this.#e.value=e)}get name(){return this.#e?this.#e.name:""}get selectedOptions(){return this.#e?Array.from(this.#e.selectedOptions).map(e=>e.value):[]}get valid(){let e=this.hasAttribute("required")||this.config.validation.required;if(this.#a){let i=Array.from(this.#e.selectedOptions).map(r=>r.value).filter(r=>r!=="");return e&&i.length===0?!1:i.every(r=>this.#t.has(r))}if(e&&!this.#e.value)return!1;let t=this.#e.value;return!(t&&!this.#t.has(t))}focus(){this.#e&&this.#e.focus()}blur(){this.#e&&this.#e.blur()}addOption(e,t,i=!1){if(!this.#e)return;let r=document.createElement("option");r.value=this.sanitizeValue(e),r.textContent=this.sanitizeValue(t),r.selected=i,this.#t.add(r.value),this.#e.appendChild(r)}removeOption(e){if(!this.#e)return;let i=Array.from(this.#e.options).find(r=>r.value===e);i&&(this.#e.removeChild(i),this.#t.delete(e))}clearOptions(){this.#e&&(this.#e.innerHTML="",this.#t.clear())}disconnectedCallback(){super.disconnectedCallback()}};customElements.define("secure-select",I);var M=class l extends HTMLElement{static __stylesAdded=!1;#e=null;#s=null;#i=null;#r=!1;#t=Date.now();#n=`secure-form-${Math.random().toString(36).substring(2,11)}`;#a=c.PUBLIC;static get observedAttributes(){return["security-tier","action","method","enctype","csrf-token","csrf-header-name","csrf-field-name","novalidate"]}constructor(){super()}connectedCallback(){if(this.#e)return;this.#t=Date.now();let e=this.getAttribute("security-tier");e&&(this.#a=e);let t=this.querySelector("form");if(t){this.#e=t,this.#e.id=this.#n,this.#e.classList.contains("secure-form")||this.#e.classList.add("secure-form"),this.#u();let i=this.getAttribute("csrf-field-name")||"csrf_token",r=t.querySelector(`input[name="${i}"]`);if(r){this.#s=r;let s=this.getAttribute("csrf-token");s&&r.value!==s&&(r.value=s)}else this.#c()}else{for(this.#e=document.createElement("form"),this.#e.id=this.#n,this.#e.className="secure-form",this.#u(),this.#c();this.firstChild;)this.#e.appendChild(this.firstChild);this.appendChild(this.#e)}this.#i=document.createElement("div"),this.#i.className="form-status form-status-hidden",this.#i.setAttribute("role","status"),this.#i.setAttribute("aria-live","polite"),this.#e.insertBefore(this.#i,this.#e.firstChild),this.#o(),this.#h(),this.audit("form_initialized",{formId:this.#n,action:this.#e.action,method:this.#e.method})}#o(){if(!l.__stylesAdded){let e='secure-form { display: block; } secure-form .secure-form { padding: 16px; border: 2px solid #e0e0e0; border-radius: 8px; background-color: transparent; } secure-form[security-tier="critical"] .secure-form { padding: 20px; } secure-form[security-tier="public"] .secure-form { border: none; } secure-form .form-status { padding: 12px; margin-bottom: 16px; border-radius: 4px; font-size: 14px; } secure-form .form-status-hidden { display: none; } secure-form .form-status-info { display: block; background-color: #E3F2FD; color: #1976D2; border: 1px solid #1976D2; } secure-form .form-status-success { display: block; background-color: #E8F5E9; color: #388E3C; border: 1px solid #388E3C; } secure-form .form-status-error { display: block; background-color: #FFEBEE; color: #D32F2F; border: 1px solid #D32F2F; }';if(e.includes("{")){let t=new CSSStyleSheet;t.replaceSync(e),document.adoptedStyleSheets=[...document.adoptedStyleSheets,t]}else{let t=document.createElement("link");t.rel="stylesheet",t.href=e,document.head.appendChild(t)}l.__stylesAdded=!0}}#u(){let e=this.getAttribute("action");e&&(this.#e.action=e);let t=this.getAttribute("method")||"POST";this.#e.method=t.toUpperCase();let i=this.getAttribute("enctype")||"application/x-www-form-urlencoded";this.#e.enctype=i,this.hasAttribute("novalidate")&&(this.#e.noValidate=!0),(this.#a===c.SENSITIVE||this.#a===c.CRITICAL)&&(this.#e.autocomplete="off")}#c(){let e=this.getAttribute("csrf-token");if(e){this.#s=document.createElement("input"),this.#s.type="hidden";let t=this.getAttribute("csrf-field-name")||"csrf_token";this.#s.name=t,this.#s.value=e,this.#e.appendChild(this.#s),this.audit("csrf_token_injected",{formId:this.#n,fieldName:t})}else(this.securityTier===c.SENSITIVE||this.securityTier===c.CRITICAL)&&console.warn("CSRF token not provided for SENSITIVE/CRITICAL tier form")}#h(){this.#e.addEventListener("submit",e=>{this.#l(e)}),this.addEventListener("secure-input",e=>{this.#d(e)}),this.addEventListener("secure-textarea",e=>{this.#d(e)}),this.addEventListener("secure-select",e=>{this.#d(e)})}#d(e){this.#E()}async#l(e){let t=this.hasAttribute("enhance");if(this.#r){e.preventDefault();return}(this.#a===c.SENSITIVE||this.#a===c.CRITICAL)&&!this.#s?.value&&this.dispatchEvent(new CustomEvent("secure-threat-detected",{detail:{fieldName:this.#n,threatType:"csrf-token-absent",patternId:"csrf-token-absent",tier:this.#a,timestamp:Date.now()},bubbles:!0,composed:!0}));let i=this.checkRateLimit();if(!i.allowed){e.preventDefault(),this.#v(`Too many submission attempts. Please wait ${Math.ceil(i.retryAfter/1e3)} seconds.`,"error"),this.audit("form_rate_limited",{formId:this.#n,retryAfter:i.retryAfter});return}let r=this.#b();if(!r.valid){e.preventDefault(),this.#v(r.errors.join(", "),"error"),this.audit("form_validation_failed",{formId:this.#n,errors:r.errors});return}if(!t){this.#p(),this.audit("form_submitted_native",{formId:this.#n,action:this.#e.action,method:this.#e.method});return}e.preventDefault(),this.#r=!0,this.#v("Submitting...","info"),this.#m();let s=this.#f(),n=this.#x();this.audit("form_submitted_enhanced",{formId:this.#n,action:this.#e.action,method:this.#e.method,fieldCount:Object.keys(s).length,riskScore:n.riskScore,riskSignals:n.riskSignals});let a=new CustomEvent("secure-form-submit",{detail:{formData:s,formElement:this.#e,telemetry:n,preventDefault:()=>{this.#r=!1,this.#g()}},bubbles:!0,composed:!0,cancelable:!0});if(!this.dispatchEvent(a)){this.#r=!1,this.#g();return}try{await this.#y(s,n)}catch(u){this.#v("Submission failed. Please try again.","error"),this.audit("form_submission_error",{formId:this.#n,error:u.message})}finally{this.#r=!1,this.#g()}}#p(){this.#e.querySelectorAll("secure-input, secure-textarea, secure-select, secure-datetime, secure-file-upload").forEach(t=>{let i=t.getAttribute("name");if(!i)return;t.querySelectorAll(`input[name="${i}"], textarea[name="${i}"], select[name="${i}"]`).forEach(n=>{n.removeAttribute("name")});let s=this.#e.querySelector(`input[type="hidden"][data-secure-input="${i}"]`);s||(s=document.createElement("input"),s.type="hidden",s.setAttribute("data-secure-input",i),s.name=i,this.#e.appendChild(s)),s.value=t.value||""})}#b(){let e=[];return this.#e.querySelectorAll("secure-input, secure-textarea, secure-select, secure-datetime, secure-file-upload").forEach(i=>{if(typeof i.valid=="boolean"&&!i.valid){let r=i.getAttribute("label")||i.getAttribute("name")||"Field";e.push(`${r} is invalid`)}}),{valid:e.length===0,errors:e}}#f(){let e=Object.create(null);return this.#e.querySelectorAll("secure-input, secure-textarea, secure-select, secure-datetime, secure-file-upload").forEach(r=>{let s=r;s.name&&(e[s.name]=s.value)}),this.#e.querySelectorAll('input:not([type="hidden"]), textarea:not(.textarea-field), select:not(.select-field)').forEach(r=>{let s=r;s.name&&(e[s.name]=this.sanitizeValue(s.value))}),this.#s&&(e[this.#s.name]=this.#s.value),e}async#y(e,t){let i=this.#e.action,r=this.#e.method,s={"Content-Type":"application/json"},n=this.getAttribute("csrf-header-name");n&&this.#s&&(s[n]=this.#s.value);let a={...e,_telemetry:t},o=await fetch(i,{method:r,headers:s,body:JSON.stringify(a),credentials:"same-origin",mode:"cors",cache:"no-cache",redirect:"follow"});if(!o.ok)throw new Error(`HTTP ${o.status}: ${o.statusText}`);return this.#v("Form submitted successfully!","success"),this.dispatchEvent(new CustomEvent("secure-form-success",{detail:{formData:e,response:o,telemetry:t},bubbles:!0,composed:!0})),o}#m(){this.#e.querySelectorAll("input, textarea, select, button").forEach(i=>{i.disabled=!0}),this.querySelectorAll("secure-input, secure-textarea, secure-select, secure-datetime, secure-file-upload").forEach(i=>{i.setAttribute("disabled","")})}#g(){this.#e.querySelectorAll("input, textarea, select, button").forEach(i=>{i.disabled=!1}),this.querySelectorAll("secure-input, secure-textarea, secure-select, secure-datetime, secure-file-upload").forEach(i=>{i.removeAttribute("disabled")})}#v(e,t="info"){this.#i.textContent=e,this.#i.className=`form-status form-status-${t}`}#E(){this.#i.textContent="",this.#i.className="form-status form-status-hidden"}#x(){let t=this.querySelectorAll("secure-input, secure-textarea, secure-select, secure-datetime, secure-card"),i=[];t.forEach(a=>{let o=a;if(typeof o.getFieldTelemetry!="function")return;let u=a.getAttribute("name")??a.tagName.toLowerCase(),d={...o.getFieldTelemetry(),fieldName:u,fieldType:a.tagName.toLowerCase()};i.push(d)});let r=Date.now()-this.#t,{riskScore:s,riskSignals:n}=this.#w(i,r);return{sessionDuration:r,fieldCount:i.length,fields:i,riskScore:s,riskSignals:n,submittedAt:new Date().toISOString()}}#w(e,t){let i=[],r=0;if(t<3e3?(r+=30,i.push("session_too_fast")):t<8e3&&(r+=10,i.push("session_fast")),e.length===0)return{riskScore:Math.min(r,100),riskSignals:i};e.every(h=>h.pasteDetected&&h.velocity===0)&&(r+=25,i.push("all_fields_pasted")),e.some(h=>h.velocity>15)&&(r+=15,i.push("high_velocity_typing")),e.some(h=>h.focusCount===0)&&(r+=15,i.push("field_filled_without_focus")),e.some(h=>h.focusCount>1&&h.blurWithoutChange>1)&&(r+=10,i.push("form_probing")),e.some(h=>h.corrections>5)&&(r+=5,i.push("high_correction_count"));let d=e.filter(h=>h.autofillDetected);return d.length>0&&d.length===e.length&&(r-=10,i.push("autofill_detected")),{riskScore:Math.max(0,Math.min(r,100)),riskSignals:i}}getData(){return this.#f()}reset(){this.#e&&(this.#e.reset(),this.#E(),this.audit("form_reset",{formId:this.#n}))}submit(){this.#e&&this.#e.dispatchEvent(new Event("submit",{bubbles:!0,cancelable:!0}))}get valid(){return this.#b().valid}disconnectedCallback(){this.#e&&this.#e.reset()}attributeChangedCallback(e,t,i){if(this.#e)switch(e){case"security-tier":this.#a=i||c.PUBLIC;break;case"action":this.#e.action=i;break;case"method":this.#e.method=i;break;case"csrf-token":this.#s&&(this.#s.value=i);break}}get securityTier(){return this.#a}sanitizeValue(e){if(typeof e!="string")return"";let t=document.createElement("div");return t.textContent=e,t.innerHTML}audit(e,t){console.debug&&console.debug(`[secure-form] ${e}`,t)}checkRateLimit(){return{allowed:!0,retryAfter:0}}};customElements.define("secure-form",M);var D=class extends p{#e=null;#s=null;#i=null;#r=null;#t=null;#n=null;#a=null;#o=`secure-file-upload-${Math.random().toString(36).substring(2,11)}`;#u=new Set;#c=5*1024*1024;#h=null;#d=!1;static get observedAttributes(){return[...super.observedAttributes,"name","label","accept","max-size","multiple","required","capture"]}constructor(){super()}render(){let e=document.createDocumentFragment(),t=document.createElement("div");t.className="file-upload-container",t.setAttribute("part","container");let i=this.getAttribute("label");i&&(this.#s=document.createElement("label"),this.#s.htmlFor=this.#o,this.#s.textContent=this.sanitizeValue(i),this.#s.setAttribute("part","label"),t.appendChild(this.#s)),this.#t=document.createElement("div"),this.#t.className="drop-zone",this.#t.setAttribute("part","wrapper"),this.#e=document.createElement("input"),this.#e.type="file",this.#e.id=this.#o,this.#e.className="file-input",this.#e.setAttribute("part","input"),this.#l(),this.#g();let r=document.createElement("div");r.className="drop-zone-content has-name";let s=document.createElement("span");s.className="file-cta";let n=document.createElement("span");n.className="drop-icon";let a=document.createElementNS("http://www.w3.org/2000/svg","svg");a.setAttribute("width","16"),a.setAttribute("height","16"),a.setAttribute("viewBox","0 0 24 24"),a.setAttribute("fill","none"),a.setAttribute("stroke","currentColor"),a.setAttribute("stroke-width","2"),a.setAttribute("stroke-linecap","round"),a.setAttribute("stroke-linejoin","round"),a.setAttribute("aria-hidden","true"),a.setAttribute("focusable","false");let o=document.createElementNS("http://www.w3.org/2000/svg","path");o.setAttribute("d","M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4");let u=document.createElementNS("http://www.w3.org/2000/svg","polyline");u.setAttribute("points","17 8 12 3 7 8");let d=document.createElementNS("http://www.w3.org/2000/svg","line");d.setAttribute("x1","12"),d.setAttribute("y1","3"),d.setAttribute("x2","12"),d.setAttribute("y2","15"),a.appendChild(o),a.appendChild(u),a.appendChild(d),n.appendChild(a),s.appendChild(n);let h=document.createElement("span");h.className="drop-text",h.textContent="Choose a file\u2026",s.appendChild(h),r.appendChild(s),this.#n=document.createElement("span"),this.#n.className="file-name-display",this.#n.textContent="No file selected",r.appendChild(this.#n),this.#t.appendChild(this.#e),this.#t.appendChild(r),t.appendChild(this.#t);let f=document.createElement("div");return f.className="drop-hint",f.textContent=this.#m(),t.appendChild(f),this.#r=document.createElement("div"),this.#r.className="preview-container",t.appendChild(this.#r),this.#i=document.createElement("div"),this.#i.className="error-container hidden",this.#i.setAttribute("role","alert"),this.#i.setAttribute("part","error"),this.#i.id=`${this.#o}-error`,t.appendChild(this.#i),this.#e.setAttribute("aria-describedby",`${this.#o}-error`),this.addComponentStyles(this.#P()),e.appendChild(t),e}#l(){let e=this.config,t=this.getAttribute("name");t&&(this.#e.name=this.sanitizeValue(t));let i=this.getAttribute("accept");if(i)this.#e.accept=i,this.#p(i);else{let n=this.#f();this.#e.accept=n,this.#p(n)}let r=this.getAttribute("max-size");r?this.#c=parseInt(r,10):this.#c=this.#y(),this.hasAttribute("multiple")&&(this.#e.multiple=!0),(this.hasAttribute("required")||e.validation.required)&&(this.#e.required=!0);let s=this.getAttribute("capture");s&&(this.#e.capture=s),this.hasAttribute("disabled")&&(this.#e.disabled=!0)}#p(e){this.#u.clear(),e.split(",").map(i=>i.trim()).forEach(i=>{if(i.startsWith(".")){let r=this.#b(i);r&&this.#u.add(r)}else this.#u.add(i)})}#b(e){return{".pdf":"application/pdf",".doc":"application/msword",".docx":"application/vnd.openxmlformats-officedocument.wordprocessingml.document",".xls":"application/vnd.ms-excel",".xlsx":"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",".ppt":"application/vnd.ms-powerpoint",".pptx":"application/vnd.openxmlformats-officedocument.presentationml.presentation",".txt":"text/plain",".csv":"text/csv",".jpg":"image/jpeg",".jpeg":"image/jpeg",".png":"image/png",".gif":"image/gif",".svg":"image/svg+xml",".zip":"application/zip",".json":"application/json"}[e.toLowerCase()]||null}#f(){switch(this.securityTier){case c.CRITICAL:return".pdf,.txt";case c.SENSITIVE:return".pdf,.doc,.docx,.txt,.jpg,.jpeg,.png";case c.AUTHENTICATED:return".pdf,.doc,.docx,.xls,.xlsx,.txt,.csv,.jpg,.jpeg,.png,.gif";case c.PUBLIC:default:return".pdf,.doc,.docx,.xls,.xlsx,.txt,.csv,.jpg,.jpeg,.png,.gif,.zip"}}#y(){switch(this.securityTier){case c.CRITICAL:return 2*1024*1024;case c.SENSITIVE:return 5*1024*1024;case c.AUTHENTICATED:return 10*1024*1024;case c.PUBLIC:default:return 20*1024*1024}}#m(){let e=(this.#c/1048576).toFixed(1);return`Accepted: ${this.#e.accept||"all files"} (max ${e}MB)`}#g(){this.#e.addEventListener("change",e=>{this.#v(e)}),this.#t.addEventListener("dragover",e=>{e.preventDefault(),e.stopPropagation(),this.#t.classList.add("drag-over")}),this.#t.addEventListener("dragleave",e=>{e.preventDefault(),e.stopPropagation(),this.#t.classList.remove("drag-over")}),this.#t.addEventListener("drop",e=>{e.preventDefault(),e.stopPropagation(),this.#t.classList.remove("drag-over");let t=e;if(!t.dataTransfer)return;let i=t.dataTransfer.files;i.length>0&&(this.#e.files=i,this.#v({target:this.#e}))})}async#v(e){let t=e.target.files;if(!t||t.length===0)return;let i=this.checkRateLimit();if(!i.allowed){this.#D(`Too many upload attempts. Please wait ${Math.ceil(i.retryAfter/1e3)} seconds.`),this.#e.value="";return}this.#H();let r=await this.#E(t);if(!r.valid){this.#D(r.errors.join(", ")),this.#e.value="",this.#a=null;return}this.#a=t,this.#I(t),this.#$(t),this.audit("files_selected",{name:this.#e.name,fileCount:t.length,totalSize:Array.from(t).reduce((s,n)=>s+n.size,0)}),this.dispatchEvent(new CustomEvent("secure-file-upload",{detail:{name:this.#e.name,files:Array.from(t),tier:this.securityTier},bubbles:!0,composed:!0}))}async#E(e){let t=[];!this.#e.multiple&&e.length>1&&t.push("Only one file is allowed");for(let i=0;i<e.length;i++){let r=e[i];if(r.size>this.#c){let s=(this.#c/1048576).toFixed(1);t.push(`${r.name}: File size exceeds ${s}MB`);continue}if(this.#u.size>0&&!this.#x(r)){t.push(`${r.name}: File type not allowed`);continue}if(this.#w(r.name)){t.push(`${r.name}: Invalid file name`);continue}if(this.securityTier===c.CRITICAL){let s=await this.#z(r);if(!s.valid){t.push(`${r.name}: ${s.error}`);continue}}if(this.#h){let s=await this.#C(r);if(!s.valid){t.push(`${r.name}: ${s.reason||"Rejected by scan"}`);continue}}}return{valid:t.length===0,errors:t}}#x(e){if(this.#u.has(e.type))return!0;for(let t of this.#u)if(t.endsWith("/*")){let i=t.slice(0,-2);if(e.type.startsWith(i))return!0}return!1}#w(e){return!!(e.includes("..")||e.includes("/")||e.includes("\\")||["web.config",".htaccess",".env","config.php"].includes(e.toLowerCase()))}async#C(e){this.#d=!0,this.#S(e.name),this.audit("scan_started",{name:this.#e?.name??"",fileName:e.name,fileSize:e.size});try{let t=await this.#h(e);return this.audit(t.valid?"scan_passed":"scan_rejected",{name:this.#e?.name??"",fileName:e.name,reason:t.reason??""}),t}catch(t){let i=t instanceof Error?t.message:"Scan failed";return this.audit("scan_error",{name:this.#e?.name??"",fileName:e.name,error:i}),{valid:!1,reason:`Scan error: ${i}`}}finally{this.#d=!1,this.#k()}}#S(e){this.#t&&this.#t.classList.add("scanning"),this.#e&&(this.#e.disabled=!0),this.#n&&(this.#n.textContent=`Scanning ${e}\u2026`)}#k(){this.#t&&this.#t.classList.remove("scanning"),this.#e&&!this.hasAttribute("disabled")&&(this.#e.disabled=!1)}async#z(e){try{let t=await e.slice(0,4).arrayBuffer(),i=new Uint8Array(t),r={"application/pdf":[37,80,68,70],"image/jpeg":[255,216,255],"image/png":[137,80,78,71]};return r[e.type]&&!r[e.type].every((a,o)=>i[o]===a)?{valid:!1,error:"File content does not match declared type"}:{valid:!0}}catch{return{valid:!1,error:"Failed to validate file content"}}}#I(e){this.#n&&(!e||e.length===0?(this.#n.textContent="No file selected",this.#n.classList.remove("has-file")):e.length===1?(this.#n.textContent=e[0].name,this.#n.classList.add("has-file")):(this.#n.textContent=`${e.length} files selected`,this.#n.classList.add("has-file")))}#$(e){this.#r.innerHTML="",Array.from(e).forEach(t=>{let i=document.createElement("div");i.className="file-preview";let r=document.createElement("div");r.className="file-name",r.textContent=t.name;let s=document.createElement("div");s.className="file-size",s.textContent=this.#R(t.size);let n=document.createElement("button");n.className="remove-file",n.textContent="\u2715",n.type="button",n.onclick=()=>{this.#M()},i.appendChild(r),i.appendChild(s),i.appendChild(n),this.#r.appendChild(i)})}#R(e){return e<1024?e+" B":e<1024*1024?(e/1024).toFixed(1)+" KB":(e/(1024*1024)).toFixed(1)+" MB"}#M(){this.#e.value="",this.#a=null,this.#r.innerHTML="",this.#I(null),this.#H(),this.audit("file_removed",{name:this.#e.name})}#D(e){this.#i.textContent=e,this.#i.classList.remove("hidden"),this.#t.classList.add("error")}#H(){this.#i.textContent="",this.#i.classList.add("hidden"),this.#t.classList.remove("error")}#P(){return".file-upload-container { position: relative; margin-bottom: var(--secure-ui-form-gap); font-family: var(--secure-ui-font-family-base); } label { display: block; margin-bottom: var(--secure-ui-form-label-margin-bottom); font-size: var(--secure-ui-label-font-size); font-weight: var(--secure-ui-label-font-weight); color: var(--secure-ui-label-color); } .label-suffix { font-weight: var(--secure-ui-font-weight-normal); color: var(--secure-ui-color-text-secondary); font-size: var(--secure-ui-font-size-xs); margin-left: var(--secure-ui-space-1); } .security-badge { display: inline-block; padding: var(--secure-ui-badge-padding); margin-left: var(--secure-ui-space-2); font-size: var(--secure-ui-badge-font-size); font-weight: var(--secure-ui-font-weight-semibold); border-radius: var(--secure-ui-badge-border-radius); text-transform: uppercase; background-color: var(--secure-ui-color-bg-tertiary); color: var(--secure-ui-color-text-secondary); border: var(--secure-ui-border-width-thin) solid var(--secure-ui-color-border); } .drop-zone { position: relative; display: inline-flex; align-items: stretch; justify-content: flex-start; border-radius: var(--secure-ui-input-border-radius); cursor: pointer; width: 100%; } .drop-zone.drag-over { transform: scale(1.01); } .drop-zone.error .file-cta { border-color: var(--secure-ui-color-error); color: var(--secure-ui-color-error); } .file-input { position: absolute; top: 0; left: 0; width: 100%; height: 100%; opacity: 0; cursor: pointer; z-index: 1; } .file-input:focus { outline: none; } .drop-zone:focus-within .file-cta { outline: 2px solid var(--secure-ui-color-border-focus); outline-offset: 2px; box-shadow: var(--secure-ui-shadow-focus); } @media (forced-colors: active) { .drop-zone:focus-within .file-cta { outline: 2px solid ButtonText; box-shadow: none; } } .drop-zone-content { display: flex; align-items: stretch; width: 100%; pointer-events: none; } .file-cta { display: flex; align-items: center; justify-content: center; padding: var(--secure-ui-input-padding-y) var(--secure-ui-input-padding-x); background-color: var(--secure-ui-color-bg-secondary); border: var(--secure-ui-input-border-width) solid var(--secure-ui-input-border-color); border-radius: var(--secure-ui-input-border-radius); color: var(--secure-ui-color-text-primary); font-size: var(--secure-ui-input-font-size); font-weight: var(--secure-ui-font-weight-medium); white-space: nowrap; transition: all var(--secure-ui-transition-base) var(--secure-ui-transition-ease-in-out); } .drop-zone:hover .file-cta { background-color: var(--secure-ui-color-bg-tertiary); border-color: var(--secure-ui-input-border-color-hover); } .drop-zone:active .file-cta { background-color: var(--secure-ui-color-bg-tertiary); } .drop-zone.drag-over .file-cta { background-color: var(--secure-ui-color-primary-light, rgba(102, 126, 234, 0.1)); border-color: var(--secure-ui-color-primary); color: var(--secure-ui-color-primary); } .drop-icon { font-size: var(--secure-ui-font-size-base); margin-right: var(--secure-ui-space-2); display: flex; align-items: center; } .drop-text { font-size: var(--secure-ui-font-size-base); } .file-name-display { display: flex; align-items: center; flex: 1; padding: var(--secure-ui-input-padding-y) var(--secure-ui-input-padding-x); border: var(--secure-ui-input-border-width) solid var(--secure-ui-input-border-color); border-left: none; border-radius: 0 var(--secure-ui-input-border-radius) var(--secure-ui-input-border-radius) 0; background-color: var(--secure-ui-input-bg); color: var(--secure-ui-input-placeholder-color); font-size: var(--secure-ui-input-font-size); max-width: 100%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; } .file-name-display.has-file { color: var(--secure-ui-input-text-color); } .drop-zone-content.has-name .file-cta { border-radius: var(--secure-ui-input-border-radius) 0 0 var(--secure-ui-input-border-radius); border-right: none; } .drop-hint { display: block; text-align: right; margin-top: var(--secure-ui-space-1); font-size: var(--secure-ui-font-size-xs); color: var(--secure-ui-color-text-secondary); } .preview-container { margin-top: var(--secure-ui-space-3); } .file-preview { display: flex; align-items: center; padding: var(--secure-ui-space-3); background-color: var(--secure-ui-color-bg-secondary); border: var(--secure-ui-border-width-thin) solid var(--secure-ui-color-border); border-radius: var(--secure-ui-input-border-radius); margin-bottom: var(--secure-ui-space-2); } .file-name { flex: 1; font-size: var(--secure-ui-font-size-sm); color: var(--secure-ui-color-text-primary); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; } .file-size { font-size: var(--secure-ui-font-size-xs); color: var(--secure-ui-color-text-secondary); margin-left: var(--secure-ui-space-3); white-space: nowrap; } .remove-file { background: none; border: none; color: var(--secure-ui-color-error); font-size: var(--secure-ui-font-size-base); cursor: pointer; padding: var(--secure-ui-space-1) var(--secure-ui-space-2); margin-left: var(--secure-ui-space-2); border-radius: var(--secure-ui-border-radius-sm); transition: background-color var(--secure-ui-transition-base) var(--secure-ui-transition-ease-in-out); pointer-events: auto; } .remove-file:hover { background-color: var(--secure-ui-color-error-light, rgba(239, 68, 68, 0.1)); } .error-container { position: absolute; bottom: -1rem; left: 0; display: var(--error-display); margin-top: var(--secure-ui-form-error-margin-top); padding: var(--secure-ui-space-2) var(--secure-ui-space-3); background-color: var(--secure-ui-color-error-light, rgba(239, 68, 68, 0.1)); border-radius: var(--secure-ui-border-radius-sm); color: var(--secure-ui-color-error); font-size: var(--secure-ui-error-font-size); } .error-container.hidden { max-height: 0; opacity: 0; transform: translateY(-4px); margin-top: 0; } .drop-zone.disabled { opacity: var(--secure-ui-input-disabled-opacity); cursor: not-allowed; } .drop-zone.disabled .file-cta { background-color: var(--secure-ui-input-disabled-bg); } .drop-zone.scanning { pointer-events: none; opacity: 0.7; } .drop-zone.scanning .file-cta { border-color: var(--secure-ui-color-primary); } .drop-zone.scanning .file-name-display { color: var(--secure-ui-color-primary); animation: scanning-pulse 1.2s ease-in-out infinite; } @keyframes scanning-pulse { 0%, 100% { opacity: 0.5; } 50% { opacity: 1; } }"}handleAttributeChange(e,t,i){if(this.#e)switch(e){case"disabled":this.#e.disabled=this.hasAttribute("disabled");break;case"accept":this.#e.accept=i,this.#p(i);break}}get files(){return this.#a}get name(){return this.#e?this.#e.name:""}get valid(){return!((this.hasAttribute("required")||this.config.validation.required)&&(!this.#a||this.#a.length===0))}clear(){this.#M()}setScanHook(e){if(typeof e!="function")throw new TypeError("setScanHook expects a function");this.#h=e,this.audit("scan_hook_registered",{name:this.#e?.name??""})}get hasScanHook(){return this.#h!==null}get scanning(){return this.#d}disconnectedCallback(){super.disconnectedCallback(),this.#a=null,this.#e&&(this.#e.value="")}};customElements.define("secure-file-upload",D);var H=class extends p{#e=null;#s=null;#i=null;#r=null;#t=`secure-datetime-${Math.random().toString(36).substring(2,11)}`;static get observedAttributes(){return[...super.observedAttributes,"name","type","label","required","min","max","step","value","show-timezone"]}constructor(){super()}render(){let e=document.createDocumentFragment(),t=document.createElement("div");t.className="datetime-container",t.setAttribute("part","container");let i=this.getAttribute("label");i&&(this.#s=document.createElement("label"),this.#s.htmlFor=this.#t,this.#s.textContent=this.sanitizeValue(i),this.#s.setAttribute("part","label"),t.appendChild(this.#s));let r=document.createElement("div");return r.className="input-wrapper",r.setAttribute("part","wrapper"),this.#e=document.createElement("input"),this.#e.id=this.#t,this.#e.className="datetime-field",this.#e.setAttribute("part","input"),this.#n(),this.#u(),r.appendChild(this.#e),this.hasAttribute("show-timezone")&&(this.#r=document.createElement("span"),this.#r.className="timezone-display",this.#r.textContent=this.#o(),r.appendChild(this.#r)),t.appendChild(r),this.#i=document.createElement("div"),this.#i.className="error-container hidden",this.#i.setAttribute("role","alert"),this.#i.setAttribute("part","error"),this.#i.id=`${this.#t}-error`,t.appendChild(this.#i),this.addComponentStyles(this.#f()),e.appendChild(t),e}#n(){let e=this.config,t=this.getAttribute("name");t&&(this.#e.name=this.sanitizeValue(t)),!this.getAttribute("label")&&t&&this.#e.setAttribute("aria-label",this.sanitizeValue(t)),this.#e.setAttribute("aria-describedby",`${this.#t}-error`),this.#r&&this.#r.setAttribute("aria-label",`Timezone: ${this.#o()}`);let i=this.getAttribute("type")||"date";["date","time","datetime-local","month","week"].includes(i)?this.#e.type=i:(console.warn(`Invalid datetime type "${i}", defaulting to "date"`),this.#e.type="date"),(this.hasAttribute("required")||e.validation.required)&&(this.#e.required=!0,this.#e.setAttribute("aria-required","true"));let s=this.getAttribute("min");s&&(this.#e.min=this.#a(s));let n=this.getAttribute("max");n&&(this.#e.max=this.#a(n));let a=this.getAttribute("step");a&&(this.#e.step=a),this.hasAttribute("disabled")&&(this.#e.disabled=!0),this.hasAttribute("readonly")&&(this.#e.readOnly=!0),e.storage.allowAutocomplete||(this.#e.autocomplete="off");let o=this.getAttribute("value");o&&(this.#e.value=this.#a(o))}#a(e){if(!e)return"";let t=this.#e?.type||this.getAttribute("type")||"date",i={date:/^\d{4}-\d{2}-\d{2}$/,time:/^\d{2}:\d{2}(:\d{2})?$/,"datetime-local":/^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}(:\d{2})?$/,month:/^\d{4}-\d{2}$/,week:/^\d{4}-W\d{2}$/},r=Object.hasOwn(i,t)?i[t]:void 0;return r&&!r.test(e)?(console.warn(`Invalid ${t} format: ${e}`),""):e}#o(){let e=new Date().getTimezoneOffset(),t=Math.abs(Math.floor(e/60)),i=Math.abs(e%60);return`UTC${e<=0?"+":"-"}${t.toString().padStart(2,"0")}:${i.toString().padStart(2,"0")}`}#u(){this.#e.addEventListener("focus",()=>{this.recordTelemetryFocus(),this.audit("datetime_focused",{name:this.#e.name,type:this.#e.type})}),this.#e.addEventListener("input",e=>{this.recordTelemetryInput(e),this.#c(e)}),this.#e.addEventListener("change",e=>{this.#h(e)}),this.#e.addEventListener("blur",()=>{this.recordTelemetryBlur(),this.#d(),this.audit("datetime_blurred",{name:this.#e.name,hasValue:this.#e.value.length>0})})}#c(e){this.#b(),this.dispatchEvent(new CustomEvent("secure-datetime",{detail:{name:this.#e.name,value:this.#e.value,type:this.#e.type,tier:this.securityTier},bubbles:!0,composed:!0}))}#h(e){let t=this.#e.value;if(!this.#a(t)&&t){this.#p("Invalid date/time format");return}this.#b(),this.audit("datetime_changed",{name:this.#e.name,type:this.#e.type,value:t})}#d(){let e=this.checkRateLimit();if(!e.allowed){this.#p(`Too many attempts. Please wait ${Math.ceil(e.retryAfter/1e3)} seconds.`);return}let t=this.#e.value;if(this.#e.required&&!t){this.#p("This field is required");return}if(t){if(this.#e.min&&t<this.#e.min){this.#p(`Value must be after ${this.#l(this.#e.min)}`);return}if(this.#e.max&&t>this.#e.max){this.#p(`Value must be before ${this.#l(this.#e.max)}`);return}}if(this.securityTier===c.CRITICAL&&t){let i=new Date(t);if(isNaN(i.getTime())){this.#p("Invalid date/time");return}let r=i.getFullYear();if(r<1900||r>2100){this.#p("Date must be between 1900 and 2100");return}}}#l(e){try{return new Date(e).toLocaleString()}catch{return e}}#p(e){this.#i.textContent=e,this.#i.offsetHeight,this.#i.classList.remove("hidden"),this.#e.classList.add("error"),this.#e.setAttribute("aria-invalid","true")}#b(){this.#i.classList.add("hidden"),this.#i.addEventListener("transitionend",()=>{this.#i.classList.contains("hidden")&&(this.#i.textContent="")},{once:!0}),this.#e.classList.remove("error"),this.#e.removeAttribute("aria-invalid")}#f(){return`.datetime-container { margin-bottom: var(--secure-ui-form-gap); font-family: var(--secure-ui-font-family-base); } label { display: block; margin-bottom: var(--secure-ui-form-label-margin-bottom); font-size: var(--secure-ui-label-font-size); font-weight: var(--secure-ui-label-font-weight); color: var(--secure-ui-label-color); } .label-suffix { font-weight: var(--secure-ui-font-weight-normal); color: var(--secure-ui-color-text-secondary); font-size: var(--secure-ui-font-size-xs); margin-left: var(--secure-ui-space-1); } .security-badge { display: inline-block; padding: var(--secure-ui-badge-padding); margin-left: var(--secure-ui-space-2); font-size: var(--secure-ui-badge-font-size); font-weight: var(--secure-ui-font-weight-semibold); border-radius: var(--secure-ui-badge-border-radius); text-transform: uppercase; background-color: var(--secure-ui-color-bg-tertiary); color: var(--secure-ui-color-text-secondary); border: var(--secure-ui-border-width-thin) solid var(--secure-ui-color-border); } .input-wrapper { position: relative; } .datetime-field { width: 100%; height: var(--secure-ui-input-height); padding: var(--secure-ui-input-padding-y) var(--secure-ui-input-padding-x); font-family: var(--secure-ui-font-family-base); font-size: var(--secure-ui-input-font-size); line-height: var(--secure-ui-line-height-normal); color: var(--secure-ui-input-text-color); background-color: var(--secure-ui-input-bg); border: var(--secure-ui-input-border-width) solid var(--secure-ui-input-border-color); border-radius: var(--secure-ui-input-border-radius); transition: all var(--secure-ui-transition-base) var(--secure-ui-transition-ease-in-out); cursor: pointer; box-sizing: border-box; } .datetime-field::placeholder { color: var(--secure-ui-input-placeholder-color); } .datetime-field:hover:not(:disabled):not([readonly]) { border-color: var(--secure-ui-input-border-color-hover); } .datetime-field:focus { outline: none; border-color: var(--secure-ui-input-border-color-focus); box-shadow: var(--secure-ui-shadow-focus); } .datetime-field.error { border-color: var(--secure-ui-color-error); } .datetime-field.error:focus { box-shadow: var(--secure-ui-shadow-focus-error); } .datetime-field:disabled { background-color: var(--secure-ui-input-disabled-bg); cursor: not-allowed; opacity: var(--secure-ui-input-disabled-opacity); } .datetime-field[readonly] { background-color: var(--secure-ui-color-bg-secondary); cursor: default; } .input-wrapper::after { content: '\u{1F4C5}' / ''; position: absolute; right: var(--secure-ui-space-3); top: 50%; transform: translateY(-50%); pointer-events: none; font-size: var(--secure-ui-font-size-lg); color: var(--secure-ui-color-text-secondary); } .input-wrapper[data-type="time"]::after { content: '\u{1F550}' / ''; } .input-wrapper[data-type="datetime-local"]::after { content: '\u{1F4C5}' / ''; } .input-wrapper[data-type="month"]::after { content: '\u{1F4C6}' / ''; } .input-wrapper[data-type="week"]::after { content: '\u{1F4C5}' / ''; } .input-wrapper .timezone-display { position: absolute; right: 0; bottom: -1.25rem; } .range-display { display: none; margin-top: var(--secure-ui-space-2); padding: var(--secure-ui-space-2) var(--secure-ui-space-3); background-color: var(--secure-ui-color-bg-secondary); border-radius: var(--secure-ui-border-radius-sm); font-size: var(--secure-ui-font-size-xs); color: var(--secure-ui-color-text-secondary); } .range-display.visible { display: block; } .range-item { margin-bottom: var(--secure-ui-space-1); } .range-item:last-child { margin-bottom: 0; } .range-label { font-weight: var(--secure-ui-font-weight-medium); margin-right: var(--secure-ui-space-1); } .helper-text { margin-top: var(--secure-ui-space-2); font-size: var(--secure-ui-font-size-xs); color: var(--secure-ui-color-text-secondary); line-height: var(--secure-ui-line-height-normal); } .error-container { position: absolute; margin-top: var(--secure-ui-form-error-margin-top); font-size: var(--secure-ui-error-font-size); color: var(--secure-ui-error-color); line-height: var(--secure-ui-line-height-normal); overflow: hidden; max-height: 40px; opacity: 1; transform: translateY(0); transition: opacity 0.2s ease-out, transform 0.2s ease-out, max-height 0.2s ease-out, margin-top 0.2s ease-out; } .error-container.hidden { max-height: 0; opacity: 0; transform: translateY(-4px); margin-top: 0; } @media (prefers-reduced-motion: reduce) { .datetime-field, .error-container { transition: none !important; } } .datetime-field::-webkit-calendar-picker-indicator { display: inline-block; cursor: pointer; opacity: 1; padding: 4px; margin-left: 4px; } .datetime-field:disabled::-webkit-calendar-picker-indicator { cursor: not-allowed; opacity: 0.3; } .datetime-field::-webkit-inner-spin-button { height: auto; opacity: 0.6; cursor: pointer; } .datetime-field:valid:not(:placeholder-shown):not(:focus) { border-color: var(--secure-ui-color-success); } .datetime-field:invalid:not(:placeholder-shown):not(:focus) { border-color: var(--secure-ui-color-error); } .datetime-container:focus-within label { color: var(--secure-ui-color-primary); } .datetime-container.disabled { opacity: var(--secure-ui-input-disabled-opacity); } .datetime-container.disabled label { color: var(--secure-ui-color-text-disabled); } label .required { color: var(--secure-ui-color-error); margin-left: var(--secure-ui-space-1); }`}handleAttributeChange(e,t,i){if(this.#e)switch(e){case"disabled":this.#e.disabled=this.hasAttribute("disabled");break;case"readonly":this.#e.readOnly=this.hasAttribute("readonly");break;case"value":i!==this.#e.value&&(this.#e.value=this.#a(i||""));break;case"min":this.#e.min=this.#a(i||"");break;case"max":this.#e.max=this.#a(i||"");break}}get value(){return this.#e?this.#e.value:""}set value(e){this.#e&&(this.#e.value=this.#a(e||""))}get name(){return this.#e?this.#e.name:""}getValueAsDate(){if(!this.#e||!this.#e.value)return null;try{let e=new Date(this.#e.value);return isNaN(e.getTime())?null:e}catch{return null}}setValueFromDate(e){if(!this.#e||!(e instanceof Date))return;let t=this.#e.type,i="";switch(t){case"date":i=e.toISOString().split("T")[0];break;case"time":i=e.toTimeString().slice(0,5);break;case"datetime-local":i=e.toISOString().slice(0,16);break;case"month":i=e.toISOString().slice(0,7);break;case"week":let r=new Date(e);r.setHours(0,0,0,0),r.setDate(r.getDate()+4-(r.getDay()||7));let s=new Date(r.getFullYear(),0,1),n=Math.ceil(((r.getTime()-s.getTime())/864e5+1)/7);i=`${r.getFullYear()}-W${n.toString().padStart(2,"0")}`;break}this.#e.value=i}get valid(){let e=this.hasAttribute("required")||this.config.validation.required,t=this.#e?this.#e.value:"";return!(e&&!t||t&&!this.#a(t)||this.#e&&(this.#e.min&&t<this.#e.min||this.#e.max&&t>this.#e.max))}focus(){this.#e&&this.#e.focus()}blur(){this.#e&&this.#e.blur()}disconnectedCallback(){super.disconnectedCallback(),this.#e&&(this.#e.value="")}};customElements.define("secure-datetime",H);var N=class extends p{#e=[];#s=[];#i=[];#r="";#t={column:null,direction:"asc"};#n={currentPage:1,pageSize:10};#a=!1;constructor(){super()}render(){return null}connectedCallback(){this.initializeSecurity();let e=this.querySelector('table[slot="table"]'),t=this.#o();t&&(this.#a=!0,this.#s=t.columns,this.#e=t.data,this.#i=[...t.data],e&&e.remove()),this.#y(),this.audit("table_mounted",{rowCount:this.#e.length,columnCount:this.#s.length,usingSlottedContent:this.#a})}#o(){let e=this.querySelector('table[slot="table"]');if(!e)return null;try{let t=e.querySelectorAll("thead th");if(t.length===0)return null;let i=Array.from(t).map(n=>({key:n.getAttribute("data-key")||n.textContent.trim().toLowerCase().replace(/\s+/g,"_"),label:n.textContent.trim().replace(/\s+$/,""),sortable:n.hasAttribute("data-sortable")?n.getAttribute("data-sortable")!=="false":!0,filterable:n.hasAttribute("data-filterable")?n.getAttribute("data-filterable")!=="false":void 0,tier:n.getAttribute("data-tier")||void 0,width:n.getAttribute("data-width")||void 0,render:n.hasAttribute("data-render-html")?this.#u(n):void 0})),r=e.querySelectorAll("tbody tr"),s=Array.from(r).map((n,a)=>{let o=n.querySelectorAll("td"),u=Object.create(null);return o.forEach((d,h)=>{if(h<i.length){let f=i[h],b=d.getAttribute("data-key")||f.key;if(b==="__proto__"||b==="constructor"||b==="prototype")return;d.innerHTML.trim().includes("<")?(u[b]=d.textContent?.trim()??"",u[`${b}_html`]=d.innerHTML.trim()):u[b]=d.textContent?.trim()??""}}),u});return{columns:i,data:s}}catch(t){return console.error("SecureTable: Error parsing slotted table",t),null}}#u(e){return(t,i,r)=>{let s=`${r}_html`;return(Object.hasOwn(i,s)?i[s]:null)||this.#l(t)}}set data(e){Array.isArray(e)&&(this.#e=e,this.#i=[...e],this.#y())}get data(){return this.#e}set columns(e){Array.isArray(e)&&(this.#s=e,this.#y())}get columns(){return this.#s}#c(e){this.#r=e.toLowerCase(),this.#r?this.#i=this.#e.filter(t=>this.#s.some(i=>i.filterable===!1?!1:String(t[i.key]??"").toLowerCase().includes(this.#r))):this.#i=[...this.#e],this.#n.currentPage=1,this.#m(),this.audit("table_filtered",{filterTerm:e,resultCount:this.#i.length})}#h(e){this.#t.column===e?this.#t.direction=this.#t.direction==="asc"?"desc":"asc":(this.#t.column=e,this.#t.direction="asc"),this.#i.sort((t,i)=>{let r=Object.hasOwn(t,e)?t[e]:void 0,s=Object.hasOwn(i,e)?i[e]:void 0,n=0;return r>s&&(n=1),r<s&&(n=-1),this.#t.direction==="asc"?n:-n}),this.#m(),this.audit("table_sorted",{column:e,direction:this.#t.direction})}#d(e){let t=Math.ceil(this.#i.length/this.#n.pageSize);e<1||e>t||(this.#n.currentPage=e,this.#m())}#l(e){return e==null||e===""?"":String(e).replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;").replace(/'/g,"&#x27;")}#p(e,t){if(e==null||e==="")return"-";let i=String(e);return t===c.SENSITIVE&&i.length>4?"\u2022".repeat(i.length-4)+i.slice(-4):t===c.CRITICAL?"\u2022".repeat(i.length):this.#l(i)}#b(e,t,i){if(typeof i.render=="function")return i.render(e,t,i.key);let r=`${i.key}_html`;return Object.hasOwn(t,r)&&t[r]?t[r]:this.#p(e,i.tier)}#f(){let e=Math.ceil(this.#i.length/this.#n.pageSize),t=(this.#n.currentPage-1)*this.#n.pageSize,i=t+this.#n.pageSize,r=this.#i.slice(t,i),s,n;if(r.length===0||this.#s.length===0){let a=this.#s.length===0?"No columns configured":"No results found",o=this.#s.length===0?"Set the columns property to configure the table":"Try adjusting your search term";s=`
1
+ var u=Object.freeze({PUBLIC:"public",AUTHENTICATED:"authenticated",SENSITIVE:"sensitive",CRITICAL:"critical"}),w=Object.freeze({[u.PUBLIC]:Object.freeze({name:"Public",level:1,validation:Object.freeze({required:!1,strict:!1,maxLength:5e3,pattern:null,sanitizeHtml:!0}),masking:Object.freeze({enabled:!1,character:"\u2022",partial:!1}),storage:Object.freeze({allowAutocomplete:!0,allowCache:!0,allowHistory:!0}),audit:Object.freeze({logAccess:!1,logChanges:!1,logSubmission:!1,includeMetadata:!1}),rateLimit:Object.freeze({enabled:!1,maxAttempts:0,windowMs:0})}),[u.AUTHENTICATED]:Object.freeze({name:"Authenticated",level:2,validation:Object.freeze({required:!0,strict:!1,maxLength:1e3,pattern:null,sanitizeHtml:!0}),masking:Object.freeze({enabled:!1,character:"\u2022",partial:!1}),storage:Object.freeze({allowAutocomplete:!0,allowCache:!1,allowHistory:!1}),audit:Object.freeze({logAccess:!1,logChanges:!0,logSubmission:!0,includeMetadata:!0}),rateLimit:Object.freeze({enabled:!1,maxAttempts:0,windowMs:0})}),[u.SENSITIVE]:Object.freeze({name:"Sensitive",level:3,validation:Object.freeze({required:!0,strict:!0,maxLength:500,pattern:null,sanitizeHtml:!0}),masking:Object.freeze({enabled:!0,character:"\u2022",partial:!0}),storage:Object.freeze({allowAutocomplete:!1,allowCache:!1,allowHistory:!1}),audit:Object.freeze({logAccess:!0,logChanges:!0,logSubmission:!0,includeMetadata:!0}),rateLimit:Object.freeze({enabled:!0,maxAttempts:10,windowMs:6e4})}),[u.CRITICAL]:Object.freeze({name:"Critical",level:4,validation:Object.freeze({required:!0,strict:!0,maxLength:256,pattern:null,sanitizeHtml:!0}),masking:Object.freeze({enabled:!0,character:"\u2022",partial:!1}),storage:Object.freeze({allowAutocomplete:!1,allowCache:!1,allowHistory:!1}),audit:Object.freeze({logAccess:!0,logChanges:!0,logSubmission:!0,includeMetadata:!0}),rateLimit:Object.freeze({enabled:!0,maxAttempts:5,windowMs:6e4})})});function v(l){return!l||!w[l]?(console.warn(`Invalid security tier "${l}", defaulting to CRITICAL`),w[u.CRITICAL]):w[l]}function A(l){return Object.values(u).includes(l)}function B(l,e){let t=v(l),i=v(e);return Math.sign(t.level-i.level)}function G(l,e){return B(l,e)>=0?l:e}var Q=Object.freeze({[u.PUBLIC]:Object.freeze({"default-src":["'self'"],"script-src":["'self'"],"style-src":["'self'"]}),[u.AUTHENTICATED]:Object.freeze({"default-src":["'self'"],"script-src":["'self'"],"style-src":["'self'"],"form-action":["'self'"]}),[u.SENSITIVE]:Object.freeze({"default-src":["'self'"],"script-src":["'self'"],"style-src":["'self'"],"form-action":["'self'"],"frame-ancestors":["'none'"],"upgrade-insecure-requests":[]}),[u.CRITICAL]:Object.freeze({"default-src":["'self'"],"script-src":["'self'"],"style-src":["'self'"],"form-action":["'self'"],"frame-ancestors":["'none'"],"upgrade-insecure-requests":[],"block-all-mixed-content":[],"base-uri":["'none'"]})}),ee=Object.freeze({"X-Content-Type-Options":"nosniff","X-Frame-Options":"DENY","X-XSS-Protection":"1; mode=block","Referrer-Policy":"strict-origin-when-cross-origin","Permissions-Policy":"geolocation=(), microphone=(), camera=()"});var p=class l extends HTMLElement{static#e=1e3;static#t={"script-tag":"Script injection blocked","js-protocol":"JavaScript protocol blocked","event-handler":"Event handler injection blocked","html-injection":"HTML element injection blocked","css-expression":"CSS expression injection blocked",vbscript:"VBScript injection blocked","data-uri-html":"Data URI injection blocked","template-syntax":"Template injection blocked"};static#i=[{id:"script-tag",pattern:/<script[\s>/]/i},{id:"js-protocol",pattern:/javascript\s*:/i},{id:"event-handler",pattern:/\bon\w+\s*=/i},{id:"html-injection",pattern:/<\s*(img|svg|iframe|object|embed|link|meta|base)[^>]*/i},{id:"css-expression",pattern:/expression\s*\(/i},{id:"vbscript",pattern:/vbscript\s*:/i},{id:"data-uri-html",pattern:/data:\s*text\/html/i},{id:"template-syntax",pattern:/\{\{[\s\S]*?\}\}/}];#s=u.CRITICAL;#r;#n;#a=[];#o={attempts:0,windowStart:Date.now()};#c=!1;#l={focusAt:null,firstKeystrokeAt:null,blurAt:null,keyCount:0,correctionCount:0,pasteDetected:!1,autofillDetected:!1,focusCount:0,blurWithoutChange:0,lastInputLength:0};constructor(){super(),this.#n=this.attachShadow({mode:"closed"}),this.#r=v(this.#s)}static get observedAttributes(){return["security-tier","disabled","readonly","threat-feedback"]}connectedCallback(){this.#c||(this.#p(),this.#c=!0)}#p(){this.initializeSecurity(),this.#d()}initializeSecurity(){let e=this.getAttribute("security-tier");e&&A(e)&&(this.#s=e),this.#r=v(this.#s),this.#u("component_initialized",{tier:this.#s,timestamp:new Date().toISOString()})}attributeChangedCallback(e,t,i){if(e==="security-tier"&&this.#c){console.warn(`Security tier cannot be changed after initialization. Attempted change from "${t}" to "${i}" blocked.`),t!==null&&this.setAttribute("security-tier",t);return}this.#c&&this.handleAttributeChange(e,t,i)}handleAttributeChange(e,t,i){}#d(){this.#n.innerHTML="",this.addComponentStyles(":host { display: block; box-sizing: border-box; font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif; font-size: 14px; line-height: 1.5; } :host([hidden]) { display: none; } * { box-sizing: border-box; } .hidden { display: none; } .security-badge { display: inline-block; padding: var(--secure-ui-badge-padding, 2px 6px); margin-left: var(--secure-ui-space-2, 0.5rem); font-size: var(--secure-ui-badge-font-size, 0.6875rem); font-weight: var(--secure-ui-font-weight-semibold, 600); border-radius: var(--secure-ui-badge-border-radius, 0.25rem); text-transform: uppercase; background-color: var(--secure-ui-color-bg-tertiary); color: var(--secure-ui-color-text-secondary); border: var(--secure-ui-border-width-thin, 1px) solid var(--secure-ui-color-border); }");let e=this.render();e&&this.#n.appendChild(e)}getBaseStylesheetUrl(){return":host { display: block; box-sizing: border-box; font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif; font-size: 14px; line-height: 1.5; } :host([hidden]) { display: none; } * { box-sizing: border-box; } .hidden { display: none; } .security-badge { display: inline-block; padding: var(--secure-ui-badge-padding, 2px 6px); margin-left: var(--secure-ui-space-2, 0.5rem); font-size: var(--secure-ui-badge-font-size, 0.6875rem); font-weight: var(--secure-ui-font-weight-semibold, 600); border-radius: var(--secure-ui-badge-border-radius, 0.25rem); text-transform: uppercase; background-color: var(--secure-ui-color-bg-tertiary); color: var(--secure-ui-color-text-secondary); border: var(--secure-ui-border-width-thin, 1px) solid var(--secure-ui-color-border); }"}addComponentStyles(e){if(e.includes("{")){let t=new CSSStyleSheet;t.replaceSync(e),this.#n.adoptedStyleSheets=[...this.#n.adoptedStyleSheets,t]}else{let t=document.createElement("link");t.rel="stylesheet",t.href=e,this.#n.appendChild(t)}}sanitizeValue(e){if(typeof e!="string")return"";let t=document.createElement("div");return t.textContent=e,t.innerHTML}validateInput(e,t={}){let i=[],r=this.#r;(t.required!==void 0?t.required:r.validation.required)&&(!e||e.trim().length===0)&&i.push("This field is required");let n=t.maxLength||r.validation.maxLength;e&&e.length>n&&i.push(`Value exceeds maximum length of ${n}`);let a=t.minLength||0;e&&e.length<a&&i.push(`Value must be at least ${a} characters`);let o=t.pattern||r.validation.pattern;return o&&e&&!o.test(e)&&i.push("Value does not match required format"),r.validation.strict&&i.length>0&&this.#u("validation_failed",{errors:i,valueLength:e?e.length:0}),{valid:i.length===0,errors:i}}checkRateLimit(){if(!this.#r.rateLimit.enabled)return{allowed:!0,retryAfter:0};let e=Date.now(),t=this.#r.rateLimit.windowMs;if(e-this.#o.windowStart>t&&(this.#o.attempts=0,this.#o.windowStart=e),this.#o.attempts>=this.#r.rateLimit.maxAttempts){let i=t-(e-this.#o.windowStart);return this.#u("rate_limit_exceeded",{attempts:this.#o.attempts,retryAfter:i}),{allowed:!1,retryAfter:i}}return this.#o.attempts++,{allowed:!0,retryAfter:0}}#u(e,t={}){let i=this.#r.audit;if(!(e.includes("access")&&i.logAccess||e.includes("change")&&i.logChanges||e.includes("submit")&&i.logSubmission||e.includes("initialized")||e.includes("rate_limit")||e.includes("validation")||e.includes("threat")))return;let s={event:e,tier:this.#s,timestamp:new Date().toISOString(),data:Object.keys(t).length>0?t:void 0};i.includeMetadata&&(s.userAgent=navigator.userAgent,s.language=navigator.language),this.#a.length>=l.#e&&this.#a.shift(),this.#a.push(s),this.dispatchEvent(new CustomEvent("secure-audit",{detail:s,bubbles:!0,composed:!0}))}get shadowRoot(){return this.#n}get securityTier(){return this.#s}get config(){return this.#r}getAuditLog(){return[...this.#a]}clearAuditLog(){this.#a=[]}audit(e,t){this.#u(e,t)}detectInjection(e,t,i=!1){let r=i||this.hasAttribute("threat-feedback");for(let{id:s,pattern:n}of l.#i)if(n.test(e)){this.audit("threat_detected",{fieldName:t,patternId:s,threatType:"injection"}),this.dispatchEvent(new CustomEvent("secure-threat-detected",{detail:{fieldName:t,threatType:"injection",patternId:s,tier:this.securityTier,timestamp:Date.now()},bubbles:!0,composed:!0})),r&&this.showThreatFeedback(s);return}r&&this.clearThreatFeedback()}showThreatFeedback(e){}clearThreatFeedback(){}getThreatLabel(e){return l.#t[e]??`Injection blocked: ${e}`}rerender(){this.#d()}recordTelemetryFocus(){let e=this.#l;e.focusAt=Date.now(),e.blurAt=null,e.focusCount++;let t=this.shadowRoot.querySelector('input:not([type="hidden"]), textarea, select');e.lastInputLength=t?t.value.length:0}recordTelemetryInput(e){let t=this.#l,i=Date.now();t.firstKeystrokeAt===null&&(t.firstKeystrokeAt=i);let s=e.inputType??"";s==="insertFromPaste"||s==="insertFromPasteAsQuotation"?t.pasteDetected=!0:s==="insertReplacementText"?t.autofillDetected=!0:s.startsWith("delete")||s==="historyUndo"||s==="historyRedo"?t.correctionCount++:t.keyCount++;let n=e.target;n&&(t.lastInputLength=n.value.length)}recordTelemetryBlur(){let e=this.#l;e.blurAt=Date.now();let t=this.shadowRoot.querySelector('input:not([type="hidden"]), textarea, select');(t?t.value.length:0)===e.lastInputLength&&e.keyCount===0&&!e.pasteDetected&&e.blurWithoutChange++}getFieldTelemetry(){let e=this.#l,t=e.focusAt??Date.now(),i=e.firstKeystrokeAt,r=e.blurAt??Date.now(),s=i!==null?i-t:0,n=i!==null?r-i:0,a=n/1e3,o=a>0?e.keyCount/a:0;return{dwell:s,completionTime:n,velocity:Math.round(o*100)/100,corrections:e.correctionCount,pasteDetected:e.pasteDetected,autofillDetected:e.autofillDetected,focusCount:e.focusCount,blurWithoutChange:e.blurWithoutChange}}#h(){this.#l={focusAt:null,firstKeystrokeAt:null,blurAt:null,keyCount:0,correctionCount:0,pasteDetected:!1,autofillDetected:!1,focusCount:0,blurWithoutChange:0,lastInputLength:0}}disconnectedCallback(){this.#o={attempts:0,windowStart:Date.now()},this.#h(),this.#r.audit.logAccess&&this.#u("component_disconnected",{timestamp:new Date().toISOString()})}};var I=class l extends p{static#e=new Set(["text","url","search"]);#t=null;#i=null;#s=null;#r=null;#n="";#a=!1;#o=null;#c=null;#l=`secure-input-${Math.random().toString(36).substring(2,11)}`;static get observedAttributes(){return[...super.observedAttributes,"name","type","label","placeholder","required","pattern","minlength","maxlength","autocomplete","value"]}render(){let e=document.createDocumentFragment(),t=document.createElement("div");t.className="input-container",t.setAttribute("part","container");let i=this.getAttribute("label");i&&(this.#i=document.createElement("label"),this.#i.htmlFor=this.#l,this.#i.textContent=this.sanitizeValue(i),this.#i.setAttribute("part","label"),t.appendChild(this.#i));let r=document.createElement("div");return r.className="input-wrapper",r.setAttribute("part","wrapper"),this.#t=document.createElement("input"),this.#t.id=this.#l,this.#t.className="input-field",this.#t.setAttribute("part","input"),this.#h(),this.#y(),r.appendChild(this.#t),t.appendChild(r),this.#s=document.createElement("div"),this.#s.className="error-container hidden",this.#s.setAttribute("role","alert"),this.#s.setAttribute("part","error"),this.#s.id=`${this.#l}-error`,t.appendChild(this.#s),this.#r=document.createElement("div"),this.#r.className="threat-container hidden",this.#r.setAttribute("role","alert"),this.#r.setAttribute("part","threat"),this.#r.id=`${this.#l}-threat`,t.appendChild(this.#r),this.#p(),this.#u(),this.addComponentStyles(this.#A()),e.appendChild(t),e}#p(){let e=this.getAttribute("name");e&&(this.closest("secure-form")||(this.#o=document.createElement("input"),this.#o.type="hidden",this.#o.name=e,this.#o.value=this.#n||"",this.appendChild(this.#o)))}#d(){this.#o&&(this.#o.value=this.#n||"")}#u(){this.querySelectorAll("input, textarea, select").forEach(t=>{if(t===this.#o)return;let i=t;i.removeAttribute("required"),i.removeAttribute("name"),i.removeAttribute("minlength"),i.removeAttribute("maxlength"),i.removeAttribute("pattern"),i.setAttribute("tabindex","-1"),i.setAttribute("aria-hidden","true")})}#h(){let e=this.config,t=this.getAttribute("name");t&&(this.#t.name=this.sanitizeValue(t)),!this.getAttribute("label")&&t&&this.#t.setAttribute("aria-label",this.sanitizeValue(t)),this.#t.setAttribute("aria-describedby",`${this.#l}-error`);let i=this.getAttribute("type")||"text";this.#t.type=i;let r=this.getAttribute("placeholder");r&&(this.#t.placeholder=this.sanitizeValue(r)),(this.hasAttribute("required")||e.validation.required)&&(this.#t.required=!0,this.#t.setAttribute("aria-required","true"));let s=this.getAttribute("pattern");s&&(this.#t.pattern=s);let n=this.getAttribute("minlength");n&&(this.#t.minLength=parseInt(n,10));let a=this.getAttribute("maxlength")||e.validation.maxLength;if(a&&(this.#t.maxLength=parseInt(String(a),10)),e.storage.allowAutocomplete){let c=this.getAttribute("autocomplete")||"on";this.#t.autocomplete=c}else this.#t.autocomplete="off",this.#t.type==="password"&&(this.#t.autocomplete="new-password");this.hasAttribute("disabled")&&(this.#t.disabled=!0),this.hasAttribute("readonly")&&(this.#t.readOnly=!0);let o=this.getAttribute("value");o&&this.#m(o);let d=new Set(["email","url","tel"]);e.masking.enabled&&this.#t.type!=="password"&&!d.has(this.#t.type)&&(this.#a=!0)}#y(){this.#t.addEventListener("focus",()=>{this.recordTelemetryFocus(),this.audit("input_focused",{name:this.#t.name})}),this.#t.addEventListener("input",e=>{this.recordTelemetryInput(e),this.#w(e)}),this.#t.addEventListener("blur",()=>{this.recordTelemetryBlur(),this.#E(),this.audit("input_blurred",{name:this.#t.name,hasValue:this.#n.length>0})}),this.#t.addEventListener("paste",e=>{this.#a&&(this.#c=e.clipboardData?.getData("text/plain")??null)}),this.#t.addEventListener("change",()=>{this.audit("input_changed",{name:this.#t.name,valueLength:this.#n.length})})}#w(e){if(this.#a&&this.#t.type!=="password"){let i=e,r=i.inputType,s=i.data||"",n=this.#t.selectionStart||0;if(r==="deleteContentBackward")n<this.#n.length&&(this.#n=this.#n.substring(0,n)+this.#n.substring(n+1));else if(r==="deleteContentForward")this.#n=this.#n.substring(0,n)+this.#n.substring(n+1);else if(r==="insertText")this.#n=this.#n.substring(0,n-s.length)+s+this.#n.substring(n-s.length);else if(r==="insertFromPaste"){let o=this.#c??s;this.#c=null,o&&(this.#n=this.#n.substring(0,n-o.length)+o+this.#n.substring(n-o.length))}else this.#n="",this.#t.value="";let a=this.#x(this.#n);this.#t.value=a,this.#t.setSelectionRange(n,n)}else this.#n=this.#t.value;let t=this.#t.type;t!=="number"&&this.detectInjection(this.#n,this.#t.name,l.#e.has(t)),this.#b(),this.#d(),this.dispatchEvent(new CustomEvent("secure-input-change",{detail:{name:this.#t.name,value:this.#n,masked:this.#a,tier:this.securityTier},bubbles:!0,composed:!0}))}#x(e){let t=this.config,i=t.masking.character;if(!t.masking.partial||this.securityTier===u.CRITICAL||e.length<=4)return i.repeat(e.length);let r=i.repeat(e.length-4),s=e.slice(-4);return r+s}#g(e){if(!this.#t||this.#t.type!=="password"||!e||e.length===0)return null;let t=this.securityTier;if(t==="critical"){if(e.length<8)return"Password must be at least 8 characters";if(!/[a-z]/.test(e))return"Password must include a lowercase letter";if(!/[A-Z]/.test(e))return"Password must include an uppercase letter";if(!/[0-9]/.test(e))return"Password must include a number";if(!/[^a-zA-Z0-9]/.test(e))return"Password must include a special character"}else if(t==="sensitive"){if(e.length<8)return"Password must be at least 8 characters";if(!/[a-z]/.test(e))return"Password must include a lowercase letter";if(!/[A-Z]/.test(e))return"Password must include an uppercase letter";if(!/[0-9]/.test(e))return"Password must include a number"}else if(t==="authenticated"&&e.length<6)return"Password must be at least 6 characters";return null}#v(e){if(!this.#t||this.#t.type!=="number"||!e||e.length===0)return null;let t=Number(e);if(!Number.isFinite(t))return"Value must be a valid number";if(!e.includes(".")&&!Number.isSafeInteger(t))return"Value exceeds safe integer range";let i=this.getAttribute("min"),r=this.getAttribute("max");if(i!==null){let s=Number(i);if(Number.isFinite(s)&&t<s)return`Value must be at least ${s}`}if(r!==null){let s=Number(r);if(Number.isFinite(s)&&t>s)return`Value must be at most ${s}`}return null}#E(){let e=this.checkRateLimit();if(!e.allowed){this.#f(`Too many attempts. Please wait ${Math.ceil(e.retryAfter/1e3)} seconds.`);return}let t=this.getAttribute("pattern"),i=this.getAttribute("minlength"),r=this.getAttribute("maxlength"),s=null;if(t)try{s=new RegExp(t)}catch{}let n=this.validateInput(this.#n,{required:this.hasAttribute("required")||this.config.validation.required,pattern:s,minLength:i?parseInt(i,10):0,maxLength:r?parseInt(r,10):this.config.validation.maxLength});if(!n.valid){this.#f(n.errors.join(", "));return}let a=this.#g(this.#n);if(a){this.#f(a);return}let o=this.#v(this.#n);if(o){this.#f(o);return}if(this.#t&&this.#n){let d,c;if(this.#a){let m=this.#t.value;this.#t.value=this.#n,d=this.#t.checkValidity(),c=this.#t.validationMessage,this.#t.value=m}else d=this.#t.checkValidity(),c=this.#t.validationMessage;if(!d){this.#f(c);return}}}#f(e){this.#s.textContent=e,this.#s.offsetHeight,this.#s.classList.remove("hidden"),this.#t.classList.add("error"),this.#t.setAttribute("aria-invalid","true")}#b(){this.#s.classList.add("hidden"),this.#s.addEventListener("transitionend",()=>{this.#s.classList.contains("hidden")&&(this.#s.textContent="")},{once:!0}),this.#t.classList.remove("error"),this.#t.removeAttribute("aria-invalid")}#m(e){this.#n=e,this.#a&&this.#t.type!=="password"?this.#t.value=this.#x(e):this.#t.value=e,this.#d()}#A(){return".input-container { margin-bottom: var(--secure-ui-form-gap); font-family: var(--secure-ui-font-family-base); } label { display: flex; align-items: flex-end; margin-bottom: var(--secure-ui-form-label-margin-bottom); font-size: var(--secure-ui-label-font-size); font-weight: var(--secure-ui-label-font-weight); color: var(--secure-ui-label-color); } .label-suffix { font-weight: var(--secure-ui-font-weight-normal); color: var(--secure-ui-color-text-secondary); font-size: var(--secure-ui-font-size-xs); margin-left: var(--secure-ui-space-1); } .security-badge { display: inline-block; padding: var(--secure-ui-badge-padding); margin-left: var(--secure-ui-space-2); font-size: var(--secure-ui-badge-font-size); font-weight: var(--secure-ui-font-weight-semibold); border-radius: var(--secure-ui-badge-border-radius); text-transform: uppercase; background-color: var(--secure-ui-color-bg-tertiary); color: var(--secure-ui-color-text-secondary); border: var(--secure-ui-border-width-thin) solid var(--secure-ui-color-border); } .input-wrapper { position: relative; } .input-field { width: 100%; height: var(--secure-ui-input-height); padding: var(--secure-ui-input-padding-y) var(--secure-ui-input-padding-x); font-family: var(--secure-ui-font-family-base); font-size: var(--secure-ui-input-font-size); line-height: var(--secure-ui-line-height-normal); color: var(--secure-ui-input-text-color); background-color: var(--secure-ui-input-bg); border: var(--secure-ui-input-border-width) solid var(--secure-ui-input-border-color); border-radius: var(--secure-ui-input-border-radius); transition: all var(--secure-ui-transition-base) var(--secure-ui-transition-ease-in-out); box-sizing: border-box; } .input-field::placeholder { color: var(--secure-ui-input-placeholder-color); } .input-field:hover:not(:disabled) { border-color: var(--secure-ui-input-border-color-hover); } .input-field:focus { outline: none; border-color: var(--secure-ui-input-border-color-focus); box-shadow: var(--secure-ui-shadow-focus); } .input-field.error { border-color: var(--secure-ui-color-error) !important; } .input-field.error:focus { box-shadow: var(--secure-ui-shadow-focus-error); } .input-field:disabled { background-color: var(--secure-ui-input-disabled-bg); cursor: not-allowed; opacity: var(--secure-ui-input-disabled-opacity); } .input-field:read-only:not(:disabled) { background-color: var(--secure-ui-color-bg-secondary); cursor: default; } .error-container { position: absolute; margin-top: var(--secure-ui-form-error-margin-top); font-size: var(--secure-ui-error-font-size); color: var(--secure-ui-error-color); line-height: var(--secure-ui-line-height-normal); overflow: hidden; max-height: 40px; opacity: 1; transform: translateY(0); transition: all 0.5s ease-in-out; } .error-container.hidden { max-height: 0; opacity: 0; transform: translateY(-4px); margin-top: 0; transition: all 0.2s ease-in-out; } @media (prefers-reduced-motion: reduce) { .input-field, .error-container, .threat-container { transition: none !important; } } .threat-container { margin-top: var(--secure-ui-form-error-margin-top); font-size: var(--secure-ui-error-font-size); color: var(--secure-ui-color-warning); line-height: var(--secure-ui-line-height-normal); overflow: hidden; max-height: 40px; opacity: 1; transform: translateY(0); transition: all 0.5s ease-in-out; display: flex; align-items: center; gap: var(--secure-ui-space-1, 4px); flex-wrap: wrap; } .threat-container.hidden { max-height: 0; opacity: 0; transform: translateY(-4px); margin-top: 0; transition: all 0.2s ease-in-out; } .threat-message { flex: 1; min-width: 0; } .threat-badge { display: inline-block; padding: var(--secure-ui-badge-padding); font-size: var(--secure-ui-badge-font-size); font-weight: var(--secure-ui-font-weight-semibold); border-radius: var(--secure-ui-badge-border-radius); background-color: color-mix(in srgb, var(--secure-ui-color-warning) 12%, transparent); color: var(--secure-ui-color-warning); border: var(--secure-ui-border-width-thin) solid currentColor; font-family: var(--secure-ui-font-family-mono, monospace); white-space: nowrap; } .input-field.threat { border-color: var(--secure-ui-color-warning) !important; } .input-field.threat:focus { box-shadow: 0 0 0 3px color-mix(in srgb, var(--secure-ui-color-warning) 25%, transparent); } .input-field:-webkit-autofill { -webkit-box-shadow: 0 0 0 1000px var(--secure-ui-input-bg) inset; -webkit-text-fill-color: var(--secure-ui-input-text-color); }"}handleAttributeChange(e,t,i){if(this.#t)switch(e){case"disabled":this.#t.disabled=this.hasAttribute("disabled");break;case"readonly":this.#t.readOnly=this.hasAttribute("readonly");break;case"value":i!==this.#n&&this.#m(i||"");break}}get value(){return this.#n}set value(e){this.#m(e||"")}get name(){return this.#t?this.#t.name:""}get valid(){let e=this.getAttribute("pattern"),t=this.getAttribute("minlength"),i=this.getAttribute("maxlength"),r=null;if(e)try{r=new RegExp(e)}catch{}if(!this.validateInput(this.#n,{required:this.hasAttribute("required")||this.config.validation.required,pattern:r,minLength:t?parseInt(t,10):0,maxLength:i?parseInt(i,10):this.config.validation.maxLength}).valid||this.#g(this.#n)!==null||this.#v(this.#n)!==null)return!1;if(this.#t&&this.#n){let n;if(this.#a){let a=this.#t.value;this.#t.value=this.#n,n=this.#t.checkValidity(),this.#t.value=a}else n=this.#t.checkValidity();if(!n)return!1}return!0}focus(){this.#t&&this.#t.focus()}blur(){this.#t&&this.#t.blur()}showThreatFeedback(e){if(!this.#r||!this.#t)return;this.#r.textContent="";let t=document.createElement("span");t.className="threat-message",t.textContent=this.getThreatLabel(e);let i=document.createElement("span");i.className="threat-badge",i.textContent=e,this.#r.appendChild(t),this.#r.appendChild(i),this.#r.offsetHeight,this.#r.classList.remove("hidden"),this.#t.classList.add("threat"),this.#t.setAttribute("aria-invalid","true")}clearThreatFeedback(){!this.#r||!this.#t||(this.#r.classList.add("hidden"),this.#r.addEventListener("transitionend",()=>{this.#r.classList.contains("hidden")&&(this.#r.textContent="")},{once:!0}),this.#t.classList.remove("threat"),this.#t.removeAttribute("aria-invalid"))}disconnectedCallback(){super.disconnectedCallback(),this.#n="",this.#c=null,this.#t&&(this.#t.value="")}};customElements.define("secure-input",I);var M=class extends p{#e=null;#t=null;#i=null;#s=null;#r=null;#n=`secure-textarea-${Math.random().toString(36).substring(2,11)}`;static get observedAttributes(){return[...super.observedAttributes,"name","label","placeholder","required","minlength","maxlength","rows","cols","wrap","value"]}render(){let e=document.createDocumentFragment(),t=document.createElement("div");t.className="textarea-container",t.setAttribute("part","container");let i=this.getAttribute("label");i&&(this.#t=document.createElement("label"),this.#t.htmlFor=this.#n,this.#t.textContent=this.sanitizeValue(i),this.#t.setAttribute("part","label"),t.appendChild(this.#t));let r=document.createElement("div");return r.className="textarea-wrapper",r.setAttribute("part","wrapper"),this.#e=document.createElement("textarea"),this.#e.id=this.#n,this.#e.className="textarea-field",this.#e.setAttribute("part","textarea"),this.#a(),this.#o(),r.appendChild(this.#e),t.appendChild(r),this.#r=document.createElement("span"),this.#r.className="char-count",this.#l(),t.appendChild(this.#r),this.#i=document.createElement("div"),this.#i.className="error-container hidden",this.#i.setAttribute("role","alert"),this.#i.setAttribute("part","error"),this.#i.id=`${this.#n}-error`,t.appendChild(this.#i),this.#s=document.createElement("div"),this.#s.className="threat-container hidden",this.#s.setAttribute("role","alert"),this.#s.setAttribute("part","threat"),this.#s.id=`${this.#n}-threat`,t.appendChild(this.#s),this.addComponentStyles(this.#h()),e.appendChild(t),e}#a(){let e=this.config,t=this.getAttribute("name");t&&(this.#e.name=this.sanitizeValue(t)),!this.getAttribute("label")&&t&&this.#e.setAttribute("aria-label",this.sanitizeValue(t)),this.#e.setAttribute("aria-describedby",`${this.#n}-error`);let i=this.getAttribute("placeholder");i&&(this.#e.placeholder=this.sanitizeValue(i)),(this.hasAttribute("required")||e.validation.required)&&(this.#e.required=!0,this.#e.setAttribute("aria-required","true"));let r=this.getAttribute("minlength");r&&(this.#e.minLength=parseInt(r,10));let s=this.getAttribute("maxlength")||e.validation.maxLength;s&&(this.#e.maxLength=parseInt(String(s),10));let n=this.getAttribute("rows")||3;this.#e.rows=parseInt(String(n),10);let a=this.getAttribute("cols");a&&(this.#e.cols=parseInt(a,10));let o=this.getAttribute("wrap")||"soft";if(this.#e.wrap=o,e.storage.allowAutocomplete){let c=this.getAttribute("autocomplete")||"on";this.#e.autocomplete=c}else this.#e.autocomplete="off";this.hasAttribute("disabled")&&(this.#e.disabled=!0),this.hasAttribute("readonly")&&(this.#e.readOnly=!0);let d=this.getAttribute("value");d&&(this.#e.value=d)}#o(){this.#e.addEventListener("focus",()=>{this.recordTelemetryFocus(),this.audit("textarea_focused",{name:this.#e.name})}),this.#e.addEventListener("input",e=>{this.recordTelemetryInput(e),this.#c(e)}),this.#e.addEventListener("blur",()=>{this.recordTelemetryBlur(),this.#p(),this.audit("textarea_blurred",{name:this.#e.name,hasValue:this.#e.value.length>0})}),this.#e.addEventListener("change",()=>{this.audit("textarea_changed",{name:this.#e.name,valueLength:this.#e.value.length})})}#c(e){this.detectInjection(this.#e.value,this.#e.name),this.#l(),this.#u(),this.dispatchEvent(new CustomEvent("secure-textarea-change",{detail:{name:this.#e.name,value:this.#e.value,tier:this.securityTier},bubbles:!0,composed:!0}))}#l(){let e=this.#e.value.length,t=this.#e.maxLength;t>0?(this.#r.textContent=`${e} / ${t}`,e>t*.9?this.#r.classList.add("warning"):this.#r.classList.remove("warning")):this.#r.textContent=`${e}`}#p(){let e=this.checkRateLimit();if(!e.allowed){this.#d(`Too many attempts. Please wait ${Math.ceil(e.retryAfter/1e3)} seconds.`);return}let t=this.getAttribute("minlength"),i=this.getAttribute("maxlength"),r=this.validateInput(this.#e.value,{required:this.hasAttribute("required")||this.config.validation.required,minLength:t?parseInt(t,10):0,maxLength:i?parseInt(i,10):this.config.validation.maxLength});r.valid||this.#d(r.errors.join(", "))}#d(e){this.#i.textContent=e,this.#i.offsetHeight,this.#i.classList.remove("hidden"),this.#e.classList.add("error"),this.#e.setAttribute("aria-invalid","true")}#u(){this.#i.classList.add("hidden"),this.#i.addEventListener("transitionend",()=>{this.#i.classList.contains("hidden")&&(this.#i.textContent="")},{once:!0}),this.#e.classList.remove("error"),this.#e.removeAttribute("aria-invalid")}#h(){return'.textarea-container { margin-bottom: var(--secure-ui-form-gap); font-family: var(--secure-ui-font-family-base); } label { display: block; margin-bottom: var(--secure-ui-form-label-margin-bottom); font-size: var(--secure-ui-label-font-size); font-weight: var(--secure-ui-label-font-weight); color: var(--secure-ui-label-color); } .label-suffix { font-weight: var(--secure-ui-font-weight-normal); color: var(--secure-ui-color-text-secondary); font-size: var(--secure-ui-font-size-xs); margin-left: var(--secure-ui-space-1); } .security-badge { display: inline-block; padding: var(--secure-ui-badge-padding); margin-left: var(--secure-ui-space-2); font-size: var(--secure-ui-badge-font-size); font-weight: var(--secure-ui-font-weight-semibold); border-radius: var(--secure-ui-badge-border-radius); text-transform: uppercase; background-color: var(--secure-ui-color-bg-tertiary); color: var(--secure-ui-color-text-secondary); border: var(--secure-ui-border-width-thin) solid var(--secure-ui-color-border); } .textarea-wrapper { position: relative; } .textarea-field { width: 100%; min-height: var(--secure-ui-textarea-min-height); padding: var(--secure-ui-textarea-padding); font-family: var(--secure-ui-font-family-base); font-size: var(--secure-ui-input-font-size); line-height: var(--secure-ui-line-height-normal); color: var(--secure-ui-input-text-color); background-color: var(--secure-ui-input-bg); border: var(--secure-ui-input-border-width) solid var(--secure-ui-input-border-color); border-radius: var(--secure-ui-input-border-radius); transition: all var(--secure-ui-transition-base) var(--secure-ui-transition-ease-in-out); resize: vertical; box-sizing: border-box; } .textarea-field::placeholder { color: var(--secure-ui-input-placeholder-color); } .textarea-field:hover:not(:disabled) { border-color: var(--secure-ui-input-border-color-hover); } .textarea-field:focus { outline: none; border-color: var(--secure-ui-input-border-color-focus); box-shadow: var(--secure-ui-shadow-focus); } .textarea-field.error { border-color: var(--secure-ui-color-error); } .textarea-field.error:focus { box-shadow: var(--secure-ui-shadow-focus-error); } .textarea-field:read-only:not(:disabled) { background-color: var(--secure-ui-color-bg-secondary); cursor: default; resize: none; } .textarea-field:disabled { background-color: var(--secure-ui-input-disabled-bg); cursor: not-allowed; opacity: var(--secure-ui-input-disabled-opacity); } .char-count { display: block; margin-top: var(--secure-ui-space-1); font-size: var(--secure-ui-font-size-xs); color: var(--secure-ui-color-text-secondary); text-align: right; } .char-count.warning { color: var(--secure-ui-color-warning); font-weight: var(--secure-ui-font-weight-medium); } .error-container { margin-top: var(--secure-ui-form-error-margin-top); font-size: var(--secure-ui-error-font-size); color: var(--secure-ui-error-color); line-height: var(--secure-ui-line-height-normal); overflow: hidden; max-height: 40px; opacity: 1; transform: translateY(0); transition: opacity 0.2s ease-out, transform 0.2s ease-out, max-height 0.2s ease-out, margin-top 0.2s ease-out; } .error-container.hidden { max-height: 0; opacity: 0; transform: translateY(-4px); margin-top: 0; } @media (prefers-reduced-motion: reduce) { .textarea-field, .error-container, .threat-container { transition: none !important; } } .threat-container { margin-top: var(--secure-ui-form-error-margin-top); font-size: var(--secure-ui-error-font-size); color: var(--secure-ui-color-warning); line-height: var(--secure-ui-line-height-normal); overflow: hidden; max-height: 40px; opacity: 1; transform: translateY(0); transition: opacity 0.2s ease-out, transform 0.2s ease-out, max-height 0.2s ease-out, margin-top 0.2s ease-out; display: flex; align-items: center; gap: var(--secure-ui-space-1, 4px); flex-wrap: wrap; } .threat-container.hidden { max-height: 0; opacity: 0; transform: translateY(-4px); margin-top: 0; } .threat-message { flex: 1; min-width: 0; } .threat-badge { display: inline-block; padding: var(--secure-ui-badge-padding); font-size: var(--secure-ui-badge-font-size); font-weight: var(--secure-ui-font-weight-semibold); border-radius: var(--secure-ui-badge-border-radius); background-color: color-mix(in srgb, var(--secure-ui-color-warning) 12%, transparent); color: var(--secure-ui-color-warning); border: var(--secure-ui-border-width-thin) solid currentColor; font-family: var(--secure-ui-font-family-mono, monospace); white-space: nowrap; } .textarea-field.threat { border-color: var(--secure-ui-color-warning) !important; } .textarea-field.threat:focus { box-shadow: 0 0 0 3px color-mix(in srgb, var(--secure-ui-color-warning) 25%, transparent); } :host([security-tier="authenticated"]) .textarea-field { border-color: var(--secure-ui-tier-authenticated); } :host([security-tier="sensitive"]) .textarea-field { border-color: var(--secure-ui-tier-sensitive); } :host([security-tier="critical"]) .textarea-field { border-color: var(--secure-ui-tier-critical); }'}handleAttributeChange(e,t,i){if(this.#e)switch(e){case"disabled":this.#e.disabled=this.hasAttribute("disabled");break;case"readonly":this.#e.readOnly=this.hasAttribute("readonly");break;case"value":i!==this.#e.value&&(this.#e.value=i||"",this.#l());break}}get value(){return this.#e?this.#e.value:""}set value(e){this.#e&&(this.#e.value=e||"",this.#l())}get name(){return this.#e?this.#e.name:""}get valid(){let e=this.getAttribute("minlength"),t=this.getAttribute("maxlength");return this.validateInput(this.#e.value,{required:this.hasAttribute("required")||this.config.validation.required,minLength:e?parseInt(e,10):0,maxLength:t?parseInt(t,10):this.config.validation.maxLength}).valid}focus(){this.#e&&this.#e.focus()}blur(){this.#e&&this.#e.blur()}showThreatFeedback(e){if(!this.#s||!this.#e)return;this.#s.textContent="";let t=document.createElement("span");t.className="threat-message",t.textContent=this.getThreatLabel(e);let i=document.createElement("span");i.className="threat-badge",i.textContent=e,this.#s.appendChild(t),this.#s.appendChild(i),this.#s.offsetHeight,this.#s.classList.remove("hidden"),this.#e.classList.add("threat"),this.#e.setAttribute("aria-invalid","true")}clearThreatFeedback(){!this.#s||!this.#e||(this.#s.classList.add("hidden"),this.#s.addEventListener("transitionend",()=>{this.#s.classList.contains("hidden")&&(this.#s.textContent="")},{once:!0}),this.#e.classList.remove("threat"),this.#e.removeAttribute("aria-invalid"))}disconnectedCallback(){super.disconnectedCallback(),this.#e&&(this.#e.value="")}};customElements.define("secure-textarea",M);var D=class extends p{#e=null;#t=null;#i=null;#s=`secure-select-${Math.random().toString(36).substring(2,11)}`;#r=new Set;#n=!1;#a=!1;static get observedAttributes(){return[...super.observedAttributes,"name","label","required","multiple","size","value"]}render(){let e=document.createDocumentFragment(),t=document.createElement("div");t.className="select-container",t.setAttribute("part","container"),this.#a=this.hasAttribute("multiple");let i=this.getAttribute("label");i&&(this.#t=document.createElement("label"),this.#t.htmlFor=this.#s,this.#t.textContent=this.sanitizeValue(i),this.#t.setAttribute("part","label"),t.appendChild(this.#t));let r=document.createElement("div");return r.className="select-wrapper",r.setAttribute("part","wrapper"),this.#e=document.createElement("select"),this.#e.id=this.#s,this.#e.className="select-field",this.#e.setAttribute("part","select"),this.#o(),this.#l(),queueMicrotask(()=>{this.#c()}),r.appendChild(this.#e),t.appendChild(r),this.#i=document.createElement("div"),this.#i.className="error-container hidden",this.#i.setAttribute("role","alert"),this.#i.setAttribute("part","error"),this.#i.id=`${this.#s}-error`,t.appendChild(this.#i),this.addComponentStyles(this.#y()),e.appendChild(t),e}#o(){let e=this.config,t=this.getAttribute("name");t&&(this.#e.name=this.sanitizeValue(t)),!this.getAttribute("label")&&t&&this.#e.setAttribute("aria-label",this.sanitizeValue(t)),this.#e.setAttribute("aria-describedby",`${this.#s}-error`),(this.hasAttribute("required")||e.validation.required)&&(this.#e.required=!0,this.#e.setAttribute("aria-required","true")),this.hasAttribute("multiple")&&(this.#e.multiple=!0);let i=this.getAttribute("size");i&&(this.#e.size=parseInt(i,10)),this.hasAttribute("disabled")&&(this.#e.disabled=!0),e.storage.allowAutocomplete||(this.#e.autocomplete="off")}#c(){if(this.#n)return;this.#n=!0;let e=Array.from(this.querySelectorAll("option"));if(e.length===0)return;let t=[];if(e.forEach(i=>{let r=document.createElement("option"),s=i.getAttribute("value")||"";r.value=this.sanitizeValue(s),this.#r.add(r.value),r.textContent=this.sanitizeValue(i.textContent||""),i.hasAttribute("selected")&&(r.selected=!0,t.push(r.value)),i.hasAttribute("disabled")&&(r.disabled=!0),this.#e.appendChild(r)}),!this.#a){let i=this.getAttribute("value");i?this.#e.value=i:t.length>0&&(this.#e.value=t[0])}}#l(){this.#e.addEventListener("focus",()=>{this.recordTelemetryFocus(),this.audit("select_focused",{name:this.#e.name})}),this.#e.addEventListener("change",e=>{this.recordTelemetryInput(e),this.#p(e)}),this.#e.addEventListener("blur",()=>{this.recordTelemetryBlur(),this.#d(),this.audit("select_blurred",{name:this.#e.name,hasValue:this.#a?this.#e.selectedOptions.length>0:this.#e.value.length>0})})}#p(e){if(this.#a){let t=Array.from(this.#e.selectedOptions).map(r=>r.value),i=t.filter(r=>r&&!this.#r.has(r));if(i.length>0){this.#u("Invalid option selected"),this.audit("invalid_option_detected",{name:this.#e.name,attemptedValues:i});return}this.#h(),this.audit("select_changed",{name:this.#e.name,values:t}),this.dispatchEvent(new CustomEvent("secure-select-change",{detail:{name:this.#e.name,value:t,tier:this.securityTier},bubbles:!0,composed:!0}))}else{let t=this.#e.value;if(t&&!this.#r.has(t)){this.#u("Invalid option selected"),this.audit("invalid_option_detected",{name:this.#e.name,attemptedValue:t}),this.#e.value="";return}this.#h(),this.audit("select_changed",{name:this.#e.name,value:t}),this.dispatchEvent(new CustomEvent("secure-select-change",{detail:{name:this.#e.name,value:t,tier:this.securityTier},bubbles:!0,composed:!0}))}}#d(){let e=this.checkRateLimit();if(!e.allowed){this.#u(`Too many attempts. Please wait ${Math.ceil(e.retryAfter/1e3)} seconds.`);return}let t=this.hasAttribute("required")||this.config.validation.required;if(this.#a){let i=Array.from(this.#e.selectedOptions).map(s=>s.value).filter(s=>s!=="");if(t&&i.length===0){this.#u("Please select at least one option");return}if(i.filter(s=>!this.#r.has(s)).length>0){this.#u("Invalid option selected");return}}else{if(t&&!this.#e.value){this.#u("Please select an option");return}let i=this.#e.value;if(i&&!this.#r.has(i)){this.#u("Invalid option selected");return}}}#u(e){this.#i.textContent=e,this.#i.offsetHeight,this.#i.classList.remove("hidden"),this.#e.classList.add("error"),this.#e.setAttribute("aria-invalid","true")}#h(){this.#i.classList.add("hidden"),this.#i.addEventListener("transitionend",()=>{this.#i.classList.contains("hidden")&&(this.#i.textContent="")},{once:!0}),this.#e.classList.remove("error"),this.#e.removeAttribute("aria-invalid")}#y(){return'.select-container { margin-bottom: var(--secure-ui-form-gap); font-family: var(--secure-ui-font-family-base); } label { display: block; margin-bottom: var(--secure-ui-form-label-margin-bottom); font-size: var(--secure-ui-label-font-size); font-weight: var(--secure-ui-label-font-weight); color: var(--secure-ui-label-color); } .label-suffix { font-weight: var(--secure-ui-font-weight-normal); color: var(--secure-ui-color-text-secondary); font-size: var(--secure-ui-font-size-xs); margin-left: var(--secure-ui-space-1); } .security-badge { display: inline-block; padding: var(--secure-ui-badge-padding); margin-left: var(--secure-ui-space-2); font-size: var(--secure-ui-badge-font-size); font-weight: var(--secure-ui-font-weight-semibold); border-radius: var(--secure-ui-badge-border-radius); text-transform: uppercase; background-color: var(--secure-ui-color-bg-tertiary); color: var(--secure-ui-color-text-secondary); border: var(--secure-ui-border-width-thin) solid var(--secure-ui-color-border); } .select-wrapper { position: relative; } .select-field { width: 100%; height: var(--secure-ui-select-height); padding: var(--secure-ui-select-padding); font-family: var(--secure-ui-font-family-base); font-size: var(--secure-ui-input-font-size); line-height: var(--secure-ui-line-height-normal); color: var(--secure-ui-select-color); background-color: var(--secure-ui-select-background-color); border: var(--secure-ui-input-border-width) solid var(--secure-ui-input-border-color); border-radius: var(--secure-ui-input-border-radius); transition: all var(--secure-ui-transition-base) var(--secure-ui-transition-ease-in-out); cursor: pointer; box-sizing: border-box; } .select-field, ::picker(select) { appearance: base-select; border-radius: .25rem; } .select-field::picker-icon { color: #999999; transition: 0.2s rotate; } .select-field:open::picker-icon { rotate: 180deg; } .select-field option { display: flex; justify-content: flex-start; color: var(--secure-ui-select-color); background-color: var(--secure-ui-select-background-color); padding: .5rem; } .select-field option:hover { box-shadow: 0px 0px 4px 0px var(--secure-ui-input-border-color) inset; transition: all 0.2s ease-in-out; } .select-field option:first-of-type { border-top-left-radius: none; border-top-right-radius: none; } .select-field option:last-of-type { border-bottom-left-radius: none; border-bottom-right-radius: none; } .select-field option:nth-of-type(odd) { } .select-field option:checked { font-weight: bold; } .select-field option::checkmark { order: 1; margin-left: auto; content: "\u2713"; } .select-field option + option { border-top: 1px solid var(--secure-ui-input-border-color); } .select-field:hover:not(:disabled) { border-color: var(--secure-ui-input-border-color-hover); } .select-field:focus { outline: none; border-color: var(--secure-ui-input-border-color-focus); box-shadow: var(--secure-ui-shadow-focus); } .select-field.error { border-color: var(--secure-ui-color-error); } .select-field.error:focus { box-shadow: var(--secure-ui-shadow-focus-error); } .select-field:disabled { background-color: var(--secure-ui-input-disabled-bg); cursor: not-allowed; opacity: var(--secure-ui-input-disabled-opacity); } .select-field[multiple] { height: auto; min-height: calc(var(--secure-ui-select-height) * 2); padding: var(--secure-ui-space-2); } .error-container { position: absolute; margin-top: var(--secure-ui-form-error-margin-top); font-size: var(--secure-ui-error-font-size); color: var(--secure-ui-error-color); line-height: var(--secure-ui-line-height-normal); overflow: hidden; max-height: 40px; opacity: 1; transform: translateY(0); transition: opacity 0.2s ease-out, transform 0.2s ease-out, max-height 0.2s ease-out, margin-top 0.2s ease-out; } .error-container.hidden { max-height: 0; opacity: 0; transform: translateY(-4px); margin-top: 0; } @media (prefers-reduced-motion: reduce) { .select-field, .error-container { transition: none !important; } }'}handleAttributeChange(e,t,i){if(this.#e)switch(e){case"disabled":this.#e.disabled=this.hasAttribute("disabled");break;case"value":i!==this.#e.value&&(this.#e.value=i||"");break}}get value(){return this.#e?this.#a?Array.from(this.#e.selectedOptions).map(e=>e.value).filter(e=>e!==""):this.#e.value:this.#a?[]:""}set value(e){if(this.#e)if(this.#a){let t=Array.isArray(e)?e:e.split(",").map(i=>i.trim()).filter(i=>i!=="");Array.from(this.#e.options).forEach(i=>{i.selected=!1}),t.forEach(i=>{if(this.#r.has(i)){let r=Array.from(this.#e.options).find(s=>s.value===i);r&&(r.selected=!0)}})}else{let t=Array.isArray(e)?e[0]??"":e;this.#r.has(t)&&(this.#e.value=t)}}get name(){return this.#e?this.#e.name:""}get selectedOptions(){return this.#e?Array.from(this.#e.selectedOptions).map(e=>e.value):[]}get valid(){let e=this.hasAttribute("required")||this.config.validation.required;if(this.#a){let i=Array.from(this.#e.selectedOptions).map(r=>r.value).filter(r=>r!=="");return e&&i.length===0?!1:i.every(r=>this.#r.has(r))}if(e&&!this.#e.value)return!1;let t=this.#e.value;return!(t&&!this.#r.has(t))}focus(){this.#e&&this.#e.focus()}blur(){this.#e&&this.#e.blur()}addOption(e,t,i=!1){if(!this.#e)return;let r=document.createElement("option");r.value=this.sanitizeValue(e),r.textContent=this.sanitizeValue(t),r.selected=i,this.#r.add(r.value),this.#e.appendChild(r)}removeOption(e){if(!this.#e)return;let i=Array.from(this.#e.options).find(r=>r.value===e);i&&(this.#e.removeChild(i),this.#r.delete(e))}clearOptions(){this.#e&&(this.#e.innerHTML="",this.#r.clear())}disconnectedCallback(){super.disconnectedCallback()}};customElements.define("secure-select",D);var N=class l extends HTMLElement{static#e=!1;#t=null;#i=null;#s=null;#r=!1;#n=Date.now();#a={attempts:0,windowStart:Date.now()};#o=`secure-form-${Math.random().toString(36).substring(2,11)}`;#c=u.PUBLIC;static get observedAttributes(){return["security-tier","action","method","enctype","csrf-token","csrf-header-name","csrf-field-name","novalidate"]}constructor(){super()}connectedCallback(){if(this.#t)return;this.#n=Date.now();let e=this.getAttribute("security-tier");e&&A(e)&&(this.#c=e);let t=this.querySelector("form");if(t){this.#t=t,this.#t.id=this.#o,this.#t.classList.contains("secure-form")||this.#t.classList.add("secure-form"),this.#p();let i=this.getAttribute("csrf-field-name")||"csrf_token",r=t.querySelector(`input[name="${CSS.escape(i)}"]`);if(r){this.#i=r;let s=this.getAttribute("csrf-token");s&&r.value!==s&&(r.value=s)}else this.#d()}else{for(this.#t=document.createElement("form"),this.#t.id=this.#o,this.#t.className="secure-form",this.#p(),this.#d();this.firstChild;)this.#t.appendChild(this.firstChild);this.appendChild(this.#t)}this.#s=document.createElement("div"),this.#s.className="form-status form-status-hidden",this.#s.setAttribute("role","status"),this.#s.setAttribute("aria-live","polite"),this.#t.insertBefore(this.#s,this.#t.firstChild),this.#l(),this.#u(),this.audit("form_initialized",{formId:this.#o,action:this.#t.action,method:this.#t.method})}#l(){if(!l.#e){let e='secure-form { display: block; } secure-form .secure-form { padding: 16px; border: 2px solid #e0e0e0; border-radius: 8px; background-color: transparent; } secure-form[security-tier="critical"] .secure-form { padding: 20px; } secure-form[security-tier="public"] .secure-form { border: none; } secure-form .form-status { padding: 12px; margin-bottom: 16px; border-radius: 4px; font-size: 14px; } secure-form .form-status-hidden { display: none; } secure-form .form-status-info { display: block; background-color: #E3F2FD; color: #1976D2; border: 1px solid #1976D2; } secure-form .form-status-success { display: block; background-color: #E8F5E9; color: #388E3C; border: 1px solid #388E3C; } secure-form .form-status-error { display: block; background-color: #FFEBEE; color: #D32F2F; border: 1px solid #D32F2F; }';if(e.includes("{")){let t=new CSSStyleSheet;t.replaceSync(e),document.adoptedStyleSheets=[...document.adoptedStyleSheets,t]}else{let t=document.createElement("link");t.rel="stylesheet",t.href=e,document.head.appendChild(t)}l.#e=!0}}#p(){let e=this.getAttribute("action");e&&(this.#t.action=e);let t=this.getAttribute("method")||"POST";this.#t.method=t.toUpperCase();let i=this.getAttribute("enctype")||"application/x-www-form-urlencoded";this.#t.enctype=i,this.hasAttribute("novalidate")&&(this.#t.noValidate=!0),(this.#c===u.SENSITIVE||this.#c===u.CRITICAL)&&(this.#t.autocomplete="off")}#d(){let e=this.getAttribute("csrf-token");if(e){this.#i=document.createElement("input"),this.#i.type="hidden";let t=this.getAttribute("csrf-field-name")||"csrf_token";this.#i.name=t,this.#i.value=e,this.#t.appendChild(this.#i),this.audit("csrf_token_injected",{formId:this.#o,fieldName:t})}else(this.securityTier===u.SENSITIVE||this.securityTier===u.CRITICAL)&&console.warn("CSRF token not provided for SENSITIVE/CRITICAL tier form")}#u(){this.#t.addEventListener("submit",e=>{this.#y(e)}),this.addEventListener("secure-input-change",e=>{this.#h(e)}),this.addEventListener("secure-textarea-change",e=>{this.#h(e)}),this.addEventListener("secure-select-change",e=>{this.#h(e)}),this.addEventListener("secure-threat-detected",e=>{let t=e.detail;t&&this.#v.push(t)})}#h(e){this.#T()}async#y(e){let t=this.hasAttribute("use-fetch");if(this.#r){e.preventDefault();return}(this.#c===u.SENSITIVE||this.#c===u.CRITICAL)&&!this.#i?.value&&this.dispatchEvent(new CustomEvent("secure-threat-detected",{detail:{fieldName:this.#o,threatType:"csrf-token-absent",patternId:"csrf-token-absent",tier:this.#c,timestamp:Date.now()},bubbles:!0,composed:!0}));let i=this.checkRateLimit();if(!i.allowed){e.preventDefault(),this.#A(`Too many submission attempts. Please wait ${Math.ceil(i.retryAfter/1e3)} seconds.`,"error"),this.audit("form_rate_limited",{formId:this.#o,retryAfter:i.retryAfter});return}let r=this.#x();if(!r.valid){e.preventDefault(),this.#A(r.errors.join(", "),"error"),this.audit("form_validation_failed",{formId:this.#o,errors:r.errors});return}if(!t){this.#w(),this.audit("form_submitted_native",{formId:this.#o,action:this.#t.action,method:this.#t.method});return}e.preventDefault(),this.#r=!0,this.#A("Submitting...","info"),this.#b();let s=this.#g(),n=this.#S();this.audit("form_submitted_enhanced",{formId:this.#o,action:this.#t.action,method:this.#t.method,fieldCount:Object.keys(s).length,riskScore:n.riskScore,riskSignals:n.riskSignals});let a=new CustomEvent("secure-form-submit",{detail:{formData:s,telemetry:n,cancelSubmission:()=>{this.#r=!1,this.#m()}},bubbles:!0,composed:!0,cancelable:!0});if(!this.dispatchEvent(a)){this.#r=!1,this.#m();return}try{await this.#f(s,n)}catch(d){this.#A("Submission failed. Please try again.","error"),this.audit("form_submission_error",{formId:this.#o,error:d.message})}finally{this.#r=!1,this.#m()}}#w(){this.#t.querySelectorAll("secure-input, secure-textarea, secure-select, secure-datetime, secure-file-upload").forEach(t=>{let i=t.getAttribute("name");if(!i)return;t.querySelectorAll(`input[name="${i}"], textarea[name="${i}"], select[name="${i}"]`).forEach(n=>{n.removeAttribute("name")});let s=this.#t.querySelector(`input[type="hidden"][data-secure-input="${i}"]`);s||(s=document.createElement("input"),s.type="hidden",s.setAttribute("data-secure-input",i),s.name=i,this.#t.appendChild(s)),s.value=t.value||""})}#x(){let e=[];return this.#t.querySelectorAll("secure-input, secure-textarea, secure-select, secure-datetime, secure-file-upload").forEach(i=>{if(typeof i.valid=="boolean"&&!i.valid){let r=i.getAttribute("label")||i.getAttribute("name")||"Field";e.push(`${r} is invalid`)}}),{valid:e.length===0,errors:e}}#g(){let e=Object.create(null);return this.#t.querySelectorAll("secure-input, secure-textarea, secure-select, secure-datetime, secure-file-upload").forEach(r=>{let s=r;s.name&&(e[s.name]=s.value)}),this.#t.querySelectorAll('input:not([type="hidden"]), textarea, select').forEach(r=>{let s=r;s.name&&(e[s.name]=this.sanitizeValue(s.value))}),this.#i&&(e[this.#i.name]=this.#i.value),e}#v=[];#E=null;async#f(e,t){this.#E?.abort(),this.#E=new AbortController;let i=this.#t.action,r=this.#t.method,s={"Content-Type":"application/json"},n=this.getAttribute("csrf-header-name");n&&this.#i&&(s[n]=this.#i.value);let a={...e,_telemetry:t},o=await fetch(i,{method:r,headers:s,body:JSON.stringify(a),credentials:"same-origin",mode:"cors",cache:"no-cache",redirect:"follow",signal:this.#E.signal});if(!o.ok)throw new Error(`HTTP ${o.status}: ${o.statusText}`);return this.#A("Form submitted successfully!","success"),this.dispatchEvent(new CustomEvent("secure-form-success",{detail:{formData:e,response:o,telemetry:t},bubbles:!0,composed:!0})),o}#b(){this.#t.querySelectorAll("input, textarea, select, button").forEach(i=>{i.disabled=!0}),this.querySelectorAll("secure-input, secure-textarea, secure-select, secure-datetime, secure-file-upload").forEach(i=>{i.setAttribute("disabled","")})}#m(){this.#t.querySelectorAll("input, textarea, select, button").forEach(i=>{i.disabled=!1}),this.querySelectorAll("secure-input, secure-textarea, secure-select, secure-datetime, secure-file-upload").forEach(i=>{i.removeAttribute("disabled")})}#A(e,t="info"){this.#s.textContent=e,this.#s.className=`form-status form-status-${t}`}#T(){this.#s.textContent="",this.#s.className="form-status form-status-hidden"}#S(){let t=this.querySelectorAll("secure-input, secure-textarea, secure-select, secure-datetime, secure-card"),i=[];t.forEach(a=>{let o=a;if(typeof o.getFieldTelemetry!="function")return;let d=a.getAttribute("name")??a.tagName.toLowerCase(),c={...o.getFieldTelemetry(),fieldName:d,fieldType:a.tagName.toLowerCase()};i.push(c)});let r=Date.now()-this.#n,{riskScore:s,riskSignals:n}=this.#k(i,r,this.#v);return{sessionDuration:r,fieldCount:i.length,fields:i,riskScore:s,riskSignals:n,submittedAt:new Date().toISOString(),detectedThreats:this.#v.length>0?[...this.#v]:void 0}}#k(e,t,i=[]){let r=[],s=0,n=i.filter(h=>h.threatType==="injection"),a=i.some(h=>h.threatType==="csrf-token-absent");if(n.length>0&&(s+=40,r.push("injection_detected")),a&&(s+=20,r.push("csrf_token_absent")),t<3e3?(s+=30,r.push("session_too_fast")):t<8e3&&(s+=10,r.push("session_fast")),e.length===0)return{riskScore:Math.min(s,100),riskSignals:r};e.every(h=>h.pasteDetected&&h.velocity===0)&&(s+=25,r.push("all_fields_pasted")),e.some(h=>h.velocity>15)&&(s+=15,r.push("high_velocity_typing")),e.some(h=>h.focusCount===0)&&(s+=15,r.push("field_filled_without_focus")),e.some(h=>h.focusCount>1&&h.blurWithoutChange>1)&&(s+=10,r.push("form_probing")),e.some(h=>h.corrections>5)&&(s+=5,r.push("high_correction_count"));let b=e.filter(h=>h.autofillDetected);return b.length>0&&b.length===e.length&&(s-=10,r.push("autofill_detected")),{riskScore:Math.max(0,Math.min(s,100)),riskSignals:r}}getData(){return this.#g()}reset(){this.#t&&(this.#t.reset(),this.#T(),this.#v=[],this.audit("form_reset",{formId:this.#o}))}submit(){this.#t&&this.#t.dispatchEvent(new Event("submit",{bubbles:!0,cancelable:!0}))}get valid(){return this.#x().valid}disconnectedCallback(){this.#E?.abort(),this.#t&&this.#t.reset()}attributeChangedCallback(e,t,i){if(this.#t)switch(e){case"security-tier":console.warn(`SecureForm: security-tier cannot be changed after initialization. Attempted change from "${t}" to "${i}" blocked.`);return;case"action":this.#t.action=i;break;case"method":this.#t.method=i;break;case"csrf-token":this.#i&&(this.#i.value=i);break}}get securityTier(){return this.#c}sanitizeValue(e){if(typeof e!="string")return"";let t=document.createElement("div");return t.textContent=e,t.innerHTML}audit(e,t){console.debug&&console.debug(`[secure-form] ${e}`,t)}checkRateLimit(){let e=w[this.#c];if(!e.rateLimit.enabled)return{allowed:!0,retryAfter:0};let{maxAttempts:t,windowMs:i}=e.rateLimit,r=Date.now();return r-this.#a.windowStart>i&&(this.#a.attempts=0,this.#a.windowStart=r),this.#a.attempts>=t?{allowed:!1,retryAfter:i-(r-this.#a.windowStart)}:(this.#a.attempts++,{allowed:!0,retryAfter:0})}};customElements.define("secure-form",N);var H=class extends p{#e=null;#t=null;#i=null;#s=null;#r=null;#n=null;#a=null;#o=`secure-file-upload-${Math.random().toString(36).substring(2,11)}`;#c=new Set;#l=5*1024*1024;#p=null;#d=!1;static get observedAttributes(){return[...super.observedAttributes,"name","label","accept","max-size","multiple","required","capture"]}constructor(){super()}render(){let e=document.createDocumentFragment(),t=document.createElement("div");t.className="file-upload-container",t.setAttribute("part","container");let i=this.getAttribute("label");i&&(this.#t=document.createElement("label"),this.#t.htmlFor=this.#o,this.#t.textContent=this.sanitizeValue(i),this.#t.setAttribute("part","label"),t.appendChild(this.#t)),this.#r=document.createElement("div"),this.#r.className="drop-zone",this.#r.setAttribute("part","wrapper"),this.#e=document.createElement("input"),this.#e.type="file",this.#e.id=this.#o,this.#e.className="file-input",this.#e.setAttribute("part","input"),this.#u(),this.#v();let r=document.createElement("div");r.className="drop-zone-content has-name";let s=document.createElement("span");s.className="file-cta";let n=document.createElement("span");n.className="drop-icon";let a=document.createElementNS("http://www.w3.org/2000/svg","svg");a.setAttribute("width","16"),a.setAttribute("height","16"),a.setAttribute("viewBox","0 0 24 24"),a.setAttribute("fill","none"),a.setAttribute("stroke","currentColor"),a.setAttribute("stroke-width","2"),a.setAttribute("stroke-linecap","round"),a.setAttribute("stroke-linejoin","round"),a.setAttribute("aria-hidden","true"),a.setAttribute("focusable","false");let o=document.createElementNS("http://www.w3.org/2000/svg","path");o.setAttribute("d","M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4");let d=document.createElementNS("http://www.w3.org/2000/svg","polyline");d.setAttribute("points","17 8 12 3 7 8");let c=document.createElementNS("http://www.w3.org/2000/svg","line");c.setAttribute("x1","12"),c.setAttribute("y1","3"),c.setAttribute("x2","12"),c.setAttribute("y2","15"),a.appendChild(o),a.appendChild(d),a.appendChild(c),n.appendChild(a),s.appendChild(n);let m=document.createElement("span");m.className="drop-text",m.textContent="Choose a file\u2026",s.appendChild(m),r.appendChild(s),this.#n=document.createElement("span"),this.#n.className="file-name-display",this.#n.textContent="No file selected",r.appendChild(this.#n),this.#r.appendChild(this.#e),this.#r.appendChild(r),t.appendChild(this.#r);let g=document.createElement("div");return g.className="drop-hint",g.textContent=this.#g(),t.appendChild(g),this.#s=document.createElement("div"),this.#s.className="preview-container",t.appendChild(this.#s),this.#i=document.createElement("div"),this.#i.className="error-container hidden",this.#i.setAttribute("role","alert"),this.#i.setAttribute("part","error"),this.#i.id=`${this.#o}-error`,t.appendChild(this.#i),this.#e.setAttribute("aria-describedby",`${this.#o}-error`),this.addComponentStyles(this.#P()),e.appendChild(t),e}#u(){let e=this.config,t=this.getAttribute("name");t&&(this.#e.name=this.sanitizeValue(t));let i=this.getAttribute("accept");if(i)this.#e.accept=i,this.#h(i);else{let n=this.#w();this.#e.accept=n,this.#h(n)}let r=this.getAttribute("max-size");r?this.#l=parseInt(r,10):this.#l=this.#x(),this.hasAttribute("multiple")&&(this.#e.multiple=!0),(this.hasAttribute("required")||e.validation.required)&&(this.#e.required=!0);let s=this.getAttribute("capture");s&&(this.#e.capture=s),this.hasAttribute("disabled")&&(this.#e.disabled=!0)}#h(e){this.#c.clear(),e.split(",").map(i=>i.trim()).forEach(i=>{if(i.startsWith(".")){let r=this.#y(i);r&&this.#c.add(r)}else this.#c.add(i)})}#y(e){return{".pdf":"application/pdf",".doc":"application/msword",".docx":"application/vnd.openxmlformats-officedocument.wordprocessingml.document",".xls":"application/vnd.ms-excel",".xlsx":"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",".ppt":"application/vnd.ms-powerpoint",".pptx":"application/vnd.openxmlformats-officedocument.presentationml.presentation",".txt":"text/plain",".csv":"text/csv",".jpg":"image/jpeg",".jpeg":"image/jpeg",".png":"image/png",".gif":"image/gif",".svg":"image/svg+xml",".zip":"application/zip",".json":"application/json"}[e.toLowerCase()]||null}#w(){switch(this.securityTier){case u.CRITICAL:return".pdf,.txt";case u.SENSITIVE:return".pdf,.doc,.docx,.txt,.jpg,.jpeg,.png";case u.AUTHENTICATED:return".pdf,.doc,.docx,.xls,.xlsx,.txt,.csv,.jpg,.jpeg,.png,.gif";case u.PUBLIC:default:return".pdf,.doc,.docx,.xls,.xlsx,.txt,.csv,.jpg,.jpeg,.png,.gif,.zip"}}#x(){switch(this.securityTier){case u.CRITICAL:return 2*1024*1024;case u.SENSITIVE:return 5*1024*1024;case u.AUTHENTICATED:return 10*1024*1024;case u.PUBLIC:default:return 20*1024*1024}}#g(){let e=(this.#l/1048576).toFixed(1);return`Accepted: ${this.#e.accept||"all files"} (max ${e}MB)`}#v(){this.#e.addEventListener("change",e=>{this.#E(e)}),this.#r.addEventListener("dragover",e=>{e.preventDefault(),e.stopPropagation(),this.#r.classList.add("drag-over")}),this.#r.addEventListener("dragleave",e=>{e.preventDefault(),e.stopPropagation(),this.#r.classList.remove("drag-over")}),this.#r.addEventListener("drop",e=>{e.preventDefault(),e.stopPropagation(),this.#r.classList.remove("drag-over");let t=e;if(!t.dataTransfer)return;let i=t.dataTransfer.files;i.length>0&&(this.#e.files=i,this.#E({target:this.#e}))})}async#E(e){let t=e.target.files;if(!t||t.length===0)return;let i=this.checkRateLimit();if(!i.allowed){this.#D(`Too many upload attempts. Please wait ${Math.ceil(i.retryAfter/1e3)} seconds.`),this.#e.value="";return}this.#N();let r=await this.#f(t);if(!r.valid){this.#D(r.errors.join(", ")),this.#e.value="",this.#a=null;return}this.#a=t,this.#I(t),this.#$(t),this.audit("files_selected",{name:this.#e.name,fileCount:t.length,totalSize:Array.from(t).reduce((s,n)=>s+n.size,0)}),this.dispatchEvent(new CustomEvent("secure-file-change",{detail:{name:this.#e.name,files:Array.from(t),tier:this.securityTier},bubbles:!0,composed:!0}))}async#f(e){let t=[];!this.#e.multiple&&e.length>1&&t.push("Only one file is allowed");for(let i=0;i<e.length;i++){let r=e[i];if(r.size>this.#l){let s=(this.#l/1048576).toFixed(1);t.push(`${r.name}: File size exceeds ${s}MB`);continue}if(this.#c.size>0&&!this.#b(r)){t.push(`${r.name}: File type not allowed`);continue}if(this.#m(r.name)){t.push(`${r.name}: Invalid file name`);continue}if(this.securityTier===u.CRITICAL){let s=await this.#k(r);if(!s.valid){t.push(`${r.name}: ${s.error}`);continue}}if(this.#p){let s=await this.#A(r);if(!s.valid){t.push(`${r.name}: ${s.reason||"Rejected by scan"}`);continue}}}return{valid:t.length===0,errors:t}}#b(e){if(this.#c.has(e.type))return!0;for(let t of this.#c)if(t.endsWith("/*")){let i=t.slice(0,-2);if(e.type.startsWith(i))return!0}return!1}#m(e){return!!(e.includes("..")||e.includes("/")||e.includes("\\")||["web.config",".htaccess",".env","config.php"].includes(e.toLowerCase()))}async#A(e){this.#d=!0,this.#T(e.name),this.audit("scan_started",{name:this.#e?.name??"",fileName:e.name,fileSize:e.size});try{let t=await this.#p(e);return this.audit(t.valid?"scan_passed":"scan_rejected",{name:this.#e?.name??"",fileName:e.name,reason:t.reason??""}),t}catch(t){let i=t instanceof Error?t.message:"Scan failed";return this.audit("scan_error",{name:this.#e?.name??"",fileName:e.name,error:i}),{valid:!1,reason:`Scan error: ${i}`}}finally{this.#d=!1,this.#S()}}#T(e){this.#r&&this.#r.classList.add("scanning"),this.#e&&(this.#e.disabled=!0),this.#n&&(this.#n.textContent=`Scanning ${e}\u2026`)}#S(){this.#r&&this.#r.classList.remove("scanning"),this.#e&&!this.hasAttribute("disabled")&&(this.#e.disabled=!1)}async#k(e){try{let t=await e.slice(0,4).arrayBuffer(),i=new Uint8Array(t),r={"application/pdf":[37,80,68,70],"image/jpeg":[255,216,255],"image/png":[137,80,78,71]};return r[e.type]&&!r[e.type].every((a,o)=>i[o]===a)?{valid:!1,error:"File content does not match declared type"}:{valid:!0}}catch{return{valid:!1,error:"Failed to validate file content"}}}#I(e){this.#n&&(!e||e.length===0?(this.#n.textContent="No file selected",this.#n.classList.remove("has-file")):e.length===1?(this.#n.textContent=e[0].name,this.#n.classList.add("has-file")):(this.#n.textContent=`${e.length} files selected`,this.#n.classList.add("has-file")))}#$(e){this.#s.innerHTML="",Array.from(e).forEach(t=>{let i=document.createElement("div");i.className="file-preview";let r=document.createElement("div");r.className="file-name",r.textContent=t.name;let s=document.createElement("div");s.className="file-size",s.textContent=this.#R(t.size);let n=document.createElement("button");n.className="remove-file",n.textContent="\u2715",n.type="button",n.onclick=()=>{this.#M()},i.appendChild(r),i.appendChild(s),i.appendChild(n),this.#s.appendChild(i)})}#R(e){return e<1024?e+" B":e<1024*1024?(e/1024).toFixed(1)+" KB":(e/(1024*1024)).toFixed(1)+" MB"}#M(){this.#e.value="",this.#a=null,this.#s.innerHTML="",this.#I(null),this.#N(),this.audit("file_removed",{name:this.#e.name})}#D(e){this.#i.textContent=e,this.#i.classList.remove("hidden"),this.#r.classList.add("error")}#N(){this.#i.textContent="",this.#i.classList.add("hidden"),this.#r.classList.remove("error")}#P(){return".file-upload-container { position: relative; margin-bottom: var(--secure-ui-form-gap); font-family: var(--secure-ui-font-family-base); } label { display: block; margin-bottom: var(--secure-ui-form-label-margin-bottom); font-size: var(--secure-ui-label-font-size); font-weight: var(--secure-ui-label-font-weight); color: var(--secure-ui-label-color); } .label-suffix { font-weight: var(--secure-ui-font-weight-normal); color: var(--secure-ui-color-text-secondary); font-size: var(--secure-ui-font-size-xs); margin-left: var(--secure-ui-space-1); } .security-badge { display: inline-block; padding: var(--secure-ui-badge-padding); margin-left: var(--secure-ui-space-2); font-size: var(--secure-ui-badge-font-size); font-weight: var(--secure-ui-font-weight-semibold); border-radius: var(--secure-ui-badge-border-radius); text-transform: uppercase; background-color: var(--secure-ui-color-bg-tertiary); color: var(--secure-ui-color-text-secondary); border: var(--secure-ui-border-width-thin) solid var(--secure-ui-color-border); } .drop-zone { position: relative; display: inline-flex; align-items: stretch; justify-content: flex-start; border-radius: var(--secure-ui-input-border-radius); cursor: pointer; width: 100%; } .drop-zone.drag-over { transform: scale(1.01); } .drop-zone.error .file-cta { border-color: var(--secure-ui-color-error); color: var(--secure-ui-color-error); } .file-input { position: absolute; top: 0; left: 0; width: 100%; height: 100%; opacity: 0; cursor: pointer; z-index: 1; } .file-input:focus { outline: none; } .drop-zone:focus-within .file-cta { outline: 2px solid var(--secure-ui-color-border-focus); outline-offset: 2px; box-shadow: var(--secure-ui-shadow-focus); } @media (forced-colors: active) { .drop-zone:focus-within .file-cta { outline: 2px solid ButtonText; box-shadow: none; } } .drop-zone-content { display: flex; align-items: stretch; width: 100%; pointer-events: none; } .file-cta { display: flex; align-items: center; justify-content: center; padding: var(--secure-ui-input-padding-y) var(--secure-ui-input-padding-x); background-color: var(--secure-ui-color-bg-secondary); border: var(--secure-ui-input-border-width) solid var(--secure-ui-input-border-color); border-radius: var(--secure-ui-input-border-radius); color: var(--secure-ui-color-text-primary); font-size: var(--secure-ui-input-font-size); font-weight: var(--secure-ui-font-weight-medium); white-space: nowrap; transition: all var(--secure-ui-transition-base) var(--secure-ui-transition-ease-in-out); } .drop-zone:hover .file-cta { background-color: var(--secure-ui-color-bg-tertiary); border-color: var(--secure-ui-input-border-color-hover); } .drop-zone:active .file-cta { background-color: var(--secure-ui-color-bg-tertiary); } .drop-zone.drag-over .file-cta { background-color: var(--secure-ui-color-primary-light, rgba(102, 126, 234, 0.1)); border-color: var(--secure-ui-color-primary); color: var(--secure-ui-color-primary); } .drop-icon { font-size: var(--secure-ui-font-size-base); margin-right: var(--secure-ui-space-2); display: flex; align-items: center; } .drop-text { font-size: var(--secure-ui-font-size-base); } .file-name-display { display: flex; align-items: center; flex: 1; padding: var(--secure-ui-input-padding-y) var(--secure-ui-input-padding-x); border: var(--secure-ui-input-border-width) solid var(--secure-ui-input-border-color); border-left: none; border-radius: 0 var(--secure-ui-input-border-radius) var(--secure-ui-input-border-radius) 0; background-color: var(--secure-ui-input-bg); color: var(--secure-ui-input-placeholder-color); font-size: var(--secure-ui-input-font-size); max-width: 100%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; } .file-name-display.has-file { color: var(--secure-ui-input-text-color); } .drop-zone-content.has-name .file-cta { border-radius: var(--secure-ui-input-border-radius) 0 0 var(--secure-ui-input-border-radius); border-right: none; } .drop-hint { display: block; text-align: right; margin-top: var(--secure-ui-space-1); font-size: var(--secure-ui-font-size-xs); color: var(--secure-ui-color-text-secondary); } .preview-container { margin-top: var(--secure-ui-space-3); } .file-preview { display: flex; align-items: center; padding: var(--secure-ui-space-3); background-color: var(--secure-ui-color-bg-secondary); border: var(--secure-ui-border-width-thin) solid var(--secure-ui-color-border); border-radius: var(--secure-ui-input-border-radius); margin-bottom: var(--secure-ui-space-2); } .file-name { flex: 1; font-size: var(--secure-ui-font-size-sm); color: var(--secure-ui-color-text-primary); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; } .file-size { font-size: var(--secure-ui-font-size-xs); color: var(--secure-ui-color-text-secondary); margin-left: var(--secure-ui-space-3); white-space: nowrap; } .remove-file { background: none; border: none; color: var(--secure-ui-color-error); font-size: var(--secure-ui-font-size-base); cursor: pointer; padding: var(--secure-ui-space-1) var(--secure-ui-space-2); margin-left: var(--secure-ui-space-2); border-radius: var(--secure-ui-border-radius-sm); transition: background-color var(--secure-ui-transition-base) var(--secure-ui-transition-ease-in-out); pointer-events: auto; } .remove-file:hover { background-color: var(--secure-ui-color-error-light, rgba(239, 68, 68, 0.1)); } .error-container { position: absolute; bottom: -1rem; left: 0; display: var(--error-display); margin-top: var(--secure-ui-form-error-margin-top); padding: var(--secure-ui-space-2) var(--secure-ui-space-3); background-color: var(--secure-ui-color-error-light, rgba(239, 68, 68, 0.1)); border-radius: var(--secure-ui-border-radius-sm); color: var(--secure-ui-color-error); font-size: var(--secure-ui-error-font-size); } .error-container.hidden { max-height: 0; opacity: 0; transform: translateY(-4px); margin-top: 0; } .drop-zone.disabled { opacity: var(--secure-ui-input-disabled-opacity); cursor: not-allowed; } .drop-zone.disabled .file-cta { background-color: var(--secure-ui-input-disabled-bg); } .drop-zone.scanning { pointer-events: none; opacity: 0.7; } .drop-zone.scanning .file-cta { border-color: var(--secure-ui-color-primary); } .drop-zone.scanning .file-name-display { color: var(--secure-ui-color-primary); animation: scanning-pulse 1.2s ease-in-out infinite; } @keyframes scanning-pulse { 0%, 100% { opacity: 0.5; } 50% { opacity: 1; } }"}handleAttributeChange(e,t,i){if(this.#e)switch(e){case"disabled":this.#e.disabled=this.hasAttribute("disabled");break;case"accept":this.#e.accept=i,this.#h(i);break}}get files(){return this.#a}get name(){return this.#e?this.#e.name:""}get valid(){return!((this.hasAttribute("required")||this.config.validation.required)&&(!this.#a||this.#a.length===0))}clear(){this.#M()}setScanHook(e){if(typeof e!="function")throw new TypeError("setScanHook expects a function");this.#p=e,this.audit("scan_hook_registered",{name:this.#e?.name??""})}get hasScanHook(){return this.#p!==null}get scanning(){return this.#d}disconnectedCallback(){super.disconnectedCallback(),this.#a=null,this.#e&&(this.#e.value="")}};customElements.define("secure-file-upload",H);var F=class extends p{#e=null;#t=null;#i=null;#s=null;#r=`secure-datetime-${Math.random().toString(36).substring(2,11)}`;static get observedAttributes(){return[...super.observedAttributes,"name","type","label","required","min","max","step","value","show-timezone"]}constructor(){super()}render(){let e=document.createDocumentFragment(),t=document.createElement("div");t.className="datetime-container",t.setAttribute("part","container");let i=this.getAttribute("label");i&&(this.#t=document.createElement("label"),this.#t.htmlFor=this.#r,this.#t.textContent=this.sanitizeValue(i),this.#t.setAttribute("part","label"),t.appendChild(this.#t));let r=document.createElement("div");return r.className="input-wrapper",r.setAttribute("part","wrapper"),this.#e=document.createElement("input"),this.#e.id=this.#r,this.#e.className="datetime-field",this.#e.setAttribute("part","input"),this.#n(),this.#c(),r.appendChild(this.#e),this.hasAttribute("show-timezone")&&(this.#s=document.createElement("span"),this.#s.className="timezone-display",this.#s.textContent=this.#o(),r.appendChild(this.#s)),t.appendChild(r),this.#i=document.createElement("div"),this.#i.className="error-container hidden",this.#i.setAttribute("role","alert"),this.#i.setAttribute("part","error"),this.#i.id=`${this.#r}-error`,t.appendChild(this.#i),this.addComponentStyles(this.#w()),e.appendChild(t),e}#n(){let e=this.config,t=this.getAttribute("name");t&&(this.#e.name=this.sanitizeValue(t)),!this.getAttribute("label")&&t&&this.#e.setAttribute("aria-label",this.sanitizeValue(t)),this.#e.setAttribute("aria-describedby",`${this.#r}-error`),this.#s&&this.#s.setAttribute("aria-label",`Timezone: ${this.#o()}`);let i=this.getAttribute("type")||"date";["date","time","datetime-local","month","week"].includes(i)?this.#e.type=i:(console.warn(`Invalid datetime type "${i}", defaulting to "date"`),this.#e.type="date"),(this.hasAttribute("required")||e.validation.required)&&(this.#e.required=!0,this.#e.setAttribute("aria-required","true"));let s=this.getAttribute("min");s&&(this.#e.min=this.#a(s));let n=this.getAttribute("max");n&&(this.#e.max=this.#a(n));let a=this.getAttribute("step");a&&(this.#e.step=a),this.hasAttribute("disabled")&&(this.#e.disabled=!0),this.hasAttribute("readonly")&&(this.#e.readOnly=!0),e.storage.allowAutocomplete||(this.#e.autocomplete="off");let o=this.getAttribute("value");o&&(this.#e.value=this.#a(o))}#a(e){if(!e)return"";let t=this.#e?.type||this.getAttribute("type")||"date",i={date:/^\d{4}-\d{2}-\d{2}$/,time:/^\d{2}:\d{2}(:\d{2})?$/,"datetime-local":/^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}(:\d{2})?$/,month:/^\d{4}-\d{2}$/,week:/^\d{4}-W\d{2}$/},r=Object.hasOwn(i,t)?i[t]:void 0;return r&&!r.test(e)?(console.warn(`Invalid ${t} format: ${e}`),""):e}#o(){let e=new Date().getTimezoneOffset(),t=Math.abs(Math.floor(e/60)),i=Math.abs(e%60);return`UTC${e<=0?"+":"-"}${t.toString().padStart(2,"0")}:${i.toString().padStart(2,"0")}`}#c(){this.#e.addEventListener("focus",()=>{this.recordTelemetryFocus(),this.audit("datetime_focused",{name:this.#e.name,type:this.#e.type})}),this.#e.addEventListener("input",e=>{this.recordTelemetryInput(e),this.#l(e)}),this.#e.addEventListener("change",e=>{this.#p(e)}),this.#e.addEventListener("blur",()=>{this.recordTelemetryBlur(),this.#d(),this.audit("datetime_blurred",{name:this.#e.name,hasValue:this.#e.value.length>0})})}#l(e){this.#y(),this.dispatchEvent(new CustomEvent("secure-datetime-change",{detail:{name:this.#e.name,value:this.#e.value,type:this.#e.type,tier:this.securityTier},bubbles:!0,composed:!0}))}#p(e){let t=this.#e.value;if(!this.#a(t)&&t){this.#h("Invalid date/time format");return}this.#y(),this.audit("datetime_changed",{name:this.#e.name,type:this.#e.type,value:t})}#d(){let e=this.checkRateLimit();if(!e.allowed){this.#h(`Too many attempts. Please wait ${Math.ceil(e.retryAfter/1e3)} seconds.`);return}let t=this.#e.value;if(this.#e.required&&!t){this.#h("This field is required");return}if(t){if(this.#e.min&&t<this.#e.min){this.#h(`Value must be after ${this.#u(this.#e.min)}`);return}if(this.#e.max&&t>this.#e.max){this.#h(`Value must be before ${this.#u(this.#e.max)}`);return}}if(this.securityTier===u.CRITICAL&&t){let i=new Date(t);if(isNaN(i.getTime())){this.#h("Invalid date/time");return}let r=i.getFullYear();if(r<1900||r>2100){this.#h("Date must be between 1900 and 2100");return}}}#u(e){try{return new Date(e).toLocaleString()}catch{return e}}#h(e){this.#i.textContent=e,this.#i.offsetHeight,this.#i.classList.remove("hidden"),this.#e.classList.add("error"),this.#e.setAttribute("aria-invalid","true")}#y(){this.#i.classList.add("hidden"),this.#i.addEventListener("transitionend",()=>{this.#i.classList.contains("hidden")&&(this.#i.textContent="")},{once:!0}),this.#e.classList.remove("error"),this.#e.removeAttribute("aria-invalid")}#w(){return`.datetime-container { margin-bottom: var(--secure-ui-form-gap); font-family: var(--secure-ui-font-family-base); } label { display: block; margin-bottom: var(--secure-ui-form-label-margin-bottom); font-size: var(--secure-ui-label-font-size); font-weight: var(--secure-ui-label-font-weight); color: var(--secure-ui-label-color); } .label-suffix { font-weight: var(--secure-ui-font-weight-normal); color: var(--secure-ui-color-text-secondary); font-size: var(--secure-ui-font-size-xs); margin-left: var(--secure-ui-space-1); } .security-badge { display: inline-block; padding: var(--secure-ui-badge-padding); margin-left: var(--secure-ui-space-2); font-size: var(--secure-ui-badge-font-size); font-weight: var(--secure-ui-font-weight-semibold); border-radius: var(--secure-ui-badge-border-radius); text-transform: uppercase; background-color: var(--secure-ui-color-bg-tertiary); color: var(--secure-ui-color-text-secondary); border: var(--secure-ui-border-width-thin) solid var(--secure-ui-color-border); } .input-wrapper { position: relative; } .datetime-field { width: 100%; height: var(--secure-ui-input-height); padding: var(--secure-ui-input-padding-y) var(--secure-ui-input-padding-x); font-family: var(--secure-ui-font-family-base); font-size: var(--secure-ui-input-font-size); line-height: var(--secure-ui-line-height-normal); color: var(--secure-ui-input-text-color); background-color: var(--secure-ui-input-bg); border: var(--secure-ui-input-border-width) solid var(--secure-ui-input-border-color); border-radius: var(--secure-ui-input-border-radius); transition: all var(--secure-ui-transition-base) var(--secure-ui-transition-ease-in-out); cursor: pointer; box-sizing: border-box; } .datetime-field::placeholder { color: var(--secure-ui-input-placeholder-color); } .datetime-field:hover:not(:disabled):not([readonly]) { border-color: var(--secure-ui-input-border-color-hover); } .datetime-field:focus { outline: none; border-color: var(--secure-ui-input-border-color-focus); box-shadow: var(--secure-ui-shadow-focus); } .datetime-field.error { border-color: var(--secure-ui-color-error); } .datetime-field.error:focus { box-shadow: var(--secure-ui-shadow-focus-error); } .datetime-field:disabled { background-color: var(--secure-ui-input-disabled-bg); cursor: not-allowed; opacity: var(--secure-ui-input-disabled-opacity); } .datetime-field[readonly] { background-color: var(--secure-ui-color-bg-secondary); cursor: default; } .input-wrapper::after { content: '\u{1F4C5}' / ''; position: absolute; right: var(--secure-ui-space-3); top: 50%; transform: translateY(-50%); pointer-events: none; font-size: var(--secure-ui-font-size-lg); color: var(--secure-ui-color-text-secondary); } .input-wrapper[data-type="time"]::after { content: '\u{1F550}' / ''; } .input-wrapper[data-type="datetime-local"]::after { content: '\u{1F4C5}' / ''; } .input-wrapper[data-type="month"]::after { content: '\u{1F4C6}' / ''; } .input-wrapper[data-type="week"]::after { content: '\u{1F4C5}' / ''; } .input-wrapper .timezone-display { position: absolute; right: 0; bottom: -1.25rem; } .range-display { display: none; margin-top: var(--secure-ui-space-2); padding: var(--secure-ui-space-2) var(--secure-ui-space-3); background-color: var(--secure-ui-color-bg-secondary); border-radius: var(--secure-ui-border-radius-sm); font-size: var(--secure-ui-font-size-xs); color: var(--secure-ui-color-text-secondary); } .range-display.visible { display: block; } .range-item { margin-bottom: var(--secure-ui-space-1); } .range-item:last-child { margin-bottom: 0; } .range-label { font-weight: var(--secure-ui-font-weight-medium); margin-right: var(--secure-ui-space-1); } .helper-text { margin-top: var(--secure-ui-space-2); font-size: var(--secure-ui-font-size-xs); color: var(--secure-ui-color-text-secondary); line-height: var(--secure-ui-line-height-normal); } .error-container { position: absolute; margin-top: var(--secure-ui-form-error-margin-top); font-size: var(--secure-ui-error-font-size); color: var(--secure-ui-error-color); line-height: var(--secure-ui-line-height-normal); overflow: hidden; max-height: 40px; opacity: 1; transform: translateY(0); transition: opacity 0.2s ease-out, transform 0.2s ease-out, max-height 0.2s ease-out, margin-top 0.2s ease-out; } .error-container.hidden { max-height: 0; opacity: 0; transform: translateY(-4px); margin-top: 0; } @media (prefers-reduced-motion: reduce) { .datetime-field, .error-container { transition: none !important; } } .datetime-field::-webkit-calendar-picker-indicator { display: inline-block; cursor: pointer; opacity: 1; padding: 4px; margin-left: 4px; } .datetime-field:disabled::-webkit-calendar-picker-indicator { cursor: not-allowed; opacity: 0.3; } .datetime-field::-webkit-inner-spin-button { height: auto; opacity: 0.6; cursor: pointer; } .datetime-field:valid:not(:placeholder-shown):not(:focus) { border-color: var(--secure-ui-color-success); } .datetime-field:invalid:not(:placeholder-shown):not(:focus) { border-color: var(--secure-ui-color-error); } .datetime-container:focus-within label { color: var(--secure-ui-color-primary); } .datetime-container.disabled { opacity: var(--secure-ui-input-disabled-opacity); } .datetime-container.disabled label { color: var(--secure-ui-color-text-disabled); } label .required { color: var(--secure-ui-color-error); margin-left: var(--secure-ui-space-1); }`}handleAttributeChange(e,t,i){if(this.#e)switch(e){case"disabled":this.#e.disabled=this.hasAttribute("disabled");break;case"readonly":this.#e.readOnly=this.hasAttribute("readonly");break;case"value":i!==this.#e.value&&(this.#e.value=this.#a(i||""));break;case"min":this.#e.min=this.#a(i||"");break;case"max":this.#e.max=this.#a(i||"");break}}get value(){return this.#e?this.#e.value:""}set value(e){this.#e&&(this.#e.value=this.#a(e||""))}get name(){return this.#e?this.#e.name:""}getValueAsDate(){if(!this.#e||!this.#e.value)return null;try{let e=new Date(this.#e.value);return isNaN(e.getTime())?null:e}catch{return null}}setValueFromDate(e){if(!this.#e||!(e instanceof Date))return;let t=this.#e.type,i="";switch(t){case"date":i=e.toISOString().split("T")[0];break;case"time":i=e.toTimeString().slice(0,5);break;case"datetime-local":i=e.toISOString().slice(0,16);break;case"month":i=e.toISOString().slice(0,7);break;case"week":let r=new Date(e);r.setHours(0,0,0,0),r.setDate(r.getDate()+4-(r.getDay()||7));let s=new Date(r.getFullYear(),0,1),n=Math.ceil(((r.getTime()-s.getTime())/864e5+1)/7);i=`${r.getFullYear()}-W${n.toString().padStart(2,"0")}`;break}this.#e.value=i}get valid(){let e=this.hasAttribute("required")||this.config.validation.required,t=this.#e?this.#e.value:"";return!(e&&!t||t&&!this.#a(t)||this.#e&&(this.#e.min&&t<this.#e.min||this.#e.max&&t>this.#e.max))}focus(){this.#e&&this.#e.focus()}blur(){this.#e&&this.#e.blur()}disconnectedCallback(){super.disconnectedCallback(),this.#e&&(this.#e.value="")}};customElements.define("secure-datetime",F);var $=class l extends p{#e=[];#t=[];#i=[];#s="";#r={column:null,direction:"asc"};#n={currentPage:1,pageSize:10};#a=!1;constructor(){super()}render(){return null}connectedCallback(){this.initializeSecurity();let e=this.querySelector('table[slot="table"]'),t=this.#o();t&&(this.#a=!0,this.#t=t.columns,this.#e=t.data,this.#i=[...t.data],e&&e.remove()),this.#f(),this.audit("table_mounted",{rowCount:this.#e.length,columnCount:this.#t.length,usingSlottedContent:this.#a})}#o(){let e=this.querySelector('table[slot="table"]');if(!e)return null;try{let t=e.querySelectorAll("thead th");if(t.length===0)return null;let i=Array.from(t).map(n=>({key:n.getAttribute("data-key")||n.textContent.trim().toLowerCase().replace(/\s+/g,"_"),label:n.textContent.trim().replace(/\s+$/,""),sortable:n.hasAttribute("data-sortable")?n.getAttribute("data-sortable")!=="false":!0,filterable:n.hasAttribute("data-filterable")?n.getAttribute("data-filterable")!=="false":void 0,tier:n.getAttribute("data-tier")||void 0,width:n.getAttribute("data-width")||void 0,render:n.hasAttribute("data-render-html")?this.#c(n):void 0})),r=e.querySelectorAll("tbody tr"),s=Array.from(r).map((n,a)=>{let o=n.querySelectorAll("td"),d=Object.create(null);return o.forEach((c,m)=>{if(m<i.length){let g=i[m],b=c.getAttribute("data-key")||g.key;if(b==="__proto__"||b==="constructor"||b==="prototype")return;c.innerHTML.trim().includes("<")?(d[b]=c.textContent?.trim()??"",d[`${b}_html`]=c.innerHTML.trim()):d[b]=c.textContent?.trim()??""}}),d});return{columns:i,data:s}}catch(t){return console.error("SecureTable: Error parsing slotted table",t),null}}#c(e){return(t,i,r)=>{let s=`${r}_html`,n=Object.hasOwn(i,s)?i[s]:null;return n?this.#w(n):this.#u(t)}}set data(e){Array.isArray(e)&&(this.#e=e,this.#i=[...e],this.#f())}get data(){return this.#e}set columns(e){Array.isArray(e)&&(this.#t=e,this.#f())}get columns(){return this.#t}#l(e){this.#s=e.toLowerCase(),this.#s?this.#i=this.#e.filter(t=>this.#t.some(i=>i.filterable===!1?!1:String(t[i.key]??"").toLowerCase().includes(this.#s))):this.#i=[...this.#e],this.#n.currentPage=1,this.#b(),this.audit("table_filtered",{filterTerm:e,resultCount:this.#i.length})}#p(e){this.#r.column===e?this.#r.direction=this.#r.direction==="asc"?"desc":"asc":(this.#r.column=e,this.#r.direction="asc"),this.#i.sort((t,i)=>{let r=Object.hasOwn(t,e)?t[e]:void 0,s=Object.hasOwn(i,e)?i[e]:void 0,n=r==null,a=s==null;if(n&&a)return 0;if(n)return 1;if(a)return-1;let o=typeof r=="number"?r:String(r),d=typeof s=="number"?s:String(s),c=0;return o>d?c=1:o<d&&(c=-1),this.#r.direction==="asc"?c:-c}),this.#b(),this.audit("table_sorted",{column:e,direction:this.#r.direction})}#d(e){let t=Math.ceil(this.#i.length/this.#n.pageSize);e<1||e>t||(this.#n.currentPage=e,this.#b())}#u(e){return e==null||e===""?"":String(e).replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;").replace(/'/g,"&#x27;")}static#h=new Set(["a","abbr","b","br","button","code","em","i","s","small","span","strong","time","u"]);static#y=new Set(["class","href","title","aria-label","aria-hidden","type","datetime"]);#w(e){if(!e)return"";let t=new DOMParser().parseFromString(`<!DOCTYPE html><body>${e}`,"text/html");return this.#x(t.body),t.body.innerHTML}#x(e){for(let t of Array.from(e.childNodes)){if(t.nodeType===Node.TEXT_NODE)continue;if(t.nodeType!==Node.ELEMENT_NODE){e.removeChild(t);continue}let i=t,r=i.tagName.toLowerCase();if(!l.#h.has(r)){let s=document.createDocumentFragment();for(;i.firstChild;)s.appendChild(i.firstChild);e.replaceChild(s,i);continue}for(let s of Array.from(i.attributes)){let n=s.name.toLowerCase();if(n.startsWith("on")){i.removeAttribute(s.name);continue}if((n==="href"||n==="src"||n==="action")&&/^\s*(javascript|data)\s*:/i.test(s.value)){i.removeAttribute(s.name);continue}!l.#y.has(n)&&!n.startsWith("data-")&&i.removeAttribute(s.name)}this.#x(i)}}#g(e,t){if(e==null||e==="")return"-";let i=String(e);return t===u.SENSITIVE&&i.length>4?"\u2022".repeat(i.length-4)+i.slice(-4):t===u.CRITICAL?"\u2022".repeat(i.length):this.#u(i)}#v(e,t,i){if(typeof i.render=="function")return this.#w(i.render(e,t,i.key));let r=`${i.key}_html`;return Object.hasOwn(t,r)&&t[r]?this.#w(t[r]):this.#g(e,i.tier)}#E(){let e=Math.ceil(this.#i.length/this.#n.pageSize),t=(this.#n.currentPage-1)*this.#n.pageSize,i=t+this.#n.pageSize,r=this.#i.slice(t,i),s,n;if(r.length===0||this.#t.length===0){let a=this.#t.length===0?"No columns configured":"No results found",o=this.#t.length===0?"Set the columns property to configure the table":"Try adjusting your search term";s=`
2
2
  <div class="empty-state">
3
3
  <div class="empty-state-icon" aria-hidden="true">\u{1F50D}</div>
4
- <h3>${this.#l(a)}</h3>
5
- <p>${this.#l(o)}</p>
4
+ <h3>${this.#u(a)}</h3>
5
+ <p>${this.#u(o)}</p>
6
6
  </div>`,n=""}else s=`
7
7
  <div class="table-wrapper">
8
8
  <table class="data-table">
9
9
  <thead>
10
10
  <tr>
11
- ${this.#s.map(a=>{let o=this.#t.column===a.key,u=o?this.#t.direction==="asc"?"\u25B2":"\u25BC":"\u25B2",d=a.sortable!==!1?`aria-sort="${o?this.#t.direction==="asc"?"ascending":"descending":"none"}"`:"";return`
11
+ ${this.#t.map(a=>{let o=this.#r.column===a.key,d=o?this.#r.direction==="asc"?"\u25B2":"\u25BC":"\u25B2",c=a.sortable!==!1?`aria-sort="${o?this.#r.direction==="asc"?"ascending":"descending":"none"}"`:"";return`
12
12
  <th
13
13
  class="${a.sortable!==!1?"sortable":""} ${o?"sorted":""}"
14
- data-column="${this.#l(a.key)}"
15
- ${d}
14
+ data-column="${this.#u(a.key)}"
15
+ ${c}
16
16
  >
17
- ${this.#l(a.label)}
18
- ${a.sortable!==!1?`<span class="sort-indicator" aria-hidden="true">${u}</span>`:""}
19
- ${a.tier?`<span class="security-badge" aria-hidden="true">${this.#l(a.tier)}</span>`:""}
17
+ ${this.#u(a.label)}
18
+ ${a.sortable!==!1?`<span class="sort-indicator" aria-hidden="true">${d}</span>`:""}
19
+ ${a.tier?`<span class="security-badge" aria-hidden="true">${this.#u(a.tier)}</span>`:""}
20
20
  </th>`}).join("")}
21
21
  </tr>
22
22
  </thead>
23
23
  <tbody>
24
24
  ${r.map(a=>`
25
25
  <tr>
26
- ${this.#s.map(o=>`
27
- <td>${this.#b(a[o.key],a,o)}</td>
26
+ ${this.#t.map(o=>`
27
+ <td>${this.#v(a[o.key],a,o)}</td>
28
28
  `).join("")}
29
29
  </tr>
30
30
  `).join("")}
@@ -39,196 +39,31 @@ var c=Object.freeze({PUBLIC:"public",AUTHENTICATED:"authenticated",SENSITIVE:"se
39
39
  <button class="pagination-button" id="prevBtn" ${this.#n.currentPage===1?"disabled":""}>
40
40
  \u2190 Previous
41
41
  </button>
42
- ${this.#g(e)}
42
+ ${this.#m(e)}
43
43
  <button class="pagination-button" id="nextBtn" ${this.#n.currentPage===e?"disabled":""}>
44
44
  Next \u2192
45
45
  </button>
46
46
  </div>
47
- </div>`:"";return{tableHtml:s,paginationHtml:n}}#y(){if(!this.shadowRoot)return;let{tableHtml:e,paginationHtml:t}=this.#f();this.shadowRoot.innerHTML="",this.addComponentStyles(this.getBaseStylesheetUrl()),this.addComponentStyles(':host { display: block; font-family: var(--secure-ui-font-family-base); } .table-container { background: var(--secure-ui-color-bg-primary); border-radius: var(--secure-ui-border-radius-lg); border: var(--secure-ui-border-width-thin) solid var(--secure-ui-color-border); overflow: hidden; } .table-header { display: flex; justify-content: space-between; align-items: center; padding: var(--secure-ui-space-4); background-color: var(--secure-ui-color-bg-secondary); border-bottom: var(--secure-ui-border-width-thin) solid var(--secure-ui-color-border); gap: var(--secure-ui-space-3); flex-wrap: wrap; } .table-title { font-size: var(--secure-ui-font-size-lg); font-weight: var(--secure-ui-font-weight-semibold); color: var(--secure-ui-color-text-primary); margin: 0; } .table-controls { display: flex; gap: var(--secure-ui-space-3); align-items: center; } .search-input { padding: var(--secure-ui-space-2) var(--secure-ui-space-3); border: var(--secure-ui-border-width-thin) solid var(--secure-ui-color-border); border-radius: var(--secure-ui-border-radius-base); font-size: var(--secure-ui-font-size-sm); font-family: var(--secure-ui-font-family-base); color: var(--secure-ui-color-text-primary); background-color: var(--secure-ui-color-bg-primary); min-width: 200px; transition: all var(--secure-ui-transition-base) var(--secure-ui-transition-ease-in-out); } .search-input:focus { outline: none; border-color: var(--secure-ui-color-primary); box-shadow: var(--secure-ui-shadow-focus); } .search-input::placeholder { color: var(--secure-ui-color-text-secondary); } .table-wrapper { overflow-x: auto; overflow-y: visible; } .data-table { width: 100%; border-collapse: collapse; font-size: var(--secure-ui-font-size-sm); color: var(--secure-ui-table-font-color); } .data-table thead { background-color: var(--secure-ui-color-bg-tertiary); border-bottom: var(--secure-ui-border-width-base) solid var(--secure-ui-color-border); } .data-table th { padding: var(--secure-ui-space-3) var(--secure-ui-space-4); text-align: left; font-weight: var(--secure-ui-font-weight-semibold); color: var(--secure-ui-color-text-primary); white-space: nowrap; position: relative; } .data-table th.sortable { cursor: pointer; user-select: none; transition: background-color var(--secure-ui-transition-fast) var(--secure-ui-transition-ease-in-out); } .data-table th.sortable:hover { background-color: var(--secure-ui-color-bg-secondary); } .data-table th.sorted { color: var(--secure-ui-color-primary); } .sort-indicator { display: inline-block; margin-left: var(--secure-ui-space-1); font-size: var(--secure-ui-font-size-xs); opacity: 0.5; transition: opacity var(--secure-ui-transition-fast) var(--secure-ui-transition-ease-in-out); } .data-table th.sorted .sort-indicator { opacity: 1; } .data-table tbody tr { border-bottom: var(--secure-ui-border-width-thin) solid var(--secure-ui-color-border); transition: background-color var(--secure-ui-transition-fast) var(--secure-ui-transition-ease-in-out); } .data-table tbody tr:hover { background-color: var(--secure-ui-color-bg-secondary); } .data-table tbody tr:last-child { border-bottom: none; } .data-table td { padding: var(--secure-ui-space-3) var(--secure-ui-space-4); color: var(--secure-ui-color-text-primary); vertical-align: middle; } .masked-cell { font-family: var(--secure-ui-font-family-mono); color: var(--secure-ui-color-text-secondary); letter-spacing: 0.1em; } .empty-state { padding: var(--secure-ui-space-8) var(--secure-ui-space-4); text-align: center; color: var(--secure-ui-color-text-secondary); } .empty-state-icon { font-size: var(--secure-ui-font-size-3xl); margin-bottom: var(--secure-ui-space-2); } .empty-state-text { font-size: var(--secure-ui-font-size-base); margin: 0; } .pagination { display: flex; justify-content: space-between; align-items: center; padding: var(--secure-ui-space-4); background-color: var(--secure-ui-color-bg-secondary); border-top: var(--secure-ui-border-width-thin) solid var(--secure-ui-color-border); gap: var(--secure-ui-space-3); flex-wrap: wrap; } .pagination-info { font-size: var(--secure-ui-font-size-sm); color: var(--secure-ui-color-text-secondary); } .pagination-controls { display: flex; gap: var(--secure-ui-space-2); } .pagination-button { padding: var(--secure-ui-space-2) var(--secure-ui-space-3); border: var(--secure-ui-border-width-thin) solid var(--secure-ui-color-border); border-radius: var(--secure-ui-border-radius-base); background-color: var(--secure-ui-color-bg-primary); color: var(--secure-ui-color-text-primary); font-size: var(--secure-ui-font-size-sm); font-family: var(--secure-ui-font-family-base); cursor: pointer; transition: all var(--secure-ui-transition-base) var(--secure-ui-transition-ease-in-out); } .pagination-button:hover:not(:disabled) { background-color: var(--secure-ui-color-primary); color: var(--secure-ui-color-text-inverse); border-color: var(--secure-ui-color-primary); } .pagination-button:disabled { opacity: var(--secure-ui-input-disabled-opacity); cursor: not-allowed; } .pagination-button.active { background-color: var(--secure-ui-color-primary); color: var(--secure-ui-color-text-inverse); border-color: var(--secure-ui-color-primary); } .page-size-selector { display: flex; align-items: center; gap: var(--secure-ui-space-2); font-size: var(--secure-ui-font-size-sm); color: var(--secure-ui-color-text-secondary); } .page-size-select { padding: var(--secure-ui-space-1) var(--secure-ui-space-2); border: var(--secure-ui-border-width-thin) solid var(--secure-ui-color-border); border-radius: var(--secure-ui-border-radius-base); background-color: var(--secure-ui-color-bg-primary); color: var(--secure-ui-color-text-primary); font-size: var(--secure-ui-font-size-sm); font-family: var(--secure-ui-font-family-base); cursor: pointer; } .loading-overlay { position: absolute; top: 0; left: 0; right: 0; bottom: 0; background-color: rgba(255, 255, 255, 0.8); display: flex; justify-content: center; align-items: center; z-index: var(--secure-ui-z-sticky); } .loading-spinner { width: 40px; height: 40px; border: 4px solid var(--secure-ui-color-border); border-top-color: var(--secure-ui-color-primary); border-radius: 50%; animation: spin 0.8s linear infinite; } @keyframes spin { to { transform: rotate(360deg); } } :host([security-tier="authenticated"]) .table-container { border-top: var(--secure-ui-border-width-thick) solid var(--secure-ui-tier-authenticated); } :host([security-tier="sensitive"]) .table-container { border-top: var(--secure-ui-border-width-thick) solid var(--secure-ui-tier-sensitive); } :host([security-tier="critical"]) .table-container { border-top: var(--secure-ui-border-width-thick) solid var(--secure-ui-tier-critical); } .security-badge { display: inline-block; padding: var(--secure-ui-badge-padding); margin-left: var(--secure-ui-space-2); font-size: var(--secure-ui-badge-font-size); font-weight: var(--secure-ui-font-weight-semibold); border-radius: var(--secure-ui-badge-border-radius); text-transform: uppercase; background-color: var(--secure-ui-color-bg-tertiary); color: var(--secure-ui-color-text-secondary); border: var(--secure-ui-border-width-thin) solid var(--secure-ui-color-border); } @media (max-width: 768px) { .table-header { flex-direction: column; align-items: stretch; } .table-controls { flex-direction: column; width: 100%; } .search-input { width: 100%; min-width: auto; } .pagination { flex-direction: column; align-items: stretch; } .pagination-controls { justify-content: center; } .table-wrapper { position: relative; background: linear-gradient(to right, var(--secure-ui-color-bg-primary) 0%, transparent 100%) left, linear-gradient(to left, var(--secure-ui-color-bg-primary) 0%, transparent 100%) right, radial-gradient(farthest-side at 0 50%, rgba(0,0,0,.12), transparent) left, radial-gradient(farthest-side at 100% 50%, rgba(0,0,0,.12), transparent) right; background-repeat: no-repeat; background-size: 32px 100%, 32px 100%, 10px 100%, 10px 100%; background-attachment: local, local, scroll, scroll; } } .data-table tbody tr:nth-child(even) { background-color: rgba(0, 0, 0, 0.01); } .data-table tbody tr:nth-child(even):hover { background-color: var(--secure-ui-color-bg-secondary); }');let i=document.createElement("slot");i.name="table",this.shadowRoot.appendChild(i);let r=document.createElement("div");r.className="table-container",r.innerHTML=`
47
+ </div>`:"";return{tableHtml:s,paginationHtml:n}}#f(){if(!this.shadowRoot)return;let{tableHtml:e,paginationHtml:t}=this.#E();this.shadowRoot.innerHTML="",this.addComponentStyles(this.getBaseStylesheetUrl()),this.addComponentStyles(':host { display: block; font-family: var(--secure-ui-font-family-base); } .table-container { background: var(--secure-ui-color-bg-primary); border-radius: var(--secure-ui-border-radius-lg); border: var(--secure-ui-border-width-thin) solid var(--secure-ui-color-border); overflow: hidden; } .table-header { display: flex; justify-content: space-between; align-items: center; padding: var(--secure-ui-space-4); background-color: var(--secure-ui-color-bg-secondary); border-bottom: var(--secure-ui-border-width-thin) solid var(--secure-ui-color-border); gap: var(--secure-ui-space-3); flex-wrap: wrap; } .table-title { font-size: var(--secure-ui-font-size-lg); font-weight: var(--secure-ui-font-weight-semibold); color: var(--secure-ui-color-text-primary); margin: 0; } .table-controls { display: flex; gap: var(--secure-ui-space-3); align-items: center; } .search-input { padding: var(--secure-ui-space-2) var(--secure-ui-space-3); border: var(--secure-ui-border-width-thin) solid var(--secure-ui-color-border); border-radius: var(--secure-ui-border-radius-base); font-size: var(--secure-ui-font-size-sm); font-family: var(--secure-ui-font-family-base); color: var(--secure-ui-color-text-primary); background-color: var(--secure-ui-color-bg-primary); min-width: 200px; transition: all var(--secure-ui-transition-base) var(--secure-ui-transition-ease-in-out); } .search-input:focus { outline: none; border-color: var(--secure-ui-color-primary); box-shadow: var(--secure-ui-shadow-focus); } .search-input::placeholder { color: var(--secure-ui-color-text-secondary); } .table-wrapper { overflow-x: auto; overflow-y: visible; } .data-table { width: 100%; border-collapse: collapse; font-size: var(--secure-ui-font-size-sm); color: var(--secure-ui-table-font-color); } .data-table thead { background-color: var(--secure-ui-color-bg-tertiary); border-bottom: var(--secure-ui-border-width-base) solid var(--secure-ui-color-border); } .data-table th { padding: var(--secure-ui-space-3) var(--secure-ui-space-4); text-align: left; font-weight: var(--secure-ui-font-weight-semibold); color: var(--secure-ui-color-text-primary); white-space: nowrap; position: relative; } .data-table th.sortable { cursor: pointer; user-select: none; transition: background-color var(--secure-ui-transition-fast) var(--secure-ui-transition-ease-in-out); } .data-table th.sortable:hover { background-color: var(--secure-ui-color-bg-secondary); } .data-table th.sorted { color: var(--secure-ui-color-primary); } .sort-indicator { display: inline-block; margin-left: var(--secure-ui-space-1); font-size: var(--secure-ui-font-size-xs); opacity: 0.5; transition: opacity var(--secure-ui-transition-fast) var(--secure-ui-transition-ease-in-out); } .data-table th.sorted .sort-indicator { opacity: 1; } .data-table tbody tr { border-bottom: var(--secure-ui-border-width-thin) solid var(--secure-ui-color-border); transition: background-color var(--secure-ui-transition-fast) var(--secure-ui-transition-ease-in-out); } .data-table tbody tr:hover { background-color: var(--secure-ui-color-bg-secondary); } .data-table tbody tr:last-child { border-bottom: none; } .data-table td { padding: var(--secure-ui-space-3) var(--secure-ui-space-4); color: var(--secure-ui-color-text-primary); vertical-align: middle; } .masked-cell { font-family: var(--secure-ui-font-family-mono); color: var(--secure-ui-color-text-secondary); letter-spacing: 0.1em; } .empty-state { padding: var(--secure-ui-space-8) var(--secure-ui-space-4); text-align: center; color: var(--secure-ui-color-text-secondary); } .empty-state-icon { font-size: var(--secure-ui-font-size-3xl); margin-bottom: var(--secure-ui-space-2); } .empty-state-text { font-size: var(--secure-ui-font-size-base); margin: 0; } .pagination { display: flex; justify-content: space-between; align-items: center; padding: var(--secure-ui-space-4); background-color: var(--secure-ui-color-bg-secondary); border-top: var(--secure-ui-border-width-thin) solid var(--secure-ui-color-border); gap: var(--secure-ui-space-3); flex-wrap: wrap; } .pagination-info { font-size: var(--secure-ui-font-size-sm); color: var(--secure-ui-color-text-secondary); } .pagination-controls { display: flex; gap: var(--secure-ui-space-2); } .pagination-button { padding: var(--secure-ui-space-2) var(--secure-ui-space-3); border: var(--secure-ui-border-width-thin) solid var(--secure-ui-color-border); border-radius: var(--secure-ui-border-radius-base); background-color: var(--secure-ui-color-bg-primary); color: var(--secure-ui-color-text-primary); font-size: var(--secure-ui-font-size-sm); font-family: var(--secure-ui-font-family-base); cursor: pointer; transition: all var(--secure-ui-transition-base) var(--secure-ui-transition-ease-in-out); } .pagination-button:hover:not(:disabled) { background-color: var(--secure-ui-color-primary); color: var(--secure-ui-color-text-inverse); border-color: var(--secure-ui-color-primary); } .pagination-button:disabled { opacity: var(--secure-ui-input-disabled-opacity); cursor: not-allowed; } .pagination-button.active { background-color: var(--secure-ui-color-primary); color: var(--secure-ui-color-text-inverse); border-color: var(--secure-ui-color-primary); } .page-size-selector { display: flex; align-items: center; gap: var(--secure-ui-space-2); font-size: var(--secure-ui-font-size-sm); color: var(--secure-ui-color-text-secondary); } .page-size-select { padding: var(--secure-ui-space-1) var(--secure-ui-space-2); border: var(--secure-ui-border-width-thin) solid var(--secure-ui-color-border); border-radius: var(--secure-ui-border-radius-base); background-color: var(--secure-ui-color-bg-primary); color: var(--secure-ui-color-text-primary); font-size: var(--secure-ui-font-size-sm); font-family: var(--secure-ui-font-family-base); cursor: pointer; } .loading-overlay { position: absolute; top: 0; left: 0; right: 0; bottom: 0; background-color: rgba(255, 255, 255, 0.8); display: flex; justify-content: center; align-items: center; z-index: var(--secure-ui-z-sticky); } .loading-spinner { width: 40px; height: 40px; border: 4px solid var(--secure-ui-color-border); border-top-color: var(--secure-ui-color-primary); border-radius: 50%; animation: spin 0.8s linear infinite; } @keyframes spin { to { transform: rotate(360deg); } } :host([security-tier="authenticated"]) .table-container { border-top: var(--secure-ui-border-width-thick) solid var(--secure-ui-tier-authenticated); } :host([security-tier="sensitive"]) .table-container { border-top: var(--secure-ui-border-width-thick) solid var(--secure-ui-tier-sensitive); } :host([security-tier="critical"]) .table-container { border-top: var(--secure-ui-border-width-thick) solid var(--secure-ui-tier-critical); } .security-badge { display: inline-block; padding: var(--secure-ui-badge-padding); margin-left: var(--secure-ui-space-2); font-size: var(--secure-ui-badge-font-size); font-weight: var(--secure-ui-font-weight-semibold); border-radius: var(--secure-ui-badge-border-radius); text-transform: uppercase; background-color: var(--secure-ui-color-bg-tertiary); color: var(--secure-ui-color-text-secondary); border: var(--secure-ui-border-width-thin) solid var(--secure-ui-color-border); } @media (max-width: 768px) { .table-header { flex-direction: column; align-items: stretch; } .table-controls { flex-direction: column; width: 100%; } .search-input { width: 100%; min-width: auto; } .pagination { flex-direction: column; align-items: stretch; } .pagination-controls { justify-content: center; } .table-wrapper { position: relative; background: linear-gradient(to right, var(--secure-ui-color-bg-primary) 0%, transparent 100%) left, linear-gradient(to left, var(--secure-ui-color-bg-primary) 0%, transparent 100%) right, radial-gradient(farthest-side at 0 50%, rgba(0,0,0,.12), transparent) left, radial-gradient(farthest-side at 100% 50%, rgba(0,0,0,.12), transparent) right; background-repeat: no-repeat; background-size: 32px 100%, 32px 100%, 10px 100%, 10px 100%; background-attachment: local, local, scroll, scroll; } } .data-table tbody tr:nth-child(even) { background-color: rgba(0, 0, 0, 0.01); } .data-table tbody tr:nth-child(even):hover { background-color: var(--secure-ui-color-bg-secondary); }');let i=document.createElement("slot");i.name="table",this.shadowRoot.appendChild(i);let r=document.createElement("div");r.className="table-container",r.innerHTML=`
48
48
  <div class="table-header">
49
49
  <input
50
50
  type="search"
51
51
  class="search-input"
52
52
  placeholder="Search across all columns..."
53
- value="${this.#l(this.#r)}"
53
+ value="${this.#u(this.#s)}"
54
54
  id="searchInput"
55
55
  />
56
56
  </div>
57
57
  <div id="tableContent">${e}</div>
58
58
  <div id="paginationContent">${t}</div>
59
- `,this.shadowRoot.appendChild(r),this.#v()}#m(){if(!this.shadowRoot)return;let e=this.shadowRoot.getElementById("tableContent"),t=this.shadowRoot.getElementById("paginationContent");if(!e){this.#y();return}let{tableHtml:i,paginationHtml:r}=this.#f();e.innerHTML=i,t&&(t.innerHTML=r),this.#E()}#g(e){let i=Math.max(1,this.#n.currentPage-Math.floor(2.5)),r=Math.min(e,i+5-1);r-i<4&&(i=Math.max(1,r-5+1));let s="";for(let n=i;n<=r;n++)s+=`
59
+ `,this.shadowRoot.appendChild(r),this.#A()}#b(){if(!this.shadowRoot)return;let e=this.shadowRoot.getElementById("tableContent"),t=this.shadowRoot.getElementById("paginationContent");if(!e){this.#f();return}let{tableHtml:i,paginationHtml:r}=this.#E();e.innerHTML=i,t&&(t.innerHTML=r),this.#T()}#m(e){let i=Math.max(1,this.#n.currentPage-Math.floor(2.5)),r=Math.min(e,i+5-1);r-i<4&&(i=Math.max(1,r-5+1));let s="";for(let n=i;n<=r;n++)s+=`
60
60
  <button
61
61
  class="pagination-button ${n===this.#n.currentPage?"active":""}"
62
62
  data-page="${n}"
63
63
  >
64
64
  ${n}
65
65
  </button>
66
- `;return s}#v(){let e=this.shadowRoot.getElementById("searchInput");e&&e.addEventListener("input",t=>{this.#c(t.target.value)}),this.#E()}#E(){this.shadowRoot.querySelectorAll("th.sortable").forEach(n=>{n.addEventListener("click",()=>{let a=n.getAttribute("data-column");a&&this.#h(a)})});let t=this.shadowRoot.getElementById("prevBtn"),i=this.shadowRoot.getElementById("nextBtn");t&&t.addEventListener("click",()=>{this.#d(this.#n.currentPage-1)}),i&&i.addEventListener("click",()=>{this.#d(this.#n.currentPage+1)}),this.shadowRoot.querySelectorAll(".pagination-button[data-page]").forEach(n=>{n.addEventListener("click",()=>{let a=parseInt(n.getAttribute("data-page"),10);this.#d(a)})});let s=this.shadowRoot.getElementById("tableContent");s&&s.addEventListener("click",n=>{let a=n.target.closest("[data-action]");if(!a)return;let o=a.getAttribute("data-action"),u=Object.create(null);u.action=o;for(let d of Array.from(a.attributes))if(d.name.startsWith("data-")&&d.name!=="data-action"){let h=d.name.slice(5).replace(/-([a-z])/g,(f,b)=>b.toUpperCase());if(h==="__proto__"||h==="constructor"||h==="prototype")continue;u[h]=d.value}this.dispatchEvent(new CustomEvent("table-action",{bubbles:!0,composed:!0,detail:u})),this.audit("table_action",u)})}};customElements.define("secure-table",N);var F=class extends p{#e=null;#s=null;#i=null;#r=null;#t=!1;#n=!1;#a="critical";#o;#u=`secure-submit-button-${Math.random().toString(36).substring(2,11)}`;#c;#h;static get observedAttributes(){return[...super.observedAttributes,"label","loading-label","disabled"]}constructor(){super(),this.#o=g(this.#a),this.#c=this.#b.bind(this),this.#h=this.#g.bind(this)}connectedCallback(){super.connectedCallback(),queueMicrotask(()=>{this.#d(),this.#l(),this.#p(),this.#f(),this.audit("submit_button_initialized",{tier:this.#a,hasParentForm:!!this.#r})})}render(){let e=document.createDocumentFragment(),t=document.createElement("div");t.className="submit-container";let i=`${this.#u}-hint`,r=document.createElement("p");r.id=i,r.className="sr-only",r.textContent="Complete all required fields to enable this button",t.appendChild(r),this.#e=document.createElement("button"),this.#e.type="button",this.#e.className="submit-btn",this.#e.disabled=!0,this.#e.setAttribute("aria-disabled","true"),this.#e.setAttribute("aria-describedby",i),this.#s=document.createElement("span"),this.#s.className="btn-label",this.#s.textContent=this.sanitizeValue(this.getAttribute("label")||"Submit"),this.#i=document.createElement("span"),this.#i.className="btn-loading hidden",this.#i.setAttribute("aria-hidden","true");let s=document.createElement("span");s.className="spinner";let n=document.createElement("span");return n.textContent=this.sanitizeValue(this.getAttribute("loading-label")||"Submitting..."),this.#i.appendChild(s),this.#i.appendChild(n),this.#e.appendChild(this.#s),this.#e.appendChild(this.#i),this.#e.addEventListener("click",this.#h),t.appendChild(this.#e),e.appendChild(t),this.addComponentStyles(this.#E()),e}#d(){this.#r=this.closest("secure-form")}#l(){!this.getAttribute("security-tier")&&this.#r?this.#a=this.#r.securityTier:this.#a=this.securityTier,this.#o=g(this.#a)}#p(){let e=this.#r||this.parentElement;e&&(e.addEventListener("secure-input",this.#c),e.addEventListener("secure-textarea",this.#c),e.addEventListener("secure-select",this.#c),e.addEventListener("secure-datetime",this.#c))}#b(e){this.#f()}#f(){if(this.hasAttribute("disabled")){this.#m(!0);return}if(!this.#n){if(!this.#o.validation.required){this.#t=!0,this.#m(!1);return}this.#r&&typeof this.#r.valid=="boolean"?this.#t=this.#r.valid:this.#t=this.#y(),this.#m(!this.#t)}}#y(){let e=this.#r||this.parentElement;if(!e)return!1;let t=e.querySelectorAll("secure-input, secure-textarea, secure-select, secure-datetime, secure-file-upload");for(let i of t){let r=i;if(typeof r.valid=="boolean"&&!r.valid)return!1}return t.length>0}#m(e){this.#e&&(this.#e.disabled=e,this.#e.setAttribute("aria-disabled",String(e)))}#g(){if(this.#n||this.#e?.disabled)return;let e=this.checkRateLimit();if(!e.allowed){this.audit("submit_button_rate_limited",{retryAfter:e.retryAfter});return}this.audit("submit_button_clicked",{tier:this.#a,formValid:this.#t}),this.#v(!0),this.#r&&this.#r.submit(),this.#v(!1)}#v(e){this.#n=e,this.#e&&(this.#e.disabled=e,this.#e.setAttribute("aria-disabled",String(e))),this.#s&&this.#s.classList.toggle("hidden",e),this.#i&&(this.#i.classList.toggle("hidden",!e),this.#i.setAttribute("aria-hidden",String(!e)))}handleAttributeChange(e,t,i){switch(e){case"label":this.#s&&(this.#s.textContent=this.sanitizeValue(i||"Submit"));break;case"loading-label":if(this.#i){let r=this.#i.querySelector("span:last-child");r&&(r.textContent=this.sanitizeValue(i||"Submitting..."))}break;case"disabled":this.#f();break}}get disabled(){return this.#e?this.#e.disabled:!0}set disabled(e){e?this.setAttribute("disabled",""):this.removeAttribute("disabled"),this.#f()}get label(){return this.getAttribute("label")||"Submit"}set label(e){this.setAttribute("label",e)}#E(){return":host { display: inline-block; } .submit-container { margin-top: 8px; position: relative; } .submit-btn { display: inline-flex; align-items: center; justify-content: center; gap: var(--secure-ui-space-2); padding: var(--secure-ui-button-padding-y) var(--secure-ui-button-padding-x); min-height: var(--secure-ui-button-height); font-family: inherit; font-size: var(--secure-ui-font-size-sm); font-weight: var(--secure-ui-button-font-weight); line-height: 1; border-radius: var(--secure-ui-button-border-radius); border: var(--secure-ui-border-width-base) solid transparent; cursor: pointer; transition: background-color var(--secure-ui-transition-base) var(--secure-ui-transition-ease-out), border-color var(--secure-ui-transition-base) var(--secure-ui-transition-ease-out), opacity var(--secure-ui-transition-base) var(--secure-ui-transition-ease-out), box-shadow var(--secure-ui-transition-base) var(--secure-ui-transition-ease-out), color var(--secure-ui-transition-base) var(--secure-ui-transition-ease-out), transform var(--secure-ui-transition-fast) var(--secure-ui-transition-ease-out); background-color: var(--secure-ui-color-info); color: var(--secure-ui-color-text-inverse); user-select: none; } .submit-btn:hover:not(:disabled) { background-color: color-mix(in srgb, var(--secure-ui-color-info) 82%, black); transform: translateY(-1px); box-shadow: 0 2px 8px rgba(59, 130, 246, 0.25); } .submit-btn:focus-visible { outline: 2px solid var(--secure-ui-color-info); outline-offset: 2px; box-shadow: 0 0 0 3px rgba(59, 130, 246, 0.3); } @media (forced-colors: active) { .submit-btn:focus-visible { outline: 2px solid ButtonText; box-shadow: none; } } .submit-btn:active:not(:disabled) { background-color: color-mix(in srgb, var(--secure-ui-color-info) 72%, black); transform: scale(0.98); box-shadow: none; } .submit-btn:disabled { background-color: var(--secure-ui-color-bg-disabled); color: var(--secure-ui-color-text-disabled); border-color: var(--secure-ui-color-border); cursor: not-allowed; opacity: 0.7; transform: none; box-shadow: none; } .sr-only { position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px; overflow: hidden; clip: rect(0, 0, 0, 0); white-space: nowrap; border: 0; } .btn-label, .btn-loading { display: inline-flex; align-items: center; gap: 8px; transition: opacity 0.2s ease-out; } .btn-label.hidden, .btn-loading.hidden { display: none; } .spinner { display: inline-block; width: 14px; height: 14px; border: 2px solid currentColor; border-right-color: transparent; border-radius: 50%; animation: spin 0.6s linear infinite; } @keyframes spin { to { transform: rotate(360deg); } } @media (prefers-reduced-motion: reduce) { .submit-btn { transition: none !important; } .btn-label, .btn-loading { transition: none !important; } .spinner { animation: none; border-right-color: currentColor; opacity: 0.5; } }"}disconnectedCallback(){super.disconnectedCallback();let e=this.#r||this.parentElement;e&&(e.removeEventListener("secure-input",this.#c),e.removeEventListener("secure-textarea",this.#c),e.removeEventListener("secure-select",this.#c),e.removeEventListener("secure-datetime",this.#c))}};customElements.define("secure-submit-button",F);var U=Object.freeze([{type:"amex",pattern:/^3[47]/,format:[4,6,5],cvcLength:4,lengths:[15],label:"Amex"},{type:"diners",pattern:/^3(?:0[0-5]|[68])/,format:[4,6,4],cvcLength:3,lengths:[14],label:"Diners"},{type:"discover",pattern:/^6(?:011|5[0-9]{2})/,format:[4,4,4,4],cvcLength:3,lengths:[16],label:"Discover"},{type:"jcb",pattern:/^(?:2131|1800|35\d{3})/,format:[4,4,4,4],cvcLength:3,lengths:[16],label:"JCB"},{type:"mastercard",pattern:/^(?:5[1-5]|2[2-7])/,format:[4,4,4,4],cvcLength:3,lengths:[16],label:"Mastercard"},{type:"visa",pattern:/^4/,format:[4,4,4,4],cvcLength:3,lengths:[13,16,19],label:"Visa"}]);function J(l){return l?U.find(e=>e.pattern.test(l))??null:null}function x(l,e){let t="",i=0;for(let r=0;r<e.length;r++){let s=l.slice(i,i+e[r]);if(!s)break;r>0&&(t+=" "),t+=s,i+=e[r]}return t}function X(l,e){let t=e.reduce((n,a)=>n+a,0);if(!l)return x("\u2022".repeat(t),e);let i=l.padEnd(t,"\u2022").slice(0,t),r=Math.max(0,i.length-4),s="\u2022".repeat(r)+i.slice(r);return x(s,e)}function B(l){if(!l||l.length<12)return!1;let e=0,t=!1;for(let i=l.length-1;i>=0;i--){let r=l[i];if(!r)return!1;let s=parseInt(r,10);if(isNaN(s))return!1;let n=s;t&&(n*=2,n>9&&(n-=9)),e+=n,t=!t}return e%10===0}function Y(l,e){let t=new Date,i=t.getFullYear()%100,r=t.getMonth()+1;return!(e<i||e===i&&l<r)}var Q=0,$=class extends p{#e=null;#s=null;#i=null;#r=null;#t=null;#n=null;#a=null;#o=null;#u=null;#c=null;#h=null;#d=null;#l=null;#p=null;#b=null;#f=null;#y=null;#m="";#g="";#v="";#E="";#x=null;#w;constructor(){super(),this.#w=`secure-card-${++Q}`}static get observedAttributes(){return[...super.observedAttributes,"name","label","show-name"]}render(){let e=document.createDocumentFragment(),t=this.hasAttribute("disabled"),i=this.hasAttribute("show-name"),r=this.getAttribute("label")??"",s=document.createElement("div");s.className="card-container",s.setAttribute("part","container");let n=document.createElement("div");n.className="card-scene",n.setAttribute("aria-hidden","true"),this.#t=document.createElement("div"),this.#t.className="card";let a=document.createElement("div");a.className="card-face card-front";let o=document.createElement("div");o.className="card-top-row";let u=document.createElement("div");u.className="card-chip",this.#u=document.createElement("div"),this.#u.className="card-type-label",o.appendChild(u),o.appendChild(this.#u),a.appendChild(o),this.#n=document.createElement("div"),this.#n.className="card-number-display",this.#n.textContent="\u2022\u2022\u2022\u2022 \u2022\u2022\u2022\u2022 \u2022\u2022\u2022\u2022 \u2022\u2022\u2022\u2022",a.appendChild(this.#n);let d=document.createElement("div");d.className="card-bottom-row";let h=document.createElement("div");h.className="card-name-section";let f=document.createElement("div");f.className="card-field-label",f.textContent="Card holder",this.#o=document.createElement("div"),this.#o.className="card-name-display",this.#o.textContent="FULL NAME",h.appendChild(f),h.appendChild(this.#o);let b=document.createElement("div");b.className="card-expiry-section";let q=document.createElement("div");q.className="card-field-label",q.textContent="Expires",this.#a=document.createElement("div"),this.#a.className="card-expiry-display",this.#a.textContent="MM/YY",b.appendChild(q),b.appendChild(this.#a),d.appendChild(h),d.appendChild(b),a.appendChild(d);let w=document.createElement("div");w.className="card-face card-back";let j=document.createElement("div");j.className="card-strip";let E=document.createElement("div");E.className="card-cvc-area";let V=document.createElement("div");V.className="card-cvc-label",V.textContent="CVC",this.#c=document.createElement("div"),this.#c.className="card-cvc-display",this.#c.textContent="\u2022\u2022\u2022",E.appendChild(V),E.appendChild(this.#c),w.appendChild(j),w.appendChild(E),this.#t.appendChild(a),this.#t.appendChild(w),n.appendChild(this.#t);let v=document.createElement("div");if(v.className="card-fields",r){let m=document.createElement("div");m.className="card-legend",m.setAttribute("part","label"),m.textContent=this.sanitizeValue(r),v.appendChild(m)}let A=this.#C(`${this.#w}-number`),K=A.querySelector("label");K.textContent="Card number",this.#e=document.createElement("input"),this.#e.id=`${this.#w}-number`,this.#e.className="card-input card-number-input",this.#e.setAttribute("type","text"),this.#e.setAttribute("inputmode","numeric"),this.#e.setAttribute("autocomplete","cc-number"),this.#e.setAttribute("placeholder","0000 0000 0000 0000"),this.#e.setAttribute("maxlength","23"),this.#e.setAttribute("aria-required","true"),this.#e.setAttribute("aria-describedby",`${this.#w}-number-error`),this.#e.setAttribute("part","number-input"),t&&(this.#e.disabled=!0),this.#h=A.querySelector(".error-container"),this.#h.id=`${this.#w}-number-error`,A.querySelector(".input-wrapper").appendChild(this.#e),v.appendChild(A);let C=document.createElement("div");C.className="field-row";let T=this.#C(`${this.#w}-expiry`);T.querySelector("label").textContent="Expiry date",this.#s=document.createElement("input"),this.#s.id=`${this.#w}-expiry`,this.#s.className="card-input",this.#s.setAttribute("type","text"),this.#s.setAttribute("inputmode","numeric"),this.#s.setAttribute("autocomplete","cc-exp"),this.#s.setAttribute("placeholder","MM/YY"),this.#s.setAttribute("maxlength","5"),this.#s.setAttribute("aria-required","true"),this.#s.setAttribute("aria-describedby",`${this.#w}-expiry-error`),this.#s.setAttribute("part","expiry-input"),t&&(this.#s.disabled=!0),this.#d=T.querySelector(".error-container"),this.#d.id=`${this.#w}-expiry-error`,T.querySelector(".input-wrapper").appendChild(this.#s);let L=this.#C(`${this.#w}-cvc`);L.querySelector("label").textContent="Security code",this.#i=document.createElement("input"),this.#i.id=`${this.#w}-cvc`,this.#i.className="card-input cvc-input",this.#i.setAttribute("type","password"),this.#i.setAttribute("inputmode","numeric"),this.#i.setAttribute("autocomplete","cc-csc"),this.#i.setAttribute("placeholder","\u2022\u2022\u2022"),this.#i.setAttribute("maxlength","4"),this.#i.setAttribute("aria-required","true"),this.#i.setAttribute("aria-describedby",`${this.#w}-cvc-error`),this.#i.setAttribute("part","cvc-input"),t&&(this.#i.disabled=!0),this.#l=L.querySelector(".error-container"),this.#l.id=`${this.#w}-cvc-error`,L.querySelector(".input-wrapper").appendChild(this.#i),C.appendChild(T),C.appendChild(L),v.appendChild(C);let y=this.#C(`${this.#w}-name`);return y.id=`${this.#w}-name-group`,y.querySelector("label").textContent="Cardholder name",i||(y.hidden=!0),this.#r=document.createElement("input"),this.#r.id=`${this.#w}-name`,this.#r.className="card-input",this.#r.setAttribute("type","text"),this.#r.setAttribute("autocomplete","cc-name"),this.#r.setAttribute("placeholder","Name as it appears on card"),this.#r.setAttribute("spellcheck","false"),this.#r.setAttribute("aria-describedby",`${this.#w}-name-error`),this.#r.setAttribute("part","name-input"),t&&(this.#r.disabled=!0),this.#p=y.querySelector(".error-container"),this.#p.id=`${this.#w}-name-error`,y.querySelector(".input-wrapper").appendChild(this.#r),v.appendChild(y),s.appendChild(n),s.appendChild(v),this.#V(),this.addComponentStyles(":host { --secure-card-width: 340px; --secure-card-radius: 16px; --secure-card-font: var(--secure-ui-font-family-mono, 'Courier New', monospace); --secure-card-transition: transform 0.6s cubic-bezier(0.4, 0, 0.2, 1); --secure-card-gradient: linear-gradient(135deg, #1e2a4a 0%, #2d4a8a 100%); display: block; } .card-container { width: 100%; max-width: 480px; font-family: var(--secure-ui-font-family-sans, system-ui, sans-serif); } .card-scene { width: var(--secure-card-width); max-width: 100%; aspect-ratio: 85.6 / 54; perspective: 1000px; margin-inline: auto; margin-block-end: var(--secure-ui-space-6, 1.5rem); user-select: none; } .card { width: 100%; height: 100%; position: relative; transform-style: preserve-3d; transition: var(--secure-card-transition); border-radius: var(--secure-card-radius); filter: drop-shadow(0 8px 24px rgba(0, 0, 0, 0.35)); } .card.is-flipped { transform: rotateY(180deg); } .card-face { position: absolute; inset: 0; border-radius: var(--secure-card-radius); backface-visibility: hidden; -webkit-backface-visibility: hidden; background: var(--secure-card-gradient); color: #fff; overflow: hidden; } .card-face::before { content: ''; position: absolute; inset: 0; background: linear-gradient( 135deg, rgba(255, 255, 255, 0.15) 0%, rgba(255, 255, 255, 0) 60% ); border-radius: inherit; pointer-events: none; } .card-back { transform: rotateY(180deg); } .card--visa { --secure-card-gradient: linear-gradient(135deg, #1a1f71 0%, #2563eb 100%); } .card--mastercard { --secure-card-gradient: linear-gradient(135deg, #1a1a2e 0%, #16213e 50%, #e63946 100%); } .card--amex { --secure-card-gradient: linear-gradient(135deg, #007b5e 0%, #00b894 100%); } .card--discover { --secure-card-gradient: linear-gradient(135deg, #b34700 0%, #e65c00 50%, #f9a825 100%); } .card--diners { --secure-card-gradient: linear-gradient(135deg, #005c97 0%, #363795 100%); } .card--jcb { --secure-card-gradient: linear-gradient(135deg, #0e4c96 0%, #e63946 100%); } .card-front { display: flex; flex-direction: column; justify-content: space-between; padding: 20px 24px 18px; } .card-top-row { display: flex; align-items: center; justify-content: space-between; } .card-chip { width: 42px; height: 32px; background: linear-gradient(135deg, #c8a84b 0%, #f0d060 40%, #c8a84b 100%); border-radius: 5px; position: relative; flex-shrink: 0; } .card-chip::before { content: ''; position: absolute; inset: 9px 0; border-top: 1.5px solid rgba(0, 0, 0, 0.25); border-bottom: 1.5px solid rgba(0, 0, 0, 0.25); } .card-chip::after { content: ''; position: absolute; inset: 0 13px; border-left: 1.5px solid rgba(0, 0, 0, 0.2); border-right: 1.5px solid rgba(0, 0, 0, 0.2); border-radius: 2px; } .card-type-label { font-size: 1rem; font-weight: 700; letter-spacing: 0.06em; font-style: italic; opacity: 0.95; min-width: 52px; text-align: end; text-transform: uppercase; } .card--mastercard .card-type-label { position: relative; width: 52px; height: 32px; font-size: 0; } .card--mastercard .card-type-label::before, .card--mastercard .card-type-label::after { content: ''; position: absolute; top: 50%; transform: translateY(-50%); width: 28px; height: 28px; border-radius: 50%; } .card--mastercard .card-type-label::before { background: #eb001b; inset-inline-start: 0; } .card--mastercard .card-type-label::after { background: #f79e1b; inset-inline-start: 16px; mix-blend-mode: multiply; } .card-number-display { font-family: var(--secure-card-font); font-size: clamp(0.85rem, 2.5vw, 1.1rem); letter-spacing: 0.18em; text-shadow: 0 1px 3px rgba(0, 0, 0, 0.4); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; } .card-bottom-row { display: flex; justify-content: space-between; align-items: flex-end; gap: var(--secure-ui-space-3, 0.75rem); } .card-field-label { font-size: 0.6rem; text-transform: uppercase; letter-spacing: 0.12em; opacity: 0.7; margin-block-end: 2px; } .card-name-display { font-size: clamp(0.7rem, 2vw, 0.85rem); letter-spacing: 0.06em; font-weight: 500; text-transform: uppercase; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; max-width: 160px; } .card-expiry-display { font-family: var(--secure-card-font); font-size: 0.85rem; letter-spacing: 0.1em; white-space: nowrap; } .card-back { display: flex; flex-direction: column; gap: var(--secure-ui-space-3, 0.75rem); } .card-strip { width: 100%; height: 40px; background: #1a1a1a; margin-block-start: 28px; flex-shrink: 0; } .card-cvc-area { display: flex; flex-direction: column; align-items: flex-end; padding-inline-end: 24px; gap: 4px; } .card-cvc-label { font-size: 0.6rem; text-transform: uppercase; letter-spacing: 0.1em; opacity: 0.7; } .card-cvc-display { background: #fff; color: #1a1a1a; font-family: var(--secure-card-font); font-size: 0.85rem; letter-spacing: 0.2em; padding: 4px 10px; border-radius: 3px; min-width: 52px; text-align: center; } .card-fields { display: flex; flex-direction: column; gap: var(--secure-ui-space-4, 1rem); } .card-legend { font-size: var(--secure-ui-font-size-sm, 0.875rem); font-weight: var(--secure-ui-font-weight-semibold, 600); color: var(--secure-ui-color-neutral-700, #374151); margin-block-end: var(--secure-ui-space-1, 0.25rem); } .field-row { display: grid; grid-template-columns: 1fr 1fr; gap: var(--secure-ui-space-4, 1rem); } .field-group { display: flex; flex-direction: column; gap: var(--secure-ui-space-1, 0.25rem); position: relative; } .field-label { font-size: var(--secure-ui-font-size-sm, 0.875rem); font-weight: var(--secure-ui-font-weight-medium, 500); color: var(--secure-ui-color-neutral-700, #374151); line-height: var(--secure-ui-line-height-tight, 1.25); } .input-wrapper { position: relative; } .card-input { width: 100%; box-sizing: border-box; padding: var(--secure-ui-input-padding-y, 0.625rem) var(--secure-ui-input-padding-x, 0.75rem); font-family: var(--secure-ui-font-family-sans, system-ui, sans-serif); font-size: var(--secure-ui-font-size-base, 1rem); line-height: var(--secure-ui-line-height-normal, 1.5); color: var(--secure-ui-input-color, #111827); background: var(--secure-ui-input-bg, #fff); border: var(--secure-ui-border-width, 1px) solid var(--secure-ui-input-border-color, #d1d5db); border-radius: var(--secure-ui-input-border-radius, 6px); outline: none; transition: border-color var(--secure-ui-transition-fast, 150ms) ease, box-shadow var(--secure-ui-transition-fast, 150ms) ease; appearance: none; -webkit-appearance: none; } .card-input:focus { border-color: var(--secure-ui-color-primary-500, #6366f1); box-shadow: 0 0 0 3px var(--secure-ui-color-primary-100, rgba(99, 102, 241, 0.2)); } .card-input[aria-invalid='true'] { border-color: var(--secure-ui-color-error-500, #ef4444) !important; box-shadow: 0 0 0 3px rgba(239, 68, 68, 0.15); } .card-input:disabled { background: var(--secure-ui-input-disabled-bg, #f3f4f6); color: var(--secure-ui-color-neutral-400, #9ca3af); cursor: not-allowed; } .card-number-input { font-family: var(--secure-card-font); letter-spacing: 0.06em; } .cvc-input::-ms-reveal, .cvc-input::-ms-clear { display: none; } .error-container { font-size: var(--secure-ui-font-size-xs, 0.75rem); color: var(--secure-ui-color-error-600, #dc2626); line-height: var(--secure-ui-line-height-tight, 1.25); min-height: 0; max-height: 3rem; overflow: hidden; transition: max-height var(--secure-ui-transition-normal, 250ms) ease, opacity var(--secure-ui-transition-fast, 150ms) ease; opacity: 1; } .error-container.hidden { max-height: 0; opacity: 0; } @media (prefers-color-scheme: dark) { .card-legend { color: var(--secure-ui-color-neutral-200, #e5e7eb); } .field-label { color: var(--secure-ui-color-neutral-200, #e5e7eb); } .card-input { color: var(--secure-ui-input-color, #f9fafb); background: var(--secure-ui-input-bg, #1f2937); border-color: var(--secure-ui-input-border-color, #374151); } .card-input:disabled { background: #111827; color: #6b7280; } .card-cvc-display { background: #f9fafb; color: #111827; } } @media (prefers-reduced-motion: reduce) { .card { transition: none; } .card-input { transition: none; } .error-container { transition: none; } } @media (max-width: 400px) { .field-row { grid-template-columns: 1fr; } }"),this.#e.addEventListener("input",m=>{this.recordTelemetryInput(m),this.#S(m)}),this.#e.addEventListener("focus",()=>{this.recordTelemetryFocus(),this.#k()}),this.#e.addEventListener("blur",()=>{this.recordTelemetryBlur(),this.#z()}),this.#s.addEventListener("input",m=>{this.recordTelemetryInput(m),this.#$(m)}),this.#s.addEventListener("focus",()=>{this.recordTelemetryFocus(),this.#L(!1)}),this.#s.addEventListener("blur",()=>{this.recordTelemetryBlur(),this.#R()}),this.#i.addEventListener("input",m=>{this.recordTelemetryInput(m),this.#M(m)}),this.#i.addEventListener("focus",()=>{this.recordTelemetryFocus(),this.#L(!0)}),this.#i.addEventListener("blur",()=>{this.recordTelemetryBlur(),this.#D()}),this.#r.addEventListener("input",m=>{this.recordTelemetryInput(m),this.#H(m)}),this.#r.addEventListener("focus",()=>{this.recordTelemetryFocus(),this.#L(!1)}),this.#r.addEventListener("blur",()=>{this.recordTelemetryBlur(),this.#P()}),e.appendChild(s),e}#C(e){let t=document.createElement("div");t.className="field-group";let i=document.createElement("label");i.htmlFor=e,i.className="field-label";let r=document.createElement("div");r.className="input-wrapper",r.setAttribute("part","wrapper");let s=document.createElement("div");return s.className="error-container hidden",s.setAttribute("role","alert"),s.setAttribute("part","error"),t.appendChild(i),t.appendChild(r),t.appendChild(s),t}handleAttributeChange(e,t,i){if(this.shadowRoot)switch(e){case"disabled":{let r=i!==null;this.#e&&(this.#e.disabled=r),this.#s&&(this.#s.disabled=r),this.#i&&(this.#i.disabled=r),this.#r&&(this.#r.disabled=r);break}case"show-name":{let r=this.shadowRoot.querySelector(`#${this.#w}-name-group`);r&&(r.hidden=i===null);break}}}#S(e){let t=e.target,i=t.value.replace(/\D/g,""),r=this.#x?.type;this.#x=J(i);let s=this.#x?.format??[4,4,4,4],n=s.reduce((a,o)=>a+o,0);if(this.#m=i.slice(0,n),t.value=x(this.#m,s),this.#x?.type!==r){let a=n+s.length-1;t.setAttribute("maxlength",String(a));let o=this.#x?.cvcLength??3;this.#i&&this.#i.setAttribute("maxlength",String(o)),this.#q()}this.#n&&(this.#n.textContent=t.value||x("\u2022".repeat(n),s)),this.#A(this.#h),this.#N(),this.#F()}#k(){if(this.#e&&this.#m){let e=this.#x?.format??[4,4,4,4],t=x(this.#m,e);this.#e.value=t,this.#n&&(this.#n.textContent=t)}this.#L(!1),this.#A(this.#h)}#z(){let e=this.checkRateLimit();if(!e.allowed){this.#T(this.#h,`Too many attempts. Try again in ${Math.ceil(e.retryAfter/1e3)}s.`);return}this.#m?B(this.#m)?(this.#A(this.#h),this.#e?.removeAttribute("aria-invalid")):(this.#T(this.#h,"Invalid card number"),this.#e?.setAttribute("aria-invalid","true")):(this.#T(this.#h,"Card number is required"),this.#e?.setAttribute("aria-invalid","true")),this.#I(),this.audit("card-number-blur",{cardType:this.#x?.type??"unknown"})}#I(){let e=this.#x?.format??[4,4,4,4],t=X(this.#m,e);this.#e&&(this.#e.value=t),this.#n&&(this.#n.textContent=t)}#$(e){let t=e.target,i=t.value.replace(/\D/g,"").slice(0,4),r=i.length>2?`${i.slice(0,2)}/${i.slice(2)}`:i;t.value=r,this.#v=r,this.#a&&(this.#a.textContent=r||"MM/YY"),this.#A(this.#d),this.#N(),this.#F()}#R(){let e=this.#v.split("/");if(!this.#v){this.#T(this.#d,"Expiry date is required"),this.#s?.setAttribute("aria-invalid","true");return}let t=parseInt(e[0]??"",10),i=parseInt(e[1]??"",10);isNaN(t)||isNaN(i)||t<1||t>12||(e[1]??"").length<2?(this.#T(this.#d,"Enter a valid expiry date (MM/YY)"),this.#s?.setAttribute("aria-invalid","true")):Y(t,i)?(this.#A(this.#d),this.#s?.removeAttribute("aria-invalid")):(this.#T(this.#d,"This card has expired"),this.#s?.setAttribute("aria-invalid","true")),this.audit("card-expiry-blur",{})}#M(e){let t=e.target,i=t.value.replace(/\D/g,""),r=this.#x?.cvcLength??3;this.#g=i.slice(0,r),t.value=this.#g,this.#c&&(this.#c.textContent=this.#g.length>0?"\u2022".repeat(this.#g.length):"\u2022\u2022\u2022"),this.#A(this.#l),this.#F()}#D(){let e=this.#x?.cvcLength??3;this.#g?this.#g.length<e?(this.#T(this.#l,`Security code must be ${e} digits`),this.#i?.setAttribute("aria-invalid","true")):(this.#A(this.#l),this.#i?.removeAttribute("aria-invalid")):(this.#T(this.#l,"Security code is required"),this.#i?.setAttribute("aria-invalid","true")),this.#L(!1),this.audit("card-cvc-blur",{})}#H(e){let t=e.target,i=t.value.replace(/[^a-zA-Z\s\-']/g,"").slice(0,50);t.value=i,this.#E=i,this.#o&&(this.#o.textContent=i.toUpperCase()||"FULL NAME"),this.#A(this.#p),this.#N(),this.#F()}#P(){this.hasAttribute("show-name")&&(this.#E.trim()?(this.#A(this.#p),this.#r?.removeAttribute("aria-invalid")):(this.#T(this.#p,"Cardholder name is required"),this.#r?.setAttribute("aria-invalid","true")))}#L(e){this.#t?.classList.toggle("is-flipped",e)}#q(){if(!this.#t)return;for(let t of U)this.#t.classList.remove(`card--${t.type}`);let e=this.#x?.type;e&&this.#t.classList.add(`card--${e}`),this.#u&&(this.#u.textContent=this.#x?.label??"")}#T(e,t){if(!e)return;e.textContent="";let i=document.createElement("span");i.textContent=t,e.appendChild(i),e.classList.remove("hidden")}#A(e){e&&(e.textContent="",e.classList.add("hidden"))}#V(){let e=this.getAttribute("name");e&&(this.#b=document.createElement("input"),this.#b.type="hidden",this.#b.name=e,this.appendChild(this.#b),this.#f=document.createElement("input"),this.#f.type="hidden",this.#f.name=`${e}-expiry`,this.appendChild(this.#f),this.#y=document.createElement("input"),this.#y.type="hidden",this.#y.name=`${e}-holder`,this.appendChild(this.#y))}#N(){this.#b&&(this.#b.value=this.#m.slice(-4)),this.#f&&(this.#f.value=this.#v),this.#y&&(this.#y.value=this.#E)}#F(){let[e,t]=this.#v.split("/");this.dispatchEvent(new CustomEvent("secure-card",{bubbles:!0,composed:!0,detail:{name:this.getAttribute("name")??"",cardType:this.#x?.type??"unknown",last4:this.#m.slice(-4),expiryMonth:parseInt(e??"0",10)||0,expiryYear:parseInt(t??"0",10)||0,cardholderName:this.#E,valid:this.valid,tier:this.securityTier}}))}disconnectedCallback(){this.#m="",this.#g="",this.#v="",this.#E="",this.#e&&(this.#e.value=""),this.#s&&(this.#s.value=""),this.#i&&(this.#i.value=""),this.#r&&(this.#r.value=""),this.#b&&(this.#b.value=""),this.#f&&(this.#f.value=""),this.#y&&(this.#y.value=""),super.disconnectedCallback()}get valid(){let e=this.#m.length>=12&&B(this.#m),[t,i]=this.#v.split("/"),r=parseInt(t??"",10),s=parseInt(i??"",10),n=!isNaN(r)&&!isNaN(s)&&r>=1&&r<=12&&(i??"").length>=2&&Y(r,s),a=this.#x?.cvcLength??3,o=this.#g.length===a,u=!this.hasAttribute("show-name")||this.#E.trim().length>0;return e&&n&&o&&u}get cardType(){return this.#x?.type??"unknown"}get last4(){return this.#m.slice(-4)}get name(){return this.getAttribute("name")??""}getCardData(){return this.valid?{number:this.#m,expiry:this.#v,cvc:this.#g,name:this.#E}:null}reset(){this.#m="",this.#g="",this.#v="",this.#E="",this.#x=null,this.#e&&(this.#e.value=""),this.#s&&(this.#s.value=""),this.#i&&(this.#i.value=""),this.#r&&(this.#r.value=""),this.#N(),this.#L(!1),this.#q();let e=[4,4,4,4];this.#n&&(this.#n.textContent=x("\u2022".repeat(16),e)),this.#a&&(this.#a.textContent="MM/YY"),this.#o&&(this.#o.textContent="FULL NAME"),this.#c&&(this.#c.textContent="\u2022\u2022\u2022"),this.#A(this.#h),this.#A(this.#d),this.#A(this.#l),this.#A(this.#p),this.audit("card-reset",{})}focus(){this.#e?.focus()}};customElements.define("secure-card",$);var R=class extends HTMLElement{static get observedAttributes(){return["signing-key"]}#e={mouseMovementDetected:!1,keyboardActivityDetected:!1,injectedScriptCount:0,domMutationDetected:!1,pointerType:"none",firstKeystrokeAt:-1,threatSignals:[]};#s=0;#i=null;#r=new Set;#t=null;#n="";#a=()=>{this.#e.mouseMovementDetected=!0};#o=()=>{this.#e.keyboardActivityDetected=!0,this.#e.firstKeystrokeAt<0&&(this.#e.firstKeystrokeAt=performance.now())};#u=e=>{this.#e.pointerType=e.pointerType};#c=e=>{this.#y(e)};#h=e=>{this.#e.threatSignals.push(e.detail)};connectedCallback(){this.#s=performance.now(),document.querySelectorAll("script").forEach(e=>this.#r.add(e)),this.#d(),this.#l()}disconnectedCallback(){this.#i?.disconnect(),this.#i=null,this.#p(),this.#t=null,this.#n=""}attributeChangedCallback(e,t,i){e==="signing-key"&&i!==this.#n&&(this.#t=null,this.#n="")}#d(){this.#i=new MutationObserver(e=>{for(let t of e)if(t.type==="childList")for(let i of Array.from(t.addedNodes))i.tagName==="SCRIPT"&&!this.#r.has(i)&&(this.#e.injectedScriptCount++,this.#e.domMutationDetected=!0,this.#r.add(i))}),this.#i.observe(document.documentElement,{childList:!0,subtree:!0})}#l(){document.addEventListener("mousemove",this.#a,{passive:!0}),document.addEventListener("keydown",this.#o,{passive:!0}),document.addEventListener("pointerdown",this.#u,{passive:!0}),this.addEventListener("secure-form-submit",this.#c),this.addEventListener("secure-threat-detected",this.#h)}#p(){document.removeEventListener("mousemove",this.#a),document.removeEventListener("keydown",this.#o),document.removeEventListener("pointerdown",this.#u),this.removeEventListener("secure-form-submit",this.#c),this.removeEventListener("secure-threat-detected",this.#h)}collectSignals(){let e=navigator,t=e.webdriver===!0||Object.prototype.hasOwnProperty.call(e,"webdriver"),i=navigator.userAgent,r=i.includes("HeadlessChrome")||i.includes("Headless")||typeof window.chrome>"u"&&i.includes("Chrome"),s=screen.width===0||screen.height===0||screen.width<100&&screen.height<100,n=performance.now(),a=this.#e.firstKeystrokeAt>=0?Math.round(this.#e.firstKeystrokeAt-this.#s):-1,o=Math.round(n-this.#s);return{webdriverDetected:t,headlessDetected:r,domMutationDetected:this.#e.domMutationDetected,injectedScriptCount:this.#e.injectedScriptCount,suspiciousScreenSize:s,pointerType:this.#e.pointerType,mouseMovementDetected:this.#e.mouseMovementDetected,keyboardActivityDetected:this.#e.keyboardActivityDetected,pageLoadToFirstKeystroke:a,loadToSubmit:o,threatSignals:this.#e.threatSignals.length>0?[...this.#e.threatSignals]:void 0}}async sign(e){let t=this.#b(),i=new Date().toISOString(),r=this.getAttribute("signing-key")??"",s=`${t}.${i}.${JSON.stringify(e)}`,n=await this.#f(r,s);return{nonce:t,issuedAt:i,environment:e,signature:n}}#b(){let e=new Uint8Array(16);return crypto.getRandomValues(e),Array.from(e,t=>t.toString(16).padStart(2,"0")).join("")}async#f(e,t){if(!crypto.subtle)return"";let i=new TextEncoder;(this.#t===null||this.#n!==e)&&(this.#t=await crypto.subtle.importKey("raw",i.encode(e),{name:"HMAC",hash:"SHA-256"},!1,["sign"]),this.#n=e);let r=await crypto.subtle.sign("HMAC",this.#t,i.encode(t));return Array.from(new Uint8Array(r),s=>s.toString(16).padStart(2,"0")).join("")}async#y(e){let t=e.detail;if(t?.telemetry)try{let i=this.collectSignals(),r=await this.sign(i);t.telemetry._env=r}catch{}}getEnvironmentalSignals(){return this.collectSignals()}};customElements.define("secure-telemetry-provider",R);var P=class extends p{#e=null;#s=null;#i=null;#r=null;#t=null;#n=null;#a=null;#o="";#u="";#c=!1;#h=!1;#d=!1;#l=null;#p=`secure-password-confirm-${Math.random().toString(36).substring(2,11)}`;connectedCallback(){this.removeAttribute("security-tier"),super.connectedCallback()}static get observedAttributes(){return[...super.observedAttributes,"name","label","password-label","confirm-label","required","minlength"]}render(){let e=document.createDocumentFragment(),t=document.createElement("div");t.className="container",t.setAttribute("part","container");let i=this.getAttribute("label");if(i){let a=document.createElement("div");a.className="group-label",a.textContent=this.sanitizeValue(i),t.appendChild(a)}let r=this.hasAttribute("required"),s=this.#b({inputPart:"password-input",wrapperPart:"password-wrapper",labelPart:"password-label",errorPart:"password-error",togglePart:"password-toggle",labelText:this.getAttribute("password-label")??"New Password",inputId:`${this.#p}-password`,errorId:`${this.#p}-password-error`,isRequired:r});this.#e=s.querySelector('[part="password-input"]'),this.#n=s.querySelector('[part="password-toggle"]'),this.#i=s.querySelector('[part="password-error"]');let n=this.#b({inputPart:"confirm-input",wrapperPart:"confirm-wrapper",labelPart:"confirm-label",errorPart:"confirm-error",togglePart:"confirm-toggle",labelText:this.getAttribute("confirm-label")??"Confirm Password",inputId:`${this.#p}-confirm`,errorId:`${this.#p}-confirm-error`,isRequired:r});return this.#s=n.querySelector('[part="confirm-input"]'),this.#a=n.querySelector('[part="confirm-toggle"]'),this.#r=n.querySelector('[part="confirm-error"]'),this.#t=document.createElement("div"),this.#t.setAttribute("part","match-indicator"),this.#t.className="match-indicator",this.#t.setAttribute("aria-hidden","true"),t.appendChild(s),t.appendChild(n),t.appendChild(this.#t),this.#f(),this.#y(),this.#m(),this.#k(),this.addComponentStyles('.container { display: flex; flex-direction: column; gap: var(--secure-ui-form-gap); font-family: var(--secure-ui-font-family-base); } .group-label { font-size: var(--secure-ui-label-font-size); font-weight: var(--secure-ui-label-font-weight); color: var(--secure-ui-label-color); margin-bottom: var(--secure-ui-space-1); } .field-section { display: flex; flex-direction: column; gap: var(--secure-ui-form-label-margin-bottom); } label { font-size: var(--secure-ui-label-font-size); font-weight: var(--secure-ui-label-font-weight); color: var(--secure-ui-label-color); } .input-wrapper { position: relative; display: flex; align-items: center; } input[type="password"], input[type="text"] { flex: 1; height: var(--secure-ui-input-height); padding: var(--secure-ui-input-padding-y) var(--secure-ui-input-padding-x); padding-inline-end: calc(var(--secure-ui-input-padding-x) * 3.5); font-family: var(--secure-ui-font-family-base); font-size: var(--secure-ui-input-font-size); color: var(--secure-ui-input-text-color); background-color: var(--secure-ui-input-bg); border: var(--secure-ui-input-border-width) solid var(--secure-ui-input-border-color); border-radius: var(--secure-ui-input-border-radius); box-sizing: border-box; transition: border-color var(--secure-ui-transition-base), box-shadow var(--secure-ui-transition-base); } input:hover:not(:disabled) { border-color: var(--secure-ui-input-border-color-hover); } input:focus { outline: none; border-color: var(--secure-ui-input-border-color-focus); box-shadow: var(--secure-ui-shadow-focus); } input[aria-invalid="true"] { border-color: var(--secure-ui-color-error) !important; } input[aria-invalid="true"]:focus { box-shadow: var(--secure-ui-shadow-focus-error); } .toggle-btn { position: absolute; inset-inline-end: var(--secure-ui-space-2); display: flex; align-items: center; justify-content: center; background: none; border: none; cursor: pointer; color: var(--secure-ui-color-text-secondary); padding: var(--secure-ui-space-1); border-radius: var(--secure-ui-border-radius-sm); line-height: 1; transition: color var(--secure-ui-transition-base); } .toggle-btn:hover { color: var(--secure-ui-color-text-primary); } .toggle-btn:focus-visible { outline: 2px solid var(--secure-ui-input-border-color-focus); outline-offset: 2px; } .toggle-btn:active .eye-icon { transform: scale(0.85); } .eye-icon { display: block; fill: none; stroke: currentColor; stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; transition: transform 0.15s ease; overflow: visible; } .eye-outline { transition: d 0.2s ease; } .eye-pupil { transform-origin: 12px 12px; transition: opacity 0.2s ease, transform 0.2s ease; } .eye-slash { stroke-dasharray: 26; stroke-dashoffset: 26; transition: stroke-dashoffset 0.3s ease; } .toggle-btn.is-visible .eye-pupil { opacity: 0; transform: scale(0.2); } .toggle-btn.is-visible .eye-slash { stroke-dashoffset: 0; } .error-container { font-size: var(--secure-ui-error-font-size); color: var(--secure-ui-error-color); line-height: var(--secure-ui-line-height-normal); overflow: hidden; max-height: 40px; opacity: 1; transition: all 0.2s ease-in-out; } .error-container.hidden { max-height: 0; opacity: 0; pointer-events: none; } .match-indicator { font-size: var(--secure-ui-font-size-sm); line-height: var(--secure-ui-line-height-normal); min-height: 1.25em; } .match-indicator.matched { color: var(--secure-ui-color-success, #2e7d32); } .match-indicator.mismatched { color: var(--secure-ui-color-error); } @media (prefers-reduced-motion: reduce) { input, .error-container, .eye-icon, .eye-pupil, .eye-slash { transition: none !important; } }'),e.appendChild(t),e}#b(e){let t=document.createElement("div");t.className="field-section";let i=document.createElement("label");i.setAttribute("part",e.labelPart),i.htmlFor=e.inputId,i.textContent=this.sanitizeValue(e.labelText);let r=document.createElement("div");r.className="input-wrapper",r.setAttribute("part",e.wrapperPart);let s=document.createElement("input");s.id=e.inputId,s.type="password",s.autocomplete="new-password",s.setAttribute("part",e.inputPart),s.setAttribute("aria-describedby",e.errorId),e.isRequired&&(s.required=!0,s.setAttribute("aria-required","true"));let n=document.createElement("button");n.type="button",n.className="toggle-btn",n.setAttribute("part",e.togglePart),n.setAttribute("aria-label","Show password"),n.appendChild(this.#g()),r.appendChild(s),r.appendChild(n);let a=document.createElement("div");return a.id=e.errorId,a.setAttribute("part",e.errorPart),a.setAttribute("role","alert"),a.className="error-container hidden",t.appendChild(i),t.appendChild(r),t.appendChild(a),t}#f(){this.#e.addEventListener("focus",()=>{this.recordTelemetryFocus()}),this.#e.addEventListener("input",e=>{this.recordTelemetryInput(e),this.#o=this.#e.value,this.detectInjection(this.#o,this.getAttribute("name")??""),this.#c&&this.#x(),this.dispatchEvent(new CustomEvent("secure-input",{detail:{name:this.getAttribute("name")??"",field:"password"},bubbles:!0,composed:!0}))}),this.#e.addEventListener("blur",()=>{this.recordTelemetryBlur(),this.#v()})}#y(){this.#s.addEventListener("input",()=>{this.#u=this.#s.value,this.detectInjection(this.#u,this.getAttribute("name")??""),this.#c&&this.#x()}),this.#s.addEventListener("blur",()=>{this.#c=!0,this.#u=this.#s.value,this.#x()})}#m(){this.#n.addEventListener("click",()=>{this.#h=!this.#h,this.#e.type=this.#h?"text":"password",this.#n.classList.toggle("is-visible",this.#h),this.#n.setAttribute("aria-label",this.#h?"Hide password":"Show password")}),this.#a.addEventListener("click",()=>{this.#d=!this.#d,this.#s.type=this.#d?"text":"password",this.#a.classList.toggle("is-visible",this.#d),this.#a.setAttribute("aria-label",this.#d?"Hide confirm password":"Show confirm password")})}#g(){let e="http://www.w3.org/2000/svg",t=document.createElementNS(e,"svg");t.setAttribute("viewBox","0 0 24 24"),t.setAttribute("aria-hidden","true"),t.setAttribute("class","eye-icon"),t.setAttribute("width","18"),t.setAttribute("height","18");let i=document.createElementNS(e,"path");i.setAttribute("class","eye-outline"),i.setAttribute("d","M1 12s4-8 11-8 11 8 11 8-4 8-11 8-11-8-11-8z");let r=document.createElementNS(e,"circle");r.setAttribute("class","eye-pupil"),r.setAttribute("cx","12"),r.setAttribute("cy","12"),r.setAttribute("r","3");let s=document.createElementNS(e,"line");return s.setAttribute("class","eye-slash"),s.setAttribute("x1","3"),s.setAttribute("y1","3"),s.setAttribute("x2","21"),s.setAttribute("y2","21"),t.append(i,r,s),t}#v(){let e=this.#E(this.#o);e?this.#w(this.#i,this.#e,e):this.#C(this.#i,this.#e)}#E(e){return e?e.length<8?"Password must be at least 8 characters":/[a-z]/.test(e)?/[A-Z]/.test(e)?/[0-9]/.test(e)?/[^a-zA-Z0-9]/.test(e)?null:"Password must include a special character":"Password must include a number":"Password must include an uppercase letter":"Password must include a lowercase letter":null}#x(){let e=this.#o.length>0&&this.#o===this.#u;if(this.#z(e),this.#S(e),e)this.#C(this.#r,this.#s),this.dispatchEvent(new CustomEvent("secure-password-match",{detail:{name:this.getAttribute("name")??"",matched:!0},bubbles:!0,composed:!0}));else{let t=this.#u.length>0?"Passwords do not match":"Please confirm your password";this.#w(this.#r,this.#s,t),this.dispatchEvent(new CustomEvent("secure-password-mismatch",{detail:{name:this.getAttribute("name")??"",matched:!1},bubbles:!0,composed:!0}))}}#w(e,t,i){e.textContent=i,e.classList.remove("hidden"),t.setAttribute("aria-invalid","true")}#C(e,t){e.classList.add("hidden"),e.textContent="",t.removeAttribute("aria-invalid")}#S(e){this.#t&&(this.#t.className=`match-indicator ${e?"matched":"mismatched"}`,this.#t.textContent=e?"\u2713 Passwords match":"\u2717 Passwords do not match")}#k(){let e=this.getAttribute("name");!e||this.closest("secure-form")||(this.#l=document.createElement("input"),this.#l.type="hidden",this.#l.name=e,this.#l.value="",this.appendChild(this.#l))}#z(e){this.#l&&(this.#l.value=e?this.#o:"")}getPasswordValue(){return!this.#o||!this.#u||this.#o!==this.#u?null:this.#o}get valid(){return!this.#o||!this.#u||this.#o!==this.#u?!1:this.#E(this.#o)===null}get name(){return this.getAttribute("name")??""}disconnectedCallback(){super.disconnectedCallback(),this.#o="",this.#u="",this.#e&&(this.#e.value=""),this.#s&&(this.#s.value=""),this.#l&&(this.#l.value="")}};customElements.define("secure-password-confirm",P);export{Z as CSP_RECOMMENDATIONS,G as SECURITY_HEADERS,p as SecureBaseComponent,$ as SecureCard,H as SecureDateTime,D as SecureFileUpload,M as SecureForm,k as SecureInput,P as SecurePasswordConfirm,I as SecureSelect,F as SecureSubmitButton,N as SecureTable,R as SecureTelemetryProvider,z as SecureTextarea,c as SecurityTier,S as TIER_CONFIG,O as compareTiers,W as getMoreSecureTier,g as getTierConfig,_ as isValidTier};
67
- /**
68
- * @fileoverview Security Configuration and Tier Definitions
69
- *
70
- * This module defines the four security tiers that govern all component behavior
71
- * in the Secure-UI library. Each tier represents a different level of data sensitivity
72
- * and applies corresponding security controls.
73
- *
74
- * Security Philosophy:
75
- * - Defense in depth: Multiple layers of protection at each tier
76
- * - Fail secure: Default to highest security when tier is ambiguous
77
- * - Progressive enhancement: All tiers work without JavaScript
78
- * - Zero trust: Always validate, never assume data is safe
79
- *
80
- * @module security-config
81
- * @license MIT
82
- */
83
- /**
84
- * @fileoverview Base Component Class for Secure-UI
85
- *
86
- * This module provides the foundational class that all Secure-UI web components
87
- * extend. It implements core security features, progressive enhancement,
88
- * and standardized lifecycle management.
89
- *
90
- * Security Features:
91
- * - Closed Shadow DOM (prevents external JavaScript access)
92
- * - Automatic XSS sanitization
93
- * - Security tier enforcement
94
- * - Audit logging infrastructure
95
- * - Rate limiting support
96
- * - Progressive enhancement (works without JS)
97
- *
98
- * @module base-component
99
- * @license MIT
100
- */
101
- /**
102
- * @fileoverview Secure Input Component
103
- *
104
- * A security-first input field component that implements progressive enhancement,
105
- * tier-based validation, masking, and audit logging.
106
- *
107
- * Progressive Enhancement Strategy:
108
- * 1. Without JavaScript: Falls back to native HTML5 input with attributes
109
- * 2. With JavaScript: Enhances with masking, real-time validation, rate limiting
110
- *
111
- * Usage:
112
- * <secure-input
113
- * security-tier="critical"
114
- * name="password"
115
- * label="Password"
116
- * type="password"
117
- * required
118
- * ></secure-input>
119
- *
120
- * Security Features:
121
- * - XSS prevention via sanitization
122
- * - Configurable masking based on security tier
123
- * - Rate limiting for sensitive/critical tiers
124
- * - Autocomplete control based on tier
125
- * - Comprehensive audit logging
126
- * - Visual security indicators
127
- *
128
- * @module secure-input
129
- * @license MIT
130
- */
131
- /**
132
- * @fileoverview Secure Textarea Component
133
- *
134
- * A security-first textarea component that implements progressive enhancement,
135
- * tier-based validation, character counting, and audit logging.
136
- *
137
- * Progressive Enhancement Strategy:
138
- * 1. Without JavaScript: Falls back to native HTML5 textarea with attributes
139
- * 2. With JavaScript: Enhances with real-time validation, character limits, rate limiting
140
- *
141
- * Usage:
142
- * <secure-textarea
143
- * security-tier="sensitive"
144
- * name="bio"
145
- * label="Biography"
146
- * rows="5"
147
- * required
148
- * ></secure-textarea>
149
- *
150
- * Security Features:
151
- * - XSS prevention via sanitization
152
- * - Character counting and limits based on security tier
153
- * - Rate limiting for sensitive/critical tiers
154
- * - Autocomplete control based on tier
155
- * - Comprehensive audit logging
156
- * - Visual security indicators
157
- *
158
- * @module secure-textarea
159
- * @license MIT
160
- */
161
- /**
162
- * @fileoverview Secure Select Component
163
- *
164
- * A security-first select dropdown component that implements progressive enhancement,
165
- * tier-based validation, and audit logging.
166
- *
167
- * Progressive Enhancement Strategy:
168
- * 1. Without JavaScript: Falls back to native HTML5 select with options
169
- * 2. With JavaScript: Enhances with validation, audit logging, rate limiting
170
- *
171
- * Usage:
172
- * <secure-select
173
- * security-tier="authenticated"
174
- * name="country"
175
- * label="Country"
176
- * required
177
- * >
178
- * <option value="">Select a country</option>
179
- * <option value="us">United States</option>
180
- * <option value="uk">United Kingdom</option>
181
- * </secure-select>
182
- *
183
- * Multiple selection:
184
- * <secure-select label="Languages" name="langs" multiple size="4">
185
- * <option value="en">English</option>
186
- * <option value="es">Spanish</option>
187
- * </secure-select>
188
- *
189
- * Security Features:
190
- * - XSS prevention via sanitization
191
- * - Option value validation
192
- * - Rate limiting for sensitive/critical tiers
193
- * - Comprehensive audit logging
194
- * - Visual security indicators
195
- *
196
- * @module secure-select
197
- * @license MIT
198
- */
199
- /**
200
- * @fileoverview Secure Form Component
201
- *
202
- * A security-first form component that implements CSRF protection, automatic
203
- * field collection, validation, and comprehensive audit logging.
204
- *
205
- * Progressive Enhancement Strategy:
206
- * 1. Without JavaScript: Falls back to native HTML5 form submission
207
- * 2. With JavaScript: Enhances with CSRF tokens, validation, secure submission
208
- *
209
- * Usage:
210
- * <secure-form
211
- * security-tier="sensitive"
212
- * action="/api/submit"
213
- * method="POST"
214
- * csrf-token="your-csrf-token"
215
- * >
216
- * <secure-input name="email" label="Email" required></secure-input>
217
- * <button type="submit">Submit</button>
218
- * </secure-form>
219
- *
220
- * Security Features:
221
- * - CSRF token injection and validation
222
- * - Automatic secure field collection
223
- * - XSS prevention via sanitization
224
- * - Rate limiting on submission
225
- * - Comprehensive audit logging
226
- * - Secure headers for form submission
227
- * - Double-submit cookie pattern support
228
- *
229
- * @module secure-form
230
- * @license MIT
231
- */
66
+ `;return s}#A(){let e=this.shadowRoot.getElementById("searchInput");e&&e.addEventListener("input",t=>{this.#l(t.target.value)}),this.#T()}#T(){this.shadowRoot.querySelectorAll("th.sortable").forEach(n=>{n.addEventListener("click",()=>{let a=n.getAttribute("data-column");a&&this.#p(a)})});let t=this.shadowRoot.getElementById("prevBtn"),i=this.shadowRoot.getElementById("nextBtn");t&&t.addEventListener("click",()=>{this.#d(this.#n.currentPage-1)}),i&&i.addEventListener("click",()=>{this.#d(this.#n.currentPage+1)}),this.shadowRoot.querySelectorAll(".pagination-button[data-page]").forEach(n=>{n.addEventListener("click",()=>{let a=parseInt(n.getAttribute("data-page"),10);this.#d(a)})});let s=this.shadowRoot.getElementById("tableContent");s&&s.addEventListener("click",n=>{let a=n.target.closest("[data-action]");if(!a)return;let o=a.getAttribute("data-action"),d=Object.create(null);d.action=o;for(let c of Array.from(a.attributes))if(c.name.startsWith("data-")&&c.name!=="data-action"){let m=c.name.slice(5).replace(/-([a-z])/g,(g,b)=>b.toUpperCase());if(m==="__proto__"||m==="constructor"||m==="prototype")continue;d[m]=c.value}this.dispatchEvent(new CustomEvent("secure-table-action",{bubbles:!0,composed:!0,detail:d})),this.audit("table_action",d)})}};customElements.define("secure-table",$);function j(l){if(l===null)return!1;let e=l;return typeof e.securityTier=="string"&&typeof e.valid=="boolean"&&typeof e.submit=="function"}var R=class extends p{#e=null;#t=null;#i=null;#s=null;#r=!1;#n=!1;#a="critical";#o;#c=`secure-submit-button-${Math.random().toString(36).substring(2,11)}`;#l;#p;#d;static get observedAttributes(){return[...super.observedAttributes,"label","loading-label","disabled"]}constructor(){super(),this.#o=v(this.#a),this.#l=this.#w.bind(this),this.#p=this.#E.bind(this),this.#d=()=>{this.#f(!1)}}connectedCallback(){super.connectedCallback(),queueMicrotask(()=>{this.#u(),this.#h(),this.#y(),this.#x(),this.audit("submit_button_initialized",{tier:this.#a,hasParentForm:!!this.#s})})}render(){let e=document.createDocumentFragment(),t=document.createElement("div");t.className="submit-container";let i=`${this.#c}-hint`,r=document.createElement("p");r.id=i,r.className="sr-only",r.textContent="Complete all required fields to enable this button",t.appendChild(r),this.#e=document.createElement("button"),this.#e.type="button",this.#e.className="submit-btn",this.#e.disabled=!0,this.#e.setAttribute("aria-disabled","true"),this.#e.setAttribute("aria-describedby",i),this.#t=document.createElement("span"),this.#t.className="btn-label",this.#t.textContent=this.sanitizeValue(this.getAttribute("label")||"Submit"),this.#i=document.createElement("span"),this.#i.className="btn-loading hidden",this.#i.setAttribute("aria-hidden","true");let s=document.createElement("span");s.className="spinner";let n=document.createElement("span");return n.textContent=this.sanitizeValue(this.getAttribute("loading-label")||"Submitting..."),this.#i.appendChild(s),this.#i.appendChild(n),this.#e.appendChild(this.#t),this.#e.appendChild(this.#i),this.#e.addEventListener("click",this.#p),t.appendChild(this.#e),e.appendChild(t),this.addComponentStyles(this.#b()),e}#u(){this.#s=this.closest("secure-form")}#h(){!this.getAttribute("security-tier")&&j(this.#s)?this.#a=this.#s.securityTier:this.#a=this.securityTier,this.#o=v(this.#a)}#y(){let e=this.#s||this.parentElement;e&&(e.addEventListener("secure-input-change",this.#l),e.addEventListener("secure-textarea-change",this.#l),e.addEventListener("secure-select-change",this.#l),e.addEventListener("secure-datetime-change",this.#l),e.addEventListener("secure-form-success",this.#d))}#w(e){this.#x()}#x(){if(this.hasAttribute("disabled")){this.#v(!0);return}if(!this.#n){if(!this.#o.validation.required){this.#r=!0,this.#v(!1);return}j(this.#s)?this.#r=this.#s.valid:this.#r=this.#g(),this.#v(!this.#r)}}#g(){let e=this.#s||this.parentElement;if(!e)return!1;let t=e.querySelectorAll("secure-input, secure-textarea, secure-select, secure-datetime, secure-file-upload");for(let i of t){let r=i;if(typeof r.valid=="boolean"&&!r.valid)return!1}return t.length>0}#v(e){this.#e&&(this.#e.disabled=e,this.#e.setAttribute("aria-disabled",String(e)))}#E(){if(this.#n||this.#e?.disabled)return;let e=this.checkRateLimit();if(!e.allowed){this.audit("submit_button_rate_limited",{retryAfter:e.retryAfter});return}this.audit("submit_button_clicked",{tier:this.#a,formValid:this.#r}),this.#f(!0),j(this.#s)?this.#s.submit():this.#f(!1)}#f(e){this.#n=e,this.#e&&(this.#e.disabled=e,this.#e.setAttribute("aria-disabled",String(e))),this.#t&&this.#t.classList.toggle("hidden",e),this.#i&&(this.#i.classList.toggle("hidden",!e),this.#i.setAttribute("aria-hidden",String(!e)))}handleAttributeChange(e,t,i){switch(e){case"label":this.#t&&(this.#t.textContent=this.sanitizeValue(i||"Submit"));break;case"loading-label":if(this.#i){let r=this.#i.querySelector("span:last-child");r&&(r.textContent=this.sanitizeValue(i||"Submitting..."))}break;case"disabled":this.#x();break}}get disabled(){return this.#e?this.#e.disabled:!0}set disabled(e){e?this.setAttribute("disabled",""):this.removeAttribute("disabled"),this.#x()}get label(){return this.getAttribute("label")||"Submit"}set label(e){this.setAttribute("label",e)}#b(){return":host { display: inline-block; } .submit-container { margin-top: 8px; position: relative; } .submit-btn { display: inline-flex; align-items: center; justify-content: center; gap: var(--secure-ui-space-2); padding: var(--secure-ui-button-padding-y) var(--secure-ui-button-padding-x); min-height: var(--secure-ui-button-height); font-family: inherit; font-size: var(--secure-ui-font-size-sm); font-weight: var(--secure-ui-button-font-weight); line-height: 1; border-radius: var(--secure-ui-button-border-radius); border: var(--secure-ui-border-width-base) solid transparent; cursor: pointer; transition: background-color var(--secure-ui-transition-base) var(--secure-ui-transition-ease-out), border-color var(--secure-ui-transition-base) var(--secure-ui-transition-ease-out), opacity var(--secure-ui-transition-base) var(--secure-ui-transition-ease-out), box-shadow var(--secure-ui-transition-base) var(--secure-ui-transition-ease-out), color var(--secure-ui-transition-base) var(--secure-ui-transition-ease-out), transform var(--secure-ui-transition-fast) var(--secure-ui-transition-ease-out); background-color: var(--secure-ui-color-info); color: var(--secure-ui-color-text-inverse); user-select: none; } .submit-btn:hover:not(:disabled) { background-color: color-mix(in srgb, var(--secure-ui-color-info) 82%, black); transform: translateY(-1px); box-shadow: 0 2px 8px rgba(59, 130, 246, 0.25); } .submit-btn:focus-visible { outline: 2px solid var(--secure-ui-color-info); outline-offset: 2px; box-shadow: 0 0 0 3px rgba(59, 130, 246, 0.3); } @media (forced-colors: active) { .submit-btn:focus-visible { outline: 2px solid ButtonText; box-shadow: none; } } .submit-btn:active:not(:disabled) { background-color: color-mix(in srgb, var(--secure-ui-color-info) 72%, black); transform: scale(0.98); box-shadow: none; } .submit-btn:disabled { background-color: var(--secure-ui-color-bg-disabled); color: var(--secure-ui-color-text-disabled); border-color: var(--secure-ui-color-border); cursor: not-allowed; opacity: 0.7; transform: none; box-shadow: none; } .sr-only { position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px; overflow: hidden; clip: rect(0, 0, 0, 0); white-space: nowrap; border: 0; } .btn-label, .btn-loading { display: inline-flex; align-items: center; gap: 8px; transition: opacity 0.2s ease-out; } .btn-label.hidden, .btn-loading.hidden { display: none; } .spinner { display: inline-block; width: 14px; height: 14px; border: 2px solid currentColor; border-right-color: transparent; border-radius: 50%; animation: spin 0.6s linear infinite; } @keyframes spin { to { transform: rotate(360deg); } } @media (prefers-reduced-motion: reduce) { .submit-btn { transition: none !important; } .btn-label, .btn-loading { transition: none !important; } .spinner { animation: none; border-right-color: currentColor; opacity: 0.5; } }"}disconnectedCallback(){super.disconnectedCallback(),this.#f(!1);let e=this.#s||this.parentElement;e&&(e.removeEventListener("secure-input-change",this.#l),e.removeEventListener("secure-textarea-change",this.#l),e.removeEventListener("secure-select-change",this.#l),e.removeEventListener("secure-datetime-change",this.#l),e.removeEventListener("secure-form-success",this.#d))}};customElements.define("secure-submit-button",R);var W=Object.freeze([{type:"amex",pattern:/^3[47]/,format:[4,6,5],cvcLength:4,lengths:[15],label:"Amex"},{type:"diners",pattern:/^3(?:0[0-5]|[68])/,format:[4,6,4],cvcLength:3,lengths:[14],label:"Diners"},{type:"discover",pattern:/^6(?:011|5[0-9]{2})/,format:[4,4,4,4],cvcLength:3,lengths:[16],label:"Discover"},{type:"jcb",pattern:/^(?:2131|1800|35\d{3})/,format:[4,4,4,4],cvcLength:3,lengths:[16],label:"JCB"},{type:"mastercard",pattern:/^(?:5[1-5]|2[2-7])/,format:[4,4,4,4],cvcLength:3,lengths:[16],label:"Mastercard"},{type:"visa",pattern:/^4/,format:[4,4,4,4],cvcLength:3,lengths:[13,16,19],label:"Visa"}]);function Z(l){return l?W.find(e=>e.pattern.test(l))??null:null}function E(l,e){let t="",i=0;for(let r=0;r<e.length;r++){let s=l.slice(i,i+e[r]);if(!s)break;r>0&&(t+=" "),t+=s,i+=e[r]}return t}function X(l,e){let t=e.reduce((n,a)=>n+a,0);if(!l)return E("\u2022".repeat(t),e);let i=l.padEnd(t,"\u2022").slice(0,t),r=Math.max(0,i.length-4),s="\u2022".repeat(r)+i.slice(r);return E(s,e)}function Y(l){if(!l||l.length<12)return!1;let e=0,t=!1;for(let i=l.length-1;i>=0;i--){let r=l[i];if(!r)return!1;let s=parseInt(r,10);if(isNaN(s))return!1;let n=s;t&&(n*=2,n>9&&(n-=9)),e+=n,t=!t}return e%10===0}function U(l,e){let t=new Date,i=t.getFullYear()%100,r=t.getMonth()+1;return!(e<i||e===i&&l<r)}var J=0,P=class extends p{#e=null;#t=null;#i=null;#s=null;#r=null;#n=null;#a=null;#o=null;#c=null;#l=null;#p=null;#d=null;#u=null;#h=null;#y=null;#w=null;#x=null;#g="";#v="";#E="";#f="";#b=null;#m;constructor(){super(),this.#m=`secure-card-${++J}`}static get observedAttributes(){return[...super.observedAttributes,"name","label","show-name"]}render(){let e=document.createDocumentFragment(),t=this.hasAttribute("disabled"),i=this.hasAttribute("show-name"),r=this.getAttribute("label")??"",s=document.createElement("div");s.className="card-container",s.setAttribute("part","container");let n=document.createElement("div");n.className="card-scene",n.setAttribute("aria-hidden","true"),this.#r=document.createElement("div"),this.#r.className="card";let a=document.createElement("div");a.className="card-face card-front";let o=document.createElement("div");o.className="card-top-row";let d=document.createElement("div");d.className="card-chip",this.#c=document.createElement("div"),this.#c.className="card-type-label",o.appendChild(d),o.appendChild(this.#c),a.appendChild(o),this.#n=document.createElement("div"),this.#n.className="card-number-display",this.#n.textContent="\u2022\u2022\u2022\u2022 \u2022\u2022\u2022\u2022 \u2022\u2022\u2022\u2022 \u2022\u2022\u2022\u2022",a.appendChild(this.#n);let c=document.createElement("div");c.className="card-bottom-row";let m=document.createElement("div");m.className="card-name-section";let g=document.createElement("div");g.className="card-field-label",g.textContent="Card holder",this.#o=document.createElement("div"),this.#o.className="card-name-display",this.#o.textContent="FULL NAME",m.appendChild(g),m.appendChild(this.#o);let b=document.createElement("div");b.className="card-expiry-section";let h=document.createElement("div");h.className="card-field-label",h.textContent="Expires",this.#a=document.createElement("div"),this.#a.className="card-expiry-display",this.#a.textContent="MM/YY",b.appendChild(h),b.appendChild(this.#a),c.appendChild(m),c.appendChild(b),a.appendChild(c);let C=document.createElement("div");C.className="card-face card-back";let O=document.createElement("div");O.className="card-strip";let T=document.createElement("div");T.className="card-cvc-area";let _=document.createElement("div");_.className="card-cvc-label",_.textContent="CVC",this.#l=document.createElement("div"),this.#l.className="card-cvc-display",this.#l.textContent="\u2022\u2022\u2022",T.appendChild(_),T.appendChild(this.#l),C.appendChild(O),C.appendChild(T),this.#r.appendChild(a),this.#r.appendChild(C),n.appendChild(this.#r);let y=document.createElement("div");if(y.className="card-fields",r){let f=document.createElement("div");f.className="card-legend",f.setAttribute("part","label"),f.textContent=this.sanitizeValue(r),y.appendChild(f)}let L=this.#A(`${this.#m}-number`),K=L.querySelector("label");K.textContent="Card number",this.#e=document.createElement("input"),this.#e.id=`${this.#m}-number`,this.#e.className="card-input card-number-input",this.#e.setAttribute("type","text"),this.#e.setAttribute("inputmode","numeric"),this.#e.setAttribute("autocomplete","cc-number"),this.#e.setAttribute("placeholder","0000 0000 0000 0000"),this.#e.setAttribute("maxlength","23"),this.#e.setAttribute("aria-required","true"),this.#e.setAttribute("aria-describedby",`${this.#m}-number-error`),this.#e.setAttribute("part","number-input"),t&&(this.#e.disabled=!0),this.#p=L.querySelector(".error-container"),this.#p.id=`${this.#m}-number-error`,L.querySelector(".input-wrapper").appendChild(this.#e),y.appendChild(L);let S=document.createElement("div");S.className="field-row";let k=this.#A(`${this.#m}-expiry`);k.querySelector("label").textContent="Expiry date",this.#t=document.createElement("input"),this.#t.id=`${this.#m}-expiry`,this.#t.className="card-input",this.#t.setAttribute("type","text"),this.#t.setAttribute("inputmode","numeric"),this.#t.setAttribute("autocomplete","cc-exp"),this.#t.setAttribute("placeholder","MM/YY"),this.#t.setAttribute("maxlength","5"),this.#t.setAttribute("aria-required","true"),this.#t.setAttribute("aria-describedby",`${this.#m}-expiry-error`),this.#t.setAttribute("part","expiry-input"),t&&(this.#t.disabled=!0),this.#d=k.querySelector(".error-container"),this.#d.id=`${this.#m}-expiry-error`,k.querySelector(".input-wrapper").appendChild(this.#t);let z=this.#A(`${this.#m}-cvc`);z.querySelector("label").textContent="Security code",this.#i=document.createElement("input"),this.#i.id=`${this.#m}-cvc`,this.#i.className="card-input cvc-input",this.#i.setAttribute("type","password"),this.#i.setAttribute("inputmode","numeric"),this.#i.setAttribute("autocomplete","cc-csc"),this.#i.setAttribute("placeholder","\u2022\u2022\u2022"),this.#i.setAttribute("maxlength","4"),this.#i.setAttribute("aria-required","true"),this.#i.setAttribute("aria-describedby",`${this.#m}-cvc-error`),this.#i.setAttribute("part","cvc-input"),t&&(this.#i.disabled=!0),this.#u=z.querySelector(".error-container"),this.#u.id=`${this.#m}-cvc-error`,z.querySelector(".input-wrapper").appendChild(this.#i),S.appendChild(k),S.appendChild(z),y.appendChild(S);let x=this.#A(`${this.#m}-name`);return x.id=`${this.#m}-name-group`,x.querySelector("label").textContent="Cardholder name",i||(x.hidden=!0),this.#s=document.createElement("input"),this.#s.id=`${this.#m}-name`,this.#s.className="card-input",this.#s.setAttribute("type","text"),this.#s.setAttribute("autocomplete","cc-name"),this.#s.setAttribute("placeholder","Name as it appears on card"),this.#s.setAttribute("spellcheck","false"),this.#s.setAttribute("aria-describedby",`${this.#m}-name-error`),this.#s.setAttribute("part","name-input"),t&&(this.#s.disabled=!0),this.#h=x.querySelector(".error-container"),this.#h.id=`${this.#m}-name-error`,x.querySelector(".input-wrapper").appendChild(this.#s),y.appendChild(x),s.appendChild(n),s.appendChild(y),this.#V(),this.addComponentStyles(":host { --secure-card-width: 340px; --secure-card-radius: 16px; --secure-card-font: var(--secure-ui-font-family-mono, 'Courier New', monospace); --secure-card-transition: transform 0.6s cubic-bezier(0.4, 0, 0.2, 1); --secure-card-gradient: linear-gradient(135deg, #1e2a4a 0%, #2d4a8a 100%); display: block; } .card-container { width: 100%; max-width: 480px; font-family: var(--secure-ui-font-family-sans, system-ui, sans-serif); } .card-scene { width: var(--secure-card-width); max-width: 100%; aspect-ratio: 85.6 / 54; perspective: 1000px; margin-inline: auto; margin-block-end: var(--secure-ui-space-6, 1.5rem); user-select: none; } .card { width: 100%; height: 100%; position: relative; transform-style: preserve-3d; transition: var(--secure-card-transition); border-radius: var(--secure-card-radius); filter: drop-shadow(0 8px 24px rgba(0, 0, 0, 0.35)); } .card.is-flipped { transform: rotateY(180deg); } .card-face { position: absolute; inset: 0; border-radius: var(--secure-card-radius); backface-visibility: hidden; -webkit-backface-visibility: hidden; background: var(--secure-card-gradient); color: #fff; overflow: hidden; } .card-face::before { content: ''; position: absolute; inset: 0; background: linear-gradient( 135deg, rgba(255, 255, 255, 0.15) 0%, rgba(255, 255, 255, 0) 60% ); border-radius: inherit; pointer-events: none; } .card-back { transform: rotateY(180deg); } .card--visa { --secure-card-gradient: linear-gradient(135deg, #1a1f71 0%, #2563eb 100%); } .card--mastercard { --secure-card-gradient: linear-gradient(135deg, #1a1a2e 0%, #16213e 50%, #e63946 100%); } .card--amex { --secure-card-gradient: linear-gradient(135deg, #007b5e 0%, #00b894 100%); } .card--discover { --secure-card-gradient: linear-gradient(135deg, #b34700 0%, #e65c00 50%, #f9a825 100%); } .card--diners { --secure-card-gradient: linear-gradient(135deg, #005c97 0%, #363795 100%); } .card--jcb { --secure-card-gradient: linear-gradient(135deg, #0e4c96 0%, #e63946 100%); } .card-front { display: flex; flex-direction: column; justify-content: space-between; padding: 20px 24px 18px; } .card-top-row { display: flex; align-items: center; justify-content: space-between; } .card-chip { width: 42px; height: 32px; background: linear-gradient(135deg, #c8a84b 0%, #f0d060 40%, #c8a84b 100%); border-radius: 5px; position: relative; flex-shrink: 0; } .card-chip::before { content: ''; position: absolute; inset: 9px 0; border-top: 1.5px solid rgba(0, 0, 0, 0.25); border-bottom: 1.5px solid rgba(0, 0, 0, 0.25); } .card-chip::after { content: ''; position: absolute; inset: 0 13px; border-left: 1.5px solid rgba(0, 0, 0, 0.2); border-right: 1.5px solid rgba(0, 0, 0, 0.2); border-radius: 2px; } .card-type-label { font-size: 1rem; font-weight: 700; letter-spacing: 0.06em; font-style: italic; opacity: 0.95; min-width: 52px; text-align: end; text-transform: uppercase; } .card--mastercard .card-type-label { position: relative; width: 52px; height: 32px; font-size: 0; } .card--mastercard .card-type-label::before, .card--mastercard .card-type-label::after { content: ''; position: absolute; top: 50%; transform: translateY(-50%); width: 28px; height: 28px; border-radius: 50%; } .card--mastercard .card-type-label::before { background: #eb001b; inset-inline-start: 0; } .card--mastercard .card-type-label::after { background: #f79e1b; inset-inline-start: 16px; mix-blend-mode: multiply; } .card-number-display { font-family: var(--secure-card-font); font-size: clamp(0.85rem, 2.5vw, 1.1rem); letter-spacing: 0.18em; text-shadow: 0 1px 3px rgba(0, 0, 0, 0.4); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; } .card-bottom-row { display: flex; justify-content: space-between; align-items: flex-end; gap: var(--secure-ui-space-3, 0.75rem); } .card-field-label { font-size: 0.6rem; text-transform: uppercase; letter-spacing: 0.12em; opacity: 0.7; margin-block-end: 2px; } .card-name-display { font-size: clamp(0.7rem, 2vw, 0.85rem); letter-spacing: 0.06em; font-weight: 500; text-transform: uppercase; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; max-width: 160px; } .card-expiry-display { font-family: var(--secure-card-font); font-size: 0.85rem; letter-spacing: 0.1em; white-space: nowrap; } .card-back { display: flex; flex-direction: column; gap: var(--secure-ui-space-3, 0.75rem); } .card-strip { width: 100%; height: 40px; background: #1a1a1a; margin-block-start: 28px; flex-shrink: 0; } .card-cvc-area { display: flex; flex-direction: column; align-items: flex-end; padding-inline-end: 24px; gap: 4px; } .card-cvc-label { font-size: 0.6rem; text-transform: uppercase; letter-spacing: 0.1em; opacity: 0.7; } .card-cvc-display { background: #fff; color: #1a1a1a; font-family: var(--secure-card-font); font-size: 0.85rem; letter-spacing: 0.2em; padding: 4px 10px; border-radius: 3px; min-width: 52px; text-align: center; } .card-fields { display: flex; flex-direction: column; gap: var(--secure-ui-space-4, 1rem); } .card-legend { font-size: var(--secure-ui-font-size-sm, 0.875rem); font-weight: var(--secure-ui-font-weight-semibold, 600); color: var(--secure-ui-color-neutral-700, #374151); margin-block-end: var(--secure-ui-space-1, 0.25rem); } .field-row { display: grid; grid-template-columns: 1fr 1fr; gap: var(--secure-ui-space-4, 1rem); } .field-group { display: flex; flex-direction: column; gap: var(--secure-ui-space-1, 0.25rem); position: relative; } .field-label { font-size: var(--secure-ui-font-size-sm, 0.875rem); font-weight: var(--secure-ui-font-weight-medium, 500); color: var(--secure-ui-color-neutral-700, #374151); line-height: var(--secure-ui-line-height-tight, 1.25); } .input-wrapper { position: relative; } .card-input { width: 100%; box-sizing: border-box; padding: var(--secure-ui-input-padding-y, 0.625rem) var(--secure-ui-input-padding-x, 0.75rem); font-family: var(--secure-ui-font-family-sans, system-ui, sans-serif); font-size: var(--secure-ui-font-size-base, 1rem); line-height: var(--secure-ui-line-height-normal, 1.5); color: var(--secure-ui-input-color, #111827); background: var(--secure-ui-input-bg, #fff); border: var(--secure-ui-border-width, 1px) solid var(--secure-ui-input-border-color, #d1d5db); border-radius: var(--secure-ui-input-border-radius, 6px); outline: none; transition: border-color var(--secure-ui-transition-fast, 150ms) ease, box-shadow var(--secure-ui-transition-fast, 150ms) ease; appearance: none; -webkit-appearance: none; } .card-input:focus { border-color: var(--secure-ui-color-primary-500, #6366f1); box-shadow: 0 0 0 3px var(--secure-ui-color-primary-100, rgba(99, 102, 241, 0.2)); } .card-input[aria-invalid='true'] { border-color: var(--secure-ui-color-error-500, #ef4444) !important; box-shadow: 0 0 0 3px rgba(239, 68, 68, 0.15); } .card-input:disabled { background: var(--secure-ui-input-disabled-bg, #f3f4f6); color: var(--secure-ui-color-neutral-400, #9ca3af); cursor: not-allowed; } .card-number-input { font-family: var(--secure-card-font); letter-spacing: 0.06em; } .cvc-input::-ms-reveal, .cvc-input::-ms-clear { display: none; } .error-container { font-size: var(--secure-ui-font-size-xs, 0.75rem); color: var(--secure-ui-color-error-600, #dc2626); line-height: var(--secure-ui-line-height-tight, 1.25); min-height: 0; max-height: 3rem; overflow: hidden; transition: max-height var(--secure-ui-transition-normal, 250ms) ease, opacity var(--secure-ui-transition-fast, 150ms) ease; opacity: 1; } .error-container.hidden { max-height: 0; opacity: 0; } @media (prefers-color-scheme: dark) { .card-legend { color: var(--secure-ui-color-neutral-200, #e5e7eb); } .field-label { color: var(--secure-ui-color-neutral-200, #e5e7eb); } .card-input { color: var(--secure-ui-input-color, #f9fafb); background: var(--secure-ui-input-bg, #1f2937); border-color: var(--secure-ui-input-border-color, #374151); } .card-input:disabled { background: #111827; color: #6b7280; } .card-cvc-display { background: #f9fafb; color: #111827; } } @media (prefers-reduced-motion: reduce) { .card { transition: none; } .card-input { transition: none; } .error-container { transition: none; } } @media (max-width: 400px) { .field-row { grid-template-columns: 1fr; } }"),this.#e.addEventListener("input",f=>{this.recordTelemetryInput(f),this.#T(f)}),this.#e.addEventListener("focus",()=>{this.recordTelemetryFocus(),this.#S()}),this.#e.addEventListener("blur",()=>{this.recordTelemetryBlur(),this.#k()}),this.#t.addEventListener("input",f=>{this.recordTelemetryInput(f),this.#$(f)}),this.#t.addEventListener("focus",()=>{this.recordTelemetryFocus(),this.#z(!1)}),this.#t.addEventListener("blur",()=>{this.recordTelemetryBlur(),this.#R()}),this.#i.addEventListener("input",f=>{this.recordTelemetryInput(f),this.#M(f)}),this.#i.addEventListener("focus",()=>{this.recordTelemetryFocus(),this.#z(!0)}),this.#i.addEventListener("blur",()=>{this.recordTelemetryBlur(),this.#D()}),this.#s.addEventListener("input",f=>{this.recordTelemetryInput(f),this.#N(f)}),this.#s.addEventListener("focus",()=>{this.recordTelemetryFocus(),this.#z(!1)}),this.#s.addEventListener("blur",()=>{this.recordTelemetryBlur(),this.#P()}),e.appendChild(s),e}#A(e){let t=document.createElement("div");t.className="field-group";let i=document.createElement("label");i.htmlFor=e,i.className="field-label";let r=document.createElement("div");r.className="input-wrapper",r.setAttribute("part","wrapper");let s=document.createElement("div");return s.className="error-container hidden",s.setAttribute("role","alert"),s.setAttribute("part","error"),t.appendChild(i),t.appendChild(r),t.appendChild(s),t}handleAttributeChange(e,t,i){if(this.shadowRoot)switch(e){case"disabled":{let r=i!==null;this.#e&&(this.#e.disabled=r),this.#t&&(this.#t.disabled=r),this.#i&&(this.#i.disabled=r),this.#s&&(this.#s.disabled=r);break}case"show-name":{let r=this.shadowRoot.querySelector(`#${this.#m}-name-group`);r&&(r.hidden=i===null);break}}}#T(e){let t=e.target,i=t.value.replace(/\D/g,""),r=this.#b?.type;this.#b=Z(i);let s=this.#b?.format??[4,4,4,4],n=s.reduce((a,o)=>a+o,0);if(this.#g=i.slice(0,n),t.value=E(this.#g,s),this.#b?.type!==r){let a=n+s.length-1;t.setAttribute("maxlength",String(a));let o=this.#b?.cvcLength??3;this.#i&&this.#i.setAttribute("maxlength",String(o)),this.#q()}this.#n&&(this.#n.textContent=t.value||E("\u2022".repeat(n),s)),this.#C(this.#p),this.#H(),this.#F()}#S(){if(this.#e&&this.#g){let e=this.#b?.format??[4,4,4,4],t=E(this.#g,e);this.#e.value=t,this.#n&&(this.#n.textContent=t)}this.#z(!1),this.#C(this.#p)}#k(){let e=this.checkRateLimit();if(!e.allowed){this.#L(this.#p,`Too many attempts. Try again in ${Math.ceil(e.retryAfter/1e3)}s.`);return}this.#g?Y(this.#g)?(this.#C(this.#p),this.#e?.removeAttribute("aria-invalid")):(this.#L(this.#p,"Invalid card number"),this.#e?.setAttribute("aria-invalid","true")):(this.#L(this.#p,"Card number is required"),this.#e?.setAttribute("aria-invalid","true")),this.#I(),this.audit("card-number-blur",{cardType:this.#b?.type??"unknown"})}#I(){let e=this.#b?.format??[4,4,4,4],t=X(this.#g,e);this.#e&&(this.#e.value=t),this.#n&&(this.#n.textContent=t)}#$(e){let t=e.target,i=t.value.replace(/\D/g,"").slice(0,4),r=i.length>2?`${i.slice(0,2)}/${i.slice(2)}`:i;t.value=r,this.#E=r,this.#a&&(this.#a.textContent=r||"MM/YY"),this.#C(this.#d),this.#H(),this.#F()}#R(){let e=this.#E.split("/");if(!this.#E){this.#L(this.#d,"Expiry date is required"),this.#t?.setAttribute("aria-invalid","true");return}let t=parseInt(e[0]??"",10),i=parseInt(e[1]??"",10);isNaN(t)||isNaN(i)||t<1||t>12||(e[1]??"").length<2?(this.#L(this.#d,"Enter a valid expiry date (MM/YY)"),this.#t?.setAttribute("aria-invalid","true")):U(t,i)?(this.#C(this.#d),this.#t?.removeAttribute("aria-invalid")):(this.#L(this.#d,"This card has expired"),this.#t?.setAttribute("aria-invalid","true")),this.audit("card-expiry-blur",{})}#M(e){let t=e.target,i=t.value.replace(/\D/g,""),r=this.#b?.cvcLength??3;this.#v=i.slice(0,r),t.value=this.#v,this.#l&&(this.#l.textContent=this.#v.length>0?"\u2022".repeat(this.#v.length):"\u2022\u2022\u2022"),this.#C(this.#u),this.#F()}#D(){let e=this.#b?.cvcLength??3;this.#v?this.#v.length<e?(this.#L(this.#u,`Security code must be ${e} digits`),this.#i?.setAttribute("aria-invalid","true")):(this.#C(this.#u),this.#i?.removeAttribute("aria-invalid")):(this.#L(this.#u,"Security code is required"),this.#i?.setAttribute("aria-invalid","true")),this.#z(!1),this.audit("card-cvc-blur",{})}#N(e){let t=e.target,i=t.value.replace(/[^a-zA-Z\s\-']/g,"").slice(0,50);t.value=i,this.#f=i,this.#o&&(this.#o.textContent=i.toUpperCase()||"FULL NAME"),this.#C(this.#h),this.#H(),this.#F()}#P(){this.hasAttribute("show-name")&&(this.#f.trim()?(this.#C(this.#h),this.#s?.removeAttribute("aria-invalid")):(this.#L(this.#h,"Cardholder name is required"),this.#s?.setAttribute("aria-invalid","true")))}#z(e){this.#r?.classList.toggle("is-flipped",e)}#q(){if(!this.#r)return;for(let t of W)this.#r.classList.remove(`card--${t.type}`);let e=this.#b?.type;e&&this.#r.classList.add(`card--${e}`),this.#c&&(this.#c.textContent=this.#b?.label??"")}#L(e,t){if(!e)return;e.textContent="";let i=document.createElement("span");i.textContent=t,e.appendChild(i),e.classList.remove("hidden")}#C(e){e&&(e.textContent="",e.classList.add("hidden"))}#V(){let e=this.getAttribute("name");e&&(this.#y=document.createElement("input"),this.#y.type="hidden",this.#y.name=e,this.appendChild(this.#y),this.#w=document.createElement("input"),this.#w.type="hidden",this.#w.name=`${e}-expiry`,this.appendChild(this.#w),this.#x=document.createElement("input"),this.#x.type="hidden",this.#x.name=`${e}-holder`,this.appendChild(this.#x))}#H(){this.#y&&(this.#y.value=this.#g.slice(-4)),this.#w&&(this.#w.value=this.#E),this.#x&&(this.#x.value=this.#f)}#F(){let[e,t]=this.#E.split("/");this.dispatchEvent(new CustomEvent("secure-card-change",{bubbles:!0,composed:!0,detail:{name:this.getAttribute("name")??"",cardType:this.#b?.type??"unknown",last4:this.#g.slice(-4),expiryMonth:parseInt(e??"0",10)||0,expiryYear:(()=>{let i=parseInt(t??"0",10);return i>0?2e3+i:0})(),cardholderName:this.#f,valid:this.valid,tier:this.securityTier}}))}disconnectedCallback(){this.#g="",this.#v="",this.#E="",this.#f="",this.#e&&(this.#e.value=""),this.#t&&(this.#t.value=""),this.#i&&(this.#i.value=""),this.#s&&(this.#s.value=""),this.#y&&(this.#y.value=""),this.#w&&(this.#w.value=""),this.#x&&(this.#x.value=""),super.disconnectedCallback()}get valid(){let e=this.#g.length>=12&&Y(this.#g),[t,i]=this.#E.split("/"),r=parseInt(t??"",10),s=parseInt(i??"",10),n=!isNaN(r)&&!isNaN(s)&&r>=1&&r<=12&&(i??"").length>=2&&U(r,s),a=this.#b?.cvcLength??3,o=this.#v.length===a,d=!this.hasAttribute("show-name")||this.#f.trim().length>0;return e&&n&&o&&d}get cardType(){return this.#b?.type??"unknown"}get last4(){return this.#g.slice(-4)}get name(){return this.getAttribute("name")??""}getCardData(){return this.valid?{number:this.#g,expiry:this.#E,cvc:this.#v,name:this.#f}:null}reset(){this.#g="",this.#v="",this.#E="",this.#f="",this.#b=null,this.#e&&(this.#e.value=""),this.#t&&(this.#t.value=""),this.#i&&(this.#i.value=""),this.#s&&(this.#s.value=""),this.#H(),this.#z(!1),this.#q();let e=[4,4,4,4];this.#n&&(this.#n.textContent=E("\u2022".repeat(16),e)),this.#a&&(this.#a.textContent="MM/YY"),this.#o&&(this.#o.textContent="FULL NAME"),this.#l&&(this.#l.textContent="\u2022\u2022\u2022"),this.#C(this.#p),this.#C(this.#d),this.#C(this.#u),this.#C(this.#h),this.audit("card-reset",{})}focus(){this.#e?.focus()}};customElements.define("secure-card",P);var q=class extends HTMLElement{static get observedAttributes(){return["signing-key"]}#e={mouseMovementDetected:!1,keyboardActivityDetected:!1,injectedScriptCount:0,domMutationDetected:!1,pointerType:"none",firstKeystrokeAt:-1,threatSignals:[]};#t=0;#i=null;#s=new Set;#r=null;#n="";#a=()=>{this.#e.mouseMovementDetected=!0};#o=()=>{this.#e.keyboardActivityDetected=!0,this.#e.firstKeystrokeAt<0&&(this.#e.firstKeystrokeAt=performance.now())};#c=e=>{this.#e.pointerType=e.pointerType};#l=e=>{this.#x(e)};#p=e=>{this.#e.threatSignals.push(e.detail)};connectedCallback(){this.#t=performance.now(),document.querySelectorAll("script").forEach(e=>this.#s.add(e)),this.#d(),this.#u()}disconnectedCallback(){this.#i?.disconnect(),this.#i=null,this.#h(),this.#r=null,this.#n=""}attributeChangedCallback(e,t,i){e==="signing-key"&&i!==this.#n&&(this.#r=null,this.#n="")}#d(){this.#i=new MutationObserver(e=>{for(let t of e)if(t.type==="childList")for(let i of Array.from(t.addedNodes))i.tagName==="SCRIPT"&&!this.#s.has(i)&&(this.#e.injectedScriptCount++,this.#e.domMutationDetected=!0,this.#s.add(i))}),this.#i.observe(document.documentElement,{childList:!0,subtree:!0})}#u(){document.addEventListener("mousemove",this.#a,{passive:!0}),document.addEventListener("keydown",this.#o,{passive:!0}),document.addEventListener("pointerdown",this.#c,{passive:!0}),this.addEventListener("secure-form-submit",this.#l),this.addEventListener("secure-threat-detected",this.#p)}#h(){document.removeEventListener("mousemove",this.#a),document.removeEventListener("keydown",this.#o),document.removeEventListener("pointerdown",this.#c),this.removeEventListener("secure-form-submit",this.#l),this.removeEventListener("secure-threat-detected",this.#p)}collectSignals(){let e=navigator,t=e.webdriver===!0||Object.prototype.hasOwnProperty.call(e,"webdriver"),i=navigator.userAgent,r=i.includes("HeadlessChrome")||i.includes("Headless")||typeof window.chrome>"u"&&i.includes("Chrome"),s=screen.width===0||screen.height===0||screen.width<100&&screen.height<100,n=performance.now(),a=this.#e.firstKeystrokeAt>=0?Math.round(this.#e.firstKeystrokeAt-this.#t):-1,o=Math.round(n-this.#t);return{webdriverDetected:t,headlessDetected:r,domMutationDetected:this.#e.domMutationDetected,injectedScriptCount:this.#e.injectedScriptCount,suspiciousScreenSize:s,pointerType:this.#e.pointerType,mouseMovementDetected:this.#e.mouseMovementDetected,keyboardActivityDetected:this.#e.keyboardActivityDetected,pageLoadToFirstKeystroke:a,loadToSubmit:o,threatSignals:this.#e.threatSignals.length>0?[...this.#e.threatSignals]:void 0}}async sign(e){let t=this.#y(),i=new Date().toISOString(),r=this.getAttribute("signing-key")??"",s=`${t}.${i}.${JSON.stringify(e)}`,n=await this.#w(r,s);return{nonce:t,issuedAt:i,environment:e,signature:n}}#y(){let e=new Uint8Array(16);return crypto.getRandomValues(e),Array.from(e,t=>t.toString(16).padStart(2,"0")).join("")}async#w(e,t){if(!crypto.subtle)return"";let i=new TextEncoder;(this.#r===null||this.#n!==e)&&(this.#r=await crypto.subtle.importKey("raw",i.encode(e),{name:"HMAC",hash:"SHA-256"},!1,["sign"]),this.#n=e);let r=await crypto.subtle.sign("HMAC",this.#r,i.encode(t));return Array.from(new Uint8Array(r),s=>s.toString(16).padStart(2,"0")).join("")}async#x(e){let t=e.detail;if(t?.telemetry)try{let i=this.collectSignals(),r=await this.sign(i);t.telemetry._env=r}catch{}}getEnvironmentalSignals(){return this.collectSignals()}};customElements.define("secure-telemetry-provider",q);var V=class extends p{#e=null;#t=null;#i=null;#s=null;#r=null;#n=null;#a=null;#o="";#c="";#l=!1;#p=!1;#d=!1;#u=null;#h=`secure-password-confirm-${Math.random().toString(36).substring(2,11)}`;connectedCallback(){let e=this.getAttribute("security-tier");e&&e!=="critical"&&console.warn(`secure-password-confirm: security-tier="${e}" ignored \u2014 this component is locked to CRITICAL.`),this.removeAttribute("security-tier"),super.connectedCallback()}static get observedAttributes(){return[...super.observedAttributes,"name","label","password-label","confirm-label","required","minlength"]}render(){let e=document.createDocumentFragment(),t=document.createElement("div");t.className="container",t.setAttribute("part","container");let i=this.getAttribute("label");if(i){let a=document.createElement("div");a.className="group-label",a.textContent=this.sanitizeValue(i),t.appendChild(a)}let r=this.hasAttribute("required"),s=this.#y({inputPart:"password-input",wrapperPart:"password-wrapper",labelPart:"password-label",errorPart:"password-error",togglePart:"password-toggle",labelText:this.getAttribute("password-label")??"New Password",inputId:`${this.#h}-password`,errorId:`${this.#h}-password-error`,isRequired:r});this.#e=s.querySelector('[part="password-input"]'),this.#n=s.querySelector('[part="password-toggle"]'),this.#i=s.querySelector('[part="password-error"]');let n=this.#y({inputPart:"confirm-input",wrapperPart:"confirm-wrapper",labelPart:"confirm-label",errorPart:"confirm-error",togglePart:"confirm-toggle",labelText:this.getAttribute("confirm-label")??"Confirm Password",inputId:`${this.#h}-confirm`,errorId:`${this.#h}-confirm-error`,isRequired:r});return this.#t=n.querySelector('[part="confirm-input"]'),this.#a=n.querySelector('[part="confirm-toggle"]'),this.#s=n.querySelector('[part="confirm-error"]'),this.#r=document.createElement("div"),this.#r.setAttribute("part","match-indicator"),this.#r.className="match-indicator",this.#r.setAttribute("aria-hidden","true"),t.appendChild(s),t.appendChild(n),t.appendChild(this.#r),this.#w(),this.#x(),this.#g(),this.#S(),this.addComponentStyles('.container { display: flex; flex-direction: column; gap: var(--secure-ui-form-gap); font-family: var(--secure-ui-font-family-base); } .group-label { font-size: var(--secure-ui-label-font-size); font-weight: var(--secure-ui-label-font-weight); color: var(--secure-ui-label-color); margin-bottom: var(--secure-ui-space-1); } .field-section { display: flex; flex-direction: column; gap: var(--secure-ui-form-label-margin-bottom); } label { font-size: var(--secure-ui-label-font-size); font-weight: var(--secure-ui-label-font-weight); color: var(--secure-ui-label-color); } .input-wrapper { position: relative; display: flex; align-items: center; } input[type="password"], input[type="text"] { flex: 1; height: var(--secure-ui-input-height); padding: var(--secure-ui-input-padding-y) var(--secure-ui-input-padding-x); padding-inline-end: calc(var(--secure-ui-input-padding-x) * 3.5); font-family: var(--secure-ui-font-family-base); font-size: var(--secure-ui-input-font-size); color: var(--secure-ui-input-text-color); background-color: var(--secure-ui-input-bg); border: var(--secure-ui-input-border-width) solid var(--secure-ui-input-border-color); border-radius: var(--secure-ui-input-border-radius); box-sizing: border-box; transition: border-color var(--secure-ui-transition-base), box-shadow var(--secure-ui-transition-base); } input:hover:not(:disabled) { border-color: var(--secure-ui-input-border-color-hover); } input:focus { outline: none; border-color: var(--secure-ui-input-border-color-focus); box-shadow: var(--secure-ui-shadow-focus); } input[aria-invalid="true"] { border-color: var(--secure-ui-color-error) !important; } input[aria-invalid="true"]:focus { box-shadow: var(--secure-ui-shadow-focus-error); } .toggle-btn { position: absolute; inset-inline-end: var(--secure-ui-space-2); display: flex; align-items: center; justify-content: center; background: none; border: none; cursor: pointer; color: var(--secure-ui-color-text-secondary); padding: var(--secure-ui-space-1); border-radius: var(--secure-ui-border-radius-sm); line-height: 1; transition: color var(--secure-ui-transition-base); } .toggle-btn:hover { color: var(--secure-ui-color-text-primary); } .toggle-btn:focus-visible { outline: 2px solid var(--secure-ui-input-border-color-focus); outline-offset: 2px; } .toggle-btn:active .eye-icon { transform: scale(0.85); } .eye-icon { display: block; fill: none; stroke: currentColor; stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; transition: transform 0.15s ease; overflow: visible; } .eye-outline { transition: d 0.2s ease; } .eye-pupil { transform-origin: 12px 12px; transition: opacity 0.2s ease, transform 0.2s ease; } .eye-slash { stroke-dasharray: 26; stroke-dashoffset: 26; transition: stroke-dashoffset 0.3s ease; } .toggle-btn.is-visible .eye-pupil { opacity: 0; transform: scale(0.2); } .toggle-btn.is-visible .eye-slash { stroke-dashoffset: 0; } .error-container { font-size: var(--secure-ui-error-font-size); color: var(--secure-ui-error-color); line-height: var(--secure-ui-line-height-normal); overflow: hidden; max-height: 40px; opacity: 1; transition: all 0.2s ease-in-out; } .error-container.hidden { max-height: 0; opacity: 0; pointer-events: none; } .match-indicator { font-size: var(--secure-ui-font-size-sm); line-height: var(--secure-ui-line-height-normal); min-height: 1.25em; } .match-indicator.matched { color: var(--secure-ui-color-success, #2e7d32); } .match-indicator.mismatched { color: var(--secure-ui-color-error); } @media (prefers-reduced-motion: reduce) { input, .error-container, .eye-icon, .eye-pupil, .eye-slash { transition: none !important; } }'),e.appendChild(t),e}#y(e){let t=document.createElement("div");t.className="field-section";let i=document.createElement("label");i.setAttribute("part",e.labelPart),i.htmlFor=e.inputId,i.textContent=this.sanitizeValue(e.labelText);let r=document.createElement("div");r.className="input-wrapper",r.setAttribute("part",e.wrapperPart);let s=document.createElement("input");s.id=e.inputId,s.type="password",s.autocomplete="new-password",s.setAttribute("part",e.inputPart),s.setAttribute("aria-describedby",e.errorId),e.isRequired&&(s.required=!0,s.setAttribute("aria-required","true"));let n=document.createElement("button");n.type="button",n.className="toggle-btn",n.setAttribute("part",e.togglePart),n.setAttribute("aria-label","Show password"),n.appendChild(this.#v()),r.appendChild(s),r.appendChild(n);let a=document.createElement("div");return a.id=e.errorId,a.setAttribute("part",e.errorPart),a.setAttribute("role","alert"),a.className="error-container hidden",t.appendChild(i),t.appendChild(r),t.appendChild(a),t}#w(){this.#e.addEventListener("focus",()=>{this.recordTelemetryFocus()}),this.#e.addEventListener("input",e=>{this.recordTelemetryInput(e),this.#o=this.#e.value,this.detectInjection(this.#o,this.getAttribute("name")??""),this.#l&&this.#b(),this.dispatchEvent(new CustomEvent("secure-input-change",{detail:{name:this.getAttribute("name")??"",field:"password"},bubbles:!0,composed:!0}))}),this.#e.addEventListener("blur",()=>{this.recordTelemetryBlur(),this.#E()})}#x(){this.#t.addEventListener("input",()=>{this.#c=this.#t.value,this.detectInjection(this.#c,this.getAttribute("name")??""),this.#l&&this.#b()}),this.#t.addEventListener("blur",()=>{this.#l=!0,this.#c=this.#t.value,this.#b()})}#g(){this.#n.addEventListener("click",()=>{this.#p=!this.#p,this.#e.type=this.#p?"text":"password",this.#n.classList.toggle("is-visible",this.#p),this.#n.setAttribute("aria-label",this.#p?"Hide password":"Show password")}),this.#a.addEventListener("click",()=>{this.#d=!this.#d,this.#t.type=this.#d?"text":"password",this.#a.classList.toggle("is-visible",this.#d),this.#a.setAttribute("aria-label",this.#d?"Hide confirm password":"Show confirm password")})}#v(){let e="http://www.w3.org/2000/svg",t=document.createElementNS(e,"svg");t.setAttribute("viewBox","0 0 24 24"),t.setAttribute("aria-hidden","true"),t.setAttribute("class","eye-icon"),t.setAttribute("width","18"),t.setAttribute("height","18");let i=document.createElementNS(e,"path");i.setAttribute("class","eye-outline"),i.setAttribute("d","M1 12s4-8 11-8 11 8 11 8-4 8-11 8-11-8-11-8z");let r=document.createElementNS(e,"circle");r.setAttribute("class","eye-pupil"),r.setAttribute("cx","12"),r.setAttribute("cy","12"),r.setAttribute("r","3");let s=document.createElementNS(e,"line");return s.setAttribute("class","eye-slash"),s.setAttribute("x1","3"),s.setAttribute("y1","3"),s.setAttribute("x2","21"),s.setAttribute("y2","21"),t.append(i,r,s),t}#E(){let e=this.#f(this.#o);e?this.#m(this.#i,this.#e,e):this.#A(this.#i,this.#e)}#f(e){return e?e.length<8?"Password must be at least 8 characters":/[a-z]/.test(e)?/[A-Z]/.test(e)?/[0-9]/.test(e)?/[^a-zA-Z0-9]/.test(e)?null:"Password must include a special character":"Password must include a number":"Password must include an uppercase letter":"Password must include a lowercase letter":null}#b(){let e=this.#o.length>0&&this.#o===this.#c;if(this.#k(e),this.#T(e),e)this.#A(this.#s,this.#t),this.dispatchEvent(new CustomEvent("secure-password-match",{detail:{name:this.getAttribute("name")??"",matched:!0},bubbles:!0,composed:!0}));else{let t=this.#c.length>0?"Passwords do not match":"Please confirm your password";this.#m(this.#s,this.#t,t),this.dispatchEvent(new CustomEvent("secure-password-mismatch",{detail:{name:this.getAttribute("name")??"",matched:!1},bubbles:!0,composed:!0}))}}#m(e,t,i){e.textContent=i,e.classList.remove("hidden"),t.setAttribute("aria-invalid","true")}#A(e,t){e.classList.add("hidden"),e.textContent="",t.removeAttribute("aria-invalid")}#T(e){this.#r&&(this.#r.className=`match-indicator ${e?"matched":"mismatched"}`,this.#r.textContent=e?"\u2713 Passwords match":"\u2717 Passwords do not match")}#S(){let e=this.getAttribute("name");!e||this.closest("secure-form")||(this.#u=document.createElement("input"),this.#u.type="hidden",this.#u.name=e,this.#u.value="",this.appendChild(this.#u))}#k(e){this.#u&&(this.#u.value=e?this.#o:"")}getPasswordValue(){return!this.#o||!this.#c||this.#o!==this.#c?null:this.#o}get valid(){return!this.#o||!this.#c||this.#o!==this.#c?!1:this.#f(this.#o)===null}get name(){return this.getAttribute("name")??""}disconnectedCallback(){super.disconnectedCallback(),this.#o="",this.#c="",this.#e&&(this.#e.value=""),this.#t&&(this.#t.value=""),this.#u&&(this.#u.value="")}};customElements.define("secure-password-confirm",V);export{P as SecureCard,F as SecureDateTime,H as SecureFileUpload,N as SecureForm,I as SecureInput,V as SecurePasswordConfirm,D as SecureSelect,R as SecureSubmitButton,$ as SecureTable,q as SecureTelemetryProvider,M as SecureTextarea,u as SecurityTier,w as TIER_CONFIG,B as compareTiers,G as getMoreSecureTier,v as getTierConfig,A as isValidTier};
232
67
  /**
233
68
  * @fileoverview Secure File Upload Component
234
69
  *
@@ -294,28 +129,6 @@ var c=Object.freeze({PUBLIC:"public",AUTHENTICATED:"authenticated",SENSITIVE:"se
294
129
  * @module secure-datetime
295
130
  * @license MIT
296
131
  */
297
- /**
298
- * @fileoverview Secure Submit Button Component
299
- *
300
- * A security-aware form submit button that integrates with <secure-form>.
301
- * The button's enabled/disabled state is driven by the parent form's security
302
- * tier and field validation state.
303
- *
304
- * Tier behaviour:
305
- * - public: Button enabled by default (validation.required = false)
306
- * - authenticated: Button disabled until all required fields are valid
307
- * - sensitive: Button disabled until all required fields are valid
308
- * - critical: Button disabled until all required fields are valid
309
- *
310
- * Usage:
311
- * <secure-form action="/api/data" method="POST" security-tier="sensitive">
312
- * <secure-input label="Name" name="name" required></secure-input>
313
- * <secure-submit-button label="Submit"></secure-submit-button>
314
- * </secure-form>
315
- *
316
- * @module secure-submit-button
317
- * @license MIT
318
- */
319
132
  /**
320
133
  * @fileoverview SecureCard — composite credit card input Web Component
321
134
  *
@@ -376,9 +189,3 @@ var c=Object.freeze({PUBLIC:"public",AUTHENTICATED:"authenticated",SENSITIVE:"se
376
189
  * @module secure-telemetry-provider
377
190
  * @license MIT
378
191
  */
379
- /**
380
- * Secure-UI Component Library
381
- *
382
- * @module @anthropic/secure-ui-components
383
- * @license MIT
384
- */