@foldkit/ui 0.163.0 → 0.164.0-canary.c9c641bf8179

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 (79) hide show
  1. package/dist/anchor/anchor.d.ts +33 -7
  2. package/dist/anchor/anchor.d.ts.map +1 -1
  3. package/dist/anchor/anchor.js +92 -14
  4. package/dist/anchor/public.d.ts +1 -1
  5. package/dist/anchor/public.d.ts.map +1 -1
  6. package/dist/anchor/public.js +1 -1
  7. package/dist/animation/index.d.ts +3 -0
  8. package/dist/animation/index.d.ts.map +1 -1
  9. package/dist/animation/schema.d.ts +13 -4
  10. package/dist/animation/schema.d.ts.map +1 -1
  11. package/dist/animation/schema.js +8 -4
  12. package/dist/animation/update.d.ts +15 -5
  13. package/dist/animation/update.d.ts.map +1 -1
  14. package/dist/animation/update.js +56 -28
  15. package/dist/combobox/multi.d.ts +5 -0
  16. package/dist/combobox/multi.d.ts.map +1 -1
  17. package/dist/combobox/shared.d.ts +19 -7
  18. package/dist/combobox/shared.d.ts.map +1 -1
  19. package/dist/combobox/shared.js +13 -13
  20. package/dist/combobox/single.d.ts +5 -0
  21. package/dist/combobox/single.d.ts.map +1 -1
  22. package/dist/datePicker/index.d.ts +13 -2
  23. package/dist/datePicker/index.d.ts.map +1 -1
  24. package/dist/dialog/index.d.ts +13 -2
  25. package/dist/dialog/index.d.ts.map +1 -1
  26. package/dist/dialog/index.js +22 -8
  27. package/dist/index.d.ts +2 -0
  28. package/dist/index.d.ts.map +1 -1
  29. package/dist/index.js +2 -0
  30. package/dist/internal/accessibleName.d.ts +9 -0
  31. package/dist/internal/accessibleName.d.ts.map +1 -0
  32. package/dist/internal/accessibleName.js +12 -0
  33. package/dist/internal/range.d.ts +7 -0
  34. package/dist/internal/range.d.ts.map +1 -0
  35. package/dist/internal/range.js +12 -0
  36. package/dist/listbox/multi.d.ts +5 -0
  37. package/dist/listbox/multi.d.ts.map +1 -1
  38. package/dist/listbox/shared.d.ts +15 -4
  39. package/dist/listbox/shared.d.ts.map +1 -1
  40. package/dist/listbox/shared.js +12 -11
  41. package/dist/listbox/single.d.ts +5 -0
  42. package/dist/listbox/single.d.ts.map +1 -1
  43. package/dist/menu/index.d.ts +16 -4
  44. package/dist/menu/index.d.ts.map +1 -1
  45. package/dist/menu/index.js +12 -11
  46. package/dist/meter/index.d.ts +26 -0
  47. package/dist/meter/index.d.ts.map +1 -0
  48. package/dist/meter/index.js +67 -0
  49. package/dist/meter/public.d.ts +3 -0
  50. package/dist/meter/public.d.ts.map +1 -0
  51. package/dist/meter/public.js +1 -0
  52. package/dist/popover/index.d.ts +20 -4
  53. package/dist/popover/index.d.ts.map +1 -1
  54. package/dist/popover/index.js +8 -8
  55. package/dist/progress/index.d.ts +24 -0
  56. package/dist/progress/index.d.ts.map +1 -0
  57. package/dist/progress/index.js +85 -0
  58. package/dist/progress/public.d.ts +3 -0
  59. package/dist/progress/public.d.ts.map +1 -0
  60. package/dist/progress/public.js +1 -0
  61. package/dist/slider/index.d.ts +61 -28
  62. package/dist/slider/index.d.ts.map +1 -1
  63. package/dist/slider/index.js +157 -81
  64. package/dist/slider/public.d.ts +1 -1
  65. package/dist/slider/public.d.ts.map +1 -1
  66. package/dist/slider/public.js +1 -1
  67. package/dist/test/apps/disabledButton.d.ts +14 -6
  68. package/dist/test/apps/disabledButton.d.ts.map +1 -1
  69. package/dist/toast/index.d.ts +89 -44
  70. package/dist/toast/index.d.ts.map +1 -1
  71. package/dist/toast/schema.d.ts +15 -4
  72. package/dist/toast/schema.d.ts.map +1 -1
  73. package/dist/toast/test.d.ts +6 -0
  74. package/dist/toast/test.d.ts.map +1 -1
  75. package/dist/toast/test.js +36 -2
  76. package/dist/toast/update.d.ts +42 -2
  77. package/dist/toast/update.d.ts.map +1 -1
  78. package/dist/tooltip/tooltip.d.ts +7 -7
  79. package/package.json +9 -9
@@ -6,17 +6,20 @@ import { defineTaggedUnion } from 'foldkit/schema';
6
6
  import { modifyFields } from 'foldkit/struct';
7
7
  import { defineView } from 'foldkit/submodel';
8
8
  import * as Subscription from 'foldkit/subscription';
9
- import { attributeSelector } from '../internal/selectors.js';
9
+ import { accessibleNameAttributes } from '../internal/accessibleName.js';
10
+ import { clamp, fractionOfValue, percentageFromFraction, } from '../internal/range.js';
11
+ import { attributeSelector, idSelector } from '../internal/selectors.js';
12
+ export { fractionOfValue } from '../internal/range.js';
10
13
  // MODEL
11
14
  const DragState = defineTaggedUnion({
12
15
  Idle: {},
13
16
  Dragging: { originValue: Schema.Number },
14
17
  });
