@debuffjp/input 0.15.0 → 0.16.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.
- package/README.md +7 -2
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js.map +1 -1
- package/dist/input.d.ts +19 -0
- package/dist/input.d.ts.map +1 -1
- package/dist/input.js +46 -11
- package/dist/input.js.map +1 -1
- package/dist/pointer.d.ts +58 -5
- package/dist/pointer.d.ts.map +1 -1
- package/dist/pointer.js +154 -21
- package/dist/pointer.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -25,14 +25,19 @@ Edges clear automatically after each simulation step, so a tap shorter than a fr
|
|
|
25
25
|
| Source | Names |
|
|
26
26
|
| --- | --- |
|
|
27
27
|
| Keyboard | [`KeyboardEvent.code`](https://developer.mozilla.org/docs/Web/API/KeyboardEvent/code): `Space`, `KeyZ`, `ArrowUp`, … |
|
|
28
|
-
| Pointer | `Pointer` (primary mouse button, touch or pen) |
|
|
28
|
+
| Pointer | `Pointer` (primary mouse button, touch or pen), `PointerRight`, `PointerMiddle` (right and middle mouse buttons) |
|
|
29
29
|
| Gamepad | `PadA` `PadB` `PadX` `PadY` `PadL1` `PadR1` `PadL2` `PadR2` `PadSelect` `PadStart` `PadL3` `PadR3` `PadUp` `PadDown` `PadLeft` `PadRight` |
|
|
30
30
|
| Left stick | `PadStickUp` `PadStickDown` `PadStickLeft` `PadStickRight` |
|
|
31
31
|
|
|
32
32
|
## API
|
|
33
33
|
|
|
34
34
|
- `input.down(action)`, `input.pressed(action)`, `input.released(action)`, `input.axis(neg, pos)`
|
|
35
|
+
- `input.rebind(action, keys)`: replace an action's bindings (a controls menu), keeping captured keys in step. `input.bindings` is Input's own copy of the map you passed, so change it with `rebind` rather than in place.
|
|
35
36
|
- `input.pointer`: `x`, `y` (logical), `down`, `pressed`, `released`, `touches`
|
|
37
|
+
- `input.pointer.kind`: `"mouse"`, `"touch"` or `"pen"`, whichever made the latest press
|
|
38
|
+
- `input.pointer.touchesStarted`, `touchesEnded`: contacts that started or ended this step (each with `id`, `x`, `y`, `kind`), so a game doesn't diff `touches` itself
|
|
39
|
+
- `input.pointer.right`, `input.pointer.middle`: `down`, `pressed`, `released` for the right and middle mouse buttons
|
|
40
|
+
- `input.pointer.wheel`, `wheelX`: wheel or trackpad scroll this step in CSS pixels (positive = down / right), reset every step. Pass `captureWheel: true` to stop the page scrolling under a game that zooms with the wheel.
|
|
36
41
|
- `input.keys`: `down(code)`, `pressed(code)`, `released(code)`
|
|
37
42
|
- `input.pads`: `stickX`, `stickY`, `connected`, `deadzone`
|
|
38
|
-
- Programmatic control for tests and on-screen buttons: `keys.press/release`, `pointer.press/move/release`
|
|
43
|
+
- Programmatic control for tests and on-screen buttons: `keys.press/release`, `pointer.press/move/release/scroll/pressButton/releaseButton`, and `pointer.touchStart(id, x, y)` / `touchMove` / `touchEnd` for multi-touch (the first contact also presses the primary pointer, as a real touch does)
|
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
export { Gamepads, PAD_BUTTONS, type PadButton, type PadState, type PadStick } from "./gamepad.js";
|
|
2
2
|
export { type Binding, type Bindings, Input, type InputHost, type InputOptions } from "./input.js";
|
|
3
3
|
export { Keyboard } from "./keyboard.js";
|
|
4
|
-
export { Pointer, type ToLogical, type TouchPoint } from "./pointer.js";
|
|
4
|
+
export { type ButtonState, Pointer, type PointerButton, type PointerKind, type ToLogical, type TouchPoint } from "./pointer.js";
|
|
5
5
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,WAAW,EAAE,KAAK,SAAS,EAAE,KAAK,QAAQ,EAAE,KAAK,QAAQ,EAAE,MAAM,cAAc,CAAC;AACnG,OAAO,EAAE,KAAK,OAAO,EAAE,KAAK,QAAQ,EAAE,KAAK,EAAE,KAAK,SAAS,EAAE,KAAK,YAAY,EAAE,MAAM,YAAY,CAAC;AACnG,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AACzC,OAAO,EAAE,OAAO,EAAE,KAAK,SAAS,EAAE,KAAK,UAAU,EAAE,MAAM,cAAc,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,WAAW,EAAE,KAAK,SAAS,EAAE,KAAK,QAAQ,EAAE,KAAK,QAAQ,EAAE,MAAM,cAAc,CAAC;AACnG,OAAO,EAAE,KAAK,OAAO,EAAE,KAAK,QAAQ,EAAE,KAAK,EAAE,KAAK,SAAS,EAAE,KAAK,YAAY,EAAE,MAAM,YAAY,CAAC;AACnG,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AACzC,OAAO,EAAE,KAAK,WAAW,EAAE,OAAO,EAAE,KAAK,aAAa,EAAE,KAAK,WAAW,EAAE,KAAK,SAAS,EAAE,KAAK,UAAU,EAAE,MAAM,cAAc,CAAC"}
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,WAAW,EAAgD,MAAM,cAAc,CAAC;AACnG,OAAO,EAA+B,KAAK,EAAqC,MAAM,YAAY,CAAC;AACnG,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AACzC,OAAO,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,WAAW,EAAgD,MAAM,cAAc,CAAC;AACnG,OAAO,EAA+B,KAAK,EAAqC,MAAM,YAAY,CAAC;AACnG,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AACzC,OAAO,EAAoB,OAAO,EAAyE,MAAM,cAAc,CAAC"}
|
package/dist/input.d.ts
CHANGED
|
@@ -5,6 +5,7 @@ import { Pointer, type ToLogical } from "./pointer.js";
|
|
|
5
5
|
* A binding is a source name:
|
|
6
6
|
* - a `KeyboardEvent.code`: `"Space"`, `"KeyZ"`, `"ArrowLeft"`
|
|
7
7
|
* - `"Pointer"`: primary mouse button / touch / pen
|
|
8
|
+
* - `"PointerRight"`, `"PointerMiddle"`: the right and middle mouse buttons
|
|
8
9
|
* - a gamepad button or stick direction: `"PadA"`, `"PadLeft"`, `"PadStickLeft"`
|
|
9
10
|
*/
|
|
10
11
|
export type Binding = string;
|
|
@@ -24,6 +25,8 @@ export interface InputOptions<A extends string> {
|
|
|
24
25
|
keyboardTarget?: Window | HTMLElement;
|
|
25
26
|
/** Block the browser default for bound keys (page scrolling in embeds). Default true. */
|
|
26
27
|
captureKeys?: boolean;
|
|
28
|
+
/** Block page scrolling while the wheel is over the canvas, for games that zoom with it. Default false. */
|
|
29
|
+
captureWheel?: boolean;
|
|
27
30
|
}
|
|
28
31
|
/**
|
|
29
32
|
* Action-based input across keyboard, pointer and gamepad.
|
|
@@ -42,8 +45,15 @@ export declare class Input<A extends string> {
|
|
|
42
45
|
readonly keys: Keyboard;
|
|
43
46
|
readonly pointer: Pointer;
|
|
44
47
|
readonly pads: Gamepads;
|
|
48
|
+
/**
|
|
49
|
+
* The current bindings: Input's own copy of the options' map, read on every call. Change them with
|
|
50
|
+
* `rebind()`, which keeps `keys.captured` in step.
|
|
51
|
+
*/
|
|
45
52
|
readonly bindings: Bindings<A>;
|
|
46
53
|
private readonly unhook;
|
|
54
|
+
private readonly captureKeys;
|
|
55
|
+
/** Keys in `keys.captured` because a binding uses them (not ones the game added itself). */
|
|
56
|
+
private readonly boundCaptured;
|
|
47
57
|
constructor(host: InputHost, options: InputOptions<A>);
|
|
48
58
|
/** Any binding for the action is held. */
|
|
49
59
|
down(action: A): boolean;
|
|
@@ -51,10 +61,19 @@ export declare class Input<A extends string> {
|
|
|
51
61
|
pressed(action: A): boolean;
|
|
52
62
|
/** The action ended this step. */
|
|
53
63
|
released(action: A): boolean;
|
|
64
|
+
/**
|
|
65
|
+
* Replace an action's bindings, e.g. from a controls menu: `input.rebind("jump", ["KeyK", "PadA"])`.
|
|
66
|
+
* Takes a copy of `keys`, and updates `keys.captured` so the new keys stop scrolling the page and the old
|
|
67
|
+
* ones scroll it again.
|
|
68
|
+
*/
|
|
69
|
+
rebind(action: A, keys: readonly Binding[]): void;
|
|
54
70
|
/** -1, 0 or 1 from two opposing actions, e.g. `axis("left", "right")`. */
|
|
55
71
|
axis(negative: A, positive: A): number;
|
|
56
72
|
dispose(): void;
|
|
57
73
|
private some;
|
|
74
|
+
private syncCaptured;
|
|
75
|
+
private isPointer;
|
|
76
|
+
private button;
|
|
58
77
|
private isPad;
|
|
59
78
|
/** Clear edges, then sample gamepads for the next step (the Gamepad API is poll-based). */
|
|
60
79
|
private endStep;
|
package/dist/input.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"input.d.ts","sourceRoot":"","sources":["../src/input.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,cAAc,CAAC;AACxC,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AACzC,OAAO,
|
|
1
|
+
{"version":3,"file":"input.d.ts","sourceRoot":"","sources":["../src/input.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,cAAc,CAAC;AACxC,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AACzC,OAAO,EAAoB,OAAO,EAAE,KAAK,SAAS,EAAE,MAAM,cAAc,CAAC;AAEzE;;;;;;GAMG;AACH,MAAM,MAAM,OAAO,GAAG,MAAM,CAAC;AAE7B,MAAM,MAAM,QAAQ,CAAC,CAAC,SAAS,MAAM,IAAI,MAAM,CAAC,CAAC,EAAE,SAAS,OAAO,EAAE,CAAC,CAAC;AAEvE,6CAA6C;AAC7C,MAAM,WAAW,SAAS;IACxB,MAAM,EAAE,WAAW,CAAC;IACpB,SAAS,EAAE,SAAS,CAAC;IACrB,KAAK,EAAE;QAAE,WAAW,CAAC,EAAE,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,IAAI,GAAG,MAAM,IAAI,CAAA;KAAE,CAAC;CAC9D;AAED,MAAM,WAAW,YAAY,CAAC,CAAC,SAAS,MAAM;IAC5C,uDAAuD;IACvD,QAAQ,EAAE,QAAQ,CAAC,CAAC,CAAC,CAAC;IACtB,2DAA2D;IAC3D,cAAc,CAAC,EAAE,MAAM,GAAG,WAAW,CAAC;IACtC,yFAAyF;IACzF,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,2GAA2G;IAC3G,YAAY,CAAC,EAAE,OAAO,CAAC;CACxB;AAED;;;;;;;;;;;;GAYG;AACH,qBAAa,KAAK,CAAC,CAAC,SAAS,MAAM;IACjC,QAAQ,CAAC,IAAI,EAAE,QAAQ,CAAC;IACxB,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC;IAC1B,QAAQ,CAAC,IAAI,WAAkB;IAC/B;;;OAGG;IACH,QAAQ,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC,CAAC,CAAC;IAC/B,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAa;IACpC,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAU;IACtC,4FAA4F;IAC5F,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAqB;IAEnD,YAAY,IAAI,EAAE,SAAS,EAAE,OAAO,EAAE,YAAY,CAAC,CAAC,CAAC,EASpD;IAED,0CAA0C;IAC1C,IAAI,CAAC,MAAM,EAAE,CAAC,GAAG,OAAO,CAEvB;IAED,oCAAoC;IACpC,OAAO,CAAC,MAAM,EAAE,CAAC,GAAG,OAAO,CAI1B;IAED,kCAAkC;IAClC,QAAQ,CAAC,MAAM,EAAE,CAAC,GAAG,OAAO,CAI3B;IAED;;;;OAIG;IACH,MAAM,CAAC,MAAM,EAAE,CAAC,EAAE,IAAI,EAAE,SAAS,OAAO,EAAE,GAAG,IAAI,CAKhD;IAED,0EAA0E;IAC1E,IAAI,CAAC,QAAQ,EAAE,CAAC,EAAE,QAAQ,EAAE,CAAC,GAAG,MAAM,CAErC;IAED,OAAO,IAAI,IAAI,CAId;IAED,OAAO,CAAC,IAAI;IAMZ,OAAO,CAAC,YAAY;IAapB,OAAO,CAAC,SAAS;IAIjB,OAAO,CAAC,MAAM;IAId,OAAO,CAAC,KAAK;IAIb,2FAA2F;IAC3F,OAAO,CAAC,OAAO;CAKhB"}
|
package/dist/input.js
CHANGED
|
@@ -18,33 +18,47 @@ export class Input {
|
|
|
18
18
|
keys;
|
|
19
19
|
pointer;
|
|
20
20
|
pads = new Gamepads();
|
|
21
|
+
/**
|
|
22
|
+
* The current bindings: Input's own copy of the options' map, read on every call. Change them with
|
|
23
|
+
* `rebind()`, which keeps `keys.captured` in step.
|
|
24
|
+
*/
|
|
21
25
|
bindings;
|
|
22
26
|
unhook;
|
|
27
|
+
captureKeys;
|
|
28
|
+
/** Keys in `keys.captured` because a binding uses them (not ones the game added itself). */
|
|
29
|
+
boundCaptured = new Set();
|
|
23
30
|
constructor(host, options) {
|
|
24
|
-
this.bindings = options.bindings;
|
|
31
|
+
this.bindings = { ...options.bindings };
|
|
25
32
|
this.keys = new Keyboard(options.keyboardTarget ?? window);
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
for (const b of list)
|
|
29
|
-
if (b !== "Pointer" && !b.startsWith("Pad"))
|
|
30
|
-
this.keys.captured.add(b);
|
|
31
|
-
}
|
|
32
|
-
}
|
|
33
|
+
this.captureKeys = options.captureKeys ?? true;
|
|
34
|
+
this.syncCaptured();
|
|
33
35
|
// Call through the host so a class method keeps its `this`.
|
|
34
36
|
this.pointer = new Pointer(host.canvas, (x, y) => host.toLogical(x, y));
|
|
37
|
+
this.pointer.captureWheel = options.captureWheel ?? false;
|
|
35
38
|
this.unhook = host.hooks.afterUpdate(() => this.endStep());
|
|
36
39
|
}
|
|
37
40
|
/** Any binding for the action is held. */
|
|
38
41
|
down(action) {
|
|
39
|
-
return this.some(action, (b) => (b
|
|
42
|
+
return this.some(action, (b) => (this.isPointer(b) ? this.button(b).down : this.isPad(b) ? this.pads.down(b) : this.keys.down(b)));
|
|
40
43
|
}
|
|
41
44
|
/** The action started this step. */
|
|
42
45
|
pressed(action) {
|
|
43
|
-
return this.some(action, (b) => (b
|
|
46
|
+
return this.some(action, (b) => this.isPointer(b) ? this.button(b).pressed : this.isPad(b) ? this.pads.pressed(b) : this.keys.pressed(b));
|
|
44
47
|
}
|
|
45
48
|
/** The action ended this step. */
|
|
46
49
|
released(action) {
|
|
47
|
-
return this.some(action, (b) => b
|
|
50
|
+
return this.some(action, (b) => this.isPointer(b) ? this.button(b).released : this.isPad(b) ? this.pads.released(b) : this.keys.released(b));
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* Replace an action's bindings, e.g. from a controls menu: `input.rebind("jump", ["KeyK", "PadA"])`.
|
|
54
|
+
* Takes a copy of `keys`, and updates `keys.captured` so the new keys stop scrolling the page and the old
|
|
55
|
+
* ones scroll it again.
|
|
56
|
+
*/
|
|
57
|
+
rebind(action, keys) {
|
|
58
|
+
if (!Object.hasOwn(this.bindings, action))
|
|
59
|
+
throw new Error(`Unknown input action "${action}". Known: ${Object.keys(this.bindings).join(", ")}`);
|
|
60
|
+
this.bindings[action] = [...keys];
|
|
61
|
+
this.syncCaptured();
|
|
48
62
|
}
|
|
49
63
|
/** -1, 0 or 1 from two opposing actions, e.g. `axis("left", "right")`. */
|
|
50
64
|
axis(negative, positive) {
|
|
@@ -61,6 +75,27 @@ export class Input {
|
|
|
61
75
|
throw new Error(`Unknown input action "${action}". Known: ${Object.keys(this.bindings).join(", ")}`);
|
|
62
76
|
return list.some(test);
|
|
63
77
|
}
|
|
78
|
+
syncCaptured() {
|
|
79
|
+
if (!this.captureKeys)
|
|
80
|
+
return;
|
|
81
|
+
for (const code of this.boundCaptured)
|
|
82
|
+
this.keys.captured.delete(code);
|
|
83
|
+
this.boundCaptured.clear();
|
|
84
|
+
for (const list of Object.values(this.bindings)) {
|
|
85
|
+
for (const b of list) {
|
|
86
|
+
if (this.isPointer(b) || this.isPad(b) || this.keys.captured.has(b))
|
|
87
|
+
continue;
|
|
88
|
+
this.keys.captured.add(b);
|
|
89
|
+
this.boundCaptured.add(b);
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
isPointer(b) {
|
|
94
|
+
return b === "Pointer" || b === "PointerRight" || b === "PointerMiddle";
|
|
95
|
+
}
|
|
96
|
+
button(b) {
|
|
97
|
+
return b === "PointerRight" ? this.pointer.right : b === "PointerMiddle" ? this.pointer.middle : this.pointer;
|
|
98
|
+
}
|
|
64
99
|
isPad(b) {
|
|
65
100
|
return b.startsWith("Pad");
|
|
66
101
|
}
|
package/dist/input.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"input.js","sourceRoot":"","sources":["../src/input.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,cAAc,CAAC;AACxC,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AACzC,OAAO,
|
|
1
|
+
{"version":3,"file":"input.js","sourceRoot":"","sources":["../src/input.ts"],"names":[],"mappings":"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"}
|
package/dist/pointer.d.ts
CHANGED
|
@@ -3,16 +3,29 @@ export type ToLogical = (clientX: number, clientY: number) => {
|
|
|
3
3
|
x: number;
|
|
4
4
|
y: number;
|
|
5
5
|
};
|
|
6
|
+
/** What made a pointer press: `PointerEvent.pointerType`, with anything unknown counted as a mouse. */
|
|
7
|
+
export type PointerKind = "mouse" | "touch" | "pen";
|
|
6
8
|
export interface TouchPoint {
|
|
7
9
|
readonly id: number;
|
|
8
10
|
x: number;
|
|
9
11
|
y: number;
|
|
12
|
+
/** Mouse, finger or pen. A held mouse button is a contact too. */
|
|
13
|
+
readonly kind: PointerKind;
|
|
14
|
+
}
|
|
15
|
+
/** A mouse button other than the main one. */
|
|
16
|
+
export type PointerButton = "right" | "middle";
|
|
17
|
+
/** Held state and this step's edges for one button, like the primary pointer's. */
|
|
18
|
+
export interface ButtonState {
|
|
19
|
+
down: boolean;
|
|
20
|
+
pressed: boolean;
|
|
21
|
+
released: boolean;
|
|
10
22
|
}
|
|
11
23
|
/**
|
|
12
24
|
* Unified mouse, touch and pen input via Pointer Events, in logical game coordinates.
|
|
13
25
|
*
|
|
14
26
|
* `x`, `y`, `down`, `pressed` and `released` describe the primary pointer. Edges are
|
|
15
|
-
* latched until `endStep()`. All active contacts are in `touches` for multi-touch.
|
|
27
|
+
* latched until `endStep()`. All active contacts are in `touches` for multi-touch. The right and
|
|
28
|
+
* middle mouse buttons are in `right` and `middle`.
|
|
16
29
|
*/
|
|
17
30
|
export declare class Pointer {
|
|
18
31
|
x: number;
|
|
@@ -20,24 +33,64 @@ export declare class Pointer {
|
|
|
20
33
|
down: boolean;
|
|
21
34
|
pressed: boolean;
|
|
22
35
|
released: boolean;
|
|
36
|
+
/** What made the latest primary press: `"mouse"`, `"touch"` or `"pen"`. `"mouse"` until the first press. */
|
|
37
|
+
kind: PointerKind;
|
|
23
38
|
/** Active contacts keyed by pointerId. */
|
|
24
39
|
readonly touches: Map<number, TouchPoint>;
|
|
40
|
+
/** Contacts that started this step, cleared by `endStep()`. They are in `touches` too unless they also ended. */
|
|
41
|
+
readonly touchesStarted: TouchPoint[];
|
|
42
|
+
/** Contacts that ended this step, at their last position, cleared by `endStep()`. */
|
|
43
|
+
readonly touchesEnded: TouchPoint[];
|
|
44
|
+
/**
|
|
45
|
+
* Vertical wheel (or trackpad) scroll over the element this step, in CSS pixels: positive scrolls down.
|
|
46
|
+
* Summed across events and reset by `endStep()`.
|
|
47
|
+
*/
|
|
48
|
+
wheel: number;
|
|
49
|
+
/** Horizontal scroll this step, like `wheel`: positive scrolls right. */
|
|
50
|
+
wheelX: number;
|
|
51
|
+
/** The right mouse button (or a pen's barrel button reported as one). */
|
|
52
|
+
readonly right: ButtonState;
|
|
53
|
+
/** The middle mouse button (wheel click). */
|
|
54
|
+
readonly middle: ButtonState;
|
|
55
|
+
/** Block the page scrolling while the wheel is over the element (for wheel zoom in embeds). Default false. */
|
|
56
|
+
captureWheel: boolean;
|
|
25
57
|
private readonly element;
|
|
58
|
+
/** The contact the primary pointer follows, while it's held through `touchStart`. */
|
|
59
|
+
private primaryId;
|
|
26
60
|
private readonly toLogical;
|
|
27
61
|
private readonly onDown;
|
|
28
62
|
private readonly onMove;
|
|
29
63
|
private readonly onContextMenu;
|
|
64
|
+
private readonly onWheel;
|
|
30
65
|
private readonly onUp;
|
|
31
66
|
constructor(element: HTMLElement, toLogical: ToLogical);
|
|
32
|
-
/** Simulate pressing the primary pointer at logical coordinates. */
|
|
33
|
-
press(x: number, y: number): void;
|
|
67
|
+
/** Simulate pressing the primary pointer at logical coordinates, by a mouse unless `kind` says otherwise. */
|
|
68
|
+
press(x: number, y: number, kind?: PointerKind): void;
|
|
34
69
|
/** Simulate moving the primary pointer. */
|
|
35
70
|
move(x: number, y: number): void;
|
|
36
71
|
/** Simulate releasing the primary pointer. */
|
|
37
72
|
release(): void;
|
|
38
|
-
/**
|
|
73
|
+
/**
|
|
74
|
+
* Simulate a contact starting (a finger by default). The first contact while the primary pointer is up
|
|
75
|
+
* also presses it, as real touches do.
|
|
76
|
+
*/
|
|
77
|
+
touchStart(id: number, x: number, y: number, kind?: PointerKind): void;
|
|
78
|
+
/** Simulate a contact moving. The primary pointer follows its contact. */
|
|
79
|
+
touchMove(id: number, x: number, y: number): void;
|
|
80
|
+
/** Simulate a contact ending. Ending the primary pointer's contact releases it. */
|
|
81
|
+
touchEnd(id: number): void;
|
|
82
|
+
/** Simulate pressing the right or middle button. */
|
|
83
|
+
pressButton(button: PointerButton): void;
|
|
84
|
+
/** Simulate releasing the right or middle button. */
|
|
85
|
+
releaseButton(button: PointerButton): void;
|
|
86
|
+
/** Simulate scrolling the wheel by `dy` (and `dx`) CSS pixels. */
|
|
87
|
+
scroll(dy: number, dx?: number): void;
|
|
88
|
+
/** Clear edges and the wheel. Call once after each simulation step. */
|
|
39
89
|
endStep(): void;
|
|
40
90
|
dispose(): void;
|
|
41
|
-
private
|
|
91
|
+
private syncButtons;
|
|
92
|
+
/** Keep receiving this pointer's moves and release outside the element, where the browser allows it. */
|
|
93
|
+
private capture;
|
|
94
|
+
private addContact;
|
|
42
95
|
}
|
|
43
96
|
//# sourceMappingURL=pointer.d.ts.map
|
package/dist/pointer.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"pointer.d.ts","sourceRoot":"","sources":["../src/pointer.ts"],"names":[],"mappings":"AAAA,gGAAgG;AAChG,MAAM,MAAM,SAAS,GAAG,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,KAAK;IAAE,CAAC,EAAE,MAAM,CAAC;IAAC,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC;AAEvF,MAAM,WAAW,UAAU;IACzB,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,CAAC,EAAE,MAAM,CAAC;IACV,CAAC,EAAE,MAAM,CAAC;
|
|
1
|
+
{"version":3,"file":"pointer.d.ts","sourceRoot":"","sources":["../src/pointer.ts"],"names":[],"mappings":"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"}
|
package/dist/pointer.js
CHANGED
|
@@ -1,8 +1,11 @@
|
|
|
1
|
+
// `PointerEvent.buttons` bits.
|
|
2
|
+
const BUTTON_BITS = { right: 2, middle: 4 };
|
|
1
3
|
/**
|
|
2
4
|
* Unified mouse, touch and pen input via Pointer Events, in logical game coordinates.
|
|
3
5
|
*
|
|
4
6
|
* `x`, `y`, `down`, `pressed` and `released` describe the primary pointer. Edges are
|
|
5
|
-
* latched until `endStep()`. All active contacts are in `touches` for multi-touch.
|
|
7
|
+
* latched until `endStep()`. All active contacts are in `touches` for multi-touch. The right and
|
|
8
|
+
* middle mouse buttons are in `right` and `middle`.
|
|
6
9
|
*/
|
|
7
10
|
export class Pointer {
|
|
8
11
|
x = 0;
|
|
@@ -10,28 +13,77 @@ export class Pointer {
|
|
|
10
13
|
down = false;
|
|
11
14
|
pressed = false;
|
|
12
15
|
released = false;
|
|
16
|
+
/** What made the latest primary press: `"mouse"`, `"touch"` or `"pen"`. `"mouse"` until the first press. */
|
|
17
|
+
kind = "mouse";
|
|
13
18
|
/** Active contacts keyed by pointerId. */
|
|
14
19
|
touches = new Map();
|
|
20
|
+
/** Contacts that started this step, cleared by `endStep()`. They are in `touches` too unless they also ended. */
|
|
21
|
+
touchesStarted = [];
|
|
22
|
+
/** Contacts that ended this step, at their last position, cleared by `endStep()`. */
|
|
23
|
+
touchesEnded = [];
|
|
24
|
+
/**
|
|
25
|
+
* Vertical wheel (or trackpad) scroll over the element this step, in CSS pixels: positive scrolls down.
|
|
26
|
+
* Summed across events and reset by `endStep()`.
|
|
27
|
+
*/
|
|
28
|
+
wheel = 0;
|
|
29
|
+
/** Horizontal scroll this step, like `wheel`: positive scrolls right. */
|
|
30
|
+
wheelX = 0;
|
|
31
|
+
/** The right mouse button (or a pen's barrel button reported as one). */
|
|
32
|
+
right = { down: false, pressed: false, released: false };
|
|
33
|
+
/** The middle mouse button (wheel click). */
|
|
34
|
+
middle = { down: false, pressed: false, released: false };
|
|
35
|
+
/** Block the page scrolling while the wheel is over the element (for wheel zoom in embeds). Default false. */
|
|
36
|
+
captureWheel = false;
|
|
15
37
|
element;
|
|
38
|
+
/** The contact the primary pointer follows, while it's held through `touchStart`. */
|
|
39
|
+
primaryId;
|
|
16
40
|
toLogical;
|
|
17
41
|
onDown = (e) => {
|
|
18
|
-
//
|
|
19
|
-
|
|
42
|
+
// preventDefault below stops a click focusing the window, so inside an iframe (game portals) keys
|
|
43
|
+
// would go nowhere until the player clicked outside the game. Take focus ourselves.
|
|
44
|
+
if (!document.hasFocus())
|
|
45
|
+
window.focus();
|
|
46
|
+
if (e.pointerType === "mouse")
|
|
47
|
+
this.syncButtons(e.buttons);
|
|
48
|
+
// Only the main mouse button is the primary pointer; right and middle are `right` and `middle`.
|
|
49
|
+
if (e.pointerType === "mouse" && e.button) {
|
|
50
|
+
this.capture(e.pointerId);
|
|
20
51
|
return;
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
52
|
+
}
|
|
53
|
+
this.capture(e.pointerId);
|
|
54
|
+
const { x, y } = this.toLogical(e.clientX, e.clientY);
|
|
55
|
+
this.touchStart(e.pointerId, x, y, kindOf(e));
|
|
25
56
|
e.preventDefault();
|
|
26
57
|
};
|
|
27
58
|
onMove = (e) => {
|
|
28
|
-
|
|
29
|
-
|
|
59
|
+
// A second button pressed or let go while another is held arrives as a move with `button` set.
|
|
60
|
+
if (e.pointerType === "mouse" && e.button > 0)
|
|
61
|
+
this.syncButtons(e.buttons);
|
|
62
|
+
if (!this.touches.has(e.pointerId) && !e.isPrimary)
|
|
63
|
+
return;
|
|
64
|
+
const { x, y } = this.toLogical(e.clientX, e.clientY);
|
|
65
|
+
if (this.touches.has(e.pointerId))
|
|
66
|
+
this.touchMove(e.pointerId, x, y);
|
|
67
|
+
// A drag that started outside the element counts as a contact, but not as a press.
|
|
68
|
+
else if (e.buttons)
|
|
69
|
+
this.addContact(e.pointerId, x, y, kindOf(e));
|
|
70
|
+
// Hover: the primary pointer follows the mouse while no button is down.
|
|
71
|
+
if (e.isPrimary && e.pointerId !== this.primaryId)
|
|
72
|
+
this.move(x, y);
|
|
30
73
|
};
|
|
31
74
|
// Right-click shouldn't open the browser menu over a game.
|
|
32
75
|
onContextMenu = (e) => e.preventDefault();
|
|
76
|
+
onWheel = (e) => {
|
|
77
|
+
if (this.captureWheel)
|
|
78
|
+
e.preventDefault();
|
|
79
|
+
// Lines and pages (Firefox, some mice) become pixels, so games see one unit everywhere.
|
|
80
|
+
const unit = e.deltaMode === 1 ? 16 : e.deltaMode === 2 ? this.element.clientHeight || 800 : 1;
|
|
81
|
+
this.scroll(e.deltaY * unit, e.deltaX * unit);
|
|
82
|
+
};
|
|
33
83
|
onUp = (e) => {
|
|
34
|
-
|
|
84
|
+
if (e.pointerType === "mouse")
|
|
85
|
+
this.syncButtons(e.buttons);
|
|
86
|
+
this.touchEnd(e.pointerId);
|
|
35
87
|
if (e.isPrimary)
|
|
36
88
|
this.release();
|
|
37
89
|
};
|
|
@@ -44,15 +96,18 @@ export class Pointer {
|
|
|
44
96
|
element.addEventListener("pointerup", this.onUp);
|
|
45
97
|
element.addEventListener("pointercancel", this.onUp);
|
|
46
98
|
element.addEventListener("contextmenu", this.onContextMenu);
|
|
99
|
+
// Not passive, so `captureWheel` can stop the page scrolling.
|
|
100
|
+
element.addEventListener("wheel", this.onWheel, { passive: false });
|
|
47
101
|
}
|
|
48
|
-
/** Simulate pressing the primary pointer at logical coordinates. */
|
|
49
|
-
press(x, y) {
|
|
102
|
+
/** Simulate pressing the primary pointer at logical coordinates, by a mouse unless `kind` says otherwise. */
|
|
103
|
+
press(x, y, kind = "mouse") {
|
|
50
104
|
this.x = x;
|
|
51
105
|
this.y = y;
|
|
52
106
|
if (this.down)
|
|
53
107
|
return;
|
|
54
108
|
this.down = true;
|
|
55
109
|
this.pressed = true;
|
|
110
|
+
this.kind = kind;
|
|
56
111
|
}
|
|
57
112
|
/** Simulate moving the primary pointer. */
|
|
58
113
|
move(x, y) {
|
|
@@ -61,15 +116,78 @@ export class Pointer {
|
|
|
61
116
|
}
|
|
62
117
|
/** Simulate releasing the primary pointer. */
|
|
63
118
|
release() {
|
|
119
|
+
this.primaryId = undefined;
|
|
64
120
|
if (!this.down)
|
|
65
121
|
return;
|
|
66
122
|
this.down = false;
|
|
67
123
|
this.released = true;
|
|
68
124
|
}
|
|
69
|
-
/**
|
|
125
|
+
/**
|
|
126
|
+
* Simulate a contact starting (a finger by default). The first contact while the primary pointer is up
|
|
127
|
+
* also presses it, as real touches do.
|
|
128
|
+
*/
|
|
129
|
+
touchStart(id, x, y, kind = "touch") {
|
|
130
|
+
if (this.touches.has(id)) {
|
|
131
|
+
this.touchMove(id, x, y);
|
|
132
|
+
return;
|
|
133
|
+
}
|
|
134
|
+
this.addContact(id, x, y, kind);
|
|
135
|
+
if (this.down)
|
|
136
|
+
return;
|
|
137
|
+
this.press(x, y, kind);
|
|
138
|
+
this.primaryId = id;
|
|
139
|
+
}
|
|
140
|
+
/** Simulate a contact moving. The primary pointer follows its contact. */
|
|
141
|
+
touchMove(id, x, y) {
|
|
142
|
+
const p = this.touches.get(id);
|
|
143
|
+
if (!p)
|
|
144
|
+
return;
|
|
145
|
+
p.x = x;
|
|
146
|
+
p.y = y;
|
|
147
|
+
if (id === this.primaryId)
|
|
148
|
+
this.move(x, y);
|
|
149
|
+
}
|
|
150
|
+
/** Simulate a contact ending. Ending the primary pointer's contact releases it. */
|
|
151
|
+
touchEnd(id) {
|
|
152
|
+
const p = this.touches.get(id);
|
|
153
|
+
if (!p)
|
|
154
|
+
return;
|
|
155
|
+
this.touches.delete(id);
|
|
156
|
+
this.touchesEnded.push(p);
|
|
157
|
+
if (id === this.primaryId)
|
|
158
|
+
this.release();
|
|
159
|
+
}
|
|
160
|
+
/** Simulate pressing the right or middle button. */
|
|
161
|
+
pressButton(button) {
|
|
162
|
+
const b = this[button];
|
|
163
|
+
if (b.down)
|
|
164
|
+
return;
|
|
165
|
+
b.down = true;
|
|
166
|
+
b.pressed = true;
|
|
167
|
+
}
|
|
168
|
+
/** Simulate releasing the right or middle button. */
|
|
169
|
+
releaseButton(button) {
|
|
170
|
+
const b = this[button];
|
|
171
|
+
if (!b.down)
|
|
172
|
+
return;
|
|
173
|
+
b.down = false;
|
|
174
|
+
b.released = true;
|
|
175
|
+
}
|
|
176
|
+
/** Simulate scrolling the wheel by `dy` (and `dx`) CSS pixels. */
|
|
177
|
+
scroll(dy, dx = 0) {
|
|
178
|
+
this.wheel += dy;
|
|
179
|
+
this.wheelX += dx;
|
|
180
|
+
}
|
|
181
|
+
/** Clear edges and the wheel. Call once after each simulation step. */
|
|
70
182
|
endStep() {
|
|
71
183
|
this.pressed = false;
|
|
72
184
|
this.released = false;
|
|
185
|
+
this.wheel = 0;
|
|
186
|
+
this.wheelX = 0;
|
|
187
|
+
for (const b of [this.right, this.middle])
|
|
188
|
+
b.pressed = b.released = false;
|
|
189
|
+
this.touchesStarted.length = 0;
|
|
190
|
+
this.touchesEnded.length = 0;
|
|
73
191
|
}
|
|
74
192
|
dispose() {
|
|
75
193
|
this.element.removeEventListener("pointerdown", this.onDown);
|
|
@@ -77,15 +195,30 @@ export class Pointer {
|
|
|
77
195
|
this.element.removeEventListener("pointerup", this.onUp);
|
|
78
196
|
this.element.removeEventListener("pointercancel", this.onUp);
|
|
79
197
|
this.element.removeEventListener("contextmenu", this.onContextMenu);
|
|
198
|
+
this.element.removeEventListener("wheel", this.onWheel);
|
|
80
199
|
}
|
|
81
|
-
|
|
82
|
-
const
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
200
|
+
syncButtons(buttons) {
|
|
201
|
+
for (const button of ["right", "middle"]) {
|
|
202
|
+
if (buttons & BUTTON_BITS[button])
|
|
203
|
+
this.pressButton(button);
|
|
204
|
+
else
|
|
205
|
+
this.releaseButton(button);
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
/** Keep receiving this pointer's moves and release outside the element, where the browser allows it. */
|
|
209
|
+
capture(id) {
|
|
210
|
+
try {
|
|
211
|
+
this.element.setPointerCapture?.(id);
|
|
212
|
+
}
|
|
213
|
+
catch {
|
|
214
|
+
// Synthetic events and unknown pointer ids throw NotFoundError; the press still counts.
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
addContact(id, x, y, kind) {
|
|
218
|
+
const p = { id, x, y, kind };
|
|
219
|
+
this.touches.set(id, p);
|
|
220
|
+
this.touchesStarted.push(p);
|
|
89
221
|
}
|
|
90
222
|
}
|
|
223
|
+
const kindOf = (e) => (e.pointerType === "touch" || e.pointerType === "pen" ? e.pointerType : "mouse");
|
|
91
224
|
//# sourceMappingURL=pointer.js.map
|
package/dist/pointer.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"pointer.js","sourceRoot":"","sources":["../src/pointer.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"pointer.js","sourceRoot":"","sources":["../src/pointer.ts"],"names":[],"mappings":"AAwBA,+BAA+B;AAC/B,MAAM,WAAW,GAAkC,EAAE,KAAK,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,CAAC;AAE3E;;;;;;GAMG;AACH,MAAM,OAAO,OAAO;IAClB,CAAC,GAAG,CAAC,CAAC;IACN,CAAC,GAAG,CAAC,CAAC;IACN,IAAI,GAAG,KAAK,CAAC;IACb,OAAO,GAAG,KAAK,CAAC;IAChB,QAAQ,GAAG,KAAK,CAAC;IACjB,4GAA4G;IAC5G,IAAI,GAAgB,OAAO,CAAC;IAC5B,0CAA0C;IACjC,OAAO,GAAG,IAAI,GAAG,EAAsB,CAAC;IACjD,iHAAiH;IACxG,cAAc,GAAiB,EAAE,CAAC;IAC3C,qFAAqF;IAC5E,YAAY,GAAiB,EAAE,CAAC;IACzC;;;OAGG;IACH,KAAK,GAAG,CAAC,CAAC;IACV,yEAAyE;IACzE,MAAM,GAAG,CAAC,CAAC;IACX,yEAAyE;IAChE,KAAK,GAAgB,EAAE,IAAI,EAAE,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE,QAAQ,EAAE,KAAK,EAAE,CAAC;IAC/E,6CAA6C;IACpC,MAAM,GAAgB,EAAE,IAAI,EAAE,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE,QAAQ,EAAE,KAAK,EAAE,CAAC;IAChF,8GAA8G;IAC9G,YAAY,GAAG,KAAK,CAAC;IAEJ,OAAO,CAAc;IACtC,qFAAqF;IAC7E,SAAS,CAAqB;IACrB,SAAS,CAAY;IAErB,MAAM,GAAG,CAAC,CAAe,EAAE,EAAE;QAC5C,kGAAkG;QAClG,oFAAoF;QACpF,IAAI,CAAC,QAAQ,CAAC,QAAQ,EAAE;YAAE,MAAM,CAAC,KAAK,EAAE,CAAC;QACzC,IAAI,CAAC,CAAC,WAAW,KAAK,OAAO;YAAE,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC;QAC3D,gGAAgG;QAChG,IAAI,CAAC,CAAC,WAAW,KAAK,OAAO,IAAI,CAAC,CAAC,MAAM,EAAE,CAAC;YAC1C,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC;YAC1B,OAAO;QACT,CAAC;QACD,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC;QAC1B,MAAM,EAAE,CAAC,EAAE,CAAC,EAAE,GAAG,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,OAAO,CAAC,CAAC;QACtD,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,EAAE,CAAC,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC;QAC9C,CAAC,CAAC,cAAc,EAAE,CAAC;IACrB,CAAC,CAAC;IACe,MAAM,GAAG,CAAC,CAAe,EAAE,EAAE;QAC5C,+FAA+F;QAC/F,IAAI,CAAC,CAAC,WAAW,KAAK,OAAO,IAAI,CAAC,CAAC,MAAM,GAAG,CAAC;YAAE,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC;QAC3E,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC,SAAS;YAAE,OAAO;QAC3D,MAAM,EAAE,CAAC,EAAE,CAAC,EAAE,GAAG,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,OAAO,CAAC,CAAC;QACtD,IAAI,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,SAAS,CAAC;YAAE,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC;QACrE,mFAAmF;aAC9E,IAAI,CAAC,CAAC,OAAO;YAAE,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,EAAE,CAAC,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC;QAClE,wEAAwE;QACxE,IAAI,CAAC,CAAC,SAAS,IAAI,CAAC,CAAC,SAAS,KAAK,IAAI,CAAC,SAAS;YAAE,IAAI,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;IACrE,CAAC,CAAC;IACF,2DAA2D;IAC1C,aAAa,GAAG,CAAC,CAAQ,EAAE,EAAE,CAAC,CAAC,CAAC,cAAc,EAAE,CAAC;IACjD,OAAO,GAAG,CAAC,CAAa,EAAE,EAAE;QAC3C,IAAI,IAAI,CAAC,YAAY;YAAE,CAAC,CAAC,cAAc,EAAE,CAAC;QAC1C,wFAAwF;QACxF,MAAM,IAAI,GAAG,CAAC,CAAC,SAAS,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,YAAY,IAAI,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;QAC/F,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,GAAG,IAAI,EAAE,CAAC,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC;IAChD,CAAC,CAAC;IACe,IAAI,GAAG,CAAC,CAAe,EAAE,EAAE;QAC1C,IAAI,CAAC,CAAC,WAAW,KAAK,OAAO;YAAE,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC;QAC3D,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC;QAC3B,IAAI,CAAC,CAAC,SAAS;YAAE,IAAI,CAAC,OAAO,EAAE,CAAC;IAClC,CAAC,CAAC;IAEF,YAAY,OAAoB,EAAE,SAAoB;QACpD,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC;QACvB,IAAI,CAAC,SAAS,GAAG,SAAS,CAAC;QAC3B,OAAO,CAAC,KAAK,CAAC,WAAW,GAAG,MAAM,CAAC;QACnC,OAAO,CAAC,gBAAgB,CAAC,aAAa,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC;QACrD,OAAO,CAAC,gBAAgB,CAAC,aAAa,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC;QACrD,OAAO,CAAC,gBAAgB,CAAC,WAAW,EAAE,IAAI,CAAC,IAAI,CAAC,CAAC;QACjD,OAAO,CAAC,gBAAgB,CAAC,eAAe,EAAE,IAAI,CAAC,IAAI,CAAC,CAAC;QACrD,OAAO,CAAC,gBAAgB,CAAC,aAAa,EAAE,IAAI,CAAC,aAAa,CAAC,CAAC;QAC5D,8DAA8D;QAC9D,OAAO,CAAC,gBAAgB,CAAC,OAAO,EAAE,IAAI,CAAC,OAAO,EAAE,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC,CAAC;IACtE,CAAC;IAED,6GAA6G;IAC7G,KAAK,CAAC,CAAS,EAAE,CAAS,EAAE,IAAI,GAAgB,OAAO;QACrD,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC;QACX,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC;QACX,IAAI,IAAI,CAAC,IAAI;YAAE,OAAO;QACtB,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;QACjB,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC;QACpB,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;IACnB,CAAC;IAED,2CAA2C;IAC3C,IAAI,CAAC,CAAS,EAAE,CAAS;QACvB,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC;QACX,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC;IACb,CAAC;IAED,8CAA8C;IAC9C,OAAO;QACL,IAAI,CAAC,SAAS,GAAG,SAAS,CAAC;QAC3B,IAAI,CAAC,IAAI,CAAC,IAAI;YAAE,OAAO;QACvB,IAAI,CAAC,IAAI,GAAG,KAAK,CAAC;QAClB,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAC;IACvB,CAAC;IAED;;;OAGG;IACH,UAAU,CAAC,EAAU,EAAE,CAAS,EAAE,CAAS,EAAE,IAAI,GAAgB,OAAO;QACtE,IAAI,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC;YACzB,IAAI,CAAC,SAAS,CAAC,EAAE,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC;YACzB,OAAO;QACT,CAAC;QACD,IAAI,CAAC,UAAU,CAAC,EAAE,EAAE,CAAC,EAAE,CAAC,EAAE,IAAI,CAAC,CAAC;QAChC,IAAI,IAAI,CAAC,IAAI;YAAE,OAAO;QACtB,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,EAAE,IAAI,CAAC,CAAC;QACvB,IAAI,CAAC,SAAS,GAAG,EAAE,CAAC;IACtB,CAAC;IAED,0EAA0E;IAC1E,SAAS,CAAC,EAAU,EAAE,CAAS,EAAE,CAAS;QACxC,MAAM,CAAC,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QAC/B,IAAI,CAAC,CAAC;YAAE,OAAO;QACf,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC;QACR,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC;QACR,IAAI,EAAE,KAAK,IAAI,CAAC,SAAS;YAAE,IAAI,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;IAC7C,CAAC;IAED,mFAAmF;IACnF,QAAQ,CAAC,EAAU;QACjB,MAAM,CAAC,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QAC/B,IAAI,CAAC,CAAC;YAAE,OAAO;QACf,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;QACxB,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAC1B,IAAI,EAAE,KAAK,IAAI,CAAC,SAAS;YAAE,IAAI,CAAC,OAAO,EAAE,CAAC;IAC5C,CAAC;IAED,oDAAoD;IACpD,WAAW,CAAC,MAAqB;QAC/B,MAAM,CAAC,GAAG,IAAI,CAAC,MAAM,CAAC,CAAC;QACvB,IAAI,CAAC,CAAC,IAAI;YAAE,OAAO;QACnB,CAAC,CAAC,IAAI,GAAG,IAAI,CAAC;QACd,CAAC,CAAC,OAAO,GAAG,IAAI,CAAC;IACnB,CAAC;IAED,qDAAqD;IACrD,aAAa,CAAC,MAAqB;QACjC,MAAM,CAAC,GAAG,IAAI,CAAC,MAAM,CAAC,CAAC;QACvB,IAAI,CAAC,CAAC,CAAC,IAAI;YAAE,OAAO;QACpB,CAAC,CAAC,IAAI,GAAG,KAAK,CAAC;QACf,CAAC,CAAC,QAAQ,GAAG,IAAI,CAAC;IACpB,CAAC;IAED,kEAAkE;IAClE,MAAM,CAAC,EAAU,EAAE,EAAE,GAAG,CAAC;QACvB,IAAI,CAAC,KAAK,IAAI,EAAE,CAAC;QACjB,IAAI,CAAC,MAAM,IAAI,EAAE,CAAC;IACpB,CAAC;IAED,uEAAuE;IACvE,OAAO;QACL,IAAI,CAAC,OAAO,GAAG,KAAK,CAAC;QACrB,IAAI,CAAC,QAAQ,GAAG,KAAK,CAAC;QACtB,IAAI,CAAC,KAAK,GAAG,CAAC,CAAC;QACf,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC;QAChB,KAAK,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,EAAE,IAAI,CAAC,MAAM,CAAC;YAAE,CAAC,CAAC,OAAO,GAAG,CAAC,CAAC,QAAQ,GAAG,KAAK,CAAC;QAC1E,IAAI,CAAC,cAAc,CAAC,MAAM,GAAG,CAAC,CAAC;QAC/B,IAAI,CAAC,YAAY,CAAC,MAAM,GAAG,CAAC,CAAC;IAC/B,CAAC;IAED,OAAO;QACL,IAAI,CAAC,OAAO,CAAC,mBAAmB,CAAC,aAAa,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC;QAC7D,IAAI,CAAC,OAAO,CAAC,mBAAmB,CAAC,aAAa,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC;QAC7D,IAAI,CAAC,OAAO,CAAC,mBAAmB,CAAC,WAAW,EAAE,IAAI,CAAC,IAAI,CAAC,CAAC;QACzD,IAAI,CAAC,OAAO,CAAC,mBAAmB,CAAC,eAAe,EAAE,IAAI,CAAC,IAAI,CAAC,CAAC;QAC7D,IAAI,CAAC,OAAO,CAAC,mBAAmB,CAAC,aAAa,EAAE,IAAI,CAAC,aAAa,CAAC,CAAC;QACpE,IAAI,CAAC,OAAO,CAAC,mBAAmB,CAAC,OAAO,EAAE,IAAI,CAAC,OAAO,CAAC,CAAC;IAC1D,CAAC;IAEO,WAAW,CAAC,OAAe;QACjC,KAAK,MAAM,MAAM,IAAI,CAAC,OAAO,EAAE,QAAQ,CAAU,EAAE,CAAC;YAClD,IAAI,OAAO,GAAG,WAAW,CAAC,MAAM,CAAC;gBAAE,IAAI,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC;;gBACvD,IAAI,CAAC,aAAa,CAAC,MAAM,CAAC,CAAC;QAClC,CAAC;IACH,CAAC;IAED,wGAAwG;IAChG,OAAO,CAAC,EAAU;QACxB,IAAI,CAAC;YACH,IAAI,CAAC,OAAO,CAAC,iBAAiB,EAAE,CAAC,EAAE,CAAC,CAAC;QACvC,CAAC;QAAC,MAAM,CAAC;YACP,wFAAwF;QAC1F,CAAC;IACH,CAAC;IAEO,UAAU,CAAC,EAAU,EAAE,CAAS,EAAE,CAAS,EAAE,IAAiB;QACpE,MAAM,CAAC,GAAG,EAAE,EAAE,EAAE,CAAC,EAAE,CAAC,EAAE,IAAI,EAAE,CAAC;QAC7B,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC;QACxB,IAAI,CAAC,cAAc,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAC9B,CAAC;CACF;AAED,MAAM,MAAM,GAAG,CAAC,CAAe,EAAe,EAAE,CAAC,CAAC,CAAC,CAAC,WAAW,KAAK,OAAO,IAAI,CAAC,CAAC,WAAW,KAAK,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC"}
|