- Add comprehensive health check system with multiple endpoints - Add Prometheus metrics endpoint - Add production logging configurations (5 strategies) - Add complete deployment documentation suite: * QUICKSTART.md - 30-minute deployment guide * DEPLOYMENT_CHECKLIST.md - Printable verification checklist * DEPLOYMENT_WORKFLOW.md - Complete deployment lifecycle * PRODUCTION_DEPLOYMENT.md - Comprehensive technical reference * production-logging.md - Logging configuration guide * ANSIBLE_DEPLOYMENT.md - Infrastructure as Code automation * README.md - Navigation hub * DEPLOYMENT_SUMMARY.md - Executive summary - Add deployment scripts and automation - Add DEPLOYMENT_PLAN.md - Concrete plan for immediate deployment - Update README with production-ready features All production infrastructure is now complete and ready for deployment.
2 lines
205 KiB
JavaScript
2 lines
205 KiB
JavaScript
var e=Object.defineProperty,t=(t,i,n)=>((t,i,n)=>i in t?e(t,i,{enumerable:!0,configurable:!0,writable:!0,value:n}):t[i]=n)(t,"symbol"!=typeof i?i+"":i,n);const i=new Map;let n=!1,r=!1;performance.now();const a=document.createElement("div");a.style.position="fixed",a.style.bottom="0",a.style.left="0",a.style.font="12px monospace",a.style.color="#0f0",a.style.background="rgba(0,0,0,0.75)",a.style.padding="0.25rem 0.5rem",a.style.zIndex="9999",a.style.pointerEvents="none",a.style.display="none";const s=`<div style="width:${Math.min(0,100)}%;height:4px;background:#0f0;margin-top:4px;"></div>`;a.innerHTML+=s,a.style.lineHeight="1.4",document.body.appendChild(a);const o=new class{constructor({fps:e=!0}={}){this.fpsEnabled=e,this.fps=0,this.frameCount=0,this.lastTime=performance.now(),this.visible=!1,this.taskTimings=new Map,this.logs=[],this.container=document.createElement("div"),this.container.style.position="fixed",this.container.style.bottom="0",this.container.style.left="0",this.container.style.font="12px Consolas, monospace",this.container.style.color="#0f0",this.container.style.background="rgba(0,0,0,0.75)",this.container.style.padding="0.5rem",this.container.style.zIndex="9999",this.container.style.pointerEvents="none",this.container.style.lineHeight="1.4",this.container.style.whiteSpace="pre",this.container.style.display="none",document.body.appendChild(this.container),window.addEventListener("keydown",e=>{"§"===e.key&&(this.visible=!this.visible,this.container.style.display=this.visible?"block":"none")})}log(e){const t=(new Date).toLocaleTimeString();this.logs.push(`[${t}] ${e}`),this.logs.length>5&&this.logs.shift()}update(e=new Map){this.frameCount++;const t=performance.now();if(t-this.lastTime>=1e3){this.fps=this.frameCount,this.frameCount=0,this.lastTime=t;const i=[];for(const[e,t]of this.taskTimings.entries())i.push(`${e}: ${t.toFixed(2)}ms`);const n=Math.min(2*this.fps,100),r=this.logs.slice().reverse().join("\n");this.container.innerHTML=`\nFPS: ${this.fps} | Tasks: ${e.size}\n${i.join("\n")}\n<div style="width:${n}%;height:4px;background:#0f0;margin-top:4px;"></div>\n${r?"\nLogs:\n"+r:""}\n `}}trackTask(e,t){const i=performance.now();t();const n=performance.now()-i;this.taskTimings.set(e,n)}};function l(e,t,a={}){i.set(e,t),a.autoStart&&!n&&function(){if(n)return;function e(){for(const[e,n]of i)try{r?o.trackTask(e,n):n()}catch(t){d.warn("[Frameloop] Fehler in Task:",t)}r&&o.update(i),requestAnimationFrame(e)}n=!0,requestAnimationFrame(e)}()}function c(e){i.delete(e)}window.addEventListener("keydown",e=>{"§"===e.key&&(r=!r,a.style.display=r?"block":"none")});class d{static debug(...e){this._write("log","[DEBUG]",e,"debug")}static log(...e){this._write("log","[LOG]",e,"info")}static info(...e){this._write("info","[INFO]",e,"info")}static warn(...e){this._write("warn","[WARN]",e,"warn")}static error(...e){this._write("error","[ERROR]",e,"error")}static _write(e,t,i,n="info"){if(!this.enabled)return;const r=this.levels[this.level]||this.levels.info;if((this.levels[n]||this.levels.info)<r)return;const a=`${t} [${(new Date).toLocaleTimeString("de-DE")}] ${i.map(e=>{if(e instanceof Error)return`${e.name}: ${e.message}\n${e.stack||""}`;if("object"==typeof e&&null!==e)try{return JSON.stringify(e)}catch(t){return"[Circular Object]"}return e}).join(" ")}`;if("function"==typeof console[e]&&console[e](a),o&&"function"==typeof o.log)try{o.log(a)}catch(s){}}static setLevel(e){this.levels.hasOwnProperty(e)?(this.level=e,this.info(`[Logger] Log level set to: ${e}`)):this.warn(`[Logger] Invalid log level: ${e}. Valid levels:`,Object.keys(this.levels))}static setEnabled(e){this.enabled=!!e,e&&console.log("[Logger] Logging enabled")}}t(d,"enabled",!1),t(d,"level","error"),t(d,"levels",{debug:0,info:1,warn:2,error:3,none:99});class h{constructor(e={}){this.config=e,this.activeObservers=new Map,this.observerInstances=new Map,d.info("[ObserverManager] Initialized with support:",{intersection:"IntersectionObserver"in window,resize:"ResizeObserver"in window,mutation:"MutationObserver"in window,performance:"PerformanceObserver"in window})}intersection(e,t,i={}){if(!("IntersectionObserver"in window))return d.warn("[ObserverManager] IntersectionObserver not supported"),this.createFallbackObserver("intersection",e,t);const n={root:null,rootMargin:"50px",threshold:[0,.1,.5,1],...i},r=this.generateId("intersection"),a=new IntersectionObserver((e,i)=>{const n=e.map(e=>({element:e.target,isIntersecting:e.isIntersecting,intersectionRatio:e.intersectionRatio,boundingClientRect:e.boundingClientRect,rootBounds:e.rootBounds,intersectionRect:e.intersectionRect,time:e.time,visibility:this.calculateVisibility(e),direction:this.getScrollDirection(e),position:this.getElementPosition(e)}));t(n,i)},n),s=Array.isArray(e)?e:[e];return s.forEach(e=>{e instanceof Element&&a.observe(e)}),this.observerInstances.set(r,a),this.activeObservers.set(r,{type:"intersection",elements:s,callback:t,options:n}),d.info(`[ObserverManager] IntersectionObserver created: ${r}`),{id:r,observer:a,unobserve:e=>a.unobserve(e),disconnect:()=>this.disconnect(r),updateThreshold:e=>this.updateIntersectionThreshold(r,e)}}resize(e,t,i={}){if(!("ResizeObserver"in window))return d.warn("[ObserverManager] ResizeObserver not supported"),this.createFallbackObserver("resize",e,t);const n=this.generateId("resize"),r=new ResizeObserver(e=>{const i=e.map(e=>({element:e.target,contentRect:e.contentRect,borderBoxSize:e.borderBoxSize,contentBoxSize:e.contentBoxSize,devicePixelContentBoxSize:e.devicePixelContentBoxSize,dimensions:{width:e.contentRect.width,height:e.contentRect.height,aspectRatio:e.contentRect.width/e.contentRect.height},deltaSize:this.calculateDeltaSize(e),breakpoint:this.detectBreakpoint(e.contentRect.width)}));t(i)}),a=Array.isArray(e)?e:[e];return a.forEach(e=>{e instanceof Element&&r.observe(e)}),this.observerInstances.set(n,r),this.activeObservers.set(n,{type:"resize",elements:a,callback:t,options:i}),d.info(`[ObserverManager] ResizeObserver created: ${n}`),{id:n,observer:r,unobserve:e=>r.unobserve(e),disconnect:()=>this.disconnect(n)}}mutation(e,t,i={}){if(!("MutationObserver"in window))return d.warn("[ObserverManager] MutationObserver not supported"),null;const n={childList:!0,attributes:!0,subtree:!0,attributeOldValue:!0,characterDataOldValue:!0,...i},r=this.generateId("mutation"),a=new MutationObserver(e=>{const i=e.map(e=>({type:e.type,target:e.target,addedNodes:Array.from(e.addedNodes),removedNodes:Array.from(e.removedNodes),attributeName:e.attributeName,attributeNamespace:e.attributeNamespace,oldValue:e.oldValue,summary:this.summarizeMutation(e),impact:this.assessMutationImpact(e)}));t(i)});return a.observe(e,n),this.observerInstances.set(r,a),this.activeObservers.set(r,{type:"mutation",target:e,callback:t,options:n}),d.info(`[ObserverManager] MutationObserver created: ${r}`),{id:r,observer:a,disconnect:()=>this.disconnect(r),takeRecords:()=>a.takeRecords()}}performance(e,t={}){if(!("PerformanceObserver"in window))return d.warn("[ObserverManager] PerformanceObserver not supported"),null;const i={entryTypes:["measure","navigation","paint","largest-contentful-paint"],buffered:!0,...t},n=this.generateId("performance"),r=new PerformanceObserver(t=>{const i=t.getEntries().map(e=>({name:e.name,entryType:e.entryType,startTime:e.startTime,duration:e.duration,details:this.enhancePerformanceEntry(e),timestamp:Date.now()}));e(i)});return r.observe(i),this.observerInstances.set(n,r),this.activeObservers.set(n,{type:"performance",callback:e,options:i}),d.info(`[ObserverManager] PerformanceObserver created: ${n}`),{id:n,observer:r,disconnect:()=>this.disconnect(n),takeRecords:()=>r.takeRecords()}}lazyLoad(e="img[data-src], iframe[data-src]",t={}){const i=document.querySelectorAll(e);return this.intersection(i,e=>{e.forEach(e=>{if(e.isIntersecting){const t=e.element;t.dataset.src&&(t.src=t.dataset.src,delete t.dataset.src),t.dataset.srcset&&(t.srcset=t.dataset.srcset,delete t.dataset.srcset),t.classList.add("loaded"),e.observer.unobserve(t),d.info("[ObserverManager] Lazy loaded:",t.src)}})},{rootMargin:"100px",...t})}scrollTrigger(e,t,i={}){return this.intersection(e,e=>{e.forEach(e=>{const i={element:e.element,progress:e.intersectionRatio,isVisible:e.isIntersecting,direction:e.direction,position:e.position};t(i)})},{threshold:this.createThresholdArray(i.steps||10),...i})}viewport(e,t={}){const i=document.createElement("div");return i.style.cssText="\n position: fixed;\n top: 0;\n left: 0;\n width: 100%;\n height: 100%;\n pointer-events: none;\n visibility: hidden;\n ",document.body.appendChild(i),this.resize([i],t=>{const i=t[0];e({width:i.dimensions.width,height:i.dimensions.height,aspectRatio:i.dimensions.aspectRatio,orientation:i.dimensions.width>i.dimensions.height?"landscape":"portrait",breakpoint:i.breakpoint})},t)}generateId(e){return`${e}_${Date.now()}_${Math.random().toString(36).substr(2,9)}`}disconnect(e){const t=this.observerInstances.get(e);t&&(t.disconnect(),this.observerInstances.delete(e),this.activeObservers.delete(e),d.info(`[ObserverManager] Observer disconnected: ${e}`))}disconnectAll(){this.observerInstances.forEach((e,t)=>{e.disconnect()}),this.observerInstances.clear(),this.activeObservers.clear(),d.info("[ObserverManager] All observers disconnected")}calculateVisibility(e){if(!e.isIntersecting)return 0;const t=e.intersectionRect.width*e.intersectionRect.height,i=e.boundingClientRect.width*e.boundingClientRect.height;return i>0?Math.round(t/i*100):0}getScrollDirection(e){return e.intersectionRatio>.5?"down":"up"}getElementPosition(e){const t=e.boundingClientRect,i=window.innerHeight;return t.top<0&&t.bottom>0?"entering-top":t.top<i&&t.bottom>i?"entering-bottom":t.top>=0&&t.bottom<=i?"visible":"hidden"}calculateDeltaSize(e){return{width:0,height:0}}detectBreakpoint(e){return e<576?"xs":e<768?"sm":e<992?"md":e<1200?"lg":"xl"}summarizeMutation(e){return`${e.type} on ${e.target.tagName}`}assessMutationImpact(e){return"childList"===e.type?e.addedNodes.length+e.removedNodes.length>5?"high":"low":"medium"}enhancePerformanceEntry(e){const t={raw:e};switch(e.entryType){case"navigation":t.loadTime=e.loadEventEnd-e.navigationStart,t.domContentLoaded=e.domContentLoadedEventEnd-e.navigationStart;break;case"paint":t.paintType=e.name;break;case"largest-contentful-paint":t.element=e.element,t.url=e.url}return t}createThresholdArray(e){const t=[];for(let i=0;i<=e;i++)t.push(i/e);return t}createFallbackObserver(e,t,i){d.warn(`[ObserverManager] Creating fallback for ${e}Observer`);const n=this.generateId(`fallback_${e}`);let r;if("intersection"===e)r=setInterval(()=>{const e=(Array.isArray(t)?t:[t]).map(e=>({element:e,isIntersecting:this.isElementInViewport(e),intersectionRatio:this.calculateIntersectionRatio(e)}));i(e)},100);return{id:n,disconnect:()=>{r&&clearInterval(r)}}}isElementInViewport(e){const t=e.getBoundingClientRect();return t.top>=0&&t.left>=0&&t.bottom<=window.innerHeight&&t.right<=window.innerWidth}calculateIntersectionRatio(e){const t=e.getBoundingClientRect(),i=window.innerHeight,n=window.innerWidth,r=Math.min(t.bottom,i)-Math.max(t.top,0),a=Math.min(t.right,n)-Math.max(t.left,0);if(r<=0||a<=0)return 0;const s=r*a,o=t.height*t.width;return o>0?s/o:0}getActiveObservers(){return Array.from(this.activeObservers.entries()).map(([e,t])=>({id:e,...t}))}}class u{constructor(e={}){var t;this.config=e,this.activeStreams=new Map,this.activeConnections=new Map,this.audioContext=null,this.support={mediaDevices:void 0!==navigator.mediaDevices,webRTC:"RTCPeerConnection"in window,webAudio:"AudioContext"in window||"webkitAudioContext"in window,mediaRecorder:"MediaRecorder"in window,screenShare:void 0!==(null==(t=navigator.mediaDevices)?void 0:t.getDisplayMedia)},d.info("[MediaManager] Initialized with support:",this.support)}async getUserCamera(e={}){if(!this.support.mediaDevices)throw new Error("MediaDevices API not supported");const t={video:{width:{ideal:1280},height:{ideal:720},facingMode:"user"},audio:!1,...e};try{const e=await navigator.mediaDevices.getUserMedia(t),i=this.generateId("camera");return this.activeStreams.set(i,{stream:e,type:"camera",constraints:t,tracks:e.getTracks()}),d.info(`[MediaManager] Camera stream acquired: ${i}`),{id:i,stream:e,video:e.getVideoTracks()[0],audio:e.getAudioTracks()[0],stop:()=>this.stopStream(i),switchCamera:()=>this.switchCamera(i),takePhoto:t=>this.takePhoto(e,t),applyFilter:e=>this.applyVideoFilter(i,e)}}catch(i){throw d.warn("[MediaManager] Camera access failed:",i.message),i}}async getUserMicrophone(e={}){if(!this.support.mediaDevices)throw new Error("MediaDevices API not supported");const t={audio:{echoCancellation:!0,noiseSuppression:!0,autoGainControl:!0,...e.audio},video:!1,...e};try{const e=await navigator.mediaDevices.getUserMedia(t),i=this.generateId("microphone");return this.activeStreams.set(i,{stream:e,type:"microphone",constraints:t,tracks:e.getTracks()}),d.info(`[MediaManager] Microphone stream acquired: ${i}`),{id:i,stream:e,audio:e.getAudioTracks()[0],stop:()=>this.stopStream(i),getVolume:()=>this.getAudioLevel(e),startRecording:t=>this.startRecording(e,t)}}catch(i){throw d.warn("[MediaManager] Microphone access failed:",i.message),i}}async getScreenShare(e={}){if(!this.support.screenShare)throw new Error("Screen sharing not supported");const t={video:{cursor:"always"},audio:!1,...e};try{const e=await navigator.mediaDevices.getDisplayMedia(t),i=this.generateId("screen");return this.activeStreams.set(i,{stream:e,type:"screen",constraints:t,tracks:e.getTracks()}),e.getTracks().forEach(e=>{e.addEventListener("ended",()=>{this.stopStream(i)})}),d.info(`[MediaManager] Screen share acquired: ${i}`),{id:i,stream:e,video:e.getVideoTracks()[0],audio:e.getAudioTracks()[0],stop:()=>this.stopStream(i)}}catch(i){throw d.warn("[MediaManager] Screen share failed:",i.message),i}}async startRecording(e,t={}){if(!this.support.mediaRecorder)throw new Error("MediaRecorder API not supported");const i={mimeType:"video/webm;codecs=vp9",videoBitsPerSecond:2e6,audioBitsPerSecond:128e3,...t},n=this.getSupportedMimeType(["video/webm;codecs=vp9","video/webm;codecs=vp8","video/webm","video/mp4"])||i.mimeType,r=new MediaRecorder(e,{...i,mimeType:n}),a=this.generateId("recording"),s=[];return r.ondataavailable=e=>{e.data.size>0&&s.push(e.data)},r.onstop=()=>{const e=new Blob(s,{type:n});this.onRecordingComplete(a,e)},r.start(),d.info(`[MediaManager] Recording started: ${a}`),{id:a,recorder:r,stop:()=>(r.stop(),new Promise(e=>{r.onstop=()=>{const t=new Blob(s,{type:n});e({blob:t,url:URL.createObjectURL(t),size:t.size,type:t.type,download:(e=`recording-${Date.now()}.webm`)=>{this.downloadBlob(t,e)}})}})),pause:()=>r.pause(),resume:()=>r.resume(),get state(){return r.state}}}takePhoto(e,t){const i=document.createElement("video");return i.srcObject=e,i.autoplay=!0,i.muted=!0,new Promise(e=>{i.onloadedmetadata=()=>{t||(t=document.createElement("canvas")),t.width=i.videoWidth,t.height=i.videoHeight;t.getContext("2d").drawImage(i,0,0),t.toBlob(i=>{e({canvas:t,blob:i,url:URL.createObjectURL(i),dataURL:t.toDataURL("image/jpeg",.9),download:(e=`photo-${Date.now()}.jpg`)=>{this.downloadBlob(i,e)}})},"image/jpeg",.9),i.remove()}})}getAudioContext(){if(!this.audioContext){if(!this.support.webAudio)return d.warn("[MediaManager] Web Audio API not supported"),null;this.audioContext=new(window.AudioContext||window.webkitAudioContext),d.info("[MediaManager] Audio context created")}return this.audioContext}createAudioAnalyzer(e,t={}){const i=this.getAudioContext();if(!i)return null;const n=i.createMediaStreamSource(e),r=i.createAnalyser();r.fftSize=t.fftSize||256,r.smoothingTimeConstant=t.smoothing||.8,n.connect(r);const a=r.frequencyBinCount,s=new Uint8Array(a);return{analyzer:r,bufferLength:a,dataArray:s,getFrequencyData:()=>(r.getByteFrequencyData(s),Array.from(s)),getTimeDomainData:()=>(r.getByteTimeDomainData(s),Array.from(s)),getAverageVolume:()=>(r.getByteFrequencyData(s),s.reduce((e,t)=>e+t,0)/a)}}async createPeerConnection(e={}){if(!this.support.webRTC)throw new Error("WebRTC not supported");const t={iceServers:[{urls:"stun:stun.l.google.com:19302"},{urls:"stun:stun1.l.google.com:19302"}],...e},i=new RTCPeerConnection(t),n=this.generateId("rtc");this.activeConnections.set(n,i);const r={id:n,connection:i,onTrack:e=>i.addEventListener("track",e),onIceCandidate:e=>i.addEventListener("icecandidate",e),onConnectionStateChange:e=>i.addEventListener("connectionstatechange",e),addStream:e=>{e.getTracks().forEach(t=>{i.addTrack(t,e)})},createOffer:()=>i.createOffer(),createAnswer:()=>i.createAnswer(),setLocalDescription:e=>i.setLocalDescription(e),setRemoteDescription:e=>i.setRemoteDescription(e),addIceCandidate:e=>i.addIceCandidate(e),close:()=>{i.close(),this.activeConnections.delete(n)},get connectionState(){return i.connectionState},get iceConnectionState(){return i.iceConnectionState}};return d.info(`[MediaManager] Peer connection created: ${n}`),r}async getDevices(){if(!this.support.mediaDevices)return{cameras:[],microphones:[],speakers:[]};try{const e=await navigator.mediaDevices.enumerateDevices();return{cameras:e.filter(e=>"videoinput"===e.kind),microphones:e.filter(e=>"audioinput"===e.kind),speakers:e.filter(e=>"audiooutput"===e.kind),all:e}}catch(e){return d.warn("[MediaManager] Device enumeration failed:",e),{cameras:[],microphones:[],speakers:[]}}}async checkPermissions(){const e={};try{if(navigator.permissions){const t=await navigator.permissions.query({name:"camera"}),i=await navigator.permissions.query({name:"microphone"});e.camera=t.state,e.microphone=i.state}}catch(t){d.warn("[MediaManager] Permission check failed:",t)}return e}stopStream(e){const t=this.activeStreams.get(e);t&&(t.tracks.forEach(e=>e.stop()),this.activeStreams.delete(e),d.info(`[MediaManager] Stream stopped: ${e}`))}stopAllStreams(){this.activeStreams.forEach((e,t)=>{e.tracks.forEach(e=>e.stop())}),this.activeStreams.clear(),d.info("[MediaManager] All streams stopped")}async switchCamera(e){const t=this.activeStreams.get(e);if(!t||"camera"!==t.type)return null;const i="user"===t.constraints.video.facingMode?"environment":"user";return this.stopStream(e),this.getUserCamera({video:{...t.constraints.video,facingMode:i}})}getAudioLevel(e){const t=this.getAudioContext();if(!t)return 0;const i=t.createMediaStreamSource(e),n=t.createAnalyser();i.connect(n);const r=new Uint8Array(n.frequencyBinCount);return n.getByteFrequencyData(r),r.reduce((e,t)=>e+t,0)/r.length}getSupportedMimeType(e){return e.find(e=>MediaRecorder.isTypeSupported(e))}downloadBlob(e,t){const i=URL.createObjectURL(e),n=document.createElement("a");n.href=i,n.download=t,document.body.appendChild(n),n.click(),document.body.removeChild(n),URL.revokeObjectURL(i)}generateId(e="media"){return`${e}_${Date.now()}_${Math.random().toString(36).substr(2,9)}`}onRecordingComplete(e,t){d.info(`[MediaManager] Recording completed: ${e}, size: ${t.size} bytes`)}applyVideoFilter(e,t){const i=this.activeStreams.get(e);if(!i||"camera"!==i.type)return;const n={none:"none",blur:"blur(2px)",brightness:"brightness(1.2)",contrast:"contrast(1.3)",grayscale:"grayscale(1)",sepia:"sepia(1)",invert:"invert(1)",vintage:"sepia(0.8) contrast(1.4) brightness(1.1)",cool:"hue-rotate(180deg) saturate(1.5)",warm:"hue-rotate(25deg) saturate(1.2)"};return{filter:n[t]||t,apply:e=>{e.style.filter=n[t]||t}}}getStatus(){var e;return{activeStreams:this.activeStreams.size,activeConnections:this.activeConnections.size,audioContextState:(null==(e=this.audioContext)?void 0:e.state)||"none",support:this.support,streams:Array.from(this.activeStreams.entries()).map(([e,t])=>({id:e,type:t.type,tracks:t.tracks.length,active:t.tracks.some(e=>"live"===e.readyState)}))}}}class m{constructor(e={}){t(this,"db",{set:async(e,t,i=null)=>new Promise((n,r)=>{if(!this.db)return void r(new Error("IndexedDB not available"));const a=this.db.transaction(["keyValue"],"readwrite").objectStore("keyValue"),s={key:e,value:t,timestamp:Date.now(),expiration:i?Date.now()+i:null},o=a.put(s);o.onsuccess=()=>{d.info(`[StorageManager] DB set: ${e}`),n(s)},o.onerror=()=>{d.error(`[StorageManager] DB set failed: ${e}`),r(o.error)}}),get:async e=>new Promise((t,i)=>{if(!this.db)return void i(new Error("IndexedDB not available"));const n=this.db.transaction(["keyValue"],"readonly").objectStore("keyValue").get(e);n.onsuccess=()=>{const i=n.result;if(i)return i.expiration&&Date.now()>i.expiration?(this.db.delete(e),void t(null)):void t(i.value);t(null)},n.onerror=()=>{d.error(`[StorageManager] DB get failed: ${e}`),i(n.error)}}),delete:async e=>new Promise((t,i)=>{if(!this.db)return void i(new Error("IndexedDB not available"));const n=this.db.transaction(["keyValue"],"readwrite").objectStore("keyValue").delete(e);n.onsuccess=()=>{d.info(`[StorageManager] DB deleted: ${e}`),t(!0)},n.onerror=()=>{i(n.error)}}),keys:async()=>new Promise((e,t)=>{if(!this.db)return void t(new Error("IndexedDB not available"));const i=this.db.transaction(["keyValue"],"readonly").objectStore("keyValue").getAllKeys();i.onsuccess=()=>{e(i.result)},i.onerror=()=>{t(i.error)}}),clear:async()=>new Promise((e,t)=>{if(!this.db)return void t(new Error("IndexedDB not available"));const i=this.db.transaction(["keyValue"],"readwrite").objectStore("keyValue").clear();i.onsuccess=()=>{d.info("[StorageManager] DB cleared"),e(!0)},i.onerror=()=>{t(i.error)}}),storeFile:async(e,t,i={})=>new Promise((n,r)=>{if(!this.db)return void r(new Error("IndexedDB not available"));const a=this.db.transaction(["files"],"readwrite").objectStore("files"),s={name:e,file:t,type:t.type,size:t.size,timestamp:Date.now(),metadata:i},o=a.add(s);o.onsuccess=()=>{d.info(`[StorageManager] File stored: ${e}`),n({id:o.result,...s})},o.onerror=()=>{r(o.error)}}),getFile:async e=>new Promise((t,i)=>{if(!this.db)return void i(new Error("IndexedDB not available"));const n=this.db.transaction(["files"],"readonly").objectStore("files").get(e);n.onsuccess=()=>{t(n.result)},n.onerror=()=>{i(n.error)}})}),t(this,"cache",{add:async(e,t=null)=>{if(!this.cache)throw new Error("Cache API not available");try{t?await this.cache.put(e,t):await this.cache.add(e),d.info(`[StorageManager] Cache add: ${e}`)}catch(i){throw d.error("[StorageManager] Cache add failed:",i),i}},get:async e=>{if(!this.cache)throw new Error("Cache API not available");try{const t=await this.cache.match(e);return t?d.info(`[StorageManager] Cache hit: ${e}`):d.info(`[StorageManager] Cache miss: ${e}`),t}catch(t){throw d.error("[StorageManager] Cache get failed:",t),t}},delete:async e=>{if(!this.cache)throw new Error("Cache API not available");try{const t=await this.cache.delete(e);return t&&d.info(`[StorageManager] Cache deleted: ${e}`),t}catch(t){throw d.error("[StorageManager] Cache delete failed:",t),t}},keys:async()=>{if(!this.cache)throw new Error("Cache API not available");try{return await this.cache.keys()}catch(e){throw d.error("[StorageManager] Cache keys failed:",e),e}},clear:async()=>{if(!this.cache)throw new Error("Cache API not available");try{const e=await this.cache.keys();await Promise.all(e.map(e=>this.cache.delete(e))),d.info("[StorageManager] Cache cleared")}catch(e){throw d.error("[StorageManager] Cache clear failed:",e),e}}}),t(this,"channel",{create:(e,t=null)=>{if(!this.support.broadcastChannel)return d.warn("[StorageManager] BroadcastChannel not supported"),null;if(this.channels.has(e))return this.channels.get(e);const i=new BroadcastChannel(e);t&&i.addEventListener("message",t);const n={name:e,channel:i,send:t=>{i.postMessage({data:t,timestamp:Date.now(),sender:"current-tab"}),d.info(`[StorageManager] Broadcast sent to ${e}`)},onMessage:e=>{i.addEventListener("message",t=>{e(t.data)})},close:()=>{i.close(),this.channels.delete(e),d.info(`[StorageManager] Channel closed: ${e}`)}};return this.channels.set(e,n),d.info(`[StorageManager] Channel created: ${e}`),n},get:e=>this.channels.get(e)||null,close:e=>{const t=this.channels.get(e);t&&t.close()},closeAll:()=>{this.channels.forEach(e=>e.close()),this.channels.clear(),d.info("[StorageManager] All channels closed")}}),t(this,"locks",{acquire:async(e,t,i={})=>{if(!this.support.webLocks)return d.warn("[StorageManager] Web Locks not supported, executing without lock"),await t();try{return await navigator.locks.request(e,i,async i=>{d.info(`[StorageManager] Lock acquired: ${e}`);const n=await t(i);return d.info(`[StorageManager] Lock released: ${e}`),n})}catch(n){throw d.error(`[StorageManager] Lock failed: ${e}`,n),n}},query:async()=>{if(!this.support.webLocks)return{held:[],pending:[]};try{return await navigator.locks.query()}catch(e){throw d.error("[StorageManager] Lock query failed:",e),e}}}),t(this,"local",{set:(e,t,i=null)=>{if(!this.support.localStorage)return!1;try{const n={value:t,timestamp:Date.now(),expiration:i?Date.now()+i:null};return localStorage.setItem(e,JSON.stringify(n)),!0}catch(n){return d.error("[StorageManager] localStorage set failed:",n),!1}},get:e=>{if(!this.support.localStorage)return null;try{const t=localStorage.getItem(e);if(!t)return null;const i=JSON.parse(t);return i.expiration&&Date.now()>i.expiration?(localStorage.removeItem(e),null):i.value}catch(t){return d.error("[StorageManager] localStorage get failed:",t),null}},delete:e=>!!this.support.localStorage&&(localStorage.removeItem(e),!0),clear:()=>!!this.support.localStorage&&(localStorage.clear(),!0),keys:()=>this.support.localStorage?Object.keys(localStorage):[]}),t(this,"session",{set:(e,t)=>{if(!this.support.sessionStorage)return!1;try{return sessionStorage.setItem(e,JSON.stringify(t)),!0}catch(i){return d.error("[StorageManager] sessionStorage set failed:",i),!1}},get:e=>{if(!this.support.sessionStorage)return null;try{const t=sessionStorage.getItem(e);return t?JSON.parse(t):null}catch(t){return d.error("[StorageManager] sessionStorage get failed:",t),null}},delete:e=>!!this.support.sessionStorage&&(sessionStorage.removeItem(e),!0),clear:()=>!!this.support.sessionStorage&&(sessionStorage.clear(),!0)}),t(this,"smartCache",{set:async(e,t,i={})=>{const{storage:n="indexedDB",expiration:r=null,fallback:a=!0}=i;try{if("indexedDB"===n&&this.db)return await this.db.set(e,t,r);if(a)return this.local.set(e,t,r)}catch(s){if(a)return this.local.set(e,t,r);throw s}},get:async(e,t={})=>{const{storage:i="indexedDB",fallback:n=!0}=t;try{if("indexedDB"===i&&this.db)return await this.db.get(e);if(n)return this.local.get(e)}catch(r){if(n)return this.local.get(e);throw r}},delete:async(e,t={})=>{const{storage:i="indexedDB",fallback:n=!0}=t;try{"indexedDB"===i&&this.db&&await this.db.delete(e),n&&this.local.delete(e)}catch(r){throw n&&this.local.delete(e),r}}}),this.config=e,this.dbName=e.dbName||"AppDatabase",this.dbVersion=e.dbVersion||1,this.db=null,this.cache=null,this.channels=new Map,this.support={indexedDB:"indexedDB"in window,cacheAPI:"caches"in window,webLocks:"locks"in navigator,broadcastChannel:"BroadcastChannel"in window,localStorage:"localStorage"in window,sessionStorage:"sessionStorage"in window},d.info("[StorageManager] Initialized with support:",this.support),this.initializeDB(),this.initializeCache()}async initializeDB(){if(this.support.indexedDB)try{const e=indexedDB.open(this.dbName,this.dbVersion);e.onerror=()=>{d.error("[StorageManager] IndexedDB failed to open")},e.onupgradeneeded=e=>{const t=e.target.result;if(!t.objectStoreNames.contains("keyValue")){t.createObjectStore("keyValue",{keyPath:"key"}).createIndex("timestamp","timestamp",{unique:!1})}if(t.objectStoreNames.contains("cache")||t.createObjectStore("cache",{keyPath:"key"}),!t.objectStoreNames.contains("files")){const e=t.createObjectStore("files",{keyPath:"id",autoIncrement:!0});e.createIndex("name","name",{unique:!1}),e.createIndex("type","type",{unique:!1})}d.info("[StorageManager] IndexedDB schema updated")},e.onsuccess=e=>{this.db=e.target.result,d.info("[StorageManager] IndexedDB connected")}}catch(e){d.error("[StorageManager] IndexedDB initialization failed:",e)}else d.warn("[StorageManager] IndexedDB not supported")}async initializeCache(){if(this.support.cacheAPI)try{this.cache=await caches.open(this.config.cacheName||"app-cache-v1"),d.info("[StorageManager] Cache API initialized")}catch(e){d.error("[StorageManager] Cache API initialization failed:",e)}else d.warn("[StorageManager] Cache API not supported")}async getStorageUsage(){const e={quota:0,usage:0,available:0,percentage:0};if("storage"in navigator&&"estimate"in navigator.storage)try{const t=await navigator.storage.estimate();e.quota=t.quota||0,e.usage=t.usage||0,e.available=e.quota-e.usage,e.percentage=e.quota>0?Math.round(e.usage/e.quota*100):0}catch(t){d.error("[StorageManager] Storage estimate failed:",t)}return e}async cleanup(){d.info("[StorageManager] Starting cleanup...");try{if(this.db){const e=this.db.transaction(["keyValue"],"readwrite").objectStore("keyValue"),t=e.index("timestamp").openCursor();let i=0;t.onsuccess=e=>{const t=e.target.result;if(t){const e=t.value;e.expiration&&Date.now()>e.expiration&&(t.delete(),i++),t.continue()}else d.info(`[StorageManager] Cleanup completed: ${i} expired entries removed`)}}if(this.support.localStorage){const e=Object.keys(localStorage);let t=0;e.forEach(e=>{try{const i=localStorage.getItem(e),n=JSON.parse(i);n.expiration&&Date.now()>n.expiration&&(localStorage.removeItem(e),t++)}catch(i){}}),t>0&&d.info(`[StorageManager] LocalStorage cleanup: ${t} expired entries removed`)}}catch(e){d.error("[StorageManager] Cleanup failed:",e)}}async getStatus(){const e=await this.getStorageUsage();return{support:this.support,usage:e,activeChannels:this.channels.size,dbConnected:!!this.db,cacheConnected:!!this.cache,channelNames:Array.from(this.channels.keys())}}}class g{constructor(e={}){t(this,"geolocation",{getCurrent:(e={})=>new Promise((t,i)=>{if(!this.support.geolocation)return void i(new Error("Geolocation not supported"));const n={enableHighAccuracy:!0,timeout:1e4,maximumAge:6e4,...e};navigator.geolocation.getCurrentPosition(e=>{const i=this.enhanceLocationData(e);d.info("[DeviceManager] Location acquired:",{lat:i.latitude,lng:i.longitude,accuracy:i.accuracy}),t(i)},e=>{d.error("[DeviceManager] Geolocation failed:",e.message),i(e)},n)}),watch:(e,t={})=>{if(!this.support.geolocation)throw new Error("Geolocation not supported");const i={enableHighAccuracy:!0,timeout:3e4,maximumAge:1e4,...t},n=navigator.geolocation.watchPosition(t=>{const i=this.enhanceLocationData(t);e(i)},t=>{d.error("[DeviceManager] Location watch failed:",t.message),e({error:t})},i);return this.activeWatchers.set(`geo_${n}`,{type:"geolocation",id:n,stop:()=>{navigator.geolocation.clearWatch(n),this.activeWatchers.delete(`geo_${n}`)}}),d.info("[DeviceManager] Location watch started:",n),{id:n,stop:()=>{navigator.geolocation.clearWatch(n),this.activeWatchers.delete(`geo_${n}`),d.info("[DeviceManager] Location watch stopped:",n)}}},distance:(e,t)=>{const i=this.toRadians(t.latitude-e.latitude),n=this.toRadians(t.longitude-e.longitude),r=Math.sin(i/2)*Math.sin(i/2)+Math.cos(this.toRadians(e.latitude))*Math.cos(this.toRadians(t.latitude))*Math.sin(n/2)*Math.sin(n/2),a=6371*(2*Math.atan2(Math.sqrt(r),Math.sqrt(1-r)));return{kilometers:a,miles:.621371*a,meters:1e3*a}}}),t(this,"motion",{start:(e,t={})=>{if(!this.support.deviceMotion)throw new Error("Device Motion not supported");const i=t=>{const i={acceleration:t.acceleration,accelerationIncludingGravity:t.accelerationIncludingGravity,rotationRate:t.rotationRate,interval:t.interval,timestamp:t.timeStamp,totalAcceleration:this.calculateTotalAcceleration(t.acceleration),shake:this.detectShake(t.accelerationIncludingGravity),orientation:this.getDeviceOrientation(t)};e(i)};"function"==typeof DeviceMotionEvent.requestPermission?DeviceMotionEvent.requestPermission().then(e=>{"granted"===e&&window.addEventListener("devicemotion",i)}):window.addEventListener("devicemotion",i);const n=this.generateId("motion");return this.activeWatchers.set(n,{type:"motion",handler:i,stop:()=>{window.removeEventListener("devicemotion",i),this.activeWatchers.delete(n)}}),d.info("[DeviceManager] Motion detection started"),{id:n,stop:()=>{window.removeEventListener("devicemotion",i),this.activeWatchers.delete(n),d.info("[DeviceManager] Motion detection stopped")}}},startOrientation:(e,t={})=>{if(!this.support.deviceOrientation)throw new Error("Device Orientation not supported");const i=t=>{const i={alpha:t.alpha,beta:t.beta,gamma:t.gamma,absolute:t.absolute,timestamp:t.timeStamp,compass:this.calculateCompass(t.alpha),tilt:this.calculateTilt(t.beta,t.gamma),rotation:this.getRotationState(t)};e(i)};"function"==typeof DeviceOrientationEvent.requestPermission?DeviceOrientationEvent.requestPermission().then(e=>{"granted"===e&&window.addEventListener("deviceorientation",i)}):window.addEventListener("deviceorientation",i);const n=this.generateId("orientation");return this.activeWatchers.set(n,{type:"orientation",handler:i,stop:()=>{window.removeEventListener("deviceorientation",i),this.activeWatchers.delete(n)}}),d.info("[DeviceManager] Orientation detection started"),{id:n,stop:()=>{window.removeEventListener("deviceorientation",i),this.activeWatchers.delete(n),d.info("[DeviceManager] Orientation detection stopped")}}}}),t(this,"vibration",{vibrate:e=>{if(!this.support.vibration)return d.warn("[DeviceManager] Vibration not supported"),!1;try{return navigator.vibrate(e),d.info("[DeviceManager] Vibration triggered:",e),!0}catch(t){return d.error("[DeviceManager] Vibration failed:",t),!1}},patterns:{short:200,long:600,double:[200,100,200],triple:[200,100,200,100,200],sos:[100,30,100,30,100,200,200,30,200,30,200,200,100,30,100,30,100],heartbeat:[100,30,100,130,40,30,40,30,100],notification:[200,100,200],success:[100],error:[300,100,300],warning:[200,100,200,100,200]},stop:()=>{this.support.vibration&&(navigator.vibrate(0),d.info("[DeviceManager] Vibration stopped"))},success:()=>this.vibration.vibrate(this.vibration.patterns.success),error:()=>this.vibration.vibrate(this.vibration.patterns.error),warning:()=>this.vibration.vibrate(this.vibration.patterns.warning),notification:()=>this.vibration.vibrate(this.vibration.patterns.notification)}),t(this,"battery",{get:async()=>{if(!this.support.battery)return d.warn("[DeviceManager] Battery API not supported"),null;try{const e=await navigator.getBattery(),t={level:Math.round(100*e.level),charging:e.charging,chargingTime:e.chargingTime,dischargingTime:e.dischargingTime,status:this.getBatteryStatus(e),timeRemaining:this.formatBatteryTime(e)};return d.info("[DeviceManager] Battery status:",t),t}catch(e){return d.error("[DeviceManager] Battery status failed:",e),null}},watch:async e=>{if(!this.support.battery)throw new Error("Battery API not supported");try{const t=await navigator.getBattery(),i=[];["chargingchange","levelchange","chargingtimechange","dischargingtimechange"].forEach(n=>{const r=()=>{const i={level:Math.round(100*t.level),charging:t.charging,chargingTime:t.chargingTime,dischargingTime:t.dischargingTime,status:this.getBatteryStatus(t),timeRemaining:this.formatBatteryTime(t),event:n};e(i)};t.addEventListener(n,r),i.push({event:n,handler:r})});const n=this.generateId("battery");return this.activeWatchers.set(n,{type:"battery",battery:t,handlers:i,stop:()=>{i.forEach(({event:e,handler:i})=>{t.removeEventListener(e,i)}),this.activeWatchers.delete(n)}}),d.info("[DeviceManager] Battery watch started"),{id:n,stop:()=>{i.forEach(({event:e,handler:i})=>{t.removeEventListener(e,i)}),this.activeWatchers.delete(n),d.info("[DeviceManager] Battery watch stopped")}}}catch(t){throw d.error("[DeviceManager] Battery watch failed:",t),t}}}),t(this,"network",{get:()=>{if(!this.support.networkInfo)return d.warn("[DeviceManager] Network Information not supported"),null;const e=navigator.connection||navigator.mozConnection||navigator.webkitConnection;return{effectiveType:e.effectiveType,downlink:e.downlink,rtt:e.rtt,saveData:e.saveData,speed:this.getConnectionSpeed(e),quality:this.getConnectionQuality(e),recommendation:this.getNetworkRecommendation(e)}},watch:e=>{if(!this.support.networkInfo)throw new Error("Network Information not supported");const t=navigator.connection||navigator.mozConnection||navigator.webkitConnection,i=()=>{const i={effectiveType:t.effectiveType,downlink:t.downlink,rtt:t.rtt,saveData:t.saveData,speed:this.getConnectionSpeed(t),quality:this.getConnectionQuality(t),recommendation:this.getNetworkRecommendation(t)};e(i)};t.addEventListener("change",i);const n=this.generateId("network");return this.activeWatchers.set(n,{type:"network",connection:t,handler:i,stop:()=>{t.removeEventListener("change",i),this.activeWatchers.delete(n)}}),d.info("[DeviceManager] Network watch started"),{id:n,stop:()=>{t.removeEventListener("change",i),this.activeWatchers.delete(n),d.info("[DeviceManager] Network watch stopped")}}}}),t(this,"wakeLock",{request:async(e="screen")=>{if(!this.support.wakeLock)return d.warn("[DeviceManager] Wake Lock not supported"),null;try{const t=await navigator.wakeLock.request(e);return d.info(`[DeviceManager] Wake lock acquired: ${e}`),{type:t.type,release:()=>{t.release(),d.info(`[DeviceManager] Wake lock released: ${e}`)}}}catch(t){throw d.error("[DeviceManager] Wake lock failed:",t),t}}}),this.config=e,this.activeWatchers=new Map,this.sensorData=new Map,this.support={geolocation:"geolocation"in navigator,deviceMotion:"DeviceMotionEvent"in window,deviceOrientation:"DeviceOrientationEvent"in window,vibration:"vibrate"in navigator,battery:"getBattery"in navigator,networkInfo:"connection"in navigator||"mozConnection"in navigator||"webkitConnection"in navigator,wakeLock:"wakeLock"in navigator,bluetooth:"bluetooth"in navigator,usb:"usb"in navigator,serial:"serial"in navigator},d.info("[DeviceManager] Initialized with support:",this.support),this.initializeSensors()}initializeSensors(){(this.support.deviceMotion||this.support.deviceOrientation)&&(this.sensorData.set("motionBaseline",{x:0,y:0,z:0}),this.sensorData.set("shakeThreshold",this.config.shakeThreshold||15))}enhanceLocationData(e){return{latitude:e.coords.latitude,longitude:e.coords.longitude,accuracy:e.coords.accuracy,altitude:e.coords.altitude,altitudeAccuracy:e.coords.altitudeAccuracy,heading:e.coords.heading,speed:e.coords.speed,timestamp:e.timestamp,coordinates:`${e.coords.latitude},${e.coords.longitude}`,accuracyLevel:this.getAccuracyLevel(e.coords.accuracy),mapUrl:`https://maps.google.com/?q=${e.coords.latitude},${e.coords.longitude}`}}getAccuracyLevel(e){return e<=5?"excellent":e<=10?"good":e<=50?"fair":"poor"}calculateTotalAcceleration(e){if(!e)return 0;const t=e.x||0,i=e.y||0,n=e.z||0;return Math.sqrt(t*t+i*i+n*n)}detectShake(e){if(!e)return!1;const t=this.sensorData.get("shakeThreshold"),i=Math.abs(e.x||0),n=Math.abs(e.y||0),r=Math.abs(e.z||0);return i>t||n>t||r>t}getDeviceOrientation(e){const t=e.accelerationIncludingGravity;if(!t)return"unknown";const i=t.x||0,n=t.y||0,r=t.z||0;return Math.abs(i)>Math.abs(n)&&Math.abs(i)>Math.abs(r)?i>0?"landscape-right":"landscape-left":Math.abs(n)>Math.abs(r)?n>0?"portrait-upside-down":"portrait":r>0?"face-down":"face-up"}calculateCompass(e){if(null===e)return null;const t=Math.round(e/45)%8;return{degrees:Math.round(e),direction:["N","NE","E","SE","S","SW","W","NW"][t],cardinal:this.getCardinalDirection(e)}}getCardinalDirection(e){return e>=337.5||e<22.5?"North":e>=22.5&&e<67.5?"Northeast":e>=67.5&&e<112.5?"East":e>=112.5&&e<157.5?"Southeast":e>=157.5&&e<202.5?"South":e>=202.5&&e<247.5?"Southwest":e>=247.5&&e<292.5?"West":e>=292.5&&e<337.5?"Northwest":"Unknown"}calculateTilt(e,t){return{x:Math.round(e||0),y:Math.round(t||0),magnitude:Math.round(Math.sqrt((e||0)**2+(t||0)**2))}}getRotationState(e){const{alpha:t,beta:i,gamma:n}=e,r=Math.abs(i)>10||Math.abs(n)>10;return{isRotating:r,intensity:r?Math.max(Math.abs(i),Math.abs(n)):0}}getBatteryStatus(e){const t=100*e.level;return e.charging?"charging":t<=10?"critical":t<=20?"low":t<=50?"medium":"high"}formatBatteryTime(e){const t=e.charging?e.chargingTime:e.dischargingTime;if(t===1/0||isNaN(t))return"Unknown";return`${Math.floor(t/3600)}h ${Math.floor(t%3600/60)}m`}getConnectionSpeed(e){const t=e.downlink;return t>=10?"fast":t>=1.5?"good":t>=.5?"slow":"very-slow"}getConnectionQuality(e){switch(e.effectiveType){case"4g":return"excellent";case"3g":return"good";case"2g":return"poor";case"slow-2g":return"very-poor";default:return"unknown"}}getNetworkRecommendation(e){switch(this.getConnectionQuality(e)){case"excellent":return"Full quality content recommended";case"good":return"Moderate quality content recommended";case"poor":return"Light content only, avoid large files";case"very-poor":return"Text-only content recommended";default:return"Monitor connection quality"}}toRadians(e){return e*(Math.PI/180)}generateId(e="device"){return`${e}_${Date.now()}_${Math.random().toString(36).substr(2,9)}`}stopAllWatchers(){this.activeWatchers.forEach(e=>{e.stop()}),this.activeWatchers.clear(),d.info("[DeviceManager] All watchers stopped")}getCapabilities(){return{support:this.support,activeWatchers:this.activeWatchers.size,watcherTypes:Array.from(this.activeWatchers.values()).map(e=>e.type)}}}class p{constructor(e={}){t(this,"effects",{fadeIn:(e=300)=>[{opacity:0},{opacity:1}],slideInLeft:(e="100px",t=300)=>[{transform:`translateX(-${e})`,opacity:0},{transform:"translateX(0)",opacity:1}],slideInRight:(e="100px",t=300)=>[{transform:`translateX(${e})`,opacity:0},{transform:"translateX(0)",opacity:1}],slideInUp:(e="100px",t=300)=>[{transform:`translateY(${e})`,opacity:0},{transform:"translateY(0)",opacity:1}],slideInDown:(e="100px",t=300)=>[{transform:`translateY(-${e})`,opacity:0},{transform:"translateY(0)",opacity:1}],scaleIn:(e=.8,t=300)=>[{transform:`scale(${e})`,opacity:0},{transform:"scale(1)",opacity:1}],rotateIn:(e="-180deg",t=600)=>[{transform:`rotate(${e})`,opacity:0},{transform:"rotate(0deg)",opacity:1}],fadeOut:(e=300)=>[{opacity:1},{opacity:0}],slideOutLeft:(e="100px",t=300)=>[{transform:"translateX(0)",opacity:1},{transform:`translateX(-${e})`,opacity:0}],slideOutRight:(e="100px",t=300)=>[{transform:"translateX(0)",opacity:1},{transform:`translateX(${e})`,opacity:0}],scaleOut:(e=.8,t=300)=>[{transform:"scale(1)",opacity:1},{transform:`scale(${e})`,opacity:0}],bounce:(e="20px",t=600)=>[{transform:"translateY(0)"},{transform:`translateY(-${e})`,offset:.25},{transform:"translateY(0)",offset:.5},{transform:`translateY(-${e})`,offset:.75},{transform:"translateY(0)"}],pulse:(e=1.1,t=600)=>[{transform:"scale(1)"},{transform:`scale(${e})`,offset:.5},{transform:"scale(1)"}],shake:(e="10px",t=600)=>[{transform:"translateX(0)"},{transform:`translateX(-${e})`,offset:.1},{transform:`translateX(${e})`,offset:.2},{transform:`translateX(-${e})`,offset:.3},{transform:`translateX(${e})`,offset:.4},{transform:`translateX(-${e})`,offset:.5},{transform:`translateX(${e})`,offset:.6},{transform:`translateX(-${e})`,offset:.7},{transform:`translateX(${e})`,offset:.8},{transform:`translateX(-${e})`,offset:.9},{transform:"translateX(0)"}],rubberBand:(e=1e3)=>[{transform:"scale(1)"},{transform:"scale(1.25, 0.75)",offset:.3},{transform:"scale(0.75, 1.25)",offset:.4},{transform:"scale(1.15, 0.85)",offset:.5},{transform:"scale(0.95, 1.05)",offset:.65},{transform:"scale(1.05, 0.95)",offset:.75},{transform:"scale(1)"}],spin:(e=1e3)=>[{transform:"rotate(0deg)"},{transform:"rotate(360deg)"}],heartbeat:(e=1.3,t=1e3)=>[{transform:"scale(1)"},{transform:`scale(${e})`,offset:.14},{transform:"scale(1)",offset:.28},{transform:`scale(${e})`,offset:.42},{transform:"scale(1)",offset:.7}]}),t(this,"easings",{linear:"linear",ease:"ease",easeIn:"ease-in",easeOut:"ease-out",easeInOut:"ease-in-out",easeInQuad:"cubic-bezier(0.25, 0.46, 0.45, 0.94)",easeOutQuad:"cubic-bezier(0.25, 0.46, 0.45, 0.94)",easeInOutQuad:"cubic-bezier(0.455, 0.03, 0.515, 0.955)",easeInCubic:"cubic-bezier(0.32, 0, 0.67, 0)",easeOutCubic:"cubic-bezier(0.33, 1, 0.68, 1)",easeInOutCubic:"cubic-bezier(0.65, 0, 0.35, 1)",easeInQuart:"cubic-bezier(0.5, 0, 0.75, 0)",easeOutQuart:"cubic-bezier(0.25, 1, 0.5, 1)",easeInOutQuart:"cubic-bezier(0.76, 0, 0.24, 1)",easeOutBack:"cubic-bezier(0.34, 1.56, 0.64, 1)",easeInBack:"cubic-bezier(0.36, 0, 0.66, -0.56)",easeInOutBack:"cubic-bezier(0.68, -0.6, 0.32, 1.6)"}),this.config=e,this.activeAnimations=new Map,this.animationGroups=new Map,this.defaultEasing=e.easing||"ease-out",this.defaultDuration=e.duration||300,this.supported="animate"in Element.prototype,this.supported?d.info("[AnimationManager] Initialized with Web Animations API support"):d.warn("[AnimationManager] Web Animations API not supported, using fallbacks")}animate(e,t,i={}){if(!e||!t)return d.warn("[AnimationManager] Missing element or keyframes"),null;const n={duration:this.defaultDuration,easing:this.defaultEasing,fill:"forwards",...i},r=this.generateId();if(this.supported){const i=e.animate(t,n),a=this.enhanceAnimation(i,r,{element:e,keyframes:t,options:n});return this.activeAnimations.set(r,a),i.addEventListener("finish",()=>{this.activeAnimations.delete(r)}),d.info(`[AnimationManager] Animation started: ${r}`),a}return this.fallbackAnimate(e,t,n,r)}keyframes(e){if(Array.isArray(e))return e;if("object"==typeof e){const t=[];return Object.keys(e).sort((e,t)=>parseFloat(e.replace("%",""))-parseFloat(t.replace("%",""))).forEach(i=>{const n=parseFloat(i.replace("%",""))/100;t.push({...e[i],offset:n})}),t}return e}fadeIn(e,t={}){return this.animate(e,this.effects.fadeIn(),{duration:300,easing:this.easings.easeOut,...t})}fadeOut(e,t={}){return this.animate(e,this.effects.fadeOut(),{duration:300,easing:this.easings.easeIn,...t})}slideIn(e,t="up",i={}){return this.animate(e,this.effects[{up:"slideInUp",down:"slideInDown",left:"slideInLeft",right:"slideInRight"}[t]](),{duration:400,easing:this.easings.easeOutBack,...i})}bounce(e,t={}){return this.animate(e,this.effects.bounce(),{duration:600,easing:this.easings.easeInOut,...t})}pulse(e,t={}){return this.animate(e,this.effects.pulse(),{duration:600,easing:this.easings.easeInOut,iterations:1/0,...t})}group(e,t={}){const i=this.generateId("group"),n=[];e.forEach(({element:e,keyframes:i,animationOptions:r={}})=>{const a=this.animate(e,i,{...r,...t});a&&a.finished&&n.push(a.finished)});const r={id:i,finished:Promise.all(n),play:()=>{e.forEach(e=>{e.animation&&e.animation.play()})},pause:()=>{e.forEach(e=>{e.animation&&e.animation.pause()})},reverse:()=>{e.forEach(e=>{e.animation&&e.animation.reverse()})},cancel:()=>{e.forEach(e=>{e.animation&&e.animation.cancel()})}};return this.animationGroups.set(i,r),r}stagger(e,t,i={}){const n=i.staggerDelay||100,r=[];return e.forEach((e,a)=>{const s=a*n,o=this.animate(e,t,{...i,delay:s});r.push({element:e,animation:o})}),this.group(r.map(({element:e,animation:i})=>({element:e,keyframes:t,animation:i})))}timeline(e){const t=this.generateId("timeline");let i=0;const n=[];return e.forEach(e=>{var t;const r=void 0!==e.at?e.at:i,a=this.animate(e.element,e.keyframes,{...e.options,delay:r});n.push(a),void 0===e.at&&(i+=(null==(t=e.options)?void 0:t.duration)||this.defaultDuration)}),{id:t,animations:n,finished:Promise.all(n.map(e=>e.finished)),play:()=>n.forEach(e=>e.play()),pause:()=>n.forEach(e=>e.pause()),reverse:()=>n.forEach(e=>e.reverse()),cancel:()=>n.forEach(e=>e.cancel())}}onScroll(e,t,i={}){const n=i.trigger||e,r=i.start||0,a=i.end||1,s=new IntersectionObserver(n=>{n.forEach(n=>{if(n.isIntersecting){Math.min(Math.max((n.intersectionRatio-r)/(a-r),0),1)>=0&&this.animate(e,t,{...i,duration:i.duration||this.defaultDuration})}})},{threshold:this.createThresholdArray(20)});return s.observe(n),{observer:s,disconnect:()=>s.disconnect()}}enhanceAnimation(e,t,i){return{id:t,animation:e,metadata:i,play:()=>e.play(),pause:()=>e.pause(),reverse:()=>e.reverse(),cancel:()=>e.cancel(),finish:()=>e.finish(),get currentTime(){return e.currentTime},set currentTime(t){e.currentTime=t},get playbackRate(){return e.playbackRate},set playbackRate(t){e.playbackRate=t},get playState(){return e.playState},get finished(){return e.finished},seek(t){e.currentTime=e.effect.getTiming().duration*t},setProgress(e){this.seek(Math.max(0,Math.min(1,e)))},onFinish(t){e.addEventListener("finish",t)},onCancel(t){e.addEventListener("cancel",t)}}}fallbackAnimate(e,t,i,n){d.info("[AnimationManager] Using CSS fallback animation");const r=t[t.length-1];return e.style.transition=`all ${i.duration}ms ${i.easing}`,Object.assign(e.style,r),{id:n,finished:new Promise(e=>setTimeout(e,i.duration)),play:()=>{},pause:()=>{},cancel:()=>{e.style.transition=""}}}generateId(e="anim"){return`${e}_${Date.now()}_${Math.random().toString(36).substr(2,9)}`}createThresholdArray(e){const t=[];for(let i=0;i<=e;i++)t.push(i/e);return t}getActiveAnimations(){return Array.from(this.activeAnimations.entries()).map(([e,t])=>({id:e,playState:t.playState,currentTime:t.currentTime,metadata:t.metadata}))}cancelAll(){this.activeAnimations.forEach(e=>{e.cancel()}),this.activeAnimations.clear(),d.info("[AnimationManager] All animations cancelled")}pauseAll(){this.activeAnimations.forEach(e=>{e.pause()}),d.info("[AnimationManager] All animations paused")}resumeAll(){this.activeAnimations.forEach(e=>{"paused"===e.playState&&e.play()}),d.info("[AnimationManager] All animations resumed")}}class f{constructor(e={}){t(this,"web",{create:(e,t={})=>{if(!this.support.webWorkers)throw new Error("Web Workers not supported");let i;const n=this.generateId("worker");try{if("string"==typeof e)i=new Worker(e,t);else if("function"==typeof e){const n=this.createWorkerBlob(e);i=new Worker(URL.createObjectURL(n),t)}else{if(!(e instanceof Blob))throw new Error("Invalid script type");i=new Worker(URL.createObjectURL(e),t)}const r={id:n,worker:i,send:(e,t=null)=>{t?i.postMessage(e,t):i.postMessage(e),d.info(`[WorkerManager] Message sent to worker: ${n}`)},onMessage:e=>{i.addEventListener("message",t=>{e(t.data,t)})},onError:e=>{i.addEventListener("error",e),i.addEventListener("messageerror",e)},terminate:()=>{i.terminate(),this.activeWorkers.delete(n),d.info(`[WorkerManager] Worker terminated: ${n}`)},execute:(e,t=null)=>new Promise((n,r)=>{const a=this.generateId("msg"),s=e=>{e.data.id===a&&(i.removeEventListener("message",s),e.data.error?r(new Error(e.data.error)):n(e.data.result))};i.addEventListener("message",s),i.postMessage({id:a,type:"execute",function:e.toString(),data:t}),setTimeout(()=>{i.removeEventListener("message",s),r(new Error("Worker execution timeout"))},3e4)})};return this.activeWorkers.set(n,r),d.info(`[WorkerManager] Web Worker created: ${n}`),r}catch(r){throw d.error("[WorkerManager] Worker creation failed:",r),r}},createPool:(e,t=navigator.hardwareConcurrency||4,i={})=>{const n=[];for(let s=0;s<t;s++)n.push(this.web.create(e,i));let r=0;const a={workers:n,execute:async(e,t=null)=>{const i=n[r];return r=(r+1)%n.length,i.execute(e,t)},broadcast:e=>{n.forEach(t=>{t.send(e)})},terminate:()=>{n.forEach(e=>{e.terminate()}),n.length=0,d.info("[WorkerManager] Worker pool terminated")}};return d.info(`[WorkerManager] Worker pool created with ${t} workers`),a},tasks:{compute:(e,t)=>this.web.create("\n self.addEventListener('message', function(e) {\n const { id, function: fnString, data } = e.data;\n \n try {\n const fn = new Function('return ' + fnString)();\n const result = fn(data);\n self.postMessage({ id, result });\n } catch (error) {\n self.postMessage({ id, error: error.message });\n }\n });\n ").execute(e,t),processImage:(e,t)=>this.web.create("\n self.addEventListener('message', function(e) {\n const { id, data: { imageData, filters } } = e.data;\n \n try {\n const pixels = imageData.data;\n \n for (let i = 0; i < pixels.length; i += 4) {\n // Apply filters\n if (filters.brightness) {\n pixels[i] *= filters.brightness; // R\n pixels[i + 1] *= filters.brightness; // G\n pixels[i + 2] *= filters.brightness; // B\n }\n \n if (filters.contrast) {\n const factor = (259 * (filters.contrast * 255 + 255)) / (255 * (259 - filters.contrast * 255));\n pixels[i] = factor * (pixels[i] - 128) + 128;\n pixels[i + 1] = factor * (pixels[i + 1] - 128) + 128;\n pixels[i + 2] = factor * (pixels[i + 2] - 128) + 128;\n }\n \n if (filters.grayscale) {\n const gray = 0.299 * pixels[i] + 0.587 * pixels[i + 1] + 0.114 * pixels[i + 2];\n pixels[i] = gray;\n pixels[i + 1] = gray;\n pixels[i + 2] = gray;\n }\n }\n \n self.postMessage({ id, result: imageData }, [imageData.data.buffer]);\n } catch (error) {\n self.postMessage({ id, error: error.message });\n }\n });\n ").execute(null,{imageData:e,filters:t}),processData:(e,t)=>this.web.create("\n self.addEventListener('message', function(e) {\n const { id, data, function: processorString } = e.data;\n \n try {\n const processor = new Function('return ' + processorString)();\n const result = data.map(processor);\n self.postMessage({ id, result });\n } catch (error) {\n self.postMessage({ id, error: error.message });\n }\n });\n ").execute(t,e)}}),t(this,"service",{register:async(e,t={})=>{if(!this.support.serviceWorker)throw new Error("Service Worker not supported");try{const i=await navigator.serviceWorker.register(e,t);return d.info("[WorkerManager] Service Worker registered:",e),{registration:i,scope:i.scope,update:()=>i.update(),unregister:()=>i.unregister(),postMessage:e=>{i.active&&i.active.postMessage(e)},onUpdate:e=>{i.addEventListener("updatefound",()=>{const t=i.installing;t.addEventListener("statechange",()=>{"installed"===t.state&&navigator.serviceWorker.controller&&e(t)})})},checkForUpdates:()=>i.update()}}catch(i){throw d.error("[WorkerManager] Service Worker registration failed:",i),i}},getRegistration:async(e="/")=>{if(!this.support.serviceWorker)return null;try{return await navigator.serviceWorker.getRegistration(e)}catch(t){return d.error("[WorkerManager] Get registration failed:",t),null}},getRegistrations:async()=>{if(!this.support.serviceWorker)return[];try{return await navigator.serviceWorker.getRegistrations()}catch(e){return d.error("[WorkerManager] Get registrations failed:",e),[]}}}),t(this,"shared",{create:(e,t={})=>{if(!this.support.sharedWorker)throw new Error("Shared Worker not supported");try{const i=new SharedWorker(e,t),n=i.port,r=this.generateId("shared");n.start();const a={id:r,worker:i,port:n,send:(e,t=null)=>{t?n.postMessage(e,t):n.postMessage(e)},onMessage:e=>{n.addEventListener("message",t=>{e(t.data,t)})},onError:e=>{i.addEventListener("error",e),n.addEventListener("messageerror",e)},close:()=>{n.close(),this.activeWorkers.delete(r),d.info(`[WorkerManager] Shared Worker closed: ${r}`)}};return this.activeWorkers.set(r,a),d.info(`[WorkerManager] Shared Worker created: ${r}`),a}catch(i){throw d.error("[WorkerManager] Shared Worker creation failed:",i),i}}}),t(this,"offscreen",{create:(e,t=null)=>{if(!this.support.offscreenCanvas)throw new Error("Offscreen Canvas not supported");try{const i=e.transferControlToOffscreen(),n=t||"\n self.addEventListener('message', function(e) {\n const { canvas, type, data } = e.data;\n \n if (type === 'init') {\n self.canvas = canvas;\n self.ctx = canvas.getContext('2d');\n }\n \n if (type === 'draw' && self.ctx) {\n // Basic drawing operations\n const { operations } = data;\n \n operations.forEach(op => {\n switch (op.type) {\n case 'fillRect':\n self.ctx.fillRect(...op.args);\n break;\n case 'strokeRect':\n self.ctx.strokeRect(...op.args);\n break;\n case 'fillText':\n self.ctx.fillText(...op.args);\n break;\n case 'setFillStyle':\n self.ctx.fillStyle = op.value;\n break;\n case 'setStrokeStyle':\n self.ctx.strokeStyle = op.value;\n break;\n }\n });\n }\n });\n ",r=this.web.create(n);return r.send({type:"init",canvas:i},[i]),{worker:r,draw:e=>{r.send({type:"draw",data:{operations:e}})},send:e=>r.send(e),onMessage:e=>r.onMessage(e),terminate:()=>r.terminate()}}catch(i){throw d.error("[WorkerManager] Offscreen Canvas creation failed:",i),i}}}),t(this,"utils",{benchmark:async(e,t,i=1e3)=>{const n=this.web.create(()=>{self.addEventListener("message",e=>{const{id:t,function:i,data:n,iterations:r}=e.data;try{const e=new Function("return "+i)(),a=performance.now();for(let t=0;t<r;t++)e(n);const s=performance.now()-a,o=s/r;self.postMessage({id:t,result:{totalTime:s,avgTime:o,iterations:r,opsPerSecond:1e3/o}})}catch(a){self.postMessage({id:t,error:a.message})}})}),r=await n.execute(e,t,i);return n.terminate(),r},parallelMap:async(e,t,i=null)=>{const n=i||Math.ceil(e.length/(navigator.hardwareConcurrency||4)),r=this.web.createPool(()=>{self.addEventListener("message",e=>{const{id:t,data:{chunk:i,function:n}}=e.data;try{const e=new Function("return "+n)(),r=i.map(e);self.postMessage({id:t,result:r})}catch(r){self.postMessage({id:t,error:r.message})}})}),a=[];for(let o=0;o<e.length;o+=n){const i=e.slice(o,o+n);a.push(r.execute(t,i))}const s=await Promise.all(a);return r.terminate(),s.flat()}}),this.config=e,this.activeWorkers=new Map,this.messageHandlers=new Map,this.workerScripts=new Map,this.support={webWorkers:"Worker"in window,serviceWorker:"serviceWorker"in navigator,sharedWorker:"SharedWorker"in window,offscreenCanvas:"OffscreenCanvas"in window},d.info("[WorkerManager] Initialized with support:",this.support)}createWorkerBlob(e){const t=`\n (function() {\n const workerFunction = ${e.toString()};\n \n if (typeof workerFunction === 'function') {\n // If function expects to be called immediately\n if (workerFunction.length === 0) {\n workerFunction();\n }\n }\n \n // Standard worker message handling\n self.addEventListener('message', function(e) {\n if (e.data.type === 'execute' && e.data.function) {\n try {\n const fn = new Function('return ' + e.data.function)();\n const result = fn(e.data.data);\n self.postMessage({ \n id: e.data.id, \n result \n });\n } catch (error) {\n self.postMessage({ \n id: e.data.id, \n error: error.message \n });\n }\n }\n });\n })();\n `;return new Blob([t],{type:"application/javascript"})}generateId(e="worker"){return`${e}_${Date.now()}_${Math.random().toString(36).substr(2,9)}`}terminateAll(){this.activeWorkers.forEach(e=>{e.terminate?e.terminate():e.close&&e.close()}),this.activeWorkers.clear(),d.info("[WorkerManager] All workers terminated")}getStats(){const e=Array.from(this.activeWorkers.values());return{total:e.length,byType:e.reduce((e,t)=>{const i=t.id.split("_")[0];return e[i]=(e[i]||0)+1,e},{}),support:this.support,hardwareConcurrency:navigator.hardwareConcurrency||"unknown"}}}class v{constructor(e={}){var i,n,r;t(this,"timing",{mark:(e,t={})=>{if(!this.support.userTiming)return d.warn("[PerformanceManager] User Timing not supported"),null;try{return performance.mark(e,t),this.marks.set(e,{name:e,timestamp:performance.now(),options:t}),d.info(`[PerformanceManager] Mark created: ${e}`),this.marks.get(e)}catch(i){return d.error("[PerformanceManager] Mark creation failed:",i),null}},measure:(e,t,i,n={})=>{if(!this.support.userTiming)return d.warn("[PerformanceManager] User Timing not supported"),null;try{performance.measure(e,t,i,n);const r=performance.getEntriesByName(e,"measure")[0],a={name:e,startTime:r.startTime,duration:r.duration,startMark:t,endMark:i,options:n};return this.measures.set(e,a),d.info(`[PerformanceManager] Measure created: ${e} (${a.duration.toFixed(2)}ms)`),a}catch(r){return d.error("[PerformanceManager] Measure creation failed:",r),null}},clear:(e=null)=>{if(this.support.userTiming)try{e?(performance.clearMarks(e),performance.clearMeasures(e),this.marks.delete(e),this.measures.delete(e)):(performance.clearMarks(),performance.clearMeasures(),this.marks.clear(),this.measures.clear()),d.info(`[PerformanceManager] Cleared: ${e||"all"}`)}catch(t){d.error("[PerformanceManager] Clear failed:",t)}},getMarks:()=>this.support.userTiming?Array.from(this.marks.values()):[],getMeasures:()=>this.support.userTiming?Array.from(this.measures.values()):[]}),t(this,"navigation",{get:()=>{if(!this.support.navigation)return this.getLegacyNavigationTiming();try{const e=performance.getEntriesByType("navigation")[0];return e?{redirect:e.redirectEnd-e.redirectStart,dns:e.domainLookupEnd-e.domainLookupStart,connect:e.connectEnd-e.connectStart,ssl:e.connectEnd-e.secureConnectionStart,ttfb:e.responseStart-e.requestStart,download:e.responseEnd-e.responseStart,domProcessing:e.domContentLoadedEventStart-e.responseEnd,domComplete:e.domComplete-e.domContentLoadedEventStart,loadComplete:e.loadEventEnd-e.loadEventStart,totalTime:e.loadEventEnd-e.startTime,navigationStart:e.startTime,unloadTime:e.unloadEventEnd-e.unloadEventStart,redirectCount:e.redirectCount,transferSize:e.transferSize,encodedBodySize:e.encodedBodySize,decodedBodySize:e.decodedBodySize,connectionInfo:{nextHopProtocol:e.nextHopProtocol,renderBlockingStatus:e.renderBlockingStatus}}:null}catch(e){return d.error("[PerformanceManager] Navigation timing failed:",e),null}},getInsights:()=>{const e=this.navigation.get();return e?{insights:{serverResponseTime:this.getInsight("ttfb",e.ttfb,200,500),domProcessing:this.getInsight("domProcessing",e.domProcessing,500,1e3),totalLoadTime:this.getInsight("totalTime",e.totalTime,2e3,4e3),transferEfficiency:this.getTransferEfficiency(e)},recommendations:this.getNavigationRecommendations(e)}:null}}),t(this,"resources",{get:(e=null)=>{if(!this.support.resourceTiming)return d.warn("[PerformanceManager] Resource Timing not supported"),[];try{const t=performance.getEntriesByType("resource").map(e=>({name:e.name,type:this.getResourceType(e),startTime:e.startTime,duration:e.duration,size:{transfer:e.transferSize,encoded:e.encodedBodySize,decoded:e.decodedBodySize},timing:{redirect:e.redirectEnd-e.redirectStart,dns:e.domainLookupEnd-e.domainLookupStart,connect:e.connectEnd-e.connectStart,ssl:e.connectEnd-e.secureConnectionStart,ttfb:e.responseStart-e.requestStart,download:e.responseEnd-e.responseStart},protocol:e.nextHopProtocol,cached:0===e.transferSize&&e.decodedBodySize>0}));return e?t.filter(t=>t.type===e):t}catch(t){return d.error("[PerformanceManager] Resource timing failed:",t),[]}},getSummary:()=>{const e=this.resources.get(),t={total:e.length,types:{},totalSize:0,totalDuration:0,cached:0,slowResources:[]};return e.forEach(e=>{const i=e.type;t.types[i]||(t.types[i]={count:0,size:0,duration:0}),t.types[i].count++,t.types[i].size+=e.size.transfer,t.types[i].duration+=e.duration,t.totalSize+=e.size.transfer,t.totalDuration+=e.duration,e.cached&&t.cached++,e.duration>1e3&&t.slowResources.push(e)}),t}}),t(this,"vitals",{start:(e=null)=>{const t={};return this.observePaint(i=>{i.forEach(i=>{"first-contentful-paint"===i.name&&(t.fcp=i.startTime,this.checkThreshold("fcp",i.startTime),e&&e("fcp",i.startTime))})}),this.observeLCP(i=>{i.forEach(i=>{t.lcp=i.startTime,this.checkThreshold("lcp",i.startTime),e&&e("lcp",i.startTime)})}),this.observeFID(i=>{i.forEach(i=>{t.fid=i.processingStart-i.startTime,this.checkThreshold("fid",t.fid),e&&e("fid",t.fid)})}),this.observeCLS(i=>{let n=0;i.forEach(e=>{e.hadRecentInput||(n+=e.value)}),t.cls=n,this.checkThreshold("cls",n),e&&e("cls",n)}),t},get:()=>({fcp:this.getMetric("fcp"),lcp:this.getMetric("lcp"),fid:this.getMetric("fid"),cls:this.getMetric("cls"),ratings:{fcp:this.getRating("fcp",this.getMetric("fcp")),lcp:this.getRating("lcp",this.getMetric("lcp")),fid:this.getRating("fid",this.getMetric("fid")),cls:this.getRating("cls",this.getMetric("cls"))}})}),t(this,"memory",{get:()=>{if(!this.support.memory)return d.warn("[PerformanceManager] Memory API not supported"),null;try{const e=performance.memory;return{used:e.usedJSHeapSize,total:e.totalJSHeapSize,limit:e.jsHeapSizeLimit,percentage:e.usedJSHeapSize/e.jsHeapSizeLimit*100,formatted:{used:this.formatBytes(e.usedJSHeapSize),total:this.formatBytes(e.totalJSHeapSize),limit:this.formatBytes(e.jsHeapSizeLimit)}}}catch(e){return d.error("[PerformanceManager] Memory get failed:",e),null}},monitor:(e,t=5e3)=>{if(!this.support.memory)return null;const i=setInterval(()=>{const t=this.memory.get();t&&(e(t),t.percentage>80&&d.warn("[PerformanceManager] High memory usage detected:",t.percentage.toFixed(1)+"%"))},t);return{stop:()=>clearInterval(i)}}}),t(this,"longTasks",{start:(e=null)=>{if(!this.support.longTask)return d.warn("[PerformanceManager] Long Task API not supported"),null;try{const t=new PerformanceObserver(t=>{t.getEntries().forEach(t=>{const i={duration:t.duration,startTime:t.startTime,name:t.name,attribution:t.attribution||[]};d.warn("[PerformanceManager] Long task detected:",i),e&&e(i)})});t.observe({entryTypes:["longtask"]});const i=this.generateId("longtask");return this.observers.set(i,t),{id:i,stop:()=>{t.disconnect(),this.observers.delete(i)}}}catch(t){return d.error("[PerformanceManager] Long task monitoring failed:",t),null}}}),t(this,"optimize",{deferScript:(e,t=null)=>{const i=document.createElement("script");return i.src=e,i.defer=!0,t&&(i.onload=t),document.head.appendChild(i),i},preload:(e,t,i=!1)=>{const n=document.createElement("link");return n.rel="preload",n.href=e,n.as=t,i&&(n.crossOrigin="anonymous"),document.head.appendChild(n),n},prefetch:e=>{const t=document.createElement("link");return t.rel="prefetch",t.href=e,document.head.appendChild(t),t},lazyImages:(e="img[data-src]")=>{if("IntersectionObserver"in window){const t=document.querySelectorAll(e),i=new IntersectionObserver(e=>{e.forEach(e=>{if(e.isIntersecting){const t=e.target;t.src=t.dataset.src,t.classList.remove("lazy"),i.unobserve(t)}})});return t.forEach(e=>i.observe(e)),i}document.querySelectorAll(e).forEach(e=>{e.src=e.dataset.src,e.classList.remove("lazy")})},analyzeBundles:()=>{const e=Array.from(document.querySelectorAll("script[src]")),t=Array.from(document.querySelectorAll('link[rel="stylesheet"]')),i={scripts:e.map(e=>({src:e.src,async:e.async,defer:e.defer})),styles:t.map(e=>({href:e.href,media:e.media})),recommendations:[]};return e.length>10&&i.recommendations.push("Consider bundling JavaScript files"),t.length>5&&i.recommendations.push("Consider bundling CSS files"),i}}),this.config=e,this.marks=new Map,this.measures=new Map,this.observers=new Map,this.metrics=new Map,this.thresholds={fcp:2e3,lcp:2500,fid:100,cls:.1,...e.thresholds},this.support={performance:"performance"in window,timing:"timing"in(window.performance||{}),navigation:"navigation"in(window.performance||{}),observer:"PerformanceObserver"in window,memory:"memory"in(window.performance||{}),userTiming:"mark"in(window.performance||{}),resourceTiming:"getEntriesByType"in(window.performance||{}),paintTiming:"PerformanceObserver"in window&&(null==(i=PerformanceObserver.supportedEntryTypes)?void 0:i.includes("paint")),layoutInstability:"PerformanceObserver"in window&&(null==(n=PerformanceObserver.supportedEntryTypes)?void 0:n.includes("layout-shift")),longTask:"PerformanceObserver"in window&&(null==(r=PerformanceObserver.supportedEntryTypes)?void 0:r.includes("longtask"))},d.info("[PerformanceManager] Initialized with support:",this.support),this.startCoreMetrics()}startCoreMetrics(){this.vitals.start((e,t)=>{this.setMetric(e,t)}),this.support.memory&&this.memory.monitor(e=>{this.setMetric("memory",e)})}observePaint(e){if(this.support.paintTiming)try{const t=new PerformanceObserver(t=>{e(t.getEntries())});return t.observe({entryTypes:["paint"]}),t}catch(t){d.error("[PerformanceManager] Paint observer failed:",t)}}observeLCP(e){if(this.support.observer)try{const t=new PerformanceObserver(t=>{e(t.getEntries())});return t.observe({entryTypes:["largest-contentful-paint"]}),t}catch(t){d.error("[PerformanceManager] LCP observer failed:",t)}}observeFID(e){if(this.support.observer)try{const t=new PerformanceObserver(t=>{e(t.getEntries())});return t.observe({entryTypes:["first-input"]}),t}catch(t){d.error("[PerformanceManager] FID observer failed:",t)}}observeCLS(e){if(this.support.layoutInstability)try{const t=new PerformanceObserver(t=>{e(t.getEntries())});return t.observe({entryTypes:["layout-shift"]}),t}catch(t){d.error("[PerformanceManager] CLS observer failed:",t)}}getLegacyNavigationTiming(){if(!this.support.timing)return null;const e=performance.timing,t=e.navigationStart;return{redirect:e.redirectEnd-e.redirectStart,dns:e.domainLookupEnd-e.domainLookupStart,connect:e.connectEnd-e.connectStart,ssl:e.connectEnd-e.secureConnectionStart,ttfb:e.responseStart-e.requestStart,download:e.responseEnd-e.responseStart,domProcessing:e.domContentLoadedEventStart-e.responseEnd,domComplete:e.domComplete-e.domContentLoadedEventStart,loadComplete:e.loadEventEnd-e.loadEventStart,totalTime:e.loadEventEnd-t}}getResourceType(e){return{js:"script",css:"stylesheet",png:"image",jpg:"image",jpeg:"image",gif:"image",svg:"image",webp:"image",woff:"font",woff2:"font",ttf:"font",eot:"font",json:"fetch",xml:"fetch"}[new URL(e.name).pathname.split(".").pop().toLowerCase()]||e.initiatorType||"other"}getInsight(e,t,i,n){return t<i?{rating:"good",message:`Excellent ${e}`}:t<n?{rating:"needs-improvement",message:`${e} needs improvement`}:{rating:"poor",message:`Poor ${e} performance`}}getTransferEfficiency(e){const t=e.decodedBodySize>0?e.encodedBodySize/e.decodedBodySize:1;return{ratio:t,rating:t<.7?"good":t<.9?"fair":"poor"}}getNavigationRecommendations(e){const t=[];return e.ttfb>500&&t.push("Server response time is slow. Consider optimizing backend performance."),e.dns>100&&t.push("DNS lookup time is high. Consider using a faster DNS provider."),e.connect>1e3&&t.push("Connection time is slow. Check network latency."),e.domProcessing>1e3&&t.push("DOM processing is slow. Consider optimizing JavaScript execution."),t}checkThreshold(e,t){const i=this.thresholds[e];i&&t>i&&d.warn(`[PerformanceManager] ${e.toUpperCase()} threshold exceeded: ${t}ms (threshold: ${i}ms)`)}getRating(e,t){const i={fcp:{good:1800,poor:3e3},lcp:{good:2500,poor:4e3},fid:{good:100,poor:300},cls:{good:.1,poor:.25}}[e];return i&&null!=t?t<=i.good?"good":t<=i.poor?"needs-improvement":"poor":"unknown"}setMetric(e,t){this.metrics.set(e,{value:t,timestamp:Date.now()})}getMetric(e){const t=this.metrics.get(e);return t?t.value:null}formatBytes(e){if(0===e)return"0 Bytes";const t=Math.floor(Math.log(e)/Math.log(1024));return parseFloat((e/Math.pow(1024,t)).toFixed(2))+" "+["Bytes","KB","MB","GB"][t]}generateId(e="perf"){return`${e}_${Date.now()}_${Math.random().toString(36).substr(2,9)}`}cleanup(){this.observers.forEach(e=>{e.disconnect()}),this.observers.clear(),this.metrics.clear(),this.marks.clear(),this.measures.clear(),d.info("[PerformanceManager] Cleanup completed")}getReport(){return{support:this.support,navigation:this.navigation.get(),resources:this.resources.getSummary(),vitals:this.vitals.get(),memory:this.memory.get(),marks:this.timing.getMarks(),measures:this.timing.getMeasures(),activeObservers:this.observers.size,timestamp:Date.now()}}}class y{constructor(e={}){var t;this.config=e,this.permissionCache=new Map,this.permissionWatchers=new Map,this.requestQueue=new Map,this.support={permissions:"permissions"in navigator,query:void 0!==(null==(t=navigator.permissions)?void 0:t.query),request:"requestPermission"in Notification||"getUserMedia"in(navigator.mediaDevices||{}),geolocation:"geolocation"in navigator,notifications:"Notification"in window,camera:void 0!==navigator.mediaDevices,microphone:void 0!==navigator.mediaDevices,clipboard:"clipboard"in navigator,vibration:"vibrate"in navigator},this.permissionMap={camera:{name:"camera",api:"mediaDevices"},microphone:{name:"microphone",api:"mediaDevices"},geolocation:{name:"geolocation",api:"geolocation"},notifications:{name:"notifications",api:"notification"},"clipboard-read":{name:"clipboard-read",api:"clipboard"},"clipboard-write":{name:"clipboard-write",api:"clipboard"},"background-sync":{name:"background-sync",api:"serviceWorker"},"persistent-storage":{name:"persistent-storage",api:"storage"},push:{name:"push",api:"serviceWorker"},midi:{name:"midi",api:"midi"},"payment-handler":{name:"payment-handler",api:"payment"}},d.info("[PermissionManager] Initialized with support:",this.support),this.cacheCurrentPermissions()}async check(e){if(!this.support.permissions||!this.support.query)return d.warn("[PermissionManager] Permissions API not supported, using fallback"),this.checkFallback(e);try{const t=this.permissionCache.get(e);if(t&&Date.now()-t.timestamp<3e4)return t.status;const i=this.getPermissionDescriptor(e),n=await navigator.permissions.query(i),r={name:e,state:n.state,timestamp:Date.now(),supported:!0};return this.permissionCache.set(e,r),n.addEventListener("change",()=>{this.onPermissionChange(e,n.state)}),d.info(`[PermissionManager] Permission checked: ${e} = ${n.state}`),r}catch(t){return d.warn(`[PermissionManager] Permission check failed for ${e}:`,t.message),this.checkFallback(e)}}async request(e,t={}){const{showRationale:i=!0,fallbackMessage:n=null,timeout:r=3e4}=t;try{const t=await this.check(e);if("granted"===t.state)return{granted:!0,state:"granted",fromCache:!0};if("denied"===t.state)return i&&await this.showPermissionRationale(e,n),{granted:!1,state:"denied",reason:"previously-denied"};const a=e;if(this.requestQueue.has(a))return d.info(`[PermissionManager] Permission request already in progress: ${e}`),this.requestQueue.get(a);const s=this.executePermissionRequest(e,r);this.requestQueue.set(a,s);const o=await s;return this.requestQueue.delete(a),this.permissionCache.set(e,{name:e,state:o.state,timestamp:Date.now(),supported:!0}),o}catch(a){return d.error(`[PermissionManager] Permission request failed: ${e}`,a),this.requestQueue.delete(e),{granted:!1,state:"error",error:a.message}}}async requestMultiple(e,t={}){const i={};if(t.sequential){for(const r of e)if(i[r]=await this.request(r,t),t.requireAll&&!i[r].granted)break}else{const n=e.map(e=>this.request(e,t).then(t=>[e,t]));(await Promise.allSettled(n)).forEach(e=>{if("fulfilled"===e.status){const[t,n]=e.value;i[t]=n}else d.error("[PermissionManager] Batch permission request failed:",e.reason)})}const n={results:i,granted:Object.values(i).filter(e=>e.granted).length,denied:Object.values(i).filter(e=>!e.granted).length,total:Object.keys(i).length};return d.info(`[PermissionManager] Batch permissions: ${n.granted}/${n.total} granted`),n}async checkRequired(e){const t={},i=[];for(const n of e){const e=await this.check(n);t[n]=e,"granted"!==e.state&&i.push(n)}return{allGranted:0===i.length,granted:Object.keys(t).filter(e=>"granted"===t[e].state),missing:i,statuses:t}}watch(e,t){const i=this.generateId("watcher");return this.permissionWatchers.set(i,{permission:e,callback:t,active:!0}),this.setupPermissionWatcher(e,t),d.info(`[PermissionManager] Permission watcher created: ${e}`),{id:i,stop:()=>{const t=this.permissionWatchers.get(i);t&&(t.active=!1,this.permissionWatchers.delete(i),d.info(`[PermissionManager] Permission watcher stopped: ${e}`))}}}getRecommendations(e=[]){const t={essential:[],recommended:[],optional:[]},i={camera:{permissions:["camera"],priority:"essential"},microphone:{permissions:["microphone"],priority:"essential"},location:{permissions:["geolocation"],priority:"recommended"},notifications:{permissions:["notifications"],priority:"recommended"},clipboard:{permissions:["clipboard-read","clipboard-write"],priority:"optional"},offline:{permissions:["persistent-storage"],priority:"recommended"},background:{permissions:["background-sync","push"],priority:"optional"}};return e.forEach(e=>{const n=i[e];n&&t[n.priority].push(...n.permissions)}),Object.keys(t).forEach(e=>{t[e]=[...new Set(t[e])]}),t}createOnboardingFlow(e,t={}){const{title:i="Permissions Required",descriptions:n={},onComplete:r=null,onSkip:a=null}=t;return{permissions:e,title:i,descriptions:n,async start(){d.info("[PermissionManager] Starting onboarding flow");const t=[];for(const r of e){const e=n[r]||this.getDefaultDescription(r),i=await this.showPermissionDialog(r,e);if("grant"===i){const e=await this.request(r);t.push({permission:r,...e})}else{if("skip"!==i)return a&&a(t),{cancelled:!0,results:t};t.push({permission:r,granted:!1,skipped:!0})}}const i={completed:!0,granted:t.filter(e=>e.granted).length,total:t.length,results:t};return r&&r(i),i},getDefaultDescription:e=>({camera:"Take photos and record videos for enhanced functionality",microphone:"Record audio for voice features and communication",geolocation:"Provide location-based services and content",notifications:"Send you important updates and reminders","clipboard-read":"Access clipboard content for convenience features","clipboard-write":"Copy content to clipboard for easy sharing"}[e]||`Allow access to ${e} functionality`),async showPermissionDialog(e,t){return new Promise(i=>{const n=document.createElement("div");n.className="permission-dialog-modal",n.innerHTML=`\n <div class="permission-dialog-backdrop" style="\n position: fixed;\n top: 0;\n left: 0;\n right: 0;\n bottom: 0;\n background: rgba(0,0,0,0.5);\n z-index: 10000;\n display: flex;\n align-items: center;\n justify-content: center;\n ">\n <div class="permission-dialog" style="\n background: white;\n border-radius: 8px;\n padding: 2rem;\n max-width: 400px;\n margin: 1rem;\n box-shadow: 0 4px 20px rgba(0,0,0,0.3);\n ">\n <h3 style="margin: 0 0 1rem 0; color: #333;">\n ${this.getPermissionIcon(e)} ${this.getPermissionTitle(e)}\n </h3>\n <p style="margin: 0 0 2rem 0; color: #666; line-height: 1.5;">\n ${t}\n </p>\n <div style="display: flex; gap: 1rem; justify-content: flex-end;">\n <button class="btn-skip" style="\n background: #f5f5f5;\n border: 1px solid #ddd;\n padding: 0.5rem 1rem;\n border-radius: 4px;\n cursor: pointer;\n ">Skip</button>\n <button class="btn-grant" style="\n background: #007bff;\n color: white;\n border: none;\n padding: 0.5rem 1rem;\n border-radius: 4px;\n cursor: pointer;\n ">Allow</button>\n </div>\n </div>\n </div>\n `,document.body.appendChild(n);const r=n.querySelector(".btn-skip"),a=n.querySelector(".btn-grant"),s=()=>document.body.removeChild(n);r.onclick=()=>{s(),i("skip")},a.onclick=()=>{s(),i("grant")},n.querySelector(".permission-dialog-backdrop").onclick=e=>{e.target===e.currentTarget&&(s(),i("cancel"))}})},getPermissionIcon:e=>({camera:"📷",microphone:"🎤",geolocation:"📍",notifications:"🔔","clipboard-read":"📋","clipboard-write":"📋"}[e]||"🔐"),getPermissionTitle:e=>({camera:"Camera Access",microphone:"Microphone Access",geolocation:"Location Access",notifications:"Notifications","clipboard-read":"Clipboard Access","clipboard-write":"Clipboard Access"}[e]||`${e} Permission`)}}async cacheCurrentPermissions(){if(!this.support.permissions)return;const e=["camera","microphone","geolocation","notifications"];for(const i of e)try{await this.check(i)}catch(t){}}getPermissionDescriptor(e){switch(e){case"camera":return{name:"camera"};case"microphone":return{name:"microphone"};case"geolocation":return{name:"geolocation"};case"notifications":return{name:"notifications"};case"clipboard-read":return{name:"clipboard-read"};case"clipboard-write":return{name:"clipboard-write"};case"persistent-storage":return{name:"persistent-storage"};case"background-sync":return{name:"background-sync"};case"push":return{name:"push",userVisibleOnly:!0};default:return{name:e}}}async checkFallback(e){const t={camera:()=>void 0!==navigator.mediaDevices,microphone:()=>void 0!==navigator.mediaDevices,geolocation:()=>"geolocation"in navigator,notifications:()=>"Notification"in window,"clipboard-read":()=>"clipboard"in navigator,"clipboard-write":()=>"clipboard"in navigator}[e],i=!!t&&t();return{name:e,state:i?"prompt":"unsupported",timestamp:Date.now(),supported:i,fallback:!0}}async executePermissionRequest(e,t){return new Promise(async(i,n)=>{const r=setTimeout(()=>{n(new Error("Permission request timeout"))},t);try{let t;switch(e){case"notifications":if("Notification"in window){const e=await Notification.requestPermission();t={granted:"granted"===e,state:e}}else t={granted:!1,state:"unsupported"};break;case"camera":case"microphone":try{const i={};i["camera"===e?"video":"audio"]=!0;(await navigator.mediaDevices.getUserMedia(i)).getTracks().forEach(e=>e.stop()),t={granted:!0,state:"granted"}}catch(a){t={granted:!1,state:"NotAllowedError"===a.name?"denied":"error",error:a.message}}break;case"geolocation":try{await new Promise((e,t)=>{navigator.geolocation.getCurrentPosition(e,t,{timeout:1e4,maximumAge:0})}),t={granted:!0,state:"granted"}}catch(a){t={granted:!1,state:1===a.code?"denied":"error",error:a.message}}break;default:if(this.support.permissions){const i=await navigator.permissions.query(this.getPermissionDescriptor(e));t={granted:"granted"===i.state,state:i.state}}else t={granted:!1,state:"unsupported"}}clearTimeout(r),i(t)}catch(a){clearTimeout(r),n(a)}})}async setupPermissionWatcher(e,t){if(this.support.permissions)try{const i=await navigator.permissions.query(this.getPermissionDescriptor(e));i.addEventListener("change",()=>{t({permission:e,state:i.state,timestamp:Date.now()})})}catch(i){d.warn(`[PermissionManager] Could not set up watcher for ${e}:`,i)}}onPermissionChange(e,t){d.info(`[PermissionManager] Permission changed: ${e} → ${t}`),this.permissionCache.set(e,{name:e,state:t,timestamp:Date.now(),supported:!0}),this.permissionWatchers.forEach(i=>{i.permission===e&&i.active&&i.callback({permission:e,state:t,timestamp:Date.now()})})}async showPermissionRationale(e,t=null){const i=t||{camera:"Camera access is needed to take photos and record videos. You can enable this in your browser settings.",microphone:"Microphone access is needed for audio recording and voice features. Please check your browser settings.",geolocation:"Location access helps provide relevant local content. You can manage this in your browser settings.",notifications:"Notifications keep you updated with important information. You can change this anytime in settings."}[e]||`${e} permission was denied. Please enable it in your browser settings to use this feature.`;return!("undefined"==typeof window||!window.confirm)&&window.confirm(i+"\n\nWould you like to try again?")}generateId(e="perm"){return`${e}_${Date.now()}_${Math.random().toString(36).substr(2,9)}`}async getPermissionReport(){return{support:this.support,cached:Array.from(this.permissionCache.entries()).map(([e,t])=>({name:e,...t})),watchers:Array.from(this.permissionWatchers.keys()),timestamp:Date.now()}}clearCache(){this.permissionCache.clear(),d.info("[PermissionManager] Permission cache cleared")}cleanup(){this.permissionWatchers.forEach(e=>{e.active=!1}),this.permissionWatchers.clear(),this.requestQueue.clear(),this.permissionCache.clear(),d.info("[PermissionManager] Cleanup completed")}}class b{constructor(e={}){this.config={rpName:e.rpName||"Custom PHP Framework",rpId:e.rpId||window.location.hostname,timeout:e.timeout||6e4,userVerification:e.userVerification||"preferred",authenticatorSelection:{authenticatorAttachment:"platform",userVerification:"preferred",requireResidentKey:!1,...e.authenticatorSelection},...e},this.credentials=new Map,this.authSessions=new Map,this.support={webAuthn:"credentials"in navigator&&"create"in navigator.credentials,conditionalUI:"conditional"in window.PublicKeyCredential||!1,userVerifyingPlatformAuthenticator:!1,residentKey:!1},this.detectFeatures(),d.info("[BiometricAuthManager] Initialized with support:",this.support)}async detectFeatures(){if(this.support.webAuthn)try{const e=await window.PublicKeyCredential.isUserVerifyingPlatformAuthenticatorAvailable();this.support.userVerifyingPlatformAuthenticator=e,window.PublicKeyCredential.isConditionalMediationAvailable&&(this.support.conditionalUI=await window.PublicKeyCredential.isConditionalMediationAvailable()),d.info("[BiometricAuthManager] Enhanced features detected:",{platform:this.support.userVerifyingPlatformAuthenticator,conditional:this.support.conditionalUI})}catch(e){d.warn("[BiometricAuthManager] Feature detection failed:",e)}}async register(e,t={}){var i,n;if(!this.support.webAuthn)throw new Error("WebAuthn not supported");const{challenge:r=null,excludeCredentials:a=[],extensions:s={}}=t;try{const t=r?this.base64ToArrayBuffer(r):crypto.getRandomValues(new Uint8Array(32)),o={rp:{name:this.config.rpName,id:this.config.rpId},user:{id:this.stringToArrayBuffer(e.id||e.username),name:e.username||e.email,displayName:e.displayName||e.name||e.username},challenge:t,pubKeyCredParams:[{type:"public-key",alg:-7},{type:"public-key",alg:-35},{type:"public-key",alg:-36},{type:"public-key",alg:-257},{type:"public-key",alg:-258},{type:"public-key",alg:-259}],authenticatorSelection:this.config.authenticatorSelection,timeout:this.config.timeout,attestation:"direct",extensions:{credProps:!0,...s}};a.length>0&&(o.excludeCredentials=a.map(e=>({type:"public-key",id:"string"==typeof e?this.base64ToArrayBuffer(e):e,transports:["internal","hybrid"]}))),d.info("[BiometricAuthManager] Starting registration...");const l=await navigator.credentials.create({publicKey:o});if(!l)throw new Error("Credential creation failed");const c=this.processCredential(l,"registration"),h={id:c.id,rawId:c.rawId,userId:e.id||e.username,userDisplayName:e.displayName||e.name,createdAt:Date.now(),lastUsed:null,counter:c.response.counter||0,transports:(null==(n=(i=l.response).getTransports)?void 0:n.call(i))||["internal"]};return this.credentials.set(c.id,h),d.info("[BiometricAuthManager] Registration successful:",{id:c.id,user:e.username,authenticator:h.transports}),{success:!0,credential:c,info:h,attestation:this.parseAttestation(l.response)}}catch(o){return d.error("[BiometricAuthManager] Registration failed:",o),{success:!1,error:o.message,name:o.name}}}async authenticate(e={}){if(!this.support.webAuthn)throw new Error("WebAuthn not supported");const{challenge:t=null,allowCredentials:i=[],userVerification:n=this.config.userVerification,conditional:r=!1,extensions:a={}}=e;try{const e={challenge:t?this.base64ToArrayBuffer(t):crypto.getRandomValues(new Uint8Array(32)),timeout:this.config.timeout,userVerification:n,extensions:{credProps:!0,...a}};i.length>0&&(e.allowCredentials=i.map(e=>({type:"public-key",id:"string"==typeof e?this.base64ToArrayBuffer(e):e,transports:["internal","hybrid","usb","nfc","ble"]}))),d.info("[BiometricAuthManager] Starting authentication...",{conditional:r});const s=r&&this.support.conditionalUI?await navigator.credentials.get({publicKey:e,mediation:"conditional"}):await navigator.credentials.get({publicKey:e});if(!s)throw new Error("Authentication failed");const o=this.processCredential(s,"authentication"),l=this.credentials.get(o.id);l&&(l.lastUsed=Date.now(),l.counter=o.response.counter||0);const c=this.generateSessionId(),h={id:c,credentialId:o.id,userId:null==l?void 0:l.userId,authenticatedAt:Date.now(),userAgent:navigator.userAgent,ipAddress:await this.getClientIP().catch(()=>"unknown")};return this.authSessions.set(c,h),d.info("[BiometricAuthManager] Authentication successful:",{sessionId:c,credentialId:o.id,userId:null==l?void 0:l.userId}),{success:!0,credential:o,session:h,info:l}}catch(s){return d.error("[BiometricAuthManager] Authentication failed:",s),{success:!1,error:s.message,name:s.name}}}async isAvailable(){const e={webAuthn:this.support.webAuthn,platform:this.support.userVerifyingPlatformAuthenticator,conditional:this.support.conditionalUI,hasCredentials:this.credentials.size>0,recommended:!1};return e.recommended=e.webAuthn&&(e.platform||e.hasCredentials),e}async setupConditionalUI(e='input[type="email"], input[type="text"]',t={}){if(!this.support.conditionalUI)return d.warn("[BiometricAuthManager] Conditional UI not supported"),null;const i=document.querySelectorAll(e);if(0===i.length)return d.warn("[BiometricAuthManager] No suitable inputs found for conditional UI"),null;try{return i.forEach(e=>{e.addEventListener("focus",async()=>{var i;d.info("[BiometricAuthManager] Setting up conditional authentication");try{const n=await this.authenticate({...t,conditional:!0});if(n.success){const t=new CustomEvent("biometric-auth-success",{detail:n});e.dispatchEvent(t),(null==(i=n.info)?void 0:i.userDisplayName)&&(e.value=n.info.userDisplayName)}}catch(n){d.warn("[BiometricAuthManager] Conditional auth failed:",n)}})}),d.info("[BiometricAuthManager] Conditional UI setup complete"),{inputs:i.length,selector:e}}catch(n){return d.error("[BiometricAuthManager] Conditional UI setup failed:",n),null}}createLoginFlow(e={}){const{registerSelector:t="#register-biometric",loginSelector:i="#login-biometric",statusSelector:n="#biometric-status",onRegister:r=null,onLogin:a=null,onError:s=null}=e;return{async init(){const e=await this.isAvailable(),r=document.querySelector(n);r&&(r.innerHTML=this.createStatusHTML(e));const a=document.querySelector(t);a&&(a.style.display=e.webAuthn?"block":"none",a.onclick=()=>this.handleRegister());const s=document.querySelector(i);return s&&(s.style.display=e.hasCredentials?"block":"none",s.onclick=()=>this.handleLogin()),e.conditional&&await this.setupConditionalUI(),e},async handleRegister(){try{const e=await this.getUserInfo();if(!e)return;const t=await this.register(e);t.success?(r&&r(t),this.showSuccess("Biometric authentication registered successfully!")):(s&&s(t),this.showError(t.error))}catch(e){s&&s({error:e.message}),this.showError(e.message)}},async handleLogin(){try{const e=await this.authenticate();e.success?(a&&a(e),this.showSuccess("Biometric authentication successful!")):(s&&s(e),this.showError(e.error))}catch(e){s&&s({error:e.message}),this.showError(e.message)}},async getUserInfo(){const e=document.querySelector('input[name="username"], input[name="email"]'),t=document.querySelector('input[name="name"], input[name="display_name"]');if(null==e?void 0:e.value)return{id:e.value,username:e.value,displayName:(null==t?void 0:t.value)||e.value};const i=prompt("Please enter your username or email:");if(!i)return null;return{id:i,username:i,displayName:prompt("Please enter your display name:")||i}},createStatusHTML:e=>e.webAuthn?e.platform||e.hasCredentials?e.hasCredentials?'<div class="alert alert-success">✅ Biometric authentication available</div>':'<div class="alert alert-info">🔐 Biometric authentication can be set up</div>':'<div class="alert alert-info">ℹ️ No biometric authenticators available</div>':'<div class="alert alert-warning">⚠️ Biometric authentication not supported in this browser</div>',showSuccess(e){this.showMessage(e,"success")},showError(e){this.showMessage(e,"error")},showMessage(e,t="info"){const i=document.createElement("div");i.className=`biometric-toast toast-${t}`,i.style.cssText=`\n position: fixed;\n top: 20px;\n right: 20px;\n background: ${"error"===t?"#f44336":"success"===t?"#4caf50":"#2196f3"};\n color: white;\n padding: 1rem;\n border-radius: 4px;\n box-shadow: 0 2px 10px rgba(0,0,0,0.3);\n z-index: 10001;\n max-width: 300px;\n `,i.textContent=e,document.body.appendChild(i),setTimeout(()=>{i.parentNode&&document.body.removeChild(i)},5e3)}}}processCredential(e,t){var i,n;const r={id:this.arrayBufferToBase64(e.rawId),rawId:this.arrayBufferToBase64(e.rawId),type:e.type,response:{}};return r.response="registration"===t?{attestationObject:this.arrayBufferToBase64(e.response.attestationObject),clientDataJSON:this.arrayBufferToBase64(e.response.clientDataJSON),transports:(null==(n=(i=e.response).getTransports)?void 0:n.call(i))||[]}:{authenticatorData:this.arrayBufferToBase64(e.response.authenticatorData),clientDataJSON:this.arrayBufferToBase64(e.response.clientDataJSON),signature:this.arrayBufferToBase64(e.response.signature),userHandle:e.response.userHandle?this.arrayBufferToBase64(e.response.userHandle):null},r}parseAttestation(e){try{const t=JSON.parse(this.arrayBufferToString(e.clientDataJSON));return{format:"packed",clientData:t,origin:t.origin,challenge:t.challenge}}catch(t){return d.warn("[BiometricAuthManager] Attestation parsing failed:",t),null}}async getClientIP(){try{const e=await fetch("https://api.ipify.org?format=json");return(await e.json()).ip}catch(e){return"unknown"}}generateSessionId(){return`biometric_${Date.now()}_${Math.random().toString(36).substr(2,9)}`}arrayBufferToBase64(e){const t=new Uint8Array(e);let i="";for(let n=0;n<t.byteLength;n++)i+=String.fromCharCode(t[n]);return btoa(i)}base64ToArrayBuffer(e){const t=atob(e),i=new Uint8Array(t.length);for(let n=0;n<t.length;n++)i[n]=t.charCodeAt(n);return i.buffer}stringToArrayBuffer(e){return(new TextEncoder).encode(e)}arrayBufferToString(e){return(new TextDecoder).decode(e)}getCredentials(){return Array.from(this.credentials.values())}getActiveSessions(){return Array.from(this.authSessions.values())}revokeCredential(e){const t=this.credentials.delete(e);return t&&d.info(`[BiometricAuthManager] Credential revoked: ${e}`),t}endSession(e){const t=this.authSessions.delete(e);return t&&d.info(`[BiometricAuthManager] Session ended: ${e}`),t}cleanupSessions(e=864e5){const t=Date.now();let i=0;for(const[n,r]of this.authSessions.entries())t-r.authenticatedAt>e&&(this.authSessions.delete(n),i++);return i>0&&d.info(`[BiometricAuthManager] Cleaned up ${i} expired sessions`),i}async getStatusReport(){return{availability:await this.isAvailable(),credentials:this.credentials.size,sessions:this.authSessions.size,support:this.support,config:{rpName:this.config.rpName,rpId:this.config.rpId,timeout:this.config.timeout},timestamp:Date.now()}}}const w={name:"api-manager",init(e={},t=null){return d.info("[APIManager] Module initialized - All Web APIs available"),this.initializeAPIManagers(e),this.exposeGlobalAPI(),this},initializeAPIManagers(e){this.observers=new h(e.observers||{}),this.media=new u(e.media||{}),this.storage=new m(e.storage||{}),this.device=new g(e.device||{}),this.animation=new p(e.animation||{}),this.worker=new f(e.worker||{}),this.performance=new v(e.performance||{}),this.permissions=new y(e.permissions||{}),this.biometric=new b(e.biometric||{}),d.info("[APIManager] All API managers initialized")},exposeGlobalAPI(){"undefined"!=typeof window&&(window.API={observers:this.observers,media:this.media,storage:this.storage,device:this.device,animation:this.animation,worker:this.worker,performance:this.performance,permissions:this.permissions,biometric:this.biometric},d.info("[APIManager] Global API exposed at window.API"))},getAPI(e){return this[e]||null},isSupported:e=>({IntersectionObserver:"IntersectionObserver"in window,ResizeObserver:"ResizeObserver"in window,MutationObserver:"MutationObserver"in window,PerformanceObserver:"PerformanceObserver"in window,MediaDevices:void 0!==navigator.mediaDevices,WebRTC:"RTCPeerConnection"in window,WebAudio:"AudioContext"in window||"webkitAudioContext"in window,MediaRecorder:"MediaRecorder"in window,IndexedDB:"indexedDB"in window,CacheAPI:"caches"in window,WebLocks:"locks"in navigator,BroadcastChannel:"BroadcastChannel"in window,Geolocation:"geolocation"in navigator,DeviceMotion:"DeviceMotionEvent"in window,DeviceOrientation:"DeviceOrientationEvent"in window,Vibration:"vibrate"in navigator,Battery:"getBattery"in navigator,NetworkInfo:"connection"in navigator,WebAnimations:"animate"in Element.prototype,VisualViewport:"visualViewport"in window,WebWorkers:"Worker"in window,ServiceWorker:"serviceWorker"in navigator,SharedWorker:"SharedWorker"in window,PerformanceAPI:"performance"in window,NavigationTiming:"getEntriesByType"in performance,Permissions:"permissions"in navigator,WebAuthn:"credentials"in navigator&&"create"in navigator.credentials}[e]||!1),getCapabilities(){const e={};return Object.keys(this.getSupportMap()).forEach(t=>{e[t]=this.isSupported(t)}),{capabilities:e,modernBrowser:this.isModernBrowser(),recommendedAPIs:this.getRecommendedAPIs(),summary:this.getCapabilitySummary(e)}},isModernBrowser(){return["IntersectionObserver","ResizeObserver","WebAnimations","IndexedDB"].every(e=>this.isSupported(e))},getRecommendedAPIs(){const e=[];return this.isSupported("IntersectionObserver")&&e.push({api:"IntersectionObserver",use:"Lazy loading, scroll triggers, viewport detection",example:"API.observers.intersection(elements, callback)"}),this.isSupported("WebAnimations")&&e.push({api:"Web Animations",use:"High-performance animations with timeline control",example:"API.animation.animate(element, keyframes, options)"}),this.isSupported("IndexedDB")&&e.push({api:"IndexedDB",use:"Client-side database for complex data",example:"API.storage.db.set(key, value)"}),this.isSupported("MediaDevices")&&e.push({api:"Media Devices",use:"Camera, microphone, screen sharing",example:"API.media.getUserCamera()"}),e},getCapabilitySummary(e){const t=Object.keys(e).length,i=Object.values(e).filter(Boolean).length,n=Math.round(i/t*100);return{total:t,supported:i,percentage:n,grade:this.getGrade(n)}},getGrade:e=>e>=90?"A+":e>=80?"A":e>=70?"B":e>=60?"C":"D",getSupportMap:()=>({IntersectionObserver:"Viewport intersection detection",ResizeObserver:"Element resize detection",MutationObserver:"DOM change detection",PerformanceObserver:"Performance metrics monitoring",MediaDevices:"Camera and microphone access",WebRTC:"Real-time communication",WebAudio:"Audio processing and synthesis",MediaRecorder:"Audio/video recording",IndexedDB:"Client-side database",CacheAPI:"HTTP cache management",WebLocks:"Resource locking",BroadcastChannel:"Cross-tab communication",Geolocation:"GPS and location services",DeviceMotion:"Accelerometer and gyroscope",DeviceOrientation:"Device orientation",Vibration:"Haptic feedback",Battery:"Battery status",NetworkInfo:"Network connection info",WebAnimations:"High-performance animations",VisualViewport:"Viewport information",WebWorkers:"Background processing",ServiceWorker:"Background sync and caching",SharedWorker:"Shared background processing",PerformanceAPI:"Performance measurement",NavigationTiming:"Navigation timing metrics",Permissions:"Browser permission management",WebAuthn:"Biometric authentication"})},S=w.init.bind(w),M=Object.freeze(Object.defineProperty({__proto__:null,default:w,init:S},Symbol.toStringTag,{value:"Module"})),k=new Map,x={add(e,t,i,{module:n="global",options:r=!1}={}){e.addEventListener(t,i,r),k.has(n)||k.set(n,[]),k.get(n).push([e,t,i,r])},removeModule(e){const t=k.get(e);t&&(t.forEach(([e,t,i,n])=>{e.removeEventListener(t,i,n)}),k.delete(e))},clearAll(){for(const[e,t]of k.entries())t.forEach(([e,t,i,n])=>{e.removeEventListener(t,i,n)});k.clear()},debug(){console.table([...k.entries()].map(([e,t])=>({module:e,listeners:t.length})))}};function E(e,t,i,n=import.meta,r=!1){var a;const s="string"==typeof n?n:(null==(a=n.url)?void 0:a.split("/").slice(-2,-1)[0])||"unknown";return x.add(e,t,i,{module:s,options:r}),()=>{x.removeModule(s)}}class A{constructor(e,t={}){this.canvas=e,this.ctx=e.getContext("2d"),this.options={responsive:!0,pixelRatio:window.devicePixelRatio||1,...t},this.animationId=null,this.isAnimating=!1,this.init()}init(){this.setupCanvas(),this.options.responsive&&this.setupResponsive(),d.info("[CanvasManager] Initialized",{width:this.canvas.width,height:this.canvas.height,pixelRatio:this.options.pixelRatio})}setupCanvas(){this.resize(),this.canvas.style.width=this.canvas.width+"px",this.canvas.style.height=this.canvas.height+"px",this.options.pixelRatio>1&&this.ctx.scale(this.options.pixelRatio,this.options.pixelRatio)}setupResponsive(){E(window,"resize",()=>{this.resize()},"canvas-manager"),E(window,"orientationchange",()=>{setTimeout(()=>this.resize(),100)},"canvas-manager")}resize(){const e=this.canvas.parentElement,t=this.options.pixelRatio;let i,n;e&&"static"!==getComputedStyle(e).position?(i=e.clientWidth,n=e.clientHeight):(i=this.canvas.clientWidth||window.innerWidth,n=this.canvas.clientHeight||window.innerHeight),this.canvas.width=Math.floor(i*t),this.canvas.height=Math.floor(n*t),this.canvas.style.width=i+"px",this.canvas.style.height=n+"px",t>1&&this.ctx.scale(t,t),d.info("[CanvasManager] Resized",{displayWidth:i,displayHeight:n,canvasWidth:this.canvas.width,canvasHeight:this.canvas.height})}clear(){this.ctx.clearRect(0,0,this.canvas.width,this.canvas.height)}getSize(){return{width:this.canvas.clientWidth,height:this.canvas.clientHeight,pixelWidth:this.canvas.width,pixelHeight:this.canvas.height}}getMousePosition(e){const t=this.canvas.getBoundingClientRect();return{x:(e.clientX-t.left)*this.options.pixelRatio,y:(e.clientY-t.top)*this.options.pixelRatio}}startAnimation(e){this.isAnimating&&this.stopAnimation(),this.isAnimating=!0;const t=i=>{this.isAnimating&&(e(i),this.animationId=requestAnimationFrame(t))};this.animationId=requestAnimationFrame(t),d.info("[CanvasManager] Animation started")}stopAnimation(){this.animationId&&(cancelAnimationFrame(this.animationId),this.animationId=null),this.isAnimating=!1,d.info("[CanvasManager] Animation stopped")}destroy(){this.stopAnimation(),d.info("[CanvasManager] Destroyed")}}const C={initParallax(e,t){const i=new A(e),n=this.createParallaxElements(e,t);let r=!1;const a=()=>{r||(requestAnimationFrame(()=>{this.renderParallax(i,n,t),r=!1}),r=!0)};E(window,"scroll",a,"scroll-parallax"),E(window,"resize",a,"scroll-parallax"),a(),d.info("[ScrollEffects] Parallax initialized with",n.length,"elements")},createParallaxElements(e,t){const i=[],n=t.layers||3,r=t.elements||20;for(let a=0;a<r;a++)i.push({x:Math.random()*e.clientWidth,y:Math.random()*e.clientHeight*2,size:20*Math.random()+5,layer:Math.floor(Math.random()*n),speed:.1+.5*Math.random(),opacity:.7*Math.random()+.3,color:this.getLayerColor(Math.floor(Math.random()*n),t)});return i},getLayerColor(e,t){const i=t.colors||["rgba(100, 150, 255, 0.6)","rgba(150, 100, 255, 0.4)","rgba(200, 100, 150, 0.2)"];return i[e]||i[0]},renderParallax(e,t,i){e.clear();const n=window.pageYOffset,r=(n-(e.canvas.getBoundingClientRect().top+n))/window.innerHeight;t.forEach(t=>{const i=r*t.speed*100,n=t.y-i;n>-t.size&&n<e.canvas.clientHeight+t.size&&(e.ctx.save(),e.ctx.globalAlpha=t.opacity,e.ctx.fillStyle=t.color,e.ctx.beginPath(),e.ctx.arc(t.x,n,t.size,0,2*Math.PI),e.ctx.fill(),e.ctx.restore())})},initScrollAnimation(e,t){const i=new A(e),n=t.animation||"wave";let r=!1;const a=()=>{r||(requestAnimationFrame(()=>{this.renderScrollAnimation(i,n,t),r=!1}),r=!0)};E(window,"scroll",a,"scroll-animation"),E(window,"resize",a,"scroll-animation"),a(),d.info("[ScrollEffects] Scroll animation initialized:",n)},renderScrollAnimation(e,t,i){e.clear();const n=window.pageYOffset,r=n-(e.canvas.getBoundingClientRect().top+n),a=Math.max(0,Math.min(1,r/window.innerHeight));switch(t){case"wave":default:this.renderWaveAnimation(e,a,i);break;case"progress":this.renderProgressAnimation(e,a,i);break;case"morph":this.renderMorphAnimation(e,a,i)}},renderWaveAnimation(e,t,i){const{ctx:n}=e,{width:r,height:a}=e.getSize();n.strokeStyle=i.color||"rgba(100, 150, 255, 0.8)",n.lineWidth=i.lineWidth||3,n.beginPath();const s=(i.amplitude||50)*t,o=i.frequency||.02,l=t*Math.PI*2;for(let c=0;c<=r;c+=2){const e=a/2+Math.sin(c*o+l)*s;0===c?n.moveTo(c,e):n.lineTo(c,e)}n.stroke()},renderProgressAnimation(e,t,i){const{ctx:n}=e,{width:r,height:a}=e.getSize(),s=i.barHeight||10,o=a/2-s/2;n.fillStyle=i.backgroundColor||"rgba(255, 255, 255, 0.2)",n.fillRect(0,o,r,s),n.fillStyle=i.color||"rgba(100, 150, 255, 0.8)",n.fillRect(0,o,r*t,s)},renderMorphAnimation(e,t,i){const{ctx:n}=e,{width:r,height:a}=e.getSize();n.fillStyle=i.color||"rgba(100, 150, 255, 0.6)";const s=r/2,o=a/2,l=Math.min(r,a)/3;n.beginPath();const c=i.points||6;for(let d=0;d<=c;d++){const e=d/c*Math.PI*2,i=l*t*(.3*Math.sin(t*Math.PI*4+3*e)+1),r=s+Math.cos(e)*i,a=o+Math.sin(e)*i;0===d?n.moveTo(r,a):n.lineTo(r,a)}n.closePath(),n.fill()}},I={init(e,t){const i=new A(e),n=t.effect||"ripple",r={mouse:{x:0,y:0,isOver:!1},effects:[],lastTime:0};this.setupInteractionEvents(e,i,r,t),this.startAnimationLoop(i,r,n,t),d.info("[InteractiveEffects] Initialized with effect:",n)},setupInteractionEvents(e,t,i,n){E(e,"mousemove",e=>{const r=t.getMousePosition(e);i.mouse.x=r.x,i.mouse.y=r.y,"trail"===n.effect&&this.addTrailPoint(i,r.x,r.y)},"interactive-effects"),E(e,"mouseenter",()=>{i.mouse.isOver=!0},"interactive-effects"),E(e,"mouseleave",()=>{i.mouse.isOver=!1},"interactive-effects"),E(e,"click",e=>{const r=t.getMousePosition(e);this.addClickEffect(i,r.x,r.y,n)},"interactive-effects"),E(e,"touchstart",e=>{e.preventDefault();const r=e.touches[0],a=t.getMousePosition(r);this.addClickEffect(i,a.x,a.y,n)},"interactive-effects"),E(e,"touchmove",e=>{e.preventDefault();const r=e.touches[0],a=t.getMousePosition(r);i.mouse.x=a.x,i.mouse.y=a.y,i.mouse.isOver=!0,"trail"===n.effect&&this.addTrailPoint(i,a.x,a.y)},"interactive-effects"),E(e,"touchend",()=>{i.mouse.isOver=!1},"interactive-effects")},startAnimationLoop(e,t,i,n){const r=a=>{const s=a-t.lastTime;switch(t.lastTime=a,e.clear(),i){case"ripple":default:this.renderRippleEffect(e,t,n);break;case"trail":this.renderTrailEffect(e,t,n);break;case"particles":this.renderParticleEffect(e,t,n,s);break;case"magnetic":this.renderMagneticEffect(e,t,n)}this.updateEffects(t.effects,s),requestAnimationFrame(r)};requestAnimationFrame(r)},addClickEffect(e,t,i,n){const r={x:t,y:i,age:0,maxAge:n.duration||1e3,type:"click",intensity:n.intensity||1};e.effects.push(r)},addTrailPoint(e,t,i){const n={x:t,y:i,age:0,maxAge:500,type:"trail"};e.effects.push(n);const r=e.effects.filter(e=>"trail"===e.type);if(r.length>20){const t=e.effects.indexOf(r[0]);e.effects.splice(t,1)}},renderRippleEffect(e,t,i){const{ctx:n}=e;t.effects.forEach(t=>{if("click"===t.type){const r=t.age/t.maxAge,a=r*(i.maxRadius||100),s=.8*(1-r);n.save(),n.globalAlpha=s,n.strokeStyle=i.color||"rgba(100, 150, 255, 1)",n.lineWidth=i.lineWidth||3,n.beginPath(),n.arc(t.x/e.options.pixelRatio,t.y/e.options.pixelRatio,a,0,2*Math.PI),n.stroke(),n.restore()}}),t.mouse.isOver&&(n.save(),n.globalAlpha=.3,n.fillStyle=i.hoverColor||"rgba(100, 150, 255, 0.3)",n.beginPath(),n.arc(t.mouse.x/e.options.pixelRatio,t.mouse.y/e.options.pixelRatio,i.hoverRadius||30,0,2*Math.PI),n.fill(),n.restore())},renderTrailEffect(e,t,i){const{ctx:n}=e,r=t.effects.filter(e=>"trail"===e.type);r.length<2||(n.save(),n.strokeStyle=i.color||"rgba(100, 150, 255, 0.8)",n.lineWidth=i.lineWidth||5,n.lineCap="round",n.lineJoin="round",n.beginPath(),r.forEach((t,i)=>{const r=1-t.age/t.maxAge,a=t.x/e.options.pixelRatio,s=t.y/e.options.pixelRatio;n.globalAlpha=.8*r,0===i?n.moveTo(a,s):n.lineTo(a,s)}),n.stroke(),n.restore())},renderParticleEffect(e,t,i,n){const{ctx:r}=e;if(t.mouse.isOver&&Math.random()<.1){const e={x:t.mouse.x,y:t.mouse.y,vx:4*(Math.random()-.5),vy:4*(Math.random()-.5),age:0,maxAge:1e3,size:5*Math.random()+2,type:"particle"};t.effects.push(e)}t.effects.forEach(t=>{if("particle"===t.type){t.x+=t.vx,t.y+=t.vy,t.vy+=.1;const n=t.age/t.maxAge,a=.8*(1-n);r.save(),r.globalAlpha=a,r.fillStyle=i.color||"rgba(100, 150, 255, 1)",r.beginPath(),r.arc(t.x/e.options.pixelRatio,t.y/e.options.pixelRatio,t.size*(1-.5*n),0,2*Math.PI),r.fill(),r.restore()}})},renderMagneticEffect(e,t,i){const{ctx:n}=e,{width:r,height:a}=e.getSize();if(!t.mouse.isOver)return;const s=r/2,o=a/2,l=t.mouse.x/e.options.pixelRatio,c=t.mouse.y/e.options.pixelRatio;n.save(),n.strokeStyle=i.color||"rgba(100, 150, 255, 0.6)",n.lineWidth=2;for(let d=0;d<8;d++){const e=d/8*Math.PI*2,t=s+50*Math.cos(e),i=o+50*Math.sin(e),r=(t+l)/2+30*Math.sin(e),a=(i+c)/2+30*Math.cos(e);n.beginPath(),n.moveTo(t,i),n.quadraticCurveTo(r,a,l,c),n.stroke()}n.restore()},updateEffects(e,t){for(let i=e.length-1;i>=0;i--)e[i].age+=t,e[i].age>=e[i].maxAge&&e.splice(i,1)}},P={init(e,t){const i=new A(e),n=t.type||"bar",r=this.parseData(e,t);if(r&&0!==r.length){switch(n){case"bar":default:this.createBarChart(i,r,t);break;case"line":this.createLineChart(i,r,t);break;case"pie":this.createPieChart(i,r,t);break;case"progress":this.createProgressChart(i,r,t)}d.info("[DataVisualization] Initialized",n,"chart with",r.length,"data points")}else d.warn("[DataVisualization] No data provided for canvas")},parseData(e,t){let i=t.data;if(!i&&e.dataset.canvasData)try{i=JSON.parse(e.dataset.canvasData)}catch(n){d.warn("[DataVisualization] Failed to parse canvas data",n)}if(!i){const t=e.nextElementSibling;if(t&&"SCRIPT"===t.tagName&&"application/json"===t.type)try{i=JSON.parse(t.textContent)}catch(n){d.warn("[DataVisualization] Failed to parse script data",n)}}if(!i)return d.warn("[DataVisualization] No data found"),[];if(!Array.isArray(i))if("number"==typeof i)i=[{value:i,label:"Progress"}];else{if("object"!=typeof i)return d.warn("[DataVisualization] Data format not recognized:",i),[];i=Object.entries(i).map(([e,t])=>({label:e,value:"object"==typeof t&&t.value||t}))}return i},createBarChart(e,t,i){const{ctx:n}=e,{width:r,height:a}=e.getSize(),s=i.padding||40,o=r-2*s,l=a-2*s,c=o/t.length*.8,d=o/t.length*.2,h=Math.max(...t.map(e=>e.value));let u=0;const m=i.animationDuration||2e3;let g=null;const p=n=>{g||(g=n);const r=n-g;u=Math.min(r/m,1);const a=1-Math.pow(1-u,3);e.clear(),this.renderBarChart(e,t,i,a,{padding:s,chartWidth:o,chartHeight:l,barWidth:c,barSpacing:d,maxValue:h}),u<1&&requestAnimationFrame(p)};requestAnimationFrame(p)},renderBarChart(e,t,i,n,r){const{ctx:a}=e,{padding:s,chartHeight:o,barWidth:l,barSpacing:c,maxValue:d}=r;t.forEach((e,t)=>{const r=s+t*(l+c),h=e.value/d*o*n,u=s+o-h;a.fillStyle=e.color||i.barColor||"rgba(100, 150, 255, 0.8)",a.fillRect(r,u,l,h),!1!==i.showLabels&&(a.fillStyle=i.textColor||"#333",a.font=i.font||"12px Arial",a.textAlign="center",a.fillText(e.label,r+l/2,s+o+20),!1!==i.showValues&&a.fillText(Math.round(e.value*n),r+l/2,u-5))}),!1!==i.showAxes&&(a.strokeStyle=i.axisColor||"#ccc",a.lineWidth=1,a.beginPath(),a.moveTo(s,s),a.lineTo(s,s+o),a.stroke(),a.beginPath(),a.moveTo(s,s+o),a.lineTo(s+r.chartWidth,s+o),a.stroke())},createLineChart(e,t,i){const{ctx:n}=e,{width:r,height:a}=e.getSize(),s=i.padding||40,o=r-2*s,l=a-2*s,c=Math.max(...t.map(e=>e.value)),d=Math.min(...t.map(e=>e.value)),h=c-d;let u=0;const m=i.animationDuration||2e3;let g=null;const p=n=>{g||(g=n);const r=n-g;u=Math.min(r/m,1),e.clear(),this.renderLineChart(e,t,i,u,{padding:s,chartWidth:o,chartHeight:l,maxValue:c,minValue:d,valueRange:h}),u<1&&requestAnimationFrame(p)};requestAnimationFrame(p)},renderLineChart(e,t,i,n,r){const{ctx:a}=e,{padding:s,chartWidth:o,chartHeight:l,minValue:c,valueRange:d}=r,h=Math.floor(t.length*n);a.strokeStyle=i.lineColor||"rgba(100, 150, 255, 0.8)",a.lineWidth=i.lineWidth||3,a.lineCap="round",a.lineJoin="round",a.beginPath();for(let u=0;u<=h&&u<t.length;u++){const e=s+u/(t.length-1)*o,i=s+l-(t[u].value-c)/d*l;0===u?a.moveTo(e,i):a.lineTo(e,i)}if(a.stroke(),!1!==i.showPoints){a.fillStyle=i.pointColor||i.lineColor||"rgba(100, 150, 255, 0.8)";for(let e=0;e<=h&&e<t.length;e++){const n=s+e/(t.length-1)*o,r=s+l-(t[e].value-c)/d*l;a.beginPath(),a.arc(n,r,i.pointSize||4,0,2*Math.PI),a.fill(),!1!==i.showLabels&&t[e].label&&(a.fillStyle=i.textColor||"#333",a.font=i.font||"12px Arial",a.textAlign="center",a.fillText(t[e].label,n,s+l+20))}}},createPieChart(e,t,i){const{ctx:n}=e,{width:r,height:a}=e.getSize(),s=r/2,o=a/2,l=Math.min(r,a)/2*.8,c=t.reduce((e,t)=>e+t.value,0);let d=0;const h=i.animationDuration||2e3;let u=null;const m=n=>{u||(u=n);const r=n-u;d=Math.min(r/h,1),e.clear(),this.renderPieChart(e,t,i,d,{centerX:s,centerY:o,radius:l,total:c}),d<1&&requestAnimationFrame(m)};requestAnimationFrame(m)},renderPieChart(e,t,i,n,r){const{ctx:a}=e,{centerX:s,centerY:o,radius:l,total:c}=r;let d=-Math.PI/2;const h=d+2*Math.PI*n;for(let u=0;u<t.length&&!(d>=h);u++){const e=t[u],n=e.value/c*Math.PI*2,r=Math.min(d+n,h);if(r>d&&(a.fillStyle=e.color||this.getDefaultColor(u),a.beginPath(),a.moveTo(s,o),a.arc(s,o,l,d,r),a.closePath(),a.fill(),!1!==i.showLabels&&r===d+n)){const t=d+n/2,r=s+Math.cos(t)*l*.7,c=o+Math.sin(t)*l*.7;a.fillStyle=i.textColor||"#333",a.font=i.font||"12px Arial",a.textAlign="center",a.fillText(e.label,r,c)}d+=n}},createProgressChart(e,t,i){const{ctx:n}=e,{width:r,height:a}=e.getSize();let s=0;const o=i.animationDuration||1500;let l=null;const c=n=>{l||(l=n);const r=n-l;s=Math.min(r/o,1),e.clear(),this.renderProgressChart(e,t,i,s),s<1&&requestAnimationFrame(c)};requestAnimationFrame(c)},renderProgressChart(e,t,i,n){var r;const{ctx:a}=e,{width:s,height:o}=e.getSize(),l=s/2,c=o/2,d=Math.min(s,o)/2*.8,h=i.lineWidth||20,u=(null==(r=t[0])?void 0:r.value)||0,m=i.maxValue||100,g=u/m*n;a.strokeStyle=i.backgroundColor||"rgba(200, 200, 200, 0.3)",a.lineWidth=h,a.beginPath(),a.arc(l,c,d,0,2*Math.PI),a.stroke(),a.strokeStyle=i.color||"rgba(100, 150, 255, 0.8)",a.lineCap="round",a.beginPath(),a.arc(l,c,d,-Math.PI/2,-Math.PI/2+g/m*Math.PI*2),a.stroke(),!1!==i.showText&&(a.fillStyle=i.textColor||"#333",a.font=i.font||"bold 24px Arial",a.textAlign="center",a.textBaseline="middle",a.fillText(Math.round(g)+"%",l,c))},getDefaultColor(e){const t=["rgba(100, 150, 255, 0.8)","rgba(255, 100, 150, 0.8)","rgba(150, 255, 100, 0.8)","rgba(255, 200, 100, 0.8)","rgba(200, 100, 255, 0.8)","rgba(100, 255, 200, 0.8)"];return t[e%t.length]}},T={name:"canvas-animations",init(e={},t=null){return d.info("[CanvasAnimations] Module initialized"),this.initializeCanvasElements(),this},initializeCanvasElements(){const e=document.querySelectorAll("canvas[data-canvas-type]");e.forEach(e=>{this.initElement(e)}),d.info(`[CanvasAnimations] Initialized ${e.length} canvas elements`)},initElement(e,t={}){const i=e.dataset.canvasType,n=this.parseCanvasConfig(e);switch(d.info(`[CanvasAnimations] Initializing canvas type: ${i}`),i){case"interactive":I.init(e,n);break;case"scroll-parallax":C.initParallax(e,n);break;case"scroll-animation":C.initScrollAnimation(e,n);break;case"data-viz":P.init(e,n);break;case"background":this.initBackgroundAnimation(e,n);break;default:d.warn(`[CanvasAnimations] Unknown canvas type: ${i}`)}},parseCanvasConfig(e){const t={};return Object.keys(e.dataset).forEach(i=>{if(i.startsWith("canvas")){const r=i.replace("canvas","").toLowerCase();let a=e.dataset[i];if(a.startsWith("{")&&a.endsWith("}")||a.startsWith("[")&&a.endsWith("]"))try{a=JSON.parse(a)}catch(n){d.warn(`[CanvasAnimations] Failed to parse JSON config: ${i}`,n)}else"true"===a?a=!0:"false"===a?a=!1:isNaN(a)||""===a||(a=parseFloat(a));t[r]=a}}),t},initBackgroundAnimation(e,t){const i=new A(e),n=t.particles||50,r=[];for(let a=0;a<n;a++)r.push({x:Math.random()*e.width,y:Math.random()*e.height,vx:.5*(Math.random()-.5),vy:.5*(Math.random()-.5),size:3*Math.random()+1,opacity:.5*Math.random()+.2});!function n(){i.clear(),i.ctx.fillStyle=t.color||"rgba(100, 150, 255, 0.6)",r.forEach(t=>{t.x+=t.vx,t.y+=t.vy,t.x<0&&(t.x=e.width),t.x>e.width&&(t.x=0),t.y<0&&(t.y=e.height),t.y>e.height&&(t.y=0),i.ctx.save(),i.ctx.globalAlpha=t.opacity,i.ctx.beginPath(),i.ctx.arc(t.x,t.y,t.size,0,2*Math.PI),i.ctx.fill(),i.ctx.restore()}),requestAnimationFrame(n)}()}},$=T.init.bind(T),D=Object.freeze(Object.defineProperty({__proto__:null,default:T,init:$},Symbol.toStringTag,{value:"Module"}));let L="example-module",z=null,O=null;const F=Object.freeze(Object.defineProperty({__proto__:null,destroy:function(){d.info("[example-module] destroy"),z&&(window.removeEventListener("resize",z),z=null),c(L),O&&"function"==typeof O.cleanup&&O.cleanup(),O=null},init:function(e={},t=null){d.info("[example-module] init"),O=t,O&&(O.register("windowSize",{width:window.innerWidth,height:window.innerHeight}),O.register("scrollPosition",{x:0,y:0}),O.register("isVisible",!0)),z=()=>{const e={width:window.innerWidth,height:window.innerHeight};d.info("Fenstergröße geändert:",e),O&&O.set("windowSize",e)},window.addEventListener("resize",z),l(L,()=>{const e=window.scrollY,t=window.scrollX;if(O){const i=O.get("scrollPosition");i.x===t&&i.y===e||O.set("scrollPosition",{x:t,y:e})}},{autoStart:!0})}},Symbol.toStringTag,{value:"Module"}));class R{constructor(e){this.form=e,this.errors=new Map}static create(e){return new R(e)}validate(){this.errors.clear();const e=this.form.querySelectorAll("input, textarea, select");for(const t of e)"hidden"===t.type||t.disabled||this.validateField(t);return 0===this.errors.size}validateField(e){const t=e.value,i=e.name;if(e.hasAttribute("required")&&(!t||""===t.trim()))return void this.errors.set(i,this.getErrorMessage(e,"valueMissing")||`${this.getFieldLabel(e)} ist erforderlich`);if(!t||""===t.trim())return;if("email"===e.type&&!this.isValidEmail(t))return void this.errors.set(i,this.getErrorMessage(e,"typeMismatch")||"Bitte geben Sie eine gültige E-Mail-Adresse ein");if("url"===e.type&&!this.isValidUrl(t))return void this.errors.set(i,this.getErrorMessage(e,"typeMismatch")||"Bitte geben Sie eine gültige URL ein");const n=e.getAttribute("minlength");if(n&&t.length<parseInt(n))return void this.errors.set(i,this.getErrorMessage(e,"tooShort")||`Mindestens ${n} Zeichen erforderlich`);const r=e.getAttribute("maxlength");if(r&&t.length>parseInt(r))return void this.errors.set(i,this.getErrorMessage(e,"tooLong")||`Maximal ${r} Zeichen erlaubt`);if("number"===e.type){const n=e.getAttribute("min"),r=e.getAttribute("max"),a=parseFloat(t);if(n&&a<parseFloat(n))return void this.errors.set(i,this.getErrorMessage(e,"rangeUnderflow")||`Wert muss mindestens ${n} sein`);if(r&&a>parseFloat(r))return void this.errors.set(i,this.getErrorMessage(e,"rangeOverflow")||`Wert darf maximal ${r} sein`)}const a=e.getAttribute("pattern");if(a){if(!new RegExp(a).test(t))return void this.errors.set(i,this.getErrorMessage(e,"patternMismatch")||"Ungültiges Format")}const s=e.getAttribute("data-validate");if(s){const n=this.runCustomValidation(s,t,e);if(!n.valid)return void this.errors.set(i,n.message)}}runCustomValidation(e,t,i){switch(e){case"phone":return{valid:/^[\+]?[0-9\s\-\(\)]{10,}$/.test(t),message:"Bitte geben Sie eine gültige Telefonnummer ein"};case"postal-code-de":return{valid:/^[0-9]{5}$/.test(t),message:"Bitte geben Sie eine gültige Postleitzahl ein"};case"no-html":return{valid:!/<[^>]*>/g.test(t),message:"HTML-Code ist nicht erlaubt"};default:return d.warn(`Unknown custom validation: ${e}`),{valid:!0,message:""}}}isValidEmail(e){return/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(e)}isValidUrl(e){try{return new URL(e),!0}catch{return!1}}getFieldLabel(e){const t=this.form.querySelector(`label[for="${e.id}"]`)||this.form.querySelector(`label:has([name="${e.name}"])`);return t?t.textContent.trim().replace(":",""):e.name}getErrorMessage(e,t){return e.getAttribute(`data-error-${t}`)||e.getAttribute("data-error")}getErrors(){return Object.fromEntries(this.errors)}getFieldError(e){return this.errors.get(e)}hasErrors(){return this.errors.size>0}clearErrors(){this.errors.clear()}validateWithHTML5(){const e=this.form.checkValidity();if(!e){const e=this.form.querySelectorAll("input, textarea, select");for(const t of e)t.validity.valid||this.errors.set(t.name,t.validationMessage)}return e}}class _{constructor(e){this.form=e,this.pristineValues=new Map,this.touchedFields=new Set,this.dirtyFields=new Set,this.init()}static create(e){return new _(e)}init(){this.captureInitialValues(),this.bindEvents(),d.info(`[FormState] Initialized for form: ${this.form.id||"unnamed"}`)}captureInitialValues(){this.form.querySelectorAll("input, textarea, select").forEach(e=>{let t;switch(e.type){case"checkbox":case"radio":t=e.checked;break;default:t=e.value}this.pristineValues.set(e.name,t)})}bindEvents(){this.form.querySelectorAll("input, textarea, select").forEach(e=>{"hidden"!==e.type&&(e.addEventListener("focus",()=>{this.markAsTouched(e.name)}),e.addEventListener("input",()=>{this.checkDirtyState(e)}),e.addEventListener("change",()=>{this.checkDirtyState(e)}))})}markAsTouched(e){this.touchedFields.add(e),this.updateFormClasses()}checkDirtyState(e){const t=e.name;this.getFieldValue(e)!==this.pristineValues.get(t)?this.dirtyFields.add(t):this.dirtyFields.delete(t),this.updateFormClasses()}getFieldValue(e){switch(e.type){case"checkbox":case"radio":return e.checked;default:return e.value}}updateFormClasses(){this.isDirty()?(this.form.classList.add("form-dirty"),this.form.classList.remove("form-pristine")):(this.form.classList.add("form-pristine"),this.form.classList.remove("form-dirty")),this.hasTouchedFields()?this.form.classList.add("form-touched"):this.form.classList.remove("form-touched")}isPristine(){return 0===this.dirtyFields.size}isDirty(){return this.dirtyFields.size>0}hasTouchedFields(){return this.touchedFields.size>0}isFieldTouched(e){return this.touchedFields.has(e)}isFieldDirty(e){return this.dirtyFields.has(e)}isFieldPristine(e){return!this.dirtyFields.has(e)}getFieldState(e){return{pristine:this.isFieldPristine(e),dirty:this.isFieldDirty(e),touched:this.isFieldTouched(e),pristineValue:this.pristineValues.get(e),currentValue:this.getCurrentFieldValue(e)}}getCurrentFieldValue(e){const t=this.form.querySelector(`[name="${e}"]`);return t?this.getFieldValue(t):void 0}getFormState(){return{pristine:this.isPristine(),dirty:this.isDirty(),touched:this.hasTouchedFields(),dirtyFields:Array.from(this.dirtyFields),touchedFields:Array.from(this.touchedFields),totalFields:this.pristineValues.size}}reset(){this.touchedFields.clear(),this.dirtyFields.clear(),setTimeout(()=>{this.captureInitialValues(),this.updateFormClasses()},0),d.info("[FormState] State reset")}resetField(e){this.touchedFields.delete(e),this.dirtyFields.delete(e);const t=this.form.querySelector(`[name="${e}"]`),i=this.pristineValues.get(e);if(t&&void 0!==i)switch(t.type){case"checkbox":case"radio":t.checked=i;break;default:t.value=i}this.updateFormClasses(),d.info(`[FormState] Field "${e}" reset to pristine state`)}triggerStateEvent(e,t={}){const i=new CustomEvent(e,{detail:{...t,formState:this.getFormState()},bubbles:!0,cancelable:!0});this.form.dispatchEvent(i)}hasChanges(){return this.isDirty()}getChangedFields(){const e={};return this.dirtyFields.forEach(t=>{e[t]={pristineValue:this.pristineValues.get(t),currentValue:this.getCurrentFieldValue(t)}}),e}enableUnsavedChangesWarning(){window.addEventListener("beforeunload",e=>{if(this.isDirty())return e.preventDefault(),e.returnValue="Sie haben ungespeicherte Änderungen. Möchten Sie die Seite wirklich verlassen?",e.returnValue})}destroy(){this.pristineValues.clear(),this.touchedFields.clear(),this.dirtyFields.clear(),d.info("[FormState] Destroyed")}}class B{constructor(e,t={}){this.form=e,this.options={validateOnSubmit:!0,validateOnBlur:!1,validateOnInput:!1,showInlineErrors:!0,preventSubmitOnError:!0,submitMethod:"POST",ajaxSubmit:!0,...t},this.validator=R.create(e),this.state=_.create(e),this.isSubmitting=!1,this.init()}static create(e,t={}){return new B(e,t)}init(){this.bindEvents(),this.setupErrorDisplay(),this.form.setAttribute("data-enhanced","true"),d.info(`[FormHandler] Initialized for form: ${this.form.id||"unnamed"}`)}bindEvents(){if(this.form.addEventListener("submit",e=>this.handleSubmit(e)),this.options.validateOnBlur||this.options.validateOnInput){this.form.querySelectorAll("input, textarea, select").forEach(e=>{this.options.validateOnBlur&&e.addEventListener("blur",()=>this.validateSingleField(e)),this.options.validateOnInput&&e.addEventListener("input",()=>this.validateSingleField(e))})}}async handleSubmit(e){if(this.isSubmitting)e.preventDefault();else{if(this.options.validateOnSubmit){if(!this.validator.validate())return e.preventDefault(),void this.displayErrors()}this.options.ajaxSubmit&&(e.preventDefault(),await this.submitViaAjax())}}async submitViaAjax(){try{this.setSubmitState(!0),this.clearErrors();const e=new FormData(this.form),t=this.form.action||window.location.href,i=this.form.method||this.options.submitMethod,n=await fetch(t,{method:i.toUpperCase(),body:e,headers:{"X-Requested-With":"XMLHttpRequest"}}),r=await this.parseResponse(n);n.ok?this.handleSuccess(r):this.handleError(r)}catch(e){d.error("[FormHandler] Submit error:",e),this.handleError({message:"Ein Fehler ist aufgetreten. Bitte versuchen Sie es erneut.",errors:{}})}finally{this.setSubmitState(!1)}}async parseResponse(e){const t=e.headers.get("content-type");if(null==t?void 0:t.includes("application/json"))return await e.json();const i=await e.text();try{return JSON.parse(i)}catch{return{message:i}}}handleSuccess(e){d.info("[FormHandler] Form submitted successfully"),!1!==e.clearForm&&(this.form.reset(),this.state.reset()),this.showMessage(e.message||"Formular erfolgreich gesendet!","success"),this.triggerEvent("form:success",{data:e})}handleError(e){if(d.warn("[FormHandler] Form submission error:",e),e.errors&&"object"==typeof e.errors){for(const[t,i]of Object.entries(e.errors))this.validator.errors.set(t,i);this.displayErrors()}this.showMessage(e.message||"Ein Fehler ist aufgetreten.","error"),this.triggerEvent("form:error",{data:e})}validateSingleField(e){this.validator.errors.delete(e.name),this.validator.validateField(e),this.displayFieldError(e)}displayErrors(){if(!this.options.showInlineErrors)return;const e=this.validator.getErrors();for(const[t,i]of Object.entries(e)){const e=this.form.querySelector(`[name="${t}"]`);e&&this.displayFieldError(e,i)}}displayFieldError(e,t=null){const i=t||this.validator.getFieldError(e.name),n=this.getOrCreateErrorElement(e);i?(n.textContent=i,n.style.display="block",e.classList.add("error"),e.setAttribute("aria-invalid","true"),e.setAttribute("aria-describedby",n.id)):(n.textContent="",n.style.display="none",e.classList.remove("error"),e.removeAttribute("aria-invalid"),e.removeAttribute("aria-describedby"))}getOrCreateErrorElement(e){const t=`error-${e.name}`;let i=document.getElementById(t);if(!i){i=document.createElement("div"),i.id=t,i.className="form-error",i.setAttribute("role","alert"),i.style.display="none";(e.closest(".form-group")||e.parentElement).appendChild(i)}return i}setupErrorDisplay(){if(!document.getElementById("form-handler-styles")){const e=document.createElement("style");e.id="form-handler-styles",e.textContent="\n .form-error {\n color: #dc2626;\n font-size: 0.875rem;\n margin-top: 0.25rem;\n }\n input.error, textarea.error, select.error {\n border-color: #dc2626;\n box-shadow: 0 0 0 1px #dc2626;\n }\n .form-message {\n padding: 0.75rem;\n border-radius: 0.375rem;\n margin: 1rem 0;\n }\n .form-message.success {\n background-color: #dcfce7;\n color: #166534;\n border: 1px solid #bbf7d0;\n }\n .form-message.error {\n background-color: #fef2f2;\n color: #dc2626;\n border: 1px solid #fecaca;\n }\n ",document.head.appendChild(e)}}showMessage(e,t="info"){let i=this.form.querySelector(".form-messages");i||(i=document.createElement("div"),i.className="form-messages",this.form.prepend(i));const n=document.createElement("div");n.className=`form-message ${t}`,n.textContent=e,n.setAttribute("role","error"===t?"alert":"status"),i.innerHTML="",i.appendChild(n),"success"===t&&setTimeout(()=>{n.parentElement&&n.remove()},5e3)}clearErrors(){this.validator.clearErrors();this.form.querySelectorAll(".error").forEach(e=>{e.classList.remove("error"),e.removeAttribute("aria-invalid"),e.removeAttribute("aria-describedby")});this.form.querySelectorAll(".form-error").forEach(e=>{e.style.display="none",e.textContent=""});const e=this.form.querySelector(".form-messages");e&&(e.innerHTML="")}setSubmitState(e){this.isSubmitting=e;this.form.querySelectorAll('button[type="submit"], input[type="submit"]').forEach(t=>{if(t.disabled=e,e)t.setAttribute("data-original-text",t.textContent),t.textContent="Wird gesendet...";else{const e=t.getAttribute("data-original-text");e&&(t.textContent=e,t.removeAttribute("data-original-text"))}})}triggerEvent(e,t={}){const i=new CustomEvent(e,{detail:t,bubbles:!0,cancelable:!0});this.form.dispatchEvent(i)}destroy(){this.form.removeAttribute("data-enhanced"),d.info("[FormHandler] Destroyed")}}const q={name:"form-handling",init(e={},t=null){return d.info("[FormHandling] Module initialized (ready for DOM elements)"),this},initElement(e,t={}){d.info(`[FormHandling] Initializing on form: ${e.id||"unnamed"}`);const i={validateOnSubmit:!0,validateOnBlur:!1,validateOnInput:!1,showInlineErrors:!0,preventSubmitOnError:!0,ajaxSubmit:!0,submitMethod:"POST",enableStateTracking:!0,enableUnsavedWarning:!1,...t},n=B.create(e,i);e._formHandler=n,e._formValidator=n.validator,e._formState=n.state,i.enableUnsavedWarning&&n.state.enableUnsavedChangesWarning(),e.classList.add("form-enhanced");const r=new CustomEvent("form:initialized",{detail:{handler:n,validator:n.validator,state:n.state,config:i},bubbles:!0});return e.dispatchEvent(r),d.info(`[FormHandling] Successfully initialized for form: ${e.id||"unnamed"}`),n},destroyElement(e){e._formHandler&&(e._formHandler.destroy(),delete e._formHandler,delete e._formValidator,delete e._formState),e.classList.remove("form-enhanced"),e.removeAttribute("data-enhanced"),d.info(`[FormHandling] Destroyed for form: ${e.id||"unnamed"}`)},destroy(){d.info("[FormHandling] Module destroyed")}},W=q.init.bind(q),j=q.initElement.bind(q),N=Object.freeze(Object.defineProperty({__proto__:null,FormHandler:B,FormHandlingModule:q,FormState:_,FormValidator:R,default:q,init:W,initElement:j},Symbol.toStringTag,{value:"Module"})),V={name:"image-manager",activeGalleries:new Map,activeUploaders:new Map,async init(e={},t){return d.info("[ImageManager] Module initialized"),this.initializeGalleries(),this.initializeUploaders(),this.initializeModal(),this},initializeGalleries(){const e=document.querySelectorAll("[data-image-gallery]");d.info(`[ImageManager] Found ${e.length} gallery elements`),e.forEach((e,t)=>{const i=`gallery-${t}`,n=new H(e,{listEndpoint:e.dataset.listEndpoint||"/api/images",pageSize:parseInt(e.dataset.pageSize)||20,columns:parseInt(e.dataset.columns)||4});this.activeGalleries.set(i,n),d.info(`[ImageManager] Initialized gallery: ${i}`)})},initializeUploaders(){const e=document.querySelectorAll("[data-image-uploader]");d.info(`[ImageManager] Found ${e.length} uploader elements`),e.forEach((e,t)=>{var i;const n=`uploader-${t}`,r=new U(e,{uploadUrl:e.dataset.uploadUrl||"/api/images",maxFileSize:parseInt(e.dataset.maxFileSize)||10485760,allowedTypes:(null==(i=e.dataset.allowedTypes)?void 0:i.split(","))||["image/jpeg","image/png","image/gif","image/webp"],maxFiles:parseInt(e.dataset.maxFiles)||10});this.activeUploaders.set(n,r),d.info(`[ImageManager] Initialized uploader: ${n}`)})},initializeModal(){const e=new G;window.ImageModal=e,d.info("[ImageManager] Modal initialized")},destroy(){this.activeGalleries.forEach((e,t)=>{e.destroy(),d.info(`[ImageManager] Destroyed gallery: ${t}`)}),this.activeGalleries.clear(),this.activeUploaders.forEach((e,t)=>{e.destroy(),d.info(`[ImageManager] Destroyed uploader: ${t}`)}),this.activeUploaders.clear(),window.ImageModal&&(window.ImageModal.destroy(),delete window.ImageModal),d.info("[ImageManager] Module destroyed")}};class H{constructor(e,t){this.element=e,this.config=t,this.currentPage=1,this.images=[],this.loading=!1,this.init()}async init(){d.info("[ImageGallery] Initializing gallery"),this.element.innerHTML="",this.buildGalleryUI(),await this.loadImages()}buildGalleryUI(){this.element.innerHTML=`\n <div class="image-gallery">\n <div class="gallery__controls">\n <div class="gallery__search-wrapper">\n <input type="text" class="gallery__search" placeholder="Search images...">\n <button type="button" class="gallery__search-clear">×</button>\n </div>\n <div class="gallery__sort-wrapper">\n <label>Sort:</label>\n <select class="gallery__sort">\n <option value="created_desc">Newest First</option>\n <option value="created_asc">Oldest First</option>\n <option value="name_asc">Name A-Z</option>\n <option value="name_desc">Name Z-A</option>\n </select>\n </div>\n </div>\n <div class="gallery__grid" style="--columns: ${this.config.columns}"></div>\n <div class="gallery__pagination">\n <button type="button" class="gallery__load-more" style="display: none;">Load More</button>\n </div>\n <div class="gallery__loading">\n <div class="loading-spinner"></div>\n <p>Loading images...</p>\n </div>\n </div>\n `,this.setupEventListeners()}setupEventListeners(){const e=this.element.querySelector(".gallery__search"),t=this.element.querySelector(".gallery__search-clear"),i=this.element.querySelector(".gallery__sort"),n=this.element.querySelector(".gallery__load-more");let r;e.addEventListener("input",e=>{clearTimeout(r),r=setTimeout(()=>{this.searchImages(e.target.value)},300)}),t.addEventListener("click",()=>{e.value="",this.searchImages("")}),i.addEventListener("change",e=>{this.sortImages(e.target.value)}),n.addEventListener("click",()=>{this.loadMoreImages()})}async loadImages(){if(!this.loading){this.loading=!0,this.showLoading();try{d.info("[ImageGallery] Loading images from:",this.config.listEndpoint);const e=await fetch(`${this.config.listEndpoint}?page=${this.currentPage}&limit=${this.config.pageSize}`);if(!e.ok)throw new Error(`HTTP ${e.status}: ${e.statusText}`);const t=await e.json();d.info("[ImageGallery] API Response:",t);let i=[],n={};t.data&&Array.isArray(t.data)?(i=t.data,n=t.meta||{}):t.images&&Array.isArray(t.images)?(i=t.images,n=t):Array.isArray(t)?(i=t,n={}):(d.warn("[ImageGallery] Unexpected API response format:",t),i=[],n={}),d.info("[ImageGallery] Processed images:",i.length),1===this.currentPage?this.images=i:this.images=[...this.images,...i],this.renderImages(),this.updateLoadMoreButton(n)}catch(e){d.error("[ImageGallery] Failed to load images:",e),this.showError(`Failed to load images: ${e.message}`)}finally{this.loading=!1,this.hideLoading()}}}renderImages(){const e=this.element.querySelector(".gallery__grid");0!==this.images.length?(e.innerHTML=this.images.map(e=>this.renderImageItem(e)).join(""),e.querySelectorAll(".gallery__item").forEach((e,t)=>{e.addEventListener("click",()=>{this.showImageModal(this.images[t])})})):e.innerHTML='\n <div class="gallery__empty">\n <div class="empty-state__icon">\n <svg width="48" height="48" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1">\n <rect x="3" y="3" width="18" height="18" rx="2" ry="2"></rect>\n <circle cx="8.5" cy="8.5" r="1.5"></circle>\n <polyline points="21,15 16,10 5,21"></polyline>\n </svg>\n </div>\n <h3>No images found</h3>\n <p>Upload some images to get started</p>\n </div>\n '}renderImageItem(e){let t="0 B",i="0 × 0";return e.file_size&&("object"==typeof e.file_size&&e.file_size.bytes?t=this.formatFileSize(e.file_size.bytes):"number"==typeof e.file_size&&(t=this.formatFileSize(e.file_size))),e.dimensions&&e.dimensions.width&&e.dimensions.height?i=`${e.dimensions.width} × ${e.dimensions.height}`:e.width&&e.height&&(i=`${e.width} × ${e.height}`),`\n <div class="gallery__item" data-image-id="${e.ulid}">\n <div class="gallery__item-inner">\n <div class="gallery__item-image">\n <img src="${e.url}" alt="${e.alt_text||e.filename}" loading="lazy">\n <div class="gallery__item-overlay">\n <div class="gallery__item-actions">\n <button type="button" class="action-btn" title="View Details">👁</button>\n <button type="button" class="action-btn" title="Edit">✏️</button>\n <button type="button" class="action-btn" title="Delete">🗑</button>\n </div>\n </div>\n </div>\n <div class="gallery__item-info">\n <div class="gallery__item-name" title="${e.original_filename||e.filename}">\n ${e.original_filename||e.filename}\n </div>\n <div class="gallery__item-meta">\n <span class="meta-item">${i}</span>\n <span class="meta-item">${t}</span>\n <span class="meta-item">${(e.mime_type||"").replace("image/","")}</span>\n </div>\n </div>\n </div>\n </div>\n `}showImageModal(e){window.ImageModal&&window.ImageModal.show(e)}formatFileSize(e){if(0===e)return"0 B";const t=Math.floor(Math.log(e)/Math.log(1024));return`${Math.round(e/Math.pow(1024,t)*100)/100} ${["B","KB","MB","GB"][t]}`}showLoading(){const e=this.element.querySelector(".gallery__loading");e&&(e.style.display="flex")}hideLoading(){const e=this.element.querySelector(".gallery__loading");e&&(e.style.display="none")}showError(e){this.element.querySelector(".gallery__grid").innerHTML=`\n <div class="gallery__error">\n <div class="error-message">\n <span>⚠️</span>\n <span>${e}</span>\n <button type="button" class="error-close" onclick="this.parentElement.parentElement.remove()">×</button>\n </div>\n </div>\n `}updateLoadMoreButton(e){var t;const i=this.element.querySelector(".gallery__load-more");e.has_more||e.hasMore||(null==(t=e.pagination)?void 0:t.hasMore)||!1?(i.style.display="block",i.disabled=!1):i.style.display="none"}async loadMoreImages(){this.currentPage++,await this.loadImages()}searchImages(e){const t=this.images.filter(t=>(t.filename||"").toLowerCase().includes(e.toLowerCase())||(t.original_filename||"").toLowerCase().includes(e.toLowerCase())||(t.alt_text||"").toLowerCase().includes(e.toLowerCase()));this.element.querySelector(".gallery__grid").innerHTML=t.map(e=>this.renderImageItem(e)).join("")}sortImages(e){const t=[...this.images];switch(e){case"created_desc":t.sort((e,t)=>new Date(t.created_at)-new Date(e.created_at));break;case"created_asc":t.sort((e,t)=>new Date(e.created_at)-new Date(t.created_at));break;case"name_asc":t.sort((e,t)=>(e.filename||"").localeCompare(t.filename||""));break;case"name_desc":t.sort((e,t)=>(t.filename||"").localeCompare(e.filename||""))}this.images=t,this.renderImages()}destroy(){this.element.innerHTML="",d.info("[ImageGallery] Gallery destroyed")}}class U{constructor(e,t){this.element=e,this.config=t,d.info("[ImageUploader] Uploader placeholder initialized")}destroy(){d.info("[ImageUploader] Uploader destroyed")}}class G{constructor(){d.info("[ImageModal] Modal placeholder initialized")}show(e){d.info("[ImageModal] Would show modal for image:",e)}destroy(){d.info("[ImageModal] Modal destroyed")}}const K=V.init.bind(V),J=V.destroy.bind(V),X=Object.freeze(Object.defineProperty({__proto__:null,default:V,definition:{name:"image-manager",version:"1.0.0",dependencies:[],provides:["image-upload","image-gallery","image-modal"],priority:5},destroy:J,init:K},Symbol.toStringTag,{value:"Module"}));let Y,Q="inertia-scroll",Z=0,ee=window.scrollY,te=!1,ie=.9,ne=.2;function re(){te=!0,clearTimeout(Y),Y=setTimeout(()=>{te=!1},50)}const ae=Object.freeze(Object.defineProperty({__proto__:null,destroy:function(){window.removeEventListener("scroll",re),c(Q),Z=0,ee=window.scrollY,te=!1,clearTimeout(Y);const e=document.documentElement;delete e.dataset.scrollState,delete e.dataset.scrollDirection,delete e.dataset.scrollSpeed},init:function(e={}){ie="number"==typeof e.damping?e.damping:.9,ne="number"==typeof e.minVelocity?contig.minVelocity:.1,window.addEventListener("scroll",re,{passive:!0}),l(Q,()=>{const e=document.documentElement,t=window.scrollY,i=t-ee,n=i>0?"down":i<0?"up":"none",r=Math.abs(i);!te&&Math.abs(Z)>ne?(window.scrollTo(0,t+Z),Z*=ie,e.dataset.scrollState="inertia"):te?(Z=i,ee=t,e.dataset.scrollState="active"):delete e.dataset.scrollState,e.dataset.scrollDirection=n,e.dataset.scrollSpeed=r.toFixed(2)},{autoStart:!0})}},Symbol.toStringTag,{value:"Module"}));class se{constructor({content:e="",className:t="",onClose:i=null}={}){this.onClose=i,this.className=t,this.isOpenState=!1,this.dialog=document.createElement("dialog"),this.dialog.className=t,this.eventCleanup=[],this.updateContent(e),this.bindEvents()}bindEvents(){this.cleanupEvents(),this.clickHandler=e=>{!e.target.closest("."+this.className+"-content")&&this.close()},this.cancelHandler=e=>{e.preventDefault(),this.close()},this.dialog.addEventListener("click",this.clickHandler),this.dialog.addEventListener("cancel",this.cancelHandler),this.eventCleanup=[()=>this.dialog.removeEventListener("click",this.clickHandler),()=>this.dialog.removeEventListener("cancel",this.cancelHandler)]}cleanupEvents(){this.eventCleanup.forEach(e=>e()),this.eventCleanup=[]}updateContent(e){this.dialog.innerHTML=`\n <form method="dialog" class="${this.className}-content">\n ${e}\n <button class="${this.className}-close" value="close">×</button>\n </form>\n `}open(){var e,t,i,n;this.dialog.parentElement||document.body.appendChild(this.dialog),(this.dialog.hasAttribute("open")||this.dialog.open)&&((null==(t=(e=this.dialog).close)?void 0:t.call(e))||this.dialog.removeAttribute("open")),(null==(n=(i=this.dialog).showModal)?void 0:n.call(i))||this.dialog.setAttribute("open",""),document.documentElement.dataset[`${this.dialog.className}Open`]="true",this.isOpenState=!0}close(){var e,t,i;this.isOpenState&&((null==(t=(e=this.dialog).close)?void 0:t.call(e))||this.dialog.removeAttribute("open"),delete document.documentElement.dataset[`${this.dialog.className}Open`],this.isOpenState=!1,null==(i=this.onClose)||i.call(this))}isOpen(){const e=this.dialog&&(this.dialog.hasAttribute("open")||this.dialog.open);return e!==this.isOpenState&&(this.isOpenState=e),this.isOpenState}destroy(){this.isOpenState&&this.close(),this.cleanupEvents(),this.dialog.parentElement&&this.dialog.remove()}}const oe={modal:class extends se{constructor(e){super({...e,className:"modal"})}},lightbox:class extends se{constructor(e){super({...e,className:"lightbox"})}}},le={},ce={open(e,t={}){const i=oe[e];if(!i)return d.warn(`[UIManager] Unknown type: ${e}`),null;if("lightbox"===e){if(le.lightbox)return d.info("[UIManager] Reusing existing lightbox instance"),le.lightbox.updateContent(t.content||""),le.lightbox.open(),le.lightbox;{d.info("[UIManager] Creating new lightbox instance");const e=new i({...t,onClose:()=>{d.info("[UIManager] Lightbox closed, instance kept for reuse"),t.onClose&&t.onClose()}});return le.lightbox=e,e.open(),e}}const n=new i(t);return n.open(),n},close(e){(null==e?void 0:e.close)&&e.close()},closeByType(e){le[e]&&this.close(le[e])},isOpen(e){var t;return(null==(t=le[e])?void 0:t.isOpen())||!1},destroyAll(){Object.values(le).forEach(e=>{(null==e?void 0:e.destroy)&&e.destroy()}),Object.keys(le).forEach(e=>{delete le[e]})}};function de(e){let t=null;if(t="IMG"===e.target.tagName?e.target:e.target.querySelector("img"),!t)return;if("false"===t.dataset.lightbox)return;if(t.naturalWidth<200||t.naturalHeight<200)return;if(t.closest("nav, header, footer, .no-lightbox"))return;e.preventDefault();const i=function(e){if(e.dataset.lightboxSrc)return e.dataset.lightboxSrc;if(e.currentSrc)return e.currentSrc;return e.src}(t),n=t.alt||t.dataset.caption||t.title||"",r=t.closest("picture");let a;if(r){const e=r.cloneNode(!0);e.querySelector("img").className="lightbox-image",a=`\n <div class="lightbox-content">\n ${e.outerHTML}\n ${n?`<div class="lightbox-caption">${n}</div>`:""}\n </div>\n `,d.info("[Lightbox] Opening responsive image (picture element):",i)}else a=`\n <div class="lightbox-content">\n <img src="${i}" alt="${n}" class="lightbox-image" />\n ${n?`<div class="lightbox-caption">${n}</div>`:""}\n </div>\n `,d.info("[Lightbox] Opening standalone image:",i);const s=ce.open("lightbox",{content:a});ce.isOpen("lightbox")&&s&&d.info("[Lightbox] Reused existing lightbox instance")}const he=Object.freeze(Object.defineProperty({__proto__:null,destroy:function(){d.info("[lightbox-trigger] destroy"),document.querySelectorAll("img.lightbox-enabled").forEach(e=>{e.classList.remove("lightbox-enabled"),e.style.cursor="","Klicken zum Vergrößern"===e.title&&(e.title="")})},init:function(){d.info("[lightbox-trigger] Auto-enabling lightbox for all images (including picture/srcset)"),d.info('[lightbox-trigger] Use data-lightbox="false" to opt-out'),d.info("[lightbox-trigger] Use data-lightbox-src for custom high-res versions"),E(document,"click",de),function(){const e=document.querySelectorAll('img:not([data-lightbox="false"])');let t=0;e.forEach(e=>{e.naturalWidth<200||e.naturalHeight<200||e.closest("nav, header, footer, .no-lightbox")||(e.classList.add("lightbox-enabled"),e.style.cursor="zoom-in",e.title||e.alt||(e.title="Klicken zum Vergrößern"),t++)}),d.info(`[Lightbox] Enhanced ${t} images with lightbox functionality`)}()}},Symbol.toStringTag,{value:"Module"}));const ue=new class{constructor(){this.components=new Map,this.eventHandlers=new Map,this.csrf=this.getCSRFToken(),this.debounceTimers=new Map}init(e){const t=e.dataset.liveComponent;if(!t)return;const i={id:t,element:e,pollInterval:parseInt(e.dataset.pollInterval)||null,pollTimer:null};this.components.set(t,i),this.setupActionHandlers(e),this.setupFileUploadHandlers(e),i.pollInterval&&this.startPolling(t),console.log(`[LiveComponent] Initialized: ${t}`)}setupActionHandlers(e){e.querySelectorAll("[data-live-action]").forEach(t=>{if("INPUT"===t.tagName||"TEXTAREA"===t.tagName||"SELECT"===t.tagName){const i=parseInt(t.dataset.liveDebounce)||0;t.addEventListener("input",async n=>{const r=e.dataset.liveComponent,a=t.dataset.liveAction,s=this.extractParams(t);"checkbox"===t.type?s[t.name||"value"]=t.checked?"yes":"no":(t.type,s[t.name||"value"]=t.value),i>0?this.debouncedAction(r,a,s,i):await this.executeAction(r,a,s)}),"radio"!==t.type&&"checkbox"!==t.type||t.addEventListener("change",async i=>{const n=e.dataset.liveComponent,r=t.dataset.liveAction,a=this.extractParams(t);"checkbox"===t.type?a[t.name||"value"]=t.checked?"yes":"no":"radio"===t.type&&(a[t.name||"value"]=t.value),await this.executeAction(n,r,a)})}else t.addEventListener("click",async i=>{i.preventDefault();const n=e.dataset.liveComponent,r=t.dataset.liveAction,a=this.extractParams(t);await this.executeAction(n,r,a)})})}debouncedAction(e,t,i,n){const r=`${e}_${t}`;this.debounceTimers.has(r)&&clearTimeout(this.debounceTimers.get(r));const a=setTimeout(async()=>{await this.executeAction(e,t,i),this.debounceTimers.delete(r)},n);this.debounceTimers.set(r,a)}extractParams(e){const t={};return Object.keys(e.dataset).forEach(i=>{if(i.startsWith("param")){const n=i.replace("param","").toLowerCase();t[n]=e.dataset[i]}}),t}async executeAction(e,t,i={}){const n=this.components.get(e);if(n)try{const r=n.element.dataset.state||"{}",a=JSON.parse(r),s=a.data||a,o=await fetch(`/live-component/${e}`,{method:"POST",headers:{"Content-Type":"application/json","X-CSRF-Token":this.csrf,"X-Requested-With":"XMLHttpRequest"},body:JSON.stringify({method:t,params:i,state:s})});if(!o.ok)throw new Error(`HTTP ${o.status}: ${o.statusText}`);const l=await o.json();l.html&&(n.element.innerHTML=l.html,this.setupActionHandlers(n.element)),l.state&&(n.element.dataset.state=l.state),l.events&&l.events.length>0&&this.handleServerEvents(l.events),console.log(`[LiveComponent] Action executed: ${e}.${t}`,l)}catch(r){console.error("[LiveComponent] Action failed:",r),this.handleError(e,r)}else console.error(`[LiveComponent] Unknown component: ${e}`)}handleServerEvents(e){e.forEach(e=>{const{name:t,payload:i,target:n}=e;console.log("[LiveComponent] Server event:",{name:t,payload:i,target:n}),n?this.dispatchToComponent(n,t,i):this.broadcast(t,i)})}dispatchToComponent(e,t,i){(this.eventHandlers.get(t)||[]).forEach(t=>{t.componentId===e&&t.callback(i)})}broadcast(e,t){(this.eventHandlers.get(e)||[]).forEach(e=>{e.callback(t)}),document.dispatchEvent(new CustomEvent(`livecomponent:${e}`,{detail:t}))}on(e,t,i){this.eventHandlers.has(t)||this.eventHandlers.set(t,[]),this.eventHandlers.get(t).push({componentId:e,callback:i}),console.log(`[LiveComponent] Event listener registered: ${e} -> ${t}`)}startPolling(e){const t=this.components.get(e);t&&t.pollInterval&&(t.pollTimer&&clearInterval(t.pollTimer),t.pollTimer=setInterval(async()=>{await this.executeAction(e,"poll",{})},t.pollInterval),console.log(`[LiveComponent] Polling started: ${e} (${t.pollInterval}ms)`))}stopPolling(e){const t=this.components.get(e);t&&t.pollTimer&&(clearInterval(t.pollTimer),t.pollTimer=null,console.log(`[LiveComponent] Polling stopped: ${e}`))}getCSRFToken(){const e=document.querySelector('meta[name="csrf-token"]');return e?e.content:""}handleError(e,t){const i=this.components.get(e);if(!i)return;const n=`\n <div class="livecomponent-error" style="padding: 1rem; background: #fee; color: #c00; border: 1px solid #faa; border-radius: 4px;">\n <strong>LiveComponent Error:</strong> ${t.message}\n </div>\n `;i.element.insertAdjacentHTML("beforeend",n),setTimeout(()=>{var e;null==(e=i.element.querySelector(".livecomponent-error"))||e.remove()},5e3)}setupFileUploadHandlers(e){const t=e.dataset.liveComponent;e.querySelectorAll('input[type="file"][data-live-upload]').forEach(e=>{e.addEventListener("change",async e=>{const i=e.target.files;i.length>0&&await this.uploadFile(t,i[0])})}),e.querySelectorAll("[data-live-dropzone]").forEach(e=>{this.setupDropzone(t,e)})}setupDropzone(e,t){["dragenter","dragover","dragleave","drop"].forEach(e=>{t.addEventListener(e,e=>{e.preventDefault(),e.stopPropagation()})}),["dragenter","dragover"].forEach(e=>{t.addEventListener(e,()=>{t.classList.add("drag-over")})}),["dragleave","drop"].forEach(e=>{t.addEventListener(e,()=>{t.classList.remove("drag-over")})}),t.addEventListener("drop",async t=>{const i=t.dataTransfer.files;i.length>0&&await this.uploadFile(e,i[0])})}async uploadFile(e,t,i={}){const n=this.components.get(e);if(n)try{const r=n.element.dataset.state||"{}",a=JSON.parse(r),s=new FormData;s.append("file",t),s.append("state",JSON.stringify(a)),s.append("params",JSON.stringify(i)),this.showUploadProgress(e,0);const o=await fetch(`/live-component/${e}/upload`,{method:"POST",headers:{"X-CSRF-Token":this.csrf,"X-Requested-With":"XMLHttpRequest"},body:s});if(!o.ok){const e=await o.json();throw new Error(e.error||"Upload failed")}const l=await o.json();if(!l.success)throw new Error(l.error||"Upload failed");l.html&&(n.element.innerHTML=l.html,this.setupActionHandlers(n.element),this.setupFileUploadHandlers(n.element)),l.state&&(n.element.dataset.state=l.state),l.events&&l.events.length>0&&this.handleServerEvents(l.events),this.hideUploadProgress(e),console.log(`[LiveComponent] File uploaded: ${e}`,l.file),document.dispatchEvent(new CustomEvent("livecomponent:upload:success",{detail:{componentId:e,file:l.file}}))}catch(r){console.error("[LiveComponent] Upload failed:",r),this.hideUploadProgress(e),this.handleError(e,r),document.dispatchEvent(new CustomEvent("livecomponent:upload:error",{detail:{componentId:e,error:r.message}}))}else console.error(`[LiveComponent] Unknown component: ${e}`)}showUploadProgress(e,t){const i=this.components.get(e);if(!i)return;let n=i.element.querySelector(".livecomponent-upload-progress");if(n){n.querySelector(".progress-bar").style.width=`${t}%`}else{n=document.createElement("div"),n.className="livecomponent-upload-progress",n.style.cssText="\n position: absolute;\n top: 0;\n left: 0;\n right: 0;\n height: 3px;\n background: #e0e0e0;\n z-index: 1000;\n ";const e=document.createElement("div");e.className="progress-bar",e.style.cssText=`\n height: 100%;\n background: #2196F3;\n transition: width 0.3s ease;\n width: ${t}%;\n `,n.appendChild(e),i.element.style.position="relative",i.element.appendChild(n)}}hideUploadProgress(e){const t=this.components.get(e);if(!t)return;const i=t.element.querySelector(".livecomponent-upload-progress");i&&i.remove()}destroy(e){this.stopPolling(e),this.components.delete(e),this.eventHandlers.forEach((t,i)=>{const n=t.filter(t=>t.componentId!==e);this.eventHandlers.set(i,n)}),console.log(`[LiveComponent] Destroyed: ${e}`)}};window.LiveComponent=ue,"loading"===document.readyState&&document.addEventListener("DOMContentLoaded",()=>{document.querySelectorAll("[data-livecomponent]").forEach(e=>{ue.init(e)})});const me=Object.freeze(Object.defineProperty({__proto__:null,LiveComponent:ue,default:ue,definition:{name:"livecomponent",version:"1.0.0",dependencies:[],provides:["LiveComponent"],priority:0},init:async function(e={},t={}){return console.log("[LiveComponent] Module initializing..."),console.log("[LiveComponent] Module initialized (components will be initialized via initElement)"),{manager:ue,state:t}},initElement:function(e,t={}){console.log("[LiveComponent] Initializing element with data-module:",e);const i=e.querySelectorAll("[data-live-component]");return 0===i.length&&e.hasAttribute("data-live-component")?ue.init(e):i.forEach(e=>ue.init(e)),ue}},Symbol.toStringTag,{value:"Module"}));const ge=Object.freeze(Object.defineProperty({__proto__:null,init:function(e={}){d.log("Noise Toggle Init",e);const{selector:t=".noise-overlay",toggleKey:i="g",className:n="grainy",enableTransition:r=!0}=e,a=document.body,s=document.querySelector(t);if(!s)return;function o(){r?s.classList.toggle("hidden",!a.classList.contains(n)):s.style.display=a.classList.contains(n)?"block":"none"}o(),document.addEventListener("keydown",e=>{var t;e.key.toLowerCase()!==i||e.ctrlKey||e.metaKey||e.altKey||(t=e.target,["input","textarea"].includes(t.tagName.toLowerCase()))||(a.classList.toggle(n),o())})}},Symbol.toStringTag,{value:"Module"}));const pe=Object.freeze(Object.defineProperty({__proto__:null,init:function(e={}){d.info("Parallax init");const t={selector:"[data-parallax]",speedAttr:"data-parallax-speed",defaultSpeed:.5,...e},i=document.querySelectorAll(t.selector);l("parallax",function(){const e=window.scrollY;i.forEach(i=>{const n=parseFloat(i.getAttribute(t.speedAttr))||t.defaultSpeed,r=e*n;i.style.transform=`translateY(${r}px)`})},{autoStart:!0})}},Symbol.toStringTag,{value:"Module"}));class fe{constructor(){this.modules=new Map,this.dependents=new Map,this.initialized=new Set,this.initializing=new Set,this.initializationOrder=[]}register(e){this.modules.has(e.name)?d.warn(`[DependencyManager] Module '${e.name}' already registered`):this.validateDefinition(e)&&(this.modules.set(e.name,e),e.dependencies.forEach(t=>{this.dependents.has(t.name)||this.dependents.set(t.name,[]),this.dependents.get(t.name).push(e.name)}),d.info(`[DependencyManager] Registered '${e.name}' v${e.version}`))}calculateInitializationOrder(){const e=new Set,t=new Set,i=[],n=r=>{if(t.has(r))throw new Error(`Circular dependency detected involving '${r}'`);if(e.has(r))return;const a=this.modules.get(r);a&&(t.add(r),a.dependencies.forEach(e=>{e.optional&&!this.modules.has(e.name)||n(e.name)}),t.delete(r),e.add(r),i.push(r))};return Array.from(this.modules.entries()).sort(([,e],[,t])=>(t.priority||0)-(e.priority||0)).map(([e])=>e).forEach(t=>{e.has(t)||n(t)}),this.initializationOrder=i,d.info(`[DependencyManager] Initialization order: ${i.join(" → ")}`),i}checkDependencies(e){const t=this.modules.get(e);if(!t)return{satisfied:!1,missing:[],reason:`Module '${e}' not registered`};const i=[],n=[];return t.dependencies.forEach(e=>{this.modules.get(e.name)?this.initialized.has(e.name)||e.optional||i.push(`${e.name} (not initialized)`):e.optional?n.push(e.name):i.push(e.name)}),{satisfied:0===i.length,missing:i,optional:n,reason:i.length>0?`Missing: ${i.join(", ")}`:"OK"}}markInitialized(e){this.initialized.add(e),this.initializing.delete(e),d.info(`[DependencyManager] '${e}' initialized`)}markInitializing(e){this.initializing.add(e)}getDependents(e){return this.dependents.get(e)||[]}getModule(e){return this.modules.get(e)}isReadyToInitialize(e){if(this.initialized.has(e)||this.initializing.has(e))return!1;return this.checkDependencies(e).satisfied}getStatus(){const e=this.modules.size,t=this.initialized.size,i=this.initializing.size;return{total:e,initialized:t,initializing:i,pending:e-t-i,modules:{initialized:Array.from(this.initialized),initializing:Array.from(this.initializing),pending:Array.from(this.modules.keys()).filter(e=>!this.initialized.has(e)&&!this.initializing.has(e))}}}validateDefinition(e){if(!e.name||"string"!=typeof e.name)return d.error("[DependencyManager] Module name is required and must be string"),!1;if(!e.version||"string"!=typeof e.version)return d.error(`[DependencyManager] Version is required for module '${e.name}'`),!1;if(!Array.isArray(e.dependencies))return d.error(`[DependencyManager] Dependencies must be array for module '${e.name}'`),!1;for(const t of e.dependencies)if(!t.name||"string"!=typeof t.name)return d.error(`[DependencyManager] Invalid dependency in module '${e.name}': missing name`),!1;return!0}reset(){this.modules.clear(),this.dependents.clear(),this.initialized.clear(),this.initializing.clear(),this.initializationOrder=[],d.info("[DependencyManager] Reset complete")}static createDefinition(e,t){const i={name:e,version:t,dependencies:[],provides:[],priority:0},n={depends(e,t="*",n=!1){return i.dependencies.push({name:e,version:t,optional:n}),this},provides(...e){return i.provides.push(...e),this},priority(e){return i.priority=e,this},build:()=>i};return Object.setPrototypeOf(n,i),Object.keys(i).forEach(e=>{e in n||Object.defineProperty(n,e,{get:()=>i[e],set(t){i[e]=t},enumerable:!0,configurable:!0})}),n}}const ve=new fe;"undefined"!=typeof window&&(window.dependencyManager=ve,window.depStatus=()=>ve.getStatus());const ye=fe.createDefinition("scroll-dependent","1.0.0").depends("example-module","1.0.0").depends("scrollfx","1.0.0",!0).provides("scroll-coordination").priority(10);let be=null,we=null;const Se=Object.freeze(Object.defineProperty({__proto__:null,definition:ye,destroy:function(){d.info("[scroll-dependent] destroy"),be&&we&&(we.unsubscribe(be),be=null),we&&"function"==typeof we.cleanup&&we.cleanup(),we=null},init:function(e={},t=null){d.info("[scroll-dependent] init"),we=t,we&&(we.register("isScrolling",!1),we.register("scrollDirection","none"),be=we.subscribe("example-module.scrollPosition",(e,t)=>{if(t.y!==e.y){const i=e.y>t.y?"down":"up";we.set("scrollDirection",i),we.set("isScrolling",!0),setTimeout(()=>{we&&we.set("isScrolling",!1)},150),d.info(`[scroll-dependent] Scroll ${i}: ${e.y}`)}}))}},Symbol.toStringTag,{value:"Module"}));const Me=Object.freeze(Object.defineProperty({__proto__:null,init:function(e={}){const t=document.querySelectorAll("[data-scroll-loop]");t.forEach(e=>{if("translate"===(e.dataset.scrollType||"translate")&&1===e.children.length){const t=e.firstElementChild.cloneNode(!0);t.setAttribute("aria-hidden","true"),e.appendChild(t)}}),l("scroll-loop",()=>{const i=window.scrollY,n=window.scrollX;t.forEach(t=>{const r=parseFloat(t.dataset.scrollSpeed||e.speed||.2),a=t.dataset.scrollAxis||"y",s=t.dataset.scrollType||"translate",o="true"===t.dataset.loopPause,l=parseFloat(t.dataset.loopOffset||0),c=parseFloat(t.dataset.loopLimit||0),d="x"===a?n:i;if(c&&d>c)return;if(o&&(t.matches(":hover")||t.matches(":active")))return;const h=(d+l)*r;switch(s){case"translate":{const e=-h%("x"===a?t.offsetWidth:t.offsetHeight),i="x"===a?`translateX(${e}px)`:`translateY(${e}px)`;t.style.transform=i;break}case"rotate":{const e=h%360;t.style.transform=`rotate(${e}deg)`;break}case"background":{const e=h%100;t.style.backgroundPosition="x"===a?`${e}% center`:`center ${e}%`;break}case"scale":{const e=1+.1*Math.sin(.01*h);t.style.transform=`scale(${e.toFixed(3)})`;break}}})},{autoStart:!0})}},Symbol.toStringTag,{value:"Module"})),ke={onEnter(e,t){t.classList.add("active"),document.body.dataset.activeScrollStep=e,d.info(`[ScrollStep] Enter: ${e}`),1===e&&d.info("Intro sichtbar"),2===e&&d.info("Chart aktiviert"),3===e&&d.info("Zitat eingeblendet")},onLeave(e,t){t.classList.remove("active"),t.style.transitionDelay="",d.info(`[ScrollStep] Leave: ${e}`),document.body.dataset.activeScrollStep===String(e)&&delete document.body.dataset.activeScrollStep,1===e&&d.info("Intro ausgeblendet"),2===e&&d.info("Chart deaktiviert"),3===e&&d.info("Zitat ausgeblendet")}};const xe=Object.freeze(Object.defineProperty({__proto__:null,destroy:function(){c("scroll-timeline")},init:function(e={}){d.info("ScrollTimeline init");const t={attribute:"data-scroll-step",triggerPoint:.4,once:!0,...e},i=Array.from(document.querySelectorAll(`[${t.attribute}]`)).map(e=>({el:e,index:parseInt(e.getAttribute(t.attribute),10),active:!1}));l("scroll-timeline",function(){const e=window.innerHeight*t.triggerPoint;i.forEach(i=>{var n,r;const a=i.el.getBoundingClientRect(),s=a.top<e&&a.bottom>0;s&&!i.active&&(i.active=!0,i.el.classList.add("active"),d.log(`➡️ ENTER step ${i.index}`),null==(n=ke.onEnter)||n.call(ke,i.index,i.el)),!s&&i.active&&(i.active=!1,i.el.classList.remove("active"),d.log(`⬅️ LEAVE step ${i.index}`),t.once||null==(r=ke.onLeave)||r.call(ke,i.index,i.el))})},{autoStart:!0})}},Symbol.toStringTag,{value:"Module"}));const Ee=new class{constructor(){this.triggers=new Set,this.viewportHeight=window.innerHeight,this._loop=this._loop.bind(this),window.addEventListener("resize",()=>{this.viewportHeight=window.innerHeight}),requestAnimationFrame(this._loop)}register(e){this.triggers.add(e)}unregister(e){this.triggers.delete(e)}clear(){this.triggers.clear()}_loop(){this.triggers.forEach(e=>{e.update(this.viewportHeight)}),requestAnimationFrame(this._loop)}};class Ae{constructor(e){if(this.element=this.resolveElement(e.element),this.target=e.target?this.element.querySelector(e.target):this.element,e.target&&!this.target)throw new Error(`Target selector '${e.target}' not found inside element '${e.element}'.`);this.start=e.start||"top 80%",this.end=e.end||"bottom 20%",this.scrub=e.scrub||!1,this.onEnter=e.onEnter||null,this.onLeave=e.onLeave||null,this.onUpdate=e.onUpdate||null,this._wasVisible=!1,this._progress=0}resolveElement(e){if("string"==typeof e){const t=document.querySelectorAll(e);if(1===t.length)return t[0];throw new Error(`Selector '${e}' matched ${t.length} elements, expected exactly 1.`)}return e}getScrollProgress(e){const t=this.element.getBoundingClientRect(),i=this.parsePosition(this.start,e),n=this.parsePosition(this.end,e)-i,r=t.top-i;return 1-Math.min(Math.max(r/n,0),1)}parsePosition(e,t){const[i,n]=e.split(" ");return("top"===i?0:t)-t*(parseFloat(n)/100)}update(e){const t=this.element.getBoundingClientRect(),i=t.bottom>0&&t.top<e;if(i&&!this._wasVisible&&(this._wasVisible=!0,this.onEnter&&this.onEnter(this.target)),!i&&this._wasVisible&&(this._wasVisible=!1,this.onLeave&&this.onLeave(this.target)),this.scrub&&i){const t=this.getScrollProgress(e);this.onUpdate&&this.onUpdate(this.target,t)}}}const Ce=Object.freeze(Object.defineProperty({__proto__:null,createTrigger:function(e){const t="string"==typeof e.element?document.querySelectorAll(e.element):[e.element],i=[];return t.forEach(t=>{const n=new Ae({...e,element:t});Ee.register(n),i.push(n)}),1===i.length?i[0]:i},init:function(e={}){const{selector:t=".fade-in-on-scroll, .zoom-in, .fade-out, .fade",offset:i=.85,baseDelay:n=.05,once:r=!0}=e,a=Array.from(document.querySelectorAll(t)).map(e=>({el:e,triggered:!1}));requestAnimationFrame(function e(){const t=window.innerHeight*i;a.forEach((e,i)=>{if(e.triggered&&r)return;e.el.getBoundingClientRect().top<t?(e.el.style.transitionDelay=i*n+"s",e.el.classList.add("visible","entered"),e.el.classList.remove("fade-out"),e.triggered=!0):r||(e.el.classList.remove("visible","entered"),e.triggered=!1)}),requestAnimationFrame(e)})}},Symbol.toStringTag,{value:"Module"})),Ie=Object.freeze(Object.defineProperty({__proto__:null},Symbol.toStringTag,{value:"Module"}));class Pe{constructor(e={}){this.options={containerSelector:"main",linkSelector:'a[href^="/"]',loadingClass:"spa-loading",excludeSelector:'[data-spa="false"], [download], [target="_blank"], [href^="mailto:"], [href^="tel:"], [href^="#"]',enableTransitions:!0,transitionDuration:100,skeletonTemplate:this.createSkeletonTemplate(),...e},this.container=null,this.isLoading=!1,this.currentUrl=window.location.href,this.abortController=null,this.handleLinkClick=this.handleLinkClick.bind(this),this.handlePopState=this.handlePopState.bind(this),this.handleFormSubmit=this.handleFormSubmit.bind(this),this.init()}static create(e={}){return new Pe(e)}init(){this.container=document.querySelector(this.options.containerSelector),this.container?(this.bindEvents(),this.setupStyles(),this.updateHistoryState(window.location.href,document.title),d.info("[SPARouter] Initialized")):d.error(`[SPARouter] Container "${this.options.containerSelector}" not found`)}bindEvents(){document.addEventListener("click",this.handleLinkClick),window.addEventListener("popstate",this.handlePopState),document.addEventListener("submit",this.handleFormSubmit)}handleLinkClick(e){const t=e.target.closest(this.options.linkSelector);if(!t)return;if(t.matches(this.options.excludeSelector))return;if(e.ctrlKey||e.metaKey||e.shiftKey)return;e.preventDefault();const i=t.href,n=t.title||t.textContent.trim();this.navigate(i,n)}handlePopState(e){const t=window.location.href;t!==this.currentUrl&&this.loadContent(t,!1)}handleFormSubmit(e){const t=e.target;t.hasAttribute("data-spa")&&"false"===t.getAttribute("data-spa")||t._moduleInstance}async navigate(e,t=""){var i;if(this.isLoading&&(d.warn("[SPARouter] Already loading, aborting previous request"),null==(i=this.abortController)||i.abort()),e!==this.currentUrl){d.info(`[SPARouter] Navigating to: ${e}`);try{await this.loadContent(e,!0,t)}catch(n){"AbortError"!==n.name&&(d.error("[SPARouter] Navigation failed:",n),window.location.href=e)}}else d.info(`[SPARouter] Already at ${e}, skipping navigation`)}async loadContent(e,t=!0,i=""){var n;if(e!==this.currentUrl||t){this.isLoading&&(null==(n=this.abortController)||n.abort()),this.isLoading=!0,this.abortController=new AbortController;try{this.showLoadingState();const n=await fetch(e,{headers:{"X-Requested-With":"XMLHttpRequest","X-SPA-Request":"true",Accept:"application/json, text/html"},signal:this.abortController.signal});if(!n.ok)throw new Error(`HTTP ${n.status}: ${n.statusText}`);const r=n.headers.get("content-type");let a,s;if(null==r?void 0:r.includes("application/json")){const e=await n.json();a=e.html,s=e.title||i,e.meta&&this.updateMetaTags(e.meta)}else{const e=await n.text();a=this.extractMainContent(e),s=this.extractTitle(e)||i}await this.updateContent(a,s),t&&this.updateHistoryState(e,s),this.currentUrl=e,d.info(`[SPARouter] Successfully loaded: ${e}`)}catch(r){if("AbortError"!==r.name)throw this.hideLoadingState(),r}finally{this.isLoading=!1,this.abortController=null}}}extractMainContent(e){const t=(new DOMParser).parseFromString(e,"text/html"),i=t.querySelector("main");if(i)return i.innerHTML;const n=['[role="main"]',".main-content","#main",".content"];for(const r of n){const e=t.querySelector(r);if(e)return d.warn(`[SPARouter] Using fallback selector: ${r}`),e.innerHTML}return d.warn("[SPARouter] No main element found, using entire body"),t.body.innerHTML}extractTitle(e){const t=(new DOMParser).parseFromString(e,"text/html").querySelector("title");return t?t.textContent.trim():""}async updateContent(e,t){t&&(document.title=t),this.options.enableTransitions&&await this.transitionOut(),this.container.innerHTML=e,this.reinitializeModules(),this.options.enableTransitions&&await this.transitionIn(),this.hideLoadingState(),window.scrollTo({top:0,behavior:"smooth"}),this.triggerNavigationEvent()}showLoadingState(){document.body.classList.add(this.options.loadingClass),this.options.enableTransitions&&this.container.classList.add("spa-transitioning-out")}hideLoadingState(){document.body.classList.remove(this.options.loadingClass)}async transitionOut(){return new Promise(e=>{this.container.style.transition=`opacity ${this.options.transitionDuration}ms cubic-bezier(0.4, 0, 1, 1)`,this.container.style.opacity="0",setTimeout(()=>{e()},this.options.transitionDuration)})}async transitionIn(){return new Promise(e=>{this.container.style.opacity="0",setTimeout(()=>{this.container.style.transition=`opacity ${this.options.transitionDuration}ms cubic-bezier(0, 0, 0.2, 1)`,this.container.style.opacity="1",setTimeout(()=>{this.container.style.transition="",this.container.classList.remove("spa-transitioning-out"),e()},this.options.transitionDuration)},10)})}updateHistoryState(e,t){const i={url:e,title:t,timestamp:Date.now()};e!==window.location.href?history.pushState(i,t,e):history.replaceState(i,t,e)}reinitializeModules(){window.initAutoFormHandling&&window.initAutoFormHandling();this.container.querySelectorAll("[data-module]").forEach(e=>{const t=e.dataset.module;d.info(`[SPARouter] Re-initializing module "${t}" on new content`);const i=new CustomEvent("spa:reinit-module",{detail:{element:e,moduleName:t},bubbles:!0});e.dispatchEvent(i)})}createSkeletonTemplate(){return'\n <div class="spa-skeleton">\n <div class="spa-skeleton-header"></div>\n <div class="spa-skeleton-content">\n <div class="spa-skeleton-line"></div>\n <div class="spa-skeleton-line"></div>\n <div class="spa-skeleton-line short"></div>\n </div>\n </div>\n '}setupStyles(){if(document.getElementById("spa-router-styles"))return;const e=document.createElement("style");e.id="spa-router-styles",e.textContent="\n /* SPA Router Transitions */\n .spa-loading {\n cursor: progress;\n }\n \n .spa-transitioning-out {\n pointer-events: none;\n }\n \n /* Skeleton Loading Styles */\n .spa-skeleton {\n animation: spa-pulse 1.5s ease-in-out infinite alternate;\n }\n \n .spa-skeleton-header {\n height: 2rem;\n background: #e5e7eb;\n border-radius: 0.375rem;\n margin-bottom: 1rem;\n width: 60%;\n }\n \n .spa-skeleton-content {\n space-y: 0.75rem;\n }\n \n .spa-skeleton-line {\n height: 1rem;\n background: #e5e7eb;\n border-radius: 0.375rem;\n margin-bottom: 0.75rem;\n }\n \n .spa-skeleton-line.short {\n width: 75%;\n }\n \n @keyframes spa-pulse {\n 0% {\n opacity: 1;\n }\n 100% {\n opacity: 0.4;\n }\n }\n \n /* Dark mode support */\n @media (prefers-color-scheme: dark) {\n .spa-skeleton-header,\n .spa-skeleton-line {\n background: #374151;\n }\n }\n ",document.head.appendChild(e)}updateMetaTags(e){if(e.description){let t=document.querySelector('meta[name="description"]');t?t.content=e.description:(t=document.createElement("meta"),t.name="description",t.content=e.description,document.head.appendChild(t))}Object.entries(e).forEach(([e,t])=>{if("description"!==e&&t){let i=document.querySelector(`meta[name="${e}"]`);i?i.content=t:(i=document.createElement("meta"),i.name=e,i.content=t,document.head.appendChild(i))}})}triggerNavigationEvent(){const e=new CustomEvent("spa:navigated",{detail:{url:this.currentUrl,container:this.container,timestamp:Date.now()},bubbles:!0});document.dispatchEvent(e)}navigateTo(e,t){return this.navigate(e,t)}getCurrentUrl(){return this.currentUrl}isNavigating(){return this.isLoading}destroy(){var e;null==(e=this.abortController)||e.abort(),document.removeEventListener("click",this.handleLinkClick),window.removeEventListener("popstate",this.handlePopState),document.removeEventListener("submit",this.handleFormSubmit);const t=document.getElementById("spa-router-styles");t&&t.remove(),d.info("[SPARouter] Destroyed")}}const Te={enableTransitions:!0,transitionDuration:50},$e={enableTransitions:!0,transitionDuration:100},De={enableTransitions:!1,transitionDuration:0};function Le(){if(window.matchMedia("(prefers-reduced-motion: reduce)").matches)return De;const e=navigator.connection||navigator.mozConnection||navigator.webkitConnection;if(e){if("4g"===e.effectiveType)return Te;if("3g"===e.effectiveType)return $e}/Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent);return $e}const ze={name:"spa-router",router:null,initialized:!1,init(e={}){if(this.initialized&&this.router)return d.warn("[SPARouterModule] SPA Router already initialized, returning existing instance"),this.router;d.info("[SPARouterModule] Initializing SPA Router");const t={...{containerSelector:"main",linkSelector:'a[href^="/"]',excludeSelector:'[data-spa="false"], [download], [target="_blank"], [href^="mailto:"], [href^="tel:"], [href^="#"]',enableSkeletonLoading:!0,...$e,...Le()},...e};return this.router=Pe.create(t),this.initialized=!0,"undefined"!=typeof window&&(window.spaRouter=this.router),document.addEventListener("spa:reinit-module",this.handleModuleReinit.bind(this)),document.addEventListener("spa:navigated",this.handleNavigation.bind(this)),d.info("[SPARouterModule] SPA Router initialized successfully"),this.router},handleModuleReinit(e){const{element:t,moduleName:i}=e.detail;d.info(`[SPARouterModule] Re-initializing module: ${i}`,t);const n=new CustomEvent("module:reinit-needed",{detail:{element:t,moduleName:i},bubbles:!0});document.dispatchEvent(n)},handleNavigation(e){const{url:t,timestamp:i}=e.detail;d.info(`[SPARouterModule] Navigation completed to: ${t}`),"function"==typeof window.initAutoFormHandling&&setTimeout(()=>{window.initAutoFormHandling()},100),"function"==typeof window.gtag&&window.gtag("config","GA_TRACKING_ID",{page_path:new URL(t).pathname})},navigateTo(e,t){if(this.router)return this.router.navigateTo(e,t);d.warn("[SPARouterModule] Router not initialized")},getCurrentUrl(){var e;return(null==(e=this.router)?void 0:e.getCurrentUrl())||window.location.href},isNavigating(){var e;return(null==(e=this.router)?void 0:e.isNavigating())||!1},destroy(){this.router&&(this.router.destroy(),this.router=null),this.initialized=!1,"undefined"!=typeof window&&window.spaRouter&&delete window.spaRouter,document.removeEventListener("spa:reinit-module",this.handleModuleReinit),document.removeEventListener("spa:navigated",this.handleNavigation),d.info("[SPARouterModule] SPA Router destroyed")}},Oe=ze.init.bind(ze),Fe=Object.freeze(Object.defineProperty({__proto__:null,SPARouter:Pe,SPARouterModule:ze,default:ze,init:Oe},Symbol.toStringTag,{value:"Module"}));let Re="sticky-fade",_e=[],Be=window.scrollY,qe=new WeakMap,We={direction:!1,reset:!1};const je=Object.freeze(Object.defineProperty({__proto__:null,destroy:function(){c(Re),_e.forEach(e=>{e.style.opacity="",e.style.transform="",e.classList.remove("visible"),delete e.dataset.scrollDir}),_e=[],qe=new WeakMap},init:function(e={}){_e=Array.from(document.querySelectorAll("[data-sticky-fade]")),0!==_e.length&&(We.direction=e.direction??!1,We.reset=e.reset??!1,l(Re,()=>{const e=window.scrollY,t=e>Be?"down":e<Be?"up":"none";Be=e;const i=window.innerHeight;_e.forEach(e=>{const n=e.getBoundingClientRect(),r=1-Math.min(Math.max(n.top/i,0),1);if(e.style.opacity=r.toFixed(3),e.style.transform=`translateY(${20*(1-r)}px)`,We.direction&&(e.dataset.scrollDir=t),We.reset){const t=r>=1,i=qe.get(e)||!1;t&&!i?(e.classList.add("visible"),qe.set(e,!0)):!t&&i&&(e.classList.remove("visible"),qe.set(e,!1))}})},{autoStart:!0}))}},Symbol.toStringTag,{value:"Module"}));const Ne=Object.freeze(Object.defineProperty({__proto__:null,destroy:function(){c("sticky-steps")},init:function(e={}){d.info("StickySteps init");const t={containerSelector:"[data-sticky-container]",stepSelector:"[data-sticky-step]",activeClass:"is-sticky-active",datasetKey:"activeStickyStep",...e};document.querySelectorAll(t.containerSelector).forEach(e=>{const i=e.querySelectorAll(t.stepSelector),n=e.offsetTop;l(`sticky-steps-${e.dataset.moduleId||Math.random()}`,function(){const r=window.scrollY,a=e.offsetHeight;i.forEach((s,o)=>{const l=n+o*(a/i.length),c=n+(o+1)*(a/i.length),d=r>=l&&r<c;s.classList.toggle(t.activeClass,d),d&&(e.dataset[t.datasetKey]=o)})},{autoStart:!0})})}},Symbol.toStringTag,{value:"Module"}));const Ve=Object.freeze(Object.defineProperty({__proto__:null,init:function(){}},Symbol.toStringTag,{value:"Module"})),He=Object.freeze(Object.defineProperty({__proto__:null},Symbol.toStringTag,{value:"Module"})),Ue={noise:{selector:".noise-overlay",toggleKey:"g",className:"grainy",enableTransition:!0},"shortcut-handler.js":{debug:!1},scrollfx:{selector:".fade-in-on-scroll, .zoom-in",offset:.8,baseDelay:.075,once:!0},"scroll-timeline":{attribute:"data-scroll-step",triggerPoint:.4,once:!1},"smooth-scroll":{speed:.2}};const Ge=new class{constructor(){this.crashedModules=new Set,this.recoveryAttempts=new Map,this.maxRecoveryAttempts=3,this.recoveryDelay=1e3}wrapModule(e,t){return e&&"object"==typeof e?new Proxy(e,{get:(e,i,n)=>{const r=e[i];if("function"!=typeof r)return r;const a=Object.getOwnPropertyDescriptor(e,i);return a&&!a.configurable?r:(...n)=>{try{const a=r.apply(e,n);return a&&"function"==typeof a.catch?a.catch(e=>(this.handleModuleError(e,t,i,n),this.getRecoveryValue(t,i))):a}catch(a){return this.handleModuleError(a,t,i,n),this.getRecoveryValue(t,i)}}},getOwnPropertyDescriptor:(e,t)=>{const i=Object.getOwnPropertyDescriptor(e,t);return i&&i.configurable,i},has:(e,t)=>t in e,ownKeys:e=>Object.getOwnPropertyNames(e)}):(d.warn(`[ErrorBoundary] Cannot wrap non-object module: ${t}`),e)}handleModuleError(e,t,i,n){const r=`${t}.${i}`;d.error(`[ErrorBoundary] Module ${t} crashed in ${i}():`,e),this.crashedModules.add(t);const a=this.recoveryAttempts.get(r)||0;this.recoveryAttempts.set(r,a+1),window.dispatchEvent(new CustomEvent("module-error",{detail:{moduleName:t,method:i,error:e.message,args:n,attempts:a+1}})),a<this.maxRecoveryAttempts?this.scheduleRecovery(t,i,n):(d.error(`[ErrorBoundary] Module ${t} exceeded recovery attempts. Marking as permanently failed.`),this.markModuleAsPermanentlyFailed(t))}scheduleRecovery(e,t,i){setTimeout(()=>{try{d.info(`[ErrorBoundary] Attempting recovery for ${e}.${t}()`)}catch(i){d.error(`[ErrorBoundary] Recovery failed for ${e}.${t}():`,i)}},this.recoveryDelay)}getRecoveryValue(e,t){switch(t){case"init":case"destroy":case"update":case"render":return Promise.resolve();case"getData":case"getConfig":return{};case"isEnabled":case"isActive":return!1;default:return}}markModuleAsPermanentlyFailed(e){window.dispatchEvent(new CustomEvent("module-permanent-failure",{detail:{moduleName:e}}))}getHealthStatus(){return{totalCrashedModules:this.crashedModules.size,crashedModules:Array.from(this.crashedModules),recoveryAttempts:Object.fromEntries(this.recoveryAttempts),timestamp:(new Date).toISOString()}}resetModule(e){this.crashedModules.delete(e);for(const[t]of this.recoveryAttempts)t.startsWith(`${e}.`)&&this.recoveryAttempts.delete(t);d.info(`[ErrorBoundary] Reset error tracking for module: ${e}`)}reset(){this.crashedModules.clear(),this.recoveryAttempts.clear(),d.info("[ErrorBoundary] Reset all error tracking")}};window.addEventListener("error",e=>{d.error("[Global] Unhandled error:",e.error||e.message)}),window.addEventListener("unhandledrejection",e=>{d.error("[Global] Unhandled promise rejection:",e.reason)});const Ke=new class{constructor(){this.state=new Map,this.subscribers=new Map,this.stateOwners=new Map,this.defaultValues=new Map,this.currentModule="unknown",this.subscriptionCounter=0}setContext(e){this.currentModule=e}register(e,t,i=this.currentModule){this.state.has(e)?d.warn(`[StateManager] State key '${e}' already registered by ${this.stateOwners.get(e)}`):(this.state.set(e,t),this.defaultValues.set(e,t),this.stateOwners.set(e,i),this.subscribers.set(e,[]),d.info(`[StateManager] Registered '${e}' (owner: ${i})`))}get(e){if(this.state.has(e))return this.state.get(e);d.warn(`[StateManager] Unknown state key: '${e}'`)}set(e,t,i=!1){if(!this.state.has(e))return d.warn(`[StateManager] Cannot set unknown state key: '${e}'`),!1;const n=this.stateOwners.get(e);if(!i&&n!==this.currentModule)return d.warn(`[StateManager] Module '${this.currentModule}' cannot modify '${e}' (owned by ${n})`),!1;const r=this.state.get(e);return r===t||(this.state.set(e,t),this.notifySubscribers(e,t,r),d.info(`[StateManager] Updated '${e}' by ${this.currentModule}`)),!0}subscribe(e,t,i=this.currentModule){if(!this.state.has(e))return d.warn(`[StateManager] Cannot subscribe to unknown state key: '${e}'`),null;const n=`${i}_${++this.subscriptionCounter}`,r={id:n,callback:t,subscriber:i};return this.subscribers.has(e)||this.subscribers.set(e,[]),this.subscribers.get(e).push(r),d.info(`[StateManager] Subscribed '${i}' to '${e}'`),n}unsubscribe(e){for(const[t,i]of this.subscribers.entries()){const n=i.findIndex(t=>t.id===e);if(-1!==n){const e=i[n];return i.splice(n,1),void d.info(`[StateManager] Unsubscribed '${e.subscriber}' from '${t}'`)}}d.warn(`[StateManager] Subscription ID not found: ${e}`)}notifySubscribers(e,t,i){(this.subscribers.get(e)||[]).forEach(n=>{try{n.callback(t,i,e)}catch(r){d.error(`[StateManager] Error in subscriber '${n.subscriber}' for '${e}':`,r)}})}reset(e){if(!this.state.has(e))return d.warn(`[StateManager] Cannot reset unknown state key: '${e}'`),!1;const t=this.defaultValues.get(e);return this.set(e,t,!0)}clearModuleSubscriptions(e){let t=0;for(const[i,n]of this.subscribers.entries()){const r=n.filter(t=>t.subscriber!==e);t+=n.length-r.length,this.subscribers.set(i,r)}t>0&&d.info(`[StateManager] Cleared ${t} subscriptions for module '${e}'`)}getSnapshot(){const e={state:Object.fromEntries(this.state),owners:Object.fromEntries(this.stateOwners),subscriptions:{}};for(const[t,i]of this.subscribers.entries())e.subscriptions[t]=i.map(e=>({id:e.id,subscriber:e.subscriber}));return e}resetAll(){this.state.clear(),this.subscribers.clear(),this.stateOwners.clear(),this.defaultValues.clear(),this.subscriptionCounter=0,d.info("[StateManager] Reset complete")}createScope(e){return{register:(t,i)=>(this.setContext(e),this.register(t,i,e)),get:e=>this.get(e),set:(t,i)=>(this.setContext(e),this.set(t,i)),subscribe:(t,i)=>(this.setContext(e),this.subscribe(t,i,e)),unsubscribe:e=>this.unsubscribe(e),reset:e=>this.reset(e),cleanup:()=>this.clearModuleSubscriptions(e)}}};"undefined"!=typeof window&&(window.stateManager=Ke,window.stateSnapshot=()=>Ke.getSnapshot());const Je=new Map;function Xe(){const e=document.querySelectorAll("[data-module]");d.info(`[DOMInit] Found ${e.length} elements with data-module attributes`),e.forEach(e=>{const t=e.dataset.module,i=Je.get(t);if(!i||!i.mod)return void d.warn(`[DOMInit] Module "${t}" not found or failed to initialize`);let n={};try{e.dataset.options&&(n=JSON.parse(e.dataset.options))}catch(r){d.warn(`[DOMInit] Invalid JSON in data-options for ${t}:`,r)}try{const r=i.mod;if("function"==typeof r.initElement){const i=r.initElement(e,n);d.info(`[DOMInit] Initialized ${t} on element:`,e),e._moduleInstance=i,e._moduleName=t}else if("function"==typeof r.init){const i=r.init(e,n);d.info(`[DOMInit] Initialized ${t} on element:`,e),e._moduleInstance=i,e._moduleName=t}else d.warn(`[DOMInit] Module ${t} has no init method for DOM elements`)}catch(r){d.error(`[DOMInit] Failed to initialize ${t} on element:`,r,e)}})}function Ye(){const e=document.querySelectorAll('form:not([data-form-handling="false"]):not([data-auto-enhanced])');if(d.info(`[AutoForms] Found ${e.length} forms for auto-enhancement`),0===e.length)return;const t=Je.get("form-handling");t&&t.mod?e.forEach(e=>{if(e.hasAttribute("data-module"))return void d.info("[AutoForms] Skipping form with explicit data-module:",e);if(e.hasAttribute("data-auto-enhanced"))return;let i={};try{e.dataset.formOptions&&(i=JSON.parse(e.dataset.formOptions))}catch(r){d.warn("[AutoForms] Invalid JSON in data-form-options:",r)}const n={validateOnSubmit:!0,validateOnBlur:!1,validateOnInput:!1,showInlineErrors:!0,ajaxSubmit:!0,enableStateTracking:!1,...i};try{const i=t.mod.initElement?t.mod.initElement(e,n):t.mod.init(e,n);d.info("[AutoForms] Auto-enhanced form:",{id:e.id||"unnamed",action:e.action||"none",method:e.method||"get",elements:e.elements.length}),e.setAttribute("data-auto-enhanced","true"),e._moduleInstance=i,e._moduleName="form-handling"}catch(r){d.error("[AutoForms] Failed to auto-enhance form:",r,e)}}):d.warn("[AutoForms] form-handling module not available, skipping auto-init")}async function Qe(){await async function(){var e;let t;t="undefined"!=typeof global&&(null==(e=global.importMeta)?void 0:e.glob)?global.importMeta.glob("./*/index.js",{eager:!0}):Object.assign({"./api-manager/index.js":M,"./canvas-animations/index.js":D,"./example-module/index.js":F,"./form-handling/index.js":N,"./image-manager/index.js":X,"./inertia-scroll/index.js":ae,"./lightbox-trigger/index.js":he,"./livecomponent/index.js":me,"./noise/index.js":ge,"./parallax/index.js":pe,"./scroll-dependent/index.js":Se,"./scroll-loop/index.js":Me,"./scroll-timeline/index.js":xe,"./scrollfx/index.js":Ce,"./smooth-scroll/index.js":Ie,"./spa-router/index.js":Fe,"./sticky-fade/index.js":je,"./sticky-steps/index.js":Ne,"./ui/index.js":Ve,"./wheel-boost/index.js":He}),d.info("[Modules] Found modules:",Object.keys(t));const i=new Set(Array.from(document.querySelectorAll("[data-module]")).map(e=>e.dataset.module).filter(Boolean)),n=new Set(["spa-router","form-handling","api-manager","image-manager"]),r=new Set([...i,...n]),a=r.size===n.size&&0===i.size;d.info("[Modules] DOM modules found:",[...i]),d.info("[Modules] Core modules:",[...n]),d.info("[Modules] Used modules:",[...r]),d.info("[Modules] Fallback mode:",a),console.log("🔍 [Modules] Starting Phase 1 - Module Registration"),console.log("🔍 [Modules] All discovered modules:",Object.keys(t)),console.log("🔍 [Modules] Used modules:",[...r]),console.log("🔍 [Modules] Fallback mode:",a),Object.entries(t).forEach(([e,t])=>{const i=e.split("/").slice(-2,-1)[0];if(console.log(`🔍 [Module] Processing: ${i} from ${e}`),console.log(`🔍 [Module] Used modules has ${i}:`,r.has(i)),a||r.has(i))if(console.log(`✅ [Module] Registering ${i} with dependency manager`),"object"==typeof t.definition)d.info(`📋 [Module] Using definition for ${i}:`,t.definition),ve.register(t.definition);else{const e={name:i,version:"1.0.0",dependencies:[],provides:[],priority:0};d.info(`📋 [Module] Using default definition for ${i}:`,e),ve.register(e)}else console.log(`⏭️ [Module] Skipping unused module: ${i}`)});const s=ve.calculateInitializationOrder();console.log("🔍 [Modules] Phase 2 - Initialization Order:",s);for(const l of s){if(console.log(`🔍 [Module] Phase 3 - Processing ${l} for initialization`),console.log(`🔍 [Module] Used modules has ${l}:`,r.has(l)),console.log("🔍 [Module] Fallback mode:",a),!a&&!r.has(l)){console.log(`⏭️ [Module] Skipped (not used in DOM): ${l}`);continue}const e=Object.keys(t).find(e=>e.split("/").slice(-2,-1)[0]===l);if(console.log(`🔍 [Module] Looking for module path for ${l}, found:`,e),!e){console.log(`⛔ [Module] No implementation found for: ${l}`);continue}const i=t[e],n=Ue[l]||{};console.log(`🔍 [Module] Module ${l} object:`,i),console.log(`🔍 [Module] Config for ${l}:`,n);const s=ve.checkDependencies(l);if(console.log(`🔍 [Module] Dependency check for ${l}:`,s),s.satisfied)if(console.log(`🔍 [Module] Checking init function for ${l}:`,typeof i.init,i.init),console.log(`🔍 [Module] Module object keys for ${l}:`,Object.keys(i)),console.log(`🔍 [Module] Full module object for ${l}:`,i),"function"==typeof i.init)try{d.info(`🚀 [Module] Starting initialization for ${l}`),ve.markInitializing(l);const e=Ke.createScope(l),t=Ge.wrapModule(i,l);await t.init(n,e),ve.markInitialized(l),Je.set(l,{mod:t,config:n,state:e,original:i}),d.info(`✅ [Module] Initialized: ${l}`)}catch(o){d.error(`❌ [Module] Failed to initialize ${l}:`,o),Je.set(l,{mod:null,config:n,error:o,original:i})}else d.warn(`⛔ [Module] No init() in ${l} - typeof:`,typeof i.init),d.warn("⛔ [Module] Available properties:",Object.getOwnPropertyNames(i));else console.log(`❌ [Module] Cannot initialize ${l}: ${s.reason}`),Je.set(l,{mod:null,config:n,error:new Error(s.reason),original:i})}a&&d.info("⚠️ [Module] No data-module usage detected, fallback to full init mode")}(),Xe(),Ye(),function(){const e=Je.get("spa-router");if(e&&e.mod)try{e.mod.init({containerSelector:"main",enableTransitions:!0,transitionDuration:300}),window.initAutoFormHandling=Ye,window.initDataModuleElements=Xe,d.info("[Init] SPA Router initialized successfully")}catch(t){d.error("[Init] Failed to initialize SPA Router:",t)}else d.info("[Init] SPA Router module not available, skipping")}(),function(){const e=document.querySelectorAll("video[data-src]"),t=window.innerWidth,i=(navigator.connection||{}).effectiveType||"4g";e.forEach(e=>{const n=e.dataset.src;let r="480";r="2g"===i||"slow-2g"===i?"480":"3g"===i?t>=1200?"720":"480":t>=1200?"1080":t>=800?"720":"480";const a=`${n}-${r}.webm`,s=document.createElement("video");s.autoplay=!0,s.loop=!0,s.muted=!0,s.playsInline=!0,s.poster=e.getAttribute("poster")||"",s.setAttribute("width",e.getAttribute("width")||"100%");const o=document.createElement("source");o.src=a,o.type="video/webm",s.appendChild(o),e.replaceWith(s)})}()}"undefined"!=typeof window&&(window.moduleHealth=function(){const e={total:Je.size,active:0,failed:0,modules:{},errorBoundary:Ge.getHealthStatus()};for(const[t,{mod:i,error:n}]of Je.entries())n?(e.failed++,e.modules[t]={status:"failed",error:n.message}):i?(e.active++,e.modules[t]={status:"active"}):e.modules[t]={status:"unknown"};return e},window.activeModules=Je);const Ze=class e{constructor(t={}){this.config={...e.DEFAULT_CONFIG,...t},this.intervalId=null,this.isActive=!1,this.retryCount=0,this.lastRefreshTime=null,this.isPageVisible=!document.hidden,this.log("CSRF Auto-Refresh initialized",this.config),this.setupEventListeners(),this.isPageVisible&&this.start()}setupEventListeners(){this.config.pauseWhenHidden&&document.addEventListener("visibilitychange",()=>{this.isPageVisible=!document.hidden,this.isPageVisible?(this.log("Page became visible, resuming CSRF refresh"),this.start()):(this.log("Page became hidden, pausing CSRF refresh"),this.stop())}),window.addEventListener("beforeunload",()=>{this.stop()})}start(){this.isActive?this.log("Auto-refresh already active"):(this.isActive=!0,this.intervalId=setInterval(()=>{this.refreshToken()},this.config.refreshInterval),this.log(`Auto-refresh started. Next refresh in ${this.config.refreshInterval/1e3/60} minutes`),this.config.enableVisualFeedback)}stop(){this.isActive&&(this.intervalId&&(clearInterval(this.intervalId),this.intervalId=null),this.isActive=!1,this.log("Auto-refresh stopped"))}async refreshToken(){if(this.isPageVisible||!this.config.pauseWhenHidden)try{this.log("Refreshing CSRF token...");const e=await fetch(`${this.config.apiEndpoint}?form_id=${encodeURIComponent(this.config.formId)}`,{method:"GET",headers:{Accept:"application/json","X-Requested-With":"XMLHttpRequest"}});if(!e.ok)throw new Error(`HTTP ${e.status}: ${e.statusText}`);const t=await e.json();if(!t.success||!t.token)throw new Error(t.error||"Invalid response from server");this.updateTokenInForms(t.token),this.lastRefreshTime=new Date,this.retryCount=0,this.log("CSRF token refreshed successfully",{token:t.token.substring(0,8)+"...",formId:t.form_id,expiresIn:t.expires_in}),this.config.enableVisualFeedback}catch(e){this.handleRefreshError(e)}else this.log("Page not visible, skipping refresh")}updateTokenInForms(e){const t=document.querySelectorAll(this.config.tokenSelector);let i=0;return t.forEach(t=>{const n=t.closest("form");if(n){const r=n.querySelector(this.config.formIdSelector);r&&r.value===this.config.formId&&(t.value=e,i++)}}),this.log(`Updated ${i} token input(s)`),0===i&&console.warn("CsrfAutoRefresh: No token inputs found to update. Check your selectors."),i}handleRefreshError(e){this.retryCount++,console.error("CSRF token refresh failed:",e),this.retryCount<=this.config.maxRetries?(this.log(`Retrying in ${this.config.retryDelay/1e3}s (attempt ${this.retryCount}/${this.config.maxRetries})`),setTimeout(()=>{this.refreshToken()},this.config.retryDelay),this.config.enableVisualFeedback):(this.log("Max retries reached, stopping auto-refresh"),this.stop(),this.config.enableVisualFeedback)}showStatusMessage(e,t="info"){let i=document.getElementById("csrf-status-message");i||(i=document.createElement("div"),i.id="csrf-status-message",i.style.cssText="\n position: fixed;\n top: 20px;\n right: 20px;\n padding: 12px 16px;\n border-radius: 6px;\n font-size: 14px;\n z-index: 10000;\n max-width: 300px;\n box-shadow: 0 4px 12px rgba(0,0,0,0.1);\n transition: opacity 0.3s ease;\n ",document.body.appendChild(i)),i.textContent=e,i.className=`csrf-status-${t}`;const n={info:"background: #e3f2fd; color: #1976d2; border-left: 4px solid #2196f3;",success:"background: #e8f5e8; color: #2e7d32; border-left: 4px solid #4caf50;",warning:"background: #fff3e0; color: #f57c00; border-left: 4px solid #ff9800;",error:"background: #ffebee; color: #d32f2f; border-left: 4px solid #f44336;"};i.style.cssText+=n[t]||n.info,i.style.opacity="1","error"!==t&&setTimeout(()=>{i&&(i.style.opacity="0",setTimeout(()=>{i&&i.parentNode&&i.parentNode.removeChild(i)},300))},"success"===t?3e3:5e3)}log(e,t=null){if(this.config.enableConsoleLogging){const i=(new Date).toLocaleTimeString();t?console.log(`[${i}] CsrfAutoRefresh: ${e}`,t):console.log(`[${i}] CsrfAutoRefresh: ${e}`)}}getStatus(){var e;return{isActive:this.isActive,formId:this.config.formId,lastRefreshTime:this.lastRefreshTime,retryCount:this.retryCount,isPageVisible:this.isPageVisible,nextRefreshIn:this.isActive?Math.max(0,this.config.refreshInterval-(Date.now()-((null==(e=this.lastRefreshTime)?void 0:e.getTime())||Date.now()))):null}}async manualRefresh(){this.log("Manual refresh triggered"),await this.refreshToken()}static initializeAll(){const t=document.querySelectorAll('input[name="_token"]'),i=new Set;t.forEach(e=>{const t=e.closest("form");if(t){const e=t.querySelector('input[name="_form_id"]');e&&e.value&&i.add(e.value)}});const n=[];return i.forEach(t=>{const i=new e({formId:t});n.push(i)}),console.log(`CsrfAutoRefresh: Initialized for ${n.length} forms:`,Array.from(i)),n}};t(Ze,"DEFAULT_CONFIG",{formId:"contact_form",refreshInterval:63e5,apiEndpoint:"/api/csrf/refresh",tokenSelector:'input[name="_token"]',formIdSelector:'input[name="_form_id"]',enableVisualFeedback:!1,enableConsoleLogging:!0,pauseWhenHidden:!0,maxRetries:3,retryDelay:5e3});let et=Ze;"loading"===document.readyState?document.addEventListener("DOMContentLoaded",()=>{et.initializeAll()}):et.initializeAll();const tt=class e{constructor(t={}){this.config={...e.DEFAULT_CONFIG,...t},this.form=null,this.storageKey=null,this.saveTimer=null,this.lastSaveTime=null,this.hasChanges=!1,this.isInitialized=!1,this.fieldValues=new Map,this.log("FormAutoSave initializing",this.config),this.initialize()}initialize(){this.form=document.querySelector(this.config.formSelector),this.form?(this.storageKey=this.config.storageKey||this.config.storagePrefix+this.generateFormId(),this.log("Form found, storage key:",this.storageKey),this.config.cleanupOnInit&&this.cleanupExpiredDrafts(),this.setupEventListeners(),this.storeInitialValues(),this.restoreDraft(),this.startAutoSave(),this.isInitialized=!0,this.log("FormAutoSave initialized successfully"),this.config.enableVisualFeedback&&this.showStatus("Auto-save enabled","info",3e3)):this.log("Form not found with selector:",this.config.formSelector)}generateFormId(){var e;return(this.form.id||this.form.getAttribute("data-form-id")||(null==(e=this.form.querySelector('input[name="_form_id"]'))?void 0:e.value)||"form_"+Date.now()).replace(/[^a-zA-Z0-9_-]/g,"_")}setupEventListeners(){this.form.addEventListener("input",e=>{this.onFieldChange(e)}),this.form.addEventListener("change",e=>{this.onFieldChange(e)}),this.form.addEventListener("submit",()=>{this.onFormSubmit()}),window.addEventListener("beforeunload",()=>{this.hasChanges&&this.saveDraft()}),document.addEventListener("visibilitychange",()=>{document.hidden&&this.hasChanges&&this.saveDraft()})}storeInitialValues(){const e=this.getFormFields();e.forEach(e=>{const t=this.getFieldKey(e),i=this.getFieldValue(e);this.fieldValues.set(t,i)}),this.log(`Stored initial values for ${e.length} fields`)}onFieldChange(e){const t=e.target;if(this.isFieldExcluded(t))return;const i=this.getFieldKey(t),n=this.getFieldValue(t);n!==this.fieldValues.get(i)&&(this.fieldValues.set(i,n),this.hasChanges=!0,this.log(`Field changed: ${i} = "${n}"`),this.isImmediateField(t)&&this.saveDraft())}onFormSubmit(){this.log("Form submitted, clearing draft"),this.clearDraft(),this.stopAutoSave(),this.config.enableVisualFeedback&&this.showStatus("Form submitted, draft cleared","success",2e3)}startAutoSave(){this.saveTimer||(this.saveTimer=setInterval(()=>{this.hasChanges&&this.saveDraft()},this.config.saveInterval),this.log(`Auto-save started, interval: ${this.config.saveInterval}ms`))}stopAutoSave(){this.saveTimer&&(clearInterval(this.saveTimer),this.saveTimer=null,this.log("Auto-save stopped"))}saveDraft(){if(this.form&&this.hasChanges)try{const e=this.extractFormData(),t={data:e,timestamp:Date.now(),formId:this.generateFormId(),url:window.location.href,version:"1.0"};localStorage.setItem(this.storageKey,JSON.stringify(t)),this.lastSaveTime=new Date,this.hasChanges=!1,this.log("Draft saved",{fields:Object.keys(e).length,size:JSON.stringify(t).length+" chars"}),this.config.enableVisualFeedback&&this.showStatus("Draft saved","success",1500)}catch(e){console.error("Failed to save form draft:",e),this.config.enableVisualFeedback&&this.showStatus("Failed to save draft","error",3e3)}}restoreDraft(){try{const e=localStorage.getItem(this.storageKey);if(!e)return void this.log("No draft found");const t=JSON.parse(e);if(this.isDraftExpired(t))return this.log("Draft expired, removing"),void localStorage.removeItem(this.storageKey);if(t.url&&t.url!==window.location.href)return void this.log("Draft from different URL, skipping restore");this.restoreFormData(t.data);const i=this.formatDuration(Date.now()-t.timestamp);this.log(`Draft restored (age: ${i})`,t.data),this.config.enableVisualFeedback&&this.showStatus(`Draft restored from ${i} ago`,"info",4e3)}catch(e){console.error("Failed to restore draft:",e),localStorage.removeItem(this.storageKey)}}extractFormData(){const e=this.getFormFields(),t={};return e.forEach(e=>{if(!this.isFieldExcluded(e)){const i=this.getFieldKey(e),n=this.getFieldValue(e);null!=n&&""!==n&&(t[i]=n)}}),t}restoreFormData(e){let t=0;Object.entries(e).forEach(([e,i])=>{const n=this.findFieldByKey(e);n&&!this.isFieldExcluded(n)&&(this.setFieldValue(n,i),this.fieldValues.set(e,i),t++)}),this.log(`Restored ${t} field values`);return this.getFormFields().forEach(e=>{this.isFieldExcluded(e)||e.dispatchEvent(new Event("change",{bubbles:!0}))}),t}getFormFields(){return Array.from(this.form.querySelectorAll('input:not([type="submit"]):not([type="button"]):not([type="reset"]), textarea, select'))}isFieldExcluded(e){return this.config.excludeFields.some(t=>e.matches(t))}isImmediateField(e){return this.config.immediateFields.some(t=>e.matches(t))}getFieldKey(e){return e.name||e.id||`field_${e.type}_${Date.now()}`}getFieldValue(e){switch(e.type){case"checkbox":return e.checked;case"radio":return e.checked?e.value:null;case"file":return null;default:return e.value}}setFieldValue(e,t){switch(e.type){case"checkbox":e.checked=Boolean(t);break;case"radio":e.checked=e.value===t;break;case"file":break;default:e.value=t}}findFieldByKey(e){return this.form.querySelector(`[name="${e}"], #${e}`)}isDraftExpired(e){return Date.now()-e.timestamp>this.config.retentionPeriod}clearDraft(){localStorage.removeItem(this.storageKey),this.hasChanges=!1,this.log("Draft cleared")}cleanupExpiredDrafts(){let e=0;const t=this.config.storagePrefix;for(let n=localStorage.length-1;n>=0;n--){const r=localStorage.key(n);if(r&&r.startsWith(t))try{const t=JSON.parse(localStorage.getItem(r));Date.now()-t.timestamp>this.config.maxDraftAge&&(localStorage.removeItem(r),e++)}catch(i){localStorage.removeItem(r),e++}}e>0&&this.log(`Cleaned up ${e} expired drafts`)}formatDuration(e){const t=Math.floor(e/1e3),i=Math.floor(t/60),n=Math.floor(i/60);return n>0?`${n}h ${i%60}m`:i>0?`${i}m`:`${t}s`}showStatus(e,t="info",i=3e3){let n=document.getElementById("form-autosave-status");n||(n=document.createElement("div"),n.id="form-autosave-status",n.style.cssText="\n position: fixed;\n bottom: 20px;\n right: 20px;\n padding: 8px 12px;\n border-radius: 4px;\n font-size: 12px;\n z-index: 9999;\n max-width: 250px;\n box-shadow: 0 2px 8px rgba(0,0,0,0.1);\n transition: opacity 0.3s ease;\n font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;\n ",document.body.appendChild(n)),n.textContent=e,n.className=`autosave-status-${t}`;const r={info:"background: #e3f2fd; color: #1565c0; border: 1px solid #bbdefb;",success:"background: #e8f5e8; color: #2e7d32; border: 1px solid #c8e6c9;",error:"background: #ffebee; color: #c62828; border: 1px solid #ffcdd2;"};n.style.cssText+=r[t]||r.info,n.style.opacity="1",setTimeout(()=>{n&&(n.style.opacity="0",setTimeout(()=>{n&&n.parentNode&&n.parentNode.removeChild(n)},300))},i)}log(e,t=null){if(this.config.enableConsoleLogging){const i=`[${(new Date).toLocaleTimeString()}] FormAutoSave`;t?console.log(`${i}: ${e}`,t):console.log(`${i}: ${e}`)}}getStatus(){return{isInitialized:this.isInitialized,formId:this.generateFormId(),storageKey:this.storageKey,hasChanges:this.hasChanges,lastSaveTime:this.lastSaveTime,fieldCount:this.fieldValues.size,draftExists:!!localStorage.getItem(this.storageKey)}}forceSave(){this.hasChanges=!0,this.saveDraft()}destroy(){this.stopAutoSave(),this.isInitialized=!1,this.log("FormAutoSave destroyed")}static initializeAll(){const t=document.querySelectorAll('form[data-autosave], form:has(input[name="_token"])'),i=[];return t.forEach((t,n)=>{var r;const a=t.id||t.getAttribute("data-form-id")||(null==(r=t.querySelector('input[name="_form_id"]'))?void 0:r.value)||`form_${n}`,s=new e({formSelector:`#${t.id||"form_"+n}`,storageKey:`form_draft_${a}`});t.id||(t.id=`form_${n}`),i.push(s)}),console.log(`FormAutoSave: Initialized for ${i.length} forms`),i}};t(tt,"DEFAULT_CONFIG",{formSelector:"form[data-autosave]",saveInterval:3e4,retentionPeriod:864e5,storagePrefix:"form_draft_",enableVisualFeedback:!0,enableConsoleLogging:!0,excludeFields:['input[type="password"]','input[type="hidden"][name="_token"]','input[type="hidden"][name="_form_id"]','input[name*="password"]','input[name*="confirm"]','input[name*="honeypot"]','input[name="email_confirm"]','input[name="website_url"]','input[name="user_name"]','input[name="company_name"]'],immediateFields:["textarea",'input[type="email"]','input[type="text"]',"select"],maxDraftAge:6048e5,cleanupOnInit:!0});let it=tt;document.addEventListener("DOMContentLoaded",async()=>{try{console.log("🚀 Starting app initialization..."),await Qe(),console.log("✅ App initialized successfully!");const e=et.initializeAll();console.log(`🔒 CSRF Auto-Refresh initialized for ${e.length} forms`);const t=it.initializeAll();console.log(`💾 Form Auto-Save initialized for ${t.length} forms`),setTimeout(()=>{console.log("📊 Debug Info:"),console.log("- Forms found:",document.querySelectorAll("form").length),console.log("- Links found:",document.querySelectorAll('a[href^="/"]').length),console.log("- SPA Router:",window.spaRouter?"Active":"Missing"),console.log("- Enhanced forms:",document.querySelectorAll("form[data-auto-enhanced]").length),console.log("- CSRF protected forms:",document.querySelectorAll('input[name="_token"]').length)},500)}catch(e){console.error("❌ App initialization failed:",e),console.error("Stack trace:",e.stack)}});
|