15
- /** Schema for the slider component's private interaction state. The current
18
+ /** Schema for the Slider's private interaction state. The current
16
19
  * value is owned by the parent and passed in via `ViewInputs.value`, so it is
17
- * not stored here. `min`/`max`/`step` are configuration the drag subscription
18
- * reads to map pointer positions into values. `dragState` tracks the active
19
- * drag phase and captures the pre-drag value so Escape can restore it. */
20
+ * not stored here. `min`, `max`, and `step` configure how the drag Subscription
21
+ * maps pointer positions into values. `dragState` tracks the active drag phase
22
+ * and captures the pre-drag value so Escape can restore it. */
20
23
  export const Model = Schema.Struct({
21
24
  id: Schema.String,
22
25
  min: Schema.Number,
@@ -25,7 +28,7 @@ export const Model = Schema.Struct({
25
28
  dragState: DragState,
26
29
  });
27
30
  // MESSAGE
28
- /** Union of all messages the slider component can produce. */
31
+ /** Union of all Messages the Slider can produce. */
29
32
  export const Message = defineMessageUnion({
30
33
  PressedThumb: { originValue: Schema.Number },
31
34
  PressedPointer: {
@@ -48,11 +51,11 @@ export const Message = defineMessageUnion({
48
51
  },
49
52
  });
50
53
  // OUT MESSAGE
51
- /** Union of all out-messages the slider component can emit to its parent. */
54
+ /** Union of all OutMessages the Slider can emit to its parent. */
52
55
  export const OutMessage = defineMessageUnion({
53
56
  ChangedValue: { value: Schema.Number },
54
57
  });
55
- /** Creates an initial slider model from a config. The value lives in the
58
+ /** Creates an initial Slider Model from a config. The value lives in the
56
59
  * parent Model; initialize it there and snap it with {@link snapAndClamp}. */
57
60
  export const init = (config) => (__foldkitBrandViewResult(({
58
61
  id: config.id,
@@ -73,25 +76,13 @@ const roundToStepPrecision = (value, step) => {
73
76
  const decimals = stepDecimals(step);
74
77
  return __foldkitBrandViewResult((Number(value.toFixed(decimals))), "@foldkit/ui/slider/index.js#roundToStepPrecision");
75
78
  };
76
- const clamp = (value, min, max) => __foldkitBrandViewResult((Math.min(Math.max(value, min), max)), "@foldkit/ui/slider/index.js#clamp");
77
79
  /** Snaps a value to the nearest step and clamps it into `[min, max]`. Exported
78
- * so a parent can conform the value it owns to the slider's range, for example
80
+ * so a parent can conform the value it owns to the Slider's range, for example
79
81
  * when seeding the initial value or reacting to an external update. */
80
82
  export const snapAndClamp = (value, min, max, step) => {
81
83
  const snapped = min + Math.round((value - min) / step) * step;
82
84
  return __foldkitBrandViewResult((roundToStepPrecision(clamp(snapped, min, max), step)), "@foldkit/ui/slider/index.js#snapAndClamp");
83
85
  };
84
- /** Computes the fraction (0–1) of a value between min and max. Returns 0 when
85
- * the range has zero width. */
86
- export const fractionOfValue = (value, min, max) => {
87
- const range = max - min;
88
- if (range <= 0) {
89
- return __foldkitBrandViewResult((0), "@foldkit/ui/slider/index.js#fractionOfValue");
90
- }
91
- else {
92
- return __foldkitBrandViewResult((clamp((value - min) / range, 0, 1)), "@foldkit/ui/slider/index.js#fractionOfValue");
93
- }
94
- };
95
86
  const PAGE_STEP_MULTIPLIER = 10;
96
87
  const nextValueForDirection = (value, min, max, step, direction) => __foldkitBrandViewResult((Match.value(direction).pipe(Match.withReturnType(), Match.when('StepIncrement', () => __foldkitBrandViewResult((snapAndClamp(value + step, min, max, step)), "@foldkit/ui/slider/index.js#anonymous")), Match.when('StepDecrement', () => __foldkitBrandViewResult((snapAndClamp(value - step, min, max, step)), "@foldkit/ui/slider/index.js#anonymous~2")), Match.when('PageIncrement', () => __foldkitBrandViewResult((snapAndClamp(value + step * PAGE_STEP_MULTIPLIER, min, max, step)), "@foldkit/ui/slider/index.js#anonymous~3")), Match.when('PageDecrement', () => __foldkitBrandViewResult((snapAndClamp(value - step * PAGE_STEP_MULTIPLIER, min, max, step)), "@foldkit/ui/slider/index.js#anonymous~4")), Match.when('Min', () => __foldkitBrandViewResult((min), "@foldkit/ui/slider/index.js#anonymous~5")), Match.when('Max', () => __foldkitBrandViewResult((max), "@foldkit/ui/slider/index.js#anonymous~6")), Match.exhaustive)), "@foldkit/ui/slider/index.js#nextValueForDirection");
97
88
  const withUpdateReturn = Match.withReturnType();
@@ -155,21 +146,64 @@ export const reflectRange = Function.dual(2, (model, range) => __foldkitBrandVie
155
146
  // SUBSCRIPTION
156
147
  const DragActivity = Schema.Literals(['Idle', 'Active']);
157
148
  const dragActivityFromModel = (model) => __foldkitBrandViewResult((Match.value(model.dragState).pipe(Match.withReturnType(), Match.tag('Dragging', () => __foldkitBrandViewResult(('Active'), "@foldkit/ui/slider/index.js#anonymous~18")), Match.orElse(() => __foldkitBrandViewResult(('Idle'), "@foldkit/ui/slider/index.js#anonymous~19")))), "@foldkit/ui/slider/index.js#dragActivityFromModel");
158
- const trackElement = (id, root) => __foldkitBrandViewResult((Option.fromNullishOr(root.querySelector(attributeSelector('data-slider-track-id', id)))), "@foldkit/ui/slider/index.js#trackElement");
159
- const valueFromClientX = (clientX, trackElement_, min, max) => {
160
- const rect = trackElement_.getBoundingClientRect();
161
- if (rect.width === 0) {
162
- return __foldkitBrandViewResult((min), "@foldkit/ui/slider/index.js#valueFromClientX");
149
+ const findTrackElement = (sliderId, trackRoot) => __foldkitBrandViewResult((Option.fromNullishOr(trackRoot.querySelector(attributeSelector('data-slider-track-id', sliderId)))), "@foldkit/ui/slider/index.js#findTrackElement");
150
+ const isVerticalTrack = (track) => __foldkitBrandViewResult((track.getAttribute('data-orientation') === 'vertical' ||
151
+ track.hasAttribute('data-vertical')), "@foldkit/ui/slider/index.js#isVerticalTrack");
152
+ const isEdgeAlignedTrack = (track) => __foldkitBrandViewResult((track.getAttribute('data-thumb-alignment') === 'edge'), "@foldkit/ui/slider/index.js#isEdgeAlignedTrack");
153
+ const findThumbElementForTrack = (track) => __foldkitBrandViewResult((pipe(track.getAttribute('data-slider-track-id'), Option.fromNullishOr, Option.flatMap(sliderId => {
154
+ const thumbSelector = idSelector(`${sliderId}-thumb`);
155
+ const maybeSliderRoot = Option.fromNullishOr(track.closest(attributeSelector('data-slider-id', sliderId)));
156
+ return __foldkitBrandViewResult((Option.match(maybeSliderRoot, {
157
+ onNone: () => __foldkitBrandViewResult((Option.fromNullishOr(track.ownerDocument.getElementById(`${sliderId}-thumb`))), "@foldkit/ui/slider/index.js#onNone~2"),
158
+ onSome: sliderRoot => __foldkitBrandViewResult((Option.fromNullishOr(sliderRoot.querySelector(thumbSelector))), "@foldkit/ui/slider/index.js#onSome~2"),
159
+ })), "@foldkit/ui/slider/index.js#anonymous~20");
160
+ }))), "@foldkit/ui/slider/index.js#findThumbElementForTrack");
161
+ const edgeInsetForTrack = (track) => {
162
+ if (!isEdgeAlignedTrack(track)) {
163
+ return __foldkitBrandViewResult((0), "@foldkit/ui/slider/index.js#edgeInsetForTrack");
164
+ }
165
+ const maybeThumb = findThumbElementForTrack(track);
166
+ if (Option.isNone(maybeThumb)) {
167
+ return __foldkitBrandViewResult((0), "@foldkit/ui/slider/index.js#edgeInsetForTrack");
168
+ }
169
+ const thumbRect = maybeThumb.value.getBoundingClientRect();
170
+ const thumbSize = isVerticalTrack(track) ? thumbRect.height : thumbRect.width;
171
+ return __foldkitBrandViewResult((thumbSize / 2), "@foldkit/ui/slider/index.js#edgeInsetForTrack");
172
+ };
173
+ const fractionOfPointerPosition = (pointerPosition, trackSize, edgeInset) => {
174
+ const travelSize = trackSize - edgeInset * 2;
175
+ if (travelSize <= 0) {
176
+ return __foldkitBrandViewResult((clamp(pointerPosition / trackSize, 0, 1)), "@foldkit/ui/slider/index.js#fractionOfPointerPosition");
163
177
  }
164
178
  else {
165
- const fraction = clamp((clientX - rect.left) / rect.width, 0, 1);
166
- return __foldkitBrandViewResult((min + fraction * (max - min)), "@foldkit/ui/slider/index.js#valueFromClientX");
179
+ return __foldkitBrandViewResult((clamp((pointerPosition - edgeInset) / travelSize, 0, 1)), "@foldkit/ui/slider/index.js#fractionOfPointerPosition");
167
180
  }
168
181
  };
169
- /** Builds slider drag subscriptions, looking up the track
170
- * element through the supplied root resolver. Use this when the slider is
171
- * rendered inside a Shadow DOM. The root is read lazily so consumers can
172
- * resolve it at subscription time. */
182
+ /** Maps a pointer position to a Slider value. Vertical tracks place `min` at
183
+ * the bottom and `max` at the top. Edge-aligned tracks measure the rendered
184
+ * thumb and map the pointer across the same inset range it travels through. */
185
+ export const valueFromPointer = (clientX, clientY, track, min, max) => {
186
+ const trackRect = track.getBoundingClientRect();
187
+ if (isVerticalTrack(track)) {
188
+ if (trackRect.height === 0) {
189
+ return __foldkitBrandViewResult((min), "@foldkit/ui/slider/index.js#valueFromPointer");
190
+ }
191
+ else {
192
+ const fraction = fractionOfPointerPosition(trackRect.bottom - clientY, trackRect.height, edgeInsetForTrack(track));
193
+ return __foldkitBrandViewResult((min + fraction * (max - min)), "@foldkit/ui/slider/index.js#valueFromPointer");
194
+ }
195
+ }
196
+ if (trackRect.width === 0) {
197
+ return __foldkitBrandViewResult((min), "@foldkit/ui/slider/index.js#valueFromPointer");
198
+ }
199
+ else {
200
+ const fraction = fractionOfPointerPosition(clientX - trackRect.left, trackRect.width, edgeInsetForTrack(track));
201
+ return __foldkitBrandViewResult((min + fraction * (max - min)), "@foldkit/ui/slider/index.js#valueFromPointer");
202
+ }
203
+ };
204
+ /** Builds Slider drag Subscriptions that find the track through the supplied
205
+ * root resolver. Use this when the Slider is rendered inside a Shadow DOM.
206
+ * The resolver runs at subscription time. */
173
207
  export const subscriptionsForRoot = (getTrackRoot) => __foldkitBrandViewResult((Subscription.make()(entry => (__foldkitBrandViewResult(({
174
208
  dragPointer: entry({
175
209
  dragActivity: DragActivity,
@@ -184,9 +218,9 @@ export const subscriptionsForRoot = (getTrackRoot) => __foldkitBrandViewResult((
184
218
  max: model.max,
185
219
  }), "@foldkit/ui/slider/index.js#modelToDependencies")),
186
220
  dependenciesToStream: ({ dragActivity, id, min, max }) => {
187
- const pointerEvents = Stream.merge(Stream.fromEventListener(document, 'pointermove').pipe(Stream.mapEffect(event => __foldkitBrandViewResult((Effect.sync(() => __foldkitBrandViewResult((Option.map(trackElement(id, getTrackRoot()), element => __foldkitBrandViewResult((Message.MovedDragPointer({
188
- value: valueFromClientX(event.clientX, element, min, max),
189
- })), "@foldkit/ui/slider/index.js#anonymous~23"))), "@foldkit/ui/slider/index.js#anonymous~22"))), "@foldkit/ui/slider/index.js#anonymous~21")), Stream.filter(Option.isSome), Stream.map(option => __foldkitBrandViewResult((option.value), "@foldkit/ui/slider/index.js#anonymous~24"))), Stream.fromEventListener(document, 'pointerup').pipe(Stream.map(() => __foldkitBrandViewResult((Message.ReleasedDragPointer()), "@foldkit/ui/slider/index.js#anonymous~25"))));
221
+ const pointerEvents = Stream.merge(Stream.fromEventListener(document, 'pointermove').pipe(Stream.mapEffect(event => __foldkitBrandViewResult((Effect.sync(() => __foldkitBrandViewResult((Option.map(findTrackElement(id, getTrackRoot()), track => __foldkitBrandViewResult((Message.MovedDragPointer({
222
+ value: valueFromPointer(event.clientX, event.clientY, track, min, max),
223
+ })), "@foldkit/ui/slider/index.js#anonymous~24"))), "@foldkit/ui/slider/index.js#anonymous~23"))), "@foldkit/ui/slider/index.js#anonymous~22")), Stream.filter(Option.isSome), Stream.map(option => __foldkitBrandViewResult((option.value), "@foldkit/ui/slider/index.js#anonymous~25"))), Stream.fromEventListener(document, 'pointerup').pipe(Stream.map(() => __foldkitBrandViewResult((Message.ReleasedDragPointer()), "@foldkit/ui/slider/index.js#anonymous~26"))));
190
224
  // NOTE: prevents text selection and locks cursor to grabbing while the
191
225
  // user drags the thumb. Matches the approach used in drag-and-drop.
192
226
  const documentDragStyles = Stream.callback(() => __foldkitBrandViewResult((Effect.acquireRelease(Effect.sync(() => {
@@ -195,54 +229,112 @@ export const subscriptionsForRoot = (getTrackRoot) => __foldkitBrandViewResult((
195
229
  const cursorStyle = document.createElement('style');
196
230
  cursorStyle.textContent = '* { cursor: grabbing !important; }';
197
231
  document.head.appendChild(cursorStyle);
198
- return __foldkitBrandViewResult((cursorStyle), "@foldkit/ui/slider/index.js#anonymous~27");
232
+ return __foldkitBrandViewResult((cursorStyle), "@foldkit/ui/slider/index.js#anonymous~28");
199
233
  }), cursorStyle => __foldkitBrandViewResult((Effect.sync(() => {
200
234
  document.documentElement.style.removeProperty('user-select');
201
235
  document.documentElement.style.removeProperty('-webkit-user-select');
202
236
  cursorStyle.remove();
203
- })), "@foldkit/ui/slider/index.js#anonymous~28")).pipe(Effect.flatMap(() => __foldkitBrandViewResult((Effect.never), "@foldkit/ui/slider/index.js#anonymous~30")))), "@foldkit/ui/slider/index.js#anonymous~26"));
204
- return __foldkitBrandViewResult((Stream.when(Stream.merge(pointerEvents, documentDragStyles), Effect.sync(() => __foldkitBrandViewResult((dragActivity === 'Active'), "@foldkit/ui/slider/index.js#anonymous~31")))), "@foldkit/ui/slider/index.js#dependenciesToStream");
237
+ })), "@foldkit/ui/slider/index.js#anonymous~29")).pipe(Effect.flatMap(() => __foldkitBrandViewResult((Effect.never), "@foldkit/ui/slider/index.js#anonymous~31")))), "@foldkit/ui/slider/index.js#anonymous~27"));
238
+ return __foldkitBrandViewResult((Stream.when(Stream.merge(pointerEvents, documentDragStyles), Effect.sync(() => __foldkitBrandViewResult((dragActivity === 'Active'), "@foldkit/ui/slider/index.js#anonymous~32")))), "@foldkit/ui/slider/index.js#dependenciesToStream");
205
239
  },
206
240
  }),
207
241
  dragEscape: entry({ dragActivity: DragActivity }, {
208
242
  modelToDependencies: model => (__foldkitBrandViewResult(({
209
243
  dragActivity: dragActivityFromModel(model),
210
244
  }), "@foldkit/ui/slider/index.js#modelToDependencies~2")),
211
- dependenciesToStream: ({ dragActivity }) => __foldkitBrandViewResult((Stream.when(Stream.fromEventListener(document, 'keydown').pipe(Stream.filter(({ key }) => __foldkitBrandViewResult((key === 'Escape'), "@foldkit/ui/slider/index.js#anonymous~32")), Stream.map(() => __foldkitBrandViewResult((Message.CancelledDrag()), "@foldkit/ui/slider/index.js#anonymous~33"))), Effect.sync(() => __foldkitBrandViewResult((dragActivity === 'Active'), "@foldkit/ui/slider/index.js#anonymous~34")))), "@foldkit/ui/slider/index.js#dependenciesToStream~2"),
245
+ dependenciesToStream: ({ dragActivity }) => __foldkitBrandViewResult((Stream.when(Stream.fromEventListener(document, 'keydown').pipe(Stream.filter(({ key }) => __foldkitBrandViewResult((key === 'Escape'), "@foldkit/ui/slider/index.js#anonymous~33")), Stream.map(() => __foldkitBrandViewResult((Message.CancelledDrag()), "@foldkit/ui/slider/index.js#anonymous~34"))), Effect.sync(() => __foldkitBrandViewResult((dragActivity === 'Active'), "@foldkit/ui/slider/index.js#anonymous~35")))), "@foldkit/ui/slider/index.js#dependenciesToStream~2"),
212
246
  }),
213
- }), "@foldkit/ui/slider/index.js#anonymous~20")))), "@foldkit/ui/slider/index.js#subscriptionsForRoot");
214
- /** Default drag subscriptions, with the track looked up via `document`. */
215
- export const subscriptions = subscriptionsForRoot(() => __foldkitBrandViewResult((document), "@foldkit/ui/slider/index.js#anonymous~35"));
247
+ }), "@foldkit/ui/slider/index.js#anonymous~21")))), "@foldkit/ui/slider/index.js#subscriptionsForRoot");
248
+ /** Default drag Subscriptions, with the track looked up via `document`. */
249
+ export const subscriptions = subscriptionsForRoot(() => __foldkitBrandViewResult((document), "@foldkit/ui/slider/index.js#anonymous~36"));
216
250
  // VIEW
