@omnipad/core 0.2.0-alpha.3 → 0.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1 @@
1
+ 'use strict';var chunkFWW6DLM7_cjs=require('../chunk-FWW6DLM7.cjs');var E=(t,o,n="omnipad-prevent")=>{let r=document.elementsFromPoint(t,o).find(i=>!i.classList.contains(n));if(!r)return null;for(;r&&r.shadowRoot;){let f=r.shadowRoot.elementsFromPoint(t,o).find(u=>!u.classList.contains(n));if(!f||f===r)break;r=f;}return r},y=()=>{let t=document.activeElement;for(;t&&t.shadowRoot&&t.shadowRoot.activeElement;)t=t.shadowRoot.activeElement;return t},S=t=>{y()!==t&&(t.hasAttribute("tabindex")||t.setAttribute("tabindex","-1"),t.focus());},Q=(t,o)=>{let n=new KeyboardEvent(t,{...o,which:o.keyCode,bubbles:true,cancelable:true,view:window});window.dispatchEvent(n);},_=(t,o,n,a)=>{let r=E(o,n);if(!r)return;let i={bubbles:true,cancelable:true,composed:true,clientX:o,clientY:n,view:window,...a};if(t.startsWith("pointer")){r.dispatchEvent(new PointerEvent(t,{isPrimary:true,pointerId:9999,pointerType:"mouse",...i}));let f=t.replace("pointer","mouse");r.dispatchEvent(new MouseEvent(f,i));}else r.dispatchEvent(new MouseEvent(t,i));},X=(t,o,n)=>{let a=E(t,o);if(!a)return;y()!==a&&(S(a),n());},l,Y=()=>(l!==void 0||(l=typeof window<"u"&&!!window.CSS?.supports?.("width: 1cqw")),l),C=(t,o)=>{if(t instanceof Element)try{t.setPointerCapture(o);}catch(n){undefined?.DEV&&console.warn("[Omnipad-DOM] Failed to set pointer capture:",n);}},I=(t,o)=>{if(t instanceof Element&&t.hasPointerCapture(o))try{t.releasePointerCapture(o);}catch{}};function Z(t,o={}){return {onPointerDown(n){if(!n.isTrusted||o?.requireDirectHit&&n.target!==n.currentTarget||t.activePointerId!=null)return;n.cancelable&&n.preventDefault(),n.stopPropagation();let a=n.currentTarget;a&&C(a,n.pointerId),t.onPointerDown(n);},onPointerMove(n){n.isTrusted&&(t.activePointerId!=null&&t.activePointerId!==n.pointerId||(n.cancelable&&n.preventDefault(),t.onPointerMove(n)));},onPointerUp(n){if(!n.isTrusted||t.activePointerId!=null&&t.activePointerId!==n.pointerId)return;n.cancelable&&n.preventDefault();let a=n.currentTarget;a&&I(a,n.pointerId),t.onPointerUp(n);},onPointerCancel(n){if(!n.isTrusted||t.activePointerId!=null&&t.activePointerId!==n.pointerId)return;let a=n.currentTarget;a&&I(a,n.pointerId),t.onPointerCancel(n);}}}var v=(t="omnipad")=>{let o=Date.now().toString(36),n=Math.random().toString(36).substring(2,6);return `${t}-${o}-${n}`};function m(t){return t.startsWith("$")}var et=t=>{if(!t)return {};let o={};o.position="absolute",t.isSquare&&(o.aspectRatio="1/1"),["left","top","right","bottom","width","height"].forEach(r=>{let i=t[r];i!==void 0&&typeof i=="number"?o[r]=`${i}px`:i!==void 0&&typeof i=="string"&&(o[r]=i);}),t.zIndex!==void 0&&(o.zIndex=t.zIndex);let a={"top-left":"translate(0, 0)","top-center":"translate(-50%, 0)","top-right":"translate(-100%, 0)","center-left":"translate(0, -50%)",center:"translate(-50%, -50%)","center-right":"translate(-100%, -50%)","bottom-left":"translate(0, -100%)","bottom-center":"translate(-50%, -100%)","bottom-right":"translate(-100%, -100%)"};return t.anchor&&(o.transform=a[t.anchor]),o};function it(t){if(!t||typeof t!="object")throw new Error("[OmniPad-Validation] Profile must be a valid JSON object.");if(!Array.isArray(t.items))throw new Error('[OmniPad-Validation] "items" must be an array.');let o={name:t.meta?.name||"Untitled Profile",version:t.meta?.version||"1.0.0",author:t.meta?.author||"Unknown"},n=t.items.map((r,i)=>{if(!r.id||!r.type)throw new Error(`[OmniPad-Validation] Item at index ${i} is missing "id" or "type".`);return {id:String(r.id),type:String(r.type),parentId:r.parentId?String(r.parentId):void 0,config:r.config||{}}}),a=t.gamepadMappings;return {meta:o,items:n,gamepadMappings:a}}function at(t){let{items:o,gamepadMappings:n}=t,a=new Map,r=(e,s="node")=>m(e)?e:(a.has(e)||a.set(e,v(s)),a.get(e));o.forEach(e=>r(e.id,e.type));let i=[];n&&n.forEach(e=>{let s={};if(e.buttons){s.buttons={};for(let[c,d]of Object.entries(e.buttons))s.buttons[c]=r(d);}e.dpad&&(s.dpad=r(e.dpad)),e.leftStick&&(s.leftStick=r(e.leftStick)),e.rightStick&&(s.rightStick=r(e.rightStick)),i.push(s);});let f=new Map,u=[];o.forEach(e=>{e.parentId?(f.has(e.parentId)||f.set(e.parentId,[]),f.get(e.parentId).push(e)):u.push(e);});let g=(e,s)=>{if(s.has(e.id))throw new Error(`[Omnipad-Core] Circular dependency detected at node: ${e.id}`);s.add(e.id);let c={...e.config};c?.targetStageId&&(c.targetStageId=r(c.targetStageId)),c?.dynamicWidgetId&&(c.dynamicWidgetId=r(c.dynamicWidgetId));let h=(f.get(e.id)||[]).map(b=>g(b,new Set(s)));return {uid:r(e.id),type:e.type,config:c,children:h}},p={};return u.forEach(e=>{p[e.id]=g(e,new Set);}),{roots:p,runtimeGamepadMappings:i}}function st(t,o,n){let a=chunkFWW6DLM7_cjs.b.getInstance(),r=[];if(!o||o.length===0)r=a.getAllEntities();else {let e=new Set;o.forEach(s=>{a.getEntitiesByRoot(s).forEach(d=>e.add(d));}),r=Array.from(e);}let i=new Map,f=0,u=e=>m(e)?e:(i.has(e)||i.set(e,`node_${++f}`),i.get(e)),g=r.map(e=>{let s=e.getConfig(),c=e.uid,d={...s};d.targetStageId&&(d.targetStageId=u(d.targetStageId)),d.dynamicWidgetId&&(d.dynamicWidgetId=u(d.dynamicWidgetId));let{id:h,parentId:b,...w}=d;return {id:u(c),type:e.type,parentId:s.parentId?u(s.parentId):void 0,config:w}}),p=[];return n&&n.forEach(e=>{let s={};if(e.buttons){s.buttons={};for(let[c,d]of Object.entries(e.buttons))i.has(d)&&(s.buttons[c]=i.get(d));}e.dpad&&i.has(e.dpad)&&(s.dpad=i.get(e.dpad)),e.leftStick&&i.has(e.leftStick)&&(s.leftStick=i.get(e.leftStick)),e.rightStick&&i.has(e.rightStick)&&(s.rightStick=i.get(e.rightStick)),Object.keys(s).length>0?p.push(s):p.push({});}),{meta:t,items:g,gamepadMappings:Object.keys(p).length>0?p:void 0}}Object.defineProperty(exports,"addVec",{enumerable:true,get:function(){return chunkFWW6DLM7_cjs.d}});Object.defineProperty(exports,"applyAxialDeadzone",{enumerable:true,get:function(){return chunkFWW6DLM7_cjs.x}});Object.defineProperty(exports,"applyRadialDeadzone",{enumerable:true,get:function(){return chunkFWW6DLM7_cjs.w}});Object.defineProperty(exports,"clamp",{enumerable:true,get:function(){return chunkFWW6DLM7_cjs.f}});Object.defineProperty(exports,"clampVector",{enumerable:true,get:function(){return chunkFWW6DLM7_cjs.m}});Object.defineProperty(exports,"degToRad",{enumerable:true,get:function(){return chunkFWW6DLM7_cjs.l}});Object.defineProperty(exports,"getAngle",{enumerable:true,get:function(){return chunkFWW6DLM7_cjs.j}});Object.defineProperty(exports,"getDeadzoneScalar",{enumerable:true,get:function(){return chunkFWW6DLM7_cjs.v}});Object.defineProperty(exports,"getDistance",{enumerable:true,get:function(){return chunkFWW6DLM7_cjs.i}});Object.defineProperty(exports,"isVec2Equal",{enumerable:true,get:function(){return chunkFWW6DLM7_cjs.u}});Object.defineProperty(exports,"lerp",{enumerable:true,get:function(){return chunkFWW6DLM7_cjs.g}});Object.defineProperty(exports,"lockTo4Directions",{enumerable:true,get:function(){return chunkFWW6DLM7_cjs.o}});Object.defineProperty(exports,"lockTo8Directions",{enumerable:true,get:function(){return chunkFWW6DLM7_cjs.n}});Object.defineProperty(exports,"normalizeVec",{enumerable:true,get:function(){return chunkFWW6DLM7_cjs.r}});Object.defineProperty(exports,"percentToPx",{enumerable:true,get:function(){return chunkFWW6DLM7_cjs.p}});Object.defineProperty(exports,"pxToPercent",{enumerable:true,get:function(){return chunkFWW6DLM7_cjs.q}});Object.defineProperty(exports,"radToDeg",{enumerable:true,get:function(){return chunkFWW6DLM7_cjs.k}});Object.defineProperty(exports,"radToVec",{enumerable:true,get:function(){return chunkFWW6DLM7_cjs.s}});Object.defineProperty(exports,"remap",{enumerable:true,get:function(){return chunkFWW6DLM7_cjs.t}});Object.defineProperty(exports,"roundTo",{enumerable:true,get:function(){return chunkFWW6DLM7_cjs.h}});Object.defineProperty(exports,"scaleVec",{enumerable:true,get:function(){return chunkFWW6DLM7_cjs.e}});Object.defineProperty(exports,"subVec",{enumerable:true,get:function(){return chunkFWW6DLM7_cjs.c}});exports.createPointerBridge=Z;exports.dispatchKeyboardEvent=Q;exports.dispatchPointerEventAtPos=_;exports.exportProfile=st;exports.focusElement=S;exports.generateUID=v;exports.getDeepActiveElement=y;exports.getDeepElement=E;exports.isGlobalID=m;exports.parseProfileJson=it;exports.parseProfileTrees=at;exports.reclaimFocusAtPos=X;exports.resolveLayoutStyle=et;exports.safeReleaseCapture=I;exports.safeSetCapture=C;exports.supportsContainerQueries=Y;
@@ -0,0 +1,310 @@
1
+ import { e as IPointerHandler, M as LayoutBox, V as Vec2, v as ConfigTreeNode, G as GamepadMappingConfig, x as GamepadProfile } from '../index-DRA1rw5_.cjs';
2
+
3
+ /**
4
+ * Recursively penetrates Shadow DOM boundaries to find the deepest element at the
5
+ * specified viewport coordinates.
6
+ *
7
+ * @param x - Viewport X coordinate (px)
8
+ * @param y - Viewport Y coordinate (px)
9
+ * @param ignoreClass - Style class of DOM elements to be ignored
10
+ * @returns The deepmost Element or null if none found at the position.
11
+ */
12
+ declare const getDeepElement: (x: number, y: number, ignoreClass?: string) => Element | null;
13
+ /**
14
+ * Recursively finds the truly focused element by traversing Shadow DOM boundaries.
15
+ *
16
+ * @returns The deepmost active Element in focus or null.
17
+ */
18
+ declare const getDeepActiveElement: () => Element | null;
19
+ /**
20
+ * Forcefully focuses an element.
21
+ * Automatically handles the 'tabindex' attribute to ensure non-focusable elements (like Canvas)
22
+ * can receive focus.
23
+ *
24
+ * @param el - The target HTMLElement to focus.
25
+ */
26
+ declare const focusElement: (el: HTMLElement) => void;
27
+ /**
28
+ * Dispatches a synthetic KeyboardEvent to the window object.
29
+ *
30
+ * @param type - The event type, e.g., 'keydown' or 'keyup'.
31
+ * @param payload - Key mapping data including key, code, and legacy keyCode.
32
+ */
33
+ declare const dispatchKeyboardEvent: (type: string, payload: {
34
+ key: string;
35
+ code: string;
36
+ keyCode: number;
37
+ }) => void;
38
+ /**
39
+ * Dispatches a high-fidelity sequence of Pointer and Mouse events at specific pixel coordinates.
40
+ * Finds the target element dynamically at the moment of dispatch.
41
+ *
42
+ * @param type - The event type (should start with 'pointer' for best compatibility).
43
+ * @param x - Viewport X coordinate (px).
44
+ * @param y - Viewport Y coordinate (px).
45
+ * @param opts - Additional PointerEvent options (button, pressure, etc.).
46
+ */
47
+ declare const dispatchPointerEventAtPos: (type: string, x: number, y: number, opts: {
48
+ button: number;
49
+ buttons: number;
50
+ pressure: number;
51
+ }) => void;
52
+ /**
53
+ * Reclaims browser focus for the element located at the specified viewport coordinates.
54
+ *
55
+ * This utility identifies the deepest element (penetrating Shadow DOM) at the given position
56
+ * and ensures it becomes the active element. It is essential for ensuring that
57
+ * game engines (like Ruffle) receive keyboard events immediately after a virtual interaction.
58
+ *
59
+ * @param x - The horizontal coordinate relative to the viewport.
60
+ * @param y - The vertical coordinate relative to the viewport.
61
+ * @returns True if the focus was successfully moved to the target; false if it was already focused or no target found.
62
+ */
63
+ declare const reclaimFocusAtPos: (x: number, y: number, callback: () => void) => void;
64
+ declare const supportsContainerQueries: () => boolean;
65
+ /**
66
+ * Safely sets pointer capture on an element.
67
+ *
68
+ * @param el - The target element to capture the pointer.
69
+ * @param pointerId - The unique ID of the pointer (from PointerEvent).
70
+ */
71
+ declare const safeSetCapture: (el: EventTarget | null, pointerId: number) => void;
72
+ /**
73
+ * Safely releases pointer capture from an element.
74
+ * Checks for current capture state and wraps in try-catch to prevent crashes.
75
+ *
76
+ * @param el - The target element.
77
+ * @param pointerId - The unique ID of the pointer to release.
78
+ */
79
+ declare const safeReleaseCapture: (el: EventTarget | null, pointerId: number) => void;
80
+ /**
81
+ * Creates a standardized bridge between native DOM PointerEvents and Core abstract handlers.
82
+ * Handles event prevention, stop propagation, pointer capture, and multi-touch filtering.
83
+ *
84
+ * @param coreHandler - The logic core instance that implements IPointerHandler.
85
+ * @param getElement - A getter function to retrieve the DOM element for pointer capture.
86
+ * @returns An object containing mapped event handlers for Vue/React template binding.
87
+ */
88
+ declare function createPointerBridge(coreHandler: IPointerHandler & {
89
+ activePointerId?: number | null;
90
+ }, options?: {
91
+ /** Respond only to direct clicks (without responding to events bubbled up from child elements) */
92
+ requireDirectHit?: boolean;
93
+ }): {
94
+ /**
95
+ * Entry point for a pointer interaction.
96
+ * Establishes capture and initializes core logic.
97
+ */
98
+ onPointerDown(e: PointerEvent): void;
99
+ /**
100
+ * Continuous movement handling.
101
+ * Throttling should be handled within the core implementation.
102
+ */
103
+ onPointerMove(e: PointerEvent): void;
104
+ /**
105
+ * Successful interaction completion.
106
+ * Filters by pointerId to ensure only the capturing finger triggers release.
107
+ */
108
+ onPointerUp(e: PointerEvent): void;
109
+ /**
110
+ * System-level interaction cancellation (e.g., alert popups, browser gestures).
111
+ */
112
+ onPointerCancel(e: PointerEvent): void;
113
+ };
114
+
115
+ /**
116
+ * Generates a globally unique identifier (UID) for runtime entity management and DOM keys.
117
+ *
118
+ * The generated ID follows the format: `[prefix]-[timestamp_base36]-[random_string]`.
119
+ * This ensures that components generated at different times or across multiple sessions
120
+ * remain unique within the current page instance.
121
+ *
122
+ * @param prefix - A string prefix for the ID, typically the component type (e.g., 'btn', 'joy'). Defaults to 'omnipad'.
123
+ * @returns A unique string identifier.
124
+ *
125
+ * @example
126
+ * generateUID('button') // returns "button-m7x8k1p2-f4k2"
127
+ */
128
+ declare const generateUID: (prefix?: string) => string;
129
+ /**
130
+ * Checks if the provided ID is a reserved global identifier.
131
+ *
132
+ * In OmniPad, IDs starting with the `$` symbol are considered "Global IDs".
133
+ * These identifiers are treated as static references and are not transformed
134
+ * into dynamic UIDs during configuration parsing.
135
+ *
136
+ * @param id - The identifier string to check.
137
+ * @returns `true` if the ID starts with `$`, otherwise `false`.
138
+ *
139
+ * @example
140
+ * isGlobalID('$root-layer') // returns true
141
+ * isGlobalID('btn-up') // returns false
142
+ */
143
+ declare function isGlobalID(id: string): boolean;
144
+
145
+ /**
146
+ * Converts a LayoutBox configuration into a CSS style object suitable for Vue/React.
147
+ *
148
+ * This utility handles:
149
+ * 1. Unit normalization: Converts numeric values to 'px' strings while preserving unit strings (vh, %, etc.).
150
+ * 2. Positioning: Sets 'absolute' positioning by default.
151
+ * 3. Anchoring: Maps AnchorPoint values to CSS 'transform' translations to ensure
152
+ * the component's origin matches its defined coordinates.
153
+ *
154
+ * @param layout - The LayoutBox configuration object.
155
+ * @returns A CSS style record object.
156
+ *
157
+ * @example
158
+ * // returns { position: 'absolute', left: '50%', top: '50%', transform: 'translate(-50%, -50%)' }
159
+ * resolveLayoutStyle({ left: '50%', top: '50%', anchor: 'center' });
160
+ */
161
+ declare const resolveLayoutStyle: (layout: LayoutBox) => Record<string, string | number>;
162
+
163
+ /**
164
+ * Subtracts vector v2 from v1.
165
+ * @param v1 - The source vector.
166
+ * @param v2 - The vector to subtract.
167
+ */
168
+ declare const subVec: (v1: Vec2, v2: Vec2) => Vec2;
169
+ /**
170
+ * Adds vector v2 to v1.
171
+ */
172
+ declare const addVec: (v1: Vec2, v2: Vec2) => Vec2;
173
+ /**
174
+ * Scales a vector by a scalar value.
175
+ * Useful for mapping normalized vectors back to specific pixel magnitudes.
176
+ */
177
+ declare const scaleVec: (v: Vec2, s: number) => Vec2;
178
+ /**
179
+ * Clamps a numeric value between a minimum and maximum range.
180
+ */
181
+ declare const clamp: (val: number, min: number, max: number) => number;
182
+ /**
183
+ * Linearly interpolates between two values.
184
+ */
185
+ declare const lerp: (start: number, end: number, t: number) => number;
186
+ /**
187
+ * Rounds a number to a specific decimal precision.
188
+ * Solves floating-point precision issues in pixel calculations.
189
+ */
190
+ declare const roundTo: (val: number, precision?: number) => number;
191
+ /**
192
+ * Calculates the Euclidean distance between two points.
193
+ */
194
+ declare const getDistance: (p1: Vec2, p2: Vec2) => number;
195
+ /**
196
+ * Calculates the angle in radians from point p1 to p2.
197
+ * Range: -PI to PI.
198
+ */
199
+ declare const getAngle: (p1: Vec2, p2: Vec2) => number;
200
+ /**
201
+ * Converts radians to degrees.
202
+ */
203
+ declare const radToDeg: (rad: number) => number;
204
+ /**
205
+ * Converts degrees to radians.
206
+ */
207
+ declare const degToRad: (deg: number) => number;
208
+ /**
209
+ * Constrains a target point within a circular radius relative to an origin.
210
+ * Commonly used for joystick physical displacement limits.
211
+ */
212
+ declare const clampVector: (origin: Vec2, target: Vec2, radius: number) => Vec2;
213
+ /**
214
+ * Snaps a radian angle to the nearest of 8 directions (45-degree steps).
215
+ */
216
+ declare const lockTo8Directions: (rad: number) => number;
217
+ /**
218
+ * Snaps a radian angle to the nearest of 4 directions (90-degree steps).
219
+ */
220
+ declare const lockTo4Directions: (rad: number) => number;
221
+ /**
222
+ * Converts percentage (0-100) to pixel values (px).
223
+ */
224
+ declare const percentToPx: (percent: number, totalPx: number) => number;
225
+ /**
226
+ * Converts pixel values (px) to percentage (0-100).
227
+ */
228
+ declare const pxToPercent: (px: number, totalPx: number) => number;
229
+ /**
230
+ * Normalizes a vector to a length of 1.
231
+ * Returns {0, 0} if the vector magnitude is 0.
232
+ */
233
+ declare const normalizeVec: (v: Vec2) => Vec2;
234
+ /**
235
+ * Converts a radian angle to a unit vector.
236
+ */
237
+ declare const radToVec: (rad: number) => Vec2;
238
+ /**
239
+ * Linearly remaps a value from one range [inMin, inMax] to another [outMin, outMax].
240
+ */
241
+ declare const remap: (val: number, inMin: number, inMax: number, outMin: number, outMax: number) => number;
242
+ /**
243
+ * Performs a dirty check to see if two Vec2 points are different within an epsilon.
244
+ */
245
+ declare const isVec2Equal: (v1: Vec2, v2: Vec2, epsilon?: number) => boolean;
246
+ /**
247
+ * Core deadzone logic.
248
+ * Maps a value from [threshold, max] to a normalized scale [0, 1].
249
+ * @returns A scalar value between 0 and 1.
250
+ */
251
+ declare const getDeadzoneScalar: (magnitude: number, threshold: number, max: number) => number;
252
+ /**
253
+ * Applies a radial deadzone to a vector.
254
+ * Suitable for analog sticks to ensure a smooth transition from center.
255
+ * @param v - Input vector.
256
+ * @param radius - The total radius of the joystick base.
257
+ * @param deadzonePercent - Deadzone threshold (0.0 to 1.0).
258
+ */
259
+ declare const applyRadialDeadzone: (v: Vec2, radius: number, deadzonePercent: number) => Vec2;
260
+ /**
261
+ * Applies an axial deadzone to a vector.
262
+ * Independently processes X and Y axes. Useful for D-Pads or precision directional inputs.
263
+ * @param v - Input vector.
264
+ * @param threshold - The deadzone threshold value.
265
+ * @param max - Maximum value for the axis.
266
+ */
267
+ declare const applyAxialDeadzone: (v: Vec2, threshold: number, max: number) => Vec2;
268
+
269
+ /**
270
+ * Validates and normalizes raw JSON data into a standard GamepadProfile.
271
+ * Performs structural checks and injects default metadata.
272
+ *
273
+ * @param raw - The raw JSON object from disk or network.
274
+ * @returns A validated GamepadProfile object.
275
+ * @throws Error if the core structure is invalid.
276
+ */
277
+ declare function parseProfileJson(raw: any): GamepadProfile;
278
+ /**
279
+ * The resulting structure after parsing a GamepadProfile.
280
+ * Contains a map of root nodes and a runtime-ready gamepad mapping table.
281
+ */
282
+ interface ParsedProfileForest {
283
+ /** Root nodes indexed by their original Config ID. */
284
+ roots: Record<string, ConfigTreeNode>;
285
+ /**
286
+ * Processed gamepad mapping where all CIDs have been
287
+ * translated into unique runtime UIDs.
288
+ */
289
+ runtimeGamepadMappings: GamepadMappingConfig[];
290
+ }
291
+ /**
292
+ * Converts a flat GamepadProfile into a forest of ConfigTreeNodes for runtime rendering.
293
+ * Automatically identifies all items without a parentId as root nodes.
294
+ *
295
+ * @param profile - The normalized profile data.
296
+ * @returns A record map of root nodes, keyed by their original configuration ID.
297
+ */
298
+ declare function parseProfileTrees(profile: GamepadProfile): ParsedProfileForest;
299
+ /**
300
+ * Serializes the specified runtime entities into a flat GamepadProfile.
301
+ * If no rootUids are provided, exports all entities currently in the registry.
302
+ *
303
+ * @param meta - Metadata for the exported profile.
304
+ * @param rootUid - The Entity ID of the node to be treated as the root.
305
+ * @param runtimeGamepadMapping - The current mapping from GamepadManager (using UIDs).
306
+ * @returns A flat GamepadProfile ready for storage.
307
+ */
308
+ declare function exportProfile(meta: GamepadProfile['meta'], rootUids?: string[], runtimeGamepadMappings?: Readonly<GamepadMappingConfig[]>): GamepadProfile;
309
+
310
+ export { type ParsedProfileForest, addVec, applyAxialDeadzone, applyRadialDeadzone, clamp, clampVector, createPointerBridge, degToRad, dispatchKeyboardEvent, dispatchPointerEventAtPos, exportProfile, focusElement, generateUID, getAngle, getDeadzoneScalar, getDeepActiveElement, getDeepElement, getDistance, isGlobalID, isVec2Equal, lerp, lockTo4Directions, lockTo8Directions, normalizeVec, parseProfileJson, parseProfileTrees, percentToPx, pxToPercent, radToDeg, radToVec, reclaimFocusAtPos, remap, resolveLayoutStyle, roundTo, safeReleaseCapture, safeSetCapture, scaleVec, subVec, supportsContainerQueries };
@@ -0,0 +1,310 @@
1
+ import { e as IPointerHandler, M as LayoutBox, V as Vec2, v as ConfigTreeNode, G as GamepadMappingConfig, x as GamepadProfile } from '../index-DRA1rw5_.js';
2
+
3
+ /**
4
+ * Recursively penetrates Shadow DOM boundaries to find the deepest element at the
5
+ * specified viewport coordinates.
6
+ *
7
+ * @param x - Viewport X coordinate (px)
8
+ * @param y - Viewport Y coordinate (px)
9
+ * @param ignoreClass - Style class of DOM elements to be ignored
10
+ * @returns The deepmost Element or null if none found at the position.
11
+ */
12
+ declare const getDeepElement: (x: number, y: number, ignoreClass?: string) => Element | null;
13
+ /**
14
+ * Recursively finds the truly focused element by traversing Shadow DOM boundaries.
15
+ *
16
+ * @returns The deepmost active Element in focus or null.
17
+ */
18
+ declare const getDeepActiveElement: () => Element | null;
19
+ /**
20
+ * Forcefully focuses an element.
21
+ * Automatically handles the 'tabindex' attribute to ensure non-focusable elements (like Canvas)
22
+ * can receive focus.
23
+ *
24
+ * @param el - The target HTMLElement to focus.
25
+ */
26
+ declare const focusElement: (el: HTMLElement) => void;
27
+ /**
28
+ * Dispatches a synthetic KeyboardEvent to the window object.
29
+ *
30
+ * @param type - The event type, e.g., 'keydown' or 'keyup'.
31
+ * @param payload - Key mapping data including key, code, and legacy keyCode.
32
+ */
33
+ declare const dispatchKeyboardEvent: (type: string, payload: {
34
+ key: string;
35
+ code: string;
36
+ keyCode: number;
37
+ }) => void;
38
+ /**
39
+ * Dispatches a high-fidelity sequence of Pointer and Mouse events at specific pixel coordinates.
40
+ * Finds the target element dynamically at the moment of dispatch.
41
+ *
42
+ * @param type - The event type (should start with 'pointer' for best compatibility).
43
+ * @param x - Viewport X coordinate (px).
44
+ * @param y - Viewport Y coordinate (px).
45
+ * @param opts - Additional PointerEvent options (button, pressure, etc.).
46
+ */
47
+ declare const dispatchPointerEventAtPos: (type: string, x: number, y: number, opts: {
48
+ button: number;
49
+ buttons: number;
50
+ pressure: number;
51
+ }) => void;
52
+ /**
53
+ * Reclaims browser focus for the element located at the specified viewport coordinates.
54
+ *
55
+ * This utility identifies the deepest element (penetrating Shadow DOM) at the given position
56
+ * and ensures it becomes the active element. It is essential for ensuring that
57
+ * game engines (like Ruffle) receive keyboard events immediately after a virtual interaction.
58
+ *
59
+ * @param x - The horizontal coordinate relative to the viewport.
60
+ * @param y - The vertical coordinate relative to the viewport.
61
+ * @returns True if the focus was successfully moved to the target; false if it was already focused or no target found.
62
+ */
63
+ declare const reclaimFocusAtPos: (x: number, y: number, callback: () => void) => void;
64
+ declare const supportsContainerQueries: () => boolean;
65
+ /**
66
+ * Safely sets pointer capture on an element.
67
+ *
68
+ * @param el - The target element to capture the pointer.
69
+ * @param pointerId - The unique ID of the pointer (from PointerEvent).
70
+ */
71
+ declare const safeSetCapture: (el: EventTarget | null, pointerId: number) => void;
72
+ /**
73
+ * Safely releases pointer capture from an element.
74
+ * Checks for current capture state and wraps in try-catch to prevent crashes.
75
+ *
76
+ * @param el - The target element.
77
+ * @param pointerId - The unique ID of the pointer to release.
78
+ */
79
+ declare const safeReleaseCapture: (el: EventTarget | null, pointerId: number) => void;
80
+ /**
81
+ * Creates a standardized bridge between native DOM PointerEvents and Core abstract handlers.
82
+ * Handles event prevention, stop propagation, pointer capture, and multi-touch filtering.
83
+ *
84
+ * @param coreHandler - The logic core instance that implements IPointerHandler.
85
+ * @param getElement - A getter function to retrieve the DOM element for pointer capture.
86
+ * @returns An object containing mapped event handlers for Vue/React template binding.
87
+ */
88
+ declare function createPointerBridge(coreHandler: IPointerHandler & {
89
+ activePointerId?: number | null;
90
+ }, options?: {
91
+ /** Respond only to direct clicks (without responding to events bubbled up from child elements) */
92
+ requireDirectHit?: boolean;
93
+ }): {
94
+ /**
95
+ * Entry point for a pointer interaction.
96
+ * Establishes capture and initializes core logic.
97
+ */
98
+ onPointerDown(e: PointerEvent): void;
99
+ /**
100
+ * Continuous movement handling.
101
+ * Throttling should be handled within the core implementation.
102
+ */
103
+ onPointerMove(e: PointerEvent): void;
104
+ /**
105
+ * Successful interaction completion.
106
+ * Filters by pointerId to ensure only the capturing finger triggers release.
107
+ */
108
+ onPointerUp(e: PointerEvent): void;
109
+ /**
110
+ * System-level interaction cancellation (e.g., alert popups, browser gestures).
111
+ */
112
+ onPointerCancel(e: PointerEvent): void;
113
+ };
114
+
115
+ /**
116
+ * Generates a globally unique identifier (UID) for runtime entity management and DOM keys.
117
+ *
118
+ * The generated ID follows the format: `[prefix]-[timestamp_base36]-[random_string]`.
119
+ * This ensures that components generated at different times or across multiple sessions
120
+ * remain unique within the current page instance.
121
+ *
122
+ * @param prefix - A string prefix for the ID, typically the component type (e.g., 'btn', 'joy'). Defaults to 'omnipad'.
123
+ * @returns A unique string identifier.
124
+ *
125
+ * @example
126
+ * generateUID('button') // returns "button-m7x8k1p2-f4k2"
127
+ */
128
+ declare const generateUID: (prefix?: string) => string;
129
+ /**
130
+ * Checks if the provided ID is a reserved global identifier.
131
+ *
132
+ * In OmniPad, IDs starting with the `$` symbol are considered "Global IDs".
133
+ * These identifiers are treated as static references and are not transformed
134
+ * into dynamic UIDs during configuration parsing.
135
+ *
136
+ * @param id - The identifier string to check.
137
+ * @returns `true` if the ID starts with `$`, otherwise `false`.
138
+ *
139
+ * @example
140
+ * isGlobalID('$root-layer') // returns true
141
+ * isGlobalID('btn-up') // returns false
142
+ */
143
+ declare function isGlobalID(id: string): boolean;
144
+
145
+ /**
146
+ * Converts a LayoutBox configuration into a CSS style object suitable for Vue/React.
147
+ *
148
+ * This utility handles:
149
+ * 1. Unit normalization: Converts numeric values to 'px' strings while preserving unit strings (vh, %, etc.).
150
+ * 2. Positioning: Sets 'absolute' positioning by default.
151
+ * 3. Anchoring: Maps AnchorPoint values to CSS 'transform' translations to ensure
152
+ * the component's origin matches its defined coordinates.
153
+ *
154
+ * @param layout - The LayoutBox configuration object.
155
+ * @returns A CSS style record object.
156
+ *
157
+ * @example
158
+ * // returns { position: 'absolute', left: '50%', top: '50%', transform: 'translate(-50%, -50%)' }
159
+ * resolveLayoutStyle({ left: '50%', top: '50%', anchor: 'center' });
160
+ */
161
+ declare const resolveLayoutStyle: (layout: LayoutBox) => Record<string, string | number>;
162
+
163
+ /**
164
+ * Subtracts vector v2 from v1.
165
+ * @param v1 - The source vector.
166
+ * @param v2 - The vector to subtract.
167
+ */
168
+ declare const subVec: (v1: Vec2, v2: Vec2) => Vec2;
169
+ /**
170
+ * Adds vector v2 to v1.
171
+ */
172
+ declare const addVec: (v1: Vec2, v2: Vec2) => Vec2;
173
+ /**
174
+ * Scales a vector by a scalar value.
175
+ * Useful for mapping normalized vectors back to specific pixel magnitudes.
176
+ */
177
+ declare const scaleVec: (v: Vec2, s: number) => Vec2;
178
+ /**
179
+ * Clamps a numeric value between a minimum and maximum range.
180
+ */
181
+ declare const clamp: (val: number, min: number, max: number) => number;
182
+ /**
183
+ * Linearly interpolates between two values.
184
+ */
185
+ declare const lerp: (start: number, end: number, t: number) => number;
186
+ /**
187
+ * Rounds a number to a specific decimal precision.
188
+ * Solves floating-point precision issues in pixel calculations.
189
+ */
190
+ declare const roundTo: (val: number, precision?: number) => number;
191
+ /**
192
+ * Calculates the Euclidean distance between two points.
193
+ */
194
+ declare const getDistance: (p1: Vec2, p2: Vec2) => number;
195
+ /**
196
+ * Calculates the angle in radians from point p1 to p2.
197
+ * Range: -PI to PI.
198
+ */
199
+ declare const getAngle: (p1: Vec2, p2: Vec2) => number;
200
+ /**
201
+ * Converts radians to degrees.
202
+ */
203
+ declare const radToDeg: (rad: number) => number;
204
+ /**
205
+ * Converts degrees to radians.
206
+ */
207
+ declare const degToRad: (deg: number) => number;
208
+ /**
209
+ * Constrains a target point within a circular radius relative to an origin.
210
+ * Commonly used for joystick physical displacement limits.
211
+ */
212
+ declare const clampVector: (origin: Vec2, target: Vec2, radius: number) => Vec2;
213
+ /**
214
+ * Snaps a radian angle to the nearest of 8 directions (45-degree steps).
215
+ */
216
+ declare const lockTo8Directions: (rad: number) => number;
217
+ /**
218
+ * Snaps a radian angle to the nearest of 4 directions (90-degree steps).
219
+ */
220
+ declare const lockTo4Directions: (rad: number) => number;
221
+ /**
222
+ * Converts percentage (0-100) to pixel values (px).
223
+ */
224
+ declare const percentToPx: (percent: number, totalPx: number) => number;
225
+ /**
226
+ * Converts pixel values (px) to percentage (0-100).
227
+ */
228
+ declare const pxToPercent: (px: number, totalPx: number) => number;
229
+ /**
230
+ * Normalizes a vector to a length of 1.
231
+ * Returns {0, 0} if the vector magnitude is 0.
232
+ */
233
+ declare const normalizeVec: (v: Vec2) => Vec2;
234
+ /**
235
+ * Converts a radian angle to a unit vector.
236
+ */
237
+ declare const radToVec: (rad: number) => Vec2;
238
+ /**
239
+ * Linearly remaps a value from one range [inMin, inMax] to another [outMin, outMax].
240
+ */
241
+ declare const remap: (val: number, inMin: number, inMax: number, outMin: number, outMax: number) => number;
242
+ /**
243
+ * Performs a dirty check to see if two Vec2 points are different within an epsilon.
244
+ */
245
+ declare const isVec2Equal: (v1: Vec2, v2: Vec2, epsilon?: number) => boolean;
246
+ /**
247
+ * Core deadzone logic.
248
+ * Maps a value from [threshold, max] to a normalized scale [0, 1].
249
+ * @returns A scalar value between 0 and 1.
250
+ */
251
+ declare const getDeadzoneScalar: (magnitude: number, threshold: number, max: number) => number;
252
+ /**
253
+ * Applies a radial deadzone to a vector.
254
+ * Suitable for analog sticks to ensure a smooth transition from center.
255
+ * @param v - Input vector.
256
+ * @param radius - The total radius of the joystick base.
257
+ * @param deadzonePercent - Deadzone threshold (0.0 to 1.0).
258
+ */
259
+ declare const applyRadialDeadzone: (v: Vec2, radius: number, deadzonePercent: number) => Vec2;
260
+ /**
261
+ * Applies an axial deadzone to a vector.
262
+ * Independently processes X and Y axes. Useful for D-Pads or precision directional inputs.
263
+ * @param v - Input vector.
264
+ * @param threshold - The deadzone threshold value.
265
+ * @param max - Maximum value for the axis.
266
+ */
267
+ declare const applyAxialDeadzone: (v: Vec2, threshold: number, max: number) => Vec2;
268
+
269
+ /**
270
+ * Validates and normalizes raw JSON data into a standard GamepadProfile.
271
+ * Performs structural checks and injects default metadata.
272
+ *
273
+ * @param raw - The raw JSON object from disk or network.
274
+ * @returns A validated GamepadProfile object.
275
+ * @throws Error if the core structure is invalid.
276
+ */
277
+ declare function parseProfileJson(raw: any): GamepadProfile;
278
+ /**
279
+ * The resulting structure after parsing a GamepadProfile.
280
+ * Contains a map of root nodes and a runtime-ready gamepad mapping table.
281
+ */
282
+ interface ParsedProfileForest {
283
+ /** Root nodes indexed by their original Config ID. */
284
+ roots: Record<string, ConfigTreeNode>;
285
+ /**
286
+ * Processed gamepad mapping where all CIDs have been
287
+ * translated into unique runtime UIDs.
288
+ */
289
+ runtimeGamepadMappings: GamepadMappingConfig[];
290
+ }
291
+ /**
292
+ * Converts a flat GamepadProfile into a forest of ConfigTreeNodes for runtime rendering.
293
+ * Automatically identifies all items without a parentId as root nodes.
294
+ *
295
+ * @param profile - The normalized profile data.
296
+ * @returns A record map of root nodes, keyed by their original configuration ID.
297
+ */
298
+ declare function parseProfileTrees(profile: GamepadProfile): ParsedProfileForest;
299
+ /**
300
+ * Serializes the specified runtime entities into a flat GamepadProfile.
301
+ * If no rootUids are provided, exports all entities currently in the registry.
302
+ *
303
+ * @param meta - Metadata for the exported profile.
304
+ * @param rootUid - The Entity ID of the node to be treated as the root.
305
+ * @param runtimeGamepadMapping - The current mapping from GamepadManager (using UIDs).
306
+ * @returns A flat GamepadProfile ready for storage.
307
+ */
308
+ declare function exportProfile(meta: GamepadProfile['meta'], rootUids?: string[], runtimeGamepadMappings?: Readonly<GamepadMappingConfig[]>): GamepadProfile;
309
+
310
+ export { type ParsedProfileForest, addVec, applyAxialDeadzone, applyRadialDeadzone, clamp, clampVector, createPointerBridge, degToRad, dispatchKeyboardEvent, dispatchPointerEventAtPos, exportProfile, focusElement, generateUID, getAngle, getDeadzoneScalar, getDeepActiveElement, getDeepElement, getDistance, isGlobalID, isVec2Equal, lerp, lockTo4Directions, lockTo8Directions, normalizeVec, parseProfileJson, parseProfileTrees, percentToPx, pxToPercent, radToDeg, radToVec, reclaimFocusAtPos, remap, resolveLayoutStyle, roundTo, safeReleaseCapture, safeSetCapture, scaleVec, subVec, supportsContainerQueries };
@@ -0,0 +1 @@
1
+ import {b}from'../chunk-K6RXCH3Q.mjs';export{d as addVec,x as applyAxialDeadzone,w as applyRadialDeadzone,f as clamp,m as clampVector,l as degToRad,j as getAngle,v as getDeadzoneScalar,i as getDistance,u as isVec2Equal,g as lerp,o as lockTo4Directions,n as lockTo8Directions,r as normalizeVec,p as percentToPx,q as pxToPercent,k as radToDeg,s as radToVec,t as remap,h as roundTo,e as scaleVec,c as subVec}from'../chunk-K6RXCH3Q.mjs';var E=(t,o,n="omnipad-prevent")=>{let r=document.elementsFromPoint(t,o).find(i=>!i.classList.contains(n));if(!r)return null;for(;r&&r.shadowRoot;){let f=r.shadowRoot.elementsFromPoint(t,o).find(u=>!u.classList.contains(n));if(!f||f===r)break;r=f;}return r},y=()=>{let t=document.activeElement;for(;t&&t.shadowRoot&&t.shadowRoot.activeElement;)t=t.shadowRoot.activeElement;return t},S=t=>{y()!==t&&(t.hasAttribute("tabindex")||t.setAttribute("tabindex","-1"),t.focus());},Q=(t,o)=>{let n=new KeyboardEvent(t,{...o,which:o.keyCode,bubbles:true,cancelable:true,view:window});window.dispatchEvent(n);},_=(t,o,n,a)=>{let r=E(o,n);if(!r)return;let i={bubbles:true,cancelable:true,composed:true,clientX:o,clientY:n,view:window,...a};if(t.startsWith("pointer")){r.dispatchEvent(new PointerEvent(t,{isPrimary:true,pointerId:9999,pointerType:"mouse",...i}));let f=t.replace("pointer","mouse");r.dispatchEvent(new MouseEvent(f,i));}else r.dispatchEvent(new MouseEvent(t,i));},X=(t,o,n)=>{let a=E(t,o);if(!a)return;y()!==a&&(S(a),n());},l,Y=()=>(l!==void 0||(l=typeof window<"u"&&!!window.CSS?.supports?.("width: 1cqw")),l),C=(t,o)=>{if(t instanceof Element)try{t.setPointerCapture(o);}catch(n){import.meta.env?.DEV&&console.warn("[Omnipad-DOM] Failed to set pointer capture:",n);}},I=(t,o)=>{if(t instanceof Element&&t.hasPointerCapture(o))try{t.releasePointerCapture(o);}catch{}};function Z(t,o={}){return {onPointerDown(n){if(!n.isTrusted||o?.requireDirectHit&&n.target!==n.currentTarget||t.activePointerId!=null)return;n.cancelable&&n.preventDefault(),n.stopPropagation();let a=n.currentTarget;a&&C(a,n.pointerId),t.onPointerDown(n);},onPointerMove(n){n.isTrusted&&(t.activePointerId!=null&&t.activePointerId!==n.pointerId||(n.cancelable&&n.preventDefault(),t.onPointerMove(n)));},onPointerUp(n){if(!n.isTrusted||t.activePointerId!=null&&t.activePointerId!==n.pointerId)return;n.cancelable&&n.preventDefault();let a=n.currentTarget;a&&I(a,n.pointerId),t.onPointerUp(n);},onPointerCancel(n){if(!n.isTrusted||t.activePointerId!=null&&t.activePointerId!==n.pointerId)return;let a=n.currentTarget;a&&I(a,n.pointerId),t.onPointerCancel(n);}}}var v=(t="omnipad")=>{let o=Date.now().toString(36),n=Math.random().toString(36).substring(2,6);return `${t}-${o}-${n}`};function m(t){return t.startsWith("$")}var et=t=>{if(!t)return {};let o={};o.position="absolute",t.isSquare&&(o.aspectRatio="1/1"),["left","top","right","bottom","width","height"].forEach(r=>{let i=t[r];i!==void 0&&typeof i=="number"?o[r]=`${i}px`:i!==void 0&&typeof i=="string"&&(o[r]=i);}),t.zIndex!==void 0&&(o.zIndex=t.zIndex);let a={"top-left":"translate(0, 0)","top-center":"translate(-50%, 0)","top-right":"translate(-100%, 0)","center-left":"translate(0, -50%)",center:"translate(-50%, -50%)","center-right":"translate(-100%, -50%)","bottom-left":"translate(0, -100%)","bottom-center":"translate(-50%, -100%)","bottom-right":"translate(-100%, -100%)"};return t.anchor&&(o.transform=a[t.anchor]),o};function it(t){if(!t||typeof t!="object")throw new Error("[OmniPad-Validation] Profile must be a valid JSON object.");if(!Array.isArray(t.items))throw new Error('[OmniPad-Validation] "items" must be an array.');let o={name:t.meta?.name||"Untitled Profile",version:t.meta?.version||"1.0.0",author:t.meta?.author||"Unknown"},n=t.items.map((r,i)=>{if(!r.id||!r.type)throw new Error(`[OmniPad-Validation] Item at index ${i} is missing "id" or "type".`);return {id:String(r.id),type:String(r.type),parentId:r.parentId?String(r.parentId):void 0,config:r.config||{}}}),a=t.gamepadMappings;return {meta:o,items:n,gamepadMappings:a}}function at(t){let{items:o,gamepadMappings:n}=t,a=new Map,r=(e,s="node")=>m(e)?e:(a.has(e)||a.set(e,v(s)),a.get(e));o.forEach(e=>r(e.id,e.type));let i=[];n&&n.forEach(e=>{let s={};if(e.buttons){s.buttons={};for(let[c,d]of Object.entries(e.buttons))s.buttons[c]=r(d);}e.dpad&&(s.dpad=r(e.dpad)),e.leftStick&&(s.leftStick=r(e.leftStick)),e.rightStick&&(s.rightStick=r(e.rightStick)),i.push(s);});let f=new Map,u=[];o.forEach(e=>{e.parentId?(f.has(e.parentId)||f.set(e.parentId,[]),f.get(e.parentId).push(e)):u.push(e);});let g=(e,s)=>{if(s.has(e.id))throw new Error(`[Omnipad-Core] Circular dependency detected at node: ${e.id}`);s.add(e.id);let c={...e.config};c?.targetStageId&&(c.targetStageId=r(c.targetStageId)),c?.dynamicWidgetId&&(c.dynamicWidgetId=r(c.dynamicWidgetId));let h=(f.get(e.id)||[]).map(b=>g(b,new Set(s)));return {uid:r(e.id),type:e.type,config:c,children:h}},p={};return u.forEach(e=>{p[e.id]=g(e,new Set);}),{roots:p,runtimeGamepadMappings:i}}function st(t,o,n){let a=b.getInstance(),r=[];if(!o||o.length===0)r=a.getAllEntities();else {let e=new Set;o.forEach(s=>{a.getEntitiesByRoot(s).forEach(d=>e.add(d));}),r=Array.from(e);}let i=new Map,f=0,u=e=>m(e)?e:(i.has(e)||i.set(e,`node_${++f}`),i.get(e)),g=r.map(e=>{let s=e.getConfig(),c=e.uid,d={...s};d.targetStageId&&(d.targetStageId=u(d.targetStageId)),d.dynamicWidgetId&&(d.dynamicWidgetId=u(d.dynamicWidgetId));let{id:h,parentId:b,...w}=d;return {id:u(c),type:e.type,parentId:s.parentId?u(s.parentId):void 0,config:w}}),p=[];return n&&n.forEach(e=>{let s={};if(e.buttons){s.buttons={};for(let[c,d]of Object.entries(e.buttons))i.has(d)&&(s.buttons[c]=i.get(d));}e.dpad&&i.has(e.dpad)&&(s.dpad=i.get(e.dpad)),e.leftStick&&i.has(e.leftStick)&&(s.leftStick=i.get(e.leftStick)),e.rightStick&&i.has(e.rightStick)&&(s.rightStick=i.get(e.rightStick)),Object.keys(s).length>0?p.push(s):p.push({});}),{meta:t,items:g,gamepadMappings:Object.keys(p).length>0?p:void 0}}export{Z as createPointerBridge,Q as dispatchKeyboardEvent,_ as dispatchPointerEventAtPos,st as exportProfile,S as focusElement,v as generateUID,y as getDeepActiveElement,E as getDeepElement,m as isGlobalID,it as parseProfileJson,at as parseProfileTrees,X as reclaimFocusAtPos,et as resolveLayoutStyle,I as safeReleaseCapture,C as safeSetCapture,Y as supportsContainerQueries};