@utsp/input 0.14.0 → 0.14.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs CHANGED
@@ -1 +1 @@
1
- "use strict";var P=Object.defineProperty;var le=Object.getOwnPropertyDescriptor;var de=Object.getOwnPropertyNames;var ce=Object.prototype.hasOwnProperty;var pe=(d,s,e)=>s in d?P(d,s,{enumerable:!0,configurable:!0,writable:!0,value:e}):d[s]=e;var h=(d,s)=>P(d,"name",{value:s,configurable:!0});var he=(d,s)=>{for(var e in s)P(d,e,{get:s[e],enumerable:!0})},be=(d,s,e,t)=>{if(s&&typeof s=="object"||typeof s=="function")for(let o of de(s))!ce.call(d,o)&&o!==e&&P(d,o,{get:()=>s[o],enumerable:!(t=le(s,o))||t.enumerable});return d};var me=d=>be(P({},"__esModule",{value:!0}),d);var r=(d,s,e)=>(pe(d,typeof s!="symbol"?s+"":s,e),e);var ge={};he(ge,{BaseInputs:()=>v,GamepadInput:()=>M.GamepadInput,GamepadInputs:()=>C,InputCollector:()=>L,InputDeviceType:()=>M.InputDeviceType,InputEventType:()=>J,KeyboardInput:()=>M.KeyboardInput,KeyboardInputs:()=>E,MobileInputs:()=>w,MobileVibration:()=>B,MouseInput:()=>M.MouseInput,MouseInputs:()=>I,TouchInput:()=>M.TouchInput,UnifiedInputRouter:()=>A,Vector2:()=>K.Vector2,Vector3:()=>K.Vector3,VibrationPatterns:()=>g,getMobileVibration:()=>te,isInputs:()=>Q,useGamepadInputs:()=>se,useKeyboardInputs:()=>Z,useMobileInputs:()=>ee,useMouseInputs:()=>_});module.exports=me(ge);var K=require("@utsp/types"),M=require("@utsp/types");var J=(b=>(b.KeyDown="keydown",b.KeyUp="keyup",b.MouseDown="mousedown",b.MouseUp="mouseup",b.MouseMove="mousemove",b.MouseWheel="mousewheel",b.TouchStart="touchstart",b.TouchEnd="touchend",b.TouchMove="touchmove",b.GamepadConnected="gamepadconnected",b.GamepadDisconnected="gamepaddisconnected",b.GamepadButton="gamepadbutton",b.GamepadAxis="gamepadaxis",b))(J||{}),W=class W{constructor(s=window,e={}){r(this,"isActive",!1);r(this,"targetElement");r(this,"config");r(this,"callbacks",{});this.targetElement=s,this.config={enabled:!0,preventDefault:!1,stopPropagation:!1,debug:!1,...e}}isListening(){return this.isActive}destroy(){this.stop(),this.clearCallbacks()}setCallbacks(s){typeof s=="object"&&s!==null&&Object.assign(this.callbacks,s)}clearCallbacks(){this.callbacks={}}getTargetElement(){return this.targetElement}enable(){this.config.enabled=!0,this.isActive||this.start()}disable(){this.config.enabled=!1,this.isActive&&this.stop()}isEnabled(){return this.config.enabled??!0}emit(s,...e){this.callbacks[s]&&this.callbacks[s].forEach(t=>{try{t(...e)}catch(o){this.config.debug&&console.error(`Error in ${s} callback:`,o)}})}log(...s){this.config.debug&&console.warn("[InputSystem]",...s)}};h(W,"BaseInputs");var v=W;function Q(d){return typeof d=="object"&&d!==null&&"start"in d&&"stop"in d&&"reset"in d&&"isListening"in d&&"destroy"in d}h(Q,"isInputs");var U=class U extends v{constructor(e=window,t={}){super(e,t);r(this,"keys",{});r(this,"keyboardCallbacks",{});r(this,"textInputsThisFrame",[]);r(this,"boundHandlers");this.boundHandlers={keyDown:this.handleKeyDown.bind(this),keyUp:this.handleKeyUp.bind(this)}}start(){this.isActive||(this.targetElement.addEventListener("keydown",this.boundHandlers.keyDown),this.targetElement.addEventListener("keyup",this.boundHandlers.keyUp),this.isActive=!0)}stop(){this.isActive&&(this.targetElement.removeEventListener("keydown",this.boundHandlers.keyDown),this.targetElement.removeEventListener("keyup",this.boundHandlers.keyUp),this.isActive=!1)}reset(){this.keys={}}resetDelta(){}poll(){for(let e in this.keys)this.keys[e].justPressed=!1,this.keys[e].justReleased=!1;this.textInputsThisFrame=[]}getTextInputs(){return this.textInputsThisFrame}isKeyPressed(e){return this.keys[e]?.pressed||!1}isKeyJustPressed(e){return this.keys[e]?.justPressed||!1}isKeyJustReleased(e){return this.keys[e]?.justReleased||!1}getKeysPressed(){return Object.keys(this.keys).filter(e=>this.keys[e].pressed)}getKeysJustPressed(){return Object.keys(this.keys).filter(e=>this.keys[e].justPressed)}getKeysJustReleased(){return Object.keys(this.keys).filter(e=>this.keys[e].justReleased)}isAnyKeyPressed(){return Object.values(this.keys).some(e=>e.pressed)}setKeyboardCallbacks(e){this.keyboardCallbacks={...this.keyboardCallbacks,...e}}clearKeyboardCallbacks(){this.keyboardCallbacks={}}setCallbacks(e){this.isKeyboardCallbacks(e)&&this.setKeyboardCallbacks(e)}isKeyboardCallbacks(e){return typeof e=="object"&&e!==null&&("onKeyDown"in e||"onKeyUp"in e)}shouldAllowDefault(e,t){let o=/^F([1-9]|1[0-2])$/.test(e),n=(t.ctrlKey||t.metaKey)&&(e==="KeyT"||e==="KeyW"||e==="KeyR"||e==="KeyN"||e==="Tab");return o||n}handleKeyDown(e){try{let t=e.code,o=this.shouldAllowDefault(t,e);this.config.preventDefault&&!o&&e.preventDefault(),this.config.stopPropagation&&!o&&e.stopPropagation(),this.keys[t]||(this.keys[t]={pressed:!1,justPressed:!1,justReleased:!1}),this.keys[t].pressed||(this.keys[t].justPressed=!0,this.keyboardCallbacks.onKeyDown?.(t,e)),this.keys[t].pressed=!0,this.keys[t].justReleased=!1;let n=e.key;n.length===1&&!e.ctrlKey&&!e.metaKey&&this.textInputsThisFrame.push(n)}catch(t){console.error("Error in keyboard keydown handler:",t)}}handleKeyUp(e){try{let t=e.code,o=this.shouldAllowDefault(t,e);this.config.preventDefault&&!o&&e.preventDefault(),this.config.stopPropagation&&!o&&e.stopPropagation(),this.keys[t]||(this.keys[t]={pressed:!1,justPressed:!1,justReleased:!1}),this.keys[t].pressed&&(this.keys[t].justReleased=!0,this.keyboardCallbacks.onKeyUp?.(t,e)),this.keys[t].pressed=!1,this.keys[t].justPressed=!1}catch(t){console.error("Error in keyboard keyup handler:",t)}}};h(U,"KeyboardInputs");var E=U;function Z(d,s){let e=new E(d);return s&&e.setCallbacks(s),e.start(),e}h(Z,"useKeyboardInputs");var k=require("@utsp/types");var x=class x extends v{constructor(e=window,t={}){super(e,t);r(this,"mouseButtons",{left:{pressed:!1,justPressed:!1,justReleased:!1},middle:{pressed:!1,justPressed:!1,justReleased:!1},right:{pressed:!1,justPressed:!1,justReleased:!1}});r(this,"mousePosition",k.Vector2.zero());r(this,"mouseDelta",k.Vector2.zero());r(this,"wheelDelta",0);r(this,"mouseCallbacks",{});r(this,"boundHandlers");this.boundHandlers={mouseDown:this.handleMouseDown.bind(this),mouseUp:this.handleMouseUp.bind(this),mouseMove:this.handleMouseMove.bind(this),wheel:this.handleWheel.bind(this),mouseEnter:this.handleMouseEnter.bind(this),mouseLeave:this.handleMouseLeave.bind(this),contextMenu:this.handleContextMenu.bind(this)}}start(){this.isActive||(this.targetElement.addEventListener("mousedown",this.boundHandlers.mouseDown),this.targetElement.addEventListener("mouseup",this.boundHandlers.mouseUp),this.targetElement.addEventListener("mousemove",this.boundHandlers.mouseMove),this.targetElement.addEventListener("wheel",this.boundHandlers.wheel),this.targetElement.addEventListener("mouseenter",this.boundHandlers.mouseEnter),this.targetElement.addEventListener("mouseleave",this.boundHandlers.mouseLeave),this.targetElement.addEventListener("contextmenu",this.boundHandlers.contextMenu),this.isActive=!0)}stop(){this.isActive&&(this.targetElement.removeEventListener("mousedown",this.boundHandlers.mouseDown),this.targetElement.removeEventListener("mouseup",this.boundHandlers.mouseUp),this.targetElement.removeEventListener("mousemove",this.boundHandlers.mouseMove),this.targetElement.removeEventListener("wheel",this.boundHandlers.wheel),this.targetElement.removeEventListener("mouseenter",this.boundHandlers.mouseEnter),this.targetElement.removeEventListener("mouseleave",this.boundHandlers.mouseLeave),this.targetElement.removeEventListener("contextmenu",this.boundHandlers.contextMenu),this.isActive=!1)}reset(){this.mouseButtons={left:{pressed:!1,justPressed:!1,justReleased:!1},middle:{pressed:!1,justPressed:!1,justReleased:!1},right:{pressed:!1,justPressed:!1,justReleased:!1}},this.mousePosition=k.Vector2.zero(),this.mouseDelta=k.Vector2.zero(),this.wheelDelta=0}poll(){this.mouseButtons.left.justPressed=!1,this.mouseButtons.left.justReleased=!1,this.mouseButtons.middle.justPressed=!1,this.mouseButtons.middle.justReleased=!1,this.mouseButtons.right.justPressed=!1,this.mouseButtons.right.justReleased=!1,this.resetDelta()}resetDelta(){this.mouseDelta=k.Vector2.zero(),this.wheelDelta=0}isLeftMousePressed(){return this.mouseButtons.left.pressed}isLeftMouseJustPressed(){return this.mouseButtons.left.justPressed}isLeftMouseJustReleased(){return this.mouseButtons.left.justReleased}isRightMousePressed(){return this.mouseButtons.right.pressed}isRightMouseJustPressed(){return this.mouseButtons.right.justPressed}isRightMouseJustReleased(){return this.mouseButtons.right.justReleased}isMiddleMousePressed(){return this.mouseButtons.middle.pressed}isMiddleMouseJustPressed(){return this.mouseButtons.middle.justPressed}isMiddleMouseJustReleased(){return this.mouseButtons.middle.justReleased}getMousePosition(){return this.mousePosition.clone()}getMouseDelta(){return this.mouseDelta.clone()}getWheelDelta(){return this.wheelDelta}setMouseCallbacks(e){this.mouseCallbacks={...this.mouseCallbacks,...e}}clearMouseCallbacks(){this.mouseCallbacks={}}setCallbacks(e){this.isMouseCallbacks(e)&&this.setMouseCallbacks(e)}isMouseCallbacks(e){return typeof e=="object"&&e!==null&&("onMouseDown"in e||"onMouseUp"in e||"onMouseMove"in e||"onMouseWheel"in e||"onMouseEnter"in e||"onMouseLeave"in e)}getButtonByIndex(e){let t=x.BUTTON_NAMES[e];return t?{state:this.mouseButtons[t],name:t}:null}handleMouseDown(e){try{this.config.preventDefault&&e.preventDefault(),this.config.stopPropagation&&e.stopPropagation();let t=this.getButtonByIndex(e.button);t&&(t.state.pressed||(t.state.justPressed=!0),t.state.pressed=!0,t.state.justReleased=!1,this.mouseCallbacks.onMouseDown?.(t.name,this.mousePosition,e))}catch(t){console.error("Error in mouse down handler:",t)}}handleMouseUp(e){try{this.config.preventDefault&&e.preventDefault(),this.config.stopPropagation&&e.stopPropagation();let t=this.getButtonByIndex(e.button);t&&(t.state.pressed&&(t.state.justReleased=!0),t.state.pressed=!1,t.state.justPressed=!1,this.mouseCallbacks.onMouseUp?.(t.name,this.mousePosition,e))}catch(t){console.error("Error in mouse up handler:",t)}}handleMouseMove(e){try{this.config.preventDefault&&e.preventDefault(),this.config.stopPropagation&&e.stopPropagation();let t=new k.Vector2(e.clientX,e.clientY);this.mouseDelta=t.subtract(this.mousePosition),this.mousePosition=t,this.mouseCallbacks.onMouseMove?.(this.mousePosition,this.mouseDelta,e)}catch(t){console.error("Error in mouse move handler:",t)}}handleWheel(e){try{this.config.preventDefault&&e.preventDefault(),this.config.stopPropagation&&e.stopPropagation(),this.wheelDelta=e.deltaY,this.mouseCallbacks.onMouseWheel?.(this.wheelDelta,e)}catch(t){console.error("Error in mouse wheel handler:",t)}}handleMouseEnter(e){try{this.mouseCallbacks.onMouseEnter?.(e)}catch(t){console.error("Error in mouse enter handler:",t)}}handleMouseLeave(e){try{this.mouseCallbacks.onMouseLeave?.(e)}catch(t){console.error("Error in mouse leave handler:",t)}}handleContextMenu(e){try{e.preventDefault(),this.config.stopPropagation&&e.stopPropagation()}catch(t){console.error("Error in context menu handler:",t)}}};h(x,"MouseInputs"),r(x,"BUTTON_NAMES",["left","middle","right"]);var I=x;function _(d,s){let e=new I(d);return s&&e.setCallbacks(s),e.start(),e}h(_,"useMouseInputs");var X=require("@utsp/types");var Y=class Y extends v{constructor(e=window,t={}){super(e,t);r(this,"touches",new Map);r(this,"nativeToInternal",new Map);r(this,"mobileCallbacks",{});r(this,"mobileConfig");r(this,"maxTouches",10);r(this,"lastLogTime",0);r(this,"boundHandlers");this.mobileConfig={targetElement:e,preventDefault:t.preventDefault??!0,passive:t.passive??!1,maxTouches:t.maxTouches??10,enabled:t.enabled??!0,debug:t.debug??!1,stopPropagation:t.stopPropagation??!1},this.maxTouches=this.mobileConfig.maxTouches,this.mobileConfig.preventDefault&&this.mobileConfig.passive&&(console.warn("[MobileInputs] passive=true prevents preventDefault() from working! Setting passive=false."),this.mobileConfig.passive=!1),this.boundHandlers={touchStart:this.handleTouchStart.bind(this),touchEnd:this.handleTouchEnd.bind(this),touchMove:this.handleTouchMove.bind(this),touchCancel:this.handleTouchCancel.bind(this),orientationChange:this.handleOrientationChange.bind(this)}}start(){if(this.isActive)return;let e={passive:!this.mobileConfig.preventDefault&&this.mobileConfig.passive};this.targetElement.addEventListener("touchstart",this.boundHandlers.touchStart,e),this.targetElement.addEventListener("touchend",this.boundHandlers.touchEnd,e),this.targetElement.addEventListener("touchmove",this.boundHandlers.touchMove,e),this.targetElement.addEventListener("touchcancel",this.boundHandlers.touchCancel,e),window.addEventListener("orientationchange",this.boundHandlers.orientationChange),this.isActive=!0}stop(){this.isActive&&(this.targetElement.removeEventListener("touchstart",this.boundHandlers.touchStart),this.targetElement.removeEventListener("touchend",this.boundHandlers.touchEnd),this.targetElement.removeEventListener("touchmove",this.boundHandlers.touchMove),this.targetElement.removeEventListener("touchcancel",this.boundHandlers.touchCancel),window.removeEventListener("orientationchange",this.boundHandlers.orientationChange),this.isActive=!1)}reset(){this.touches.clear(),this.nativeToInternal.clear()}resetDelta(){}poll(){for(let e of this.touches.values())e.justTouched=!1,e.justReleased=!1}isTouchActive(e){return e<0||e>=this.maxTouches?!1:this.touches.has(e)}getTouchPosition(e){if(e<0||e>=this.maxTouches)return null;let t=this.touches.get(e);return t?t.position.clone():null}getTouchStartPosition(e){if(e<0||e>=this.maxTouches)return null;let t=this.touches.get(e);return t?t.startPosition.clone():null}getTouchDelta(e){if(e<0||e>=this.maxTouches)return null;let t=this.touches.get(e);return t?t.position.subtract(t.startPosition):null}getTouchCount(){return this.touches.size}isTouchJustStarted(e){if(e<0||e>=this.maxTouches)return!1;let t=this.touches.get(e);return t?t.justTouched:!1}isTouchJustReleased(e){if(e<0||e>=this.maxTouches)return!1;let t=this.touches.get(e);return t?t.justReleased:!1}isAnyTouchJustStarted(){for(let e of this.touches.values())if(e.justTouched)return!0;return!1}getAllTouches(){return Array.from(this.touches.values())}setMobileCallbacks(e){this.mobileCallbacks={...this.mobileCallbacks,...e}}clearMobileCallbacks(){this.mobileCallbacks={}}setCallbacks(e){this.isMobileCallbacks(e)&&this.setMobileCallbacks(e)}isMobileCallbacks(e){return typeof e=="object"&&e!==null&&("onTouchStart"in e||"onTouchEnd"in e||"onTouchMove"in e||"onTouchCancel"in e||"onOrientationChange"in e)}handleTouchStart(e){try{this.mobileConfig.preventDefault&&e.preventDefault();let t=Array.from(e.changedTouches),o=[];for(let n of t){if(this.touches.size>=this.maxTouches)break;let i=-1;for(let c=0;c<this.maxTouches;c++)if(!this.touches.has(c)){i=c;break}if(i===-1)continue;let a=new X.Vector2(n.clientX,n.clientY),p={id:i,nativeId:n.identifier,position:a.clone(),startPosition:a.clone(),active:!0,justTouched:!0,justReleased:!1};this.touches.set(i,p),this.nativeToInternal.set(n.identifier,i),o.push(p),console.warn(`\u{1F446} Touch START - ID: ${i}`)}this.mobileCallbacks.onTouchStart?.(o,e)}catch(t){console.error("Error in touch start handler:",t)}}handleTouchEnd(e){try{this.mobileConfig.preventDefault&&e.preventDefault();let t=Array.from(e.changedTouches),o=[];for(let n of t){let i=this.nativeToInternal.get(n.identifier);if(i!==void 0){let a=this.touches.get(i);a&&(a.justReleased=!0,a.justTouched=!1,o.push({...a}))}}for(let n of t){let i=this.nativeToInternal.get(n.identifier);i!==void 0&&(this.touches.delete(i),this.nativeToInternal.delete(n.identifier),console.warn(`\u{1F447} Touch END - ID: ${i}`))}this.mobileCallbacks.onTouchEnd?.(o,e)}catch(t){console.error("Error in touch end handler:",t)}}handleTouchMove(e){try{let t=Array.from(e.changedTouches);this.mobileConfig.debug&&(!this.lastLogTime||Date.now()-this.lastLogTime>200)&&(console.warn(`\u{1F504} TouchMove event - ${t.length} touches changed`),this.lastLogTime=Date.now());for(let o of t){let n=this.nativeToInternal.get(o.identifier);if(n!==void 0){let i=this.touches.get(n);if(i){let a=i.position.clone();i.position=new X.Vector2(o.clientX,o.clientY),this.mobileConfig.debug&&(!this.lastLogTime||Date.now()-this.lastLogTime>200)&&console.warn(`\u{1F504} Updated touch ${i.id} (native ${o.identifier}) - ${a.x.toFixed(1)},${a.y.toFixed(1)} \u2192 ${o.clientX.toFixed(1)},${o.clientY.toFixed(1)}`)}}else this.mobileConfig.debug&&console.warn(`\u26A0\uFE0F Touch move for unknown native ID ${o.identifier}`)}this.mobileCallbacks.onTouchMove?.(this.getAllTouches(),e)}catch(t){console.error("Error in touch move handler:",t)}}handleTouchCancel(e){try{this.mobileConfig.preventDefault&&e.preventDefault();let t=[],o=Array.from(e.changedTouches);for(let n of o){let i=this.nativeToInternal.get(n.identifier);if(i!==void 0){let a=this.touches.get(i);a&&(a.justReleased=!0,a.justTouched=!1,t.push({...a}))}}for(let n of o){let i=this.nativeToInternal.get(n.identifier);i!==void 0&&(this.touches.delete(i),this.nativeToInternal.delete(n.identifier),this.mobileConfig.debug&&console.warn(`\u274C Touch CANCEL - ID: ${i}, nativeId: ${n.identifier}`))}this.mobileCallbacks.onTouchCancel?.(t,e)}catch(t){console.error("Error in touch cancel handler:",t)}}handleOrientationChange(e){try{let t=(window.screen.orientation&&window.screen.orientation.angle)??window.orientation??0;this.mobileCallbacks.onOrientationChange?.(t)}catch(t){console.error("Error in orientation change handler:",t)}}};h(Y,"MobileInputs");var w=Y;function ee(d,s,e){console.warn("[MobileInputs] useMobileInputs() is deprecated and causes memory leaks. Use useMemo + useEffect instead.");let t=new w(d,e);return s&&t.setCallbacks(s),t.start(),t}h(ee,"useMobileInputs");var g={tap:10,mediumTap:25,heavyTap:50,success:[30,50,30],error:[50,30,50,30,50],warning:[100],selection:5,impactLight:15,impactMedium:30,impactHeavy:50,notification:[100,100,100,100,100],sos:[100,30,100,30,100,30,200,30,200,30,200,30,100,30,100,30,100]},N=class N{constructor(s={}){r(this,"config");r(this,"supported",!1);r(this,"userActivated",!1);this.config={enabled:s.enabled??!0,debug:s.debug??!1,intensity:Math.max(0,Math.min(1,s.intensity??1))},this.supported=typeof navigator<"u"&&"vibrate"in navigator,this.config.debug&&console.log(`[MobileVibration] Vibration API supported: ${this.supported}`)}isSupported(){return this.supported}isEnabled(){return this.config.enabled&&this.supported}setEnabled(s){this.config.enabled=s,this.config.debug&&console.log(`[MobileVibration] Enabled: ${s}`)}setIntensity(s){this.config.intensity=Math.max(0,Math.min(1,s)),this.config.debug&&console.log(`[MobileVibration] Intensity set to: ${this.config.intensity}`)}getIntensity(){return this.config.intensity}vibrate(s){if(!this.isEnabled())return!1;try{let e=this.scalePattern(s),t=typeof e=="number"?e:[...e],o=navigator.vibrate(t);return this.config.debug&&console.log(`[MobileVibration] Vibrate: ${JSON.stringify(e)} -> ${o}`),o&&(this.userActivated=!0),o}catch(e){return this.config.debug&&console.error("[MobileVibration] Vibration failed:",e),!1}}cancel(){this.supported&&(navigator.vibrate(0),this.config.debug&&console.log("[MobileVibration] Vibration cancelled"))}hasUserActivation(){return this.userActivated}tap(){return this.vibrate(g.tap)}mediumTap(){return this.vibrate(g.mediumTap)}heavyTap(){return this.vibrate(g.heavyTap)}success(){return this.vibrate(g.success)}error(){return this.vibrate(g.error)}warning(){return this.vibrate(g.warning)}selection(){return this.vibrate(g.selection)}impactLight(){return this.vibrate(g.impactLight)}impactMedium(){return this.vibrate(g.impactMedium)}impactHeavy(){return this.vibrate(g.impactHeavy)}notification(){return this.vibrate(g.notification)}scalePattern(s){return this.config.intensity===1?s:typeof s=="number"?Math.round(s*this.config.intensity):s.map((e,t)=>t%2===0?Math.round(e*this.config.intensity):e)}};h(N,"MobileVibration");var B=N,z=null;function te(){return z||(z=new B),z}h(te,"getMobileVibration");var fe=.01,O=class O extends v{constructor(e={}){super(window,e);r(this,"gamepads",new Map);r(this,"previousGamepads",new Map);r(this,"gamepadCallbacks",{});r(this,"gamepadConfig");r(this,"pollingIntervalId",null);r(this,"rafId",null);r(this,"boundHandlers");r(this,"vibrationPresets",{tap:{duration:50,strongMagnitude:.3,weakMagnitude:.5},impact:{duration:100,strongMagnitude:.7,weakMagnitude:.3},heavy:{duration:200,strongMagnitude:1,weakMagnitude:.2},success:{duration:150,strongMagnitude:.4,weakMagnitude:.6},error:{duration:300,strongMagnitude:.8,weakMagnitude:.4},explosion:{duration:400,strongMagnitude:1,weakMagnitude:.8},engine:{duration:1e3,strongMagnitude:.5,weakMagnitude:.2},heartbeat:{duration:100,strongMagnitude:.6,weakMagnitude:.1}});this.gamepadConfig={targetElement:window,maxGamepads:e.maxGamepads??4,axisDeadzone:e.axisDeadzone??.1,pollingInterval:e.pollingInterval??16,autoPolling:e.autoPolling??!0,enabled:e.enabled??!0,debug:e.debug??!1,preventDefault:e.preventDefault??!1,stopPropagation:e.stopPropagation??!1},this.boundHandlers={connected:this.handleGamepadConnected.bind(this),disconnected:this.handleGamepadDisconnected.bind(this)}}start(){this.isActive||(window.addEventListener("gamepadconnected",this.boundHandlers.connected),window.addEventListener("gamepaddisconnected",this.boundHandlers.disconnected),this.gamepadConfig.autoPolling&&this.startPolling(),this.isActive=!0,this.log("GamepadInputs started"))}stop(){this.isActive&&(window.removeEventListener("gamepadconnected",this.boundHandlers.connected),window.removeEventListener("gamepaddisconnected",this.boundHandlers.disconnected),this.stopPolling(),this.isActive=!1,this.log("GamepadInputs stopped"))}reset(){this.gamepads.clear(),this.previousGamepads.clear()}resetDelta(){this.previousGamepads.clear(),this.gamepads.forEach((e,t)=>{this.previousGamepads.set(t,this.cloneGamepadState(e))})}startPolling(){if(this.pollingIntervalId!==null||this.rafId!==null)return;let e=h(()=>{this.poll(),this.rafId=requestAnimationFrame(e)},"poll");this.rafId=requestAnimationFrame(e),this.log("Polling started")}stopPolling(){this.rafId!==null&&(cancelAnimationFrame(this.rafId),this.rafId=null),this.pollingIntervalId!==null&&(clearInterval(this.pollingIntervalId),this.pollingIntervalId=null),this.log("Polling stopped")}poll(){let e=navigator.getGamepads?navigator.getGamepads():[];for(let t=0;t<e.length&&t<this.gamepadConfig.maxGamepads;t++){let o=e[t];o&&this.updateGamepadState(o)}}getConnectedGamepadCount(){return this.gamepads.size}isGamepadConnected(e){return this.gamepads.has(e)&&this.gamepads.get(e).connected}getGamepadState(e){return this.gamepads.get(e)||null}getAllGamepads(){return Array.from(this.gamepads.values()).filter(e=>e.connected)}isButtonPressed(e,t){if(!Number.isInteger(e)||e<0)throw new Error(`Invalid gamepadIndex: ${e}. Must be a non-negative integer.`);if(!Number.isInteger(t)||t<0)throw new Error(`Invalid buttonIndex: ${t}. Must be a non-negative integer.`);let o=this.gamepads.get(e);return!o||!o.connected||t>=o.buttons.length?!1:o.buttons[t].pressed}isButtonJustPressed(e,t){if(!Number.isInteger(e)||e<0)throw new Error(`Invalid gamepadIndex: ${e}. Must be a non-negative integer.`);if(!Number.isInteger(t)||t<0)throw new Error(`Invalid buttonIndex: ${t}. Must be a non-negative integer.`);let o=this.gamepads.get(e);return!o||!o.connected||t>=o.buttons.length?!1:o.buttons[t].justPressed}isButtonJustReleased(e,t){if(!Number.isInteger(e)||e<0)throw new Error(`Invalid gamepadIndex: ${e}. Must be a non-negative integer.`);if(!Number.isInteger(t)||t<0)throw new Error(`Invalid buttonIndex: ${t}. Must be a non-negative integer.`);let o=this.gamepads.get(e);return!o||!o.connected||t>=o.buttons.length?!1:o.buttons[t].justReleased}getButtonValue(e,t){if(!Number.isInteger(e)||e<0)throw new Error(`Invalid gamepadIndex: ${e}. Must be a non-negative integer.`);if(!Number.isInteger(t)||t<0)throw new Error(`Invalid buttonIndex: ${t}. Must be a non-negative integer.`);let o=this.gamepads.get(e);return!o||!o.connected||t>=o.buttons.length?0:o.buttons[t].value}getAxis(e,t){if(!Number.isInteger(e)||e<0)throw new Error(`Invalid gamepadIndex: ${e}. Must be a non-negative integer.`);if(!Number.isInteger(t)||t<0)throw new Error(`Invalid axisIndex: ${t}. Must be a non-negative integer.`);let o=this.gamepads.get(e);if(!o||!o.connected||t>=o.axes.length)return 0;let n=o.axes[t];return this.applyDeadzone(n)}getAxisRaw(e,t){if(!Number.isInteger(e)||e<0)throw new Error(`Invalid gamepadIndex: ${e}. Must be a non-negative integer.`);if(!Number.isInteger(t)||t<0)throw new Error(`Invalid axisIndex: ${t}. Must be a non-negative integer.`);let o=this.gamepads.get(e);return!o||!o.connected||t>=o.axes.length?0:o.axes[t]}getLeftStick(e){return{x:this.getAxis(e,0),y:this.getAxis(e,1)}}getRightStick(e){return{x:this.getAxis(e,2),y:this.getAxis(e,3)}}supportsVibration(e){let t=this.getNativeGamepad(e);if(!t)return!1;let o=t.vibrationActuator;if(o&&typeof o.playEffect=="function")return!0;let n=t.hapticActuators;return!!(n&&n.length>0)}async vibrate(e,t){let o=this.getNativeGamepad(e);if(!o)return this.log(`Vibrate failed: gamepad ${e} not found`),!1;let{duration:n,strongMagnitude:i=1,weakMagnitude:a=.5,startDelay:p=0}=t;try{let c=o.vibrationActuator;if(c&&typeof c.playEffect=="function"){let f=await c.playEffect("dual-rumble",{startDelay:p,duration:n,strongMagnitude:Math.min(1,Math.max(0,i)),weakMagnitude:Math.min(1,Math.max(0,a))});return this.log(`Vibration effect result: ${f}`),f==="complete"}let m=o.hapticActuators;if(m&&m.length>0){let f=Math.max(i,a);return await m[0].pulse(f,n),!0}return this.log(`Vibrate failed: gamepad ${e} does not support vibration`),!1}catch(c){return this.log("Vibrate error:",c),!1}}async stopVibration(e){let t=this.getNativeGamepad(e);if(!t)return!1;try{let o=t.vibrationActuator;return o&&typeof o.reset=="function"?(await o.reset(),!0):o&&typeof o.playEffect=="function"?(await o.playEffect("dual-rumble",{duration:0,strongMagnitude:0,weakMagnitude:0}),!0):!1}catch(o){return this.log("Stop vibration error:",o),!1}}async stopAllVibrations(){let e=[];for(let[t]of this.gamepads)e.push(this.stopVibration(t));await Promise.all(e)}async vibrateAll(e){let t=[];for(let[o]of this.gamepads)t.push(this.vibrate(o,e));await Promise.all(t)}async vibratePreset(e,t){let o=this.vibrationPresets[t];return o?this.vibrate(e,o):(this.log(`Unknown vibration preset: ${t}`),!1)}getNativeGamepad(e){return(navigator.getGamepads?navigator.getGamepads():[])[e]||null}setGamepadCallbacks(e){this.gamepadCallbacks={...this.gamepadCallbacks,...e}}clearGamepadCallbacks(){this.gamepadCallbacks={}}setCallbacks(e){this.isGamepadCallbacks(e)&&this.setGamepadCallbacks(e)}isGamepadCallbacks(e){return typeof e=="object"&&e!==null&&("onGamepadConnected"in e||"onGamepadDisconnected"in e||"onButtonDown"in e||"onButtonUp"in e||"onAxisMove"in e)}updateGamepadState(e){let t=this.gamepads.get(e.index),o=Array.from(e.buttons).map((a,p)=>{let c=t?.buttons[p],m=a.pressed,f=c?.pressed??!1;return{pressed:m,justPressed:m&&!f,justReleased:!m&&f,value:a.value,touched:a.touched??!1}}),n=Array.from(e.axes),i={id:e.id,index:e.index,connected:e.connected,buttons:o,axes:n,timestamp:e.timestamp,mapping:e.mapping};this.gamepads.set(e.index,i),this.triggerCallbacks(i,t)}triggerCallbacks(e,t){try{e.buttons.forEach((o,n)=>{o.justPressed&&this.gamepadCallbacks.onButtonDown?.(e.index,n,o.value),o.justReleased&&this.gamepadCallbacks.onButtonUp?.(e.index,n)}),e.axes.forEach((o,n)=>{let i=t?.axes[n]??0,a=this.applyDeadzone(o),p=this.applyDeadzone(i);Math.abs(a-p)>fe&&this.gamepadCallbacks.onAxisMove?.(e.index,n,a)})}catch(o){this.log("Error in gamepad callbacks:",o)}}handleGamepadConnected(e){try{this.log(`Gamepad connected: ${e.gamepad.id} at index ${e.gamepad.index}`);let t={id:e.gamepad.id,index:e.gamepad.index,connected:!0,buttons:Array.from(e.gamepad.buttons).map(o=>({pressed:o.pressed,justPressed:!1,justReleased:!1,value:o.value,touched:o.touched??!1})),axes:Array.from(e.gamepad.axes),timestamp:e.gamepad.timestamp,mapping:e.gamepad.mapping};this.gamepads.set(e.gamepad.index,t),this.gamepadCallbacks.onGamepadConnected?.(t)}catch(t){this.log("Error handling gamepad connected:",t)}}handleGamepadDisconnected(e){try{this.log(`Gamepad disconnected at index ${e.gamepad.index}`),this.gamepads.delete(e.gamepad.index),this.previousGamepads.delete(e.gamepad.index),this.gamepadCallbacks.onGamepadDisconnected?.(e.gamepad.index)}catch(t){this.log("Error handling gamepad disconnected:",t)}}applyDeadzone(e){let t=this.gamepadConfig.axisDeadzone;return Math.abs(e)<t?0:(e>0?1:-1)*((Math.abs(e)-t)/(1-t))}cloneGamepadState(e){return{...e,buttons:e.buttons.map(t=>({...t})),axes:[...e.axes]}}};h(O,"GamepadInputs");var C=O;function se(d,s){let e=new C(s);return d&&e.setGamepadCallbacks(d),e.start(),e}h(se,"useGamepadInputs");var u=require("@utsp/types");var F=class F{constructor(s={}){r(this,"keyboard",null);r(this,"mouse",null);r(this,"gamepad",null);r(this,"mobile",null);r(this,"config");this.config={enableKeyboardMouse:s.enableKeyboardMouse??!0,enableGamepad:s.enableGamepad??!0,enableMobile:s.enableMobile??!1,targetElement:s.targetElement??window,mobileTargetElement:s.mobileTargetElement??s.targetElement??window,debug:s.debug??!1,keyboardConfig:{preventDefault:!1,stopPropagation:!1,...s.keyboardConfig},mouseConfig:{preventDefault:!1,stopPropagation:!1,...s.mouseConfig},mobileConfig:{preventDefault:!0,passive:!1,maxTouches:10,...s.mobileConfig}},this.initialize()}initialize(){this.config.enableKeyboardMouse&&(this.keyboard=new E(this.config.targetElement,{preventDefault:this.config.keyboardConfig?.preventDefault??!1,stopPropagation:this.config.keyboardConfig?.stopPropagation??!1,debug:this.config.debug}),this.keyboard.start(),this.mouse=new I(this.config.targetElement,{preventDefault:this.config.mouseConfig?.preventDefault??!1,stopPropagation:this.config.mouseConfig?.stopPropagation??!1,debug:this.config.debug}),this.mouse.start(),this.log("Keyboard/Mouse initialized")),this.config.enableGamepad&&(this.gamepad=new C({debug:this.config.debug}),this.gamepad.start(),this.log("Gamepad initialized")),this.config.enableMobile&&(this.config.mobileTargetElement?(this.mobile=new w(this.config.mobileTargetElement,this.config.mobileConfig),this.mobile.start(),this.log("Mobile/Touch initialized")):this.warn("Mobile input enabled but no canvas provided - mobile input will be disabled until setMobileTarget() is called"))}getButton(s,e){if(!(0,u.isButton)({device:s,input:e}))return this.warn(`Input ${e} on device ${s} is not a button`),!1;switch(s){case u.InputDeviceType.Keyboard:return this.getKeyboardButton(e);case u.InputDeviceType.Mouse:return this.getMouseButton(e);case u.InputDeviceType.Gamepad:return this.getGamepadButton(e);case u.InputDeviceType.Touch:return this.getTouchButton(e);default:return this.warn(`Unknown device type: ${s}`),!1}}getButtonJustPressed(s,e){if(!(0,u.isButton)({device:s,input:e}))return this.warn(`Input ${e} on device ${s} is not a button`),!1;switch(s){case u.InputDeviceType.Keyboard:return this.getKeyboardButtonJustPressed(e);case u.InputDeviceType.Mouse:return this.getMouseButtonJustPressed(e);case u.InputDeviceType.Gamepad:return this.getGamepadButtonJustPressed(e);case u.InputDeviceType.Touch:return this.getTouchButtonJustPressed(e);default:return this.warn(`Unknown device type: ${s}`),!1}}getButtonJustReleased(s,e){if(!(0,u.isButton)({device:s,input:e}))return this.warn(`Input ${e} on device ${s} is not a button`),!1;switch(s){case u.InputDeviceType.Keyboard:return this.getKeyboardButtonJustReleased(e);case u.InputDeviceType.Mouse:return this.getMouseButtonJustReleased(e);case u.InputDeviceType.Gamepad:return this.getGamepadButtonJustReleased(e);case u.InputDeviceType.Touch:return this.getTouchButtonJustReleased(e);default:return this.warn(`Unknown device type: ${s}`),!1}}getAxis(s,e){if(!(0,u.isAxis)({device:s,input:e}))return this.warn(`Input ${e} on device ${s} is not an axis`),0;switch(s){case u.InputDeviceType.Keyboard:return this.warn("Keyboard does not have axis inputs"),0;case u.InputDeviceType.Mouse:return this.getMouseAxis(e);case u.InputDeviceType.Gamepad:return this.getGamepadAxis(e);case u.InputDeviceType.Touch:return this.getTouchAxis(e);default:return this.warn(`Unknown device type: ${s}`),0}}isLeftMousePressed(){return this.mouse?this.mouse.isLeftMousePressed():!1}getKeyboardButton(s){if(!this.keyboard)return!1;let e=u.KeyboardInput[s];return this.keyboard.isKeyPressed(e)}getKeyboardButtonJustPressed(s){if(!this.keyboard)return!1;let e=u.KeyboardInput[s];return this.keyboard.isKeyJustPressed(e)}getKeyboardButtonJustReleased(s){if(!this.keyboard)return!1;let e=u.KeyboardInput[s];return this.keyboard.isKeyJustReleased(e)}getMouseButton(s){if(!this.mouse)return!1;switch(s){case u.MouseInput.LeftButton:return this.mouse.isLeftMousePressed();case u.MouseInput.RightButton:return this.mouse.isRightMousePressed();case u.MouseInput.MiddleButton:return this.mouse.isMiddleMousePressed();default:return!1}}getMouseButtonJustPressed(s){if(!this.mouse)return!1;switch(s){case u.MouseInput.LeftButton:return this.mouse.isLeftMouseJustPressed();case u.MouseInput.RightButton:return this.mouse.isRightMouseJustPressed();case u.MouseInput.MiddleButton:return this.mouse.isMiddleMouseJustPressed();default:return!1}}getMouseButtonJustReleased(s){if(!this.mouse)return!1;switch(s){case u.MouseInput.LeftButton:return this.mouse.isLeftMouseJustReleased();case u.MouseInput.RightButton:return this.mouse.isRightMouseJustReleased();case u.MouseInput.MiddleButton:return this.mouse.isMiddleMouseJustReleased();default:return!1}}getGamepadButton(s){return!this.gamepad||s>=100?!1:this.gamepad.isButtonPressed(0,s)}getGamepadButtonJustPressed(s){return!this.gamepad||s>=100?!1:this.gamepad.isButtonJustPressed(0,s)}getGamepadButtonJustReleased(s){return!this.gamepad||s>=100?!1:this.gamepad.isButtonJustReleased(0,s)}getTouchButton(s){return this.mobile?s>=100?!1:this.mobile.isTouchActive?.(s)??!1:(console.warn("\u{1F6AB} MobileInputs not initialized!"),!1)}getTouchButtonJustPressed(s){return!this.mobile||s>=100?!1:this.mobile.isTouchJustStarted?.(s)??!1}getTouchButtonJustReleased(s){return!this.mobile||s>=100?!1:this.mobile.isTouchJustReleased?.(s)??!1}getMouseAxis(s){if(!this.mouse)return 0;switch(s){case u.MouseInput.PositionX:return this.mouse.getMousePosition().x;case u.MouseInput.PositionY:return this.mouse.getMousePosition().y;case u.MouseInput.DeltaX:return this.mouse.getMouseDelta().x;case u.MouseInput.DeltaY:return this.mouse.getMouseDelta().y;case u.MouseInput.WheelDeltaY:return this.mouse.getWheelDelta();default:return 0}}getGamepadAxis(s){if(!this.gamepad||s<100)return 0;let e=s-100;return this.gamepad.getAxis(0,e)}getTouchAxis(s){if(!this.mobile)return 0;if(s>=100&&s<200){let e=Math.floor((s-100)/2),t=(s-100)%2===0,o=this.mobile.getTouchPosition?.(e);return this.config.debug&&o&&console.warn(`\u{1F3AF} getTouchAxis(${s}) - touchIndex: ${e}, ${t?"X":"Y"}: ${t?o.x:o.y}`),o?t?o.x:o.y:0}return 0}getMousePosition(){if(!this.mouse)return null;let s=this.mouse.getMousePosition();return{x:s.x,y:s.y}}setMobileTarget(s){if(!s){this.warn("setMobileTarget() called with null/undefined canvas - mobile input will remain disabled");return}if(this.config.mobileTargetElement=s,!this.config.enableMobile){this.warn("setMobileTarget() called but mobile input is disabled in config");return}this.mobile&&this.mobile.stop(),this.mobile=new w(s,this.config.mobileConfig),this.mobile.start()}getTextInputs(){return this.keyboard?this.keyboard.getTextInputs():[]}start(){this.keyboard?.start(),this.mouse?.start(),this.log("Input router started")}stop(){this.keyboard?.stop(),this.mouse?.stop(),this.log("Input router stopped")}reset(){this.keyboard?.reset(),this.mouse?.reset(),this.log("Input router reset")}poll(){this.keyboard?.poll(),this.mouse?.poll(),this.gamepad?.poll(),this.mobile?.poll()}isListening(){return this.keyboard!==null&&this.config.enableKeyboardMouse||this.gamepad!==null&&this.config.enableGamepad||this.mobile!==null&&this.config.enableMobile}getGamepad(){return this.gamepad}getKeyboard(){return this.keyboard}getMouse(){return this.mouse}getMobile(){return this.mobile}destroy(){this.keyboard?.destroy(),this.mouse?.destroy(),this.keyboard=null,this.mouse=null,this.gamepad=null,this.mobile=null,this.log("Input router destroyed")}log(s){this.config.debug&&console.warn(`[InputRouter] ${s}`)}warn(s){console.warn(`[InputRouter] ${s}`)}};h(F,"UnifiedInputRouter");var A=F;var l=require("@utsp/types");var oe=100,ne=2,D=class D{static calculateRenderMetrics(s,e){let t=s.getBoundingClientRect(),o=s.width/s.height,n=t.width/t.height,i,a,p,c;o>n?(i=t.width,a=t.width/o,p=0,c=(t.height-a)/2):(i=t.height*o,a=t.height,p=(t.width-i)/2,c=0);let m=e?.offsetX||0,f=e?.offsetY||0;return p+=m,c+=f,i-=m*2,a-=f*2,{renderWidth:i,renderHeight:a,offsetX:p,offsetY:c,rect:t}}static collectAxisSources(s,e){let t=new Map;for(let o of s)for(let n of o.sources){if(t.has(n.sourceId))continue;let i=0,a=!1;if(n.type===l.InputDeviceType.Keyboard&&n.negativeKey!==void 0&&n.positiveKey!==void 0){let p=e.getButton(l.InputDeviceType.Keyboard,n.negativeKey);e.getButton(l.InputDeviceType.Keyboard,n.positiveKey)&&(i+=1),p&&(i-=1),a=!0}else if(n.type===l.InputDeviceType.Mouse&&n.mouseAxis!==void 0)i=e.getAxis(l.InputDeviceType.Mouse,n.mouseAxis),a=!0;else if(n.type===l.InputDeviceType.Gamepad&&n.axis!==void 0)i=e.getAxis(l.InputDeviceType.Gamepad,n.axis),a=!0;else if(n.type===l.InputDeviceType.Touch&&n.touchId!==void 0&&n.touchAxis!==void 0){let p=100+n.touchId*2,c=n.touchAxis==="x"?p:p+1;i=e.getAxis(l.InputDeviceType.Touch,c),a=!0}a&&t.set(n.sourceId,i)}return t}static collectButtonSources(s,e){let t=new Map;for(let o of s)for(let n of o.sources){if(t.has(n.sourceId))continue;let i=!1,a=!1;n.type===l.InputDeviceType.Keyboard&&n.key!==void 0?(i=e.getButton(l.InputDeviceType.Keyboard,n.key),a=!0):n.type===l.InputDeviceType.Mouse&&n.mouseButton!==void 0?(i=e.getButton(l.InputDeviceType.Mouse,n.mouseButton),a=!0):n.type===l.InputDeviceType.Gamepad&&n.button!==void 0?(i=e.getButton(l.InputDeviceType.Gamepad,n.button),a=!0):n.type===l.InputDeviceType.Touch&&n.touchButton!==void 0&&(i=e.getButton(l.InputDeviceType.Touch,n.touchButton),a=!0),a&&t.set(n.sourceId,i)}return t}static collectButtonSourcesWithTransitions(s,e){let t=new Map;for(let o of s)for(let n of o.sources){if(t.has(n.sourceId))continue;let i=!1,a=!1,p=!1,c=!1;n.type===l.InputDeviceType.Keyboard&&n.key!==void 0?(i=e.getButton(l.InputDeviceType.Keyboard,n.key),a=e.getButtonJustPressed?.(l.InputDeviceType.Keyboard,n.key)??!1,p=e.getButtonJustReleased?.(l.InputDeviceType.Keyboard,n.key)??!1,c=!0):n.type===l.InputDeviceType.Mouse&&n.mouseButton!==void 0?(i=e.getButton(l.InputDeviceType.Mouse,n.mouseButton),a=e.getButtonJustPressed?.(l.InputDeviceType.Mouse,n.mouseButton)??!1,p=e.getButtonJustReleased?.(l.InputDeviceType.Mouse,n.mouseButton)??!1,c=!0):n.type===l.InputDeviceType.Gamepad&&n.button!==void 0?(i=e.getButton(l.InputDeviceType.Gamepad,n.button),a=e.getButtonJustPressed?.(l.InputDeviceType.Gamepad,n.button)??!1,p=e.getButtonJustReleased?.(l.InputDeviceType.Gamepad,n.button)??!1,c=!0):n.type===l.InputDeviceType.Touch&&n.touchButton!==void 0&&(i=e.getButton(l.InputDeviceType.Touch,n.touchButton),a=e.getButtonJustPressed?.(l.InputDeviceType.Touch,n.touchButton)??!1,p=e.getButtonJustReleased?.(l.InputDeviceType.Touch,n.touchButton)??!1,c=!0),c&&t.set(n.sourceId,{pressed:i,justPressed:a,justReleased:p})}return t}static collectMousePosition(s,e,t,o,n){let i=s.getAxis(l.InputDeviceType.Mouse,l.MouseInput.PositionX),a=s.getAxis(l.InputDeviceType.Mouse,l.MouseInput.PositionY),p=s.isLeftMousePressed?.()??!1,{renderWidth:c,renderHeight:m,offsetX:f,offsetY:G,rect:b}=D.calculateRenderMetrics(e,n),T=i-b.left-f,y=a-b.top-G,R=c/t,q=m/o,S=Math.floor(T/R),V=Math.floor(y/q),H=T>=0&&T<c&&y>=0&&y<m;return{x:Math.max(0,Math.min(t-1,S)),y:Math.max(0,Math.min(o-1,V)),over:H,isLeftDown:p}}static collectTouchPositions(s,e,t,o,n=10,i){let a=[],{renderWidth:p,renderHeight:c,offsetX:m,offsetY:f,rect:G}=D.calculateRenderMetrics(e,i),b=p/t,T=c/o;for(let y=0;y<n;y++){let R=y;if(s.getButton(l.InputDeviceType.Touch,R)){let S=oe+y*ne,V=oe+y*ne+1,H=s.getAxis(l.InputDeviceType.Touch,S),ie=s.getAxis(l.InputDeviceType.Touch,V),j=H-G.left-m,$=ie-G.top-f,ae=Math.floor(j/b),re=Math.floor($/T),ue=j>=0&&j<p&&$>=0&&$<c;a.push({id:y,x:Math.max(0,Math.min(t-1,ae)),y:Math.max(0,Math.min(o-1,re)),over:ue})}}return a}static collectTextInputs(s){return typeof s.getTextInputs=="function"?s.getTextInputs():[]}};h(D,"InputCollector");var L=D;
1
+ "use strict";var A=Object.defineProperty;var ce=Object.getOwnPropertyDescriptor;var he=Object.getOwnPropertyNames;var pe=Object.prototype.hasOwnProperty;var be=(p,s,e)=>s in p?A(p,s,{enumerable:!0,configurable:!0,writable:!0,value:e}):p[s]=e;var f=(p,s)=>A(p,"name",{value:s,configurable:!0});var me=(p,s)=>{for(var e in s)A(p,e,{get:s[e],enumerable:!0})},fe=(p,s,e,t)=>{if(s&&typeof s=="object"||typeof s=="function")for(let o of he(s))!pe.call(p,o)&&o!==e&&A(p,o,{get:()=>s[o],enumerable:!(t=ce(s,o))||t.enumerable});return p};var ge=p=>fe(A({},"__esModule",{value:!0}),p);var r=(p,s,e)=>(be(p,typeof s!="symbol"?s+"":s,e),e);var ye={};me(ye,{BaseInputs:()=>y,GamepadInput:()=>w.GamepadInput,GamepadInputs:()=>L,InputCollector:()=>K,InputDeviceType:()=>w.InputDeviceType,InputEventType:()=>W,KeyboardInput:()=>w.KeyboardInput,KeyboardInputs:()=>x,MobileInputs:()=>k,MobileVibration:()=>R,MouseInput:()=>w.MouseInput,MouseInputs:()=>B,TouchInput:()=>w.TouchInput,TouchZoneInput:()=>w.TouchZoneInput,TouchZoneInputs:()=>D,UnifiedInputRouter:()=>H,Vector2:()=>j.Vector2,Vector3:()=>j.Vector3,VibrationPatterns:()=>T,getMobileVibration:()=>oe,isInputs:()=>_,useGamepadInputs:()=>ne,useKeyboardInputs:()=>ee,useMobileInputs:()=>se,useMouseInputs:()=>te});module.exports=ge(ye);var j=require("@utsp/types"),w=require("@utsp/types");var W=(b=>(b.KeyDown="keydown",b.KeyUp="keyup",b.MouseDown="mousedown",b.MouseUp="mouseup",b.MouseMove="mousemove",b.MouseWheel="mousewheel",b.TouchStart="touchstart",b.TouchEnd="touchend",b.TouchMove="touchmove",b.GamepadConnected="gamepadconnected",b.GamepadDisconnected="gamepaddisconnected",b.GamepadButton="gamepadbutton",b.GamepadAxis="gamepadaxis",b))(W||{}),X=class X{constructor(s=window,e={}){r(this,"isActive",!1);r(this,"targetElement");r(this,"config");r(this,"callbacks",{});this.targetElement=s,this.config={enabled:!0,preventDefault:!1,stopPropagation:!1,debug:!1,...e}}isListening(){return this.isActive}destroy(){this.stop(),this.clearCallbacks()}setCallbacks(s){typeof s=="object"&&s!==null&&Object.assign(this.callbacks,s)}clearCallbacks(){this.callbacks={}}getTargetElement(){return this.targetElement}enable(){this.config.enabled=!0,this.isActive||this.start()}disable(){this.config.enabled=!1,this.isActive&&this.stop()}isEnabled(){return this.config.enabled??!0}emit(s,...e){this.callbacks[s]&&this.callbacks[s].forEach(t=>{try{t(...e)}catch(o){this.config.debug&&console.error(`Error in ${s} callback:`,o)}})}log(...s){this.config.debug&&console.warn("[InputSystem]",...s)}};f(X,"BaseInputs");var y=X;function _(p){return typeof p=="object"&&p!==null&&"start"in p&&"stop"in p&&"reset"in p&&"isListening"in p&&"destroy"in p}f(_,"isInputs");var Y=class Y extends y{constructor(e=window,t={}){super(e,t);r(this,"keys",{});r(this,"keyboardCallbacks",{});r(this,"textInputsThisFrame",[]);r(this,"boundHandlers");this.boundHandlers={keyDown:this.handleKeyDown.bind(this),keyUp:this.handleKeyUp.bind(this)}}start(){this.isActive||(this.targetElement.addEventListener("keydown",this.boundHandlers.keyDown),this.targetElement.addEventListener("keyup",this.boundHandlers.keyUp),this.isActive=!0)}stop(){this.isActive&&(this.targetElement.removeEventListener("keydown",this.boundHandlers.keyDown),this.targetElement.removeEventListener("keyup",this.boundHandlers.keyUp),this.isActive=!1)}reset(){this.keys={}}resetDelta(){}poll(){for(let e in this.keys)this.keys[e].justPressed=!1,this.keys[e].justReleased=!1;this.textInputsThisFrame=[]}getTextInputs(){return this.textInputsThisFrame}isKeyPressed(e){return this.keys[e]?.pressed||!1}isKeyJustPressed(e){return this.keys[e]?.justPressed||!1}isKeyJustReleased(e){return this.keys[e]?.justReleased||!1}getKeysPressed(){return Object.keys(this.keys).filter(e=>this.keys[e].pressed)}getKeysJustPressed(){return Object.keys(this.keys).filter(e=>this.keys[e].justPressed)}getKeysJustReleased(){return Object.keys(this.keys).filter(e=>this.keys[e].justReleased)}isAnyKeyPressed(){return Object.values(this.keys).some(e=>e.pressed)}setKeyboardCallbacks(e){this.keyboardCallbacks={...this.keyboardCallbacks,...e}}clearKeyboardCallbacks(){this.keyboardCallbacks={}}setCallbacks(e){this.isKeyboardCallbacks(e)&&this.setKeyboardCallbacks(e)}isKeyboardCallbacks(e){return typeof e=="object"&&e!==null&&("onKeyDown"in e||"onKeyUp"in e)}shouldAllowDefault(e,t){let o=/^F([1-9]|1[0-2])$/.test(e),n=(t.ctrlKey||t.metaKey)&&(e==="KeyT"||e==="KeyW"||e==="KeyR"||e==="KeyN"||e==="Tab");return o||n}handleKeyDown(e){try{let t=e.code,o=this.shouldAllowDefault(t,e);this.config.preventDefault&&!o&&e.preventDefault(),this.config.stopPropagation&&!o&&e.stopPropagation(),this.keys[t]||(this.keys[t]={pressed:!1,justPressed:!1,justReleased:!1}),this.keys[t].pressed||(this.keys[t].justPressed=!0,this.keyboardCallbacks.onKeyDown?.(t,e)),this.keys[t].pressed=!0,this.keys[t].justReleased=!1;let n=e.key;n.length===1&&!e.ctrlKey&&!e.metaKey&&this.textInputsThisFrame.push(n)}catch(t){console.error("Error in keyboard keydown handler:",t)}}handleKeyUp(e){try{let t=e.code,o=this.shouldAllowDefault(t,e);this.config.preventDefault&&!o&&e.preventDefault(),this.config.stopPropagation&&!o&&e.stopPropagation(),this.keys[t]||(this.keys[t]={pressed:!1,justPressed:!1,justReleased:!1}),this.keys[t].pressed&&(this.keys[t].justReleased=!0,this.keyboardCallbacks.onKeyUp?.(t,e)),this.keys[t].pressed=!1,this.keys[t].justPressed=!1}catch(t){console.error("Error in keyboard keyup handler:",t)}}};f(Y,"KeyboardInputs");var x=Y;function ee(p,s){let e=new x(p);return s&&e.setCallbacks(s),e.start(),e}f(ee,"useKeyboardInputs");var P=require("@utsp/types");var G=class G extends y{constructor(e=window,t={}){super(e,t);r(this,"mouseButtons",{left:{pressed:!1,justPressed:!1,justReleased:!1},middle:{pressed:!1,justPressed:!1,justReleased:!1},right:{pressed:!1,justPressed:!1,justReleased:!1}});r(this,"mousePosition",P.Vector2.zero());r(this,"mouseDelta",P.Vector2.zero());r(this,"wheelDelta",0);r(this,"mouseCallbacks",{});r(this,"boundHandlers");this.boundHandlers={mouseDown:this.handleMouseDown.bind(this),mouseUp:this.handleMouseUp.bind(this),mouseMove:this.handleMouseMove.bind(this),wheel:this.handleWheel.bind(this),mouseEnter:this.handleMouseEnter.bind(this),mouseLeave:this.handleMouseLeave.bind(this),contextMenu:this.handleContextMenu.bind(this)}}start(){this.isActive||(this.targetElement.addEventListener("mousedown",this.boundHandlers.mouseDown),this.targetElement.addEventListener("mouseup",this.boundHandlers.mouseUp),this.targetElement.addEventListener("mousemove",this.boundHandlers.mouseMove),this.targetElement.addEventListener("wheel",this.boundHandlers.wheel),this.targetElement.addEventListener("mouseenter",this.boundHandlers.mouseEnter),this.targetElement.addEventListener("mouseleave",this.boundHandlers.mouseLeave),this.targetElement.addEventListener("contextmenu",this.boundHandlers.contextMenu),this.isActive=!0)}stop(){this.isActive&&(this.targetElement.removeEventListener("mousedown",this.boundHandlers.mouseDown),this.targetElement.removeEventListener("mouseup",this.boundHandlers.mouseUp),this.targetElement.removeEventListener("mousemove",this.boundHandlers.mouseMove),this.targetElement.removeEventListener("wheel",this.boundHandlers.wheel),this.targetElement.removeEventListener("mouseenter",this.boundHandlers.mouseEnter),this.targetElement.removeEventListener("mouseleave",this.boundHandlers.mouseLeave),this.targetElement.removeEventListener("contextmenu",this.boundHandlers.contextMenu),this.isActive=!1)}reset(){this.mouseButtons={left:{pressed:!1,justPressed:!1,justReleased:!1},middle:{pressed:!1,justPressed:!1,justReleased:!1},right:{pressed:!1,justPressed:!1,justReleased:!1}},this.mousePosition=P.Vector2.zero(),this.mouseDelta=P.Vector2.zero(),this.wheelDelta=0}poll(){this.mouseButtons.left.justPressed=!1,this.mouseButtons.left.justReleased=!1,this.mouseButtons.middle.justPressed=!1,this.mouseButtons.middle.justReleased=!1,this.mouseButtons.right.justPressed=!1,this.mouseButtons.right.justReleased=!1,this.resetDelta()}resetDelta(){this.mouseDelta=P.Vector2.zero(),this.wheelDelta=0}isLeftMousePressed(){return this.mouseButtons.left.pressed}isLeftMouseJustPressed(){return this.mouseButtons.left.justPressed}isLeftMouseJustReleased(){return this.mouseButtons.left.justReleased}isRightMousePressed(){return this.mouseButtons.right.pressed}isRightMouseJustPressed(){return this.mouseButtons.right.justPressed}isRightMouseJustReleased(){return this.mouseButtons.right.justReleased}isMiddleMousePressed(){return this.mouseButtons.middle.pressed}isMiddleMouseJustPressed(){return this.mouseButtons.middle.justPressed}isMiddleMouseJustReleased(){return this.mouseButtons.middle.justReleased}getMousePosition(){return this.mousePosition.clone()}getMouseDelta(){return this.mouseDelta.clone()}getWheelDelta(){return this.wheelDelta}setMouseCallbacks(e){this.mouseCallbacks={...this.mouseCallbacks,...e}}clearMouseCallbacks(){this.mouseCallbacks={}}setCallbacks(e){this.isMouseCallbacks(e)&&this.setMouseCallbacks(e)}isMouseCallbacks(e){return typeof e=="object"&&e!==null&&("onMouseDown"in e||"onMouseUp"in e||"onMouseMove"in e||"onMouseWheel"in e||"onMouseEnter"in e||"onMouseLeave"in e)}getButtonByIndex(e){let t=G.BUTTON_NAMES[e];return t?{state:this.mouseButtons[t],name:t}:null}handleMouseDown(e){try{this.config.preventDefault&&e.preventDefault(),this.config.stopPropagation&&e.stopPropagation();let t=this.getButtonByIndex(e.button);t&&(t.state.pressed||(t.state.justPressed=!0),t.state.pressed=!0,t.state.justReleased=!1,this.mouseCallbacks.onMouseDown?.(t.name,this.mousePosition,e))}catch(t){console.error("Error in mouse down handler:",t)}}handleMouseUp(e){try{this.config.preventDefault&&e.preventDefault(),this.config.stopPropagation&&e.stopPropagation();let t=this.getButtonByIndex(e.button);t&&(t.state.pressed&&(t.state.justReleased=!0),t.state.pressed=!1,t.state.justPressed=!1,this.mouseCallbacks.onMouseUp?.(t.name,this.mousePosition,e))}catch(t){console.error("Error in mouse up handler:",t)}}handleMouseMove(e){try{this.config.preventDefault&&e.preventDefault(),this.config.stopPropagation&&e.stopPropagation();let t=new P.Vector2(e.clientX,e.clientY);this.mouseDelta=t.subtract(this.mousePosition),this.mousePosition=t,this.mouseCallbacks.onMouseMove?.(this.mousePosition,this.mouseDelta,e)}catch(t){console.error("Error in mouse move handler:",t)}}handleWheel(e){try{this.config.preventDefault&&e.preventDefault(),this.config.stopPropagation&&e.stopPropagation(),this.wheelDelta=e.deltaY,this.mouseCallbacks.onMouseWheel?.(this.wheelDelta,e)}catch(t){console.error("Error in mouse wheel handler:",t)}}handleMouseEnter(e){try{this.mouseCallbacks.onMouseEnter?.(e)}catch(t){console.error("Error in mouse enter handler:",t)}}handleMouseLeave(e){try{this.mouseCallbacks.onMouseLeave?.(e)}catch(t){console.error("Error in mouse leave handler:",t)}}handleContextMenu(e){try{e.preventDefault(),this.config.stopPropagation&&e.stopPropagation()}catch(t){console.error("Error in context menu handler:",t)}}};f(G,"MouseInputs"),r(G,"BUTTON_NAMES",["left","middle","right"]);var B=G;function te(p,s){let e=new B(p);return s&&e.setCallbacks(s),e.start(),e}f(te,"useMouseInputs");var S=require("@utsp/types");var U=class U extends y{constructor(e=window,t={}){super(e,t);r(this,"touches",new Map);r(this,"nativeToInternal",new Map);r(this,"mobileCallbacks",{});r(this,"mobileConfig");r(this,"maxTouches",10);r(this,"lastLogTime",0);r(this,"boundHandlers");this.mobileConfig={targetElement:e,preventDefault:t.preventDefault??!1,passive:t.passive??!0,maxTouches:t.maxTouches??10,enabled:t.enabled??!0,debug:t.debug??!1,stopPropagation:t.stopPropagation??!1},this.maxTouches=this.mobileConfig.maxTouches,this.mobileConfig.preventDefault&&this.mobileConfig.passive&&(console.warn("[MobileInputs] passive=true prevents preventDefault() from working! Setting passive=false."),this.mobileConfig.passive=!1),this.boundHandlers={touchStart:this.handleTouchStart.bind(this),touchEnd:this.handleTouchEnd.bind(this),touchMove:this.handleTouchMove.bind(this),touchCancel:this.handleTouchCancel.bind(this),orientationChange:this.handleOrientationChange.bind(this)}}start(){if(this.isActive)return;let e={passive:!this.mobileConfig.preventDefault&&this.mobileConfig.passive};this.targetElement.addEventListener("touchstart",this.boundHandlers.touchStart,e),this.targetElement.addEventListener("touchend",this.boundHandlers.touchEnd,e),this.targetElement.addEventListener("touchmove",this.boundHandlers.touchMove,e),this.targetElement.addEventListener("touchcancel",this.boundHandlers.touchCancel,e),window.addEventListener("orientationchange",this.boundHandlers.orientationChange),this.isActive=!0}stop(){this.isActive&&(this.targetElement.removeEventListener("touchstart",this.boundHandlers.touchStart),this.targetElement.removeEventListener("touchend",this.boundHandlers.touchEnd),this.targetElement.removeEventListener("touchmove",this.boundHandlers.touchMove),this.targetElement.removeEventListener("touchcancel",this.boundHandlers.touchCancel),window.removeEventListener("orientationchange",this.boundHandlers.orientationChange),this.isActive=!1)}reset(){this.touches.clear(),this.nativeToInternal.clear()}resetDelta(){}poll(){let e=[];for(let[t,o]of this.touches.entries())o.justReleased&&(e.push(t),this.nativeToInternal.delete(o.nativeId)),o.justTouched=!1,o.justReleased=!1;for(let t of e)this.touches.delete(t)}isTouchActive(e){if(e<0||e>=this.maxTouches)return!1;let t=this.touches.get(e);return t?t.active:!1}getTouchPosition(e){if(e<0||e>=this.maxTouches)return null;let t=this.touches.get(e);return t?t.position.clone():null}getTouchStartPosition(e){if(e<0||e>=this.maxTouches)return null;let t=this.touches.get(e);return t?t.startPosition.clone():null}getTouchDelta(e){if(e<0||e>=this.maxTouches)return null;let t=this.touches.get(e);return t?t.position.subtract(t.startPosition):null}getTouchCount(){let e=0;for(let t of this.touches.values())t.active&&e++;return e}isTouchJustStarted(e){if(e<0||e>=this.maxTouches)return!1;let t=this.touches.get(e);return t?t.justTouched:!1}isTouchJustReleased(e){if(e<0||e>=this.maxTouches)return!1;let t=this.touches.get(e);return t?t.justReleased:!1}isAnyTouchJustStarted(){for(let e of this.touches.values())if(e.justTouched)return!0;return!1}isAnyTouchJustReleased(){for(let e of this.touches.values())if(e.justReleased)return!0;return!1}getJustReleasedTouches(){return Array.from(this.touches.values()).filter(e=>e.justReleased)}getAllTouches(){return Array.from(this.touches.values()).filter(e=>e.active)}setMobileCallbacks(e){this.mobileCallbacks={...this.mobileCallbacks,...e}}clearMobileCallbacks(){this.mobileCallbacks={}}setCallbacks(e){this.isMobileCallbacks(e)&&this.setMobileCallbacks(e)}isMobileCallbacks(e){return typeof e=="object"&&e!==null&&("onTouchStart"in e||"onTouchEnd"in e||"onTouchMove"in e||"onTouchCancel"in e||"onOrientationChange"in e)}handleTouchStart(e){try{this.mobileConfig.preventDefault&&e.preventDefault();let t=Array.from(e.changedTouches),o=[];for(let n of t){if(this.touches.size>=this.maxTouches)break;let i=this.nativeToInternal.get(n.identifier);if(i!==void 0){let h=this.touches.get(i);if(h){let m=new S.Vector2(n.clientX,n.clientY);h.position=m.clone(),h.startPosition=m.clone(),h.active=!0,h.justTouched=!0,h.justReleased=!1,o.push({...h})}continue}let a=-1;for(let h=0;h<this.maxTouches;h++)if(!this.touches.has(h)){a=h;break}if(a===-1)continue;let d=new S.Vector2(n.clientX,n.clientY),c={id:a,nativeId:n.identifier,position:d.clone(),startPosition:d.clone(),active:!0,justTouched:!0,justReleased:!1};this.touches.set(a,c),this.nativeToInternal.set(n.identifier,a),o.push(c),console.warn(`\u{1F446} Touch START - ID: ${a}`)}this.mobileCallbacks.onTouchStart?.(o,e)}catch(t){console.error("Error in touch start handler:",t)}}handleTouchEnd(e){try{this.mobileConfig.preventDefault&&e.preventDefault();let t=Array.from(e.changedTouches),o=[];for(let n of t){let i=this.nativeToInternal.get(n.identifier);if(i!==void 0){let a=this.touches.get(i);a&&(a.justReleased=!0,a.justTouched=!1,a.active=!1,o.push({...a}),console.warn(`\u{1F447} Touch END - ID: ${i}`))}}this.mobileCallbacks.onTouchEnd?.(o,e)}catch(t){console.error("Error in touch end handler:",t)}}handleTouchMove(e){try{let t=Array.from(e.changedTouches);this.mobileConfig.debug&&(!this.lastLogTime||Date.now()-this.lastLogTime>200)&&(console.warn(`\u{1F504} TouchMove event - ${t.length} touches changed`),this.lastLogTime=Date.now());for(let o of t){let n=this.nativeToInternal.get(o.identifier);if(n!==void 0){let i=this.touches.get(n);if(i){let a=i.position.clone();i.position=new S.Vector2(o.clientX,o.clientY),this.mobileConfig.debug&&(!this.lastLogTime||Date.now()-this.lastLogTime>200)&&console.warn(`\u{1F504} Updated touch ${i.id} (native ${o.identifier}) - ${a.x.toFixed(1)},${a.y.toFixed(1)} \u2192 ${o.clientX.toFixed(1)},${o.clientY.toFixed(1)}`)}}else this.mobileConfig.debug&&console.warn(`\u26A0\uFE0F Touch move for unknown native ID ${o.identifier}`)}this.mobileCallbacks.onTouchMove?.(this.getAllTouches(),e)}catch(t){console.error("Error in touch move handler:",t)}}handleTouchCancel(e){try{this.mobileConfig.preventDefault&&e.preventDefault();let t=[],o=Array.from(e.changedTouches);for(let n of o){let i=this.nativeToInternal.get(n.identifier);if(i!==void 0){let a=this.touches.get(i);a&&(a.justReleased=!0,a.justTouched=!1,a.active=!1,t.push({...a}),this.mobileConfig.debug&&console.warn(`\u274C Touch CANCEL - ID: ${i}, nativeId: ${n.identifier}`))}}this.mobileCallbacks.onTouchCancel?.(t,e)}catch(t){console.error("Error in touch cancel handler:",t)}}handleOrientationChange(e){try{let t=(window.screen.orientation&&window.screen.orientation.angle)??window.orientation??0;this.mobileCallbacks.onOrientationChange?.(t)}catch(t){console.error("Error in orientation change handler:",t)}}};f(U,"MobileInputs");var k=U;function se(p,s,e){console.warn("[MobileInputs] useMobileInputs() is deprecated and causes memory leaks. Use useMemo + useEffect instead.");let t=new k(p,e);return s&&t.setCallbacks(s),t.start(),t}f(se,"useMobileInputs");var O=class O extends y{constructor(e,t){super(t.targetElement,t);this.mobile=e;r(this,"zones",[]);r(this,"zoneState",new Map);r(this,"gridWidth");r(this,"gridHeight");r(this,"rendererOffsets");this.gridWidth=t.gridWidth,this.gridHeight=t.gridHeight,this.rendererOffsets=t.rendererOffsets??{offsetX:0,offsetY:0},t.zones&&this.setZones(t.zones)}start(){this.isActive=!0}stop(){this.isActive=!1}reset(){this.clearZones()}resetDelta(){}setLayout(e,t,o){this.gridWidth=e,this.gridHeight=t,o&&(this.rendererOffsets=o)}setZones(e){this.zones=e.filter(t=>t.id>=0&&t.id<=31),this.zoneState.clear();for(let t of this.zones)this.zoneState.set(t.id,{pressed:!1,justPressed:!1,justReleased:!1,lastX:t.x,lastY:t.y})}clearZones(){this.zones=[],this.zoneState.clear()}updateFromTouches(){if(this.zones.length===0)return;let e=this.targetElement,t=e.getBoundingClientRect(),{renderWidth:o,renderHeight:n,offsetX:i,offsetY:a}=this.calculateRenderMetrics(e,t),d=o/this.gridWidth,c=n/this.gridHeight,h=new Map,m=new Map,E=this.mobile.getAllTouches();for(let b of E){let g=b.position.x-t.left-i,M=b.position.y-t.top-a,I=Math.floor(g/d),C=Math.floor(M/c);for(let v of this.zones)this.isInsideZone(I,C,v)&&(h.set(v.id,(h.get(v.id)??0)+1),m.set(v.id,{x:Math.max(v.x,Math.min(v.x+v.width-1,I)),y:Math.max(v.y,Math.min(v.y+v.height-1,C))}))}for(let b of this.zones){let g=this.zoneState.get(b.id)??{pressed:!1,justPressed:!1,justReleased:!1,lastX:b.x,lastY:b.y},I=(h.get(b.id)??0)>0;I&&!g.pressed&&(g.justPressed=!0),!I&&g.pressed&&(g.justReleased=!0),g.pressed=I;let C=m.get(b.id);C&&(g.lastX=C.x,g.lastY=C.y),this.zoneState.set(b.id,g)}}poll(){for(let e of this.zoneState.values())e.justPressed=!1,e.justReleased=!1}isZonePressed(e){return this.zoneState.get(e)?.pressed??!1}isZoneJustPressed(e){return this.zoneState.get(e)?.justPressed??!1}isZoneJustReleased(e){return this.zoneState.get(e)?.justReleased??!1}getZoneAxis(e,t){let o=this.zoneState.get(e);if(!o||!o.pressed)return 0;let n=this.zones.find(i=>i.id===e);if(!n)return 0;if(t==="x"){let i=(n.width-1)/2,a=n.x+i;return i>0?(o.lastX-a)/i:0}else{let i=(n.height-1)/2,a=n.y+i;return i>0?(o.lastY-a)/i:0}}getZonePosition(e){let t=this.zoneState.get(e);return t?{x:t.lastX,y:t.lastY}:null}calculateRenderMetrics(e,t){let o=e.width,n=e.height,i=o/n,a=t.width/t.height,d,c,h,m;i>a?(d=t.width,c=t.width/i,h=0,m=(t.height-c)/2):(d=t.height*i,c=t.height,h=(t.width-d)/2,m=0);let E=this.rendererOffsets;return h+=E.offsetX,m+=E.offsetY,d-=E.offsetX*2,c-=E.offsetY*2,{renderWidth:d,renderHeight:c,offsetX:h,offsetY:m}}isInsideZone(e,t,o){return e>=o.x&&e<o.x+o.width&&t>=o.y&&t<o.y+o.height}};f(O,"TouchZoneInputs");var D=O;var T={tap:10,mediumTap:25,heavyTap:50,success:[30,50,30],error:[50,30,50,30,50],warning:[100],selection:5,impactLight:15,impactMedium:30,impactHeavy:50,notification:[100,100,100,100,100],sos:[100,30,100,30,100,30,200,30,200,30,200,30,100,30,100,30,100]},F=class F{constructor(s={}){r(this,"config");r(this,"supported",!1);r(this,"userActivated",!1);this.config={enabled:s.enabled??!0,debug:s.debug??!1,intensity:Math.max(0,Math.min(1,s.intensity??1))},this.supported=typeof navigator<"u"&&"vibrate"in navigator,this.config.debug&&console.log(`[MobileVibration] Vibration API supported: ${this.supported}`)}isSupported(){return this.supported}isEnabled(){return this.config.enabled&&this.supported}setEnabled(s){this.config.enabled=s,this.config.debug&&console.log(`[MobileVibration] Enabled: ${s}`)}setIntensity(s){this.config.intensity=Math.max(0,Math.min(1,s)),this.config.debug&&console.log(`[MobileVibration] Intensity set to: ${this.config.intensity}`)}getIntensity(){return this.config.intensity}vibrate(s){if(!this.isEnabled())return!1;try{let e=this.scalePattern(s),t=typeof e=="number"?e:[...e],o=navigator.vibrate(t);return this.config.debug&&console.log(`[MobileVibration] Vibrate: ${JSON.stringify(e)} -> ${o}`),o&&(this.userActivated=!0),o}catch(e){return this.config.debug&&console.error("[MobileVibration] Vibration failed:",e),!1}}cancel(){this.supported&&(navigator.vibrate(0),this.config.debug&&console.log("[MobileVibration] Vibration cancelled"))}hasUserActivation(){return this.userActivated}tap(){return this.vibrate(T.tap)}mediumTap(){return this.vibrate(T.mediumTap)}heavyTap(){return this.vibrate(T.heavyTap)}success(){return this.vibrate(T.success)}error(){return this.vibrate(T.error)}warning(){return this.vibrate(T.warning)}selection(){return this.vibrate(T.selection)}impactLight(){return this.vibrate(T.impactLight)}impactMedium(){return this.vibrate(T.impactMedium)}impactHeavy(){return this.vibrate(T.impactHeavy)}notification(){return this.vibrate(T.notification)}scalePattern(s){return this.config.intensity===1?s:typeof s=="number"?Math.round(s*this.config.intensity):s.map((e,t)=>t%2===0?Math.round(e*this.config.intensity):e)}};f(F,"MobileVibration");var R=F,N=null;function oe(){return N||(N=new R),N}f(oe,"getMobileVibration");var ve=.01,q=class q extends y{constructor(e={}){super(window,e);r(this,"gamepads",new Map);r(this,"previousGamepads",new Map);r(this,"gamepadCallbacks",{});r(this,"gamepadConfig");r(this,"pollingIntervalId",null);r(this,"rafId",null);r(this,"boundHandlers");r(this,"vibrationPresets",{tap:{duration:50,strongMagnitude:.3,weakMagnitude:.5},impact:{duration:100,strongMagnitude:.7,weakMagnitude:.3},heavy:{duration:200,strongMagnitude:1,weakMagnitude:.2},success:{duration:150,strongMagnitude:.4,weakMagnitude:.6},error:{duration:300,strongMagnitude:.8,weakMagnitude:.4},explosion:{duration:400,strongMagnitude:1,weakMagnitude:.8},engine:{duration:1e3,strongMagnitude:.5,weakMagnitude:.2},heartbeat:{duration:100,strongMagnitude:.6,weakMagnitude:.1}});this.gamepadConfig={targetElement:window,maxGamepads:e.maxGamepads??4,axisDeadzone:e.axisDeadzone??.1,pollingInterval:e.pollingInterval??16,autoPolling:e.autoPolling??!0,enabled:e.enabled??!0,debug:e.debug??!1,preventDefault:e.preventDefault??!1,stopPropagation:e.stopPropagation??!1},this.boundHandlers={connected:this.handleGamepadConnected.bind(this),disconnected:this.handleGamepadDisconnected.bind(this)}}start(){this.isActive||(window.addEventListener("gamepadconnected",this.boundHandlers.connected),window.addEventListener("gamepaddisconnected",this.boundHandlers.disconnected),this.gamepadConfig.autoPolling&&this.startPolling(),this.isActive=!0,this.log("GamepadInputs started"))}stop(){this.isActive&&(window.removeEventListener("gamepadconnected",this.boundHandlers.connected),window.removeEventListener("gamepaddisconnected",this.boundHandlers.disconnected),this.stopPolling(),this.isActive=!1,this.log("GamepadInputs stopped"))}reset(){this.gamepads.clear(),this.previousGamepads.clear()}resetDelta(){this.previousGamepads.clear(),this.gamepads.forEach((e,t)=>{this.previousGamepads.set(t,this.cloneGamepadState(e))})}startPolling(){if(this.pollingIntervalId!==null||this.rafId!==null)return;let e=f(()=>{this.poll(),this.rafId=requestAnimationFrame(e)},"poll");this.rafId=requestAnimationFrame(e),this.log("Polling started")}stopPolling(){this.rafId!==null&&(cancelAnimationFrame(this.rafId),this.rafId=null),this.pollingIntervalId!==null&&(clearInterval(this.pollingIntervalId),this.pollingIntervalId=null),this.log("Polling stopped")}poll(){let e=navigator.getGamepads?navigator.getGamepads():[];for(let t=0;t<e.length&&t<this.gamepadConfig.maxGamepads;t++){let o=e[t];o&&this.updateGamepadState(o)}}getConnectedGamepadCount(){return this.gamepads.size}isGamepadConnected(e){return this.gamepads.has(e)&&this.gamepads.get(e).connected}getGamepadState(e){return this.gamepads.get(e)||null}getAllGamepads(){return Array.from(this.gamepads.values()).filter(e=>e.connected)}isButtonPressed(e,t){if(!Number.isInteger(e)||e<0)throw new Error(`Invalid gamepadIndex: ${e}. Must be a non-negative integer.`);if(!Number.isInteger(t)||t<0)throw new Error(`Invalid buttonIndex: ${t}. Must be a non-negative integer.`);let o=this.gamepads.get(e);return!o||!o.connected||t>=o.buttons.length?!1:o.buttons[t].pressed}isButtonJustPressed(e,t){if(!Number.isInteger(e)||e<0)throw new Error(`Invalid gamepadIndex: ${e}. Must be a non-negative integer.`);if(!Number.isInteger(t)||t<0)throw new Error(`Invalid buttonIndex: ${t}. Must be a non-negative integer.`);let o=this.gamepads.get(e);return!o||!o.connected||t>=o.buttons.length?!1:o.buttons[t].justPressed}isButtonJustReleased(e,t){if(!Number.isInteger(e)||e<0)throw new Error(`Invalid gamepadIndex: ${e}. Must be a non-negative integer.`);if(!Number.isInteger(t)||t<0)throw new Error(`Invalid buttonIndex: ${t}. Must be a non-negative integer.`);let o=this.gamepads.get(e);return!o||!o.connected||t>=o.buttons.length?!1:o.buttons[t].justReleased}getButtonValue(e,t){if(!Number.isInteger(e)||e<0)throw new Error(`Invalid gamepadIndex: ${e}. Must be a non-negative integer.`);if(!Number.isInteger(t)||t<0)throw new Error(`Invalid buttonIndex: ${t}. Must be a non-negative integer.`);let o=this.gamepads.get(e);return!o||!o.connected||t>=o.buttons.length?0:o.buttons[t].value}getAxis(e,t){if(!Number.isInteger(e)||e<0)throw new Error(`Invalid gamepadIndex: ${e}. Must be a non-negative integer.`);if(!Number.isInteger(t)||t<0)throw new Error(`Invalid axisIndex: ${t}. Must be a non-negative integer.`);let o=this.gamepads.get(e);if(!o||!o.connected||t>=o.axes.length)return 0;let n=o.axes[t];return this.applyDeadzone(n)}getAxisRaw(e,t){if(!Number.isInteger(e)||e<0)throw new Error(`Invalid gamepadIndex: ${e}. Must be a non-negative integer.`);if(!Number.isInteger(t)||t<0)throw new Error(`Invalid axisIndex: ${t}. Must be a non-negative integer.`);let o=this.gamepads.get(e);return!o||!o.connected||t>=o.axes.length?0:o.axes[t]}getLeftStick(e){return{x:this.getAxis(e,0),y:this.getAxis(e,1)}}getRightStick(e){return{x:this.getAxis(e,2),y:this.getAxis(e,3)}}supportsVibration(e){let t=this.getNativeGamepad(e);if(!t)return!1;let o=t.vibrationActuator;if(o&&typeof o.playEffect=="function")return!0;let n=t.hapticActuators;return!!(n&&n.length>0)}async vibrate(e,t){let o=this.getNativeGamepad(e);if(!o)return this.log(`Vibrate failed: gamepad ${e} not found`),!1;let{duration:n,strongMagnitude:i=1,weakMagnitude:a=.5,startDelay:d=0}=t;try{let c=o.vibrationActuator;if(c&&typeof c.playEffect=="function"){let m=await c.playEffect("dual-rumble",{startDelay:d,duration:n,strongMagnitude:Math.min(1,Math.max(0,i)),weakMagnitude:Math.min(1,Math.max(0,a))});return this.log(`Vibration effect result: ${m}`),m==="complete"}let h=o.hapticActuators;if(h&&h.length>0){let m=Math.max(i,a);return await h[0].pulse(m,n),!0}return this.log(`Vibrate failed: gamepad ${e} does not support vibration`),!1}catch(c){return this.log("Vibrate error:",c),!1}}async stopVibration(e){let t=this.getNativeGamepad(e);if(!t)return!1;try{let o=t.vibrationActuator;return o&&typeof o.reset=="function"?(await o.reset(),!0):o&&typeof o.playEffect=="function"?(await o.playEffect("dual-rumble",{duration:0,strongMagnitude:0,weakMagnitude:0}),!0):!1}catch(o){return this.log("Stop vibration error:",o),!1}}async stopAllVibrations(){let e=[];for(let[t]of this.gamepads)e.push(this.stopVibration(t));await Promise.all(e)}async vibrateAll(e){let t=[];for(let[o]of this.gamepads)t.push(this.vibrate(o,e));await Promise.all(t)}async vibratePreset(e,t){let o=this.vibrationPresets[t];return o?this.vibrate(e,o):(this.log(`Unknown vibration preset: ${t}`),!1)}getNativeGamepad(e){return(navigator.getGamepads?navigator.getGamepads():[])[e]||null}setGamepadCallbacks(e){this.gamepadCallbacks={...this.gamepadCallbacks,...e}}clearGamepadCallbacks(){this.gamepadCallbacks={}}setCallbacks(e){this.isGamepadCallbacks(e)&&this.setGamepadCallbacks(e)}isGamepadCallbacks(e){return typeof e=="object"&&e!==null&&("onGamepadConnected"in e||"onGamepadDisconnected"in e||"onButtonDown"in e||"onButtonUp"in e||"onAxisMove"in e)}updateGamepadState(e){let t=this.gamepads.get(e.index),o=Array.from(e.buttons).map((a,d)=>{let c=t?.buttons[d],h=a.pressed,m=c?.pressed??!1;return{pressed:h,justPressed:h&&!m,justReleased:!h&&m,value:a.value,touched:a.touched??!1}}),n=Array.from(e.axes),i={id:e.id,index:e.index,connected:e.connected,buttons:o,axes:n,timestamp:e.timestamp,mapping:e.mapping};this.gamepads.set(e.index,i),this.triggerCallbacks(i,t)}triggerCallbacks(e,t){try{e.buttons.forEach((o,n)=>{o.justPressed&&this.gamepadCallbacks.onButtonDown?.(e.index,n,o.value),o.justReleased&&this.gamepadCallbacks.onButtonUp?.(e.index,n)}),e.axes.forEach((o,n)=>{let i=t?.axes[n]??0,a=this.applyDeadzone(o),d=this.applyDeadzone(i);Math.abs(a-d)>ve&&this.gamepadCallbacks.onAxisMove?.(e.index,n,a)})}catch(o){this.log("Error in gamepad callbacks:",o)}}handleGamepadConnected(e){try{this.log(`Gamepad connected: ${e.gamepad.id} at index ${e.gamepad.index}`);let t={id:e.gamepad.id,index:e.gamepad.index,connected:!0,buttons:Array.from(e.gamepad.buttons).map(o=>({pressed:o.pressed,justPressed:!1,justReleased:!1,value:o.value,touched:o.touched??!1})),axes:Array.from(e.gamepad.axes),timestamp:e.gamepad.timestamp,mapping:e.gamepad.mapping};this.gamepads.set(e.gamepad.index,t),this.gamepadCallbacks.onGamepadConnected?.(t)}catch(t){this.log("Error handling gamepad connected:",t)}}handleGamepadDisconnected(e){try{this.log(`Gamepad disconnected at index ${e.gamepad.index}`),this.gamepads.delete(e.gamepad.index),this.previousGamepads.delete(e.gamepad.index),this.gamepadCallbacks.onGamepadDisconnected?.(e.gamepad.index)}catch(t){this.log("Error handling gamepad disconnected:",t)}}applyDeadzone(e){let t=this.gamepadConfig.axisDeadzone;return Math.abs(e)<t?0:(e>0?1:-1)*((Math.abs(e)-t)/(1-t))}cloneGamepadState(e){return{...e,buttons:e.buttons.map(t=>({...t})),axes:[...e.axes]}}};f(q,"GamepadInputs");var L=q;function ne(p,s){let e=new L(s);return p&&e.setGamepadCallbacks(p),e.start(),e}f(ne,"useGamepadInputs");var l=require("@utsp/types");var Q=class Q{constructor(s={}){r(this,"keyboard",null);r(this,"mouse",null);r(this,"gamepad",null);r(this,"mobile",null);r(this,"touchZones",null);r(this,"config");this.config={enableKeyboardMouse:s.enableKeyboardMouse??!0,enableGamepad:s.enableGamepad??!0,enableMobile:s.enableMobile??!1,targetElement:s.targetElement??window,mobileTargetElement:s.mobileTargetElement??s.targetElement??window,debug:s.debug??!1,keyboardConfig:{preventDefault:!1,stopPropagation:!1,...s.keyboardConfig},mouseConfig:{preventDefault:!1,stopPropagation:!1,...s.mouseConfig},mobileConfig:{preventDefault:!0,passive:!1,maxTouches:10,...s.mobileConfig},enableTouchZones:s.enableTouchZones??!1,touchZoneConfig:s.touchZoneConfig??{gridWidth:0,gridHeight:0}},this.initialize()}initialize(){if(this.config.enableKeyboardMouse&&(this.keyboard=new x(this.config.targetElement,{preventDefault:this.config.keyboardConfig?.preventDefault??!1,stopPropagation:this.config.keyboardConfig?.stopPropagation??!1,debug:this.config.debug}),this.keyboard.start(),this.mouse=new B(this.config.targetElement,{preventDefault:this.config.mouseConfig?.preventDefault??!1,stopPropagation:this.config.mouseConfig?.stopPropagation??!1,debug:this.config.debug}),this.mouse.start(),this.log("Keyboard/Mouse initialized")),this.config.enableGamepad&&(this.gamepad=new L({debug:this.config.debug}),this.gamepad.start(),this.log("Gamepad initialized")),this.config.enableMobile&&(this.config.mobileTargetElement?(this.mobile=new k(this.config.mobileTargetElement,this.config.mobileConfig),this.mobile.start(),this.log("Mobile/Touch initialized")):this.warn("Mobile input enabled but no canvas provided - mobile input will be disabled until setMobileTarget() is called")),this.config.enableTouchZones){let s=this.config.touchZoneConfig?.targetElement??this.config.mobileTargetElement;if(!s||!s.getBoundingClientRect)this.warn("Touch zones enabled but no canvas HTMLElement provided - touch zones disabled");else if(!this.mobile)this.warn("Touch zones require mobile input to be enabled - touch zones disabled");else{let e={targetElement:s,gridWidth:this.config.touchZoneConfig?.gridWidth??0,gridHeight:this.config.touchZoneConfig?.gridHeight??0,rendererOffsets:this.config.touchZoneConfig?.rendererOffsets,zones:this.config.touchZoneConfig?.zones,enabled:!0,debug:this.config.debug};this.disableSystemLongPressHaptics(s),this.touchZones=new D(this.mobile,e),this.log("Touch zones initialized")}}}getButton(s,e){if(!(0,l.isButton)({device:s,input:e}))return this.warn(`Input ${e} on device ${s} is not a button`),!1;switch(s){case l.InputDeviceType.Keyboard:return this.getKeyboardButton(e);case l.InputDeviceType.Mouse:return this.getMouseButton(e);case l.InputDeviceType.Gamepad:return this.getGamepadButton(e);case l.InputDeviceType.Touch:return this.getTouchButton(e);case l.InputDeviceType.TouchZone:return this.getTouchZoneButton(e);default:return this.warn(`Unknown device type: ${s}`),!1}}getButtonJustPressed(s,e){if(!(0,l.isButton)({device:s,input:e}))return this.warn(`Input ${e} on device ${s} is not a button`),!1;switch(s){case l.InputDeviceType.Keyboard:return this.getKeyboardButtonJustPressed(e);case l.InputDeviceType.Mouse:return this.getMouseButtonJustPressed(e);case l.InputDeviceType.Gamepad:return this.getGamepadButtonJustPressed(e);case l.InputDeviceType.Touch:return this.getTouchButtonJustPressed(e);case l.InputDeviceType.TouchZone:return this.getTouchZoneButtonJustPressed(e);default:return this.warn(`Unknown device type: ${s}`),!1}}getButtonJustReleased(s,e){if(!(0,l.isButton)({device:s,input:e}))return this.warn(`Input ${e} on device ${s} is not a button`),!1;switch(s){case l.InputDeviceType.Keyboard:return this.getKeyboardButtonJustReleased(e);case l.InputDeviceType.Mouse:return this.getMouseButtonJustReleased(e);case l.InputDeviceType.Gamepad:return this.getGamepadButtonJustReleased(e);case l.InputDeviceType.Touch:return this.getTouchButtonJustReleased(e);case l.InputDeviceType.TouchZone:return this.getTouchZoneButtonJustReleased(e);default:return this.warn(`Unknown device type: ${s}`),!1}}getAxis(s,e){if(!(0,l.isAxis)({device:s,input:e}))return this.warn(`Input ${e} on device ${s} is not an axis`),0;switch(s){case l.InputDeviceType.Keyboard:return this.warn("Keyboard does not have axis inputs"),0;case l.InputDeviceType.Mouse:return this.getMouseAxis(e);case l.InputDeviceType.Gamepad:return this.getGamepadAxis(e);case l.InputDeviceType.Touch:return this.getTouchAxis(e);case l.InputDeviceType.TouchZone:return this.getTouchZoneAxis(e);default:return this.warn(`Unknown device type: ${s}`),0}}isLeftMousePressed(){return this.mouse?this.mouse.isLeftMousePressed():!1}getKeyboardButton(s){if(!this.keyboard)return!1;let e=l.KeyboardInput[s];return this.keyboard.isKeyPressed(e)}getKeyboardButtonJustPressed(s){if(!this.keyboard)return!1;let e=l.KeyboardInput[s];return this.keyboard.isKeyJustPressed(e)}getKeyboardButtonJustReleased(s){if(!this.keyboard)return!1;let e=l.KeyboardInput[s];return this.keyboard.isKeyJustReleased(e)}getMouseButton(s){if(!this.mouse)return!1;switch(s){case l.MouseInput.LeftButton:return this.mouse.isLeftMousePressed();case l.MouseInput.RightButton:return this.mouse.isRightMousePressed();case l.MouseInput.MiddleButton:return this.mouse.isMiddleMousePressed();default:return!1}}getMouseButtonJustPressed(s){if(!this.mouse)return!1;switch(s){case l.MouseInput.LeftButton:return this.mouse.isLeftMouseJustPressed();case l.MouseInput.RightButton:return this.mouse.isRightMouseJustPressed();case l.MouseInput.MiddleButton:return this.mouse.isMiddleMouseJustPressed();default:return!1}}getMouseButtonJustReleased(s){if(!this.mouse)return!1;switch(s){case l.MouseInput.LeftButton:return this.mouse.isLeftMouseJustReleased();case l.MouseInput.RightButton:return this.mouse.isRightMouseJustReleased();case l.MouseInput.MiddleButton:return this.mouse.isMiddleMouseJustReleased();default:return!1}}getGamepadButton(s){return!this.gamepad||s>=100?!1:this.gamepad.isButtonPressed(0,s)}getGamepadButtonJustPressed(s){return!this.gamepad||s>=100?!1:this.gamepad.isButtonJustPressed(0,s)}getGamepadButtonJustReleased(s){return!this.gamepad||s>=100?!1:this.gamepad.isButtonJustReleased(0,s)}getTouchButton(s){return this.mobile?s>=100?!1:this.mobile.isTouchActive?.(s)??!1:(console.warn("\u{1F6AB} MobileInputs not initialized!"),!1)}getTouchButtonJustPressed(s){return!this.mobile||s>=100?!1:this.mobile.isTouchJustStarted?.(s)??!1}getTouchButtonJustReleased(s){return!this.mobile||s>=100?!1:this.mobile.isTouchJustReleased?.(s)??!1}ensureTouchZonesSynced(){this.touchZones?.updateFromTouches()}getTouchZoneButton(s){if(!this.touchZones)return!1;this.ensureTouchZonesSynced();let e=s;return this.touchZones.isZonePressed(e)}getTouchZoneButtonJustPressed(s){if(!this.touchZones)return!1;this.ensureTouchZonesSynced();let e=s;return this.touchZones.isZoneJustPressed(e)}getTouchZoneButtonJustReleased(s){if(!this.touchZones)return!1;this.ensureTouchZonesSynced();let e=s;return this.touchZones.isZoneJustReleased(e)}getTouchZoneAxis(s){if(!this.touchZones||s<100)return 0;this.ensureTouchZonesSynced();let e=Math.floor((s-100)/2),t=(s-100)%2===0;return this.touchZones.getZoneAxis(e,t?"x":"y")}getMouseAxis(s){if(!this.mouse)return 0;switch(s){case l.MouseInput.PositionX:return this.mouse.getMousePosition().x;case l.MouseInput.PositionY:return this.mouse.getMousePosition().y;case l.MouseInput.DeltaX:return this.mouse.getMouseDelta().x;case l.MouseInput.DeltaY:return this.mouse.getMouseDelta().y;case l.MouseInput.WheelDeltaY:return this.mouse.getWheelDelta();default:return 0}}getGamepadAxis(s){if(!this.gamepad||s<100)return 0;let e=s-100;return this.gamepad.getAxis(0,e)}getTouchAxis(s){if(!this.mobile)return 0;if(s>=100&&s<200){let e=Math.floor((s-100)/2),t=(s-100)%2===0,o=this.mobile.getTouchPosition?.(e);return this.config.debug&&o&&console.warn(`\u{1F3AF} getTouchAxis(${s}) - touchIndex: ${e}, ${t?"X":"Y"}: ${t?o.x:o.y}`),o?t?o.x:o.y:0}return 0}getMousePosition(){if(!this.mouse)return null;let s=this.mouse.getMousePosition();return{x:s.x,y:s.y}}setMobileTarget(s){if(!s){this.warn("setMobileTarget() called with null/undefined canvas - mobile input will remain disabled");return}if(this.config.mobileTargetElement=s,!this.config.enableMobile){this.warn("setMobileTarget() called but mobile input is disabled in config");return}this.mobile&&this.mobile.stop(),this.mobile=new k(s,this.config.mobileConfig),this.mobile.start()}getTextInputs(){return this.keyboard?this.keyboard.getTextInputs():[]}start(){this.keyboard?.start(),this.mouse?.start(),this.log("Input router started")}stop(){this.keyboard?.stop(),this.mouse?.stop(),this.log("Input router stopped")}reset(){this.keyboard?.reset(),this.mouse?.reset(),this.log("Input router reset")}poll(){this.keyboard?.poll(),this.mouse?.poll(),this.gamepad?.poll(),this.mobile?.poll(),this.touchZones?.poll()}isListening(){return this.keyboard!==null&&this.config.enableKeyboardMouse||this.gamepad!==null&&this.config.enableGamepad||this.mobile!==null&&this.config.enableMobile||this.touchZones!==null&&this.config.enableTouchZones}getGamepad(){return this.gamepad}getKeyboard(){return this.keyboard}getMouse(){return this.mouse}getMobile(){return this.mobile}getTouchZones(){return this.touchZones}enableTouchZonesDevice(s,e,t,o){let n=Math.max(1,e),i=Math.max(1,t);if(this.touchZones)return o&&this.touchZones.setZones(o),this.touchZones.setLayout(n,i),!0;if(!this.mobile)return this.warn("Cannot enable touch zones: mobile input not initialized"),!1;let a={targetElement:s,gridWidth:n,gridHeight:i,zones:o,enabled:!0,debug:this.config.debug};return this.disableSystemLongPressHaptics(s),this.touchZones=new D(this.mobile,a),this.touchZones.start(),this.log(`Touch zones dynamically enabled with ${o?.length??0} zones`),!0}updateTouchZoneLayout(s,e,t){let o=Math.max(1,s),n=Math.max(1,e);this.touchZones?.setLayout(o,n,t)}destroy(){this.keyboard?.destroy(),this.mouse?.destroy(),this.keyboard=null,this.mouse=null,this.gamepad=null,this.mobile=null,this.touchZones=null,this.log("Input router destroyed")}log(s){this.config.debug&&console.warn(`[InputRouter] ${s}`)}warn(s){console.warn(`[InputRouter] ${s}`)}disableSystemLongPressHaptics(s){let e="__utspTouchSurfacePatched";s[e]||(s[e]=!0,s.style.setProperty("touch-action","none"),s.style.setProperty("user-select","none"),s.style.setProperty("-webkit-user-select","none"),s.style.setProperty("-webkit-touch-callout","none"),s.addEventListener("contextmenu",t=>t.preventDefault()),s.addEventListener("touchstart",t=>{t.preventDefault()},{passive:!1}))}};f(Q,"UnifiedInputRouter");var H=Q;var u=require("@utsp/types");var ie=100,ae=2,Z=class Z{static calculateRenderMetrics(s,e){let t=s.getBoundingClientRect(),o=s.width/s.height,n=t.width/t.height,i,a,d,c;o>n?(i=t.width,a=t.width/o,d=0,c=(t.height-a)/2):(i=t.height*o,a=t.height,d=(t.width-i)/2,c=0);let h=e?.offsetX||0,m=e?.offsetY||0;return d+=h,c+=m,i-=h*2,a-=m*2,{renderWidth:i,renderHeight:a,offsetX:d,offsetY:c,rect:t}}static collectAxisSources(s,e){let t=new Map;for(let o of s)for(let n of o.sources){if(t.has(n.sourceId))continue;let i=0,a=!1;if(n.type===u.InputDeviceType.Keyboard&&n.negativeKey!==void 0&&n.positiveKey!==void 0){let d=e.getButton(u.InputDeviceType.Keyboard,n.negativeKey);e.getButton(u.InputDeviceType.Keyboard,n.positiveKey)&&(i+=1),d&&(i-=1),a=!0}else if(n.type===u.InputDeviceType.Mouse&&n.mouseAxis!==void 0)i=e.getAxis(u.InputDeviceType.Mouse,n.mouseAxis),a=!0;else if(n.type===u.InputDeviceType.Gamepad&&n.axis!==void 0)i=e.getAxis(u.InputDeviceType.Gamepad,n.axis),a=!0;else if(n.type===u.InputDeviceType.Touch&&n.touchId!==void 0&&n.touchAxis!==void 0){let d=100+n.touchId*2,c=n.touchAxis==="x"?d:d+1;i=e.getAxis(u.InputDeviceType.Touch,c),a=!0}else if(n.type===u.InputDeviceType.TouchZone&&n.touchZoneId!==void 0&&n.touchZoneAxis!==void 0){let d=100+n.touchZoneId*2,c=n.touchZoneAxis==="x"?d:d+1;i=e.getAxis(u.InputDeviceType.TouchZone,c),a=!0}a&&t.set(n.sourceId,i)}return t}static collectButtonSources(s,e){let t=new Map;for(let o of s)for(let n of o.sources){if(t.has(n.sourceId))continue;let i=!1,a=!1;n.type===u.InputDeviceType.Keyboard&&n.key!==void 0?(i=e.getButton(u.InputDeviceType.Keyboard,n.key),a=!0):n.type===u.InputDeviceType.Mouse&&n.mouseButton!==void 0?(i=e.getButton(u.InputDeviceType.Mouse,n.mouseButton),a=!0):n.type===u.InputDeviceType.Gamepad&&n.button!==void 0?(i=e.getButton(u.InputDeviceType.Gamepad,n.button),a=!0):n.type===u.InputDeviceType.Touch&&n.touchButton!==void 0?(i=e.getButton(u.InputDeviceType.Touch,n.touchButton),a=!0):n.type===u.InputDeviceType.TouchZone&&n.touchZoneId!==void 0&&(i=e.getButton(u.InputDeviceType.TouchZone,n.touchZoneId),a=!0),a&&t.set(n.sourceId,i)}return t}static collectButtonSourcesWithTransitions(s,e){let t=new Map;for(let o of s)for(let n of o.sources){if(t.has(n.sourceId))continue;let i=!1,a=!1,d=!1,c=!1;n.type===u.InputDeviceType.Keyboard&&n.key!==void 0?(i=e.getButton(u.InputDeviceType.Keyboard,n.key),a=e.getButtonJustPressed?.(u.InputDeviceType.Keyboard,n.key)??!1,d=e.getButtonJustReleased?.(u.InputDeviceType.Keyboard,n.key)??!1,c=!0):n.type===u.InputDeviceType.Mouse&&n.mouseButton!==void 0?(i=e.getButton(u.InputDeviceType.Mouse,n.mouseButton),a=e.getButtonJustPressed?.(u.InputDeviceType.Mouse,n.mouseButton)??!1,d=e.getButtonJustReleased?.(u.InputDeviceType.Mouse,n.mouseButton)??!1,c=!0):n.type===u.InputDeviceType.Gamepad&&n.button!==void 0?(i=e.getButton(u.InputDeviceType.Gamepad,n.button),a=e.getButtonJustPressed?.(u.InputDeviceType.Gamepad,n.button)??!1,d=e.getButtonJustReleased?.(u.InputDeviceType.Gamepad,n.button)??!1,c=!0):n.type===u.InputDeviceType.Touch&&n.touchButton!==void 0?(i=e.getButton(u.InputDeviceType.Touch,n.touchButton),a=e.getButtonJustPressed?.(u.InputDeviceType.Touch,n.touchButton)??!1,d=e.getButtonJustReleased?.(u.InputDeviceType.Touch,n.touchButton)??!1,c=!0):n.type===u.InputDeviceType.TouchZone&&n.touchZoneId!==void 0&&(i=e.getButton(u.InputDeviceType.TouchZone,n.touchZoneId),a=e.getButtonJustPressed?.(u.InputDeviceType.TouchZone,n.touchZoneId)??!1,d=e.getButtonJustReleased?.(u.InputDeviceType.TouchZone,n.touchZoneId)??!1,c=!0),c&&t.set(n.sourceId,{pressed:i,justPressed:a,justReleased:d})}return t}static collectMousePosition(s,e,t,o,n){let i=s.getAxis(u.InputDeviceType.Mouse,u.MouseInput.PositionX),a=s.getAxis(u.InputDeviceType.Mouse,u.MouseInput.PositionY),d=s.isLeftMousePressed?.()??!1,{renderWidth:c,renderHeight:h,offsetX:m,offsetY:E,rect:b}=Z.calculateRenderMetrics(e,n),g=i-b.left-m,M=a-b.top-E,I=c/t,C=h/o,v=Math.floor(g/I),V=Math.floor(M/C),J=g>=0&&g<c&&M>=0&&M<h;return{x:Math.max(0,Math.min(t-1,v)),y:Math.max(0,Math.min(o-1,V)),over:J,isLeftDown:d}}static collectTouchPositions(s,e,t,o,n=10,i){let a=[],{renderWidth:d,renderHeight:c,offsetX:h,offsetY:m,rect:E}=Z.calculateRenderMetrics(e,i),b=d/t,g=c/o;for(let M=0;M<n;M++){let I=M;if(s.getButton(u.InputDeviceType.Touch,I)){let v=ie+M*ae,V=ie+M*ae+1,J=s.getAxis(u.InputDeviceType.Touch,v),re=s.getAxis(u.InputDeviceType.Touch,V),z=J-E.left-h,$=re-E.top-m,ue=Math.floor(z/b),le=Math.floor($/g),de=z>=0&&z<d&&$>=0&&$<c;a.push({id:M,x:Math.max(0,Math.min(t-1,ue)),y:Math.max(0,Math.min(o-1,le)),over:de})}}return a}static collectTextInputs(s){return typeof s.getTextInputs=="function"?s.getTextInputs():[]}};f(Z,"InputCollector");var K=Z;
package/dist/index.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  import { Vector2, Vector3, IMobileVibrationProcessor, VibrationPattern, IGamepadVibrationProcessor, GamepadVibrationOptions, IInputSystem, InputDeviceType, AxisBinding, ButtonBinding } from '@utsp/types';
2
- export { GamepadInput, IInputSystem, InputDeviceType, KeyboardInput, MouseInput, TouchInput, Vector2, Vector3, VibrationPattern } from '@utsp/types';
2
+ export { GamepadInput, IInputSystem, InputDeviceType, KeyboardInput, MouseInput, TouchInput, TouchZoneInput, Vector2, Vector3, VibrationPattern } from '@utsp/types';
3
3
 
