@rydr/game-sdk 8.0.0 → 8.2.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.
Files changed (75) hide show
  1. package/dist/client/PlatformClient.d.ts.map +1 -1
  2. package/dist/client/PlatformClient.js +3 -5
  3. package/dist/client/PlatformClient.js.map +1 -1
  4. package/dist/nav/README.md +13 -2
  5. package/dist/nav/motion.d.ts +10 -0
  6. package/dist/nav/motion.d.ts.map +1 -0
  7. package/dist/nav/motion.js +16 -0
  8. package/dist/nav/motion.js.map +1 -0
  9. package/dist/nav/scroll-nav.d.ts.map +1 -1
  10. package/dist/nav/scroll-nav.js +2 -6
  11. package/dist/nav/scroll-nav.js.map +1 -1
  12. package/dist/nav/spatial-nav.d.ts +12 -1
  13. package/dist/nav/spatial-nav.d.ts.map +1 -1
  14. package/dist/nav/spatial-nav.js +19 -5
  15. package/dist/nav/spatial-nav.js.map +1 -1
  16. package/dist/protocol/buttons.d.ts +17 -0
  17. package/dist/protocol/buttons.d.ts.map +1 -1
  18. package/dist/protocol/buttons.js +24 -0
  19. package/dist/protocol/buttons.js.map +1 -1
  20. package/dist/protocol/version.d.ts +1 -1
  21. package/dist/protocol/version.js +1 -1
  22. package/dist/ui/README.md +59 -4
  23. package/dist/ui/controller/combo-demo.d.ts +13 -4
  24. package/dist/ui/controller/combo-demo.d.ts.map +1 -1
  25. package/dist/ui/controller/combo-demo.js +55 -21
  26. package/dist/ui/controller/combo-demo.js.map +1 -1
  27. package/dist/ui/controller/control-spotlight.d.ts +188 -0
  28. package/dist/ui/controller/control-spotlight.d.ts.map +1 -0
  29. package/dist/ui/controller/control-spotlight.js +563 -0
  30. package/dist/ui/controller/control-spotlight.js.map +1 -0
  31. package/dist/ui/controller/control-trainer.d.ts.map +1 -1
  32. package/dist/ui/controller/control-trainer.js +6 -22
  33. package/dist/ui/controller/control-trainer.js.map +1 -1
  34. package/dist/ui/controller/controller-map.d.ts +20 -0
  35. package/dist/ui/controller/controller-map.d.ts.map +1 -1
  36. package/dist/ui/controller/controller-map.js +115 -56
  37. package/dist/ui/controller/controller-map.js.map +1 -1
  38. package/dist/ui/controller/controller-pad.d.ts +9 -3
  39. package/dist/ui/controller/controller-pad.d.ts.map +1 -1
  40. package/dist/ui/controller/controller-pad.js +7 -7
  41. package/dist/ui/controller/controller-pad.js.map +1 -1
  42. package/dist/ui/controller/index.d.ts +2 -0
  43. package/dist/ui/controller/index.d.ts.map +1 -1
  44. package/dist/ui/controller/index.js +2 -0
  45. package/dist/ui/controller/index.js.map +1 -1
  46. package/dist/ui/controller/live-presses.d.ts +68 -0
  47. package/dist/ui/controller/live-presses.d.ts.map +1 -0
  48. package/dist/ui/controller/live-presses.js +71 -0
  49. package/dist/ui/controller/live-presses.js.map +1 -0
  50. package/dist/ui/controller/pad-svg.d.ts +23 -3
  51. package/dist/ui/controller/pad-svg.d.ts.map +1 -1
  52. package/dist/ui/controller/pad-svg.js +28 -4
  53. package/dist/ui/controller/pad-svg.js.map +1 -1
  54. package/dist/ui/controller/parts-map.d.ts +51 -3
  55. package/dist/ui/controller/parts-map.d.ts.map +1 -1
  56. package/dist/ui/controller/parts-map.js +76 -4
  57. package/dist/ui/controller/parts-map.js.map +1 -1
  58. package/dist/ui/controller/styles.js +113 -8
  59. package/dist/ui/controller/styles.js.map +1 -1
  60. package/dist/ui/keycap.d.ts +7 -1
  61. package/dist/ui/keycap.d.ts.map +1 -1
  62. package/dist/ui/keycap.js.map +1 -1
  63. package/dist/ui/option-menu.d.ts +3 -2
  64. package/dist/ui/option-menu.d.ts.map +1 -1
  65. package/dist/ui/option-menu.js +5 -0
  66. package/dist/ui/option-menu.js.map +1 -1
  67. package/dist/ui/showcase/gallery.d.ts +12 -3
  68. package/dist/ui/showcase/gallery.d.ts.map +1 -1
  69. package/dist/ui/showcase/gallery.js +16 -7
  70. package/dist/ui/showcase/gallery.js.map +1 -1
  71. package/dist/ui/showcase/index.d.ts +4 -3
  72. package/dist/ui/showcase/index.d.ts.map +1 -1
  73. package/dist/ui/showcase/index.js +175 -13
  74. package/dist/ui/showcase/index.js.map +1 -1
  75. package/package.json +1 -1