217
251
  const LEFT_MOUSE_BUTTON = 0;
218
252
  const labelId = (id) => __foldkitBrandViewResult((`${id}-label`), "@foldkit/ui/slider/index.js#labelId");
219
- const keyToDirection = (key) => __foldkitBrandViewResult((Match.value(key).pipe(Match.withReturnType(), Match.whenOr('ArrowRight', 'ArrowUp', () => __foldkitBrandViewResult(('StepIncrement'), "@foldkit/ui/slider/index.js#anonymous~36")), Match.whenOr('ArrowLeft', 'ArrowDown', () => __foldkitBrandViewResult(('StepDecrement'), "@foldkit/ui/slider/index.js#anonymous~37")), Match.when('PageUp', () => __foldkitBrandViewResult(('PageIncrement'), "@foldkit/ui/slider/index.js#anonymous~38")), Match.when('PageDown', () => __foldkitBrandViewResult(('PageDecrement'), "@foldkit/ui/slider/index.js#anonymous~39")), Match.when('Home', () => __foldkitBrandViewResult(('Min'), "@foldkit/ui/slider/index.js#anonymous~40")), Match.when('End', () => __foldkitBrandViewResult(('Max'), "@foldkit/ui/slider/index.js#anonymous~41")), Match.option)), "@foldkit/ui/slider/index.js#keyToDirection");
220
- const percentString = (fraction) => __foldkitBrandViewResult((`${Math.round(fraction * 10000) / 100}%`), "@foldkit/ui/slider/index.js#percentString");
253
+ const keyToDirection = (key) => __foldkitBrandViewResult((Match.value(key).pipe(Match.withReturnType(), Match.whenOr('ArrowRight', 'ArrowUp', () => __foldkitBrandViewResult(('StepIncrement'), "@foldkit/ui/slider/index.js#anonymous~37")), Match.whenOr('ArrowLeft', 'ArrowDown', () => __foldkitBrandViewResult(('StepDecrement'), "@foldkit/ui/slider/index.js#anonymous~38")), Match.when('PageUp', () => __foldkitBrandViewResult(('PageIncrement'), "@foldkit/ui/slider/index.js#anonymous~39")), Match.when('PageDown', () => __foldkitBrandViewResult(('PageDecrement'), "@foldkit/ui/slider/index.js#anonymous~40")), Match.when('Home', () => __foldkitBrandViewResult(('Min'), "@foldkit/ui/slider/index.js#anonymous~41")), Match.when('End', () => __foldkitBrandViewResult(('Max'), "@foldkit/ui/slider/index.js#anonymous~42")), Match.option)), "@foldkit/ui/slider/index.js#keyToDirection");
254
+ /** Direction in which the Slider lays out its track and maps pointer input. */
255
+ export const Orientation = Schema.Literals(['Horizontal', 'Vertical']);
256
+ /** Whether the thumb's center or outer edge aligns with the track endpoints. */
257
+ export const ThumbAlignment = Schema.Literals(['Center', 'Edge']);
258
+ const filledTrackStyle = (orientation, thumbAlignment, thumbSize, fraction) => __foldkitBrandViewResult((Match.value({ orientation, thumbAlignment }).pipe(Match.withReturnType(), Match.when({ orientation: 'Vertical', thumbAlignment: 'Center' }, () => (__foldkitBrandViewResult(({
259
+ position: 'absolute',
260
+ bottom: '0',
261
+ left: '0',
262
+ right: '0',
263
+ height: percentageFromFraction(fraction),
264
+ width: '100%',
265
+ 'pointer-events': 'none',
266
+ }), "@foldkit/ui/slider/index.js#anonymous~43"))), Match.when({ orientation: 'Vertical', thumbAlignment: 'Edge' }, () => (__foldkitBrandViewResult(({
267
+ position: 'absolute',
268
+ bottom: '0',
269
+ left: '0',
270
+ right: '0',
271
+ height: `calc((100% - ${thumbSize}) * ${fraction} + ${thumbSize} / 2)`,
272
+ width: '100%',
273
+ 'pointer-events': 'none',
274
+ }), "@foldkit/ui/slider/index.js#anonymous~44"))), Match.when({ orientation: 'Horizontal', thumbAlignment: 'Center' }, () => (__foldkitBrandViewResult(({
275
+ position: 'absolute',
276
+ left: '0',
277
+ top: '0',
278
+ bottom: '0',
279
+ width: percentageFromFraction(fraction),
280
+ 'pointer-events': 'none',
281
+ }), "@foldkit/ui/slider/index.js#anonymous~45"))), Match.when({ orientation: 'Horizontal', thumbAlignment: 'Edge' }, () => (__foldkitBrandViewResult(({
282
+ position: 'absolute',
283
+ left: '0',
284
+ top: '0',
285
+ bottom: '0',
286
+ width: `calc((100% - ${thumbSize}) * ${fraction} + ${thumbSize} / 2)`,
287
+ 'pointer-events': 'none',
288
+ }), "@foldkit/ui/slider/index.js#anonymous~46"))), Match.exhaustive)), "@foldkit/ui/slider/index.js#filledTrackStyle");
289
+ const thumbStyle = (orientation, thumbAlignment, thumbSize, fraction) => __foldkitBrandViewResult((Match.value({ orientation, thumbAlignment }).pipe(Match.withReturnType(), Match.when({ orientation: 'Vertical', thumbAlignment: 'Center' }, () => (__foldkitBrandViewResult(({
290
+ position: 'absolute',
291
+ bottom: percentageFromFraction(fraction),
292
+ left: '50%',
293
+ transform: 'translateX(-50%) translateY(50%)',
294
+ 'touch-action': 'none',
295
+ }), "@foldkit/ui/slider/index.js#anonymous~47"))), Match.when({ orientation: 'Vertical', thumbAlignment: 'Edge' }, () => (__foldkitBrandViewResult(({
296
+ position: 'absolute',
297
+ bottom: `calc((100% - ${thumbSize}) * ${fraction})`,
298
+ left: '50%',
299
+ transform: 'translateX(-50%)',
300
+ 'touch-action': 'none',
301
+ }), "@foldkit/ui/slider/index.js#anonymous~48"))), Match.when({ orientation: 'Horizontal', thumbAlignment: 'Center' }, () => (__foldkitBrandViewResult(({
302
+ position: 'absolute',
303
+ left: percentageFromFraction(fraction),
304
+ transform: 'translateX(-50%)',
305
+ 'touch-action': 'none',
306
+ }), "@foldkit/ui/slider/index.js#anonymous~49"))), Match.when({ orientation: 'Horizontal', thumbAlignment: 'Edge' }, () => (__foldkitBrandViewResult(({
307
+ position: 'absolute',
308
+ left: `calc((100% - ${thumbSize}) * ${fraction})`,
309
+ 'touch-action': 'none',
310
+ }), "@foldkit/ui/slider/index.js#anonymous~50"))), Match.exhaustive)), "@foldkit/ui/slider/index.js#thumbStyle");
221
311
  /** Renders an accessible slider by building ARIA attribute groups and
222
312
  * delegating layout to the consumer's `toView` callback. Follows the
223
313
  * WAI-ARIA slider pattern: role="slider" on the thumb, aria-valuemin /
224
314
  * aria-valuemax / aria-valuenow, keyboard navigation by step / page / home /
225
- * end. Pointer drag is handled by the component's drag subscriptions. */
315
+ * end. Pointer drag is handled by the Slider's drag Subscriptions. */
226
316
  export const view = defineView((model, viewInputs, h) => {
227
- const { value, formatValue, isDisabled = false, isReadOnly = false, name, getTrackRoot = () => __foldkitBrandViewResult((document), "@foldkit/ui/slider/index.js#anonymous~43"), } = viewInputs;
317
+ const { value, formatValue, isDisabled = false, isReadOnly = false, name, orientation = 'Horizontal', thumbAlignment = 'Center', thumbSize = '0.75rem', getTrackRoot = () => __foldkitBrandViewResult((document), "@foldkit/ui/slider/index.js#anonymous~52"), } = viewInputs;
228
318
  const { id, min, max } = model;
229
319
  const isDragging = model.dragState._tag === 'Dragging';
230
320
  const fraction = fractionOfValue(value, min, max);
231
- const handleKeyDown = (key) => __foldkitBrandViewResult((Option.map(keyToDirection(key), direction => __foldkitBrandViewResult((Message.PressedKeyboardNavigation({ direction, value })), "@foldkit/ui/slider/index.js#anonymous~44"))), "@foldkit/ui/slider/index.js#handleKeyDown");
232
- const pointerAtClientX = (clientX) => __foldkitBrandViewResult((Option.map(trackElement(id, getTrackRoot()), element => __foldkitBrandViewResult((Message.PressedPointer({
233
- value: valueFromClientX(clientX, element, min, max),
321
+ const handleKeyDown = (key) => __foldkitBrandViewResult((Option.map(keyToDirection(key), direction => __foldkitBrandViewResult((Message.PressedKeyboardNavigation({ direction, value })), "@foldkit/ui/slider/index.js#anonymous~53"))), "@foldkit/ui/slider/index.js#handleKeyDown");
322
+ const pressedPointerMessageAt = (clientX, clientY) => __foldkitBrandViewResult((Option.map(findTrackElement(id, getTrackRoot()), track => __foldkitBrandViewResult((Message.PressedPointer({
323
+ value: valueFromPointer(clientX, clientY, track, min, max),
234
324
  originValue: value,
235
- })), "@foldkit/ui/slider/index.js#anonymous~45"))), "@foldkit/ui/slider/index.js#pointerAtClientX");
236
- const trackPointerHandler = (_pointerType, button, _screenX, _screenY, _timeStamp, clientX) => __foldkitBrandViewResult((pipe(button, Option.liftPredicate(Equal.equals(LEFT_MOUSE_BUTTON)), Option.flatMap(() => __foldkitBrandViewResult((pointerAtClientX(clientX)), "@foldkit/ui/slider/index.js#anonymous~46")))), "@foldkit/ui/slider/index.js#trackPointerHandler");
237
- const thumbPointerHandler = (_pointerType, button) => __foldkitBrandViewResult((pipe(button, Option.liftPredicate(Equal.equals(LEFT_MOUSE_BUTTON)), Option.map(() => __foldkitBrandViewResult((Message.PressedThumb({ originValue: value })), "@foldkit/ui/slider/index.js#anonymous~47")))), "@foldkit/ui/slider/index.js#thumbPointerHandler");
325
+ })), "@foldkit/ui/slider/index.js#anonymous~54"))), "@foldkit/ui/slider/index.js#pressedPointerMessageAt");
326
+ const trackPointerHandler = (_pointerType, button, _screenX, _screenY, _timeStamp, clientX, clientY) => __foldkitBrandViewResult((pipe(button, Option.liftPredicate(Equal.equals(LEFT_MOUSE_BUTTON)), Option.flatMap(() => __foldkitBrandViewResult((pressedPointerMessageAt(clientX, clientY)), "@foldkit/ui/slider/index.js#anonymous~55")))), "@foldkit/ui/slider/index.js#trackPointerHandler");
327
+ const thumbPointerHandler = (_pointerType, button) => __foldkitBrandViewResult((pipe(button, Option.liftPredicate(Equal.equals(LEFT_MOUSE_BUTTON)), Option.map(() => __foldkitBrandViewResult((Message.PressedThumb({ originValue: value })), "@foldkit/ui/slider/index.js#anonymous~56")))), "@foldkit/ui/slider/index.js#thumbPointerHandler");
238
328
  const stateAttributes = [
239
329
  ...(isDragging ? [h.DataAttribute('dragging', '')] : []),
240
330
  ...(isDisabled ? [h.DataAttribute('disabled', '')] : []),
241
331
  ...(isReadOnly ? [h.DataAttribute('readonly', '')] : []),
242
332
  ];
333
+ const orientationAttributeValue = String.toLowerCase(orientation);
243
334
  const rootAttributes = [
244
335
  h.DataAttribute('slider-id', id),
245
- h.DataAttribute('orientation', 'horizontal'),
336
+ h.DataAttribute('orientation', orientationAttributeValue),
337
+ h.DataAttribute(orientationAttributeValue, ''),
246
338
  ...stateAttributes,
247
339
  ];
248
340
  const isInteractive = !isDisabled && !isReadOnly;
@@ -251,33 +343,22 @@ export const view = defineView((model, viewInputs, h) => {
251
343
  : [];
252
344
  const trackAttributes = [
253
345
  h.DataAttribute('slider-track-id', id),
346
+ h.DataAttribute('orientation', orientationAttributeValue),
347
+ h.DataAttribute(orientationAttributeValue, ''),
348
+ h.DataAttribute('thumb-alignment', String.toLowerCase(thumbAlignment)),
254
349
  h.Style({ position: 'relative', 'touch-action': 'none' }),
255
350
  ...stateAttributes,
256
351
  ...trackInteractionAttributes,
257
352
  ];
258
353
  const filledTrackAttributes = [
259
- h.Style({
260
- position: 'absolute',
261
- left: '0',
262
- top: '0',
263
- bottom: '0',
264
- width: percentString(fraction),
265
- 'pointer-events': 'none',
266
- }),
354
+ h.Style(filledTrackStyle(orientation, thumbAlignment, thumbSize, fraction)),
267
355
  ...stateAttributes,
268
356
  ];
269
- const resolveThumbLabel = () => {
270
- if (viewInputs.ariaLabel !== undefined) {
271
- return __foldkitBrandViewResult(([h.AriaLabel(viewInputs.ariaLabel)]), "@foldkit/ui/slider/index.js#resolveThumbLabel");
272
- }
273
- else if (viewInputs.ariaLabelledBy !== undefined) {
274
- return __foldkitBrandViewResult(([h.AriaLabelledBy(viewInputs.ariaLabelledBy)]), "@foldkit/ui/slider/index.js#resolveThumbLabel");
275
- }
276
- else {
277
- return __foldkitBrandViewResult(([h.AriaLabelledBy(labelId(id))]), "@foldkit/ui/slider/index.js#resolveThumbLabel");
278
- }
279
- };
280
- const thumbLabelAttributes = resolveThumbLabel();
357
+ const thumbLabelAttributes = accessibleNameAttributes({
358
+ ariaLabel: viewInputs.ariaLabel,
359
+ ariaLabelledBy: viewInputs.ariaLabelledBy,
360
+ fallbackLabelId: labelId(id),
361
+ }, h);
281
362
  const maybeAriaValuetext = formatValue !== undefined ? [h.AriaValuetext(formatValue(value))] : [];
282
363
  const thumbInteractionAttributes = isInteractive
283
364
  ? [
@@ -289,7 +370,7 @@ export const view = defineView((model, viewInputs, h) => {
289
370
  h.Id(`${id}-thumb`),
290
371
  h.Role('slider'),
291
372
  h.Tabindex(0),
292
- h.AriaOrientation('horizontal'),
373
+ h.AriaOrientation(orientationAttributeValue),
293
374
  h.AriaValuemin(min),
294
375
  h.AriaValuemax(max),
295
376
  h.AriaValuenow(value),
@@ -297,12 +378,7 @@ export const view = defineView((model, viewInputs, h) => {
297
378
  ...thumbLabelAttributes,
298
379
  ...(isDisabled ? [h.AriaDisabled(true)] : []),
299
380
  ...(isReadOnly ? [h.AriaReadonly(true)] : []),
300
- h.Style({
301
- position: 'absolute',
302
- left: percentString(fraction),
303
- transform: 'translateX(-50%)',
304
- 'touch-action': 'none',
305
- }),
381
+ h.Style(thumbStyle(orientation, thumbAlignment, thumbSize, fraction)),
306
382
  ...stateAttributes,
307
383
  ...thumbInteractionAttributes,
308
384
  ];
@@ -317,5 +393,5 @@ export const view = defineView((model, viewInputs, h) => {
317
393
  thumb: childAttributes(thumbAttributes),
318
394
  label: childAttributes(labelAttributes),
319
395
  hiddenInput: childAttributes(hiddenInputAttributes),
320
- })), "@foldkit/ui/slider/index.js#anonymous~42");
396
+ })), "@foldkit/ui/slider/index.js#anonymous~51");
321
397
  });