4
4
  /**
5
5
  * Base interface for all input management systems
@@ -604,6 +604,7 @@ declare class MobileInputs extends BaseInputs {
604
604
  /**
605
605
  * Poll - Reset transient states (justTouched/justReleased)
606
606
  * Should be called once per frame AFTER collecting input
607
+ * Also cleans up released touches that were kept for one frame
607
608
  */
608
609
  poll(): void;
609
610
  /**
@@ -716,6 +717,16 @@ declare class MobileInputs extends BaseInputs {
716
717
  * Check if any touch just started this frame
717
718
  */
718
719
  isAnyTouchJustStarted(): boolean;
720
+ /**
721
+ * Check if any touch just ended this frame
722
+ */
723
+ isAnyTouchJustReleased(): boolean;
724
+ /**
725
+ * Get all touches that were just released this frame
726
+ *
727
+ * @returns Array of TouchPoint objects that were just released
728
+ */
729
+ getJustReleasedTouches(): TouchPoint[];
719
730
  /**
720
731
  * Get all active touches
721
732
  *
@@ -785,6 +796,88 @@ declare class MobileInputs extends BaseInputs {
785
796
  */
786
797
  declare function useMobileInputs(targetElement?: HTMLElement | Window, callbacks?: MobileCallbacks, config?: MobileInputsConfig): MobileInputs;
