use-scroll-animate 3.6.0 → 3.8.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/CHANGELOG.md +20 -0
- package/README.md +1 -1
- package/dist/chunks/bind-B_CTL6Qn.js +22 -0
- package/dist/chunks/bind-B_CTL6Qn.js.map +1 -0
- package/dist/chunks/bind-Ui43-n2d.cjs +25 -0
- package/dist/chunks/bind-Ui43-n2d.cjs.map +1 -0
- package/dist/components/angular.cjs +67 -0
- package/dist/components/angular.cjs.map +1 -0
- package/dist/components/angular.d.cts +1662 -0
- package/dist/components/angular.d.ts +1662 -0
- package/dist/components/angular.js +61 -0
- package/dist/components/angular.js.map +1 -0
- package/dist/components/solid.cjs +62 -0
- package/dist/components/solid.cjs.map +1 -0
- package/dist/components/solid.d.cts +1693 -0
- package/dist/components/solid.d.ts +1693 -0
- package/dist/components/solid.js +58 -0
- package/dist/components/solid.js.map +1 -0
- package/dist/components/svelte.cjs +59 -0
- package/dist/components/svelte.cjs.map +1 -0
- package/dist/components/svelte.d.cts +1661 -0
- package/dist/components/svelte.d.ts +1661 -0
- package/dist/components/svelte.js +55 -0
- package/dist/components/svelte.js.map +1 -0
- package/docs/components.md +14 -0
- package/docs/frameworks-ssr.md +36 -0
- package/docs/hybrid-apps.md +130 -0
- package/package.json +31 -1
package/CHANGELOG.md
CHANGED
|
@@ -7,6 +7,26 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
7
7
|
|
|
8
8
|
## [Unreleased]
|
|
9
9
|
|
|
10
|
+
## [3.8.0] - 2026-10-07
|
|
11
|
+
|
|
12
|
+
### Added
|
|
13
|
+
- **Svelte** — `use-scroll-animate/components/svelte`: `use:usa={{ props, on }}` action (sets DOM properties, binds `usa:*` events with update / destroy; works in Svelte 3, 4 and 5) and `defineUsa(categories?)` (client-only, SvelteKit-safe).
|
|
14
|
+
- **Solid** — `use-scroll-animate/components/solid`: `use:usa` directive (`refresh()` / `destroy()`), `defineUsa()`, `SolidUsaIntrinsicElements` JSX types; native `prop:` / `on:usa:change` documented.
|
|
15
|
+
- **Angular** — `use-scroll-animate/components/angular`: `usaInitializer(categories?)` for `APP_INITIALIZER`, `defineUsa()`, `usaDetail($event)`; `CUSTOM_ELEMENTS_SCHEMA` + `[prop]` / `(usa:event)` binding documented. No `@angular/*` import.
|
|
16
|
+
- Shared framework-neutral `bindUsa(el, { props, on })` / `usaEventName()` (exported from all three entries).
|
|
17
|
+
- **Docs**: new [docs/hybrid-apps.md](./docs/hybrid-apps.md) — .NET MAUI (`HybridWebView`, `BlazorWebView`), Flutter (`webview_flutter` / `flutter_inappwebview`, `JavaScriptChannel`), Electron (context isolation, preload bridge), Tauri v2 (strict CSP, `invoke`), with native ↔ web event bridges and OS reduced-motion mirroring; `docs/frameworks-ssr.md` gains Svelte, Solid and Angular sections.
|
|
18
|
+
|
|
19
|
+
## [3.7.0] - 2026-10-07
|
|
20
|
+
|
|
21
|
+
### Added
|
|
22
|
+
- **Visual playground** — [`showcase/playground.html`](./showcase/playground.html) (no build, dogfoods `dist/components.js` with a CDN fallback):
|
|
23
|
+
- **Compose**: stack effect layers around a card, button, heading or image — scroll reveal, 3D tilt, magnetic, spring, mask reveal, depth, swipeable, click ripple, shader background, glitch and gradient text — and reorder or remove them.
|
|
24
|
+
- **Tweak**: every attribute has a live control (selects, sliders, toggles); the preview re-renders instantly, with a Replay button.
|
|
25
|
+
- **Export**: HTML (CDN, no build), ES module (per-category imports with the right `define*Components()`), React (JSX via `components/jsx` types) and Vue (`isCustomElement` hint) code, copy to clipboard.
|
|
26
|
+
- **Share**: the composition is encoded in the URL hash (`encodeState()` / `decodeState()`), so a link reproduces it.
|
|
27
|
+
- English / 中文, keyboard accessible controls, honours `prefers-reduced-motion` (shows a notice; effects render their final state).
|
|
28
|
+
- Pure, tested playground core in `showcase/playground-core.js` (`PLAYGROUND_EFFECTS`, `composeMarkup()`, `playgroundSnippets()`); the component gallery links to the playground.
|
|
29
|
+
|
|
10
30
|
## [3.6.0] - 2026-10-07
|
|
11
31
|
|
|
12
32
|
### Added
|
package/README.md
CHANGED
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
|
|
11
11
|
[English](./README.md) | [简体中文](./README_zh.md) | [日本語](./README_ja.md)
|
|
12
12
|
|
|
13
|
-
**[✨ Live showcase — every effect, live, with copy-paste code](https://harrisoncn.github.io/use-scroll-animate/)** · **[🧩 Component gallery](https://harrisoncn.github.io/use-scroll-animate/showcase/components.html)**
|
|
13
|
+
**[✨ Live showcase — every effect, live, with copy-paste code](https://harrisoncn.github.io/use-scroll-animate/)** · **[🧩 Component gallery](https://harrisoncn.github.io/use-scroll-animate/showcase/components.html)** · **[🎛 Playground](https://harrisoncn.github.io/use-scroll-animate/showcase/playground.html)**
|
|
14
14
|
|
|
15
15
|
</div>
|
|
16
16
|
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/** Normalise an event key: `change` → `usa:change`, `usa:change` stays. */
|
|
2
|
+
const usaEventName = (k) => (k.includes(':') ? k : `usa:${k}`);
|
|
3
|
+
/** Bind properties and `usa:*` listeners to an element; returns `{ update, destroy }`. */
|
|
4
|
+
function bindUsa(el, binding = {}) {
|
|
5
|
+
let current = [];
|
|
6
|
+
const apply = (b) => {
|
|
7
|
+
current.forEach(([n, f]) => el.removeEventListener(n, f));
|
|
8
|
+
current = Object.entries(b.on || {}).map(([k, f]) => [usaEventName(k), f]);
|
|
9
|
+
current.forEach(([n, f]) => el.addEventListener(n, f));
|
|
10
|
+
for (const [k, v] of Object.entries(b.props || {}))
|
|
11
|
+
if (el[k] !== v)
|
|
12
|
+
el[k] = v;
|
|
13
|
+
};
|
|
14
|
+
apply(binding);
|
|
15
|
+
return {
|
|
16
|
+
update: apply,
|
|
17
|
+
destroy: () => current.forEach(([n, f]) => el.removeEventListener(n, f)),
|
|
18
|
+
};
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export { bindUsa as b, usaEventName as u };
|
|
22
|
+
//# sourceMappingURL=bind-B_CTL6Qn.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"bind-B_CTL6Qn.js","sources":["../../src/components/frameworks/bind.ts"],"sourcesContent":["/**\n * Framework-neutral binding for `<usa-*>` elements (v3.8): set DOM\n * **properties** and listen to `usa:*` events, with update / destroy — the\n * shape Svelte actions, Solid directives and Angular directives all share.\n */\nexport interface UsaBinding {\n /** DOM properties to set (`checked`, `value`, `open`, `index`…). */\n props?: Record<string, unknown>;\n /** Event handlers by name; `change` is shorthand for `usa:change`. */\n on?: Record<string, (e: CustomEvent) => void>;\n}\n\n/** Normalise an event key: `change` → `usa:change`, `usa:change` stays. */\nexport const usaEventName = (k: string): string => (k.includes(':') ? k : `usa:${k}`);\n\n/** Bind properties and `usa:*` listeners to an element; returns `{ update, destroy }`. */\nexport function bindUsa(el: HTMLElement, binding: UsaBinding = {}): { update(b: UsaBinding): void; destroy(): void } {\n let current: [string, EventListener][] = [];\n const apply = (b: UsaBinding) => {\n current.forEach(([n, f]) => el.removeEventListener(n, f));\n current = Object.entries(b.on || {}).map(([k, f]) => [usaEventName(k), f as unknown as EventListener]);\n current.forEach(([n, f]) => el.addEventListener(n, f));\n for (const [k, v] of Object.entries(b.props || {})) if ((el as any)[k] !== v) (el as any)[k] = v;\n };\n apply(binding);\n return {\n update: apply,\n destroy: () => current.forEach(([n, f]) => el.removeEventListener(n, f)),\n };\n}\n"],"names":[],"mappings":"AAYA;AACO,MAAM,YAAY,GAAG,CAAC,CAAS,MAAc,CAAC,CAAC,QAAQ,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAA,IAAA,EAAO,CAAC,CAAA,CAAE;AAEpF;SACgB,OAAO,CAAC,EAAe,EAAE,UAAsB,EAAE,EAAA;IAC/D,IAAI,OAAO,GAA8B,EAAE;AAC3C,IAAA,MAAM,KAAK,GAAG,CAAC,CAAa,KAAI;QAC9B,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,KAAK,EAAE,CAAC,mBAAmB,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;AACzD,QAAA,OAAO,GAAG,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,KAAK,CAAC,YAAY,CAAC,CAAC,CAAC,EAAE,CAA6B,CAAC,CAAC;QACtG,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,KAAK,EAAE,CAAC,gBAAgB,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;AACtD,QAAA,KAAK,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,KAAK,IAAI,EAAE,CAAC;AAAE,YAAA,IAAK,EAAU,CAAC,CAAC,CAAC,KAAK,CAAC;AAAG,gBAAA,EAAU,CAAC,CAAC,CAAC,GAAG,CAAC;AAClG,IAAA,CAAC;IACD,KAAK,CAAC,OAAO,CAAC;IACd,OAAO;AACL,QAAA,MAAM,EAAE,KAAK;QACb,OAAO,EAAE,MAAM,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,KAAK,EAAE,CAAC,mBAAmB,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;KACzE;AACH;;;;"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
/** Normalise an event key: `change` → `usa:change`, `usa:change` stays. */
|
|
4
|
+
const usaEventName = (k) => (k.includes(':') ? k : `usa:${k}`);
|
|
5
|
+
/** Bind properties and `usa:*` listeners to an element; returns `{ update, destroy }`. */
|
|
6
|
+
function bindUsa(el, binding = {}) {
|
|
7
|
+
let current = [];
|
|
8
|
+
const apply = (b) => {
|
|
9
|
+
current.forEach(([n, f]) => el.removeEventListener(n, f));
|
|
10
|
+
current = Object.entries(b.on || {}).map(([k, f]) => [usaEventName(k), f]);
|
|
11
|
+
current.forEach(([n, f]) => el.addEventListener(n, f));
|
|
12
|
+
for (const [k, v] of Object.entries(b.props || {}))
|
|
13
|
+
if (el[k] !== v)
|
|
14
|
+
el[k] = v;
|
|
15
|
+
};
|
|
16
|
+
apply(binding);
|
|
17
|
+
return {
|
|
18
|
+
update: apply,
|
|
19
|
+
destroy: () => current.forEach(([n, f]) => el.removeEventListener(n, f)),
|
|
20
|
+
};
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
exports.bindUsa = bindUsa;
|
|
24
|
+
exports.usaEventName = usaEventName;
|
|
25
|
+
//# sourceMappingURL=bind-Ui43-n2d.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"bind-Ui43-n2d.cjs","sources":["../../src/components/frameworks/bind.ts"],"sourcesContent":["/**\n * Framework-neutral binding for `<usa-*>` elements (v3.8): set DOM\n * **properties** and listen to `usa:*` events, with update / destroy — the\n * shape Svelte actions, Solid directives and Angular directives all share.\n */\nexport interface UsaBinding {\n /** DOM properties to set (`checked`, `value`, `open`, `index`…). */\n props?: Record<string, unknown>;\n /** Event handlers by name; `change` is shorthand for `usa:change`. */\n on?: Record<string, (e: CustomEvent) => void>;\n}\n\n/** Normalise an event key: `change` → `usa:change`, `usa:change` stays. */\nexport const usaEventName = (k: string): string => (k.includes(':') ? k : `usa:${k}`);\n\n/** Bind properties and `usa:*` listeners to an element; returns `{ update, destroy }`. */\nexport function bindUsa(el: HTMLElement, binding: UsaBinding = {}): { update(b: UsaBinding): void; destroy(): void } {\n let current: [string, EventListener][] = [];\n const apply = (b: UsaBinding) => {\n current.forEach(([n, f]) => el.removeEventListener(n, f));\n current = Object.entries(b.on || {}).map(([k, f]) => [usaEventName(k), f as unknown as EventListener]);\n current.forEach(([n, f]) => el.addEventListener(n, f));\n for (const [k, v] of Object.entries(b.props || {})) if ((el as any)[k] !== v) (el as any)[k] = v;\n };\n apply(binding);\n return {\n update: apply,\n destroy: () => current.forEach(([n, f]) => el.removeEventListener(n, f)),\n };\n}\n"],"names":[],"mappings":";;AAYA;AACO,MAAM,YAAY,GAAG,CAAC,CAAS,MAAc,CAAC,CAAC,QAAQ,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAA,IAAA,EAAO,CAAC,CAAA,CAAE;AAEpF;SACgB,OAAO,CAAC,EAAe,EAAE,UAAsB,EAAE,EAAA;IAC/D,IAAI,OAAO,GAA8B,EAAE;AAC3C,IAAA,MAAM,KAAK,GAAG,CAAC,CAAa,KAAI;QAC9B,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,KAAK,EAAE,CAAC,mBAAmB,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;AACzD,QAAA,OAAO,GAAG,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,KAAK,CAAC,YAAY,CAAC,CAAC,CAAC,EAAE,CAA6B,CAAC,CAAC;QACtG,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,KAAK,EAAE,CAAC,gBAAgB,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;AACtD,QAAA,KAAK,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,KAAK,IAAI,EAAE,CAAC;AAAE,YAAA,IAAK,EAAU,CAAC,CAAC,CAAC,KAAK,CAAC;AAAG,gBAAA,EAAU,CAAC,CAAC,CAAC,GAAG,CAAC;AAClG,IAAA,CAAC;IACD,KAAK,CAAC,OAAO,CAAC;IACd,OAAO;AACL,QAAA,MAAM,EAAE,KAAK;QACb,OAAO,EAAE,MAAM,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,KAAK,EAAE,CAAC,mBAAmB,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;KACzE;AACH;;;;;"}
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var components = require('../components.cjs');
|
|
4
|
+
var bind = require('../chunks/bind-Ui43-n2d.cjs');
|
|
5
|
+
require('./reveal.cjs');
|
|
6
|
+
require('../chunks/base-CXx7jZ-o.cjs');
|
|
7
|
+
require('./text.cjs');
|
|
8
|
+
require('./interaction.cjs');
|
|
9
|
+
require('./feedback.cjs');
|
|
10
|
+
require('./background.cjs');
|
|
11
|
+
require('../chunks/variants-BNIrn4ch.cjs');
|
|
12
|
+
require('./transitions.cjs');
|
|
13
|
+
require('./physics.cjs');
|
|
14
|
+
require('../chunks/spring-2OTnYCzm.cjs');
|
|
15
|
+
require('./cards.cjs');
|
|
16
|
+
require('./click.cjs');
|
|
17
|
+
require('./ui.cjs');
|
|
18
|
+
require('./page.cjs');
|
|
19
|
+
require('./timeline.cjs');
|
|
20
|
+
require('./gesture.cjs');
|
|
21
|
+
require('../chunks/core-IaorbTdu.cjs');
|
|
22
|
+
require('./svg.cjs');
|
|
23
|
+
require('./webgl.cjs');
|
|
24
|
+
require('./depth.cjs');
|
|
25
|
+
require('./layout.cjs');
|
|
26
|
+
require('../chunks/index-tags-wbuPiMR6.cjs');
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* use-scroll-animate/components/angular — Angular integration (v3.8).
|
|
30
|
+
* Angular renders `<usa-*>` tags once the component (or NgModule) allows
|
|
31
|
+
* custom elements with `CUSTOM_ELEMENTS_SCHEMA`; property binding
|
|
32
|
+
* `[checked]="on"` and event binding `(usa:change)="…"` then work as is.
|
|
33
|
+
* This entry is framework-free (no `@angular/*` import):
|
|
34
|
+
*
|
|
35
|
+
* ```ts
|
|
36
|
+
* import { CUSTOM_ELEMENTS_SCHEMA, Component, APP_INITIALIZER } from '@angular/core';
|
|
37
|
+
* import { usaInitializer } from 'use-scroll-animate/components/angular';
|
|
38
|
+
*
|
|
39
|
+
* // app.config.ts
|
|
40
|
+
* providers: [{ provide: APP_INITIALIZER, multi: true, useFactory: usaInitializer(['click', 'ui']) }]
|
|
41
|
+
*
|
|
42
|
+
* @Component({ standalone: true, schemas: [CUSTOM_ELEMENTS_SCHEMA],
|
|
43
|
+
* template: `<usa-toggle [checked]="on" (usa:change)="on = $any($event).detail.checked"></usa-toggle>` })
|
|
44
|
+
* ```
|
|
45
|
+
* `bindUsa(el, { props, on })` is available for directives that bind imperatively.
|
|
46
|
+
*/
|
|
47
|
+
/** `APP_INITIALIZER` factory: registers the elements in the browser (no-op during SSR). */
|
|
48
|
+
function usaInitializer(categories) {
|
|
49
|
+
return () => () => {
|
|
50
|
+
if (typeof window !== 'undefined')
|
|
51
|
+
components.defineComponents(categories);
|
|
52
|
+
};
|
|
53
|
+
}
|
|
54
|
+
/** Register the elements directly (e.g. in `main.ts` before `bootstrapApplication`). */
|
|
55
|
+
function defineUsa(categories) {
|
|
56
|
+
if (typeof window !== 'undefined')
|
|
57
|
+
components.defineComponents(categories);
|
|
58
|
+
}
|
|
59
|
+
/** Read `event.detail` from a `usa:*` event in a template handler: `(usa:change)="on = usaDetail($event).checked"`. */
|
|
60
|
+
const usaDetail = (e) => e.detail;
|
|
61
|
+
|
|
62
|
+
exports.bindUsa = bind.bindUsa;
|
|
63
|
+
exports.usaEventName = bind.usaEventName;
|
|
64
|
+
exports.defineUsa = defineUsa;
|
|
65
|
+
exports.usaDetail = usaDetail;
|
|
66
|
+
exports.usaInitializer = usaInitializer;
|
|
67
|
+
//# sourceMappingURL=angular.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"angular.cjs","sources":["../../src/components/frameworks/angular.ts"],"sourcesContent":["/**\n * use-scroll-animate/components/angular — Angular integration (v3.8).\n * Angular renders `<usa-*>` tags once the component (or NgModule) allows\n * custom elements with `CUSTOM_ELEMENTS_SCHEMA`; property binding\n * `[checked]=\"on\"` and event binding `(usa:change)=\"…\"` then work as is.\n * This entry is framework-free (no `@angular/*` import):\n *\n * ```ts\n * import { CUSTOM_ELEMENTS_SCHEMA, Component, APP_INITIALIZER } from '@angular/core';\n * import { usaInitializer } from 'use-scroll-animate/components/angular';\n *\n * // app.config.ts\n * providers: [{ provide: APP_INITIALIZER, multi: true, useFactory: usaInitializer(['click', 'ui']) }]\n *\n * @Component({ standalone: true, schemas: [CUSTOM_ELEMENTS_SCHEMA],\n * template: `<usa-toggle [checked]=\"on\" (usa:change)=\"on = $any($event).detail.checked\"></usa-toggle>` })\n * ```\n * `bindUsa(el, { props, on })` is available for directives that bind imperatively.\n */\nimport { defineComponents, type ComponentCategory } from '../index';\n\nexport { bindUsa, usaEventName } from './bind';\nexport type { UsaBinding } from './bind';\n\n/** `APP_INITIALIZER` factory: registers the elements in the browser (no-op during SSR). */\nexport function usaInitializer(categories?: ComponentCategory[]): () => () => void {\n return () => () => {\n if (typeof window !== 'undefined') defineComponents(categories);\n };\n}\n\n/** Register the elements directly (e.g. in `main.ts` before `bootstrapApplication`). */\nexport function defineUsa(categories?: ComponentCategory[]): void {\n if (typeof window !== 'undefined') defineComponents(categories);\n}\n\n/** Read `event.detail` from a `usa:*` event in a template handler: `(usa:change)=\"on = usaDetail($event).checked\"`. */\nexport const usaDetail = <T = any>(e: Event): T => (e as CustomEvent<T>).detail;\n"],"names":["defineComponents"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;;;;;;;;;;;;;;;;;;AAkBG;AAMH;AACM,SAAU,cAAc,CAAC,UAAgC,EAAA;AAC7D,IAAA,OAAO,MAAM,MAAK;QAChB,IAAI,OAAO,MAAM,KAAK,WAAW;YAAEA,2BAAgB,CAAC,UAAU,CAAC;AACjE,IAAA,CAAC;AACH;AAEA;AACM,SAAU,SAAS,CAAC,UAAgC,EAAA;IACxD,IAAI,OAAO,MAAM,KAAK,WAAW;QAAEA,2BAAgB,CAAC,UAAU,CAAC;AACjE;AAEA;AACO,MAAM,SAAS,GAAG,CAAU,CAAQ,KAAS,CAAoB,CAAC;;;;;;;;"}
|