@@ -1,3 +1,3 @@
1
- export { init, update, reflectRange, view, subscriptions, subscriptionsForRoot, fractionOfValue, snapAndClamp, Model, Message, OutMessage, type PressedThumb, type PressedPointer, type MovedDragPointer, type ReleasedDragPointer, type CancelledDrag, type PressedKeyboardNavigation, } from './index.js';
1
+ export { init, update, reflectRange, view, subscriptions, subscriptionsForRoot, fractionOfValue, snapAndClamp, valueFromPointer, Model, Message, Orientation, OutMessage, ThumbAlignment, type PressedThumb, type PressedPointer, type MovedDragPointer, type ReleasedDragPointer, type CancelledDrag, type PressedKeyboardNavigation, } from './index.js';
2
2
  export type { InitConfig, ViewInputs, SliderAttributes } from './index.js';
3
3
  //# sourceMappingURL=public.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"public.d.ts","sourceRoot":"","sources":["../../src/slider/public.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,IAAI,EACJ,MAAM,EACN,YAAY,EACZ,IAAI,EACJ,aAAa,EACb,oBAAoB,EACpB,eAAe,EACf,YAAY,EACZ,KAAK,EACL,OAAO,EACP,UAAU,EACV,KAAK,YAAY,EACjB,KAAK,cAAc,EACnB,KAAK,gBAAgB,EACrB,KAAK,mBAAmB,EACxB,KAAK,aAAa,EAClB,KAAK,yBAAyB,GAC/B,MAAM,YAAY,CAAA;AAEnB,YAAY,EAAE,UAAU,EAAE,UAAU,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAA"}