787
798
 
799
+ interface TouchZoneDefinition {
800
+ id: number;
801
+ x: number;
802
+ y: number;
803
+ width: number;
804
+ height: number;
805
+ }
806
+ interface TouchZoneConfig extends InputConfig {
807
+ /** Canvas element used to map screen touches to cell coordinates */
808
+ targetElement: HTMLElement;
809
+ /** Grid width (number of columns) */
810
+ gridWidth: number;
811
+ /** Grid height (number of rows) */
812
+ gridHeight: number;
813
+ /** Optional renderer offsets (content centered inside canvas) */
814
+ rendererOffsets?: {
815
+ offsetX: number;
816
+ offsetY: number;
817
+ };
818
+ /** Initial zones */
819
+ zones?: TouchZoneDefinition[];
820
+ }
821
+ /**
822
+ * TouchZoneInputs - generic virtual touch zones device
823
+ *
824
+ * - Zones are defined in grid cells (x/y/width/height)
825
+ * - Each zone exposes a button (pressed) and two axes (last X/Y in cells)
826
+ * - Independent of native touch IDs (robust multi-touch)
827
+ */
828
+ declare class TouchZoneInputs extends BaseInputs {
829
+ private mobile;
830
+ private zones;
831
+ private zoneState;
832
+ private gridWidth;
833
+ private gridHeight;
834
+ private rendererOffsets;
835
+ constructor(mobile: MobileInputs, config: TouchZoneConfig);
836
+ start(): void;
837
+ stop(): void;
838
+ reset(): void;
839
+ resetDelta(): void;
840
+ /** Update layout info (grid size / offsets) when display changes */
841
+ setLayout(gridWidth: number, gridHeight: number, rendererOffsets?: {
842
+ offsetX: number;
843
+ offsetY: number;
844
+ }): void;
845
+ /** Define zones (replace all) */
846
+ setZones(zones: TouchZoneDefinition[]): void;
847
+ /** Clear zones */
848
+ clearZones(): void;
849
+ /** Must be called before reads each frame to sync with current touches */
850
+ updateFromTouches(): void;
851
+ poll(): void;
852
+ isZonePressed(zoneId: number): boolean;
853
+ isZoneJustPressed(zoneId: number): boolean;
854
+ isZoneJustReleased(zoneId: number): boolean;
855
+ /**
856
+ * Get zone axis value (normalized -1 to +1 relative to zone center)
857
+ *
858
+ * For joystick-like zones: returns position within zone as -1 to +1
859
+ * - Center of zone = 0
860
+ * - Left/Top edge = -1
861
+ * - Right/Bottom edge = +1
862
+ *
863
+ * Returns 0 if zone not found or not pressed.
864
+ */
865
+ getZoneAxis(zoneId: number, axis: 'x' | 'y'): number;
866
+ /**
867
+ * Get zone position in display cell coordinates (absolute)
868
+ *
869
+ * Returns the last touch position within the zone in display coordinates.
870
+ * Useful for pointer-like zones where you need exact position.
871
+ */
872
+ getZonePosition(zoneId: number): {
873
+ x: number;
874
+ y: number;
875
+ } | null;
876
+ /** Render metrics (similar to InputCollector.calculateRenderMetrics) */
877
+ private calculateRenderMetrics;
878
+ private isInsideZone;
879
+ }
880
+
788
881
  /**
789
882
  * MobileVibration - Vibration feedback for mobile devices
790
883
  *
@@ -1386,6 +1479,18 @@ interface InputRouterConfig {
1386
1479
  passive?: boolean;
1387
1480
  maxTouches?: number;
1388
1481
  };
1482
+ /** Touch zone virtual device */
1483
+ enableTouchZones?: boolean;
1484
+ touchZoneConfig?: {
1485
+ gridWidth: number;
1486
+ gridHeight: number;
1487
+ rendererOffsets?: {
1488
+ offsetX: number;
1489
+ offsetY: number;
1490
+ };
1491
+ targetElement?: HTMLElement | Window;
1492
+ zones?: TouchZoneDefinition[];
1493
+ };
1389
1494
  }