@@ -1 +1 @@
1
- {"version":3,"file":"buttons.js","sourceRoot":"","sources":["../../src/protocol/buttons.ts"],"names":[],"mappings":"AAyJA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;AACH,MAAM,CAAC,MAAM,aAAa,GAAyC;IACjE,OAAO,EAAE,IAAI;IACb,SAAS,EAAE,MAAM;IACjB,SAAS,EAAE,MAAM;IACjB,UAAU,EAAE,OAAO;IACnB,oEAAoE;IACpE,GAAG,EAAE,cAAc;IACnB,KAAK,EAAE,cAAc;IACrB,MAAM,EAAE,eAAe;IACvB,SAAS,EAAE,eAAe;IAC1B,qFAAqF;IACrF,gCAAgC;IAChC,CAAC,EAAE,YAAY;IACf,CAAC,EAAE,YAAY;IACf,CAAC,EAAE,cAAc;IACjB,CAAC,EAAE,cAAc;IACjB,CAAC,EAAE,eAAe;IAClB,CAAC,EAAE,eAAe;IAClB,CAAC,EAAE,cAAc;IACjB,CAAC,EAAE,cAAc;IACjB,6DAA6D;IAC7D,CAAC,EAAE,IAAI;IACP,CAAC,EAAE,IAAI;IACP,CAAC,EAAE,IAAI;IACP,CAAC,EAAE,IAAI;IACP,0FAA0F;IAC1F,CAAC,EAAE,SAAS;IACZ,CAAC,EAAE,SAAS;CACb,CAAC;AAEF;;;;;;;;;;;;;;;;;GAiBG;AACH,MAAM,CAAC,MAAM,qBAAqB,GAAyC;IACzE,OAAO,EAAE,KAAK;IACd,OAAO,EAAE,OAAO;IAChB,OAAO,EAAE,OAAO;IAChB,OAAO,EAAE,QAAQ;IACjB,OAAO,EAAE,cAAc;IACvB,OAAO,EAAE,cAAc;CACxB,CAAC"}
1
+ {"version":3,"file":"buttons.js","sourceRoot":"","sources":["../../src/protocol/buttons.ts"],"names":[],"mappings":"AAyJA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;AACH,MAAM,CAAC,MAAM,aAAa,GAAyC;IACjE,OAAO,EAAE,IAAI;IACb,SAAS,EAAE,MAAM;IACjB,SAAS,EAAE,MAAM;IACjB,UAAU,EAAE,OAAO;IACnB,oEAAoE;IACpE,GAAG,EAAE,cAAc;IACnB,KAAK,EAAE,cAAc;IACrB,MAAM,EAAE,eAAe;IACvB,SAAS,EAAE,eAAe;IAC1B,qFAAqF;IACrF,gCAAgC;IAChC,CAAC,EAAE,YAAY;IACf,CAAC,EAAE,YAAY;IACf,CAAC,EAAE,cAAc;IACjB,CAAC,EAAE,cAAc;IACjB,CAAC,EAAE,eAAe;IAClB,CAAC,EAAE,eAAe;IAClB,CAAC,EAAE,cAAc;IACjB,CAAC,EAAE,cAAc;IACjB,6DAA6D;IAC7D,CAAC,EAAE,IAAI;IACP,CAAC,EAAE,IAAI;IACP,CAAC,EAAE,IAAI;IACP,CAAC,EAAE,IAAI;IACP,0FAA0F;IAC1F,CAAC,EAAE,SAAS;IACZ,CAAC,EAAE,SAAS;CACb,CAAC;AAEF;;;;;;;;;;;;;GAaG;AACH,MAAM,UAAU,YAAY,CAAC,IAAc,EAAE,IAA6B;IACxE,QAAQ,IAAI,EAAE,CAAC;QACb,KAAK,IAAI,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QAC3E,KAAK,IAAI,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QACxE,KAAK,IAAI,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QAC7E,KAAK,IAAI,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IAC5E,CAAC;AACH,CAAC;AAED,uFAAuF;AACvF,MAAM,CAAC,MAAM,UAAU,GAAwB,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,CAAC,CAAC;AAExE;;;;;;;;;;;;;;;;;GAiBG;AACH,MAAM,CAAC,MAAM,qBAAqB,GAAyC;IACzE,OAAO,EAAE,KAAK;IACd,OAAO,EAAE,OAAO;IAChB,OAAO,EAAE,OAAO;IAChB,OAAO,EAAE,QAAQ;IACjB,OAAO,EAAE,cAAc;IACvB,OAAO,EAAE,cAAc;CACxB,CAAC"}
@@ -9,5 +9,5 @@
9
9
  export declare const RYDR_PROTOCOL_VERSION: 30;
10
10
  /** Semver of this SDK build. Sent in the handshake for telemetry/debugging.
11
11
  * (Bumped to 2.0.0 by `npm version major` on release — see CHANGELOG [Unreleased].) */
12
- export declare const RYDR_SDK_VERSION = "8.0.0";
12
+ export declare const RYDR_SDK_VERSION = "8.2.0";
13
13
  //# sourceMappingURL=version.d.ts.map
@@ -176,5 +176,5 @@
176
176
  export const RYDR_PROTOCOL_VERSION = 30;
177
177
  /** Semver of this SDK build. Sent in the handshake for telemetry/debugging.
178
178
  * (Bumped to 2.0.0 by `npm version major` on release — see CHANGELOG [Unreleased].) */
179
- export const RYDR_SDK_VERSION = "8.0.0";
179
+ export const RYDR_SDK_VERSION = "8.2.0";
180
180
  //# sourceMappingURL=version.js.map
package/dist/ui/README.md CHANGED
@@ -54,8 +54,9 @@ feed its `{x, y, onScreen}` into `setScreenPos`/`setVisible` — don't compute p
54
54
  | `createButtonKeycap(button, opts)` | fn | A keycap for the buttons that are neither a face letter nor a direction, drawn as the pad draws them: `OPTIONS` → a round pip with the pad's ICON (`☰` on Xbox/DualSense, `+` on Switch); `LT`/`RT` and the stick clicks → a text pill ("LT"/"L2"/"LS"), since those are printed with a word. |