1
+ {"version":3,"file":"public.d.ts","sourceRoot":"","sources":["../../src/slider/public.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,IAAI,EACJ,MAAM,EACN,YAAY,EACZ,IAAI,EACJ,aAAa,EACb,oBAAoB,EACpB,eAAe,EACf,YAAY,EACZ,gBAAgB,EAChB,KAAK,EACL,OAAO,EACP,WAAW,EACX,UAAU,EACV,cAAc,EACd,KAAK,YAAY,EACjB,KAAK,cAAc,EACnB,KAAK,gBAAgB,EACrB,KAAK,mBAAmB,EACxB,KAAK,aAAa,EAClB,KAAK,yBAAyB,GAC/B,MAAM,YAAY,CAAA;AAEnB,YAAY,EAAE,UAAU,EAAE,UAAU,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAA"}
@@ -1 +1 @@
1
- export { init, update, reflectRange, view, subscriptions, subscriptionsForRoot, fractionOfValue, snapAndClamp, Model, Message, OutMessage, } from './index.js';
1
+ export { init, update, reflectRange, view, subscriptions, subscriptionsForRoot, fractionOfValue, snapAndClamp, valueFromPointer, Model, Message, Orientation, OutMessage, ThumbAlignment, } from './index.js';
@@ -11,6 +11,7 @@ export declare const Model: Schema.Struct<{
11
11
  readonly id: Schema.String;
12
12
  readonly isShowing: Schema.Boolean;
13
13
  readonly transitionState: Schema.Literals<readonly ["Idle", "EnterStart", "EnterAnimating", "LeaveStart", "LeaveAnimating"]>;
14
+ readonly transitionGeneration: Schema.Number;
14
15
  }>;
15
16
  readonly maybeFocusSelector: Schema.Option<Schema.String>;
16
17
  }>;