1390
1495
  /**
1391
1496
  * Unified input router - manages all input devices with a type-safe enum-based API
@@ -1396,6 +1501,7 @@ declare class UnifiedInputRouter implements IInputSystem {
1396
1501
  private mouse;
1397
1502
  private gamepad;
1398
1503
  private mobile;
1504
+ private touchZones;
1399
1505
  private config;
1400
1506
  constructor(config?: InputRouterConfig);
1401
1507
  private initialize;
@@ -1432,6 +1538,11 @@ declare class UnifiedInputRouter implements IInputSystem {
1432
1538
  private getTouchButton;
1433
1539
  private getTouchButtonJustPressed;
1434
1540
  private getTouchButtonJustReleased;
1541
+ private ensureTouchZonesSynced;
1542
+ private getTouchZoneButton;
1543
+ private getTouchZoneButtonJustPressed;
1544
+ private getTouchZoneButtonJustReleased;
1545
+ private getTouchZoneAxis;
1435
1546
  private getMouseAxis;
1436
1547
  private getGamepadAxis;
1437
1548
  private getTouchAxis;
@@ -1487,9 +1598,40 @@ declare class UnifiedInputRouter implements IInputSystem {
1487
1598
  * Get the mobile/touch input handler for direct access
1488
1599
  */
1489
1600
  getMobile(): MobileInputs | null;
1601
+ /** Get the touch zones handler for direct configuration */
1602
+ getTouchZones(): TouchZoneInputs | null;
1603
+ /**
1604
+ * Enable touch zones dynamically (creates TouchZoneInputs if not already created)
1605
+ *
1606
+ * This allows touch zones to be enabled after the router is created,
1607
+ * which is needed when zones are defined in InputBindingRegistry during initUser().
1608
+ *
1609
+ * @param targetElement - Canvas element for coordinate mapping
1610
+ * @param gridWidth - Display width in cells
1611
+ * @param gridHeight - Display height in cells
1612
+ * @param zones - Initial zone definitions (optional)
1613
+ * @returns true if touch zones were enabled, false if prerequisites not met
1614
+ */
1615
+ enableTouchZonesDevice(targetElement: HTMLElement, gridWidth: number, gridHeight: number, zones?: Array<{
1616
+ id: number;
1617
+ x: number;
1618
+ y: number;
1619
+ width: number;
1620
+ height: number;
1621
+ }>): boolean;
1622
+ /** Update touch zone layout (grid size / renderer offsets) */
1623
+ updateTouchZoneLayout(gridWidth: number, gridHeight: number, rendererOffsets?: {
1624
+ offsetX: number;
1625
+ offsetY: number;
1626
+ }): void;
1490
1627
  destroy(): void;
1491
1628
  private log;
1492
1629
  private warn;
1630
+ /**
1631
+ * Prevent browser/system long-press behaviors (text selection, haptic feedback)
1632
+ * on the touch surface only, leaving the rest of the page unaffected.
1633
+ */
1634
+ private disableSystemLongPressHaptics;
1493
1635
  }
1494
1636
 