55
55
  | `mountOptionMenu(host, opts)` | fn | **The in-game menu**, opened by the game's own `OPTIONS` button: game name big in YOUR font, a free `Resume` row + your own rows, each able to advertise its in-game `shortcut`. Takes the controller over while up; leaves the trainer alone. See below. |
56
56
  | `mountControllerPad(host, opts)` | fn | **The rider's controller, drawn live** — buttons light while held, stick caps follow the real axes. Pass `press: session`. |
57
- | `mountControllerMap(host, opts)` | fn | **The controls screen** — that pad flanked by action callouts, each joined by a line to its button. Takes a declarative `ControlAction[]`. |
57
+ | `mountControllerMap(host, opts)` | fn | **The controls screen** — that pad flanked by action callouts, each joined by a line to every button its combination names. The card prints the ACTION only; the line says which control. Takes a declarative `ControlAction[]`. |
58
58
  | `mountComboDemo(host, opts)` | fn | **"Do this" animation** — loops the combination one action requires: buttons sink in, the stick swings, release, repeat. |
59
+ | `mountControlSpotlight(host, opts)` | fn | **Caption ON the button** — N controls, one at a time, each lit with its text pinned to the control itself, on a per-step clock. Or `mode: "still"` for no clock at all: one control lit and captioned indefinitely (a stick still sweeps — "still" is about the timeline, not the artwork). With `watch`, a real press paints green and stands the loop down. |
59
60
  | `mountControlTrainer(host, opts)` | fn | **Guided lesson** — a title, one panel per step side by side, one shared controller below. Watches the rider: white "do this" → blue "doing it" → green ✓. Fires `onComplete` when every step is done. |
60
61
  | `createComboStrip(action, opts)` | fn | Just the chip row for one action (`[L2] + [✕]`), for embedding in your own layout. |
61
62
  | `createInputChip(token, opts)` | fn | One control's pictogram, for embedding in your own layout. Delegates to `createKeycap` / `createDpadKeycap` / `createButtonKeycap` for the buttons, and draws its own stick pictograms. The atom the two views are built from. |
@@ -175,9 +176,10 @@ Notes worth knowing:
175
176
  the whole point of the positional vocabulary. The views also **re-letter themselves** if the rider
176
177
  swaps pads mid-screen (pass `press: session`), so you never rebuild them.
177
178
  - **`LT`/`RT` are your shoulder buttons**, and they letter as `LT` / `L2` / `ZL`. The upper `L1`/`R1`
178
- bumpers are the shell's resistance − / +, and `View`/`Guide` are the shell's too — all of them are
179
- drawn faint and can never light, so a rider can tell "this game doesn't use that" from "that isn't
180
- the game's to use".
179
+ bumpers are the shell's resistance − / +, and `View`/`Guide` are the shell's too — none of them can
180
+ ever light for a game. `View`/`Guide` are also drawn faint, since they're genuinely not your screen's
181
+ business; the **bumpers are drawn at full strength**, because the rider can always reach for their
182
+ resistance, on every screen, and dimming them read as "disabled".
181
183
  - **Devices differ.** A Zwift Play has no joysticks and no triggers, so they aren't drawn at all. A
182
184
  phone exposes only the confirm/back pair — the protocol can't tell us which buttons a device has, so
183
185
  pass `available: [...]` if your game knows, and don't gate a required flow behind a rare control.
@@ -191,6 +193,59 @@ Notes worth knowing:
191
193
  - Tuned for up to **5 callouts per side**; past that it warns rather than dropping one.
192
194
  - Live catalog: `npm run showcase` in the SDK repo, or the platform's `/game-ui` route.
193
195
 
