@scenar/core 0.5.0 → 0.7.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/index.d.ts +3 -3
- package/index.d.ts.map +1 -1
- package/index.js +2 -2
- package/index.js.map +1 -1
- package/package.json +1 -1
- package/scenario/step-action.d.ts +10 -0
- package/scenario/step-action.d.ts.map +1 -1
- package/src/index.ts +8 -2
- package/src/scenario/step-action.ts +8 -0
- package/src/timing/constants.ts +17 -10
- package/src/viewport/transform.test.ts +81 -0
- package/src/viewport/transform.ts +62 -0
- package/timing/constants.d.ts +16 -10
- package/timing/constants.d.ts.map +1 -1
- package/timing/constants.js +16 -10
- package/timing/constants.js.map +1 -1
- package/viewport/transform.d.ts +36 -0
- package/viewport/transform.d.ts.map +1 -1
- package/viewport/transform.js +38 -0
- package/viewport/transform.js.map +1 -1
package/index.d.ts
CHANGED
|
@@ -2,15 +2,15 @@ export type { ScenarioStep } from "./scenario/types.js";
|
|
|
2
2
|
export type { ScenarioBundle } from "./scenario/bundle.js";
|
|
3
3
|
export type { ActionType, StepAction, UseStepInteractionsOptions, } from "./scenario/step-action.js";
|
|
4
4
|
export type { NarrationEntry, NarrationManifest } from "./narration/types.js";
|
|
5
|
-
export type { ViewportTransform } from "./viewport/transform.js";
|
|
6
|
-
export { VIEWPORT_TRANSFORM_IDENTITY } from "./viewport/transform.js";
|
|
5
|
+
export type { ViewportTransform, ViewportCameraMove } from "./viewport/transform.js";
|
|
6
|
+
export { VIEWPORT_TRANSFORM_IDENTITY, VIEWPORT_CAMERA_AT_REST, cameraEase, interpolateViewportTransform, } from "./viewport/transform.js";
|
|
7
7
|
export type { Position } from "./cursor/compute-position.js";
|
|
8
8
|
export { computeCursorPosition } from "./cursor/compute-position.js";
|
|
9
9
|
export type { StepTimeline } from "./timeline/compute-step-timeline.js";
|
|
10
10
|
export { computeStepTimeline } from "./timeline/compute-step-timeline.js";
|
|
11
11
|
export { deriveStepFromTime } from "./timeline/derive-step.js";
|
|
12
12
|
export { getStepDurationMs } from "./timeline/step-duration.js";
|
|
13
|
-
export { CLICK_DELAY_MS, TYPE_CHAR_DELAY_MS, HOVER_HOLD_MS, DRAG_SETTLE_MS, VIEWPORT_SETTLE_MS, } from "./timing/constants.js";
|
|
13
|
+
export { CLICK_DELAY_MS, TYPE_CHAR_DELAY_MS, HOVER_HOLD_MS, DRAG_SETTLE_MS, CAMERA_TRANSITION_MS, VIEWPORT_SETTLE_MS, } from "./timing/constants.js";
|
|
14
14
|
export { findScrollParent, scrollTargetIntoView, scrollTargetIntoViewInstant, } from "./dom/scroll.js";
|
|
15
15
|
export { CURSOR_TARGET_ATTRIBUTE, SCROLL_TARGET_ATTRIBUTE, HOVER_STATE_ATTRIBUTE, DRAG_STATE_ATTRIBUTE, cursorTargetSelector, scrollTargetSelector, } from "./targeting/data-attributes.js";
|
|
16
16
|
export { SCENAR_EMBED_SOURCE, SCENAR_EMBED_PROTOCOL_VERSION, frameEmbedEvent, frameEmbedCommand, parseEmbedCommand, parseEmbedEvent, } from "./embed/protocol.js";
|
package/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAIA,YAAY,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AACxD,YAAY,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAC3D,YAAY,EACV,UAAU,EACV,UAAU,EACV,0BAA0B,GAC3B,MAAM,2BAA2B,CAAC;AAGnC,YAAY,EAAE,cAAc,EAAE,iBAAiB,EAAE,MAAM,sBAAsB,CAAC;AAG9E,YAAY,EAAE,iBAAiB,EAAE,MAAM,yBAAyB,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAIA,YAAY,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AACxD,YAAY,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAC3D,YAAY,EACV,UAAU,EACV,UAAU,EACV,0BAA0B,GAC3B,MAAM,2BAA2B,CAAC;AAGnC,YAAY,EAAE,cAAc,EAAE,iBAAiB,EAAE,MAAM,sBAAsB,CAAC;AAG9E,YAAY,EAAE,iBAAiB,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAC;AACrF,OAAO,EACL,2BAA2B,EAC3B,uBAAuB,EACvB,UAAU,EACV,4BAA4B,GAC7B,MAAM,yBAAyB,CAAC;AAGjC,YAAY,EAAE,QAAQ,EAAE,MAAM,8BAA8B,CAAC;AAC7D,OAAO,EAAE,qBAAqB,EAAE,MAAM,8BAA8B,CAAC;AAGrE,YAAY,EAAE,YAAY,EAAE,MAAM,qCAAqC,CAAC;AACxE,OAAO,EAAE,mBAAmB,EAAE,MAAM,qCAAqC,CAAC;AAC1E,OAAO,EAAE,kBAAkB,EAAE,MAAM,2BAA2B,CAAC;AAC/D,OAAO,EAAE,iBAAiB,EAAE,MAAM,6BAA6B,CAAC;AAGhE,OAAO,EACL,cAAc,EACd,kBAAkB,EAClB,aAAa,EACb,cAAc,EACd,oBAAoB,EACpB,kBAAkB,GACnB,MAAM,uBAAuB,CAAC;AAG/B,OAAO,EACL,gBAAgB,EAChB,oBAAoB,EACpB,2BAA2B,GAC5B,MAAM,iBAAiB,CAAC;AAGzB,OAAO,EACL,uBAAuB,EACvB,uBAAuB,EACvB,qBAAqB,EACrB,oBAAoB,EACpB,oBAAoB,EACpB,oBAAoB,GACrB,MAAM,gCAAgC,CAAC;AAGxC,OAAO,EACL,mBAAmB,EACnB,6BAA6B,EAC7B,eAAe,EACf,iBAAiB,EACjB,iBAAiB,EACjB,eAAe,GAChB,MAAM,qBAAqB,CAAC;AAC7B,YAAY,EACV,gBAAgB,EAChB,kBAAkB,EAClB,uBAAuB,EACvB,yBAAyB,GAC1B,MAAM,qBAAqB,CAAC;AAG7B,OAAO,EAAE,yBAAyB,EAAE,MAAM,4BAA4B,CAAC;AACvE,YAAY,EACV,yBAAyB,EACzB,qBAAqB,EACrB,sBAAsB,GACvB,MAAM,4BAA4B,CAAC"}
|
package/index.js
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
// @scenar/core — public API
|
|
2
2
|
// Pure TypeScript types, timing, and utilities for scenario playback.
|
|
3
|
-
export { VIEWPORT_TRANSFORM_IDENTITY } from "./viewport/transform.js";
|
|
3
|
+
export { VIEWPORT_TRANSFORM_IDENTITY, VIEWPORT_CAMERA_AT_REST, cameraEase, interpolateViewportTransform, } from "./viewport/transform.js";
|
|
4
4
|
export { computeCursorPosition } from "./cursor/compute-position.js";
|
|
5
5
|
export { computeStepTimeline } from "./timeline/compute-step-timeline.js";
|
|
6
6
|
export { deriveStepFromTime } from "./timeline/derive-step.js";
|
|
7
7
|
export { getStepDurationMs } from "./timeline/step-duration.js";
|
|
8
8
|
// Timing constants
|
|
9
|
-
export { CLICK_DELAY_MS, TYPE_CHAR_DELAY_MS, HOVER_HOLD_MS, DRAG_SETTLE_MS, VIEWPORT_SETTLE_MS, } from "./timing/constants.js";
|
|
9
|
+
export { CLICK_DELAY_MS, TYPE_CHAR_DELAY_MS, HOVER_HOLD_MS, DRAG_SETTLE_MS, CAMERA_TRANSITION_MS, VIEWPORT_SETTLE_MS, } from "./timing/constants.js";
|
|
10
10
|
// DOM scroll utilities
|
|
11
11
|
export { findScrollParent, scrollTargetIntoView, scrollTargetIntoViewInstant, } from "./dom/scroll.js";
|
|
12
12
|
// Data-attribute targeting contract
|
package/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,4BAA4B;AAC5B,sEAAsE;AAgBtE,OAAO,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,4BAA4B;AAC5B,sEAAsE;AAgBtE,OAAO,EACL,2BAA2B,EAC3B,uBAAuB,EACvB,UAAU,EACV,4BAA4B,GAC7B,MAAM,yBAAyB,CAAC;AAIjC,OAAO,EAAE,qBAAqB,EAAE,MAAM,8BAA8B,CAAC;AAIrE,OAAO,EAAE,mBAAmB,EAAE,MAAM,qCAAqC,CAAC;AAC1E,OAAO,EAAE,kBAAkB,EAAE,MAAM,2BAA2B,CAAC;AAC/D,OAAO,EAAE,iBAAiB,EAAE,MAAM,6BAA6B,CAAC;AAEhE,mBAAmB;AACnB,OAAO,EACL,cAAc,EACd,kBAAkB,EAClB,aAAa,EACb,cAAc,EACd,oBAAoB,EACpB,kBAAkB,GACnB,MAAM,uBAAuB,CAAC;AAE/B,uBAAuB;AACvB,OAAO,EACL,gBAAgB,EAChB,oBAAoB,EACpB,2BAA2B,GAC5B,MAAM,iBAAiB,CAAC;AAEzB,oCAAoC;AACpC,OAAO,EACL,uBAAuB,EACvB,uBAAuB,EACvB,qBAAqB,EACrB,oBAAoB,EACpB,oBAAoB,EACpB,oBAAoB,GACrB,MAAM,gCAAgC,CAAC;AAExC,0EAA0E;AAC1E,OAAO,EACL,mBAAmB,EACnB,6BAA6B,EAC7B,eAAe,EACf,iBAAiB,EACjB,iBAAiB,EACjB,eAAe,GAChB,MAAM,qBAAqB,CAAC;AAQ7B,uEAAuE;AACvE,OAAO,EAAE,yBAAyB,EAAE,MAAM,4BAA4B,CAAC"}
|
package/package.json
CHANGED
|
@@ -101,5 +101,15 @@ export interface UseStepInteractionsOptions<T> {
|
|
|
101
101
|
* needed to center the target element and calls this callback.
|
|
102
102
|
*/
|
|
103
103
|
setViewportTransform?: (transform: ViewportTransform) => void;
|
|
104
|
+
/**
|
|
105
|
+
* The camera's content element (`ViewportTransformLayer`'s `contentRef`).
|
|
106
|
+
* `viewport_transition` target math measures against it so canonical
|
|
107
|
+
* coordinates stay correct at any camera state. Optional — effects fall
|
|
108
|
+
* back to `containerRef`, which is only exact while the camera is at
|
|
109
|
+
* identity.
|
|
110
|
+
*/
|
|
111
|
+
cameraRef?: {
|
|
112
|
+
current: HTMLElement | null;
|
|
113
|
+
};
|
|
104
114
|
}
|
|
105
115
|
//# sourceMappingURL=step-action.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"step-action.d.ts","sourceRoot":"","sources":["../../src/scenario/step-action.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,uBAAuB,CAAC;AAC/D,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAC;AAClE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAE/C;;;;;GAKG;AACH,MAAM,MAAM,UAAU,GAClB,WAAW,GACX,YAAY,GACZ,cAAc,GACd,OAAO,GACP,MAAM,GACN,OAAO,GACP,MAAM,GACN,qBAAqB,CAAC;AAE1B,gDAAgD;AAChD,MAAM,WAAW,UAAU;IACzB;;;;;;;OAOG;IACH,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,mBAAmB;IACnB,QAAQ,CAAC,IAAI,EAAE,UAAU,CAAC;IAC1B;;;;;OAKG;IACH,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;IACzB;;;OAGG;IACH,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAC;IAC7B,wEAAwE;IACxE,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC;IACvB;;;OAGG;IACH,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;IAC5B;;;;OAIG;IACH,QAAQ,CAAC,aAAa,CAAC,EAAE,MAAM,CAAC;IAChC;;;;OAIG;IACH,QAAQ,CAAC,YAAY,CAAC,EAAE,MAAM,CAAC;IAC/B;;;;OAIG;IACH,QAAQ,CAAC,aAAa,CAAC,EAAE,OAAO,CAAC;CAClC;AAED,sDAAsD;AACtD,MAAM,WAAW,0BAA0B,CAAC,CAAC;IAC3C,qDAAqD;IACrD,SAAS,EAAE,MAAM,CAAC;IAClB,8CAA8C;IAC9C,iBAAiB,EAAE,iBAAiB,GAAG,SAAS,CAAC;IACjD,qCAAqC;IACrC,YAAY,EAAE;QAAE,OAAO,EAAE,WAAW,GAAG,IAAI,CAAA;KAAE,CAAC;IAC9C,qDAAqD;IACrD,eAAe,EAAE,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,KAAK,IAAI,CAAC;IACtD;;;;OAIG;IACH,KAAK,EAAE,SAAS,YAAY,CAAC,CAAC,CAAC,EAAE,CAAC;IAClC;;;;OAIG;IACH,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB;;;;OAIG;IACH,aAAa,CAAC,EAAE,CAAC,IAAI,EAAE,OAAO,KAAK,IAAI,CAAC;IACxC;;;;OAIG;IACH,WAAW,CAAC,EAAE,CAAC,QAAQ,EAAE,OAAO,KAAK,IAAI,CAAC;IAC1C;;;;OAIG;IACH,oBAAoB,CAAC,EAAE,CAAC,SAAS,EAAE,iBAAiB,KAAK,IAAI,CAAC;
|
|
1
|
+
{"version":3,"file":"step-action.d.ts","sourceRoot":"","sources":["../../src/scenario/step-action.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,uBAAuB,CAAC;AAC/D,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAC;AAClE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAE/C;;;;;GAKG;AACH,MAAM,MAAM,UAAU,GAClB,WAAW,GACX,YAAY,GACZ,cAAc,GACd,OAAO,GACP,MAAM,GACN,OAAO,GACP,MAAM,GACN,qBAAqB,CAAC;AAE1B,gDAAgD;AAChD,MAAM,WAAW,UAAU;IACzB;;;;;;;OAOG;IACH,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,mBAAmB;IACnB,QAAQ,CAAC,IAAI,EAAE,UAAU,CAAC;IAC1B;;;;;OAKG;IACH,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;IACzB;;;OAGG;IACH,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAC;IAC7B,wEAAwE;IACxE,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC;IACvB;;;OAGG;IACH,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;IAC5B;;;;OAIG;IACH,QAAQ,CAAC,aAAa,CAAC,EAAE,MAAM,CAAC;IAChC;;;;OAIG;IACH,QAAQ,CAAC,YAAY,CAAC,EAAE,MAAM,CAAC;IAC/B;;;;OAIG;IACH,QAAQ,CAAC,aAAa,CAAC,EAAE,OAAO,CAAC;CAClC;AAED,sDAAsD;AACtD,MAAM,WAAW,0BAA0B,CAAC,CAAC;IAC3C,qDAAqD;IACrD,SAAS,EAAE,MAAM,CAAC;IAClB,8CAA8C;IAC9C,iBAAiB,EAAE,iBAAiB,GAAG,SAAS,CAAC;IACjD,qCAAqC;IACrC,YAAY,EAAE;QAAE,OAAO,EAAE,WAAW,GAAG,IAAI,CAAA;KAAE,CAAC;IAC9C,qDAAqD;IACrD,eAAe,EAAE,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,KAAK,IAAI,CAAC;IACtD;;;;OAIG;IACH,KAAK,EAAE,SAAS,YAAY,CAAC,CAAC,CAAC,EAAE,CAAC;IAClC;;;;OAIG;IACH,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB;;;;OAIG;IACH,aAAa,CAAC,EAAE,CAAC,IAAI,EAAE,OAAO,KAAK,IAAI,CAAC;IACxC;;;;OAIG;IACH,WAAW,CAAC,EAAE,CAAC,QAAQ,EAAE,OAAO,KAAK,IAAI,CAAC;IAC1C;;;;OAIG;IACH,oBAAoB,CAAC,EAAE,CAAC,SAAS,EAAE,iBAAiB,KAAK,IAAI,CAAC;IAC9D;;;;;;OAMG;IACH,SAAS,CAAC,EAAE;QAAE,OAAO,EAAE,WAAW,GAAG,IAAI,CAAA;KAAE,CAAC;CAC7C"}
|
package/src/index.ts
CHANGED
|
@@ -14,8 +14,13 @@ export type {
|
|
|
14
14
|
export type { NarrationEntry, NarrationManifest } from "./narration/types.js";
|
|
15
15
|
|
|
16
16
|
// Viewport types
|
|
17
|
-
export type { ViewportTransform } from "./viewport/transform.js";
|
|
18
|
-
export {
|
|
17
|
+
export type { ViewportTransform, ViewportCameraMove } from "./viewport/transform.js";
|
|
18
|
+
export {
|
|
19
|
+
VIEWPORT_TRANSFORM_IDENTITY,
|
|
20
|
+
VIEWPORT_CAMERA_AT_REST,
|
|
21
|
+
cameraEase,
|
|
22
|
+
interpolateViewportTransform,
|
|
23
|
+
} from "./viewport/transform.js";
|
|
19
24
|
|
|
20
25
|
// Cursor types
|
|
21
26
|
export type { Position } from "./cursor/compute-position.js";
|
|
@@ -33,6 +38,7 @@ export {
|
|
|
33
38
|
TYPE_CHAR_DELAY_MS,
|
|
34
39
|
HOVER_HOLD_MS,
|
|
35
40
|
DRAG_SETTLE_MS,
|
|
41
|
+
CAMERA_TRANSITION_MS,
|
|
36
42
|
VIEWPORT_SETTLE_MS,
|
|
37
43
|
} from "./timing/constants.js";
|
|
38
44
|
|
|
@@ -110,4 +110,12 @@ export interface UseStepInteractionsOptions<T> {
|
|
|
110
110
|
* needed to center the target element and calls this callback.
|
|
111
111
|
*/
|
|
112
112
|
setViewportTransform?: (transform: ViewportTransform) => void;
|
|
113
|
+
/**
|
|
114
|
+
* The camera's content element (`ViewportTransformLayer`'s `contentRef`).
|
|
115
|
+
* `viewport_transition` target math measures against it so canonical
|
|
116
|
+
* coordinates stay correct at any camera state. Optional — effects fall
|
|
117
|
+
* back to `containerRef`, which is only exact while the camera is at
|
|
118
|
+
* identity.
|
|
119
|
+
*/
|
|
120
|
+
cameraRef?: { current: HTMLElement | null };
|
|
113
121
|
}
|
package/src/timing/constants.ts
CHANGED
|
@@ -11,9 +11,9 @@
|
|
|
11
11
|
* Milliseconds after a cursor target is set before the cursor is
|
|
12
12
|
* considered "arrived" and the click ripple appears.
|
|
13
13
|
*
|
|
14
|
-
*
|
|
15
|
-
*
|
|
16
|
-
*
|
|
14
|
+
* The Cursor's distance-adaptive travel clamps its longest move to
|
|
15
|
+
* settle inside this window (see `travelTransition` in
|
|
16
|
+
* `@scenar/react`'s Cursor) — the ripple must never fire mid-flight.
|
|
17
17
|
*/
|
|
18
18
|
export const CLICK_DELAY_MS = 450;
|
|
19
19
|
|
|
@@ -48,12 +48,19 @@ export const HOVER_HOLD_MS = 1500;
|
|
|
48
48
|
export const DRAG_SETTLE_MS = 200;
|
|
49
49
|
|
|
50
50
|
/**
|
|
51
|
-
*
|
|
52
|
-
* after a zoom or pan change.
|
|
51
|
+
* Duration (ms) of a camera move — a `viewport_transition` zoom or pan.
|
|
53
52
|
*
|
|
54
|
-
*
|
|
55
|
-
*
|
|
56
|
-
*
|
|
57
|
-
*
|
|
53
|
+
* This is a fixed tween, not a spring: browser playback eases toward the
|
|
54
|
+
* target with `cameraEase` over exactly this duration, and video export
|
|
55
|
+
* computes the same curve per frame via `interpolateViewportTransform`,
|
|
56
|
+
* so both paths agree at every instant.
|
|
58
57
|
*/
|
|
59
|
-
export const
|
|
58
|
+
export const CAMERA_TRANSITION_MS = 600;
|
|
59
|
+
|
|
60
|
+
/**
|
|
61
|
+
* Milliseconds after a `viewport_transition` fires before the camera is
|
|
62
|
+
* at rest. Equal to {@link CAMERA_TRANSITION_MS} (the move is a fixed
|
|
63
|
+
* tween). Used for dev-mode warnings when a subsequent cursor action is
|
|
64
|
+
* scheduled too close to a viewport transition.
|
|
65
|
+
*/
|
|
66
|
+
export const VIEWPORT_SETTLE_MS = CAMERA_TRANSITION_MS;
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
import { describe, expect, it } from "vitest";
|
|
2
|
+
import {
|
|
3
|
+
VIEWPORT_CAMERA_AT_REST,
|
|
4
|
+
VIEWPORT_TRANSFORM_IDENTITY,
|
|
5
|
+
cameraEase,
|
|
6
|
+
interpolateViewportTransform,
|
|
7
|
+
} from "./transform.js";
|
|
8
|
+
|
|
9
|
+
describe("cameraEase", () => {
|
|
10
|
+
it("starts at 0 and ends at 1", () => {
|
|
11
|
+
expect(cameraEase(0)).toBe(0);
|
|
12
|
+
expect(cameraEase(1)).toBe(1);
|
|
13
|
+
});
|
|
14
|
+
|
|
15
|
+
it("clamps out-of-range progress", () => {
|
|
16
|
+
expect(cameraEase(-0.5)).toBe(0);
|
|
17
|
+
expect(cameraEase(1.5)).toBe(1);
|
|
18
|
+
});
|
|
19
|
+
|
|
20
|
+
it("is monotonically non-decreasing", () => {
|
|
21
|
+
let prev = cameraEase(0);
|
|
22
|
+
for (let i = 1; i <= 100; i++) {
|
|
23
|
+
const next = cameraEase(i / 100);
|
|
24
|
+
expect(next).toBeGreaterThanOrEqual(prev);
|
|
25
|
+
prev = next;
|
|
26
|
+
}
|
|
27
|
+
});
|
|
28
|
+
|
|
29
|
+
it("decelerates: covers more than half the distance in the first quarter", () => {
|
|
30
|
+
// The defining property of a camera move — commit fast, glide to rest.
|
|
31
|
+
expect(cameraEase(0.25)).toBeGreaterThan(0.5);
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
it("never overshoots", () => {
|
|
35
|
+
for (let i = 0; i <= 100; i++) {
|
|
36
|
+
expect(cameraEase(i / 100)).toBeLessThanOrEqual(1);
|
|
37
|
+
}
|
|
38
|
+
});
|
|
39
|
+
});
|
|
40
|
+
|
|
41
|
+
describe("interpolateViewportTransform", () => {
|
|
42
|
+
const from = { scale: 1, x: 0, y: 0 };
|
|
43
|
+
const to = { scale: 1.5, x: -200, y: -120 };
|
|
44
|
+
|
|
45
|
+
it("returns `from` at progress 0", () => {
|
|
46
|
+
expect(interpolateViewportTransform(from, to, 0)).toEqual(from);
|
|
47
|
+
});
|
|
48
|
+
|
|
49
|
+
it("returns `to` at progress 1", () => {
|
|
50
|
+
expect(interpolateViewportTransform(from, to, 1)).toEqual(to);
|
|
51
|
+
});
|
|
52
|
+
|
|
53
|
+
it("clamps beyond-end progress to `to` (the camera rests after the move)", () => {
|
|
54
|
+
expect(interpolateViewportTransform(from, to, 42)).toEqual(to);
|
|
55
|
+
});
|
|
56
|
+
|
|
57
|
+
it("applies the ease to every component consistently", () => {
|
|
58
|
+
const eased = cameraEase(0.5);
|
|
59
|
+
const mid = interpolateViewportTransform(from, to, 0.5);
|
|
60
|
+
expect(mid.scale).toBeCloseTo(1 + 0.5 * eased, 10);
|
|
61
|
+
expect(mid.x).toBeCloseTo(-200 * eased, 10);
|
|
62
|
+
expect(mid.y).toBeCloseTo(-120 * eased, 10);
|
|
63
|
+
});
|
|
64
|
+
|
|
65
|
+
it("is an identity when from and to are equal", () => {
|
|
66
|
+
for (const p of [0, 0.3, 0.7, 1]) {
|
|
67
|
+
expect(
|
|
68
|
+
interpolateViewportTransform(
|
|
69
|
+
VIEWPORT_TRANSFORM_IDENTITY,
|
|
70
|
+
VIEWPORT_TRANSFORM_IDENTITY,
|
|
71
|
+
p,
|
|
72
|
+
),
|
|
73
|
+
).toEqual(VIEWPORT_TRANSFORM_IDENTITY);
|
|
74
|
+
}
|
|
75
|
+
});
|
|
76
|
+
|
|
77
|
+
it("VIEWPORT_CAMERA_AT_REST holds the identity at any time", () => {
|
|
78
|
+
const { from: f, to: t } = VIEWPORT_CAMERA_AT_REST;
|
|
79
|
+
expect(interpolateViewportTransform(f, t, 0.5)).toEqual(VIEWPORT_TRANSFORM_IDENTITY);
|
|
80
|
+
});
|
|
81
|
+
});
|
|
@@ -11,3 +11,65 @@ export const VIEWPORT_TRANSFORM_IDENTITY: Readonly<ViewportTransform> = {
|
|
|
11
11
|
x: 0,
|
|
12
12
|
y: 0,
|
|
13
13
|
};
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* A camera move: the transform it started `from`, the transform it is
|
|
17
|
+
* heading `to`, and the timeline instant the move fired at.
|
|
18
|
+
*
|
|
19
|
+
* Both output paths derive the same visual from this one value: browser
|
|
20
|
+
* playback tweens toward `to` with {@link cameraEase} over
|
|
21
|
+
* {@link CAMERA_TRANSITION_MS}; video export computes the exact
|
|
22
|
+
* intermediate transform for any frame with
|
|
23
|
+
* {@link interpolateViewportTransform} — same curve, same duration,
|
|
24
|
+
* zero drift.
|
|
25
|
+
*/
|
|
26
|
+
export interface ViewportCameraMove {
|
|
27
|
+
readonly from: ViewportTransform;
|
|
28
|
+
readonly to: ViewportTransform;
|
|
29
|
+
/** Timeline time (ms) the move fired at, in the scenario's time domain. */
|
|
30
|
+
readonly atTimeMs: number;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
/** A camera resting at the identity transform since t=0. */
|
|
34
|
+
export const VIEWPORT_CAMERA_AT_REST: Readonly<ViewportCameraMove> = {
|
|
35
|
+
from: VIEWPORT_TRANSFORM_IDENTITY,
|
|
36
|
+
to: VIEWPORT_TRANSFORM_IDENTITY,
|
|
37
|
+
atTimeMs: 0,
|
|
38
|
+
};
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* The camera's deceleration curve (ease-out quint).
|
|
42
|
+
*
|
|
43
|
+
* A camera move commits fast and glides to a stop — it must never
|
|
44
|
+
* overshoot, because overshoot reads as a zoom *effect* rather than a
|
|
45
|
+
* camera. Referentially transparent so browser playback (as a tween
|
|
46
|
+
* easing) and video export (via {@link interpolateViewportTransform})
|
|
47
|
+
* share one implementation.
|
|
48
|
+
*/
|
|
49
|
+
export function cameraEase(progress: number): number {
|
|
50
|
+
const t = Math.min(1, Math.max(0, progress));
|
|
51
|
+
return 1 - (1 - t) ** 5;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* The intermediate transform of a camera move at linear progress
|
|
56
|
+
* `progress` (0..1, clamped). Applies {@link cameraEase}, then
|
|
57
|
+
* interpolates each component. Pure — the video-export path calls this
|
|
58
|
+
* per frame.
|
|
59
|
+
*/
|
|
60
|
+
export function interpolateViewportTransform(
|
|
61
|
+
from: ViewportTransform,
|
|
62
|
+
to: ViewportTransform,
|
|
63
|
+
progress: number,
|
|
64
|
+
): ViewportTransform {
|
|
65
|
+
// Exact endpoint, not `from + (to - from) * 1`: floating point does not
|
|
66
|
+
// guarantee that expression returns `to`, and a camera at rest must land
|
|
67
|
+
// on the authored transform bit-for-bit (consumers compare identity).
|
|
68
|
+
if (progress >= 1) return { ...to };
|
|
69
|
+
const eased = cameraEase(progress);
|
|
70
|
+
return {
|
|
71
|
+
scale: from.scale + (to.scale - from.scale) * eased,
|
|
72
|
+
x: from.x + (to.x - from.x) * eased,
|
|
73
|
+
y: from.y + (to.y - from.y) * eased,
|
|
74
|
+
};
|
|
75
|
+
}
|
package/timing/constants.d.ts
CHANGED
|
@@ -10,9 +10,9 @@
|
|
|
10
10
|
* Milliseconds after a cursor target is set before the cursor is
|
|
11
11
|
* considered "arrived" and the click ripple appears.
|
|
12
12
|
*
|
|
13
|
-
*
|
|
14
|
-
*
|
|
15
|
-
*
|
|
13
|
+
* The Cursor's distance-adaptive travel clamps its longest move to
|
|
14
|
+
* settle inside this window (see `travelTransition` in
|
|
15
|
+
* `@scenar/react`'s Cursor) — the ripple must never fire mid-flight.
|
|
16
16
|
*/
|
|
17
17
|
export declare const CLICK_DELAY_MS = 450;
|
|
18
18
|
/**
|
|
@@ -43,13 +43,19 @@ export declare const HOVER_HOLD_MS = 1500;
|
|
|
43
43
|
*/
|
|
44
44
|
export declare const DRAG_SETTLE_MS = 200;
|
|
45
45
|
/**
|
|
46
|
-
*
|
|
47
|
-
* after a zoom or pan change.
|
|
46
|
+
* Duration (ms) of a camera move — a `viewport_transition` zoom or pan.
|
|
48
47
|
*
|
|
49
|
-
*
|
|
50
|
-
*
|
|
51
|
-
*
|
|
52
|
-
*
|
|
48
|
+
* This is a fixed tween, not a spring: browser playback eases toward the
|
|
49
|
+
* target with `cameraEase` over exactly this duration, and video export
|
|
50
|
+
* computes the same curve per frame via `interpolateViewportTransform`,
|
|
51
|
+
* so both paths agree at every instant.
|
|
53
52
|
*/
|
|
54
|
-
export declare const
|
|
53
|
+
export declare const CAMERA_TRANSITION_MS = 600;
|
|
54
|
+
/**
|
|
55
|
+
* Milliseconds after a `viewport_transition` fires before the camera is
|
|
56
|
+
* at rest. Equal to {@link CAMERA_TRANSITION_MS} (the move is a fixed
|
|
57
|
+
* tween). Used for dev-mode warnings when a subsequent cursor action is
|
|
58
|
+
* scheduled too close to a viewport transition.
|
|
59
|
+
*/
|
|
60
|
+
export declare const VIEWPORT_SETTLE_MS = 600;
|
|
55
61
|
//# sourceMappingURL=constants.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../../src/timing/constants.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH;;;;;;;GAOG;AACH,eAAO,MAAM,cAAc,MAAM,CAAC;AAElC;;;;;;;GAOG;AACH,eAAO,MAAM,kBAAkB,KAAK,CAAC;AAErC;;;;;;;;GAQG;AACH,eAAO,MAAM,aAAa,OAAO,CAAC;AAElC;;;;;;GAMG;AACH,eAAO,MAAM,cAAc,MAAM,CAAC;AAElC
|
|
1
|
+
{"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../../src/timing/constants.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH;;;;;;;GAOG;AACH,eAAO,MAAM,cAAc,MAAM,CAAC;AAElC;;;;;;;GAOG;AACH,eAAO,MAAM,kBAAkB,KAAK,CAAC;AAErC;;;;;;;;GAQG;AACH,eAAO,MAAM,aAAa,OAAO,CAAC;AAElC;;;;;;GAMG;AACH,eAAO,MAAM,cAAc,MAAM,CAAC;AAElC;;;;;;;GAOG;AACH,eAAO,MAAM,oBAAoB,MAAM,CAAC;AAExC;;;;;GAKG;AACH,eAAO,MAAM,kBAAkB,MAAuB,CAAC"}
|
package/timing/constants.js
CHANGED
|
@@ -10,9 +10,9 @@
|
|
|
10
10
|
* Milliseconds after a cursor target is set before the cursor is
|
|
11
11
|
* considered "arrived" and the click ripple appears.
|
|
12
12
|
*
|
|
13
|
-
*
|
|
14
|
-
*
|
|
15
|
-
*
|
|
13
|
+
* The Cursor's distance-adaptive travel clamps its longest move to
|
|
14
|
+
* settle inside this window (see `travelTransition` in
|
|
15
|
+
* `@scenar/react`'s Cursor) — the ripple must never fire mid-flight.
|
|
16
16
|
*/
|
|
17
17
|
export const CLICK_DELAY_MS = 450;
|
|
18
18
|
/**
|
|
@@ -43,13 +43,19 @@ export const HOVER_HOLD_MS = 1500;
|
|
|
43
43
|
*/
|
|
44
44
|
export const DRAG_SETTLE_MS = 200;
|
|
45
45
|
/**
|
|
46
|
-
*
|
|
47
|
-
* after a zoom or pan change.
|
|
46
|
+
* Duration (ms) of a camera move — a `viewport_transition` zoom or pan.
|
|
48
47
|
*
|
|
49
|
-
*
|
|
50
|
-
*
|
|
51
|
-
*
|
|
52
|
-
*
|
|
48
|
+
* This is a fixed tween, not a spring: browser playback eases toward the
|
|
49
|
+
* target with `cameraEase` over exactly this duration, and video export
|
|
50
|
+
* computes the same curve per frame via `interpolateViewportTransform`,
|
|
51
|
+
* so both paths agree at every instant.
|
|
53
52
|
*/
|
|
54
|
-
export const
|
|
53
|
+
export const CAMERA_TRANSITION_MS = 600;
|
|
54
|
+
/**
|
|
55
|
+
* Milliseconds after a `viewport_transition` fires before the camera is
|
|
56
|
+
* at rest. Equal to {@link CAMERA_TRANSITION_MS} (the move is a fixed
|
|
57
|
+
* tween). Used for dev-mode warnings when a subsequent cursor action is
|
|
58
|
+
* scheduled too close to a viewport transition.
|
|
59
|
+
*/
|
|
60
|
+
export const VIEWPORT_SETTLE_MS = CAMERA_TRANSITION_MS;
|
|
55
61
|
//# sourceMappingURL=constants.js.map
|
package/timing/constants.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"constants.js","sourceRoot":"","sources":["../../src/timing/constants.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH;;;;;;;GAOG;AACH,MAAM,CAAC,MAAM,cAAc,GAAG,GAAG,CAAC;AAElC;;;;;;;GAOG;AACH,MAAM,CAAC,MAAM,kBAAkB,GAAG,EAAE,CAAC;AAErC;;;;;;;;GAQG;AACH,MAAM,CAAC,MAAM,aAAa,GAAG,IAAI,CAAC;AAElC;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,cAAc,GAAG,GAAG,CAAC;AAElC
|
|
1
|
+
{"version":3,"file":"constants.js","sourceRoot":"","sources":["../../src/timing/constants.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH;;;;;;;GAOG;AACH,MAAM,CAAC,MAAM,cAAc,GAAG,GAAG,CAAC;AAElC;;;;;;;GAOG;AACH,MAAM,CAAC,MAAM,kBAAkB,GAAG,EAAE,CAAC;AAErC;;;;;;;;GAQG;AACH,MAAM,CAAC,MAAM,aAAa,GAAG,IAAI,CAAC;AAElC;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,cAAc,GAAG,GAAG,CAAC;AAElC;;;;;;;GAOG;AACH,MAAM,CAAC,MAAM,oBAAoB,GAAG,GAAG,CAAC;AAExC;;;;;GAKG;AACH,MAAM,CAAC,MAAM,kBAAkB,GAAG,oBAAoB,CAAC"}
|
package/viewport/transform.d.ts
CHANGED
|
@@ -6,4 +6,40 @@ export interface ViewportTransform {
|
|
|
6
6
|
}
|
|
7
7
|
/** The identity transform — no zoom, no translation. */
|
|
8
8
|
export declare const VIEWPORT_TRANSFORM_IDENTITY: Readonly<ViewportTransform>;
|
|
9
|
+
/**
|
|
10
|
+
* A camera move: the transform it started `from`, the transform it is
|
|
11
|
+
* heading `to`, and the timeline instant the move fired at.
|
|
12
|
+
*
|
|
13
|
+
* Both output paths derive the same visual from this one value: browser
|
|
14
|
+
* playback tweens toward `to` with {@link cameraEase} over
|
|
15
|
+
* {@link CAMERA_TRANSITION_MS}; video export computes the exact
|
|
16
|
+
* intermediate transform for any frame with
|
|
17
|
+
* {@link interpolateViewportTransform} — same curve, same duration,
|
|
18
|
+
* zero drift.
|
|
19
|
+
*/
|
|
20
|
+
export interface ViewportCameraMove {
|
|
21
|
+
readonly from: ViewportTransform;
|
|
22
|
+
readonly to: ViewportTransform;
|
|
23
|
+
/** Timeline time (ms) the move fired at, in the scenario's time domain. */
|
|
24
|
+
readonly atTimeMs: number;
|
|
25
|
+
}
|
|
26
|
+
/** A camera resting at the identity transform since t=0. */
|
|
27
|
+
export declare const VIEWPORT_CAMERA_AT_REST: Readonly<ViewportCameraMove>;
|
|
28
|
+
/**
|
|
29
|
+
* The camera's deceleration curve (ease-out quint).
|
|
30
|
+
*
|
|
31
|
+
* A camera move commits fast and glides to a stop — it must never
|
|
32
|
+
* overshoot, because overshoot reads as a zoom *effect* rather than a
|
|
33
|
+
* camera. Referentially transparent so browser playback (as a tween
|
|
34
|
+
* easing) and video export (via {@link interpolateViewportTransform})
|
|
35
|
+
* share one implementation.
|
|
36
|
+
*/
|
|
37
|
+
export declare function cameraEase(progress: number): number;
|
|
38
|
+
/**
|
|
39
|
+
* The intermediate transform of a camera move at linear progress
|
|
40
|
+
* `progress` (0..1, clamped). Applies {@link cameraEase}, then
|
|
41
|
+
* interpolates each component. Pure — the video-export path calls this
|
|
42
|
+
* per frame.
|
|
43
|
+
*/
|
|
44
|
+
export declare function interpolateViewportTransform(from: ViewportTransform, to: ViewportTransform, progress: number): ViewportTransform;
|
|
9
45
|
//# sourceMappingURL=transform.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"transform.d.ts","sourceRoot":"","sources":["../../src/viewport/transform.ts"],"names":[],"mappings":"AAAA,8DAA8D;AAC9D,MAAM,WAAW,iBAAiB;IAChC,KAAK,EAAE,MAAM,CAAC;IACd,CAAC,EAAE,MAAM,CAAC;IACV,CAAC,EAAE,MAAM,CAAC;CACX;AAED,wDAAwD;AACxD,eAAO,MAAM,2BAA2B,EAAE,QAAQ,CAAC,iBAAiB,CAInE,CAAC"}
|
|
1
|
+
{"version":3,"file":"transform.d.ts","sourceRoot":"","sources":["../../src/viewport/transform.ts"],"names":[],"mappings":"AAAA,8DAA8D;AAC9D,MAAM,WAAW,iBAAiB;IAChC,KAAK,EAAE,MAAM,CAAC;IACd,CAAC,EAAE,MAAM,CAAC;IACV,CAAC,EAAE,MAAM,CAAC;CACX;AAED,wDAAwD;AACxD,eAAO,MAAM,2BAA2B,EAAE,QAAQ,CAAC,iBAAiB,CAInE,CAAC;AAEF;;;;;;;;;;GAUG;AACH,MAAM,WAAW,kBAAkB;IACjC,QAAQ,CAAC,IAAI,EAAE,iBAAiB,CAAC;IACjC,QAAQ,CAAC,EAAE,EAAE,iBAAiB,CAAC;IAC/B,2EAA2E;IAC3E,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;CAC3B;AAED,4DAA4D;AAC5D,eAAO,MAAM,uBAAuB,EAAE,QAAQ,CAAC,kBAAkB,CAIhE,CAAC;AAEF;;;;;;;;GAQG;AACH,wBAAgB,UAAU,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAGnD;AAED;;;;;GAKG;AACH,wBAAgB,4BAA4B,CAC1C,IAAI,EAAE,iBAAiB,EACvB,EAAE,EAAE,iBAAiB,EACrB,QAAQ,EAAE,MAAM,GACf,iBAAiB,CAWnB"}
|
package/viewport/transform.js
CHANGED
|
@@ -4,4 +4,42 @@ export const VIEWPORT_TRANSFORM_IDENTITY = {
|
|
|
4
4
|
x: 0,
|
|
5
5
|
y: 0,
|
|
6
6
|
};
|
|
7
|
+
/** A camera resting at the identity transform since t=0. */
|
|
8
|
+
export const VIEWPORT_CAMERA_AT_REST = {
|
|
9
|
+
from: VIEWPORT_TRANSFORM_IDENTITY,
|
|
10
|
+
to: VIEWPORT_TRANSFORM_IDENTITY,
|
|
11
|
+
atTimeMs: 0,
|
|
12
|
+
};
|
|
13
|
+
/**
|
|
14
|
+
* The camera's deceleration curve (ease-out quint).
|
|
15
|
+
*
|
|
16
|
+
* A camera move commits fast and glides to a stop — it must never
|
|
17
|
+
* overshoot, because overshoot reads as a zoom *effect* rather than a
|
|
18
|
+
* camera. Referentially transparent so browser playback (as a tween
|
|
19
|
+
* easing) and video export (via {@link interpolateViewportTransform})
|
|
20
|
+
* share one implementation.
|
|
21
|
+
*/
|
|
22
|
+
export function cameraEase(progress) {
|
|
23
|
+
const t = Math.min(1, Math.max(0, progress));
|
|
24
|
+
return 1 - (1 - t) ** 5;
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* The intermediate transform of a camera move at linear progress
|
|
28
|
+
* `progress` (0..1, clamped). Applies {@link cameraEase}, then
|
|
29
|
+
* interpolates each component. Pure — the video-export path calls this
|
|
30
|
+
* per frame.
|
|
31
|
+
*/
|
|
32
|
+
export function interpolateViewportTransform(from, to, progress) {
|
|
33
|
+
// Exact endpoint, not `from + (to - from) * 1`: floating point does not
|
|
34
|
+
// guarantee that expression returns `to`, and a camera at rest must land
|
|
35
|
+
// on the authored transform bit-for-bit (consumers compare identity).
|
|
36
|
+
if (progress >= 1)
|
|
37
|
+
return { ...to };
|
|
38
|
+
const eased = cameraEase(progress);
|
|
39
|
+
return {
|
|
40
|
+
scale: from.scale + (to.scale - from.scale) * eased,
|
|
41
|
+
x: from.x + (to.x - from.x) * eased,
|
|
42
|
+
y: from.y + (to.y - from.y) * eased,
|
|
43
|
+
};
|
|
44
|
+
}
|
|
7
45
|
//# sourceMappingURL=transform.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"transform.js","sourceRoot":"","sources":["../../src/viewport/transform.ts"],"names":[],"mappings":"AAOA,wDAAwD;AACxD,MAAM,CAAC,MAAM,2BAA2B,GAAgC;IACtE,KAAK,EAAE,CAAC;IACR,CAAC,EAAE,CAAC;IACJ,CAAC,EAAE,CAAC;CACL,CAAC"}
|
|
1
|
+
{"version":3,"file":"transform.js","sourceRoot":"","sources":["../../src/viewport/transform.ts"],"names":[],"mappings":"AAOA,wDAAwD;AACxD,MAAM,CAAC,MAAM,2BAA2B,GAAgC;IACtE,KAAK,EAAE,CAAC;IACR,CAAC,EAAE,CAAC;IACJ,CAAC,EAAE,CAAC;CACL,CAAC;AAoBF,4DAA4D;AAC5D,MAAM,CAAC,MAAM,uBAAuB,GAAiC;IACnE,IAAI,EAAE,2BAA2B;IACjC,EAAE,EAAE,2BAA2B;IAC/B,QAAQ,EAAE,CAAC;CACZ,CAAC;AAEF;;;;;;;;GAQG;AACH,MAAM,UAAU,UAAU,CAAC,QAAgB;IACzC,MAAM,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,QAAQ,CAAC,CAAC,CAAC;IAC7C,OAAO,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC;AAC1B,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,4BAA4B,CAC1C,IAAuB,EACvB,EAAqB,EACrB,QAAgB;IAEhB,wEAAwE;IACxE,yEAAyE;IACzE,sEAAsE;IACtE,IAAI,QAAQ,IAAI,CAAC;QAAE,OAAO,EAAE,GAAG,EAAE,EAAE,CAAC;IACpC,MAAM,KAAK,GAAG,UAAU,CAAC,QAAQ,CAAC,CAAC;IACnC,OAAO;QACL,KAAK,EAAE,IAAI,CAAC,KAAK,GAAG,CAAC,EAAE,CAAC,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,KAAK;QACnD,CAAC,EAAE,IAAI,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC,CAAC,GAAG,KAAK;QACnC,CAAC,EAAE,IAAI,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC,CAAC,GAAG,KAAK;KACpC,CAAC;AACJ,CAAC"}
|