1495
1637
  /**
@@ -1726,5 +1868,5 @@ declare class InputCollector {
1726
1868
  static collectTextInputs(router: IInputSystem): string[];
1727
1869
  }
1728
1870
 
1729
- export { BaseInputs, GamepadInputs, InputCollector, InputEventType, KeyboardInputs, MobileInputs, MobileVibration, MouseInputs, UnifiedInputRouter, VibrationPatterns, getMobileVibration, isInputs, useGamepadInputs, useKeyboardInputs, useMobileInputs, useMouseInputs };
1730
- export type { ButtonState, GamepadButtonState, GamepadCallbacks, GamepadInputsConfig, GamepadState, IInputs, InputConfig, InputDevice, InputEvent, InputRouterConfig, KeyState, KeyboardCallbacks, MobileCallbacks, MobileInputsConfig, MobileVibrationConfig, MotionData, MouseButtonState, MouseButtons, MouseCallbacks, TouchPoint };
1871
+ export { BaseInputs, GamepadInputs, InputCollector, InputEventType, KeyboardInputs, MobileInputs, MobileVibration, MouseInputs, TouchZoneInputs, UnifiedInputRouter, VibrationPatterns, getMobileVibration, isInputs, useGamepadInputs, useKeyboardInputs, useMobileInputs, useMouseInputs };
1872
+ export type { ButtonState, GamepadButtonState, GamepadCallbacks, GamepadInputsConfig, GamepadState, IInputs, InputConfig, InputDevice, InputEvent, InputRouterConfig, KeyState, KeyboardCallbacks, MobileCallbacks, MobileInputsConfig, MobileVibrationConfig, MotionData, MouseButtonState, MouseButtons, MouseCallbacks, TouchPoint, TouchZoneConfig, TouchZoneDefinition };
package/dist/index.mjs CHANGED
@@ -1 +1 @@
1
- var F=Object.defineProperty;var ie=(c,s,e)=>s in c?F(c,s,{enumerable:!0,configurable:!0,writable:!0,value:e}):c[s]=e;var p=(c,s)=>F(c,"name",{value:s,configurable:!0});var r=(c,s,e)=>(ie(c,typeof s!="symbol"?s+"":s,e),e);import{Vector2 as Ne,Vector3 as Oe}from"@utsp/types";import{InputDeviceType as qe,KeyboardInput as Qe,MouseInput as Ze,GamepadInput as _e,TouchInput as et}from"@utsp/types";var q=(h=>(h.KeyDown="keydown",h.KeyUp="keyup",h.MouseDown="mousedown",h.MouseUp="mouseup",h.MouseMove="mousemove",h.MouseWheel="mousewheel",h.TouchStart="touchstart",h.TouchEnd="touchend",h.TouchMove="touchmove",h.GamepadConnected="gamepadconnected",h.GamepadDisconnected="gamepaddisconnected",h.GamepadButton="gamepadbutton",h.GamepadAxis="gamepadaxis",h))(q||{}),V=class V{constructor(s=window,e={}){r(this,"isActive",!1);r(this,"targetElement");r(this,"config");r(this,"callbacks",{});this.targetElement=s,this.config={enabled:!0,preventDefault:!1,stopPropagation:!1,debug:!1,...e}}isListening(){return this.isActive}destroy(){this.stop(),this.clearCallbacks()}setCallbacks(s){typeof s=="object"&&s!==null&&Object.assign(this.callbacks,s)}clearCallbacks(){this.callbacks={}}getTargetElement(){return this.targetElement}enable(){this.config.enabled=!0,this.isActive||this.start()}disable(){this.config.enabled=!1,this.isActive&&this.stop()}isEnabled(){return this.config.enabled??!0}emit(s,...e){this.callbacks[s]&&this.callbacks[s].forEach(t=>{try{t(...e)}catch(o){this.config.debug&&console.error(`Error in ${s} callback:`,o)}})}log(...s){this.config.debug&&console.warn("[InputSystem]",...s)}};p(V,"BaseInputs");var y=V;function ae(c){return typeof c=="object"&&c!==null&&"start"in c&&"stop"in c&&"reset"in c&&"isListening"in c&&"destroy"in c}p(ae,"isInputs");var H=class H extends y{constructor(e=window,t={}){super(e,t);r(this,"keys",{});r(this,"keyboardCallbacks",{});r(this,"textInputsThisFrame",[]);r(this,"boundHandlers");this.boundHandlers={keyDown:this.handleKeyDown.bind(this),keyUp:this.handleKeyUp.bind(this)}}start(){this.isActive||(this.targetElement.addEventListener("keydown",this.boundHandlers.keyDown),this.targetElement.addEventListener("keyup",this.boundHandlers.keyUp),this.isActive=!0)}stop(){this.isActive&&(this.targetElement.removeEventListener("keydown",this.boundHandlers.keyDown),this.targetElement.removeEventListener("keyup",this.boundHandlers.keyUp),this.isActive=!1)}reset(){this.keys={}}resetDelta(){}poll(){for(let e in this.keys)this.keys[e].justPressed=!1,this.keys[e].justReleased=!1;this.textInputsThisFrame=[]}getTextInputs(){return this.textInputsThisFrame}isKeyPressed(e){return this.keys[e]?.pressed||!1}isKeyJustPressed(e){return this.keys[e]?.justPressed||!1}isKeyJustReleased(e){return this.keys[e]?.justReleased||!1}getKeysPressed(){return Object.keys(this.keys).filter(e=>this.keys[e].pressed)}getKeysJustPressed(){return Object.keys(this.keys).filter(e=>this.keys[e].justPressed)}getKeysJustReleased(){return Object.keys(this.keys).filter(e=>this.keys[e].justReleased)}isAnyKeyPressed(){return Object.values(this.keys).some(e=>e.pressed)}setKeyboardCallbacks(e){this.keyboardCallbacks={...this.keyboardCallbacks,...e}}clearKeyboardCallbacks(){this.keyboardCallbacks={}}setCallbacks(e){this.isKeyboardCallbacks(e)&&this.setKeyboardCallbacks(e)}isKeyboardCallbacks(e){return typeof e=="object"&&e!==null&&("onKeyDown"in e||"onKeyUp"in e)}shouldAllowDefault(e,t){let o=/^F([1-9]|1[0-2])$/.test(e),n=(t.ctrlKey||t.metaKey)&&(e==="KeyT"||e==="KeyW"||e==="KeyR"||e==="KeyN"||e==="Tab");return o||n}handleKeyDown(e){try{let t=e.code,o=this.shouldAllowDefault(t,e);this.config.preventDefault&&!o&&e.preventDefault(),this.config.stopPropagation&&!o&&e.stopPropagation(),this.keys[t]||(this.keys[t]={pressed:!1,justPressed:!1,justReleased:!1}),this.keys[t].pressed||(this.keys[t].justPressed=!0,this.keyboardCallbacks.onKeyDown?.(t,e)),this.keys[t].pressed=!0,this.keys[t].justReleased=!1;let n=e.key;n.length===1&&!e.ctrlKey&&!e.metaKey&&this.textInputsThisFrame.push(n)}catch(t){console.error("Error in keyboard keydown handler:",t)}}handleKeyUp(e){try{let t=e.code,o=this.shouldAllowDefault(t,e);this.config.preventDefault&&!o&&e.preventDefault(),this.config.stopPropagation&&!o&&e.stopPropagation(),this.keys[t]||(this.keys[t]={pressed:!1,justPressed:!1,justReleased:!1}),this.keys[t].pressed&&(this.keys[t].justReleased=!0,this.keyboardCallbacks.onKeyUp?.(t,e)),this.keys[t].pressed=!1,this.keys[t].justPressed=!1}catch(t){console.error("Error in keyboard keyup handler:",t)}}};p(H,"KeyboardInputs");var E=H;function re(c,s){let e=new E(c);return s&&e.setCallbacks(s),e.start(),e}p(re,"useKeyboardInputs");import{Vector2 as k}from"@utsp/types";var P=class P extends y{constructor(e=window,t={}){super(e,t);r(this,"mouseButtons",{left:{pressed:!1,justPressed:!1,justReleased:!1},middle:{pressed:!1,justPressed:!1,justReleased:!1},right:{pressed:!1,justPressed:!1,justReleased:!1}});r(this,"mousePosition",k.zero());r(this,"mouseDelta",k.zero());r(this,"wheelDelta",0);r(this,"mouseCallbacks",{});r(this,"boundHandlers");this.boundHandlers={mouseDown:this.handleMouseDown.bind(this),mouseUp:this.handleMouseUp.bind(this),mouseMove:this.handleMouseMove.bind(this),wheel:this.handleWheel.bind(this),mouseEnter:this.handleMouseEnter.bind(this),mouseLeave:this.handleMouseLeave.bind(this),contextMenu:this.handleContextMenu.bind(this)}}start(){this.isActive||(this.targetElement.addEventListener("mousedown",this.boundHandlers.mouseDown),this.targetElement.addEventListener("mouseup",this.boundHandlers.mouseUp),this.targetElement.addEventListener("mousemove",this.boundHandlers.mouseMove),this.targetElement.addEventListener("wheel",this.boundHandlers.wheel),this.targetElement.addEventListener("mouseenter",this.boundHandlers.mouseEnter),this.targetElement.addEventListener("mouseleave",this.boundHandlers.mouseLeave),this.targetElement.addEventListener("contextmenu",this.boundHandlers.contextMenu),this.isActive=!0)}stop(){this.isActive&&(this.targetElement.removeEventListener("mousedown",this.boundHandlers.mouseDown),this.targetElement.removeEventListener("mouseup",this.boundHandlers.mouseUp),this.targetElement.removeEventListener("mousemove",this.boundHandlers.mouseMove),this.targetElement.removeEventListener("wheel",this.boundHandlers.wheel),this.targetElement.removeEventListener("mouseenter",this.boundHandlers.mouseEnter),this.targetElement.removeEventListener("mouseleave",this.boundHandlers.mouseLeave),this.targetElement.removeEventListener("contextmenu",this.boundHandlers.contextMenu),this.isActive=!1)}reset(){this.mouseButtons={left:{pressed:!1,justPressed:!1,justReleased:!1},middle:{pressed:!1,justPressed:!1,justReleased:!1},right:{pressed:!1,justPressed:!1,justReleased:!1}},this.mousePosition=k.zero(),this.mouseDelta=k.zero(),this.wheelDelta=0}poll(){this.mouseButtons.left.justPressed=!1,this.mouseButtons.left.justReleased=!1,this.mouseButtons.middle.justPressed=!1,this.mouseButtons.middle.justReleased=!1,this.mouseButtons.right.justPressed=!1,this.mouseButtons.right.justReleased=!1,this.resetDelta()}resetDelta(){this.mouseDelta=k.zero(),this.wheelDelta=0}isLeftMousePressed(){return this.mouseButtons.left.pressed}isLeftMouseJustPressed(){return this.mouseButtons.left.justPressed}isLeftMouseJustReleased(){return this.mouseButtons.left.justReleased}isRightMousePressed(){return this.mouseButtons.right.pressed}isRightMouseJustPressed(){return this.mouseButtons.right.justPressed}isRightMouseJustReleased(){return this.mouseButtons.right.justReleased}isMiddleMousePressed(){return this.mouseButtons.middle.pressed}isMiddleMouseJustPressed(){return this.mouseButtons.middle.justPressed}isMiddleMouseJustReleased(){return this.mouseButtons.middle.justReleased}getMousePosition(){return this.mousePosition.clone()}getMouseDelta(){return this.mouseDelta.clone()}getWheelDelta(){return this.wheelDelta}setMouseCallbacks(e){this.mouseCallbacks={...this.mouseCallbacks,...e}}clearMouseCallbacks(){this.mouseCallbacks={}}setCallbacks(e){this.isMouseCallbacks(e)&&this.setMouseCallbacks(e)}isMouseCallbacks(e){return typeof e=="object"&&e!==null&&("onMouseDown"in e||"onMouseUp"in e||"onMouseMove"in e||"onMouseWheel"in e||"onMouseEnter"in e||"onMouseLeave"in e)}getButtonByIndex(e){let t=P.BUTTON_NAMES[e];return t?{state:this.mouseButtons[t],name:t}:null}handleMouseDown(e){try{this.config.preventDefault&&e.preventDefault(),this.config.stopPropagation&&e.stopPropagation();let t=this.getButtonByIndex(e.button);t&&(t.state.pressed||(t.state.justPressed=!0),t.state.pressed=!0,t.state.justReleased=!1,this.mouseCallbacks.onMouseDown?.(t.name,this.mousePosition,e))}catch(t){console.error("Error in mouse down handler:",t)}}handleMouseUp(e){try{this.config.preventDefault&&e.preventDefault(),this.config.stopPropagation&&e.stopPropagation();let t=this.getButtonByIndex(e.button);t&&(t.state.pressed&&(t.state.justReleased=!0),t.state.pressed=!1,t.state.justPressed=!1,this.mouseCallbacks.onMouseUp?.(t.name,this.mousePosition,e))}catch(t){console.error("Error in mouse up handler:",t)}}handleMouseMove(e){try{this.config.preventDefault&&e.preventDefault(),this.config.stopPropagation&&e.stopPropagation();let t=new k(e.clientX,e.clientY);this.mouseDelta=t.subtract(this.mousePosition),this.mousePosition=t,this.mouseCallbacks.onMouseMove?.(this.mousePosition,this.mouseDelta,e)}catch(t){console.error("Error in mouse move handler:",t)}}handleWheel(e){try{this.config.preventDefault&&e.preventDefault(),this.config.stopPropagation&&e.stopPropagation(),this.wheelDelta=e.deltaY,this.mouseCallbacks.onMouseWheel?.(this.wheelDelta,e)}catch(t){console.error("Error in mouse wheel handler:",t)}}handleMouseEnter(e){try{this.mouseCallbacks.onMouseEnter?.(e)}catch(t){console.error("Error in mouse enter handler:",t)}}handleMouseLeave(e){try{this.mouseCallbacks.onMouseLeave?.(e)}catch(t){console.error("Error in mouse leave handler:",t)}}handleContextMenu(e){try{e.preventDefault(),this.config.stopPropagation&&e.stopPropagation()}catch(t){console.error("Error in context menu handler:",t)}}};p(P,"MouseInputs"),r(P,"BUTTON_NAMES",["left","middle","right"]);var I=P;function ue(c,s){let e=new I(c);return s&&e.setCallbacks(s),e.start(),e}p(ue,"useMouseInputs");import{Vector2 as Q}from"@utsp/types";var j=class j extends y{constructor(e=window,t={}){super(e,t);r(this,"touches",new Map);r(this,"nativeToInternal",new Map);r(this,"mobileCallbacks",{});r(this,"mobileConfig");r(this,"maxTouches",10);r(this,"lastLogTime",0);r(this,"boundHandlers");this.mobileConfig={targetElement:e,preventDefault:t.preventDefault??!0,passive:t.passive??!1,maxTouches:t.maxTouches??10,enabled:t.enabled??!0,debug:t.debug??!1,stopPropagation:t.stopPropagation??!1},this.maxTouches=this.mobileConfig.maxTouches,this.mobileConfig.preventDefault&&this.mobileConfig.passive&&(console.warn("[MobileInputs] passive=true prevents preventDefault() from working! Setting passive=false."),this.mobileConfig.passive=!1),this.boundHandlers={touchStart:this.handleTouchStart.bind(this),touchEnd:this.handleTouchEnd.bind(this),touchMove:this.handleTouchMove.bind(this),touchCancel:this.handleTouchCancel.bind(this),orientationChange:this.handleOrientationChange.bind(this)}}start(){if(this.isActive)return;let e={passive:!this.mobileConfig.preventDefault&&this.mobileConfig.passive};this.targetElement.addEventListener("touchstart",this.boundHandlers.touchStart,e),this.targetElement.addEventListener("touchend",this.boundHandlers.touchEnd,e),this.targetElement.addEventListener("touchmove",this.boundHandlers.touchMove,e),this.targetElement.addEventListener("touchcancel",this.boundHandlers.touchCancel,e),window.addEventListener("orientationchange",this.boundHandlers.orientationChange),this.isActive=!0}stop(){this.isActive&&(this.targetElement.removeEventListener("touchstart",this.boundHandlers.touchStart),this.targetElement.removeEventListener("touchend",this.boundHandlers.touchEnd),this.targetElement.removeEventListener("touchmove",this.boundHandlers.touchMove),this.targetElement.removeEventListener("touchcancel",this.boundHandlers.touchCancel),window.removeEventListener("orientationchange",this.boundHandlers.orientationChange),this.isActive=!1)}reset(){this.touches.clear(),this.nativeToInternal.clear()}resetDelta(){}poll(){for(let e of this.touches.values())e.justTouched=!1,e.justReleased=!1}isTouchActive(e){return e<0||e>=this.maxTouches?!1:this.touches.has(e)}getTouchPosition(e){if(e<0||e>=this.maxTouches)return null;let t=this.touches.get(e);return t?t.position.clone():null}getTouchStartPosition(e){if(e<0||e>=this.maxTouches)return null;let t=this.touches.get(e);return t?t.startPosition.clone():null}getTouchDelta(e){if(e<0||e>=this.maxTouches)return null;let t=this.touches.get(e);return t?t.position.subtract(t.startPosition):null}getTouchCount(){return this.touches.size}isTouchJustStarted(e){if(e<0||e>=this.maxTouches)return!1;let t=this.touches.get(e);return t?t.justTouched:!1}isTouchJustReleased(e){if(e<0||e>=this.maxTouches)return!1;let t=this.touches.get(e);return t?t.justReleased:!1}isAnyTouchJustStarted(){for(let e of this.touches.values())if(e.justTouched)return!0;return!1}getAllTouches(){return Array.from(this.touches.values())}setMobileCallbacks(e){this.mobileCallbacks={...this.mobileCallbacks,...e}}clearMobileCallbacks(){this.mobileCallbacks={}}setCallbacks(e){this.isMobileCallbacks(e)&&this.setMobileCallbacks(e)}isMobileCallbacks(e){return typeof e=="object"&&e!==null&&("onTouchStart"in e||"onTouchEnd"in e||"onTouchMove"in e||"onTouchCancel"in e||"onOrientationChange"in e)}handleTouchStart(e){try{this.mobileConfig.preventDefault&&e.preventDefault();let t=Array.from(e.changedTouches),o=[];for(let n of t){if(this.touches.size>=this.maxTouches)break;let i=-1;for(let l=0;l<this.maxTouches;l++)if(!this.touches.has(l)){i=l;break}if(i===-1)continue;let a=new Q(n.clientX,n.clientY),d={id:i,nativeId:n.identifier,position:a.clone(),startPosition:a.clone(),active:!0,justTouched:!0,justReleased:!1};this.touches.set(i,d),this.nativeToInternal.set(n.identifier,i),o.push(d),console.warn(`\u{1F446} Touch START - ID: ${i}`)}this.mobileCallbacks.onTouchStart?.(o,e)}catch(t){console.error("Error in touch start handler:",t)}}handleTouchEnd(e){try{this.mobileConfig.preventDefault&&e.preventDefault();let t=Array.from(e.changedTouches),o=[];for(let n of t){let i=this.nativeToInternal.get(n.identifier);if(i!==void 0){let a=this.touches.get(i);a&&(a.justReleased=!0,a.justTouched=!1,o.push({...a}))}}for(let n of t){let i=this.nativeToInternal.get(n.identifier);i!==void 0&&(this.touches.delete(i),this.nativeToInternal.delete(n.identifier),console.warn(`\u{1F447} Touch END - ID: ${i}`))}this.mobileCallbacks.onTouchEnd?.(o,e)}catch(t){console.error("Error in touch end handler:",t)}}handleTouchMove(e){try{let t=Array.from(e.changedTouches);this.mobileConfig.debug&&(!this.lastLogTime||Date.now()-this.lastLogTime>200)&&(console.warn(`\u{1F504} TouchMove event - ${t.length} touches changed`),this.lastLogTime=Date.now());for(let o of t){let n=this.nativeToInternal.get(o.identifier);if(n!==void 0){let i=this.touches.get(n);if(i){let a=i.position.clone();i.position=new Q(o.clientX,o.clientY),this.mobileConfig.debug&&(!this.lastLogTime||Date.now()-this.lastLogTime>200)&&console.warn(`\u{1F504} Updated touch ${i.id} (native ${o.identifier}) - ${a.x.toFixed(1)},${a.y.toFixed(1)} \u2192 ${o.clientX.toFixed(1)},${o.clientY.toFixed(1)}`)}}else this.mobileConfig.debug&&console.warn(`\u26A0\uFE0F Touch move for unknown native ID ${o.identifier}`)}this.mobileCallbacks.onTouchMove?.(this.getAllTouches(),e)}catch(t){console.error("Error in touch move handler:",t)}}handleTouchCancel(e){try{this.mobileConfig.preventDefault&&e.preventDefault();let t=[],o=Array.from(e.changedTouches);for(let n of o){let i=this.nativeToInternal.get(n.identifier);if(i!==void 0){let a=this.touches.get(i);a&&(a.justReleased=!0,a.justTouched=!1,t.push({...a}))}}for(let n of o){let i=this.nativeToInternal.get(n.identifier);i!==void 0&&(this.touches.delete(i),this.nativeToInternal.delete(n.identifier),this.mobileConfig.debug&&console.warn(`\u274C Touch CANCEL - ID: ${i}, nativeId: ${n.identifier}`))}this.mobileCallbacks.onTouchCancel?.(t,e)}catch(t){console.error("Error in touch cancel handler:",t)}}handleOrientationChange(e){try{let t=(window.screen.orientation&&window.screen.orientation.angle)??window.orientation??0;this.mobileCallbacks.onOrientationChange?.(t)}catch(t){console.error("Error in orientation change handler:",t)}}};p(j,"MobileInputs");var w=j;function le(c,s,e){console.warn("[MobileInputs] useMobileInputs() is deprecated and causes memory leaks. Use useMemo + useEffect instead.");let t=new w(c,e);return s&&t.setCallbacks(s),t.start(),t}p(le,"useMobileInputs");var v={tap:10,mediumTap:25,heavyTap:50,success:[30,50,30],error:[50,30,50,30,50],warning:[100],selection:5,impactLight:15,impactMedium:30,impactHeavy:50,notification:[100,100,100,100,100],sos:[100,30,100,30,100,30,200,30,200,30,200,30,100,30,100,30,100]},J=class J{constructor(s={}){r(this,"config");r(this,"supported",!1);r(this,"userActivated",!1);this.config={enabled:s.enabled??!0,debug:s.debug??!1,intensity:Math.max(0,Math.min(1,s.intensity??1))},this.supported=typeof navigator<"u"&&"vibrate"in navigator,this.config.debug&&console.log(`[MobileVibration] Vibration API supported: ${this.supported}`)}isSupported(){return this.supported}isEnabled(){return this.config.enabled&&this.supported}setEnabled(s){this.config.enabled=s,this.config.debug&&console.log(`[MobileVibration] Enabled: ${s}`)}setIntensity(s){this.config.intensity=Math.max(0,Math.min(1,s)),this.config.debug&&console.log(`[MobileVibration] Intensity set to: ${this.config.intensity}`)}getIntensity(){return this.config.intensity}vibrate(s){if(!this.isEnabled())return!1;try{let e=this.scalePattern(s),t=typeof e=="number"?e:[...e],o=navigator.vibrate(t);return this.config.debug&&console.log(`[MobileVibration] Vibrate: ${JSON.stringify(e)} -> ${o}`),o&&(this.userActivated=!0),o}catch(e){return this.config.debug&&console.error("[MobileVibration] Vibration failed:",e),!1}}cancel(){this.supported&&(navigator.vibrate(0),this.config.debug&&console.log("[MobileVibration] Vibration cancelled"))}hasUserActivation(){return this.userActivated}tap(){return this.vibrate(v.tap)}mediumTap(){return this.vibrate(v.mediumTap)}heavyTap(){return this.vibrate(v.heavyTap)}success(){return this.vibrate(v.success)}error(){return this.vibrate(v.error)}warning(){return this.vibrate(v.warning)}selection(){return this.vibrate(v.selection)}impactLight(){return this.vibrate(v.impactLight)}impactMedium(){return this.vibrate(v.impactMedium)}impactHeavy(){return this.vibrate(v.impactHeavy)}notification(){return this.vibrate(v.notification)}scalePattern(s){return this.config.intensity===1?s:typeof s=="number"?Math.round(s*this.config.intensity):s.map((e,t)=>t%2===0?Math.round(e*this.config.intensity):e)}};p(J,"MobileVibration");var D=J,$=null;function de(){return $||($=new D),$}p(de,"getMobileVibration");var ce=.01,W=class W extends y{constructor(e={}){super(window,e);r(this,"gamepads",new Map);r(this,"previousGamepads",new Map);r(this,"gamepadCallbacks",{});r(this,"gamepadConfig");r(this,"pollingIntervalId",null);r(this,"rafId",null);r(this,"boundHandlers");r(this,"vibrationPresets",{tap:{duration:50,strongMagnitude:.3,weakMagnitude:.5},impact:{duration:100,strongMagnitude:.7,weakMagnitude:.3},heavy:{duration:200,strongMagnitude:1,weakMagnitude:.2},success:{duration:150,strongMagnitude:.4,weakMagnitude:.6},error:{duration:300,strongMagnitude:.8,weakMagnitude:.4},explosion:{duration:400,strongMagnitude:1,weakMagnitude:.8},engine:{duration:1e3,strongMagnitude:.5,weakMagnitude:.2},heartbeat:{duration:100,strongMagnitude:.6,weakMagnitude:.1}});this.gamepadConfig={targetElement:window,maxGamepads:e.maxGamepads??4,axisDeadzone:e.axisDeadzone??.1,pollingInterval:e.pollingInterval??16,autoPolling:e.autoPolling??!0,enabled:e.enabled??!0,debug:e.debug??!1,preventDefault:e.preventDefault??!1,stopPropagation:e.stopPropagation??!1},this.boundHandlers={connected:this.handleGamepadConnected.bind(this),disconnected:this.handleGamepadDisconnected.bind(this)}}start(){this.isActive||(window.addEventListener("gamepadconnected",this.boundHandlers.connected),window.addEventListener("gamepaddisconnected",this.boundHandlers.disconnected),this.gamepadConfig.autoPolling&&this.startPolling(),this.isActive=!0,this.log("GamepadInputs started"))}stop(){this.isActive&&(window.removeEventListener("gamepadconnected",this.boundHandlers.connected),window.removeEventListener("gamepaddisconnected",this.boundHandlers.disconnected),this.stopPolling(),this.isActive=!1,this.log("GamepadInputs stopped"))}reset(){this.gamepads.clear(),this.previousGamepads.clear()}resetDelta(){this.previousGamepads.clear(),this.gamepads.forEach((e,t)=>{this.previousGamepads.set(t,this.cloneGamepadState(e))})}startPolling(){if(this.pollingIntervalId!==null||this.rafId!==null)return;let e=p(()=>{this.poll(),this.rafId=requestAnimationFrame(e)},"poll");this.rafId=requestAnimationFrame(e),this.log("Polling started")}stopPolling(){this.rafId!==null&&(cancelAnimationFrame(this.rafId),this.rafId=null),this.pollingIntervalId!==null&&(clearInterval(this.pollingIntervalId),this.pollingIntervalId=null),this.log("Polling stopped")}poll(){let e=navigator.getGamepads?navigator.getGamepads():[];for(let t=0;t<e.length&&t<this.gamepadConfig.maxGamepads;t++){let o=e[t];o&&this.updateGamepadState(o)}}getConnectedGamepadCount(){return this.gamepads.size}isGamepadConnected(e){return this.gamepads.has(e)&&this.gamepads.get(e).connected}getGamepadState(e){return this.gamepads.get(e)||null}getAllGamepads(){return Array.from(this.gamepads.values()).filter(e=>e.connected)}isButtonPressed(e,t){if(!Number.isInteger(e)||e<0)throw new Error(`Invalid gamepadIndex: ${e}. Must be a non-negative integer.`);if(!Number.isInteger(t)||t<0)throw new Error(`Invalid buttonIndex: ${t}. Must be a non-negative integer.`);let o=this.gamepads.get(e);return!o||!o.connected||t>=o.buttons.length?!1:o.buttons[t].pressed}isButtonJustPressed(e,t){if(!Number.isInteger(e)||e<0)throw new Error(`Invalid gamepadIndex: ${e}. Must be a non-negative integer.`);if(!Number.isInteger(t)||t<0)throw new Error(`Invalid buttonIndex: ${t}. Must be a non-negative integer.`);let o=this.gamepads.get(e);return!o||!o.connected||t>=o.buttons.length?!1:o.buttons[t].justPressed}isButtonJustReleased(e,t){if(!Number.isInteger(e)||e<0)throw new Error(`Invalid gamepadIndex: ${e}. Must be a non-negative integer.`);if(!Number.isInteger(t)||t<0)throw new Error(`Invalid buttonIndex: ${t}. Must be a non-negative integer.`);let o=this.gamepads.get(e);return!o||!o.connected||t>=o.buttons.length?!1:o.buttons[t].justReleased}getButtonValue(e,t){if(!Number.isInteger(e)||e<0)throw new Error(`Invalid gamepadIndex: ${e}. Must be a non-negative integer.`);if(!Number.isInteger(t)||t<0)throw new Error(`Invalid buttonIndex: ${t}. Must be a non-negative integer.`);let o=this.gamepads.get(e);return!o||!o.connected||t>=o.buttons.length?0:o.buttons[t].value}getAxis(e,t){if(!Number.isInteger(e)||e<0)throw new Error(`Invalid gamepadIndex: ${e}. Must be a non-negative integer.`);if(!Number.isInteger(t)||t<0)throw new Error(`Invalid axisIndex: ${t}. Must be a non-negative integer.`);let o=this.gamepads.get(e);if(!o||!o.connected||t>=o.axes.length)return 0;let n=o.axes[t];return this.applyDeadzone(n)}getAxisRaw(e,t){if(!Number.isInteger(e)||e<0)throw new Error(`Invalid gamepadIndex: ${e}. Must be a non-negative integer.`);if(!Number.isInteger(t)||t<0)throw new Error(`Invalid axisIndex: ${t}. Must be a non-negative integer.`);let o=this.gamepads.get(e);return!o||!o.connected||t>=o.axes.length?0:o.axes[t]}getLeftStick(e){return{x:this.getAxis(e,0),y:this.getAxis(e,1)}}getRightStick(e){return{x:this.getAxis(e,2),y:this.getAxis(e,3)}}supportsVibration(e){let t=this.getNativeGamepad(e);if(!t)return!1;let o=t.vibrationActuator;if(o&&typeof o.playEffect=="function")return!0;let n=t.hapticActuators;return!!(n&&n.length>0)}async vibrate(e,t){let o=this.getNativeGamepad(e);if(!o)return this.log(`Vibrate failed: gamepad ${e} not found`),!1;let{duration:n,strongMagnitude:i=1,weakMagnitude:a=.5,startDelay:d=0}=t;try{let l=o.vibrationActuator;if(l&&typeof l.playEffect=="function"){let f=await l.playEffect("dual-rumble",{startDelay:d,duration:n,strongMagnitude:Math.min(1,Math.max(0,i)),weakMagnitude:Math.min(1,Math.max(0,a))});return this.log(`Vibration effect result: ${f}`),f==="complete"}let m=o.hapticActuators;if(m&&m.length>0){let f=Math.max(i,a);return await m[0].pulse(f,n),!0}return this.log(`Vibrate failed: gamepad ${e} does not support vibration`),!1}catch(l){return this.log("Vibrate error:",l),!1}}async stopVibration(e){let t=this.getNativeGamepad(e);if(!t)return!1;try{let o=t.vibrationActuator;return o&&typeof o.reset=="function"?(await o.reset(),!0):o&&typeof o.playEffect=="function"?(await o.playEffect("dual-rumble",{duration:0,strongMagnitude:0,weakMagnitude:0}),!0):!1}catch(o){return this.log("Stop vibration error:",o),!1}}async stopAllVibrations(){let e=[];for(let[t]of this.gamepads)e.push(this.stopVibration(t));await Promise.all(e)}async vibrateAll(e){let t=[];for(let[o]of this.gamepads)t.push(this.vibrate(o,e));await Promise.all(t)}async vibratePreset(e,t){let o=this.vibrationPresets[t];return o?this.vibrate(e,o):(this.log(`Unknown vibration preset: ${t}`),!1)}getNativeGamepad(e){return(navigator.getGamepads?navigator.getGamepads():[])[e]||null}setGamepadCallbacks(e){this.gamepadCallbacks={...this.gamepadCallbacks,...e}}clearGamepadCallbacks(){this.gamepadCallbacks={}}setCallbacks(e){this.isGamepadCallbacks(e)&&this.setGamepadCallbacks(e)}isGamepadCallbacks(e){return typeof e=="object"&&e!==null&&("onGamepadConnected"in e||"onGamepadDisconnected"in e||"onButtonDown"in e||"onButtonUp"in e||"onAxisMove"in e)}updateGamepadState(e){let t=this.gamepads.get(e.index),o=Array.from(e.buttons).map((a,d)=>{let l=t?.buttons[d],m=a.pressed,f=l?.pressed??!1;return{pressed:m,justPressed:m&&!f,justReleased:!m&&f,value:a.value,touched:a.touched??!1}}),n=Array.from(e.axes),i={id:e.id,index:e.index,connected:e.connected,buttons:o,axes:n,timestamp:e.timestamp,mapping:e.mapping};this.gamepads.set(e.index,i),this.triggerCallbacks(i,t)}triggerCallbacks(e,t){try{e.buttons.forEach((o,n)=>{o.justPressed&&this.gamepadCallbacks.onButtonDown?.(e.index,n,o.value),o.justReleased&&this.gamepadCallbacks.onButtonUp?.(e.index,n)}),e.axes.forEach((o,n)=>{let i=t?.axes[n]??0,a=this.applyDeadzone(o),d=this.applyDeadzone(i);Math.abs(a-d)>ce&&this.gamepadCallbacks.onAxisMove?.(e.index,n,a)})}catch(o){this.log("Error in gamepad callbacks:",o)}}handleGamepadConnected(e){try{this.log(`Gamepad connected: ${e.gamepad.id} at index ${e.gamepad.index}`);let t={id:e.gamepad.id,index:e.gamepad.index,connected:!0,buttons:Array.from(e.gamepad.buttons).map(o=>({pressed:o.pressed,justPressed:!1,justReleased:!1,value:o.value,touched:o.touched??!1})),axes:Array.from(e.gamepad.axes),timestamp:e.gamepad.timestamp,mapping:e.gamepad.mapping};this.gamepads.set(e.gamepad.index,t),this.gamepadCallbacks.onGamepadConnected?.(t)}catch(t){this.log("Error handling gamepad connected:",t)}}handleGamepadDisconnected(e){try{this.log(`Gamepad disconnected at index ${e.gamepad.index}`),this.gamepads.delete(e.gamepad.index),this.previousGamepads.delete(e.gamepad.index),this.gamepadCallbacks.onGamepadDisconnected?.(e.gamepad.index)}catch(t){this.log("Error handling gamepad disconnected:",t)}}applyDeadzone(e){let t=this.gamepadConfig.axisDeadzone;return Math.abs(e)<t?0:(e>0?1:-1)*((Math.abs(e)-t)/(1-t))}cloneGamepadState(e){return{...e,buttons:e.buttons.map(t=>({...t})),axes:[...e.axes]}}};p(W,"GamepadInputs");var C=W;function pe(c,s){let e=new C(s);return c&&e.setGamepadCallbacks(c),e.start(),e}p(pe,"useGamepadInputs");import{InputDeviceType as b,KeyboardInput as U,MouseInput as g,isButton as X,isAxis as he}from"@utsp/types";var z=class z{constructor(s={}){r(this,"keyboard",null);r(this,"mouse",null);r(this,"gamepad",null);r(this,"mobile",null);r(this,"config");this.config={enableKeyboardMouse:s.enableKeyboardMouse??!0,enableGamepad:s.enableGamepad??!0,enableMobile:s.enableMobile??!1,targetElement:s.targetElement??window,mobileTargetElement:s.mobileTargetElement??s.targetElement??window,debug:s.debug??!1,keyboardConfig:{preventDefault:!1,stopPropagation:!1,...s.keyboardConfig},mouseConfig:{preventDefault:!1,stopPropagation:!1,...s.mouseConfig},mobileConfig:{preventDefault:!0,passive:!1,maxTouches:10,...s.mobileConfig}},this.initialize()}initialize(){this.config.enableKeyboardMouse&&(this.keyboard=new E(this.config.targetElement,{preventDefault:this.config.keyboardConfig?.preventDefault??!1,stopPropagation:this.config.keyboardConfig?.stopPropagation??!1,debug:this.config.debug}),this.keyboard.start(),this.mouse=new I(this.config.targetElement,{preventDefault:this.config.mouseConfig?.preventDefault??!1,stopPropagation:this.config.mouseConfig?.stopPropagation??!1,debug:this.config.debug}),this.mouse.start(),this.log("Keyboard/Mouse initialized")),this.config.enableGamepad&&(this.gamepad=new C({debug:this.config.debug}),this.gamepad.start(),this.log("Gamepad initialized")),this.config.enableMobile&&(this.config.mobileTargetElement?(this.mobile=new w(this.config.mobileTargetElement,this.config.mobileConfig),this.mobile.start(),this.log("Mobile/Touch initialized")):this.warn("Mobile input enabled but no canvas provided - mobile input will be disabled until setMobileTarget() is called"))}getButton(s,e){if(!X({device:s,input:e}))return this.warn(`Input ${e} on device ${s} is not a button`),!1;switch(s){case b.Keyboard:return this.getKeyboardButton(e);case b.Mouse:return this.getMouseButton(e);case b.Gamepad:return this.getGamepadButton(e);case b.Touch:return this.getTouchButton(e);default:return this.warn(`Unknown device type: ${s}`),!1}}getButtonJustPressed(s,e){if(!X({device:s,input:e}))return this.warn(`Input ${e} on device ${s} is not a button`),!1;switch(s){case b.Keyboard:return this.getKeyboardButtonJustPressed(e);case b.Mouse:return this.getMouseButtonJustPressed(e);case b.Gamepad:return this.getGamepadButtonJustPressed(e);case b.Touch:return this.getTouchButtonJustPressed(e);default:return this.warn(`Unknown device type: ${s}`),!1}}getButtonJustReleased(s,e){if(!X({device:s,input:e}))return this.warn(`Input ${e} on device ${s} is not a button`),!1;switch(s){case b.Keyboard:return this.getKeyboardButtonJustReleased(e);case b.Mouse:return this.getMouseButtonJustReleased(e);case b.Gamepad:return this.getGamepadButtonJustReleased(e);case b.Touch:return this.getTouchButtonJustReleased(e);default:return this.warn(`Unknown device type: ${s}`),!1}}getAxis(s,e){if(!he({device:s,input:e}))return this.warn(`Input ${e} on device ${s} is not an axis`),0;switch(s){case b.Keyboard:return this.warn("Keyboard does not have axis inputs"),0;case b.Mouse:return this.getMouseAxis(e);case b.Gamepad:return this.getGamepadAxis(e);case b.Touch:return this.getTouchAxis(e);default:return this.warn(`Unknown device type: ${s}`),0}}isLeftMousePressed(){return this.mouse?this.mouse.isLeftMousePressed():!1}getKeyboardButton(s){if(!this.keyboard)return!1;let e=U[s];return this.keyboard.isKeyPressed(e)}getKeyboardButtonJustPressed(s){if(!this.keyboard)return!1;let e=U[s];return this.keyboard.isKeyJustPressed(e)}getKeyboardButtonJustReleased(s){if(!this.keyboard)return!1;let e=U[s];return this.keyboard.isKeyJustReleased(e)}getMouseButton(s){if(!this.mouse)return!1;switch(s){case g.LeftButton:return this.mouse.isLeftMousePressed();case g.RightButton:return this.mouse.isRightMousePressed();case g.MiddleButton:return this.mouse.isMiddleMousePressed();default:return!1}}getMouseButtonJustPressed(s){if(!this.mouse)return!1;switch(s){case g.LeftButton:return this.mouse.isLeftMouseJustPressed();case g.RightButton:return this.mouse.isRightMouseJustPressed();case g.MiddleButton:return this.mouse.isMiddleMouseJustPressed();default:return!1}}getMouseButtonJustReleased(s){if(!this.mouse)return!1;switch(s){case g.LeftButton:return this.mouse.isLeftMouseJustReleased();case g.RightButton:return this.mouse.isRightMouseJustReleased();case g.MiddleButton:return this.mouse.isMiddleMouseJustReleased();default:return!1}}getGamepadButton(s){return!this.gamepad||s>=100?!1:this.gamepad.isButtonPressed(0,s)}getGamepadButtonJustPressed(s){return!this.gamepad||s>=100?!1:this.gamepad.isButtonJustPressed(0,s)}getGamepadButtonJustReleased(s){return!this.gamepad||s>=100?!1:this.gamepad.isButtonJustReleased(0,s)}getTouchButton(s){return this.mobile?s>=100?!1:this.mobile.isTouchActive?.(s)??!1:(console.warn("\u{1F6AB} MobileInputs not initialized!"),!1)}getTouchButtonJustPressed(s){return!this.mobile||s>=100?!1:this.mobile.isTouchJustStarted?.(s)??!1}getTouchButtonJustReleased(s){return!this.mobile||s>=100?!1:this.mobile.isTouchJustReleased?.(s)??!1}getMouseAxis(s){if(!this.mouse)return 0;switch(s){case g.PositionX:return this.mouse.getMousePosition().x;case g.PositionY:return this.mouse.getMousePosition().y;case g.DeltaX:return this.mouse.getMouseDelta().x;case g.DeltaY:return this.mouse.getMouseDelta().y;case g.WheelDeltaY:return this.mouse.getWheelDelta();default:return 0}}getGamepadAxis(s){if(!this.gamepad||s<100)return 0;let e=s-100;return this.gamepad.getAxis(0,e)}getTouchAxis(s){if(!this.mobile)return 0;if(s>=100&&s<200){let e=Math.floor((s-100)/2),t=(s-100)%2===0,o=this.mobile.getTouchPosition?.(e);return this.config.debug&&o&&console.warn(`\u{1F3AF} getTouchAxis(${s}) - touchIndex: ${e}, ${t?"X":"Y"}: ${t?o.x:o.y}`),o?t?o.x:o.y:0}return 0}getMousePosition(){if(!this.mouse)return null;let s=this.mouse.getMousePosition();return{x:s.x,y:s.y}}setMobileTarget(s){if(!s){this.warn("setMobileTarget() called with null/undefined canvas - mobile input will remain disabled");return}if(this.config.mobileTargetElement=s,!this.config.enableMobile){this.warn("setMobileTarget() called but mobile input is disabled in config");return}this.mobile&&this.mobile.stop(),this.mobile=new w(s,this.config.mobileConfig),this.mobile.start()}getTextInputs(){return this.keyboard?this.keyboard.getTextInputs():[]}start(){this.keyboard?.start(),this.mouse?.start(),this.log("Input router started")}stop(){this.keyboard?.stop(),this.mouse?.stop(),this.log("Input router stopped")}reset(){this.keyboard?.reset(),this.mouse?.reset(),this.log("Input router reset")}poll(){this.keyboard?.poll(),this.mouse?.poll(),this.gamepad?.poll(),this.mobile?.poll()}isListening(){return this.keyboard!==null&&this.config.enableKeyboardMouse||this.gamepad!==null&&this.config.enableGamepad||this.mobile!==null&&this.config.enableMobile}getGamepad(){return this.gamepad}getKeyboard(){return this.keyboard}getMouse(){return this.mouse}getMobile(){return this.mobile}destroy(){this.keyboard?.destroy(),this.mouse?.destroy(),this.keyboard=null,this.mouse=null,this.gamepad=null,this.mobile=null,this.log("Input router destroyed")}log(s){this.config.debug&&console.warn(`[InputRouter] ${s}`)}warn(s){console.warn(`[InputRouter] ${s}`)}};p(z,"UnifiedInputRouter");var Y=z;import{InputDeviceType as u,MouseInput as Z}from"@utsp/types";var _=100,ee=2,x=class x{static calculateRenderMetrics(s,e){let t=s.getBoundingClientRect(),o=s.width/s.height,n=t.width/t.height,i,a,d,l;o>n?(i=t.width,a=t.width/o,d=0,l=(t.height-a)/2):(i=t.height*o,a=t.height,d=(t.width-i)/2,l=0);let m=e?.offsetX||0,f=e?.offsetY||0;return d+=m,l+=f,i-=m*2,a-=f*2,{renderWidth:i,renderHeight:a,offsetX:d,offsetY:l,rect:t}}static collectAxisSources(s,e){let t=new Map;for(let o of s)for(let n of o.sources){if(t.has(n.sourceId))continue;let i=0,a=!1;if(n.type===u.Keyboard&&n.negativeKey!==void 0&&n.positiveKey!==void 0){let d=e.getButton(u.Keyboard,n.negativeKey);e.getButton(u.Keyboard,n.positiveKey)&&(i+=1),d&&(i-=1),a=!0}else if(n.type===u.Mouse&&n.mouseAxis!==void 0)i=e.getAxis(u.Mouse,n.mouseAxis),a=!0;else if(n.type===u.Gamepad&&n.axis!==void 0)i=e.getAxis(u.Gamepad,n.axis),a=!0;else if(n.type===u.Touch&&n.touchId!==void 0&&n.touchAxis!==void 0){let d=100+n.touchId*2,l=n.touchAxis==="x"?d:d+1;i=e.getAxis(u.Touch,l),a=!0}a&&t.set(n.sourceId,i)}return t}static collectButtonSources(s,e){let t=new Map;for(let o of s)for(let n of o.sources){if(t.has(n.sourceId))continue;let i=!1,a=!1;n.type===u.Keyboard&&n.key!==void 0?(i=e.getButton(u.Keyboard,n.key),a=!0):n.type===u.Mouse&&n.mouseButton!==void 0?(i=e.getButton(u.Mouse,n.mouseButton),a=!0):n.type===u.Gamepad&&n.button!==void 0?(i=e.getButton(u.Gamepad,n.button),a=!0):n.type===u.Touch&&n.touchButton!==void 0&&(i=e.getButton(u.Touch,n.touchButton),a=!0),a&&t.set(n.sourceId,i)}return t}static collectButtonSourcesWithTransitions(s,e){let t=new Map;for(let o of s)for(let n of o.sources){if(t.has(n.sourceId))continue;let i=!1,a=!1,d=!1,l=!1;n.type===u.Keyboard&&n.key!==void 0?(i=e.getButton(u.Keyboard,n.key),a=e.getButtonJustPressed?.(u.Keyboard,n.key)??!1,d=e.getButtonJustReleased?.(u.Keyboard,n.key)??!1,l=!0):n.type===u.Mouse&&n.mouseButton!==void 0?(i=e.getButton(u.Mouse,n.mouseButton),a=e.getButtonJustPressed?.(u.Mouse,n.mouseButton)??!1,d=e.getButtonJustReleased?.(u.Mouse,n.mouseButton)??!1,l=!0):n.type===u.Gamepad&&n.button!==void 0?(i=e.getButton(u.Gamepad,n.button),a=e.getButtonJustPressed?.(u.Gamepad,n.button)??!1,d=e.getButtonJustReleased?.(u.Gamepad,n.button)??!1,l=!0):n.type===u.Touch&&n.touchButton!==void 0&&(i=e.getButton(u.Touch,n.touchButton),a=e.getButtonJustPressed?.(u.Touch,n.touchButton)??!1,d=e.getButtonJustReleased?.(u.Touch,n.touchButton)??!1,l=!0),l&&t.set(n.sourceId,{pressed:i,justPressed:a,justReleased:d})}return t}static collectMousePosition(s,e,t,o,n){let i=s.getAxis(u.Mouse,Z.PositionX),a=s.getAxis(u.Mouse,Z.PositionY),d=s.isLeftMousePressed?.()??!1,{renderWidth:l,renderHeight:m,offsetX:f,offsetY:B,rect:h}=x.calculateRenderMetrics(e,n),T=i-h.left-f,M=a-h.top-B,G=l/t,O=m/o,A=Math.floor(T/G),L=Math.floor(M/O),K=T>=0&&T<l&&M>=0&&M<m;return{x:Math.max(0,Math.min(t-1,A)),y:Math.max(0,Math.min(o-1,L)),over:K,isLeftDown:d}}static collectTouchPositions(s,e,t,o,n=10,i){let a=[],{renderWidth:d,renderHeight:l,offsetX:m,offsetY:f,rect:B}=x.calculateRenderMetrics(e,i),h=d/t,T=l/o;for(let M=0;M<n;M++){let G=M;if(s.getButton(u.Touch,G)){let A=_+M*ee,L=_+M*ee+1,K=s.getAxis(u.Touch,A),te=s.getAxis(u.Touch,L),R=K-B.left-m,S=te-B.top-f,se=Math.floor(R/h),oe=Math.floor(S/T),ne=R>=0&&R<d&&S>=0&&S<l;a.push({id:M,x:Math.max(0,Math.min(t-1,se)),y:Math.max(0,Math.min(o-1,oe)),over:ne})}}return a}static collectTextInputs(s){return typeof s.getTextInputs=="function"?s.getTextInputs():[]}};p(x,"InputCollector");var N=x;export{y as BaseInputs,_e as GamepadInput,C as GamepadInputs,N as InputCollector,qe as InputDeviceType,q as InputEventType,Qe as KeyboardInput,E as KeyboardInputs,w as MobileInputs,D as MobileVibration,Ze as MouseInput,I as MouseInputs,et as TouchInput,Y as UnifiedInputRouter,Ne as Vector2,Oe as Vector3,v as VibrationPatterns,de as getMobileVibration,ae as isInputs,pe as useGamepadInputs,re as useKeyboardInputs,le as useMobileInputs,ue as useMouseInputs};
1
+ var Q=Object.defineProperty;var re=(m,s,e)=>s in m?Q(m,s,{enumerable:!0,configurable:!0,writable:!0,value:e}):m[s]=e;var b=(m,s)=>Q(m,"name",{value:s,configurable:!0});var r=(m,s,e)=>(re(m,typeof s!="symbol"?s+"":s,e),e);import{Vector2 as et,Vector3 as tt}from"@utsp/types";import{InputDeviceType as ot,KeyboardInput as nt,MouseInput as it,GamepadInput as at,TouchInput as rt,TouchZoneInput as ut}from"@utsp/types";var _=(h=>(h.KeyDown="keydown",h.KeyUp="keyup",h.MouseDown="mousedown",h.MouseUp="mouseup",h.MouseMove="mousemove",h.MouseWheel="mousewheel",h.TouchStart="touchstart",h.TouchEnd="touchend",h.TouchMove="touchmove",h.GamepadConnected="gamepadconnected",h.GamepadDisconnected="gamepaddisconnected",h.GamepadButton="gamepadbutton",h.GamepadAxis="gamepadaxis",h))(_||{}),j=class j{constructor(s=window,e={}){r(this,"isActive",!1);r(this,"targetElement");r(this,"config");r(this,"callbacks",{});this.targetElement=s,this.config={enabled:!0,preventDefault:!1,stopPropagation:!1,debug:!1,...e}}isListening(){return this.isActive}destroy(){this.stop(),this.clearCallbacks()}setCallbacks(s){typeof s=="object"&&s!==null&&Object.assign(this.callbacks,s)}clearCallbacks(){this.callbacks={}}getTargetElement(){return this.targetElement}enable(){this.config.enabled=!0,this.isActive||this.start()}disable(){this.config.enabled=!1,this.isActive&&this.stop()}isEnabled(){return this.config.enabled??!0}emit(s,...e){this.callbacks[s]&&this.callbacks[s].forEach(t=>{try{t(...e)}catch(o){this.config.debug&&console.error(`Error in ${s} callback:`,o)}})}log(...s){this.config.debug&&console.warn("[InputSystem]",...s)}};b(j,"BaseInputs");var T=j;function ue(m){return typeof m=="object"&&m!==null&&"start"in m&&"stop"in m&&"reset"in m&&"isListening"in m&&"destroy"in m}b(ue,"isInputs");var V=class V extends T{constructor(e=window,t={}){super(e,t);r(this,"keys",{});r(this,"keyboardCallbacks",{});r(this,"textInputsThisFrame",[]);r(this,"boundHandlers");this.boundHandlers={keyDown:this.handleKeyDown.bind(this),keyUp:this.handleKeyUp.bind(this)}}start(){this.isActive||(this.targetElement.addEventListener("keydown",this.boundHandlers.keyDown),this.targetElement.addEventListener("keyup",this.boundHandlers.keyUp),this.isActive=!0)}stop(){this.isActive&&(this.targetElement.removeEventListener("keydown",this.boundHandlers.keyDown),this.targetElement.removeEventListener("keyup",this.boundHandlers.keyUp),this.isActive=!1)}reset(){this.keys={}}resetDelta(){}poll(){for(let e in this.keys)this.keys[e].justPressed=!1,this.keys[e].justReleased=!1;this.textInputsThisFrame=[]}getTextInputs(){return this.textInputsThisFrame}isKeyPressed(e){return this.keys[e]?.pressed||!1}isKeyJustPressed(e){return this.keys[e]?.justPressed||!1}isKeyJustReleased(e){return this.keys[e]?.justReleased||!1}getKeysPressed(){return Object.keys(this.keys).filter(e=>this.keys[e].pressed)}getKeysJustPressed(){return Object.keys(this.keys).filter(e=>this.keys[e].justPressed)}getKeysJustReleased(){return Object.keys(this.keys).filter(e=>this.keys[e].justReleased)}isAnyKeyPressed(){return Object.values(this.keys).some(e=>e.pressed)}setKeyboardCallbacks(e){this.keyboardCallbacks={...this.keyboardCallbacks,...e}}clearKeyboardCallbacks(){this.keyboardCallbacks={}}setCallbacks(e){this.isKeyboardCallbacks(e)&&this.setKeyboardCallbacks(e)}isKeyboardCallbacks(e){return typeof e=="object"&&e!==null&&("onKeyDown"in e||"onKeyUp"in e)}shouldAllowDefault(e,t){let o=/^F([1-9]|1[0-2])$/.test(e),n=(t.ctrlKey||t.metaKey)&&(e==="KeyT"||e==="KeyW"||e==="KeyR"||e==="KeyN"||e==="Tab");return o||n}handleKeyDown(e){try{let t=e.code,o=this.shouldAllowDefault(t,e);this.config.preventDefault&&!o&&e.preventDefault(),this.config.stopPropagation&&!o&&e.stopPropagation(),this.keys[t]||(this.keys[t]={pressed:!1,justPressed:!1,justReleased:!1}),this.keys[t].pressed||(this.keys[t].justPressed=!0,this.keyboardCallbacks.onKeyDown?.(t,e)),this.keys[t].pressed=!0,this.keys[t].justReleased=!1;let n=e.key;n.length===1&&!e.ctrlKey&&!e.metaKey&&this.textInputsThisFrame.push(n)}catch(t){console.error("Error in keyboard keydown handler:",t)}}handleKeyUp(e){try{let t=e.code,o=this.shouldAllowDefault(t,e);this.config.preventDefault&&!o&&e.preventDefault(),this.config.stopPropagation&&!o&&e.stopPropagation(),this.keys[t]||(this.keys[t]={pressed:!1,justPressed:!1,justReleased:!1}),this.keys[t].pressed&&(this.keys[t].justReleased=!0,this.keyboardCallbacks.onKeyUp?.(t,e)),this.keys[t].pressed=!1,this.keys[t].justPressed=!1}catch(t){console.error("Error in keyboard keyup handler:",t)}}};b(V,"KeyboardInputs");var x=V;function le(m,s){let e=new x(m);return s&&e.setCallbacks(s),e.start(),e}b(le,"useKeyboardInputs");import{Vector2 as P}from"@utsp/types";var A=class A extends T{constructor(e=window,t={}){super(e,t);r(this,"mouseButtons",{left:{pressed:!1,justPressed:!1,justReleased:!1},middle:{pressed:!1,justPressed:!1,justReleased:!1},right:{pressed:!1,justPressed:!1,justReleased:!1}});r(this,"mousePosition",P.zero());r(this,"mouseDelta",P.zero());r(this,"wheelDelta",0);r(this,"mouseCallbacks",{});r(this,"boundHandlers");this.boundHandlers={mouseDown:this.handleMouseDown.bind(this),mouseUp:this.handleMouseUp.bind(this),mouseMove:this.handleMouseMove.bind(this),wheel:this.handleWheel.bind(this),mouseEnter:this.handleMouseEnter.bind(this),mouseLeave:this.handleMouseLeave.bind(this),contextMenu:this.handleContextMenu.bind(this)}}start(){this.isActive||(this.targetElement.addEventListener("mousedown",this.boundHandlers.mouseDown),this.targetElement.addEventListener("mouseup",this.boundHandlers.mouseUp),this.targetElement.addEventListener("mousemove",this.boundHandlers.mouseMove),this.targetElement.addEventListener("wheel",this.boundHandlers.wheel),this.targetElement.addEventListener("mouseenter",this.boundHandlers.mouseEnter),this.targetElement.addEventListener("mouseleave",this.boundHandlers.mouseLeave),this.targetElement.addEventListener("contextmenu",this.boundHandlers.contextMenu),this.isActive=!0)}stop(){this.isActive&&(this.targetElement.removeEventListener("mousedown",this.boundHandlers.mouseDown),this.targetElement.removeEventListener("mouseup",this.boundHandlers.mouseUp),this.targetElement.removeEventListener("mousemove",this.boundHandlers.mouseMove),this.targetElement.removeEventListener("wheel",this.boundHandlers.wheel),this.targetElement.removeEventListener("mouseenter",this.boundHandlers.mouseEnter),this.targetElement.removeEventListener("mouseleave",this.boundHandlers.mouseLeave),this.targetElement.removeEventListener("contextmenu",this.boundHandlers.contextMenu),this.isActive=!1)}reset(){this.mouseButtons={left:{pressed:!1,justPressed:!1,justReleased:!1},middle:{pressed:!1,justPressed:!1,justReleased:!1},right:{pressed:!1,justPressed:!1,justReleased:!1}},this.mousePosition=P.zero(),this.mouseDelta=P.zero(),this.wheelDelta=0}poll(){this.mouseButtons.left.justPressed=!1,this.mouseButtons.left.justReleased=!1,this.mouseButtons.middle.justPressed=!1,this.mouseButtons.middle.justReleased=!1,this.mouseButtons.right.justPressed=!1,this.mouseButtons.right.justReleased=!1,this.resetDelta()}resetDelta(){this.mouseDelta=P.zero(),this.wheelDelta=0}isLeftMousePressed(){return this.mouseButtons.left.pressed}isLeftMouseJustPressed(){return this.mouseButtons.left.justPressed}isLeftMouseJustReleased(){return this.mouseButtons.left.justReleased}isRightMousePressed(){return this.mouseButtons.right.pressed}isRightMouseJustPressed(){return this.mouseButtons.right.justPressed}isRightMouseJustReleased(){return this.mouseButtons.right.justReleased}isMiddleMousePressed(){return this.mouseButtons.middle.pressed}isMiddleMouseJustPressed(){return this.mouseButtons.middle.justPressed}isMiddleMouseJustReleased(){return this.mouseButtons.middle.justReleased}getMousePosition(){return this.mousePosition.clone()}getMouseDelta(){return this.mouseDelta.clone()}getWheelDelta(){return this.wheelDelta}setMouseCallbacks(e){this.mouseCallbacks={...this.mouseCallbacks,...e}}clearMouseCallbacks(){this.mouseCallbacks={}}setCallbacks(e){this.isMouseCallbacks(e)&&this.setMouseCallbacks(e)}isMouseCallbacks(e){return typeof e=="object"&&e!==null&&("onMouseDown"in e||"onMouseUp"in e||"onMouseMove"in e||"onMouseWheel"in e||"onMouseEnter"in e||"onMouseLeave"in e)}getButtonByIndex(e){let t=A.BUTTON_NAMES[e];return t?{state:this.mouseButtons[t],name:t}:null}handleMouseDown(e){try{this.config.preventDefault&&e.preventDefault(),this.config.stopPropagation&&e.stopPropagation();let t=this.getButtonByIndex(e.button);t&&(t.state.pressed||(t.state.justPressed=!0),t.state.pressed=!0,t.state.justReleased=!1,this.mouseCallbacks.onMouseDown?.(t.name,this.mousePosition,e))}catch(t){console.error("Error in mouse down handler:",t)}}handleMouseUp(e){try{this.config.preventDefault&&e.preventDefault(),this.config.stopPropagation&&e.stopPropagation();let t=this.getButtonByIndex(e.button);t&&(t.state.pressed&&(t.state.justReleased=!0),t.state.pressed=!1,t.state.justPressed=!1,this.mouseCallbacks.onMouseUp?.(t.name,this.mousePosition,e))}catch(t){console.error("Error in mouse up handler:",t)}}handleMouseMove(e){try{this.config.preventDefault&&e.preventDefault(),this.config.stopPropagation&&e.stopPropagation();let t=new P(e.clientX,e.clientY);this.mouseDelta=t.subtract(this.mousePosition),this.mousePosition=t,this.mouseCallbacks.onMouseMove?.(this.mousePosition,this.mouseDelta,e)}catch(t){console.error("Error in mouse move handler:",t)}}handleWheel(e){try{this.config.preventDefault&&e.preventDefault(),this.config.stopPropagation&&e.stopPropagation(),this.wheelDelta=e.deltaY,this.mouseCallbacks.onMouseWheel?.(this.wheelDelta,e)}catch(t){console.error("Error in mouse wheel handler:",t)}}handleMouseEnter(e){try{this.mouseCallbacks.onMouseEnter?.(e)}catch(t){console.error("Error in mouse enter handler:",t)}}handleMouseLeave(e){try{this.mouseCallbacks.onMouseLeave?.(e)}catch(t){console.error("Error in mouse leave handler:",t)}}handleContextMenu(e){try{e.preventDefault(),this.config.stopPropagation&&e.stopPropagation()}catch(t){console.error("Error in context menu handler:",t)}}};b(A,"MouseInputs"),r(A,"BUTTON_NAMES",["left","middle","right"]);var B=A;function de(m,s){let e=new B(m);return s&&e.setCallbacks(s),e.start(),e}b(de,"useMouseInputs");import{Vector2 as J}from"@utsp/types";var z=class z extends T{constructor(e=window,t={}){super(e,t);r(this,"touches",new Map);r(this,"nativeToInternal",new Map);r(this,"mobileCallbacks",{});r(this,"mobileConfig");r(this,"maxTouches",10);r(this,"lastLogTime",0);r(this,"boundHandlers");this.mobileConfig={targetElement:e,preventDefault:t.preventDefault??!1,passive:t.passive??!0,maxTouches:t.maxTouches??10,enabled:t.enabled??!0,debug:t.debug??!1,stopPropagation:t.stopPropagation??!1},this.maxTouches=this.mobileConfig.maxTouches,this.mobileConfig.preventDefault&&this.mobileConfig.passive&&(console.warn("[MobileInputs] passive=true prevents preventDefault() from working! Setting passive=false."),this.mobileConfig.passive=!1),this.boundHandlers={touchStart:this.handleTouchStart.bind(this),touchEnd:this.handleTouchEnd.bind(this),touchMove:this.handleTouchMove.bind(this),touchCancel:this.handleTouchCancel.bind(this),orientationChange:this.handleOrientationChange.bind(this)}}start(){if(this.isActive)return;let e={passive:!this.mobileConfig.preventDefault&&this.mobileConfig.passive};this.targetElement.addEventListener("touchstart",this.boundHandlers.touchStart,e),this.targetElement.addEventListener("touchend",this.boundHandlers.touchEnd,e),this.targetElement.addEventListener("touchmove",this.boundHandlers.touchMove,e),this.targetElement.addEventListener("touchcancel",this.boundHandlers.touchCancel,e),window.addEventListener("orientationchange",this.boundHandlers.orientationChange),this.isActive=!0}stop(){this.isActive&&(this.targetElement.removeEventListener("touchstart",this.boundHandlers.touchStart),this.targetElement.removeEventListener("touchend",this.boundHandlers.touchEnd),this.targetElement.removeEventListener("touchmove",this.boundHandlers.touchMove),this.targetElement.removeEventListener("touchcancel",this.boundHandlers.touchCancel),window.removeEventListener("orientationchange",this.boundHandlers.orientationChange),this.isActive=!1)}reset(){this.touches.clear(),this.nativeToInternal.clear()}resetDelta(){}poll(){let e=[];for(let[t,o]of this.touches.entries())o.justReleased&&(e.push(t),this.nativeToInternal.delete(o.nativeId)),o.justTouched=!1,o.justReleased=!1;for(let t of e)this.touches.delete(t)}isTouchActive(e){if(e<0||e>=this.maxTouches)return!1;let t=this.touches.get(e);return t?t.active:!1}getTouchPosition(e){if(e<0||e>=this.maxTouches)return null;let t=this.touches.get(e);return t?t.position.clone():null}getTouchStartPosition(e){if(e<0||e>=this.maxTouches)return null;let t=this.touches.get(e);return t?t.startPosition.clone():null}getTouchDelta(e){if(e<0||e>=this.maxTouches)return null;let t=this.touches.get(e);return t?t.position.subtract(t.startPosition):null}getTouchCount(){let e=0;for(let t of this.touches.values())t.active&&e++;return e}isTouchJustStarted(e){if(e<0||e>=this.maxTouches)return!1;let t=this.touches.get(e);return t?t.justTouched:!1}isTouchJustReleased(e){if(e<0||e>=this.maxTouches)return!1;let t=this.touches.get(e);return t?t.justReleased:!1}isAnyTouchJustStarted(){for(let e of this.touches.values())if(e.justTouched)return!0;return!1}isAnyTouchJustReleased(){for(let e of this.touches.values())if(e.justReleased)return!0;return!1}getJustReleasedTouches(){return Array.from(this.touches.values()).filter(e=>e.justReleased)}getAllTouches(){return Array.from(this.touches.values()).filter(e=>e.active)}setMobileCallbacks(e){this.mobileCallbacks={...this.mobileCallbacks,...e}}clearMobileCallbacks(){this.mobileCallbacks={}}setCallbacks(e){this.isMobileCallbacks(e)&&this.setMobileCallbacks(e)}isMobileCallbacks(e){return typeof e=="object"&&e!==null&&("onTouchStart"in e||"onTouchEnd"in e||"onTouchMove"in e||"onTouchCancel"in e||"onOrientationChange"in e)}handleTouchStart(e){try{this.mobileConfig.preventDefault&&e.preventDefault();let t=Array.from(e.changedTouches),o=[];for(let n of t){if(this.touches.size>=this.maxTouches)break;let i=this.nativeToInternal.get(n.identifier);if(i!==void 0){let c=this.touches.get(i);if(c){let p=new J(n.clientX,n.clientY);c.position=p.clone(),c.startPosition=p.clone(),c.active=!0,c.justTouched=!0,c.justReleased=!1,o.push({...c})}continue}let a=-1;for(let c=0;c<this.maxTouches;c++)if(!this.touches.has(c)){a=c;break}if(a===-1)continue;let l=new J(n.clientX,n.clientY),d={id:a,nativeId:n.identifier,position:l.clone(),startPosition:l.clone(),active:!0,justTouched:!0,justReleased:!1};this.touches.set(a,d),this.nativeToInternal.set(n.identifier,a),o.push(d),console.warn(`\u{1F446} Touch START - ID: ${a}`)}this.mobileCallbacks.onTouchStart?.(o,e)}catch(t){console.error("Error in touch start handler:",t)}}handleTouchEnd(e){try{this.mobileConfig.preventDefault&&e.preventDefault();let t=Array.from(e.changedTouches),o=[];for(let n of t){let i=this.nativeToInternal.get(n.identifier);if(i!==void 0){let a=this.touches.get(i);a&&(a.justReleased=!0,a.justTouched=!1,a.active=!1,o.push({...a}),console.warn(`\u{1F447} Touch END - ID: ${i}`))}}this.mobileCallbacks.onTouchEnd?.(o,e)}catch(t){console.error("Error in touch end handler:",t)}}handleTouchMove(e){try{let t=Array.from(e.changedTouches);this.mobileConfig.debug&&(!this.lastLogTime||Date.now()-this.lastLogTime>200)&&(console.warn(`\u{1F504} TouchMove event - ${t.length} touches changed`),this.lastLogTime=Date.now());for(let o of t){let n=this.nativeToInternal.get(o.identifier);if(n!==void 0){let i=this.touches.get(n);if(i){let a=i.position.clone();i.position=new J(o.clientX,o.clientY),this.mobileConfig.debug&&(!this.lastLogTime||Date.now()-this.lastLogTime>200)&&console.warn(`\u{1F504} Updated touch ${i.id} (native ${o.identifier}) - ${a.x.toFixed(1)},${a.y.toFixed(1)} \u2192 ${o.clientX.toFixed(1)},${o.clientY.toFixed(1)}`)}}else this.mobileConfig.debug&&console.warn(`\u26A0\uFE0F Touch move for unknown native ID ${o.identifier}`)}this.mobileCallbacks.onTouchMove?.(this.getAllTouches(),e)}catch(t){console.error("Error in touch move handler:",t)}}handleTouchCancel(e){try{this.mobileConfig.preventDefault&&e.preventDefault();let t=[],o=Array.from(e.changedTouches);for(let n of o){let i=this.nativeToInternal.get(n.identifier);if(i!==void 0){let a=this.touches.get(i);a&&(a.justReleased=!0,a.justTouched=!1,a.active=!1,t.push({...a}),this.mobileConfig.debug&&console.warn(`\u274C Touch CANCEL - ID: ${i}, nativeId: ${n.identifier}`))}}this.mobileCallbacks.onTouchCancel?.(t,e)}catch(t){console.error("Error in touch cancel handler:",t)}}handleOrientationChange(e){try{let t=(window.screen.orientation&&window.screen.orientation.angle)??window.orientation??0;this.mobileCallbacks.onOrientationChange?.(t)}catch(t){console.error("Error in orientation change handler:",t)}}};b(z,"MobileInputs");var k=z;function ce(m,s,e){console.warn("[MobileInputs] useMobileInputs() is deprecated and causes memory leaks. Use useMemo + useEffect instead.");let t=new k(m,e);return s&&t.setCallbacks(s),t.start(),t}b(ce,"useMobileInputs");var $=class $ extends T{constructor(e,t){super(t.targetElement,t);this.mobile=e;r(this,"zones",[]);r(this,"zoneState",new Map);r(this,"gridWidth");r(this,"gridHeight");r(this,"rendererOffsets");this.gridWidth=t.gridWidth,this.gridHeight=t.gridHeight,this.rendererOffsets=t.rendererOffsets??{offsetX:0,offsetY:0},t.zones&&this.setZones(t.zones)}start(){this.isActive=!0}stop(){this.isActive=!1}reset(){this.clearZones()}resetDelta(){}setLayout(e,t,o){this.gridWidth=e,this.gridHeight=t,o&&(this.rendererOffsets=o)}setZones(e){this.zones=e.filter(t=>t.id>=0&&t.id<=31),this.zoneState.clear();for(let t of this.zones)this.zoneState.set(t.id,{pressed:!1,justPressed:!1,justReleased:!1,lastX:t.x,lastY:t.y})}clearZones(){this.zones=[],this.zoneState.clear()}updateFromTouches(){if(this.zones.length===0)return;let e=this.targetElement,t=e.getBoundingClientRect(),{renderWidth:o,renderHeight:n,offsetX:i,offsetY:a}=this.calculateRenderMetrics(e,t),l=o/this.gridWidth,d=n/this.gridHeight,c=new Map,p=new Map,E=this.mobile.getAllTouches();for(let h of E){let g=h.position.x-t.left-i,M=h.position.y-t.top-a,I=Math.floor(g/l),C=Math.floor(M/d);for(let v of this.zones)this.isInsideZone(I,C,v)&&(c.set(v.id,(c.get(v.id)??0)+1),p.set(v.id,{x:Math.max(v.x,Math.min(v.x+v.width-1,I)),y:Math.max(v.y,Math.min(v.y+v.height-1,C))}))}for(let h of this.zones){let g=this.zoneState.get(h.id)??{pressed:!1,justPressed:!1,justReleased:!1,lastX:h.x,lastY:h.y},I=(c.get(h.id)??0)>0;I&&!g.pressed&&(g.justPressed=!0),!I&&g.pressed&&(g.justReleased=!0),g.pressed=I;let C=p.get(h.id);C&&(g.lastX=C.x,g.lastY=C.y),this.zoneState.set(h.id,g)}}poll(){for(let e of this.zoneState.values())e.justPressed=!1,e.justReleased=!1}isZonePressed(e){return this.zoneState.get(e)?.pressed??!1}isZoneJustPressed(e){return this.zoneState.get(e)?.justPressed??!1}isZoneJustReleased(e){return this.zoneState.get(e)?.justReleased??!1}getZoneAxis(e,t){let o=this.zoneState.get(e);if(!o||!o.pressed)return 0;let n=this.zones.find(i=>i.id===e);if(!n)return 0;if(t==="x"){let i=(n.width-1)/2,a=n.x+i;return i>0?(o.lastX-a)/i:0}else{let i=(n.height-1)/2,a=n.y+i;return i>0?(o.lastY-a)/i:0}}getZonePosition(e){let t=this.zoneState.get(e);return t?{x:t.lastX,y:t.lastY}:null}calculateRenderMetrics(e,t){let o=e.width,n=e.height,i=o/n,a=t.width/t.height,l,d,c,p;i>a?(l=t.width,d=t.width/i,c=0,p=(t.height-d)/2):(l=t.height*i,d=t.height,c=(t.width-l)/2,p=0);let E=this.rendererOffsets;return c+=E.offsetX,p+=E.offsetY,l-=E.offsetX*2,d-=E.offsetY*2,{renderWidth:l,renderHeight:d,offsetX:c,offsetY:p}}isInsideZone(e,t,o){return e>=o.x&&e<o.x+o.width&&t>=o.y&&t<o.y+o.height}};b($,"TouchZoneInputs");var D=$;var w={tap:10,mediumTap:25,heavyTap:50,success:[30,50,30],error:[50,30,50,30,50],warning:[100],selection:5,impactLight:15,impactMedium:30,impactHeavy:50,notification:[100,100,100,100,100],sos:[100,30,100,30,100,30,200,30,200,30,200,30,100,30,100,30,100]},X=class X{constructor(s={}){r(this,"config");r(this,"supported",!1);r(this,"userActivated",!1);this.config={enabled:s.enabled??!0,debug:s.debug??!1,intensity:Math.max(0,Math.min(1,s.intensity??1))},this.supported=typeof navigator<"u"&&"vibrate"in navigator,this.config.debug&&console.log(`[MobileVibration] Vibration API supported: ${this.supported}`)}isSupported(){return this.supported}isEnabled(){return this.config.enabled&&this.supported}setEnabled(s){this.config.enabled=s,this.config.debug&&console.log(`[MobileVibration] Enabled: ${s}`)}setIntensity(s){this.config.intensity=Math.max(0,Math.min(1,s)),this.config.debug&&console.log(`[MobileVibration] Intensity set to: ${this.config.intensity}`)}getIntensity(){return this.config.intensity}vibrate(s){if(!this.isEnabled())return!1;try{let e=this.scalePattern(s),t=typeof e=="number"?e:[...e],o=navigator.vibrate(t);return this.config.debug&&console.log(`[MobileVibration] Vibrate: ${JSON.stringify(e)} -> ${o}`),o&&(this.userActivated=!0),o}catch(e){return this.config.debug&&console.error("[MobileVibration] Vibration failed:",e),!1}}cancel(){this.supported&&(navigator.vibrate(0),this.config.debug&&console.log("[MobileVibration] Vibration cancelled"))}hasUserActivation(){return this.userActivated}tap(){return this.vibrate(w.tap)}mediumTap(){return this.vibrate(w.mediumTap)}heavyTap(){return this.vibrate(w.heavyTap)}success(){return this.vibrate(w.success)}error(){return this.vibrate(w.error)}warning(){return this.vibrate(w.warning)}selection(){return this.vibrate(w.selection)}impactLight(){return this.vibrate(w.impactLight)}impactMedium(){return this.vibrate(w.impactMedium)}impactHeavy(){return this.vibrate(w.impactHeavy)}notification(){return this.vibrate(w.notification)}scalePattern(s){return this.config.intensity===1?s:typeof s=="number"?Math.round(s*this.config.intensity):s.map((e,t)=>t%2===0?Math.round(e*this.config.intensity):e)}};b(X,"MobileVibration");var R=X,W=null;function he(){return W||(W=new R),W}b(he,"getMobileVibration");var pe=.01,Y=class Y extends T{constructor(e={}){super(window,e);r(this,"gamepads",new Map);r(this,"previousGamepads",new Map);r(this,"gamepadCallbacks",{});r(this,"gamepadConfig");r(this,"pollingIntervalId",null);r(this,"rafId",null);r(this,"boundHandlers");r(this,"vibrationPresets",{tap:{duration:50,strongMagnitude:.3,weakMagnitude:.5},impact:{duration:100,strongMagnitude:.7,weakMagnitude:.3},heavy:{duration:200,strongMagnitude:1,weakMagnitude:.2},success:{duration:150,strongMagnitude:.4,weakMagnitude:.6},error:{duration:300,strongMagnitude:.8,weakMagnitude:.4},explosion:{duration:400,strongMagnitude:1,weakMagnitude:.8},engine:{duration:1e3,strongMagnitude:.5,weakMagnitude:.2},heartbeat:{duration:100,strongMagnitude:.6,weakMagnitude:.1}});this.gamepadConfig={targetElement:window,maxGamepads:e.maxGamepads??4,axisDeadzone:e.axisDeadzone??.1,pollingInterval:e.pollingInterval??16,autoPolling:e.autoPolling??!0,enabled:e.enabled??!0,debug:e.debug??!1,preventDefault:e.preventDefault??!1,stopPropagation:e.stopPropagation??!1},this.boundHandlers={connected:this.handleGamepadConnected.bind(this),disconnected:this.handleGamepadDisconnected.bind(this)}}start(){this.isActive||(window.addEventListener("gamepadconnected",this.boundHandlers.connected),window.addEventListener("gamepaddisconnected",this.boundHandlers.disconnected),this.gamepadConfig.autoPolling&&this.startPolling(),this.isActive=!0,this.log("GamepadInputs started"))}stop(){this.isActive&&(window.removeEventListener("gamepadconnected",this.boundHandlers.connected),window.removeEventListener("gamepaddisconnected",this.boundHandlers.disconnected),this.stopPolling(),this.isActive=!1,this.log("GamepadInputs stopped"))}reset(){this.gamepads.clear(),this.previousGamepads.clear()}resetDelta(){this.previousGamepads.clear(),this.gamepads.forEach((e,t)=>{this.previousGamepads.set(t,this.cloneGamepadState(e))})}startPolling(){if(this.pollingIntervalId!==null||this.rafId!==null)return;let e=b(()=>{this.poll(),this.rafId=requestAnimationFrame(e)},"poll");this.rafId=requestAnimationFrame(e),this.log("Polling started")}stopPolling(){this.rafId!==null&&(cancelAnimationFrame(this.rafId),this.rafId=null),this.pollingIntervalId!==null&&(clearInterval(this.pollingIntervalId),this.pollingIntervalId=null),this.log("Polling stopped")}poll(){let e=navigator.getGamepads?navigator.getGamepads():[];for(let t=0;t<e.length&&t<this.gamepadConfig.maxGamepads;t++){let o=e[t];o&&this.updateGamepadState(o)}}getConnectedGamepadCount(){return this.gamepads.size}isGamepadConnected(e){return this.gamepads.has(e)&&this.gamepads.get(e).connected}getGamepadState(e){return this.gamepads.get(e)||null}getAllGamepads(){return Array.from(this.gamepads.values()).filter(e=>e.connected)}isButtonPressed(e,t){if(!Number.isInteger(e)||e<0)throw new Error(`Invalid gamepadIndex: ${e}. Must be a non-negative integer.`);if(!Number.isInteger(t)||t<0)throw new Error(`Invalid buttonIndex: ${t}. Must be a non-negative integer.`);let o=this.gamepads.get(e);return!o||!o.connected||t>=o.buttons.length?!1:o.buttons[t].pressed}isButtonJustPressed(e,t){if(!Number.isInteger(e)||e<0)throw new Error(`Invalid gamepadIndex: ${e}. Must be a non-negative integer.`);if(!Number.isInteger(t)||t<0)throw new Error(`Invalid buttonIndex: ${t}. Must be a non-negative integer.`);let o=this.gamepads.get(e);return!o||!o.connected||t>=o.buttons.length?!1:o.buttons[t].justPressed}isButtonJustReleased(e,t){if(!Number.isInteger(e)||e<0)throw new Error(`Invalid gamepadIndex: ${e}. Must be a non-negative integer.`);if(!Number.isInteger(t)||t<0)throw new Error(`Invalid buttonIndex: ${t}. Must be a non-negative integer.`);let o=this.gamepads.get(e);return!o||!o.connected||t>=o.buttons.length?!1:o.buttons[t].justReleased}getButtonValue(e,t){if(!Number.isInteger(e)||e<0)throw new Error(`Invalid gamepadIndex: ${e}. Must be a non-negative integer.`);if(!Number.isInteger(t)||t<0)throw new Error(`Invalid buttonIndex: ${t}. Must be a non-negative integer.`);let o=this.gamepads.get(e);return!o||!o.connected||t>=o.buttons.length?0:o.buttons[t].value}getAxis(e,t){if(!Number.isInteger(e)||e<0)throw new Error(`Invalid gamepadIndex: ${e}. Must be a non-negative integer.`);if(!Number.isInteger(t)||t<0)throw new Error(`Invalid axisIndex: ${t}. Must be a non-negative integer.`);let o=this.gamepads.get(e);if(!o||!o.connected||t>=o.axes.length)return 0;let n=o.axes[t];return this.applyDeadzone(n)}getAxisRaw(e,t){if(!Number.isInteger(e)||e<0)throw new Error(`Invalid gamepadIndex: ${e}. Must be a non-negative integer.`);if(!Number.isInteger(t)||t<0)throw new Error(`Invalid axisIndex: ${t}. Must be a non-negative integer.`);let o=this.gamepads.get(e);return!o||!o.connected||t>=o.axes.length?0:o.axes[t]}getLeftStick(e){return{x:this.getAxis(e,0),y:this.getAxis(e,1)}}getRightStick(e){return{x:this.getAxis(e,2),y:this.getAxis(e,3)}}supportsVibration(e){let t=this.getNativeGamepad(e);if(!t)return!1;let o=t.vibrationActuator;if(o&&typeof o.playEffect=="function")return!0;let n=t.hapticActuators;return!!(n&&n.length>0)}async vibrate(e,t){let o=this.getNativeGamepad(e);if(!o)return this.log(`Vibrate failed: gamepad ${e} not found`),!1;let{duration:n,strongMagnitude:i=1,weakMagnitude:a=.5,startDelay:l=0}=t;try{let d=o.vibrationActuator;if(d&&typeof d.playEffect=="function"){let p=await d.playEffect("dual-rumble",{startDelay:l,duration:n,strongMagnitude:Math.min(1,Math.max(0,i)),weakMagnitude:Math.min(1,Math.max(0,a))});return this.log(`Vibration effect result: ${p}`),p==="complete"}let c=o.hapticActuators;if(c&&c.length>0){let p=Math.max(i,a);return await c[0].pulse(p,n),!0}return this.log(`Vibrate failed: gamepad ${e} does not support vibration`),!1}catch(d){return this.log("Vibrate error:",d),!1}}async stopVibration(e){let t=this.getNativeGamepad(e);if(!t)return!1;try{let o=t.vibrationActuator;return o&&typeof o.reset=="function"?(await o.reset(),!0):o&&typeof o.playEffect=="function"?(await o.playEffect("dual-rumble",{duration:0,strongMagnitude:0,weakMagnitude:0}),!0):!1}catch(o){return this.log("Stop vibration error:",o),!1}}async stopAllVibrations(){let e=[];for(let[t]of this.gamepads)e.push(this.stopVibration(t));await Promise.all(e)}async vibrateAll(e){let t=[];for(let[o]of this.gamepads)t.push(this.vibrate(o,e));await Promise.all(t)}async vibratePreset(e,t){let o=this.vibrationPresets[t];return o?this.vibrate(e,o):(this.log(`Unknown vibration preset: ${t}`),!1)}getNativeGamepad(e){return(navigator.getGamepads?navigator.getGamepads():[])[e]||null}setGamepadCallbacks(e){this.gamepadCallbacks={...this.gamepadCallbacks,...e}}clearGamepadCallbacks(){this.gamepadCallbacks={}}setCallbacks(e){this.isGamepadCallbacks(e)&&this.setGamepadCallbacks(e)}isGamepadCallbacks(e){return typeof e=="object"&&e!==null&&("onGamepadConnected"in e||"onGamepadDisconnected"in e||"onButtonDown"in e||"onButtonUp"in e||"onAxisMove"in e)}updateGamepadState(e){let t=this.gamepads.get(e.index),o=Array.from(e.buttons).map((a,l)=>{let d=t?.buttons[l],c=a.pressed,p=d?.pressed??!1;return{pressed:c,justPressed:c&&!p,justReleased:!c&&p,value:a.value,touched:a.touched??!1}}),n=Array.from(e.axes),i={id:e.id,index:e.index,connected:e.connected,buttons:o,axes:n,timestamp:e.timestamp,mapping:e.mapping};this.gamepads.set(e.index,i),this.triggerCallbacks(i,t)}triggerCallbacks(e,t){try{e.buttons.forEach((o,n)=>{o.justPressed&&this.gamepadCallbacks.onButtonDown?.(e.index,n,o.value),o.justReleased&&this.gamepadCallbacks.onButtonUp?.(e.index,n)}),e.axes.forEach((o,n)=>{let i=t?.axes[n]??0,a=this.applyDeadzone(o),l=this.applyDeadzone(i);Math.abs(a-l)>pe&&this.gamepadCallbacks.onAxisMove?.(e.index,n,a)})}catch(o){this.log("Error in gamepad callbacks:",o)}}handleGamepadConnected(e){try{this.log(`Gamepad connected: ${e.gamepad.id} at index ${e.gamepad.index}`);let t={id:e.gamepad.id,index:e.gamepad.index,connected:!0,buttons:Array.from(e.gamepad.buttons).map(o=>({pressed:o.pressed,justPressed:!1,justReleased:!1,value:o.value,touched:o.touched??!1})),axes:Array.from(e.gamepad.axes),timestamp:e.gamepad.timestamp,mapping:e.gamepad.mapping};this.gamepads.set(e.gamepad.index,t),this.gamepadCallbacks.onGamepadConnected?.(t)}catch(t){this.log("Error handling gamepad connected:",t)}}handleGamepadDisconnected(e){try{this.log(`Gamepad disconnected at index ${e.gamepad.index}`),this.gamepads.delete(e.gamepad.index),this.previousGamepads.delete(e.gamepad.index),this.gamepadCallbacks.onGamepadDisconnected?.(e.gamepad.index)}catch(t){this.log("Error handling gamepad disconnected:",t)}}applyDeadzone(e){let t=this.gamepadConfig.axisDeadzone;return Math.abs(e)<t?0:(e>0?1:-1)*((Math.abs(e)-t)/(1-t))}cloneGamepadState(e){return{...e,buttons:e.buttons.map(t=>({...t})),axes:[...e.axes]}}};b(Y,"GamepadInputs");var L=Y;function be(m,s){let e=new L(s);return m&&e.setGamepadCallbacks(m),e.start(),e}b(be,"useGamepadInputs");import{InputDeviceType as f,KeyboardInput as U,MouseInput as y,isButton as O,isAxis as me}from"@utsp/types";var F=class F{constructor(s={}){r(this,"keyboard",null);r(this,"mouse",null);r(this,"gamepad",null);r(this,"mobile",null);r(this,"touchZones",null);r(this,"config");this.config={enableKeyboardMouse:s.enableKeyboardMouse??!0,enableGamepad:s.enableGamepad??!0,enableMobile:s.enableMobile??!1,targetElement:s.targetElement??window,mobileTargetElement:s.mobileTargetElement??s.targetElement??window,debug:s.debug??!1,keyboardConfig:{preventDefault:!1,stopPropagation:!1,...s.keyboardConfig},mouseConfig:{preventDefault:!1,stopPropagation:!1,...s.mouseConfig},mobileConfig:{preventDefault:!0,passive:!1,maxTouches:10,...s.mobileConfig},enableTouchZones:s.enableTouchZones??!1,touchZoneConfig:s.touchZoneConfig??{gridWidth:0,gridHeight:0}},this.initialize()}initialize(){if(this.config.enableKeyboardMouse&&(this.keyboard=new x(this.config.targetElement,{preventDefault:this.config.keyboardConfig?.preventDefault??!1,stopPropagation:this.config.keyboardConfig?.stopPropagation??!1,debug:this.config.debug}),this.keyboard.start(),this.mouse=new B(this.config.targetElement,{preventDefault:this.config.mouseConfig?.preventDefault??!1,stopPropagation:this.config.mouseConfig?.stopPropagation??!1,debug:this.config.debug}),this.mouse.start(),this.log("Keyboard/Mouse initialized")),this.config.enableGamepad&&(this.gamepad=new L({debug:this.config.debug}),this.gamepad.start(),this.log("Gamepad initialized")),this.config.enableMobile&&(this.config.mobileTargetElement?(this.mobile=new k(this.config.mobileTargetElement,this.config.mobileConfig),this.mobile.start(),this.log("Mobile/Touch initialized")):this.warn("Mobile input enabled but no canvas provided - mobile input will be disabled until setMobileTarget() is called")),this.config.enableTouchZones){let s=this.config.touchZoneConfig?.targetElement??this.config.mobileTargetElement;if(!s||!s.getBoundingClientRect)this.warn("Touch zones enabled but no canvas HTMLElement provided - touch zones disabled");else if(!this.mobile)this.warn("Touch zones require mobile input to be enabled - touch zones disabled");else{let e={targetElement:s,gridWidth:this.config.touchZoneConfig?.gridWidth??0,gridHeight:this.config.touchZoneConfig?.gridHeight??0,rendererOffsets:this.config.touchZoneConfig?.rendererOffsets,zones:this.config.touchZoneConfig?.zones,enabled:!0,debug:this.config.debug};this.disableSystemLongPressHaptics(s),this.touchZones=new D(this.mobile,e),this.log("Touch zones initialized")}}}getButton(s,e){if(!O({device:s,input:e}))return this.warn(`Input ${e} on device ${s} is not a button`),!1;switch(s){case f.Keyboard:return this.getKeyboardButton(e);case f.Mouse:return this.getMouseButton(e);case f.Gamepad:return this.getGamepadButton(e);case f.Touch:return this.getTouchButton(e);case f.TouchZone:return this.getTouchZoneButton(e);default:return this.warn(`Unknown device type: ${s}`),!1}}getButtonJustPressed(s,e){if(!O({device:s,input:e}))return this.warn(`Input ${e} on device ${s} is not a button`),!1;switch(s){case f.Keyboard:return this.getKeyboardButtonJustPressed(e);case f.Mouse:return this.getMouseButtonJustPressed(e);case f.Gamepad:return this.getGamepadButtonJustPressed(e);case f.Touch:return this.getTouchButtonJustPressed(e);case f.TouchZone:return this.getTouchZoneButtonJustPressed(e);default:return this.warn(`Unknown device type: ${s}`),!1}}getButtonJustReleased(s,e){if(!O({device:s,input:e}))return this.warn(`Input ${e} on device ${s} is not a button`),!1;switch(s){case f.Keyboard:return this.getKeyboardButtonJustReleased(e);case f.Mouse:return this.getMouseButtonJustReleased(e);case f.Gamepad:return this.getGamepadButtonJustReleased(e);case f.Touch:return this.getTouchButtonJustReleased(e);case f.TouchZone:return this.getTouchZoneButtonJustReleased(e);default:return this.warn(`Unknown device type: ${s}`),!1}}getAxis(s,e){if(!me({device:s,input:e}))return this.warn(`Input ${e} on device ${s} is not an axis`),0;switch(s){case f.Keyboard:return this.warn("Keyboard does not have axis inputs"),0;case f.Mouse:return this.getMouseAxis(e);case f.Gamepad:return this.getGamepadAxis(e);case f.Touch:return this.getTouchAxis(e);case f.TouchZone:return this.getTouchZoneAxis(e);default:return this.warn(`Unknown device type: ${s}`),0}}isLeftMousePressed(){return this.mouse?this.mouse.isLeftMousePressed():!1}getKeyboardButton(s){if(!this.keyboard)return!1;let e=U[s];return this.keyboard.isKeyPressed(e)}getKeyboardButtonJustPressed(s){if(!this.keyboard)return!1;let e=U[s];return this.keyboard.isKeyJustPressed(e)}getKeyboardButtonJustReleased(s){if(!this.keyboard)return!1;let e=U[s];return this.keyboard.isKeyJustReleased(e)}getMouseButton(s){if(!this.mouse)return!1;switch(s){case y.LeftButton:return this.mouse.isLeftMousePressed();case y.RightButton:return this.mouse.isRightMousePressed();case y.MiddleButton:return this.mouse.isMiddleMousePressed();default:return!1}}getMouseButtonJustPressed(s){if(!this.mouse)return!1;switch(s){case y.LeftButton:return this.mouse.isLeftMouseJustPressed();case y.RightButton:return this.mouse.isRightMouseJustPressed();case y.MiddleButton:return this.mouse.isMiddleMouseJustPressed();default:return!1}}getMouseButtonJustReleased(s){if(!this.mouse)return!1;switch(s){case y.LeftButton:return this.mouse.isLeftMouseJustReleased();case y.RightButton:return this.mouse.isRightMouseJustReleased();case y.MiddleButton:return this.mouse.isMiddleMouseJustReleased();default:return!1}}getGamepadButton(s){return!this.gamepad||s>=100?!1:this.gamepad.isButtonPressed(0,s)}getGamepadButtonJustPressed(s){return!this.gamepad||s>=100?!1:this.gamepad.isButtonJustPressed(0,s)}getGamepadButtonJustReleased(s){return!this.gamepad||s>=100?!1:this.gamepad.isButtonJustReleased(0,s)}getTouchButton(s){return this.mobile?s>=100?!1:this.mobile.isTouchActive?.(s)??!1:(console.warn("\u{1F6AB} MobileInputs not initialized!"),!1)}getTouchButtonJustPressed(s){return!this.mobile||s>=100?!1:this.mobile.isTouchJustStarted?.(s)??!1}getTouchButtonJustReleased(s){return!this.mobile||s>=100?!1:this.mobile.isTouchJustReleased?.(s)??!1}ensureTouchZonesSynced(){this.touchZones?.updateFromTouches()}getTouchZoneButton(s){if(!this.touchZones)return!1;this.ensureTouchZonesSynced();let e=s;return this.touchZones.isZonePressed(e)}getTouchZoneButtonJustPressed(s){if(!this.touchZones)return!1;this.ensureTouchZonesSynced();let e=s;return this.touchZones.isZoneJustPressed(e)}getTouchZoneButtonJustReleased(s){if(!this.touchZones)return!1;this.ensureTouchZonesSynced();let e=s;return this.touchZones.isZoneJustReleased(e)}getTouchZoneAxis(s){if(!this.touchZones||s<100)return 0;this.ensureTouchZonesSynced();let e=Math.floor((s-100)/2),t=(s-100)%2===0;return this.touchZones.getZoneAxis(e,t?"x":"y")}getMouseAxis(s){if(!this.mouse)return 0;switch(s){case y.PositionX:return this.mouse.getMousePosition().x;case y.PositionY:return this.mouse.getMousePosition().y;case y.DeltaX:return this.mouse.getMouseDelta().x;case y.DeltaY:return this.mouse.getMouseDelta().y;case y.WheelDeltaY:return this.mouse.getWheelDelta();default:return 0}}getGamepadAxis(s){if(!this.gamepad||s<100)return 0;let e=s-100;return this.gamepad.getAxis(0,e)}getTouchAxis(s){if(!this.mobile)return 0;if(s>=100&&s<200){let e=Math.floor((s-100)/2),t=(s-100)%2===0,o=this.mobile.getTouchPosition?.(e);return this.config.debug&&o&&console.warn(`\u{1F3AF} getTouchAxis(${s}) - touchIndex: ${e}, ${t?"X":"Y"}: ${t?o.x:o.y}`),o?t?o.x:o.y:0}return 0}getMousePosition(){if(!this.mouse)return null;let s=this.mouse.getMousePosition();return{x:s.x,y:s.y}}setMobileTarget(s){if(!s){this.warn("setMobileTarget() called with null/undefined canvas - mobile input will remain disabled");return}if(this.config.mobileTargetElement=s,!this.config.enableMobile){this.warn("setMobileTarget() called but mobile input is disabled in config");return}this.mobile&&this.mobile.stop(),this.mobile=new k(s,this.config.mobileConfig),this.mobile.start()}getTextInputs(){return this.keyboard?this.keyboard.getTextInputs():[]}start(){this.keyboard?.start(),this.mouse?.start(),this.log("Input router started")}stop(){this.keyboard?.stop(),this.mouse?.stop(),this.log("Input router stopped")}reset(){this.keyboard?.reset(),this.mouse?.reset(),this.log("Input router reset")}poll(){this.keyboard?.poll(),this.mouse?.poll(),this.gamepad?.poll(),this.mobile?.poll(),this.touchZones?.poll()}isListening(){return this.keyboard!==null&&this.config.enableKeyboardMouse||this.gamepad!==null&&this.config.enableGamepad||this.mobile!==null&&this.config.enableMobile||this.touchZones!==null&&this.config.enableTouchZones}getGamepad(){return this.gamepad}getKeyboard(){return this.keyboard}getMouse(){return this.mouse}getMobile(){return this.mobile}getTouchZones(){return this.touchZones}enableTouchZonesDevice(s,e,t,o){let n=Math.max(1,e),i=Math.max(1,t);if(this.touchZones)return o&&this.touchZones.setZones(o),this.touchZones.setLayout(n,i),!0;if(!this.mobile)return this.warn("Cannot enable touch zones: mobile input not initialized"),!1;let a={targetElement:s,gridWidth:n,gridHeight:i,zones:o,enabled:!0,debug:this.config.debug};return this.disableSystemLongPressHaptics(s),this.touchZones=new D(this.mobile,a),this.touchZones.start(),this.log(`Touch zones dynamically enabled with ${o?.length??0} zones`),!0}updateTouchZoneLayout(s,e,t){let o=Math.max(1,s),n=Math.max(1,e);this.touchZones?.setLayout(o,n,t)}destroy(){this.keyboard?.destroy(),this.mouse?.destroy(),this.keyboard=null,this.mouse=null,this.gamepad=null,this.mobile=null,this.touchZones=null,this.log("Input router destroyed")}log(s){this.config.debug&&console.warn(`[InputRouter] ${s}`)}warn(s){console.warn(`[InputRouter] ${s}`)}disableSystemLongPressHaptics(s){let e="__utspTouchSurfacePatched";s[e]||(s[e]=!0,s.style.setProperty("touch-action","none"),s.style.setProperty("user-select","none"),s.style.setProperty("-webkit-user-select","none"),s.style.setProperty("-webkit-touch-callout","none"),s.addEventListener("contextmenu",t=>t.preventDefault()),s.addEventListener("touchstart",t=>{t.preventDefault()},{passive:!1}))}};b(F,"UnifiedInputRouter");var N=F;import{InputDeviceType as u,MouseInput as ee}from"@utsp/types";var te=100,se=2,G=class G{static calculateRenderMetrics(s,e){let t=s.getBoundingClientRect(),o=s.width/s.height,n=t.width/t.height,i,a,l,d;o>n?(i=t.width,a=t.width/o,l=0,d=(t.height-a)/2):(i=t.height*o,a=t.height,l=(t.width-i)/2,d=0);let c=e?.offsetX||0,p=e?.offsetY||0;return l+=c,d+=p,i-=c*2,a-=p*2,{renderWidth:i,renderHeight:a,offsetX:l,offsetY:d,rect:t}}static collectAxisSources(s,e){let t=new Map;for(let o of s)for(let n of o.sources){if(t.has(n.sourceId))continue;let i=0,a=!1;if(n.type===u.Keyboard&&n.negativeKey!==void 0&&n.positiveKey!==void 0){let l=e.getButton(u.Keyboard,n.negativeKey);e.getButton(u.Keyboard,n.positiveKey)&&(i+=1),l&&(i-=1),a=!0}else if(n.type===u.Mouse&&n.mouseAxis!==void 0)i=e.getAxis(u.Mouse,n.mouseAxis),a=!0;else if(n.type===u.Gamepad&&n.axis!==void 0)i=e.getAxis(u.Gamepad,n.axis),a=!0;else if(n.type===u.Touch&&n.touchId!==void 0&&n.touchAxis!==void 0){let l=100+n.touchId*2,d=n.touchAxis==="x"?l:l+1;i=e.getAxis(u.Touch,d),a=!0}else if(n.type===u.TouchZone&&n.touchZoneId!==void 0&&n.touchZoneAxis!==void 0){let l=100+n.touchZoneId*2,d=n.touchZoneAxis==="x"?l:l+1;i=e.getAxis(u.TouchZone,d),a=!0}a&&t.set(n.sourceId,i)}return t}static collectButtonSources(s,e){let t=new Map;for(let o of s)for(let n of o.sources){if(t.has(n.sourceId))continue;let i=!1,a=!1;n.type===u.Keyboard&&n.key!==void 0?(i=e.getButton(u.Keyboard,n.key),a=!0):n.type===u.Mouse&&n.mouseButton!==void 0?(i=e.getButton(u.Mouse,n.mouseButton),a=!0):n.type===u.Gamepad&&n.button!==void 0?(i=e.getButton(u.Gamepad,n.button),a=!0):n.type===u.Touch&&n.touchButton!==void 0?(i=e.getButton(u.Touch,n.touchButton),a=!0):n.type===u.TouchZone&&n.touchZoneId!==void 0&&(i=e.getButton(u.TouchZone,n.touchZoneId),a=!0),a&&t.set(n.sourceId,i)}return t}static collectButtonSourcesWithTransitions(s,e){let t=new Map;for(let o of s)for(let n of o.sources){if(t.has(n.sourceId))continue;let i=!1,a=!1,l=!1,d=!1;n.type===u.Keyboard&&n.key!==void 0?(i=e.getButton(u.Keyboard,n.key),a=e.getButtonJustPressed?.(u.Keyboard,n.key)??!1,l=e.getButtonJustReleased?.(u.Keyboard,n.key)??!1,d=!0):n.type===u.Mouse&&n.mouseButton!==void 0?(i=e.getButton(u.Mouse,n.mouseButton),a=e.getButtonJustPressed?.(u.Mouse,n.mouseButton)??!1,l=e.getButtonJustReleased?.(u.Mouse,n.mouseButton)??!1,d=!0):n.type===u.Gamepad&&n.button!==void 0?(i=e.getButton(u.Gamepad,n.button),a=e.getButtonJustPressed?.(u.Gamepad,n.button)??!1,l=e.getButtonJustReleased?.(u.Gamepad,n.button)??!1,d=!0):n.type===u.Touch&&n.touchButton!==void 0?(i=e.getButton(u.Touch,n.touchButton),a=e.getButtonJustPressed?.(u.Touch,n.touchButton)??!1,l=e.getButtonJustReleased?.(u.Touch,n.touchButton)??!1,d=!0):n.type===u.TouchZone&&n.touchZoneId!==void 0&&(i=e.getButton(u.TouchZone,n.touchZoneId),a=e.getButtonJustPressed?.(u.TouchZone,n.touchZoneId)??!1,l=e.getButtonJustReleased?.(u.TouchZone,n.touchZoneId)??!1,d=!0),d&&t.set(n.sourceId,{pressed:i,justPressed:a,justReleased:l})}return t}static collectMousePosition(s,e,t,o,n){let i=s.getAxis(u.Mouse,ee.PositionX),a=s.getAxis(u.Mouse,ee.PositionY),l=s.isLeftMousePressed?.()??!1,{renderWidth:d,renderHeight:c,offsetX:p,offsetY:E,rect:h}=G.calculateRenderMetrics(e,n),g=i-h.left-p,M=a-h.top-E,I=d/t,C=c/o,v=Math.floor(g/I),Z=Math.floor(M/C),S=g>=0&&g<d&&M>=0&&M<c;return{x:Math.max(0,Math.min(t-1,v)),y:Math.max(0,Math.min(o-1,Z)),over:S,isLeftDown:l}}static collectTouchPositions(s,e,t,o,n=10,i){let a=[],{renderWidth:l,renderHeight:d,offsetX:c,offsetY:p,rect:E}=G.calculateRenderMetrics(e,i),h=l/t,g=d/o;for(let M=0;M<n;M++){let I=M;if(s.getButton(u.Touch,I)){let v=te+M*se,Z=te+M*se+1,S=s.getAxis(u.Touch,v),oe=s.getAxis(u.Touch,Z),H=S-E.left-c,K=oe-E.top-p,ne=Math.floor(H/h),ie=Math.floor(K/g),ae=H>=0&&H<l&&K>=0&&K<d;a.push({id:M,x:Math.max(0,Math.min(t-1,ne)),y:Math.max(0,Math.min(o-1,ie)),over:ae})}}return a}static collectTextInputs(s){return typeof s.getTextInputs=="function"?s.getTextInputs():[]}};b(G,"InputCollector");var q=G;export{T as BaseInputs,at as GamepadInput,L as GamepadInputs,q as InputCollector,ot as InputDeviceType,_ as InputEventType,nt as KeyboardInput,x as KeyboardInputs,k as MobileInputs,R as MobileVibration,it as MouseInput,B as MouseInputs,rt as TouchInput,ut as TouchZoneInput,D as TouchZoneInputs,N as UnifiedInputRouter,et as Vector2,tt as Vector3,w as VibrationPatterns,he as getMobileVibration,ue as isInputs,be as useGamepadInputs,le as useKeyboardInputs,ce as useMobileInputs,de as useMouseInputs};
package/dist/touch.cjs CHANGED
@@ -1 +1 @@
1
- "use strict";var d=Object.defineProperty;var V=Object.getOwnPropertyDescriptor;var I=Object.getOwnPropertyNames;var L=Object.prototype.hasOwnProperty;var D=(a,o,e)=>o in a?d(a,o,{enumerable:!0,configurable:!0,writable:!0,value:e}):a[o]=e;var h=(a,o)=>d(a,"name",{value:o,configurable:!0});var A=(a,o)=>{for(var e in o)d(a,e,{get:o[e],enumerable:!0})},H=(a,o,e,t)=>{if(o&&typeof o=="object"||typeof o=="function")for(let i of I(o))!L.call(a,i)&&i!==e&&d(a,i,{get:()=>o[i],enumerable:!(t=V(o,i))||t.enumerable});return a};var S=a=>H(d({},"__esModule",{value:!0}),a);var r=(a,o,e)=>(D(a,typeof o!="symbol"?o+"":o,e),e);var $={};A($,{BaseInputs:()=>b,InputDeviceType:()=>m.InputDeviceType,InputEventType:()=>g,MobileInputs:()=>p,MobileVibration:()=>f,TouchInput:()=>m.TouchInput,Vector2:()=>P.Vector2,VibrationPatterns:()=>l,getMobileVibration:()=>k,useMobileInputs:()=>x});module.exports=S($);var P=require("@utsp/types"),m=require("@utsp/types");var g=(u=>(u.KeyDown="keydown",u.KeyUp="keyup",u.MouseDown="mousedown",u.MouseUp="mouseup",u.MouseMove="mousemove",u.MouseWheel="mousewheel",u.TouchStart="touchstart",u.TouchEnd="touchend",u.TouchMove="touchmove",u.GamepadConnected="gamepadconnected",u.GamepadDisconnected="gamepaddisconnected",u.GamepadButton="gamepadbutton",u.GamepadAxis="gamepadaxis",u))(g||{}),T=class T{constructor(o=window,e={}){r(this,"isActive",!1);r(this,"targetElement");r(this,"config");r(this,"callbacks",{});this.targetElement=o,this.config={enabled:!0,preventDefault:!1,stopPropagation:!1,debug:!1,...e}}isListening(){return this.isActive}destroy(){this.stop(),this.clearCallbacks()}setCallbacks(o){typeof o=="object"&&o!==null&&Object.assign(this.callbacks,o)}clearCallbacks(){this.callbacks={}}getTargetElement(){return this.targetElement}enable(){this.config.enabled=!0,this.isActive||this.start()}disable(){this.config.enabled=!1,this.isActive&&this.stop()}isEnabled(){return this.config.enabled??!0}emit(o,...e){this.callbacks[o]&&this.callbacks[o].forEach(t=>{try{t(...e)}catch(i){this.config.debug&&console.error(`Error in ${o} callback:`,i)}})}log(...o){this.config.debug&&console.warn("[InputSystem]",...o)}};h(T,"BaseInputs");var b=T;var C=require("@utsp/types");var M=class M extends b{constructor(e=window,t={}){super(e,t);r(this,"touches",new Map);r(this,"nativeToInternal",new Map);r(this,"mobileCallbacks",{});r(this,"mobileConfig");r(this,"maxTouches",10);r(this,"lastLogTime",0);r(this,"boundHandlers");this.mobileConfig={targetElement:e,preventDefault:t.preventDefault??!0,passive:t.passive??!1,maxTouches:t.maxTouches??10,enabled:t.enabled??!0,debug:t.debug??!1,stopPropagation:t.stopPropagation??!1},this.maxTouches=this.mobileConfig.maxTouches,this.mobileConfig.preventDefault&&this.mobileConfig.passive&&(console.warn("[MobileInputs] passive=true prevents preventDefault() from working! Setting passive=false."),this.mobileConfig.passive=!1),this.boundHandlers={touchStart:this.handleTouchStart.bind(this),touchEnd:this.handleTouchEnd.bind(this),touchMove:this.handleTouchMove.bind(this),touchCancel:this.handleTouchCancel.bind(this),orientationChange:this.handleOrientationChange.bind(this)}}start(){if(this.isActive)return;let e={passive:!this.mobileConfig.preventDefault&&this.mobileConfig.passive};this.targetElement.addEventListener("touchstart",this.boundHandlers.touchStart,e),this.targetElement.addEventListener("touchend",this.boundHandlers.touchEnd,e),this.targetElement.addEventListener("touchmove",this.boundHandlers.touchMove,e),this.targetElement.addEventListener("touchcancel",this.boundHandlers.touchCancel,e),window.addEventListener("orientationchange",this.boundHandlers.orientationChange),this.isActive=!0}stop(){this.isActive&&(this.targetElement.removeEventListener("touchstart",this.boundHandlers.touchStart),this.targetElement.removeEventListener("touchend",this.boundHandlers.touchEnd),this.targetElement.removeEventListener("touchmove",this.boundHandlers.touchMove),this.targetElement.removeEventListener("touchcancel",this.boundHandlers.touchCancel),window.removeEventListener("orientationchange",this.boundHandlers.orientationChange),this.isActive=!1)}reset(){this.touches.clear(),this.nativeToInternal.clear()}resetDelta(){}poll(){for(let e of this.touches.values())e.justTouched=!1,e.justReleased=!1}isTouchActive(e){return e<0||e>=this.maxTouches?!1:this.touches.has(e)}getTouchPosition(e){if(e<0||e>=this.maxTouches)return null;let t=this.touches.get(e);return t?t.position.clone():null}getTouchStartPosition(e){if(e<0||e>=this.maxTouches)return null;let t=this.touches.get(e);return t?t.startPosition.clone():null}getTouchDelta(e){if(e<0||e>=this.maxTouches)return null;let t=this.touches.get(e);return t?t.position.subtract(t.startPosition):null}getTouchCount(){return this.touches.size}isTouchJustStarted(e){if(e<0||e>=this.maxTouches)return!1;let t=this.touches.get(e);return t?t.justTouched:!1}isTouchJustReleased(e){if(e<0||e>=this.maxTouches)return!1;let t=this.touches.get(e);return t?t.justReleased:!1}isAnyTouchJustStarted(){for(let e of this.touches.values())if(e.justTouched)return!0;return!1}getAllTouches(){return Array.from(this.touches.values())}setMobileCallbacks(e){this.mobileCallbacks={...this.mobileCallbacks,...e}}clearMobileCallbacks(){this.mobileCallbacks={}}setCallbacks(e){this.isMobileCallbacks(e)&&this.setMobileCallbacks(e)}isMobileCallbacks(e){return typeof e=="object"&&e!==null&&("onTouchStart"in e||"onTouchEnd"in e||"onTouchMove"in e||"onTouchCancel"in e||"onOrientationChange"in e)}handleTouchStart(e){try{this.mobileConfig.preventDefault&&e.preventDefault();let t=Array.from(e.changedTouches),i=[];for(let s of t){if(this.touches.size>=this.maxTouches)break;let n=-1;for(let v=0;v<this.maxTouches;v++)if(!this.touches.has(v)){n=v;break}if(n===-1)continue;let c=new C.Vector2(s.clientX,s.clientY),w={id:n,nativeId:s.identifier,position:c.clone(),startPosition:c.clone(),active:!0,justTouched:!0,justReleased:!1};this.touches.set(n,w),this.nativeToInternal.set(s.identifier,n),i.push(w),console.warn(`\u{1F446} Touch START - ID: ${n}`)}this.mobileCallbacks.onTouchStart?.(i,e)}catch(t){console.error("Error in touch start handler:",t)}}handleTouchEnd(e){try{this.mobileConfig.preventDefault&&e.preventDefault();let t=Array.from(e.changedTouches),i=[];for(let s of t){let n=this.nativeToInternal.get(s.identifier);if(n!==void 0){let c=this.touches.get(n);c&&(c.justReleased=!0,c.justTouched=!1,i.push({...c}))}}for(let s of t){let n=this.nativeToInternal.get(s.identifier);n!==void 0&&(this.touches.delete(n),this.nativeToInternal.delete(s.identifier),console.warn(`\u{1F447} Touch END - ID: ${n}`))}this.mobileCallbacks.onTouchEnd?.(i,e)}catch(t){console.error("Error in touch end handler:",t)}}handleTouchMove(e){try{let t=Array.from(e.changedTouches);this.mobileConfig.debug&&(!this.lastLogTime||Date.now()-this.lastLogTime>200)&&(console.warn(`\u{1F504} TouchMove event - ${t.length} touches changed`),this.lastLogTime=Date.now());for(let i of t){let s=this.nativeToInternal.get(i.identifier);if(s!==void 0){let n=this.touches.get(s);if(n){let c=n.position.clone();n.position=new C.Vector2(i.clientX,i.clientY),this.mobileConfig.debug&&(!this.lastLogTime||Date.now()-this.lastLogTime>200)&&console.warn(`\u{1F504} Updated touch ${n.id} (native ${i.identifier}) - ${c.x.toFixed(1)},${c.y.toFixed(1)} \u2192 ${i.clientX.toFixed(1)},${i.clientY.toFixed(1)}`)}}else this.mobileConfig.debug&&console.warn(`\u26A0\uFE0F Touch move for unknown native ID ${i.identifier}`)}this.mobileCallbacks.onTouchMove?.(this.getAllTouches(),e)}catch(t){console.error("Error in touch move handler:",t)}}handleTouchCancel(e){try{this.mobileConfig.preventDefault&&e.preventDefault();let t=[],i=Array.from(e.changedTouches);for(let s of i){let n=this.nativeToInternal.get(s.identifier);if(n!==void 0){let c=this.touches.get(n);c&&(c.justReleased=!0,c.justTouched=!1,t.push({...c}))}}for(let s of i){let n=this.nativeToInternal.get(s.identifier);n!==void 0&&(this.touches.delete(n),this.nativeToInternal.delete(s.identifier),this.mobileConfig.debug&&console.warn(`\u274C Touch CANCEL - ID: ${n}, nativeId: ${s.identifier}`))}this.mobileCallbacks.onTouchCancel?.(t,e)}catch(t){console.error("Error in touch cancel handler:",t)}}handleOrientationChange(e){try{let t=(window.screen.orientation&&window.screen.orientation.angle)??window.orientation??0;this.mobileCallbacks.onOrientationChange?.(t)}catch(t){console.error("Error in orientation change handler:",t)}}};h(M,"MobileInputs");var p=M;function x(a,o,e){console.warn("[MobileInputs] useMobileInputs() is deprecated and causes memory leaks. Use useMemo + useEffect instead.");let t=new p(a,e);return o&&t.setCallbacks(o),t.start(),t}h(x,"useMobileInputs");var l={tap:10,mediumTap:25,heavyTap:50,success:[30,50,30],error:[50,30,50,30,50],warning:[100],selection:5,impactLight:15,impactMedium:30,impactHeavy:50,notification:[100,100,100,100,100],sos:[100,30,100,30,100,30,200,30,200,30,200,30,100,30,100,30,100]},y=class y{constructor(o={}){r(this,"config");r(this,"supported",!1);r(this,"userActivated",!1);this.config={enabled:o.enabled??!0,debug:o.debug??!1,intensity:Math.max(0,Math.min(1,o.intensity??1))},this.supported=typeof navigator<"u"&&"vibrate"in navigator,this.config.debug&&console.log(`[MobileVibration] Vibration API supported: ${this.supported}`)}isSupported(){return this.supported}isEnabled(){return this.config.enabled&&this.supported}setEnabled(o){this.config.enabled=o,this.config.debug&&console.log(`[MobileVibration] Enabled: ${o}`)}setIntensity(o){this.config.intensity=Math.max(0,Math.min(1,o)),this.config.debug&&console.log(`[MobileVibration] Intensity set to: ${this.config.intensity}`)}getIntensity(){return this.config.intensity}vibrate(o){if(!this.isEnabled())return!1;try{let e=this.scalePattern(o),t=typeof e=="number"?e:[...e],i=navigator.vibrate(t);return this.config.debug&&console.log(`[MobileVibration] Vibrate: ${JSON.stringify(e)} -> ${i}`),i&&(this.userActivated=!0),i}catch(e){return this.config.debug&&console.error("[MobileVibration] Vibration failed:",e),!1}}cancel(){this.supported&&(navigator.vibrate(0),this.config.debug&&console.log("[MobileVibration] Vibration cancelled"))}hasUserActivation(){return this.userActivated}tap(){return this.vibrate(l.tap)}mediumTap(){return this.vibrate(l.mediumTap)}heavyTap(){return this.vibrate(l.heavyTap)}success(){return this.vibrate(l.success)}error(){return this.vibrate(l.error)}warning(){return this.vibrate(l.warning)}selection(){return this.vibrate(l.selection)}impactLight(){return this.vibrate(l.impactLight)}impactMedium(){return this.vibrate(l.impactMedium)}impactHeavy(){return this.vibrate(l.impactHeavy)}notification(){return this.vibrate(l.notification)}scalePattern(o){return this.config.intensity===1?o:typeof o=="number"?Math.round(o*this.config.intensity):o.map((e,t)=>t%2===0?Math.round(e*this.config.intensity):e)}};h(y,"MobileVibration");var f=y,E=null;function k(){return E||(E=new f),E}h(k,"getMobileVibration");
1
+ "use strict";var p=Object.defineProperty;var I=Object.getOwnPropertyDescriptor;var L=Object.getOwnPropertyNames;var A=Object.prototype.hasOwnProperty;var H=(s,o,e)=>o in s?p(s,o,{enumerable:!0,configurable:!0,writable:!0,value:e}):s[o]=e;var b=(s,o)=>p(s,"name",{value:o,configurable:!0});var S=(s,o)=>{for(var e in o)p(s,e,{get:o[e],enumerable:!0})},R=(s,o,e,t)=>{if(o&&typeof o=="object"||typeof o=="function")for(let i of L(o))!A.call(s,i)&&i!==e&&p(s,i,{get:()=>o[i],enumerable:!(t=I(o,i))||t.enumerable});return s};var $=s=>R(p({},"__esModule",{value:!0}),s);var a=(s,o,e)=>(H(s,typeof o!="symbol"?o+"":o,e),e);var j={};S(j,{BaseInputs:()=>d,InputDeviceType:()=>g.InputDeviceType,InputEventType:()=>T,MobileInputs:()=>f,MobileVibration:()=>v,TouchInput:()=>g.TouchInput,Vector2:()=>D.Vector2,VibrationPatterns:()=>l,getMobileVibration:()=>V,useMobileInputs:()=>P});module.exports=$(j);var D=require("@utsp/types"),g=require("@utsp/types");var T=(u=>(u.KeyDown="keydown",u.KeyUp="keyup",u.MouseDown="mousedown",u.MouseUp="mouseup",u.MouseMove="mousemove",u.MouseWheel="mousewheel",u.TouchStart="touchstart",u.TouchEnd="touchend",u.TouchMove="touchmove",u.GamepadConnected="gamepadconnected",u.GamepadDisconnected="gamepaddisconnected",u.GamepadButton="gamepadbutton",u.GamepadAxis="gamepadaxis",u))(T||{}),C=class C{constructor(o=window,e={}){a(this,"isActive",!1);a(this,"targetElement");a(this,"config");a(this,"callbacks",{});this.targetElement=o,this.config={enabled:!0,preventDefault:!1,stopPropagation:!1,debug:!1,...e}}isListening(){return this.isActive}destroy(){this.stop(),this.clearCallbacks()}setCallbacks(o){typeof o=="object"&&o!==null&&Object.assign(this.callbacks,o)}clearCallbacks(){this.callbacks={}}getTargetElement(){return this.targetElement}enable(){this.config.enabled=!0,this.isActive||this.start()}disable(){this.config.enabled=!1,this.isActive&&this.stop()}isEnabled(){return this.config.enabled??!0}emit(o,...e){this.callbacks[o]&&this.callbacks[o].forEach(t=>{try{t(...e)}catch(i){this.config.debug&&console.error(`Error in ${o} callback:`,i)}})}log(...o){this.config.debug&&console.warn("[InputSystem]",...o)}};b(C,"BaseInputs");var d=C;var m=require("@utsp/types");var M=class M extends d{constructor(e=window,t={}){super(e,t);a(this,"touches",new Map);a(this,"nativeToInternal",new Map);a(this,"mobileCallbacks",{});a(this,"mobileConfig");a(this,"maxTouches",10);a(this,"lastLogTime",0);a(this,"boundHandlers");this.mobileConfig={targetElement:e,preventDefault:t.preventDefault??!1,passive:t.passive??!0,maxTouches:t.maxTouches??10,enabled:t.enabled??!0,debug:t.debug??!1,stopPropagation:t.stopPropagation??!1},this.maxTouches=this.mobileConfig.maxTouches,this.mobileConfig.preventDefault&&this.mobileConfig.passive&&(console.warn("[MobileInputs] passive=true prevents preventDefault() from working! Setting passive=false."),this.mobileConfig.passive=!1),this.boundHandlers={touchStart:this.handleTouchStart.bind(this),touchEnd:this.handleTouchEnd.bind(this),touchMove:this.handleTouchMove.bind(this),touchCancel:this.handleTouchCancel.bind(this),orientationChange:this.handleOrientationChange.bind(this)}}start(){if(this.isActive)return;let e={passive:!this.mobileConfig.preventDefault&&this.mobileConfig.passive};this.targetElement.addEventListener("touchstart",this.boundHandlers.touchStart,e),this.targetElement.addEventListener("touchend",this.boundHandlers.touchEnd,e),this.targetElement.addEventListener("touchmove",this.boundHandlers.touchMove,e),this.targetElement.addEventListener("touchcancel",this.boundHandlers.touchCancel,e),window.addEventListener("orientationchange",this.boundHandlers.orientationChange),this.isActive=!0}stop(){this.isActive&&(this.targetElement.removeEventListener("touchstart",this.boundHandlers.touchStart),this.targetElement.removeEventListener("touchend",this.boundHandlers.touchEnd),this.targetElement.removeEventListener("touchmove",this.boundHandlers.touchMove),this.targetElement.removeEventListener("touchcancel",this.boundHandlers.touchCancel),window.removeEventListener("orientationchange",this.boundHandlers.orientationChange),this.isActive=!1)}reset(){this.touches.clear(),this.nativeToInternal.clear()}resetDelta(){}poll(){let e=[];for(let[t,i]of this.touches.entries())i.justReleased&&(e.push(t),this.nativeToInternal.delete(i.nativeId)),i.justTouched=!1,i.justReleased=!1;for(let t of e)this.touches.delete(t)}isTouchActive(e){if(e<0||e>=this.maxTouches)return!1;let t=this.touches.get(e);return t?t.active:!1}getTouchPosition(e){if(e<0||e>=this.maxTouches)return null;let t=this.touches.get(e);return t?t.position.clone():null}getTouchStartPosition(e){if(e<0||e>=this.maxTouches)return null;let t=this.touches.get(e);return t?t.startPosition.clone():null}getTouchDelta(e){if(e<0||e>=this.maxTouches)return null;let t=this.touches.get(e);return t?t.position.subtract(t.startPosition):null}getTouchCount(){let e=0;for(let t of this.touches.values())t.active&&e++;return e}isTouchJustStarted(e){if(e<0||e>=this.maxTouches)return!1;let t=this.touches.get(e);return t?t.justTouched:!1}isTouchJustReleased(e){if(e<0||e>=this.maxTouches)return!1;let t=this.touches.get(e);return t?t.justReleased:!1}isAnyTouchJustStarted(){for(let e of this.touches.values())if(e.justTouched)return!0;return!1}isAnyTouchJustReleased(){for(let e of this.touches.values())if(e.justReleased)return!0;return!1}getJustReleasedTouches(){return Array.from(this.touches.values()).filter(e=>e.justReleased)}getAllTouches(){return Array.from(this.touches.values()).filter(e=>e.active)}setMobileCallbacks(e){this.mobileCallbacks={...this.mobileCallbacks,...e}}clearMobileCallbacks(){this.mobileCallbacks={}}setCallbacks(e){this.isMobileCallbacks(e)&&this.setMobileCallbacks(e)}isMobileCallbacks(e){return typeof e=="object"&&e!==null&&("onTouchStart"in e||"onTouchEnd"in e||"onTouchMove"in e||"onTouchCancel"in e||"onOrientationChange"in e)}handleTouchStart(e){try{this.mobileConfig.preventDefault&&e.preventDefault();let t=Array.from(e.changedTouches),i=[];for(let r of t){if(this.touches.size>=this.maxTouches)break;let c=this.nativeToInternal.get(r.identifier);if(c!==void 0){let h=this.touches.get(c);if(h){let k=new m.Vector2(r.clientX,r.clientY);h.position=k.clone(),h.startPosition=k.clone(),h.active=!0,h.justTouched=!0,h.justReleased=!1,i.push({...h})}continue}let n=-1;for(let h=0;h<this.maxTouches;h++)if(!this.touches.has(h)){n=h;break}if(n===-1)continue;let w=new m.Vector2(r.clientX,r.clientY),x={id:n,nativeId:r.identifier,position:w.clone(),startPosition:w.clone(),active:!0,justTouched:!0,justReleased:!1};this.touches.set(n,x),this.nativeToInternal.set(r.identifier,n),i.push(x),console.warn(`\u{1F446} Touch START - ID: ${n}`)}this.mobileCallbacks.onTouchStart?.(i,e)}catch(t){console.error("Error in touch start handler:",t)}}handleTouchEnd(e){try{this.mobileConfig.preventDefault&&e.preventDefault();let t=Array.from(e.changedTouches),i=[];for(let r of t){let c=this.nativeToInternal.get(r.identifier);if(c!==void 0){let n=this.touches.get(c);n&&(n.justReleased=!0,n.justTouched=!1,n.active=!1,i.push({...n}),console.warn(`\u{1F447} Touch END - ID: ${c}`))}}this.mobileCallbacks.onTouchEnd?.(i,e)}catch(t){console.error("Error in touch end handler:",t)}}handleTouchMove(e){try{let t=Array.from(e.changedTouches);this.mobileConfig.debug&&(!this.lastLogTime||Date.now()-this.lastLogTime>200)&&(console.warn(`\u{1F504} TouchMove event - ${t.length} touches changed`),this.lastLogTime=Date.now());for(let i of t){let r=this.nativeToInternal.get(i.identifier);if(r!==void 0){let c=this.touches.get(r);if(c){let n=c.position.clone();c.position=new m.Vector2(i.clientX,i.clientY),this.mobileConfig.debug&&(!this.lastLogTime||Date.now()-this.lastLogTime>200)&&console.warn(`\u{1F504} Updated touch ${c.id} (native ${i.identifier}) - ${n.x.toFixed(1)},${n.y.toFixed(1)} \u2192 ${i.clientX.toFixed(1)},${i.clientY.toFixed(1)}`)}}else this.mobileConfig.debug&&console.warn(`\u26A0\uFE0F Touch move for unknown native ID ${i.identifier}`)}this.mobileCallbacks.onTouchMove?.(this.getAllTouches(),e)}catch(t){console.error("Error in touch move handler:",t)}}handleTouchCancel(e){try{this.mobileConfig.preventDefault&&e.preventDefault();let t=[],i=Array.from(e.changedTouches);for(let r of i){let c=this.nativeToInternal.get(r.identifier);if(c!==void 0){let n=this.touches.get(c);n&&(n.justReleased=!0,n.justTouched=!1,n.active=!1,t.push({...n}),this.mobileConfig.debug&&console.warn(`\u274C Touch CANCEL - ID: ${c}, nativeId: ${r.identifier}`))}}this.mobileCallbacks.onTouchCancel?.(t,e)}catch(t){console.error("Error in touch cancel handler:",t)}}handleOrientationChange(e){try{let t=(window.screen.orientation&&window.screen.orientation.angle)??window.orientation??0;this.mobileCallbacks.onOrientationChange?.(t)}catch(t){console.error("Error in orientation change handler:",t)}}};b(M,"MobileInputs");var f=M;function P(s,o,e){console.warn("[MobileInputs] useMobileInputs() is deprecated and causes memory leaks. Use useMemo + useEffect instead.");let t=new f(s,e);return o&&t.setCallbacks(o),t.start(),t}b(P,"useMobileInputs");var l={tap:10,mediumTap:25,heavyTap:50,success:[30,50,30],error:[50,30,50,30,50],warning:[100],selection:5,impactLight:15,impactMedium:30,impactHeavy:50,notification:[100,100,100,100,100],sos:[100,30,100,30,100,30,200,30,200,30,200,30,100,30,100,30,100]},y=class y{constructor(o={}){a(this,"config");a(this,"supported",!1);a(this,"userActivated",!1);this.config={enabled:o.enabled??!0,debug:o.debug??!1,intensity:Math.max(0,Math.min(1,o.intensity??1))},this.supported=typeof navigator<"u"&&"vibrate"in navigator,this.config.debug&&console.log(`[MobileVibration] Vibration API supported: ${this.supported}`)}isSupported(){return this.supported}isEnabled(){return this.config.enabled&&this.supported}setEnabled(o){this.config.enabled=o,this.config.debug&&console.log(`[MobileVibration] Enabled: ${o}`)}setIntensity(o){this.config.intensity=Math.max(0,Math.min(1,o)),this.config.debug&&console.log(`[MobileVibration] Intensity set to: ${this.config.intensity}`)}getIntensity(){return this.config.intensity}vibrate(o){if(!this.isEnabled())return!1;try{let e=this.scalePattern(o),t=typeof e=="number"?e:[...e],i=navigator.vibrate(t);return this.config.debug&&console.log(`[MobileVibration] Vibrate: ${JSON.stringify(e)} -> ${i}`),i&&(this.userActivated=!0),i}catch(e){return this.config.debug&&console.error("[MobileVibration] Vibration failed:",e),!1}}cancel(){this.supported&&(navigator.vibrate(0),this.config.debug&&console.log("[MobileVibration] Vibration cancelled"))}hasUserActivation(){return this.userActivated}tap(){return this.vibrate(l.tap)}mediumTap(){return this.vibrate(l.mediumTap)}heavyTap(){return this.vibrate(l.heavyTap)}success(){return this.vibrate(l.success)}error(){return this.vibrate(l.error)}warning(){return this.vibrate(l.warning)}selection(){return this.vibrate(l.selection)}impactLight(){return this.vibrate(l.impactLight)}impactMedium(){return this.vibrate(l.impactMedium)}impactHeavy(){return this.vibrate(l.impactHeavy)}notification(){return this.vibrate(l.notification)}scalePattern(o){return this.config.intensity===1?o:typeof o=="number"?Math.round(o*this.config.intensity):o.map((e,t)=>t%2===0?Math.round(e*this.config.intensity):e)}};b(y,"MobileVibration");var v=y,E=null;function V(){return E||(E=new v),E}b(V,"getMobileVibration");
package/dist/touch.d.ts CHANGED
@@ -218,6 +218,7 @@ declare class MobileInputs extends BaseInputs {
218
218
  /**
219
219
  * Poll - Reset transient states (justTouched/justReleased)
220
220
  * Should be called once per frame AFTER collecting input
221
+ * Also cleans up released touches that were kept for one frame
221
222
  */