196
+ ### Which of the five do I want?
197
+
198
+ They all take the same `ControlAction` vocabulary (`{ label, combo }`), so this is purely about how the
199
+ answer is presented:
200
+
201
+ | You want to say | Use |
202
+ | --- | --- |
203
+ | "here is the whole control scheme" | `mountControllerMap` — callouts in columns, lines to buttons |
204
+
205
+ > **The map does not print the button in the card.** A callout is the action's name and nothing else;
206
+ > the leader line is what identifies the control, one line per button in the combination. Keycap chips
207
+ > appear only where a line is impossible — a layout that doesn't draw that part (a Zwift pod has no
208
+ > sticks), or a control on the far side of the pad. Pass `chips: "always"` to get them back everywhere.
209
+
210
+ | "here is the one combination for THIS action" | `mountComboDemo` — animates it on a loop |
211
+ | "this button, and here's what it does" — the words ON the control | `mountControlSpotlight` |
212
+ | "…and it stays up" (a HUD hint, a pre-race legend) | `mountControlSpotlight` with `mode: "still"` — the control still animates if its engaged state is a motion |
213
+ | "do this, and I'll wait until you have" | `mountControlTrainer` — gates on the rider |
214
+ | just the drawing, reflecting real input | `mountControllerPad` |
215
+
216
+ Reach for the **spotlight** over the map when the caption has to land on the control rather than in a
217
+ list beside it — a rider on a bike, reading from a few feet away, can't be asked to trace a line from a
218
+ legend back to a button. It's also the only one of the five that gives each control its own dwell.
219
+
220
+ ```ts
221
+ import { mountControlSpotlight } from "@rydr/game-sdk/ui";
222
+
223
+ // A tour, watching the rider: blue is the demo, green is you.
224
+ mountControlSpotlight(host, {
225
+ press: session,
226
+ watch: true,
227
+ steps: [
228
+ { label: "Freiner", combo: ["LT"] },
229
+ { label: "Sauter", combo: ["DIAMOND_DOWN"], holdMs: 1400 },
230
+ ],
231
+ });
232
+
233
+ // No clock: one control lit and captioned, for as long as it's on screen.
234
+ mountControlSpotlight(hud, {
235
+ press: session,
236
+ mode: "still",
237
+ steps: [{ label: "Se déplacer", combo: ["LSTICK"] }],
238
+ });
239
+ ```
240
+
241
+ A caption is **one line: the action's name.** `hint` is typed out of `ControlSpotlightStep` — the bubble
242
+ floats over the rider's controller for a couple of seconds while they pedal, and a quieter second line
243
+ under the first means neither gets read. (`hint` still works in `mountControllerMap` / `mountComboDemo`,
244
+ where the caption sits in a card — but write it for what the combination *can't* show, "Maintenir" or
245
+ "Verrouillé", never to spell out a button's name.) Captions are also **text only** for now — a step naming several
246
+ controls lights all of them, but the bubble draws no chips; use `mountComboDemo` or `mountControllerMap`
247
+ to spell a combination out.
248
+
194
249
  ### Teaching a control — `mountControlTrainer`
195
250
 
196
251
  For a lesson the rider has to *perform*, not just watch. Built for paired controls: one concept, two
@@ -33,17 +33,26 @@
33
33
  import type { GlyphSet } from "../../protocol/glyphs.js";
34
34
  import { type ControllerPad, type PadInputSource } from "./controller-pad.js";
35
35
  import type { StickPictogramStyle } from "./input-chip.js";
36
- import { type ControlAction } from "./tokens.js";
36
+ import type { ControlAction } from "./tokens.js";
37
37
  import type { PadBrandKey } from "./types.js";
38
38
  export interface ComboDemoOptions {
39
39
  /** The single action to demonstrate. */
40
40
  action: ControlAction;
41
41
  /**
42
- * A session, used ONLY to learn the rider's lettering and to follow pad swaps — the demo deliberately
43
- * does not wire it to input. The animation is the sole writer of the drawing's state; letting real
44
- * presses write it too would make the two fight for the same classes every frame.
42
+ * A session, used for the rider's lettering, to follow pad swaps, and only with {@link watch} — to
43
+ * reflect their own presses. The animation remains the sole *writer* of the drawing either way: the
44
+ * live pass runs after it, through the same driver, rather than a second subscriber racing it.
45
45
  */
46
46
  press?: PadInputSource;
47
+ /**
48
+ * Watch the rider: any control they hold paints GREEN over the animation, whether or not this
49
+ * combination names it (see `live-presses.ts`). Default false — a bare attract loop wants no second
50
+ * hand on the drawing.
51
+ *
52
+ * The animation stays in the accent underneath, which is the whole reason the rider's own press is
53
+ * green: on a drawing already showing a press in blue, blue can't also mean "and that one was yours".
54
+ */
55
+ watch?: boolean;
47
56
  brand?: PadBrandKey;
48
57
  glyphSet?: GlyphSet;
49
58
  /** Draw the controller. Default true; `false` gives a compact chips-only cue. */
@@ -1 +1 @@
1
- {"version":3,"file":"combo-demo.d.ts","sourceRoot":"","sources":["../../../src/ui/controller/combo-demo.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG;AAEH,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,0BAA0B,CAAC;AAEzD,OAAO,EAAsB,KAAK,aAAa,EAAE,KAAK,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAClG,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,iBAAiB,CAAC;AAG3D,OAAO,EAAgC,KAAK,aAAa,EAAE,MAAM,aAAa,CAAC;AAC/E,OAAO,KAAK,EAAE,WAAW,EAAW,MAAM,YAAY,CAAC;AAEvD,MAAM,WAAW,gBAAgB;IAC/B,wCAAwC;IACxC,MAAM,EAAE,aAAa,CAAC;IACtB;;;;OAIG;IACH,KAAK,CAAC,EAAE,cAAc,CAAC;IACvB,KAAK,CAAC,EAAE,WAAW,CAAC;IACpB,QAAQ,CAAC,EAAE,QAAQ,CAAC;IACpB,iFAAiF;IACjF,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,iEAAiE;IACjE,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,IAAI,CAAC,EAAE,IAAI,GAAG,IAAI,GAAG,IAAI,CAAC;IAC1B,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,oGAAoG;IACpG,UAAU,CAAC,EAAE,mBAAmB,CAAC;IACjC,8EAA8E;IAC9E,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,wDAAwD;IACxD,OAAO,CAAC,EAAE,MAAM,IAAI,CAAC;CACtB;AAED,MAAM,WAAW,SAAS;IACxB,QAAQ,CAAC,IAAI,EAAE,cAAc,CAAC;IAC9B,QAAQ,CAAC,GAAG,EAAE,aAAa,GAAG,SAAS,CAAC;IACxC,SAAS,CAAC,MAAM,EAAE,aAAa,GAAG,IAAI,CAAC;IACvC,IAAI,IAAI,IAAI,CAAC;IACb,KAAK,IAAI,IAAI,CAAC;IACd,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,OAAO,IAAI,IAAI,CAAC;CACjB;AA4CD,wBAAgB,cAAc,CAAC,IAAI,EAAE,WAAW,EAAE,IAAI,EAAE,gBAAgB,GAAG,SAAS,CA4OnF"}
1
+ {"version":3,"file":"combo-demo.d.ts","sourceRoot":"","sources":["../../../src/ui/controller/combo-demo.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG;AAEH,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,0BAA0B,CAAC;AAEzD,OAAO,EAAsB,KAAK,aAAa,EAAE,KAAK,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAClG,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,iBAAiB,CAAC;AAI3D,OAAO,KAAK,EAAE,aAAa,EAAe,MAAM,aAAa,CAAC;AAC9D,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAE9C,MAAM,WAAW,gBAAgB;IAC/B,wCAAwC;IACxC,MAAM,EAAE,aAAa,CAAC;IACtB;;;;OAIG;IACH,KAAK,CAAC,EAAE,cAAc,CAAC;IACvB;;;;;;;OAOG;IACH,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,KAAK,CAAC,EAAE,WAAW,CAAC;IACpB,QAAQ,CAAC,EAAE,QAAQ,CAAC;IACpB,iFAAiF;IACjF,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,iEAAiE;IACjE,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,IAAI,CAAC,EAAE,IAAI,GAAG,IAAI,GAAG,IAAI,CAAC;IAC1B,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,oGAAoG;IACpG,UAAU,CAAC,EAAE,mBAAmB,CAAC;IACjC,8EAA8E;IAC9E,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,wDAAwD;IACxD,OAAO,CAAC,EAAE,MAAM,IAAI,CAAC;CACtB;AAED,MAAM,WAAW,SAAS;IACxB,QAAQ,CAAC,IAAI,EAAE,cAAc,CAAC;IAC9B,QAAQ,CAAC,GAAG,EAAE,aAAa,GAAG,SAAS,CAAC;IACxC,SAAS,CAAC,MAAM,EAAE,aAAa,GAAG,IAAI,CAAC;IACvC,IAAI,IAAI,IAAI,CAAC;IACb,KAAK,IAAI,IAAI,CAAC;IACd,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,OAAO,IAAI,IAAI,CAAC;CACjB;AAqBD,wBAAgB,cAAc,CAAC,IAAI,EAAE,WAAW,EAAE,IAAI,EAAE,gBAAgB,GAAG,SAAS,CA2RnF"}
@@ -32,9 +32,9 @@
32
32
  */
33
33
  import { createComboStrip } from "./combo-strip.js";
34
34
  import { mountControllerPad } from "./controller-pad.js";
35
- import { litPartOfControl } from "./parts-map.js";
35
+ import { createLivePresses } from "./live-presses.js";
36
+ import { channelsOf, triggerSideOfPart } from "./parts-map.js";
36
37
  import { injectPadCss } from "./styles.js";
37
- import { parseToken, STICK_DIR_VECTOR } from "./tokens.js";
38
38
  // Timings in seconds. Tuned to read at a glance from a few feet away, not to be brisk.
39
39
  const HOLD_IDLE = 0.4;
40
40
  const HOLD_STAGGER = 0.2;
@@ -52,21 +52,6 @@ const smoothstep = (t) => {
52
52
  const c = Math.max(0, Math.min(1, t));
53
53
  return c * c * (3 - 2 * c);
54
54
  };
55
- function channelsOf(action) {
56
- return action.combo.map((token, index) => {
57
- const t = parseToken(token);
58
- if (t.kind === "stick") {
59
- return {
60
- index,
61
- stick: {
62
- side: t.stick === "LSTICK" ? "l" : "r",
63
- vec: t.dir ? STICK_DIR_VECTOR[t.dir] : null, // null = undirected → sweep
64
- },
65
- };
66
- }
67
- return { index, part: litPartOfControl(t.name) };
68
- });
69
- }
70
55
  export function mountComboDemo(host, opts) {
71
56
  injectPadCss();
72
57
  const root = document.createElement("div");
@@ -128,6 +113,48 @@ export function mountComboDemo(host, opts) {
128
113
  }
129
114
  buildStrip();
130
115
  syncLabel();
116
+ // ── the rider's own presses ─────────────────────────────────────────────────────────────────────
117
+ const watch = opts.watch === true && opts.press != null;
118
+ /** What the rider is holding. Kept even for controls this combination never mentions — see below. */
119
+ const held = new Set();
120
+ /**
121
+ * Green over the animation for whatever the rider holds.
122
+ *
123
+ * A part one of the channels owns needs no restoring: `renderAt` rewrites every channel every frame, so
124
+ * the animation takes its own part back on the very next one. A part it doesn't own is this pass's to
125
+ * clear — nothing else would ever touch it again.
126
+ */
127
+ const paintLivePresses = createLivePresses({
128
+ state: "done",
129
+ axis: opts.press?.axis?.bind(opts.press),
130
+ shellOwned: false, // a combination is game vocabulary; the shoulders are drawn faint here
131
+ light: (part, state) => {
132
+ const driver = pad?.driver();
133
+ driver?.setPartState(part, state);
134
+ const meter = triggerSideOfPart(part);
135
+ if (meter)
136
+ driver?.setMeter(meter, 1);
137
+ },
138
+ setStick: (side, x, y, state) => pad?.driver().setStick(side, x, y, state === "done" ? "done" : "on"),
139
+ release: (part) => {
140
+ if (channels.some((ch) => ch.part === part))
141
+ return; // the animation repaints it next frame
142
+ const driver = pad?.driver();
143
+ driver?.setPartState(part, "off");
144
+ const meter = triggerSideOfPart(part);
145
+ if (meter)
146
+ driver?.setMeter(meter, 0);
147
+ },
148
+ });
149
+ const offButton = watch
150
+ ? opts.press?.onButton(({ name, edge }) => {
151
+ edge === "down" ? held.add(name) : held.delete(name);
152
+ // Reduced motion has no loop running, so the edge itself has to repaint: the still frame first
153
+ // (it owns the animation's parts) and then the rider's own on top.
154
+ if (reduceMotion)
155
+ renderStill();
156
+ })
157
+ : undefined;
131
158
  /** Total cycle length, in seconds at speed 1. */
132
159
  function cycleLength() {
133
160
  const n = Math.max(1, action.combo.length);
@@ -142,6 +169,11 @@ export function mountComboDemo(host, opts) {
142
169
  * decides what "engaged" looks like.
143
170
  */
144
171
  function renderAt(t) {
172
+ drawCombo(t);
173
+ if (watch)
174
+ paintLivePresses(held); // last, so the rider's own hand wins any part the animation shares
175
+ }
176
+ function drawCombo(t) {
145
177
  const driver = pad?.driver();
146
178
  if (action.sequence) {
147
179
  let completed = 0;
@@ -195,10 +227,9 @@ export function mountComboDemo(host, opts) {
195
227
  strip.setPressedAt(ch.index, on);
196
228
  if (ch.part && driver) {
197
229
  driver.setPart(ch.part, on);
198
- if (ch.part === "lt")
199
- driver.setMeter("l", on ? 1 : 0);
200
- if (ch.part === "rt")
201
- driver.setMeter("r", on ? 1 : 0);
230
+ const meter = triggerSideOfPart(ch.part);
231
+ if (meter)
232
+ driver.setMeter(meter, on ? 1 : 0);
202
233
  }
203
234
  }
204
235
  /** The still frame for reduced motion: everything engaged, sticks at full deflection. */
@@ -207,6 +238,8 @@ export function mountComboDemo(host, opts) {
207
238
  for (const ch of channels)
208
239
  applyChannel(ch, true, 1, 0, driver);
209
240
  strip.setStep(action.combo.length);
241
+ if (watch)
242
+ paintLivePresses(held);
210
243
  }
211
244
  // ── the loop ────────────────────────────────────────────────────────────────────────────────────
212
245
  const reduceMotion = typeof matchMedia === "function" && matchMedia("(prefers-reduced-motion: reduce)").matches;
@@ -285,6 +318,7 @@ export function mountComboDemo(host, opts) {
285
318
  dispose() {
286
319
  stop();
287
320
  document.removeEventListener("visibilitychange", onVisibility);
321
+ offButton?.();
288
322
  offRebuild?.();
289
323
  strip.dispose();
290
324
  pad?.dispose();
@@ -1 +1 @@
1
- {"version":3,"file":"combo-demo.js","sourceRoot":"","sources":["../../../src/ui/controller/combo-demo.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"combo-demo.js","sourceRoot":"","sources":["../../../src/ui/controller/combo-demo.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,188 @@
1
+ /**
2
+ * CONTROL SPOTLIGHT — "this button, and here's what it does", written on the button itself.
3
+ *
4
+ * ```ts
5
+ * // A tour: each control in turn, captioned, on a clock.
6
+ * const spot = mountControlSpotlight(host, {
7
+ * press: shellInput,
8
+ * watch: true,
9
+ * steps: [
10
+ * { label: "Descendre de vitesse", combo: ["LB"] },
11
+ * { label: "Monter de vitesse", combo: ["RB"] },
12
+ * ],
13
+ * });
14
+ *
15
+ * // Or no clock at all: one control, lit and captioned, indefinitely.
16
+ * mountControlSpotlight(hud, { press: session, mode: "still", steps: [{ label: "Move", combo: ["LSTICK"] }] });
17
+ * ```
18
+ *
19
+ * The caption sits **on the control**, not in a list beside the pad — which is the whole reason this
20
+ * view exists. A rider on a bike reading a trainer screen from a few feet away cannot be asked to trace
21
+ * a line from a legend back to a button, and the control genuinely cannot be named in text: the same
22
+ * button reads `LB` on an Xbox pad, `L1` on a DualSense and a bare `L` on a Switch. Pointing at it and
23
+ * saying what it does is the only honest way to teach it.
24
+ *
25
+ * ## Which of the four controller views is this
26
+ *
27
+ * {@link mountControllerPad} the drawing alone, reflecting real input
28
+ * {@link mountControllerMap} STATIC — every control at once, callouts in columns joined by lines
29
+ * {@link mountComboDemo} DYNAMIC — one combination, animated on a loop
30
+ * {@link mountControlSpotlight} N controls, ONE at a time, captioned ON the button, on its own clock
31
+ * {@link mountControlTrainer} a lesson that WATCHES and gates on the rider performing it
32
+ *
33
+ * The map is what you want for "here is the control scheme". This is what you want when the caption has
34
+ * to land on the button, when each control needs its own dwell, or when there is no clock at all and you
35
+ * simply want one control lit with a label on it.
36
+ *
37
+ * ## Two modes, one render
38
+ *
39
+ * `"tour"` walks the steps: each lights for its `holdMs`, then a dark `gapMs`, then the next. The gap is
40
+ * load-bearing — two steps shown back to back read as one flickering picture, and the dark beat between
41
+ * them is what makes them two statements rather than one.
42
+ *
43
+ * `"still"` has no clock: every step lights and every caption shows, and stays. With a single step that
44
+ * is "highlight this key, with this text, for as long as I'm on screen", which needs no timeline to
45
+ * express. `prefers-reduced-motion` simply forces this mode — so the reduced-motion still is not a
46
+ * second code path to keep in step with the first, it IS the first.
47
+ *
48
+ * ## The rider outranks the lesson (`watch`)
49
+ *
50
+ * With `watch`, a control the rider is actually holding paints **green** (`done`) instead of the accent,
51
+ * and the timeline **stands down**: it stops, every unheld control goes dark, and it restarts from the
52
+ * top `resumeMs` after they let go. A loop that keeps cycling underneath a rider trying it out is two
53
+ * hands on the same pad — they cannot tell which of the lights is theirs, which is the entire feedback
54
+ * the lesson exists to give.
55
+ *
56
+ * Green is not limited to the controls the steps name: with `watch` the drawing paints EVERY control the
57
+ * rider is holding, including ones no step teaches. A rider trying the pad out while the lesson runs is
58
+ * asking "which one is this?", and a drawing that answers only for the two buttons it happens to be
59
+ * teaching reads as a dead pad rather than as an answer. Only what the rider holds turns green, so the
60
+ * lesson's own controls stay the only BLUE thing on it.
61
+ *
62
+ * Blue says *this is the press*; green says *and that one was yours*. Neither is the whitish `hint` the
63
+ * trainer uses, which is built for "do this, I'll wait" — here the instruction is a moving picture of a
64
+ * press, and a press drawn in not-a-press colours doesn't look like the thing it's asking for.
65
+ *
66
+ * ## This component is the sole writer of the drawing
67
+ *
68
+ * The pad is mounted **glyph-only** (it gets the hardware store for its lettering, and an `onButton` that
69
+ * does nothing), exactly as {@link mountControlTrainer} does. Wiring the pad to input as well would give
70
+ * two writers for the same classes every frame, each undoing the other. We take the rider's presses
71
+ * ourselves and fold them into the paint, so there is one writer and no race.
72
+ *
73
+ * ⚠️ **A caption is ONE line: the action's name.** No `hint` subtitle — `ControlSpotlightStep` types it
74
+ * out — because this bubble floats over the rider's controller for about two seconds while they pedal,
75
+ * and a second quieter line under the first means neither gets read. Qualify the label if you must.
76
+ *
77
+ * ⚠️ **Captions are text-only for now.** A step whose combo names several controls lights all of them
78
+ * and pins its caption per the usual anchor rule, but the bubble does not draw chips — the multi-control
79
+ * case is getting its own treatment later. Don't grow chips in here by drift; `mountComboDemo` and
80
+ * `mountControllerMap` are where a combination is spelled out today.
81
+ */
82
+ import type { GlyphSet } from "../../protocol/glyphs.js";
83
+ import { type ControllerPad, type PadInputSource } from "./controller-pad.js";
84
+ import { type ControlAction } from "./tokens.js";
85
+ import { type PadBrandKey } from "./types.js";
86
+ /** How long a step holds lit, unless it says otherwise. */
87
+ export declare const SPOTLIGHT_HOLD_MS = 2000;
88
+ /**
89
+ * The dark beat after a step. Not decoration — see the note on the gap above; two lit controls with no
90
+ * dark between them read as one picture flickering rather than as two separate statements.
91
+ */
92
+ export declare const SPOTLIGHT_GAP_MS = 1000;
93
+ /** How long after the rider lets go of everything before the timeline takes the pad back. */
94
+ export declare const SPOTLIGHT_RESUME_MS = 1000;
95
+ export interface ControlSpotlightStep extends Omit<ControlAction, "hint"> {
96
+ /**
97
+ * ⛔ **Not available here.** A spotlight is the action's name and nothing else.
98
+ *
99
+ * Typed as `never` rather than quietly ignored, so passing one is a compile error at the call site
100
+ * instead of a subtitle that silently doesn't appear. `ControlAction.hint` still exists and still works
101
+ * in {@link mountControllerMap} and {@link mountComboDemo}, where the caption sits in a card with room
102
+ * to spare and time to be read.
103
+ *
104
+ * The reason it can't come along: this bubble floats ON the drawing, over the rider's own controller,
105
+ * for about two seconds while they are pedaling. One short line is what can be read in that space and
106
+ * that time — a second, quieter line under it competes with the first and gets neither read. If the
107
+ * label needs qualifying, the qualifier belongs in the label.
108
+ */
109
+ hint?: never;
110
+ /** How long this step holds lit. Default {@link SPOTLIGHT_HOLD_MS}. */
111
+ holdMs?: number;
112
+ /** The dark beat after it, before the next step. Default {@link SPOTLIGHT_GAP_MS}. */
113
+ gapMs?: number;
114
+ }
115
+ export interface ControlSpotlightOptions {
116
+ /** What to spotlight, in the order the tour plays them. One step is a perfectly good list. */
117
+ steps: readonly ControlSpotlightStep[];
118
+ /**
119
+ * `"tour"` (default) walks the steps on a clock. `"still"` has no timeline: every step lights and
120
+ * every caption shows, and stays that way.
121
+ *
122
+ * `prefers-reduced-motion` forces `"still"`, so asking for it explicitly gets you exactly what a
123
+ * reduced-motion rider already sees.
124
+ */
125
+ mode?: "tour" | "still";
126
+ /**
127
+ * The rider's input. Used for the LETTERING and for following pad swaps in both modes; only consulted
128
+ * for presses when {@link watch} is set.
129
+ *
130
+ * For a lesson about the resistance shoulders this must be a SHELL-side source: `LB`/`RB` are
131
+ * shell-owned and never reach a game's `session.onButton`.
132
+ */
133
+ press?: PadInputSource;
134
+ /**
135
+ * Watch the rider: ANY control they hold paints green — the steps' own controls (which outrank the
136
+ * timeline, so it stands down and restarts) and equally the ones no step names, so the drawing answers
137
+ * "which button is this?" rather than only "did you do the lesson?".
138
+ *
139
+ * Default false — without it this is an attract animation and nothing the rider does to their pad
140
+ * changes what it draws.
141
+ */
142
+ watch?: boolean;
143
+ /** Quiet time after the last release before the timeline resumes. Default {@link SPOTLIGHT_RESUME_MS}. */
144
+ resumeMs?: number;
145
+ /**
146
+ * Which side of its control a caption sits on. Default `"auto"`: parts in the top half of the drawing
147
+ * get their caption ABOVE and parts in the bottom half get it BELOW, so the bubble always escapes the
148
+ * drawing rather than covering its middle.
149
+ */
150
+ captionSide?: "above" | "below" | "auto";
151
+ /**
152
+ * Halo and pulse on an engaged control. Default true.
153
+ *
154
+ * `false` leaves the fill alone doing the work, which is what a lesson about ONE press wants: the halo
155
+ * reads as "this is highlighted", the fill alone reads as "this is held down", and the second is the
156
+ * only thing a spotlight is saying.
157
+ */
158
+ glow?: boolean;
159
+ /** Keep cycling. Default true. `false` plays the tour once and leaves the drawing dark. */
160
+ loop?: boolean;
161
+ /** Playback rate. `1` = normal, `0.5` = half speed. Ignored in `"still"`. */
162
+ speed?: number;
163
+ /** Pad size preset. Default `"lg"` — this is meant to be read from a saddle. */
164
+ size?: "sm" | "md" | "lg";
165
+ brand?: PadBrandKey;
166
+ glyphSet?: GlyphSet;
167
+ labels?: boolean;
168
+ accent?: string;
169
+ /** A step became the one being shown. Not called in `"still"`, where they all are. */
170
+ onStepShown?(step: ControlSpotlightStep, index: number): void;
171
+ /** The rider performed this step themselves. Fires once per step, on the first time. */
172
+ onPerformed?(step: ControlSpotlightStep, index: number): void;
173
+ /** The tour completed a full pass. */
174
+ onCycle?(): void;
175
+ }
176
+ export interface ControlSpotlight {
177
+ readonly root: HTMLDivElement;
178
+ readonly pad: ControllerPad;
179
+ /** Swap the whole list. Rebuilds the captions and restarts the timeline. */
180
+ setSteps(steps: readonly ControlSpotlightStep[]): void;
181
+ play(): void;
182
+ pause(): void;
183
+ /** Which steps the rider has performed themselves, by index. Always false without `watch`. */
184
+ performed(): readonly boolean[];
185
+ dispose(): void;
186
+ }
187
+ export declare function mountControlSpotlight(host: HTMLElement, opts: ControlSpotlightOptions): ControlSpotlight;
188
+ //# sourceMappingURL=control-spotlight.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"control-spotlight.d.ts","sourceRoot":"","sources":["../../../src/ui/controller/control-spotlight.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgFG;AAGH,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,0BAA0B,CAAC;AACzD,OAAO,EAAsB,KAAK,aAAa,EAAE,KAAK,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAclG,OAAO,EAA8B,KAAK,aAAa,EAAoB,MAAM,aAAa,CAAC;AAC/F,OAAO,EAAc,KAAK,WAAW,EAAgB,MAAM,YAAY,CAAC;AAExE,2DAA2D;AAC3D,eAAO,MAAM,iBAAiB,OAAO,CAAC;AACtC;;;GAGG;AACH,eAAO,MAAM,gBAAgB,OAAO,CAAC;AACrC,6FAA6F;AAC7F,eAAO,MAAM,mBAAmB,OAAO,CAAC;AAOxC,MAAM,WAAW,oBAAqB,SAAQ,IAAI,CAAC,aAAa,EAAE,MAAM,CAAC;IACvE;;;;;;;;;;;;OAYG;IACH,IAAI,CAAC,EAAE,KAAK,CAAC;IACb,uEAAuE;IACvE,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,sFAAsF;IACtF,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,uBAAuB;IACtC,8FAA8F;IAC9F,KAAK,EAAE,SAAS,oBAAoB,EAAE,CAAC;IACvC;;;;;;OAMG;IACH,IAAI,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC;IACxB;;;;;;OAMG;IACH,KAAK,CAAC,EAAE,cAAc,CAAC;IACvB;;;;;;;OAOG;IACH,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,0GAA0G;IAC1G,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB;;;;OAIG;IACH,WAAW,CAAC,EAAE,OAAO,GAAG,OAAO,GAAG,MAAM,CAAC;IACzC;;;;;;OAMG;IACH,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,2FAA2F;IAC3F,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,6EAA6E;IAC7E,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,gFAAgF;IAChF,IAAI,CAAC,EAAE,IAAI,GAAG,IAAI,GAAG,IAAI,CAAC;IAC1B,KAAK,CAAC,EAAE,WAAW,CAAC;IACpB,QAAQ,CAAC,EAAE,QAAQ,CAAC;IACpB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,sFAAsF;IACtF,WAAW,CAAC,CAAC,IAAI,EAAE,oBAAoB,EAAE,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9D,wFAAwF;IACxF,WAAW,CAAC,CAAC,IAAI,EAAE,oBAAoB,EAAE,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9D,sCAAsC;IACtC,OAAO,CAAC,IAAI,IAAI,CAAC;CAClB;AAED,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,CAAC,IAAI,EAAE,cAAc,CAAC;IAC9B,QAAQ,CAAC,GAAG,EAAE,aAAa,CAAC;IAC5B,4EAA4E;IAC5E,QAAQ,CAAC,KAAK,EAAE,SAAS,oBAAoB,EAAE,GAAG,IAAI,CAAC;IACvD,IAAI,IAAI,IAAI,CAAC;IACb,KAAK,IAAI,IAAI,CAAC;IACd,8FAA8F;IAC9F,SAAS,IAAI,SAAS,OAAO,EAAE,CAAC;IAChC,OAAO,IAAI,IAAI,CAAC;CACjB;AAeD,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,WAAW,EAAE,IAAI,EAAE,uBAAuB,GAAG,gBAAgB,CA2dxG"}