@@ -34,8 +35,12 @@ export declare const Message: import("foldkit/message").MessageUnion<{
34
35
  message: import("foldkit/message").MessageUnion<{
35
36
  readonly Showed: {};
36
37
  readonly Hid: {};
37
- readonly CompletedWaitForPaint: {};
38
- readonly EndedAnimation: {};
38
+ readonly CompletedWaitForPaint: {
39
+ generation: Schema.Number;
40
+ };
41
+ readonly EndedAnimation: {
42
+ generation: Schema.Number;
43
+ };
39
44
  }>;
40
45
  };
41
46
  }>;
@@ -54,6 +59,7 @@ export declare const update: (model: Model, message: Message) => Readonly<{
54
59
  readonly id: string;
55
60
  readonly isShowing: boolean;
56
61
  readonly transitionState: "EnterAnimating" | "EnterStart" | "Idle" | "LeaveAnimating" | "LeaveStart";
62
+ readonly transitionGeneration: number;
57
63
  };
58
64
  readonly maybeFocusSelector: Option.Option<string>;
59
65
  };
@@ -65,6 +71,10 @@ export declare const update: (model: Model, message: Message) => Readonly<{
65
71
  } | {
66
72
  readonly _tag: "GotDialogMessage";
67
73
  readonly message: {
74
+ readonly _tag: "RequestedOpen";
75
+ } | {
76
+ readonly _tag: "RequestedClose";
77
+ } | {
68
78
  readonly _tag: "CompletedCloseDialog";
69
79
  } | {
70
80
  readonly _tag: "CompletedReleaseDialogResources";
@@ -76,17 +86,15 @@ export declare const update: (model: Model, message: Message) => Readonly<{
76
86
  readonly _tag: "GotAnimationMessage";
77
87
  readonly message: {
78
88
  readonly _tag: "CompletedWaitForPaint";
89
+ readonly generation: number;
79
90
  } | {
80
91
  readonly _tag: "EndedAnimation";
92
+ readonly generation: number;
81
93
  } | {
82
94
  readonly _tag: "Hid";
83
95
  } | {
84
96
  readonly _tag: "Showed";
85
97
  };
86
- } | {
87
- readonly _tag: "RequestedClose";
88
- } | {
89
- readonly _tag: "RequestedOpen";
90
98
  } | {
91
99
  readonly _tag: "SucceededAcquireResources";
92
100
  } | {
@@ -1 +1 @@
1
- {"version":3,"file":"disabledButton.d.ts","sourceRoot":"","sources":["../../../src/test/apps/disabledButton.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAA;AACvC,OAAO,KAAK,EAAE,IAAI,EAAE,WAAW,EAAE,MAAM,cAAc,CAAA;AAGrD,OAAO,KAAK,MAAM,MAAM,gBAAgB,CAAA;AAMxC,eAAO,MAAM,KAAK;;;;;;;;;;;;;EAGhB,CAAA;AACF,MAAM,MAAM,KAAK,GAAG,OAAO,KAAK,CAAC,IAAI,CAAA;AAIrC,eAAO,MAAM,OAAO;;;;QAGE,OAAO;;;;;;;;;;;;;;;;;;;;EAC3B,CAAA;AACF,MAAM,MAAM,OAAO,GAAG,OAAO,OAAO,CAAC,IAAI,CAAA;AAIzC,eAAO,MAAM,YAAY,EAAE,KAG1B,CAAA;AAoBD,eAAO,MAAM,MAAM,UAAW,KAAK,WAAW,OAAO;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAQjD,CAAA;AAeJ,qCAAqC;AACrC,eAAO,MAAM,IAAI,UAAW,KAAK,KAAK,WAAW,CAAC,OAAO,CAAC,KAAG,IAQ5D,CAAA;AAED,uDAAuD;AACvD,eAAO,MAAM,cAAc,UAAW,KAAK,KAAK,WAAW,CAAC,OAAO,CAAC,KAAG,IAyBtE,CAAA"}
1
+ {"version":3,"file":"disabledButton.d.ts","sourceRoot":"","sources":["../../../src/test/apps/disabledButton.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAA;AACvC,OAAO,KAAK,EAAE,IAAI,EAAE,WAAW,EAAE,MAAM,cAAc,CAAA;AAGrD,OAAO,KAAK,MAAM,MAAM,gBAAgB,CAAA;AAMxC,eAAO,MAAM,KAAK;;;;;;;;;;;;;;EAGhB,CAAA;AACF,MAAM,MAAM,KAAK,GAAG,OAAO,KAAK,CAAC,IAAI,CAAA;AAIrC,eAAO,MAAM,OAAO;;;;QAGE,OAAO;;;;;;;;;;;;;;;;;;;;;;;;EAC3B,CAAA;AACF,MAAM,MAAM,OAAO,GAAG,OAAO,OAAO,CAAC,IAAI,CAAA;AAIzC,eAAO,MAAM,YAAY,EAAE,KAG1B,CAAA;AAoBD,eAAO,MAAM,MAAM,UAAW,KAAK,WAAW,OAAO;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAQjD,CAAA;AAeJ,qCAAqC;AACrC,eAAO,MAAM,IAAI,UAAW,KAAK,KAAK,WAAW,CAAC,OAAO,CAAC,KAAG,IAQ5D,CAAA;AAED,uDAAuD;AACvD,eAAO,MAAM,cAAc,UAAW,KAAK,KAAK,WAAW,CAAC,OAAO,CAAC,KAAG,IAyBtE,CAAA"}