222
223
  poll(): void;
223
224
  /**
@@ -330,6 +331,16 @@ declare class MobileInputs extends BaseInputs {
330
331
  * Check if any touch just started this frame
331
332
  */
332
333
  isAnyTouchJustStarted(): boolean;
334
+ /**
335
+ * Check if any touch just ended this frame
336
+ */
337
+ isAnyTouchJustReleased(): boolean;
338
+ /**
339
+ * Get all touches that were just released this frame
340
+ *
341
+ * @returns Array of TouchPoint objects that were just released
342
+ */
343
+ getJustReleasedTouches(): TouchPoint[];
333
344
  /**
334
345
  * Get all active touches
335
346
  *
package/dist/touch.mjs CHANGED
@@ -1 +1 @@
1
- var M=Object.defineProperty;var w=(l,o,e)=>o in l?M(l,o,{enumerable:!0,configurable:!0,writable:!0,value:e}):l[o]=e;var h=(l,o)=>M(l,"name",{value:o,configurable:!0});var a=(l,o,e)=>(w(l,typeof o!="symbol"?o+"":o,e),e);import{Vector2 as W}from"@utsp/types";import{InputDeviceType as U,TouchInput as B}from"@utsp/types";var E=(c=>(c.KeyDown="keydown",c.KeyUp="keyup",c.MouseDown="mousedown",c.MouseUp="mouseup",c.MouseMove="mousemove",c.MouseWheel="mousewheel",c.TouchStart="touchstart",c.TouchEnd="touchend",c.TouchMove="touchmove",c.GamepadConnected="gamepadconnected",c.GamepadDisconnected="gamepaddisconnected",c.GamepadButton="gamepadbutton",c.GamepadAxis="gamepadaxis",c))(E||{}),v=class v{constructor(o=window,e={}){a(this,"isActive",!1);a(this,"targetElement");a(this,"config");a(this,"callbacks",{});this.targetElement=o,this.config={enabled:!0,preventDefault:!1,stopPropagation:!1,debug:!1,...e}}isListening(){return this.isActive}destroy(){this.stop(),this.clearCallbacks()}setCallbacks(o){typeof o=="object"&&o!==null&&Object.assign(this.callbacks,o)}clearCallbacks(){this.callbacks={}}getTargetElement(){return this.targetElement}enable(){this.config.enabled=!0,this.isActive||this.start()}disable(){this.config.enabled=!1,this.isActive&&this.stop()}isEnabled(){return this.config.enabled??!0}emit(o,...e){this.callbacks[o]&&this.callbacks[o].forEach(t=>{try{t(...e)}catch(n){this.config.debug&&console.error(`Error in ${o} callback:`,n)}})}log(...o){this.config.debug&&console.warn("[InputSystem]",...o)}};h(v,"BaseInputs");var b=v;import{Vector2 as y}from"@utsp/types";var m=class m extends b{constructor(e=window,t={}){super(e,t);a(this,"touches",new Map);a(this,"nativeToInternal",new Map);a(this,"mobileCallbacks",{});a(this,"mobileConfig");a(this,"maxTouches",10);a(this,"lastLogTime",0);a(this,"boundHandlers");this.mobileConfig={targetElement:e,preventDefault:t.preventDefault??!0,passive:t.passive??!1,maxTouches:t.maxTouches??10,enabled:t.enabled??!0,debug:t.debug??!1,stopPropagation:t.stopPropagation??!1},this.maxTouches=this.mobileConfig.maxTouches,this.mobileConfig.preventDefault&&this.mobileConfig.passive&&(console.warn("[MobileInputs] passive=true prevents preventDefault() from working! Setting passive=false."),this.mobileConfig.passive=!1),this.boundHandlers={touchStart:this.handleTouchStart.bind(this),touchEnd:this.handleTouchEnd.bind(this),touchMove:this.handleTouchMove.bind(this),touchCancel:this.handleTouchCancel.bind(this),orientationChange:this.handleOrientationChange.bind(this)}}start(){if(this.isActive)return;let e={passive:!this.mobileConfig.preventDefault&&this.mobileConfig.passive};this.targetElement.addEventListener("touchstart",this.boundHandlers.touchStart,e),this.targetElement.addEventListener("touchend",this.boundHandlers.touchEnd,e),this.targetElement.addEventListener("touchmove",this.boundHandlers.touchMove,e),this.targetElement.addEventListener("touchcancel",this.boundHandlers.touchCancel,e),window.addEventListener("orientationchange",this.boundHandlers.orientationChange),this.isActive=!0}stop(){this.isActive&&(this.targetElement.removeEventListener("touchstart",this.boundHandlers.touchStart),this.targetElement.removeEventListener("touchend",this.boundHandlers.touchEnd),this.targetElement.removeEventListener("touchmove",this.boundHandlers.touchMove),this.targetElement.removeEventListener("touchcancel",this.boundHandlers.touchCancel),window.removeEventListener("orientationchange",this.boundHandlers.orientationChange),this.isActive=!1)}reset(){this.touches.clear(),this.nativeToInternal.clear()}resetDelta(){}poll(){for(let e of this.touches.values())e.justTouched=!1,e.justReleased=!1}isTouchActive(e){return e<0||e>=this.maxTouches?!1:this.touches.has(e)}getTouchPosition(e){if(e<0||e>=this.maxTouches)return null;let t=this.touches.get(e);return t?t.position.clone():null}getTouchStartPosition(e){if(e<0||e>=this.maxTouches)return null;let t=this.touches.get(e);return t?t.startPosition.clone():null}getTouchDelta(e){if(e<0||e>=this.maxTouches)return null;let t=this.touches.get(e);return t?t.position.subtract(t.startPosition):null}getTouchCount(){return this.touches.size}isTouchJustStarted(e){if(e<0||e>=this.maxTouches)return!1;let t=this.touches.get(e);return t?t.justTouched:!1}isTouchJustReleased(e){if(e<0||e>=this.maxTouches)return!1;let t=this.touches.get(e);return t?t.justReleased:!1}isAnyTouchJustStarted(){for(let e of this.touches.values())if(e.justTouched)return!0;return!1}getAllTouches(){return Array.from(this.touches.values())}setMobileCallbacks(e){this.mobileCallbacks={...this.mobileCallbacks,...e}}clearMobileCallbacks(){this.mobileCallbacks={}}setCallbacks(e){this.isMobileCallbacks(e)&&this.setMobileCallbacks(e)}isMobileCallbacks(e){return typeof e=="object"&&e!==null&&("onTouchStart"in e||"onTouchEnd"in e||"onTouchMove"in e||"onTouchCancel"in e||"onOrientationChange"in e)}handleTouchStart(e){try{this.mobileConfig.preventDefault&&e.preventDefault();let t=Array.from(e.changedTouches),n=[];for(let s of t){if(this.touches.size>=this.maxTouches)break;let i=-1;for(let d=0;d<this.maxTouches;d++)if(!this.touches.has(d)){i=d;break}if(i===-1)continue;let r=new y(s.clientX,s.clientY),C={id:i,nativeId:s.identifier,position:r.clone(),startPosition:r.clone(),active:!0,justTouched:!0,justReleased:!1};this.touches.set(i,C),this.nativeToInternal.set(s.identifier,i),n.push(C),console.warn(`\u{1F446} Touch START - ID: ${i}`)}this.mobileCallbacks.onTouchStart?.(n,e)}catch(t){console.error("Error in touch start handler:",t)}}handleTouchEnd(e){try{this.mobileConfig.preventDefault&&e.preventDefault();let t=Array.from(e.changedTouches),n=[];for(let s of t){let i=this.nativeToInternal.get(s.identifier);if(i!==void 0){let r=this.touches.get(i);r&&(r.justReleased=!0,r.justTouched=!1,n.push({...r}))}}for(let s of t){let i=this.nativeToInternal.get(s.identifier);i!==void 0&&(this.touches.delete(i),this.nativeToInternal.delete(s.identifier),console.warn(`\u{1F447} Touch END - ID: ${i}`))}this.mobileCallbacks.onTouchEnd?.(n,e)}catch(t){console.error("Error in touch end handler:",t)}}handleTouchMove(e){try{let t=Array.from(e.changedTouches);this.mobileConfig.debug&&(!this.lastLogTime||Date.now()-this.lastLogTime>200)&&(console.warn(`\u{1F504} TouchMove event - ${t.length} touches changed`),this.lastLogTime=Date.now());for(let n of t){let s=this.nativeToInternal.get(n.identifier);if(s!==void 0){let i=this.touches.get(s);if(i){let r=i.position.clone();i.position=new y(n.clientX,n.clientY),this.mobileConfig.debug&&(!this.lastLogTime||Date.now()-this.lastLogTime>200)&&console.warn(`\u{1F504} Updated touch ${i.id} (native ${n.identifier}) - ${r.x.toFixed(1)},${r.y.toFixed(1)} \u2192 ${n.clientX.toFixed(1)},${n.clientY.toFixed(1)}`)}}else this.mobileConfig.debug&&console.warn(`\u26A0\uFE0F Touch move for unknown native ID ${n.identifier}`)}this.mobileCallbacks.onTouchMove?.(this.getAllTouches(),e)}catch(t){console.error("Error in touch move handler:",t)}}handleTouchCancel(e){try{this.mobileConfig.preventDefault&&e.preventDefault();let t=[],n=Array.from(e.changedTouches);for(let s of n){let i=this.nativeToInternal.get(s.identifier);if(i!==void 0){let r=this.touches.get(i);r&&(r.justReleased=!0,r.justTouched=!1,t.push({...r}))}}for(let s of n){let i=this.nativeToInternal.get(s.identifier);i!==void 0&&(this.touches.delete(i),this.nativeToInternal.delete(s.identifier),this.mobileConfig.debug&&console.warn(`\u274C Touch CANCEL - ID: ${i}, nativeId: ${s.identifier}`))}this.mobileCallbacks.onTouchCancel?.(t,e)}catch(t){console.error("Error in touch cancel handler:",t)}}handleOrientationChange(e){try{let t=(window.screen.orientation&&window.screen.orientation.angle)??window.orientation??0;this.mobileCallbacks.onOrientationChange?.(t)}catch(t){console.error("Error in orientation change handler:",t)}}};h(m,"MobileInputs");var p=m;function x(l,o,e){console.warn("[MobileInputs] useMobileInputs() is deprecated and causes memory leaks. Use useMemo + useEffect instead.");let t=new p(l,e);return o&&t.setCallbacks(o),t.start(),t}h(x,"useMobileInputs");var u={tap:10,mediumTap:25,heavyTap:50,success:[30,50,30],error:[50,30,50,30,50],warning:[100],selection:5,impactLight:15,impactMedium:30,impactHeavy:50,notification:[100,100,100,100,100],sos:[100,30,100,30,100,30,200,30,200,30,200,30,100,30,100,30,100]},T=class T{constructor(o={}){a(this,"config");a(this,"supported",!1);a(this,"userActivated",!1);this.config={enabled:o.enabled??!0,debug:o.debug??!1,intensity:Math.max(0,Math.min(1,o.intensity??1))},this.supported=typeof navigator<"u"&&"vibrate"in navigator,this.config.debug&&console.log(`[MobileVibration] Vibration API supported: ${this.supported}`)}isSupported(){return this.supported}isEnabled(){return this.config.enabled&&this.supported}setEnabled(o){this.config.enabled=o,this.config.debug&&console.log(`[MobileVibration] Enabled: ${o}`)}setIntensity(o){this.config.intensity=Math.max(0,Math.min(1,o)),this.config.debug&&console.log(`[MobileVibration] Intensity set to: ${this.config.intensity}`)}getIntensity(){return this.config.intensity}vibrate(o){if(!this.isEnabled())return!1;try{let e=this.scalePattern(o),t=typeof e=="number"?e:[...e],n=navigator.vibrate(t);return this.config.debug&&console.log(`[MobileVibration] Vibrate: ${JSON.stringify(e)} -> ${n}`),n&&(this.userActivated=!0),n}catch(e){return this.config.debug&&console.error("[MobileVibration] Vibration failed:",e),!1}}cancel(){this.supported&&(navigator.vibrate(0),this.config.debug&&console.log("[MobileVibration] Vibration cancelled"))}hasUserActivation(){return this.userActivated}tap(){return this.vibrate(u.tap)}mediumTap(){return this.vibrate(u.mediumTap)}heavyTap(){return this.vibrate(u.heavyTap)}success(){return this.vibrate(u.success)}error(){return this.vibrate(u.error)}warning(){return this.vibrate(u.warning)}selection(){return this.vibrate(u.selection)}impactLight(){return this.vibrate(u.impactLight)}impactMedium(){return this.vibrate(u.impactMedium)}impactHeavy(){return this.vibrate(u.impactHeavy)}notification(){return this.vibrate(u.notification)}scalePattern(o){return this.config.intensity===1?o:typeof o=="number"?Math.round(o*this.config.intensity):o.map((e,t)=>t%2===0?Math.round(e*this.config.intensity):e)}};h(T,"MobileVibration");var f=T,g=null;function k(){return g||(g=new f),g}h(k,"getMobileVibration");export{b as BaseInputs,U as InputDeviceType,E as InputEventType,p as MobileInputs,f as MobileVibration,B as TouchInput,W as Vector2,u as VibrationPatterns,k as getMobileVibration,x as useMobileInputs};
1
+ var w=Object.defineProperty;var k=(h,o,e)=>o in h?w(h,o,{enumerable:!0,configurable:!0,writable:!0,value:e}):h[o]=e;var b=(h,o)=>w(h,"name",{value:o,configurable:!0});var s=(h,o,e)=>(k(h,typeof o!="symbol"?o+"":o,e),e);import{Vector2 as J}from"@utsp/types";import{InputDeviceType as B,TouchInput as F}from"@utsp/types";var x=(c=>(c.KeyDown="keydown",c.KeyUp="keyup",c.MouseDown="mousedown",c.MouseUp="mouseup",c.MouseMove="mousemove",c.MouseWheel="mousewheel",c.TouchStart="touchstart",c.TouchEnd="touchend",c.TouchMove="touchmove",c.GamepadConnected="gamepadconnected",c.GamepadDisconnected="gamepaddisconnected",c.GamepadButton="gamepadbutton",c.GamepadAxis="gamepadaxis",c))(x||{}),v=class v{constructor(o=window,e={}){s(this,"isActive",!1);s(this,"targetElement");s(this,"config");s(this,"callbacks",{});this.targetElement=o,this.config={enabled:!0,preventDefault:!1,stopPropagation:!1,debug:!1,...e}}isListening(){return this.isActive}destroy(){this.stop(),this.clearCallbacks()}setCallbacks(o){typeof o=="object"&&o!==null&&Object.assign(this.callbacks,o)}clearCallbacks(){this.callbacks={}}getTargetElement(){return this.targetElement}enable(){this.config.enabled=!0,this.isActive||this.start()}disable(){this.config.enabled=!1,this.isActive&&this.stop()}isEnabled(){return this.config.enabled??!0}emit(o,...e){this.callbacks[o]&&this.callbacks[o].forEach(t=>{try{t(...e)}catch(i){this.config.debug&&console.error(`Error in ${o} callback:`,i)}})}log(...o){this.config.debug&&console.warn("[InputSystem]",...o)}};b(v,"BaseInputs");var d=v;import{Vector2 as m}from"@utsp/types";var g=class g extends d{constructor(e=window,t={}){super(e,t);s(this,"touches",new Map);s(this,"nativeToInternal",new Map);s(this,"mobileCallbacks",{});s(this,"mobileConfig");s(this,"maxTouches",10);s(this,"lastLogTime",0);s(this,"boundHandlers");this.mobileConfig={targetElement:e,preventDefault:t.preventDefault??!1,passive:t.passive??!0,maxTouches:t.maxTouches??10,enabled:t.enabled??!0,debug:t.debug??!1,stopPropagation:t.stopPropagation??!1},this.maxTouches=this.mobileConfig.maxTouches,this.mobileConfig.preventDefault&&this.mobileConfig.passive&&(console.warn("[MobileInputs] passive=true prevents preventDefault() from working! Setting passive=false."),this.mobileConfig.passive=!1),this.boundHandlers={touchStart:this.handleTouchStart.bind(this),touchEnd:this.handleTouchEnd.bind(this),touchMove:this.handleTouchMove.bind(this),touchCancel:this.handleTouchCancel.bind(this),orientationChange:this.handleOrientationChange.bind(this)}}start(){if(this.isActive)return;let e={passive:!this.mobileConfig.preventDefault&&this.mobileConfig.passive};this.targetElement.addEventListener("touchstart",this.boundHandlers.touchStart,e),this.targetElement.addEventListener("touchend",this.boundHandlers.touchEnd,e),this.targetElement.addEventListener("touchmove",this.boundHandlers.touchMove,e),this.targetElement.addEventListener("touchcancel",this.boundHandlers.touchCancel,e),window.addEventListener("orientationchange",this.boundHandlers.orientationChange),this.isActive=!0}stop(){this.isActive&&(this.targetElement.removeEventListener("touchstart",this.boundHandlers.touchStart),this.targetElement.removeEventListener("touchend",this.boundHandlers.touchEnd),this.targetElement.removeEventListener("touchmove",this.boundHandlers.touchMove),this.targetElement.removeEventListener("touchcancel",this.boundHandlers.touchCancel),window.removeEventListener("orientationchange",this.boundHandlers.orientationChange),this.isActive=!1)}reset(){this.touches.clear(),this.nativeToInternal.clear()}resetDelta(){}poll(){let e=[];for(let[t,i]of this.touches.entries())i.justReleased&&(e.push(t),this.nativeToInternal.delete(i.nativeId)),i.justTouched=!1,i.justReleased=!1;for(let t of e)this.touches.delete(t)}isTouchActive(e){if(e<0||e>=this.maxTouches)return!1;let t=this.touches.get(e);return t?t.active:!1}getTouchPosition(e){if(e<0||e>=this.maxTouches)return null;let t=this.touches.get(e);return t?t.position.clone():null}getTouchStartPosition(e){if(e<0||e>=this.maxTouches)return null;let t=this.touches.get(e);return t?t.startPosition.clone():null}getTouchDelta(e){if(e<0||e>=this.maxTouches)return null;let t=this.touches.get(e);return t?t.position.subtract(t.startPosition):null}getTouchCount(){let e=0;for(let t of this.touches.values())t.active&&e++;return e}isTouchJustStarted(e){if(e<0||e>=this.maxTouches)return!1;let t=this.touches.get(e);return t?t.justTouched:!1}isTouchJustReleased(e){if(e<0||e>=this.maxTouches)return!1;let t=this.touches.get(e);return t?t.justReleased:!1}isAnyTouchJustStarted(){for(let e of this.touches.values())if(e.justTouched)return!0;return!1}isAnyTouchJustReleased(){for(let e of this.touches.values())if(e.justReleased)return!0;return!1}getJustReleasedTouches(){return Array.from(this.touches.values()).filter(e=>e.justReleased)}getAllTouches(){return Array.from(this.touches.values()).filter(e=>e.active)}setMobileCallbacks(e){this.mobileCallbacks={...this.mobileCallbacks,...e}}clearMobileCallbacks(){this.mobileCallbacks={}}setCallbacks(e){this.isMobileCallbacks(e)&&this.setMobileCallbacks(e)}isMobileCallbacks(e){return typeof e=="object"&&e!==null&&("onTouchStart"in e||"onTouchEnd"in e||"onTouchMove"in e||"onTouchCancel"in e||"onOrientationChange"in e)}handleTouchStart(e){try{this.mobileConfig.preventDefault&&e.preventDefault();let t=Array.from(e.changedTouches),i=[];for(let a of t){if(this.touches.size>=this.maxTouches)break;let r=this.nativeToInternal.get(a.identifier);if(r!==void 0){let u=this.touches.get(r);if(u){let y=new m(a.clientX,a.clientY);u.position=y.clone(),u.startPosition=y.clone(),u.active=!0,u.justTouched=!0,u.justReleased=!1,i.push({...u})}continue}let n=-1;for(let u=0;u<this.maxTouches;u++)if(!this.touches.has(u)){n=u;break}if(n===-1)continue;let M=new m(a.clientX,a.clientY),E={id:n,nativeId:a.identifier,position:M.clone(),startPosition:M.clone(),active:!0,justTouched:!0,justReleased:!1};this.touches.set(n,E),this.nativeToInternal.set(a.identifier,n),i.push(E),console.warn(`\u{1F446} Touch START - ID: ${n}`)}this.mobileCallbacks.onTouchStart?.(i,e)}catch(t){console.error("Error in touch start handler:",t)}}handleTouchEnd(e){try{this.mobileConfig.preventDefault&&e.preventDefault();let t=Array.from(e.changedTouches),i=[];for(let a of t){let r=this.nativeToInternal.get(a.identifier);if(r!==void 0){let n=this.touches.get(r);n&&(n.justReleased=!0,n.justTouched=!1,n.active=!1,i.push({...n}),console.warn(`\u{1F447} Touch END - ID: ${r}`))}}this.mobileCallbacks.onTouchEnd?.(i,e)}catch(t){console.error("Error in touch end handler:",t)}}handleTouchMove(e){try{let t=Array.from(e.changedTouches);this.mobileConfig.debug&&(!this.lastLogTime||Date.now()-this.lastLogTime>200)&&(console.warn(`\u{1F504} TouchMove event - ${t.length} touches changed`),this.lastLogTime=Date.now());for(let i of t){let a=this.nativeToInternal.get(i.identifier);if(a!==void 0){let r=this.touches.get(a);if(r){let n=r.position.clone();r.position=new m(i.clientX,i.clientY),this.mobileConfig.debug&&(!this.lastLogTime||Date.now()-this.lastLogTime>200)&&console.warn(`\u{1F504} Updated touch ${r.id} (native ${i.identifier}) - ${n.x.toFixed(1)},${n.y.toFixed(1)} \u2192 ${i.clientX.toFixed(1)},${i.clientY.toFixed(1)}`)}}else this.mobileConfig.debug&&console.warn(`\u26A0\uFE0F Touch move for unknown native ID ${i.identifier}`)}this.mobileCallbacks.onTouchMove?.(this.getAllTouches(),e)}catch(t){console.error("Error in touch move handler:",t)}}handleTouchCancel(e){try{this.mobileConfig.preventDefault&&e.preventDefault();let t=[],i=Array.from(e.changedTouches);for(let a of i){let r=this.nativeToInternal.get(a.identifier);if(r!==void 0){let n=this.touches.get(r);n&&(n.justReleased=!0,n.justTouched=!1,n.active=!1,t.push({...n}),this.mobileConfig.debug&&console.warn(`\u274C Touch CANCEL - ID: ${r}, nativeId: ${a.identifier}`))}}this.mobileCallbacks.onTouchCancel?.(t,e)}catch(t){console.error("Error in touch cancel handler:",t)}}handleOrientationChange(e){try{let t=(window.screen.orientation&&window.screen.orientation.angle)??window.orientation??0;this.mobileCallbacks.onOrientationChange?.(t)}catch(t){console.error("Error in orientation change handler:",t)}}};b(g,"MobileInputs");var p=g;function P(h,o,e){console.warn("[MobileInputs] useMobileInputs() is deprecated and causes memory leaks. Use useMemo + useEffect instead.");let t=new p(h,e);return o&&t.setCallbacks(o),t.start(),t}b(P,"useMobileInputs");var l={tap:10,mediumTap:25,heavyTap:50,success:[30,50,30],error:[50,30,50,30,50],warning:[100],selection:5,impactLight:15,impactMedium:30,impactHeavy:50,notification:[100,100,100,100,100],sos:[100,30,100,30,100,30,200,30,200,30,200,30,100,30,100,30,100]},C=class C{constructor(o={}){s(this,"config");s(this,"supported",!1);s(this,"userActivated",!1);this.config={enabled:o.enabled??!0,debug:o.debug??!1,intensity:Math.max(0,Math.min(1,o.intensity??1))},this.supported=typeof navigator<"u"&&"vibrate"in navigator,this.config.debug&&console.log(`[MobileVibration] Vibration API supported: ${this.supported}`)}isSupported(){return this.supported}isEnabled(){return this.config.enabled&&this.supported}setEnabled(o){this.config.enabled=o,this.config.debug&&console.log(`[MobileVibration] Enabled: ${o}`)}setIntensity(o){this.config.intensity=Math.max(0,Math.min(1,o)),this.config.debug&&console.log(`[MobileVibration] Intensity set to: ${this.config.intensity}`)}getIntensity(){return this.config.intensity}vibrate(o){if(!this.isEnabled())return!1;try{let e=this.scalePattern(o),t=typeof e=="number"?e:[...e],i=navigator.vibrate(t);return this.config.debug&&console.log(`[MobileVibration] Vibrate: ${JSON.stringify(e)} -> ${i}`),i&&(this.userActivated=!0),i}catch(e){return this.config.debug&&console.error("[MobileVibration] Vibration failed:",e),!1}}cancel(){this.supported&&(navigator.vibrate(0),this.config.debug&&console.log("[MobileVibration] Vibration cancelled"))}hasUserActivation(){return this.userActivated}tap(){return this.vibrate(l.tap)}mediumTap(){return this.vibrate(l.mediumTap)}heavyTap(){return this.vibrate(l.heavyTap)}success(){return this.vibrate(l.success)}error(){return this.vibrate(l.error)}warning(){return this.vibrate(l.warning)}selection(){return this.vibrate(l.selection)}impactLight(){return this.vibrate(l.impactLight)}impactMedium(){return this.vibrate(l.impactMedium)}impactHeavy(){return this.vibrate(l.impactHeavy)}notification(){return this.vibrate(l.notification)}scalePattern(o){return this.config.intensity===1?o:typeof o=="number"?Math.round(o*this.config.intensity):o.map((e,t)=>t%2===0?Math.round(e*this.config.intensity):e)}};b(C,"MobileVibration");var f=C,T=null;function V(){return T||(T=new f),T}b(V,"getMobileVibration");export{d as BaseInputs,B as InputDeviceType,x as InputEventType,p as MobileInputs,f as MobileVibration,F as TouchInput,J as Vector2,l as VibrationPatterns,V as getMobileVibration,P as useMobileInputs};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@utsp/input",
3
- "version": "0.14.0",
3
+ "version": "0.14.2",
4
4
  "description": "Comprehensive input management system for UTSP - keyboard, mouse, gamepad, and touch support with unified routing",
5
5
  "author": "THP Software",
6
6
  "license": "MIT",
@@ -104,7 +104,7 @@
104
104
  "access": "public"
105
105
  },
106
106
  "dependencies": {
107
- "@utsp/types": "0.14.0"
107
+ "@utsp/types": "0.14.2"
108
108
  },
109
109
  "devDependencies": {
110
110
  "typescript": "^5.6.3"