{"ast":null,"code":"import { IsNavigatorAvailable } from \"../Misc/domManagement.js\";\nimport { Tools } from \"../Misc/tools.js\";\nimport { DeviceEventFactory } from \"./eventFactory.js\";\nimport { DeviceType, PointerInput } from \"./InputDevices/deviceEnums.js\";\n// eslint-disable-next-line @typescript-eslint/naming-convention\nconst MAX_KEYCODES = 255;\n// eslint-disable-next-line @typescript-eslint/naming-convention\nconst MAX_POINTER_INPUTS = Object.keys(PointerInput).length / 2;\n/** @internal */\nexport class WebDeviceInputSystem {\n /**\n * Constructor for the WebDeviceInputSystem\n * @param engine Engine to reference\n * @param onDeviceConnected Callback to execute when device is connected\n * @param onDeviceDisconnected Callback to execute when device is disconnected\n * @param onInputChanged Callback to execute when input changes on device\n */\n constructor(engine, onDeviceConnected, onDeviceDisconnected, onInputChanged) {\n // Private Members\n this._inputs = [];\n this._keyboardActive = false;\n this._pointerActive = false;\n this._usingSafari = Tools.IsSafari();\n // Found solution for determining if MacOS is being used here:\n // https://stackoverflow.com/questions/10527983/best-way-to-detect-mac-os-x-or-windows-computers-with-javascript-or-jquery\n this._usingMacOS = IsNavigatorAvailable() && /(Mac|iPhone|iPod|iPad)/i.test(navigator.platform);\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n this._keyboardDownEvent = evt => {};\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n this._keyboardUpEvent = evt => {};\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n this._keyboardBlurEvent = evt => {};\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n this._pointerMoveEvent = evt => {};\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n this._pointerDownEvent = evt => {};\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n this._pointerUpEvent = evt => {};\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n this._pointerCancelEvent = evt => {};\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n this._pointerWheelEvent = evt => {};\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n this._pointerBlurEvent = evt => {};\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n this._pointerMacOSChromeOutEvent = evt => {};\n this._eventsAttached = false;\n this._mouseId = -1;\n this._isUsingFirefox = IsNavigatorAvailable() && navigator.userAgent && navigator.userAgent.indexOf(\"Firefox\") !== -1;\n this._isUsingChromium = IsNavigatorAvailable() && navigator.userAgent && navigator.userAgent.indexOf(\"Chrome\") !== -1;\n this._maxTouchPoints = 0;\n this._pointerInputClearObserver = null;\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n this._gamepadConnectedEvent = evt => {};\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n this._gamepadDisconnectedEvent = evt => {};\n this._eventPrefix = Tools.GetPointerPrefix(engine);\n this._engine = engine;\n this._onDeviceConnected = onDeviceConnected;\n this._onDeviceDisconnected = onDeviceDisconnected;\n this._onInputChanged = onInputChanged;\n // If we need a pointerId, set one for future use\n this._mouseId = this._isUsingFirefox ? 0 : 1;\n this._enableEvents();\n if (this._usingMacOS) {\n this._metaKeys = [];\n }\n // Set callback to enable event handler switching when inputElement changes\n if (!this._engine._onEngineViewChanged) {\n this._engine._onEngineViewChanged = () => {\n this._enableEvents();\n };\n }\n }\n // Public functions\n /**\n * Checks for current device input value, given an id and input index. Throws exception if requested device not initialized.\n * @param deviceType Enum specifying device type\n * @param deviceSlot \"Slot\" or index that device is referenced in\n * @param inputIndex Id of input to be checked\n * @returns Current value of input\n */\n pollInput(deviceType, deviceSlot, inputIndex) {\n const device = this._inputs[deviceType][deviceSlot];\n if (!device) {\n // eslint-disable-next-line no-throw-literal\n throw `Unable to find device ${DeviceType[deviceType]}`;\n }\n if (deviceType >= DeviceType.DualShock && deviceType <= DeviceType.DualSense) {\n this._updateDevice(deviceType, deviceSlot, inputIndex);\n }\n const currentValue = device[inputIndex];\n if (currentValue === undefined) {\n // eslint-disable-next-line no-throw-literal\n throw `Unable to find input ${inputIndex} for device ${DeviceType[deviceType]} in slot ${deviceSlot}`;\n }\n if (inputIndex === PointerInput.Move) {\n Tools.Warn(`Unable to provide information for PointerInput.Move. Try using PointerInput.Horizontal or PointerInput.Vertical for move data.`);\n }\n return currentValue;\n }\n /**\n * Check for a specific device in the DeviceInputSystem\n * @param deviceType Type of device to check for\n * @returns bool with status of device's existence\n */\n isDeviceAvailable(deviceType) {\n return this._inputs[deviceType] !== undefined;\n }\n /**\n * Dispose of all the eventlisteners\n */\n dispose() {\n // Callbacks\n this._onDeviceConnected = () => {};\n this._onDeviceDisconnected = () => {};\n this._onInputChanged = () => {};\n delete this._engine._onEngineViewChanged;\n if (this._elementToAttachTo) {\n this._disableEvents();\n }\n }\n /**\n * Enable listening for user input events\n */\n _enableEvents() {\n const inputElement = this === null || this === void 0 ? void 0 : this._engine.getInputElement();\n if (inputElement && (!this._eventsAttached || this._elementToAttachTo !== inputElement)) {\n // Remove events before adding to avoid double events or simultaneous events on multiple canvases\n this._disableEvents();\n // If the inputs array has already been created, zero it out to before setting up events\n if (this._inputs) {\n for (const inputs of this._inputs) {\n if (inputs) {\n for (const deviceSlotKey in inputs) {\n const deviceSlot = +deviceSlotKey;\n const device = inputs[deviceSlot];\n if (device) {\n for (let inputIndex = 0; inputIndex < device.length; inputIndex++) {\n device[inputIndex] = 0;\n }\n }\n }\n }\n }\n }\n this._elementToAttachTo = inputElement;\n // Set tab index for the inputElement to the engine's canvasTabIndex, if and only if the element's tab index is -1\n this._elementToAttachTo.tabIndex = this._elementToAttachTo.tabIndex !== -1 ? this._elementToAttachTo.tabIndex : this._engine.canvasTabIndex;\n this._handleKeyActions();\n this._handlePointerActions();\n this._handleGamepadActions();\n this._eventsAttached = true;\n // Check for devices that are already connected but aren't registered. Currently, only checks for gamepads and mouse\n this._checkForConnectedDevices();\n }\n }\n /**\n * Disable listening for user input events\n */\n _disableEvents() {\n if (this._elementToAttachTo) {\n // Blur Events\n this._elementToAttachTo.removeEventListener(\"blur\", this._keyboardBlurEvent);\n this._elementToAttachTo.removeEventListener(\"blur\", this._pointerBlurEvent);\n // Keyboard Events\n this._elementToAttachTo.removeEventListener(\"keydown\", this._keyboardDownEvent);\n this._elementToAttachTo.removeEventListener(\"keyup\", this._keyboardUpEvent);\n // Pointer Events\n this._elementToAttachTo.removeEventListener(this._eventPrefix + \"move\", this._pointerMoveEvent);\n this._elementToAttachTo.removeEventListener(this._eventPrefix + \"down\", this._pointerDownEvent);\n this._elementToAttachTo.removeEventListener(this._eventPrefix + \"up\", this._pointerUpEvent);\n this._elementToAttachTo.removeEventListener(this._eventPrefix + \"cancel\", this._pointerCancelEvent);\n this._elementToAttachTo.removeEventListener(this._wheelEventName, this._pointerWheelEvent);\n if (this._usingMacOS && this._isUsingChromium) {\n this._elementToAttachTo.removeEventListener(\"lostpointercapture\", this._pointerMacOSChromeOutEvent);\n }\n // Gamepad Events\n window.removeEventListener(\"gamepadconnected\", this._gamepadConnectedEvent);\n window.removeEventListener(\"gamepaddisconnected\", this._gamepadDisconnectedEvent);\n }\n if (this._pointerInputClearObserver) {\n this._engine.onEndFrameObservable.remove(this._pointerInputClearObserver);\n }\n this._eventsAttached = false;\n }\n /**\n * Checks for existing connections to devices and register them, if necessary\n * Currently handles gamepads and mouse\n */\n _checkForConnectedDevices() {\n if (navigator.getGamepads) {\n const gamepads = navigator.getGamepads();\n for (const gamepad of gamepads) {\n if (gamepad) {\n this._addGamePad(gamepad);\n }\n }\n }\n // If the device in use has mouse capabilities, pre-register mouse\n if (typeof matchMedia === \"function\" && matchMedia(\"(pointer:fine)\").matches) {\n // This will provide a dummy value for the cursor position and is expected to be overridden when the first mouse event happens.\n // There isn't any good way to get the current position outside of a pointer event so that's why this was done.\n this._addPointerDevice(DeviceType.Mouse, 0, 0, 0);\n }\n }\n // Private functions\n /**\n * Add a gamepad to the DeviceInputSystem\n * @param gamepad A single DOM Gamepad object\n */\n _addGamePad(gamepad) {\n const deviceType = this._getGamepadDeviceType(gamepad.id);\n const deviceSlot = gamepad.index;\n this._gamepads = this._gamepads || new Array(gamepad.index + 1);\n this._registerDevice(deviceType, deviceSlot, gamepad.buttons.length + gamepad.axes.length);\n this._gamepads[deviceSlot] = deviceType;\n }\n /**\n * Add pointer device to DeviceInputSystem\n * @param deviceType Type of Pointer to add\n * @param deviceSlot Pointer ID (0 for mouse, pointerId for Touch)\n * @param currentX Current X at point of adding\n * @param currentY Current Y at point of adding\n */\n _addPointerDevice(deviceType, deviceSlot, currentX, currentY) {\n if (!this._pointerActive) {\n this._pointerActive = true;\n }\n this._registerDevice(deviceType, deviceSlot, MAX_POINTER_INPUTS);\n const pointer = this._inputs[deviceType][deviceSlot]; /* initialize our pointer position immediately after registration */\n pointer[0] = currentX;\n pointer[1] = currentY;\n }\n /**\n * Add device and inputs to device array\n * @param deviceType Enum specifying device type\n * @param deviceSlot \"Slot\" or index that device is referenced in\n * @param numberOfInputs Number of input entries to create for given device\n */\n _registerDevice(deviceType, deviceSlot, numberOfInputs) {\n if (deviceSlot === undefined) {\n // eslint-disable-next-line no-throw-literal\n throw `Unable to register device ${DeviceType[deviceType]} to undefined slot.`;\n }\n if (!this._inputs[deviceType]) {\n this._inputs[deviceType] = {};\n }\n if (!this._inputs[deviceType][deviceSlot]) {\n const device = new Array(numberOfInputs);\n device.fill(0);\n this._inputs[deviceType][deviceSlot] = device;\n this._onDeviceConnected(deviceType, deviceSlot);\n }\n }\n /**\n * Given a specific device name, remove that device from the device map\n * @param deviceType Enum specifying device type\n * @param deviceSlot \"Slot\" or index that device is referenced in\n */\n _unregisterDevice(deviceType, deviceSlot) {\n if (this._inputs[deviceType][deviceSlot]) {\n delete this._inputs[deviceType][deviceSlot];\n this._onDeviceDisconnected(deviceType, deviceSlot);\n }\n }\n /**\n * Handle all actions that come from keyboard interaction\n */\n _handleKeyActions() {\n this._keyboardDownEvent = evt => {\n if (!this._keyboardActive) {\n this._keyboardActive = true;\n this._registerDevice(DeviceType.Keyboard, 0, MAX_KEYCODES);\n }\n const kbKey = this._inputs[DeviceType.Keyboard][0];\n if (kbKey) {\n kbKey[evt.keyCode] = 1;\n const deviceEvent = evt;\n deviceEvent.inputIndex = evt.keyCode;\n if (this._usingMacOS && evt.metaKey && evt.key !== \"Meta\") {\n if (!this._metaKeys.includes(evt.keyCode)) {\n this._metaKeys.push(evt.keyCode);\n }\n }\n this._onInputChanged(DeviceType.Keyboard, 0, deviceEvent);\n }\n };\n this._keyboardUpEvent = evt => {\n if (!this._keyboardActive) {\n this._keyboardActive = true;\n this._registerDevice(DeviceType.Keyboard, 0, MAX_KEYCODES);\n }\n const kbKey = this._inputs[DeviceType.Keyboard][0];\n if (kbKey) {\n kbKey[evt.keyCode] = 0;\n const deviceEvent = evt;\n deviceEvent.inputIndex = evt.keyCode;\n if (this._usingMacOS && evt.key === \"Meta\" && this._metaKeys.length > 0) {\n for (const keyCode of this._metaKeys) {\n const deviceEvent = DeviceEventFactory.CreateDeviceEvent(DeviceType.Keyboard, 0, keyCode, 0, this, this._elementToAttachTo);\n kbKey[keyCode] = 0;\n this._onInputChanged(DeviceType.Keyboard, 0, deviceEvent);\n }\n this._metaKeys.splice(0, this._metaKeys.length);\n }\n this._onInputChanged(DeviceType.Keyboard, 0, deviceEvent);\n }\n };\n this._keyboardBlurEvent = () => {\n if (this._keyboardActive) {\n const kbKey = this._inputs[DeviceType.Keyboard][0];\n for (let i = 0; i < kbKey.length; i++) {\n if (kbKey[i] !== 0) {\n kbKey[i] = 0;\n const deviceEvent = DeviceEventFactory.CreateDeviceEvent(DeviceType.Keyboard, 0, i, 0, this, this._elementToAttachTo);\n this._onInputChanged(DeviceType.Keyboard, 0, deviceEvent);\n }\n }\n if (this._usingMacOS) {\n this._metaKeys.splice(0, this._metaKeys.length);\n }\n }\n };\n this._elementToAttachTo.addEventListener(\"keydown\", this._keyboardDownEvent);\n this._elementToAttachTo.addEventListener(\"keyup\", this._keyboardUpEvent);\n this._elementToAttachTo.addEventListener(\"blur\", this._keyboardBlurEvent);\n }\n /**\n * Handle all actions that come from pointer interaction\n */\n _handlePointerActions() {\n // If maxTouchPoints is defined, use that value. Otherwise, allow for a minimum for supported gestures like pinch\n this._maxTouchPoints = IsNavigatorAvailable() && navigator.maxTouchPoints || 2;\n if (!this._activeTouchIds) {\n this._activeTouchIds = new Array(this._maxTouchPoints);\n }\n for (let i = 0; i < this._maxTouchPoints; i++) {\n this._activeTouchIds[i] = -1;\n }\n this._pointerMoveEvent = evt => {\n const deviceType = this._getPointerType(evt);\n let deviceSlot = deviceType === DeviceType.Mouse ? 0 : this._activeTouchIds.indexOf(evt.pointerId);\n // In the event that we're getting pointermove events from touch inputs that we aren't tracking,\n // look for an available slot and retroactively connect it.\n if (deviceType === DeviceType.Touch && deviceSlot === -1) {\n const idx = this._activeTouchIds.indexOf(-1);\n if (idx >= 0) {\n deviceSlot = idx;\n this._activeTouchIds[idx] = evt.pointerId;\n // Because this is a \"new\" input, inform the connected callback\n this._onDeviceConnected(deviceType, deviceSlot);\n } else {\n // We can't find an open slot to store new pointer so just return (can only support max number of touches)\n Tools.Warn(`Max number of touches exceeded. Ignoring touches in excess of ${this._maxTouchPoints}`);\n return;\n }\n }\n if (!this._inputs[deviceType]) {\n this._inputs[deviceType] = {};\n }\n if (!this._inputs[deviceType][deviceSlot]) {\n this._addPointerDevice(deviceType, deviceSlot, evt.clientX, evt.clientY);\n }\n const pointer = this._inputs[deviceType][deviceSlot];\n if (pointer) {\n const deviceEvent = evt;\n deviceEvent.inputIndex = PointerInput.Move;\n pointer[PointerInput.Horizontal] = evt.clientX;\n pointer[PointerInput.Vertical] = evt.clientY;\n // For touches that aren't started with a down, we need to set the button state to 1\n if (deviceType === DeviceType.Touch && pointer[PointerInput.LeftClick] === 0) {\n pointer[PointerInput.LeftClick] = 1;\n }\n if (evt.pointerId === undefined) {\n evt.pointerId = this._mouseId;\n }\n this._onInputChanged(deviceType, deviceSlot, deviceEvent);\n // Lets Propagate the event for move with same position.\n if (!this._usingSafari && evt.button !== -1) {\n deviceEvent.inputIndex = evt.button + 2;\n pointer[evt.button + 2] = pointer[evt.button + 2] ? 0 : 1; // Reverse state of button if evt.button has value\n this._onInputChanged(deviceType, deviceSlot, deviceEvent);\n }\n }\n };\n this._pointerDownEvent = evt => {\n const deviceType = this._getPointerType(evt);\n let deviceSlot = deviceType === DeviceType.Mouse ? 0 : evt.pointerId;\n if (deviceType === DeviceType.Touch) {\n // See if this pointerId is already using an existing slot\n // (possible on some devices which raise the pointerMove event before the pointerDown event, e.g. when using a pen)\n let idx = this._activeTouchIds.indexOf(evt.pointerId);\n if (idx === -1) {\n // If the pointerId wasn't already using a slot, find an open one\n idx = this._activeTouchIds.indexOf(-1);\n }\n if (idx >= 0) {\n deviceSlot = idx;\n this._activeTouchIds[idx] = evt.pointerId;\n } else {\n // We can't find an open slot to store new pointer so just return (can only support max number of touches)\n Tools.Warn(`Max number of touches exceeded. Ignoring touches in excess of ${this._maxTouchPoints}`);\n return;\n }\n }\n if (!this._inputs[deviceType]) {\n this._inputs[deviceType] = {};\n }\n if (!this._inputs[deviceType][deviceSlot]) {\n this._addPointerDevice(deviceType, deviceSlot, evt.clientX, evt.clientY);\n } else if (deviceType === DeviceType.Touch) {\n this._onDeviceConnected(deviceType, deviceSlot);\n }\n const pointer = this._inputs[deviceType][deviceSlot];\n if (pointer) {\n const previousHorizontal = pointer[PointerInput.Horizontal];\n const previousVertical = pointer[PointerInput.Vertical];\n if (deviceType === DeviceType.Mouse) {\n // Mouse; Set pointerId if undefined\n if (evt.pointerId === undefined) {\n evt.pointerId = this._mouseId;\n }\n if (!document.pointerLockElement) {\n try {\n this._elementToAttachTo.setPointerCapture(this._mouseId);\n } catch (e) {\n // DO NOTHING\n }\n }\n } else {\n // Touch; Since touches are dynamically assigned, only set capture if we have an id\n if (evt.pointerId && !document.pointerLockElement) {\n try {\n this._elementToAttachTo.setPointerCapture(evt.pointerId);\n } catch (e) {\n // DO NOTHING\n }\n }\n }\n pointer[PointerInput.Horizontal] = evt.clientX;\n pointer[PointerInput.Vertical] = evt.clientY;\n pointer[evt.button + 2] = 1;\n const deviceEvent = evt;\n // NOTE: The +2 used here to is because PointerInput has the same value progression for its mouse buttons as PointerEvent.button\n // However, we have our X and Y values front-loaded to group together the touch inputs but not break this progression\n // EG. ([X, Y, Left-click], Middle-click, etc...)\n deviceEvent.inputIndex = evt.button + 2;\n this._onInputChanged(deviceType, deviceSlot, deviceEvent);\n if (previousHorizontal !== evt.clientX || previousVertical !== evt.clientY) {\n deviceEvent.inputIndex = PointerInput.Move;\n this._onInputChanged(deviceType, deviceSlot, deviceEvent);\n }\n }\n };\n this._pointerUpEvent = evt => {\n var _this$_inputs$deviceT;\n const deviceType = this._getPointerType(evt);\n const deviceSlot = deviceType === DeviceType.Mouse ? 0 : this._activeTouchIds.indexOf(evt.pointerId);\n if (deviceType === DeviceType.Touch) {\n // If we're getting a pointerup event for a touch that isn't active, just return.\n if (deviceSlot === -1) {\n return;\n } else {\n this._activeTouchIds[deviceSlot] = -1;\n }\n }\n const pointer = (_this$_inputs$deviceT = this._inputs[deviceType]) === null || _this$_inputs$deviceT === void 0 ? void 0 : _this$_inputs$deviceT[deviceSlot];\n if (pointer && pointer[evt.button + 2] !== 0) {\n var _this$_elementToAttac, _this$_elementToAttac2, _this$_elementToAttac3, _this$_elementToAttac4;\n const previousHorizontal = pointer[PointerInput.Horizontal];\n const previousVertical = pointer[PointerInput.Vertical];\n pointer[PointerInput.Horizontal] = evt.clientX;\n pointer[PointerInput.Vertical] = evt.clientY;\n pointer[evt.button + 2] = 0;\n const deviceEvent = evt;\n if (evt.pointerId === undefined) {\n evt.pointerId = this._mouseId;\n }\n if (previousHorizontal !== evt.clientX || previousVertical !== evt.clientY) {\n deviceEvent.inputIndex = PointerInput.Move;\n this._onInputChanged(deviceType, deviceSlot, deviceEvent);\n }\n // NOTE: The +2 used here to is because PointerInput has the same value progression for its mouse buttons as PointerEvent.button\n // However, we have our X and Y values front-loaded to group together the touch inputs but not break this progression\n // EG. ([X, Y, Left-click], Middle-click, etc...)\n deviceEvent.inputIndex = evt.button + 2;\n if (deviceType === DeviceType.Mouse && this._mouseId >= 0 && (_this$_elementToAttac = (_this$_elementToAttac2 = this._elementToAttachTo).hasPointerCapture) !== null && _this$_elementToAttac !== void 0 && _this$_elementToAttac.call(_this$_elementToAttac2, this._mouseId)) {\n this._elementToAttachTo.releasePointerCapture(this._mouseId);\n } else if (evt.pointerId && (_this$_elementToAttac3 = (_this$_elementToAttac4 = this._elementToAttachTo).hasPointerCapture) !== null && _this$_elementToAttac3 !== void 0 && _this$_elementToAttac3.call(_this$_elementToAttac4, evt.pointerId)) {\n this._elementToAttachTo.releasePointerCapture(evt.pointerId);\n }\n this._onInputChanged(deviceType, deviceSlot, deviceEvent);\n if (deviceType === DeviceType.Touch) {\n this._onDeviceDisconnected(deviceType, deviceSlot);\n }\n }\n };\n this._pointerCancelEvent = evt => {\n if (evt.pointerType === \"mouse\") {\n var _this$_elementToAttac5, _this$_elementToAttac6;\n const pointer = this._inputs[DeviceType.Mouse][0];\n if (this._mouseId >= 0 && (_this$_elementToAttac5 = (_this$_elementToAttac6 = this._elementToAttachTo).hasPointerCapture) !== null && _this$_elementToAttac5 !== void 0 && _this$_elementToAttac5.call(_this$_elementToAttac6, this._mouseId)) {\n this._elementToAttachTo.releasePointerCapture(this._mouseId);\n }\n for (let inputIndex = PointerInput.LeftClick; inputIndex <= PointerInput.BrowserForward; inputIndex++) {\n if (pointer[inputIndex] === 1) {\n pointer[inputIndex] = 0;\n const deviceEvent = DeviceEventFactory.CreateDeviceEvent(DeviceType.Mouse, 0, inputIndex, 0, this, this._elementToAttachTo);\n this._onInputChanged(DeviceType.Mouse, 0, deviceEvent);\n }\n }\n } else {\n var _this$_elementToAttac7, _this$_elementToAttac8;\n const deviceSlot = this._activeTouchIds.indexOf(evt.pointerId);\n // If we're getting a pointercancel event for a touch that isn't active, just return\n if (deviceSlot === -1) {\n return;\n }\n if ((_this$_elementToAttac7 = (_this$_elementToAttac8 = this._elementToAttachTo).hasPointerCapture) !== null && _this$_elementToAttac7 !== void 0 && _this$_elementToAttac7.call(_this$_elementToAttac8, evt.pointerId)) {\n this._elementToAttachTo.releasePointerCapture(evt.pointerId);\n }\n this._inputs[DeviceType.Touch][deviceSlot][PointerInput.LeftClick] = 0;\n const deviceEvent = DeviceEventFactory.CreateDeviceEvent(DeviceType.Touch, deviceSlot, PointerInput.LeftClick, 0, this, this._elementToAttachTo, evt.pointerId);\n this._onInputChanged(DeviceType.Touch, deviceSlot, deviceEvent);\n this._activeTouchIds[deviceSlot] = -1;\n this._onDeviceDisconnected(DeviceType.Touch, deviceSlot);\n }\n };\n // Set Wheel Event Name, code originally from scene.inputManager\n this._wheelEventName = \"onwheel\" in document.createElement(\"div\") ? \"wheel\" // Modern browsers support \"wheel\"\n : document.onmousewheel !== undefined ? \"mousewheel\" // Webkit and IE support at least \"mousewheel\"\n : \"DOMMouseScroll\"; // let's assume that remaining browsers are older Firefox\n // Code originally in scene.inputManager.ts\n // Chrome reports warning in console if wheel listener doesn't set an explicit passive option.\n // IE11 only supports captureEvent:boolean, not options:object, and it defaults to false.\n // Feature detection technique copied from: https://github.com/github/eventlistener-polyfill (MIT license)\n let passiveSupported = false;\n const noop = function () {};\n try {\n const options = Object.defineProperty({}, \"passive\", {\n get: function () {\n passiveSupported = true;\n }\n });\n this._elementToAttachTo.addEventListener(\"test\", noop, options);\n this._elementToAttachTo.removeEventListener(\"test\", noop, options);\n } catch (e) {\n /* */\n }\n this._pointerBlurEvent = () => {\n // Handle mouse buttons\n if (this.isDeviceAvailable(DeviceType.Mouse)) {\n var _this$_elementToAttac9, _this$_elementToAttac10;\n const pointer = this._inputs[DeviceType.Mouse][0];\n if (this._mouseId >= 0 && (_this$_elementToAttac9 = (_this$_elementToAttac10 = this._elementToAttachTo).hasPointerCapture) !== null && _this$_elementToAttac9 !== void 0 && _this$_elementToAttac9.call(_this$_elementToAttac10, this._mouseId)) {\n this._elementToAttachTo.releasePointerCapture(this._mouseId);\n }\n for (let inputIndex = PointerInput.LeftClick; inputIndex <= PointerInput.BrowserForward; inputIndex++) {\n if (pointer[inputIndex] === 1) {\n pointer[inputIndex] = 0;\n const deviceEvent = DeviceEventFactory.CreateDeviceEvent(DeviceType.Mouse, 0, inputIndex, 0, this, this._elementToAttachTo);\n this._onInputChanged(DeviceType.Mouse, 0, deviceEvent);\n }\n }\n }\n // Handle Active Touches\n if (this.isDeviceAvailable(DeviceType.Touch)) {\n const pointer = this._inputs[DeviceType.Touch];\n for (let deviceSlot = 0; deviceSlot < this._activeTouchIds.length; deviceSlot++) {\n var _this$_elementToAttac11, _this$_elementToAttac12, _pointer$deviceSlot;\n const pointerId = this._activeTouchIds[deviceSlot];\n if ((_this$_elementToAttac11 = (_this$_elementToAttac12 = this._elementToAttachTo).hasPointerCapture) !== null && _this$_elementToAttac11 !== void 0 && _this$_elementToAttac11.call(_this$_elementToAttac12, pointerId)) {\n this._elementToAttachTo.releasePointerCapture(pointerId);\n }\n if (pointerId !== -1 && ((_pointer$deviceSlot = pointer[deviceSlot]) === null || _pointer$deviceSlot === void 0 ? void 0 : _pointer$deviceSlot[PointerInput.LeftClick]) === 1) {\n pointer[deviceSlot][PointerInput.LeftClick] = 0;\n const deviceEvent = DeviceEventFactory.CreateDeviceEvent(DeviceType.Touch, deviceSlot, PointerInput.LeftClick, 0, this, this._elementToAttachTo, pointerId);\n this._onInputChanged(DeviceType.Touch, deviceSlot, deviceEvent);\n this._activeTouchIds[deviceSlot] = -1;\n this._onDeviceDisconnected(DeviceType.Touch, deviceSlot);\n }\n }\n }\n };\n this._pointerWheelEvent = evt => {\n const deviceType = DeviceType.Mouse;\n const deviceSlot = 0;\n if (!this._inputs[deviceType]) {\n this._inputs[deviceType] = [];\n }\n if (!this._inputs[deviceType][deviceSlot]) {\n this._pointerActive = true;\n this._registerDevice(deviceType, deviceSlot, MAX_POINTER_INPUTS);\n }\n const pointer = this._inputs[deviceType][deviceSlot];\n if (pointer) {\n pointer[PointerInput.MouseWheelX] = evt.deltaX || 0;\n pointer[PointerInput.MouseWheelY] = evt.deltaY || evt.wheelDelta || 0;\n pointer[PointerInput.MouseWheelZ] = evt.deltaZ || 0;\n const deviceEvent = evt;\n // By default, there is no pointerId for mouse wheel events so we'll add one here\n // This logic was originally in the InputManager but was added here to make the\n // InputManager more platform-agnostic\n if (evt.pointerId === undefined) {\n evt.pointerId = this._mouseId;\n }\n if (pointer[PointerInput.MouseWheelX] !== 0) {\n deviceEvent.inputIndex = PointerInput.MouseWheelX;\n this._onInputChanged(deviceType, deviceSlot, deviceEvent);\n }\n if (pointer[PointerInput.MouseWheelY] !== 0) {\n deviceEvent.inputIndex = PointerInput.MouseWheelY;\n this._onInputChanged(deviceType, deviceSlot, deviceEvent);\n }\n if (pointer[PointerInput.MouseWheelZ] !== 0) {\n deviceEvent.inputIndex = PointerInput.MouseWheelZ;\n this._onInputChanged(deviceType, deviceSlot, deviceEvent);\n }\n }\n };\n // Workaround for MacOS Chromium Browsers for lost pointer capture bug\n if (this._usingMacOS && this._isUsingChromium) {\n this._pointerMacOSChromeOutEvent = evt => {\n if (evt.buttons > 1) {\n this._pointerCancelEvent(evt);\n }\n };\n this._elementToAttachTo.addEventListener(\"lostpointercapture\", this._pointerMacOSChromeOutEvent);\n }\n this._elementToAttachTo.addEventListener(this._eventPrefix + \"move\", this._pointerMoveEvent);\n this._elementToAttachTo.addEventListener(this._eventPrefix + \"down\", this._pointerDownEvent);\n this._elementToAttachTo.addEventListener(this._eventPrefix + \"up\", this._pointerUpEvent);\n this._elementToAttachTo.addEventListener(this._eventPrefix + \"cancel\", this._pointerCancelEvent);\n this._elementToAttachTo.addEventListener(\"blur\", this._pointerBlurEvent);\n this._elementToAttachTo.addEventListener(this._wheelEventName, this._pointerWheelEvent, passiveSupported ? {\n passive: false\n } : false);\n // Since there's no up or down event for mouse wheel or delta x/y, clear mouse values at end of frame\n this._pointerInputClearObserver = this._engine.onEndFrameObservable.add(() => {\n if (this.isDeviceAvailable(DeviceType.Mouse)) {\n const pointer = this._inputs[DeviceType.Mouse][0];\n pointer[PointerInput.MouseWheelX] = 0;\n pointer[PointerInput.MouseWheelY] = 0;\n pointer[PointerInput.MouseWheelZ] = 0;\n }\n });\n }\n /**\n * Handle all actions that come from gamepad interaction\n */\n _handleGamepadActions() {\n this._gamepadConnectedEvent = evt => {\n this._addGamePad(evt.gamepad);\n };\n this._gamepadDisconnectedEvent = evt => {\n if (this._gamepads) {\n const deviceType = this._getGamepadDeviceType(evt.gamepad.id);\n const deviceSlot = evt.gamepad.index;\n this._unregisterDevice(deviceType, deviceSlot);\n delete this._gamepads[deviceSlot];\n }\n };\n window.addEventListener(\"gamepadconnected\", this._gamepadConnectedEvent);\n window.addEventListener(\"gamepaddisconnected\", this._gamepadDisconnectedEvent);\n }\n /**\n * Update all non-event based devices with each frame\n * @param deviceType Enum specifying device type\n * @param deviceSlot \"Slot\" or index that device is referenced in\n * @param inputIndex Id of input to be checked\n */\n _updateDevice(deviceType, deviceSlot, inputIndex) {\n // Gamepads\n const gp = navigator.getGamepads()[deviceSlot];\n if (gp && deviceType === this._gamepads[deviceSlot]) {\n const device = this._inputs[deviceType][deviceSlot];\n if (inputIndex >= gp.buttons.length) {\n device[inputIndex] = gp.axes[inputIndex - gp.buttons.length].valueOf();\n } else {\n device[inputIndex] = gp.buttons[inputIndex].value;\n }\n }\n }\n /**\n * Gets DeviceType from the device name\n * @param deviceName Name of Device from DeviceInputSystem\n * @returns DeviceType enum value\n */\n _getGamepadDeviceType(deviceName) {\n if (deviceName.indexOf(\"054c\") !== -1) {\n // DualShock 4 Gamepad\n return deviceName.indexOf(\"0ce6\") !== -1 ? DeviceType.DualSense : DeviceType.DualShock;\n } else if (deviceName.indexOf(\"Xbox One\") !== -1 || deviceName.search(\"Xbox 360\") !== -1 || deviceName.search(\"xinput\") !== -1) {\n // Xbox Gamepad\n return DeviceType.Xbox;\n } else if (deviceName.indexOf(\"057e\") !== -1) {\n // Switch Gamepad\n return DeviceType.Switch;\n }\n return DeviceType.Generic;\n }\n /**\n * Get DeviceType from a given pointer/mouse/touch event.\n * @param evt PointerEvent to evaluate\n * @returns DeviceType interpreted from event\n */\n _getPointerType(evt) {\n let deviceType = DeviceType.Mouse;\n if (evt.pointerType === \"touch\" || evt.pointerType === \"pen\" || evt.touches) {\n deviceType = DeviceType.Touch;\n }\n return deviceType;\n }\n}","map":{"version":3,"names":["IsNavigatorAvailable","Tools","DeviceEventFactory","DeviceType","PointerInput","MAX_KEYCODES","MAX_POINTER_INPUTS","Object","keys","length","WebDeviceInputSystem","constructor","engine","onDeviceConnected","onDeviceDisconnected","onInputChanged","_inputs","_keyboardActive","_pointerActive","_usingSafari","IsSafari","_usingMacOS","test","navigator","platform","_keyboardDownEvent","evt","_keyboardUpEvent","_keyboardBlurEvent","_pointerMoveEvent","_pointerDownEvent","_pointerUpEvent","_pointerCancelEvent","_pointerWheelEvent","_pointerBlurEvent","_pointerMacOSChromeOutEvent","_eventsAttached","_mouseId","_isUsingFirefox","userAgent","indexOf","_isUsingChromium","_maxTouchPoints","_pointerInputClearObserver","_gamepadConnectedEvent","_gamepadDisconnectedEvent","_eventPrefix","GetPointerPrefix","_engine","_onDeviceConnected","_onDeviceDisconnected","_onInputChanged","_enableEvents","_metaKeys","_onEngineViewChanged","pollInput","deviceType","deviceSlot","inputIndex","device","DualShock","DualSense","_updateDevice","currentValue","undefined","Move","Warn","isDeviceAvailable","dispose","_elementToAttachTo","_disableEvents","inputElement","getInputElement","inputs","deviceSlotKey","tabIndex","canvasTabIndex","_handleKeyActions","_handlePointerActions","_handleGamepadActions","_checkForConnectedDevices","removeEventListener","_wheelEventName","window","onEndFrameObservable","remove","getGamepads","gamepads","gamepad","_addGamePad","matchMedia","matches","_addPointerDevice","Mouse","_getGamepadDeviceType","id","index","_gamepads","Array","_registerDevice","buttons","axes","currentX","currentY","pointer","numberOfInputs","fill","_unregisterDevice","Keyboard","kbKey","keyCode","deviceEvent","metaKey","key","includes","push","CreateDeviceEvent","splice","i","addEventListener","maxTouchPoints","_activeTouchIds","_getPointerType","pointerId","Touch","idx","clientX","clientY","Horizontal","Vertical","LeftClick","button","previousHorizontal","previousVertical","document","pointerLockElement","setPointerCapture","e","_this$_inputs$deviceT","_this$_elementToAttac","_this$_elementToAttac2","_this$_elementToAttac3","_this$_elementToAttac4","hasPointerCapture","call","releasePointerCapture","pointerType","_this$_elementToAttac5","_this$_elementToAttac6","BrowserForward","_this$_elementToAttac7","_this$_elementToAttac8","createElement","onmousewheel","passiveSupported","noop","options","defineProperty","get","_this$_elementToAttac9","_this$_elementToAttac10","_this$_elementToAttac11","_this$_elementToAttac12","_pointer$deviceSlot","MouseWheelX","deltaX","MouseWheelY","deltaY","wheelDelta","MouseWheelZ","deltaZ","passive","add","gp","valueOf","value","deviceName","search","Xbox","Switch","Generic","touches"],"sources":["F:/workspace/202226701027/huinongbao-app/node_modules/@babylonjs/core/DeviceInput/webDeviceInputSystem.js"],"sourcesContent":["import { IsNavigatorAvailable } from \"../Misc/domManagement.js\";\nimport { Tools } from \"../Misc/tools.js\";\nimport { DeviceEventFactory } from \"./eventFactory.js\";\nimport { DeviceType, PointerInput } from \"./InputDevices/deviceEnums.js\";\n// eslint-disable-next-line @typescript-eslint/naming-convention\nconst MAX_KEYCODES = 255;\n// eslint-disable-next-line @typescript-eslint/naming-convention\nconst MAX_POINTER_INPUTS = Object.keys(PointerInput).length / 2;\n/** @internal */\nexport class WebDeviceInputSystem {\n /**\n * Constructor for the WebDeviceInputSystem\n * @param engine Engine to reference\n * @param onDeviceConnected Callback to execute when device is connected\n * @param onDeviceDisconnected Callback to execute when device is disconnected\n * @param onInputChanged Callback to execute when input changes on device\n */\n constructor(engine, onDeviceConnected, onDeviceDisconnected, onInputChanged) {\n // Private Members\n this._inputs = [];\n this._keyboardActive = false;\n this._pointerActive = false;\n this._usingSafari = Tools.IsSafari();\n // Found solution for determining if MacOS is being used here:\n // https://stackoverflow.com/questions/10527983/best-way-to-detect-mac-os-x-or-windows-computers-with-javascript-or-jquery\n this._usingMacOS = IsNavigatorAvailable() && /(Mac|iPhone|iPod|iPad)/i.test(navigator.platform);\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n this._keyboardDownEvent = (evt) => { };\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n this._keyboardUpEvent = (evt) => { };\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n this._keyboardBlurEvent = (evt) => { };\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n this._pointerMoveEvent = (evt) => { };\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n this._pointerDownEvent = (evt) => { };\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n this._pointerUpEvent = (evt) => { };\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n this._pointerCancelEvent = (evt) => { };\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n this._pointerWheelEvent = (evt) => { };\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n this._pointerBlurEvent = (evt) => { };\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n this._pointerMacOSChromeOutEvent = (evt) => { };\n this._eventsAttached = false;\n this._mouseId = -1;\n this._isUsingFirefox = IsNavigatorAvailable() && navigator.userAgent && navigator.userAgent.indexOf(\"Firefox\") !== -1;\n this._isUsingChromium = IsNavigatorAvailable() && navigator.userAgent && navigator.userAgent.indexOf(\"Chrome\") !== -1;\n this._maxTouchPoints = 0;\n this._pointerInputClearObserver = null;\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n this._gamepadConnectedEvent = (evt) => { };\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n this._gamepadDisconnectedEvent = (evt) => { };\n this._eventPrefix = Tools.GetPointerPrefix(engine);\n this._engine = engine;\n this._onDeviceConnected = onDeviceConnected;\n this._onDeviceDisconnected = onDeviceDisconnected;\n this._onInputChanged = onInputChanged;\n // If we need a pointerId, set one for future use\n this._mouseId = this._isUsingFirefox ? 0 : 1;\n this._enableEvents();\n if (this._usingMacOS) {\n this._metaKeys = [];\n }\n // Set callback to enable event handler switching when inputElement changes\n if (!this._engine._onEngineViewChanged) {\n this._engine._onEngineViewChanged = () => {\n this._enableEvents();\n };\n }\n }\n // Public functions\n /**\n * Checks for current device input value, given an id and input index. Throws exception if requested device not initialized.\n * @param deviceType Enum specifying device type\n * @param deviceSlot \"Slot\" or index that device is referenced in\n * @param inputIndex Id of input to be checked\n * @returns Current value of input\n */\n pollInput(deviceType, deviceSlot, inputIndex) {\n const device = this._inputs[deviceType][deviceSlot];\n if (!device) {\n // eslint-disable-next-line no-throw-literal\n throw `Unable to find device ${DeviceType[deviceType]}`;\n }\n if (deviceType >= DeviceType.DualShock && deviceType <= DeviceType.DualSense) {\n this._updateDevice(deviceType, deviceSlot, inputIndex);\n }\n const currentValue = device[inputIndex];\n if (currentValue === undefined) {\n // eslint-disable-next-line no-throw-literal\n throw `Unable to find input ${inputIndex} for device ${DeviceType[deviceType]} in slot ${deviceSlot}`;\n }\n if (inputIndex === PointerInput.Move) {\n Tools.Warn(`Unable to provide information for PointerInput.Move. Try using PointerInput.Horizontal or PointerInput.Vertical for move data.`);\n }\n return currentValue;\n }\n /**\n * Check for a specific device in the DeviceInputSystem\n * @param deviceType Type of device to check for\n * @returns bool with status of device's existence\n */\n isDeviceAvailable(deviceType) {\n return this._inputs[deviceType] !== undefined;\n }\n /**\n * Dispose of all the eventlisteners\n */\n dispose() {\n // Callbacks\n this._onDeviceConnected = () => { };\n this._onDeviceDisconnected = () => { };\n this._onInputChanged = () => { };\n delete this._engine._onEngineViewChanged;\n if (this._elementToAttachTo) {\n this._disableEvents();\n }\n }\n /**\n * Enable listening for user input events\n */\n _enableEvents() {\n const inputElement = this?._engine.getInputElement();\n if (inputElement && (!this._eventsAttached || this._elementToAttachTo !== inputElement)) {\n // Remove events before adding to avoid double events or simultaneous events on multiple canvases\n this._disableEvents();\n // If the inputs array has already been created, zero it out to before setting up events\n if (this._inputs) {\n for (const inputs of this._inputs) {\n if (inputs) {\n for (const deviceSlotKey in inputs) {\n const deviceSlot = +deviceSlotKey;\n const device = inputs[deviceSlot];\n if (device) {\n for (let inputIndex = 0; inputIndex < device.length; inputIndex++) {\n device[inputIndex] = 0;\n }\n }\n }\n }\n }\n }\n this._elementToAttachTo = inputElement;\n // Set tab index for the inputElement to the engine's canvasTabIndex, if and only if the element's tab index is -1\n this._elementToAttachTo.tabIndex = this._elementToAttachTo.tabIndex !== -1 ? this._elementToAttachTo.tabIndex : this._engine.canvasTabIndex;\n this._handleKeyActions();\n this._handlePointerActions();\n this._handleGamepadActions();\n this._eventsAttached = true;\n // Check for devices that are already connected but aren't registered. Currently, only checks for gamepads and mouse\n this._checkForConnectedDevices();\n }\n }\n /**\n * Disable listening for user input events\n */\n _disableEvents() {\n if (this._elementToAttachTo) {\n // Blur Events\n this._elementToAttachTo.removeEventListener(\"blur\", this._keyboardBlurEvent);\n this._elementToAttachTo.removeEventListener(\"blur\", this._pointerBlurEvent);\n // Keyboard Events\n this._elementToAttachTo.removeEventListener(\"keydown\", this._keyboardDownEvent);\n this._elementToAttachTo.removeEventListener(\"keyup\", this._keyboardUpEvent);\n // Pointer Events\n this._elementToAttachTo.removeEventListener(this._eventPrefix + \"move\", this._pointerMoveEvent);\n this._elementToAttachTo.removeEventListener(this._eventPrefix + \"down\", this._pointerDownEvent);\n this._elementToAttachTo.removeEventListener(this._eventPrefix + \"up\", this._pointerUpEvent);\n this._elementToAttachTo.removeEventListener(this._eventPrefix + \"cancel\", this._pointerCancelEvent);\n this._elementToAttachTo.removeEventListener(this._wheelEventName, this._pointerWheelEvent);\n if (this._usingMacOS && this._isUsingChromium) {\n this._elementToAttachTo.removeEventListener(\"lostpointercapture\", this._pointerMacOSChromeOutEvent);\n }\n // Gamepad Events\n window.removeEventListener(\"gamepadconnected\", this._gamepadConnectedEvent);\n window.removeEventListener(\"gamepaddisconnected\", this._gamepadDisconnectedEvent);\n }\n if (this._pointerInputClearObserver) {\n this._engine.onEndFrameObservable.remove(this._pointerInputClearObserver);\n }\n this._eventsAttached = false;\n }\n /**\n * Checks for existing connections to devices and register them, if necessary\n * Currently handles gamepads and mouse\n */\n _checkForConnectedDevices() {\n if (navigator.getGamepads) {\n const gamepads = navigator.getGamepads();\n for (const gamepad of gamepads) {\n if (gamepad) {\n this._addGamePad(gamepad);\n }\n }\n }\n // If the device in use has mouse capabilities, pre-register mouse\n if (typeof matchMedia === \"function\" && matchMedia(\"(pointer:fine)\").matches) {\n // This will provide a dummy value for the cursor position and is expected to be overridden when the first mouse event happens.\n // There isn't any good way to get the current position outside of a pointer event so that's why this was done.\n this._addPointerDevice(DeviceType.Mouse, 0, 0, 0);\n }\n }\n // Private functions\n /**\n * Add a gamepad to the DeviceInputSystem\n * @param gamepad A single DOM Gamepad object\n */\n _addGamePad(gamepad) {\n const deviceType = this._getGamepadDeviceType(gamepad.id);\n const deviceSlot = gamepad.index;\n this._gamepads = this._gamepads || new Array(gamepad.index + 1);\n this._registerDevice(deviceType, deviceSlot, gamepad.buttons.length + gamepad.axes.length);\n this._gamepads[deviceSlot] = deviceType;\n }\n /**\n * Add pointer device to DeviceInputSystem\n * @param deviceType Type of Pointer to add\n * @param deviceSlot Pointer ID (0 for mouse, pointerId for Touch)\n * @param currentX Current X at point of adding\n * @param currentY Current Y at point of adding\n */\n _addPointerDevice(deviceType, deviceSlot, currentX, currentY) {\n if (!this._pointerActive) {\n this._pointerActive = true;\n }\n this._registerDevice(deviceType, deviceSlot, MAX_POINTER_INPUTS);\n const pointer = this._inputs[deviceType][deviceSlot]; /* initialize our pointer position immediately after registration */\n pointer[0] = currentX;\n pointer[1] = currentY;\n }\n /**\n * Add device and inputs to device array\n * @param deviceType Enum specifying device type\n * @param deviceSlot \"Slot\" or index that device is referenced in\n * @param numberOfInputs Number of input entries to create for given device\n */\n _registerDevice(deviceType, deviceSlot, numberOfInputs) {\n if (deviceSlot === undefined) {\n // eslint-disable-next-line no-throw-literal\n throw `Unable to register device ${DeviceType[deviceType]} to undefined slot.`;\n }\n if (!this._inputs[deviceType]) {\n this._inputs[deviceType] = {};\n }\n if (!this._inputs[deviceType][deviceSlot]) {\n const device = new Array(numberOfInputs);\n device.fill(0);\n this._inputs[deviceType][deviceSlot] = device;\n this._onDeviceConnected(deviceType, deviceSlot);\n }\n }\n /**\n * Given a specific device name, remove that device from the device map\n * @param deviceType Enum specifying device type\n * @param deviceSlot \"Slot\" or index that device is referenced in\n */\n _unregisterDevice(deviceType, deviceSlot) {\n if (this._inputs[deviceType][deviceSlot]) {\n delete this._inputs[deviceType][deviceSlot];\n this._onDeviceDisconnected(deviceType, deviceSlot);\n }\n }\n /**\n * Handle all actions that come from keyboard interaction\n */\n _handleKeyActions() {\n this._keyboardDownEvent = (evt) => {\n if (!this._keyboardActive) {\n this._keyboardActive = true;\n this._registerDevice(DeviceType.Keyboard, 0, MAX_KEYCODES);\n }\n const kbKey = this._inputs[DeviceType.Keyboard][0];\n if (kbKey) {\n kbKey[evt.keyCode] = 1;\n const deviceEvent = evt;\n deviceEvent.inputIndex = evt.keyCode;\n if (this._usingMacOS && evt.metaKey && evt.key !== \"Meta\") {\n if (!this._metaKeys.includes(evt.keyCode)) {\n this._metaKeys.push(evt.keyCode);\n }\n }\n this._onInputChanged(DeviceType.Keyboard, 0, deviceEvent);\n }\n };\n this._keyboardUpEvent = (evt) => {\n if (!this._keyboardActive) {\n this._keyboardActive = true;\n this._registerDevice(DeviceType.Keyboard, 0, MAX_KEYCODES);\n }\n const kbKey = this._inputs[DeviceType.Keyboard][0];\n if (kbKey) {\n kbKey[evt.keyCode] = 0;\n const deviceEvent = evt;\n deviceEvent.inputIndex = evt.keyCode;\n if (this._usingMacOS && evt.key === \"Meta\" && this._metaKeys.length > 0) {\n for (const keyCode of this._metaKeys) {\n const deviceEvent = DeviceEventFactory.CreateDeviceEvent(DeviceType.Keyboard, 0, keyCode, 0, this, this._elementToAttachTo);\n kbKey[keyCode] = 0;\n this._onInputChanged(DeviceType.Keyboard, 0, deviceEvent);\n }\n this._metaKeys.splice(0, this._metaKeys.length);\n }\n this._onInputChanged(DeviceType.Keyboard, 0, deviceEvent);\n }\n };\n this._keyboardBlurEvent = () => {\n if (this._keyboardActive) {\n const kbKey = this._inputs[DeviceType.Keyboard][0];\n for (let i = 0; i < kbKey.length; i++) {\n if (kbKey[i] !== 0) {\n kbKey[i] = 0;\n const deviceEvent = DeviceEventFactory.CreateDeviceEvent(DeviceType.Keyboard, 0, i, 0, this, this._elementToAttachTo);\n this._onInputChanged(DeviceType.Keyboard, 0, deviceEvent);\n }\n }\n if (this._usingMacOS) {\n this._metaKeys.splice(0, this._metaKeys.length);\n }\n }\n };\n this._elementToAttachTo.addEventListener(\"keydown\", this._keyboardDownEvent);\n this._elementToAttachTo.addEventListener(\"keyup\", this._keyboardUpEvent);\n this._elementToAttachTo.addEventListener(\"blur\", this._keyboardBlurEvent);\n }\n /**\n * Handle all actions that come from pointer interaction\n */\n _handlePointerActions() {\n // If maxTouchPoints is defined, use that value. Otherwise, allow for a minimum for supported gestures like pinch\n this._maxTouchPoints = (IsNavigatorAvailable() && navigator.maxTouchPoints) || 2;\n if (!this._activeTouchIds) {\n this._activeTouchIds = new Array(this._maxTouchPoints);\n }\n for (let i = 0; i < this._maxTouchPoints; i++) {\n this._activeTouchIds[i] = -1;\n }\n this._pointerMoveEvent = (evt) => {\n const deviceType = this._getPointerType(evt);\n let deviceSlot = deviceType === DeviceType.Mouse ? 0 : this._activeTouchIds.indexOf(evt.pointerId);\n // In the event that we're getting pointermove events from touch inputs that we aren't tracking,\n // look for an available slot and retroactively connect it.\n if (deviceType === DeviceType.Touch && deviceSlot === -1) {\n const idx = this._activeTouchIds.indexOf(-1);\n if (idx >= 0) {\n deviceSlot = idx;\n this._activeTouchIds[idx] = evt.pointerId;\n // Because this is a \"new\" input, inform the connected callback\n this._onDeviceConnected(deviceType, deviceSlot);\n }\n else {\n // We can't find an open slot to store new pointer so just return (can only support max number of touches)\n Tools.Warn(`Max number of touches exceeded. Ignoring touches in excess of ${this._maxTouchPoints}`);\n return;\n }\n }\n if (!this._inputs[deviceType]) {\n this._inputs[deviceType] = {};\n }\n if (!this._inputs[deviceType][deviceSlot]) {\n this._addPointerDevice(deviceType, deviceSlot, evt.clientX, evt.clientY);\n }\n const pointer = this._inputs[deviceType][deviceSlot];\n if (pointer) {\n const deviceEvent = evt;\n deviceEvent.inputIndex = PointerInput.Move;\n pointer[PointerInput.Horizontal] = evt.clientX;\n pointer[PointerInput.Vertical] = evt.clientY;\n // For touches that aren't started with a down, we need to set the button state to 1\n if (deviceType === DeviceType.Touch && pointer[PointerInput.LeftClick] === 0) {\n pointer[PointerInput.LeftClick] = 1;\n }\n if (evt.pointerId === undefined) {\n evt.pointerId = this._mouseId;\n }\n this._onInputChanged(deviceType, deviceSlot, deviceEvent);\n // Lets Propagate the event for move with same position.\n if (!this._usingSafari && evt.button !== -1) {\n deviceEvent.inputIndex = evt.button + 2;\n pointer[evt.button + 2] = pointer[evt.button + 2] ? 0 : 1; // Reverse state of button if evt.button has value\n this._onInputChanged(deviceType, deviceSlot, deviceEvent);\n }\n }\n };\n this._pointerDownEvent = (evt) => {\n const deviceType = this._getPointerType(evt);\n let deviceSlot = deviceType === DeviceType.Mouse ? 0 : evt.pointerId;\n if (deviceType === DeviceType.Touch) {\n // See if this pointerId is already using an existing slot\n // (possible on some devices which raise the pointerMove event before the pointerDown event, e.g. when using a pen)\n let idx = this._activeTouchIds.indexOf(evt.pointerId);\n if (idx === -1) {\n // If the pointerId wasn't already using a slot, find an open one\n idx = this._activeTouchIds.indexOf(-1);\n }\n if (idx >= 0) {\n deviceSlot = idx;\n this._activeTouchIds[idx] = evt.pointerId;\n }\n else {\n // We can't find an open slot to store new pointer so just return (can only support max number of touches)\n Tools.Warn(`Max number of touches exceeded. Ignoring touches in excess of ${this._maxTouchPoints}`);\n return;\n }\n }\n if (!this._inputs[deviceType]) {\n this._inputs[deviceType] = {};\n }\n if (!this._inputs[deviceType][deviceSlot]) {\n this._addPointerDevice(deviceType, deviceSlot, evt.clientX, evt.clientY);\n }\n else if (deviceType === DeviceType.Touch) {\n this._onDeviceConnected(deviceType, deviceSlot);\n }\n const pointer = this._inputs[deviceType][deviceSlot];\n if (pointer) {\n const previousHorizontal = pointer[PointerInput.Horizontal];\n const previousVertical = pointer[PointerInput.Vertical];\n if (deviceType === DeviceType.Mouse) {\n // Mouse; Set pointerId if undefined\n if (evt.pointerId === undefined) {\n evt.pointerId = this._mouseId;\n }\n if (!document.pointerLockElement) {\n try {\n this._elementToAttachTo.setPointerCapture(this._mouseId);\n }\n catch (e) {\n // DO NOTHING\n }\n }\n }\n else {\n // Touch; Since touches are dynamically assigned, only set capture if we have an id\n if (evt.pointerId && !document.pointerLockElement) {\n try {\n this._elementToAttachTo.setPointerCapture(evt.pointerId);\n }\n catch (e) {\n // DO NOTHING\n }\n }\n }\n pointer[PointerInput.Horizontal] = evt.clientX;\n pointer[PointerInput.Vertical] = evt.clientY;\n pointer[evt.button + 2] = 1;\n const deviceEvent = evt;\n // NOTE: The +2 used here to is because PointerInput has the same value progression for its mouse buttons as PointerEvent.button\n // However, we have our X and Y values front-loaded to group together the touch inputs but not break this progression\n // EG. ([X, Y, Left-click], Middle-click, etc...)\n deviceEvent.inputIndex = evt.button + 2;\n this._onInputChanged(deviceType, deviceSlot, deviceEvent);\n if (previousHorizontal !== evt.clientX || previousVertical !== evt.clientY) {\n deviceEvent.inputIndex = PointerInput.Move;\n this._onInputChanged(deviceType, deviceSlot, deviceEvent);\n }\n }\n };\n this._pointerUpEvent = (evt) => {\n const deviceType = this._getPointerType(evt);\n const deviceSlot = deviceType === DeviceType.Mouse ? 0 : this._activeTouchIds.indexOf(evt.pointerId);\n if (deviceType === DeviceType.Touch) {\n // If we're getting a pointerup event for a touch that isn't active, just return.\n if (deviceSlot === -1) {\n return;\n }\n else {\n this._activeTouchIds[deviceSlot] = -1;\n }\n }\n const pointer = this._inputs[deviceType]?.[deviceSlot];\n if (pointer && pointer[evt.button + 2] !== 0) {\n const previousHorizontal = pointer[PointerInput.Horizontal];\n const previousVertical = pointer[PointerInput.Vertical];\n pointer[PointerInput.Horizontal] = evt.clientX;\n pointer[PointerInput.Vertical] = evt.clientY;\n pointer[evt.button + 2] = 0;\n const deviceEvent = evt;\n if (evt.pointerId === undefined) {\n evt.pointerId = this._mouseId;\n }\n if (previousHorizontal !== evt.clientX || previousVertical !== evt.clientY) {\n deviceEvent.inputIndex = PointerInput.Move;\n this._onInputChanged(deviceType, deviceSlot, deviceEvent);\n }\n // NOTE: The +2 used here to is because PointerInput has the same value progression for its mouse buttons as PointerEvent.button\n // However, we have our X and Y values front-loaded to group together the touch inputs but not break this progression\n // EG. ([X, Y, Left-click], Middle-click, etc...)\n deviceEvent.inputIndex = evt.button + 2;\n if (deviceType === DeviceType.Mouse && this._mouseId >= 0 && this._elementToAttachTo.hasPointerCapture?.(this._mouseId)) {\n this._elementToAttachTo.releasePointerCapture(this._mouseId);\n }\n else if (evt.pointerId && this._elementToAttachTo.hasPointerCapture?.(evt.pointerId)) {\n this._elementToAttachTo.releasePointerCapture(evt.pointerId);\n }\n this._onInputChanged(deviceType, deviceSlot, deviceEvent);\n if (deviceType === DeviceType.Touch) {\n this._onDeviceDisconnected(deviceType, deviceSlot);\n }\n }\n };\n this._pointerCancelEvent = (evt) => {\n if (evt.pointerType === \"mouse\") {\n const pointer = this._inputs[DeviceType.Mouse][0];\n if (this._mouseId >= 0 && this._elementToAttachTo.hasPointerCapture?.(this._mouseId)) {\n this._elementToAttachTo.releasePointerCapture(this._mouseId);\n }\n for (let inputIndex = PointerInput.LeftClick; inputIndex <= PointerInput.BrowserForward; inputIndex++) {\n if (pointer[inputIndex] === 1) {\n pointer[inputIndex] = 0;\n const deviceEvent = DeviceEventFactory.CreateDeviceEvent(DeviceType.Mouse, 0, inputIndex, 0, this, this._elementToAttachTo);\n this._onInputChanged(DeviceType.Mouse, 0, deviceEvent);\n }\n }\n }\n else {\n const deviceSlot = this._activeTouchIds.indexOf(evt.pointerId);\n // If we're getting a pointercancel event for a touch that isn't active, just return\n if (deviceSlot === -1) {\n return;\n }\n if (this._elementToAttachTo.hasPointerCapture?.(evt.pointerId)) {\n this._elementToAttachTo.releasePointerCapture(evt.pointerId);\n }\n this._inputs[DeviceType.Touch][deviceSlot][PointerInput.LeftClick] = 0;\n const deviceEvent = DeviceEventFactory.CreateDeviceEvent(DeviceType.Touch, deviceSlot, PointerInput.LeftClick, 0, this, this._elementToAttachTo, evt.pointerId);\n this._onInputChanged(DeviceType.Touch, deviceSlot, deviceEvent);\n this._activeTouchIds[deviceSlot] = -1;\n this._onDeviceDisconnected(DeviceType.Touch, deviceSlot);\n }\n };\n // Set Wheel Event Name, code originally from scene.inputManager\n this._wheelEventName =\n \"onwheel\" in document.createElement(\"div\")\n ? \"wheel\" // Modern browsers support \"wheel\"\n : document.onmousewheel !== undefined\n ? \"mousewheel\" // Webkit and IE support at least \"mousewheel\"\n : \"DOMMouseScroll\"; // let's assume that remaining browsers are older Firefox\n // Code originally in scene.inputManager.ts\n // Chrome reports warning in console if wheel listener doesn't set an explicit passive option.\n // IE11 only supports captureEvent:boolean, not options:object, and it defaults to false.\n // Feature detection technique copied from: https://github.com/github/eventlistener-polyfill (MIT license)\n let passiveSupported = false;\n const noop = function () { };\n try {\n const options = Object.defineProperty({}, \"passive\", {\n get: function () {\n passiveSupported = true;\n },\n });\n this._elementToAttachTo.addEventListener(\"test\", noop, options);\n this._elementToAttachTo.removeEventListener(\"test\", noop, options);\n }\n catch (e) {\n /* */\n }\n this._pointerBlurEvent = () => {\n // Handle mouse buttons\n if (this.isDeviceAvailable(DeviceType.Mouse)) {\n const pointer = this._inputs[DeviceType.Mouse][0];\n if (this._mouseId >= 0 && this._elementToAttachTo.hasPointerCapture?.(this._mouseId)) {\n this._elementToAttachTo.releasePointerCapture(this._mouseId);\n }\n for (let inputIndex = PointerInput.LeftClick; inputIndex <= PointerInput.BrowserForward; inputIndex++) {\n if (pointer[inputIndex] === 1) {\n pointer[inputIndex] = 0;\n const deviceEvent = DeviceEventFactory.CreateDeviceEvent(DeviceType.Mouse, 0, inputIndex, 0, this, this._elementToAttachTo);\n this._onInputChanged(DeviceType.Mouse, 0, deviceEvent);\n }\n }\n }\n // Handle Active Touches\n if (this.isDeviceAvailable(DeviceType.Touch)) {\n const pointer = this._inputs[DeviceType.Touch];\n for (let deviceSlot = 0; deviceSlot < this._activeTouchIds.length; deviceSlot++) {\n const pointerId = this._activeTouchIds[deviceSlot];\n if (this._elementToAttachTo.hasPointerCapture?.(pointerId)) {\n this._elementToAttachTo.releasePointerCapture(pointerId);\n }\n if (pointerId !== -1 && pointer[deviceSlot]?.[PointerInput.LeftClick] === 1) {\n pointer[deviceSlot][PointerInput.LeftClick] = 0;\n const deviceEvent = DeviceEventFactory.CreateDeviceEvent(DeviceType.Touch, deviceSlot, PointerInput.LeftClick, 0, this, this._elementToAttachTo, pointerId);\n this._onInputChanged(DeviceType.Touch, deviceSlot, deviceEvent);\n this._activeTouchIds[deviceSlot] = -1;\n this._onDeviceDisconnected(DeviceType.Touch, deviceSlot);\n }\n }\n }\n };\n this._pointerWheelEvent = (evt) => {\n const deviceType = DeviceType.Mouse;\n const deviceSlot = 0;\n if (!this._inputs[deviceType]) {\n this._inputs[deviceType] = [];\n }\n if (!this._inputs[deviceType][deviceSlot]) {\n this._pointerActive = true;\n this._registerDevice(deviceType, deviceSlot, MAX_POINTER_INPUTS);\n }\n const pointer = this._inputs[deviceType][deviceSlot];\n if (pointer) {\n pointer[PointerInput.MouseWheelX] = evt.deltaX || 0;\n pointer[PointerInput.MouseWheelY] = evt.deltaY || evt.wheelDelta || 0;\n pointer[PointerInput.MouseWheelZ] = evt.deltaZ || 0;\n const deviceEvent = evt;\n // By default, there is no pointerId for mouse wheel events so we'll add one here\n // This logic was originally in the InputManager but was added here to make the\n // InputManager more platform-agnostic\n if (evt.pointerId === undefined) {\n evt.pointerId = this._mouseId;\n }\n if (pointer[PointerInput.MouseWheelX] !== 0) {\n deviceEvent.inputIndex = PointerInput.MouseWheelX;\n this._onInputChanged(deviceType, deviceSlot, deviceEvent);\n }\n if (pointer[PointerInput.MouseWheelY] !== 0) {\n deviceEvent.inputIndex = PointerInput.MouseWheelY;\n this._onInputChanged(deviceType, deviceSlot, deviceEvent);\n }\n if (pointer[PointerInput.MouseWheelZ] !== 0) {\n deviceEvent.inputIndex = PointerInput.MouseWheelZ;\n this._onInputChanged(deviceType, deviceSlot, deviceEvent);\n }\n }\n };\n // Workaround for MacOS Chromium Browsers for lost pointer capture bug\n if (this._usingMacOS && this._isUsingChromium) {\n this._pointerMacOSChromeOutEvent = (evt) => {\n if (evt.buttons > 1) {\n this._pointerCancelEvent(evt);\n }\n };\n this._elementToAttachTo.addEventListener(\"lostpointercapture\", this._pointerMacOSChromeOutEvent);\n }\n this._elementToAttachTo.addEventListener(this._eventPrefix + \"move\", this._pointerMoveEvent);\n this._elementToAttachTo.addEventListener(this._eventPrefix + \"down\", this._pointerDownEvent);\n this._elementToAttachTo.addEventListener(this._eventPrefix + \"up\", this._pointerUpEvent);\n this._elementToAttachTo.addEventListener(this._eventPrefix + \"cancel\", this._pointerCancelEvent);\n this._elementToAttachTo.addEventListener(\"blur\", this._pointerBlurEvent);\n this._elementToAttachTo.addEventListener(this._wheelEventName, this._pointerWheelEvent, passiveSupported ? { passive: false } : false);\n // Since there's no up or down event for mouse wheel or delta x/y, clear mouse values at end of frame\n this._pointerInputClearObserver = this._engine.onEndFrameObservable.add(() => {\n if (this.isDeviceAvailable(DeviceType.Mouse)) {\n const pointer = this._inputs[DeviceType.Mouse][0];\n pointer[PointerInput.MouseWheelX] = 0;\n pointer[PointerInput.MouseWheelY] = 0;\n pointer[PointerInput.MouseWheelZ] = 0;\n }\n });\n }\n /**\n * Handle all actions that come from gamepad interaction\n */\n _handleGamepadActions() {\n this._gamepadConnectedEvent = (evt) => {\n this._addGamePad(evt.gamepad);\n };\n this._gamepadDisconnectedEvent = (evt) => {\n if (this._gamepads) {\n const deviceType = this._getGamepadDeviceType(evt.gamepad.id);\n const deviceSlot = evt.gamepad.index;\n this._unregisterDevice(deviceType, deviceSlot);\n delete this._gamepads[deviceSlot];\n }\n };\n window.addEventListener(\"gamepadconnected\", this._gamepadConnectedEvent);\n window.addEventListener(\"gamepaddisconnected\", this._gamepadDisconnectedEvent);\n }\n /**\n * Update all non-event based devices with each frame\n * @param deviceType Enum specifying device type\n * @param deviceSlot \"Slot\" or index that device is referenced in\n * @param inputIndex Id of input to be checked\n */\n _updateDevice(deviceType, deviceSlot, inputIndex) {\n // Gamepads\n const gp = navigator.getGamepads()[deviceSlot];\n if (gp && deviceType === this._gamepads[deviceSlot]) {\n const device = this._inputs[deviceType][deviceSlot];\n if (inputIndex >= gp.buttons.length) {\n device[inputIndex] = gp.axes[inputIndex - gp.buttons.length].valueOf();\n }\n else {\n device[inputIndex] = gp.buttons[inputIndex].value;\n }\n }\n }\n /**\n * Gets DeviceType from the device name\n * @param deviceName Name of Device from DeviceInputSystem\n * @returns DeviceType enum value\n */\n _getGamepadDeviceType(deviceName) {\n if (deviceName.indexOf(\"054c\") !== -1) {\n // DualShock 4 Gamepad\n return deviceName.indexOf(\"0ce6\") !== -1 ? DeviceType.DualSense : DeviceType.DualShock;\n }\n else if (deviceName.indexOf(\"Xbox One\") !== -1 || deviceName.search(\"Xbox 360\") !== -1 || deviceName.search(\"xinput\") !== -1) {\n // Xbox Gamepad\n return DeviceType.Xbox;\n }\n else if (deviceName.indexOf(\"057e\") !== -1) {\n // Switch Gamepad\n return DeviceType.Switch;\n }\n return DeviceType.Generic;\n }\n /**\n * Get DeviceType from a given pointer/mouse/touch event.\n * @param evt PointerEvent to evaluate\n * @returns DeviceType interpreted from event\n */\n _getPointerType(evt) {\n let deviceType = DeviceType.Mouse;\n if (evt.pointerType === \"touch\" || evt.pointerType === \"pen\" || evt.touches) {\n deviceType = DeviceType.Touch;\n }\n return deviceType;\n }\n}\n"],"mappings":"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","ignoreList":[]},"metadata":{},"sourceType":"module","externalDependencies":[]}