char-flow 0.1.2
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/LICENSE +21 -0
- package/README.md +113 -0
- package/dist/element-ohGNSSoB.d.ts +51 -0
- package/dist/element.d.ts +1 -0
- package/dist/element.js +84 -0
- package/dist/element.js.map +1 -0
- package/dist/index.d.ts +12 -0
- package/dist/index.js +84 -0
- package/dist/index.js.map +1 -0
- package/dist/react.d.ts +299 -0
- package/dist/react.js +2 -0
- package/dist/react.js.map +1 -0
- package/package.json +77 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 CharFlow contributors
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
# CharFlow
|
|
2
|
+
|
|
3
|
+
Lightweight animated alphanumeric text for license plates, codes, and flowing paragraphs.
|
|
4
|
+
|
|
5
|
+
Digits and letters roll through their alphabet on change; inserts and deletes slide in and out. Built as a web component with an optional React wrapper.
|
|
6
|
+
|
|
7
|
+
<p align="center">
|
|
8
|
+
<img src="./assets/demo.gif" alt="CharFlow demo: animated text and license plate" width="720" />
|
|
9
|
+
</p>
|
|
10
|
+
|
|
11
|
+
## Install
|
|
12
|
+
|
|
13
|
+
```sh
|
|
14
|
+
npm install char-flow
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
## Web component
|
|
18
|
+
|
|
19
|
+
Import the element entry to register `<char-flow>`:
|
|
20
|
+
|
|
21
|
+
```html
|
|
22
|
+
<script type="module">
|
|
23
|
+
import 'char-flow/element'
|
|
24
|
+
</script>
|
|
25
|
+
|
|
26
|
+
<char-flow value="G-123-BB" preset="plate"></char-flow>
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
Or use the main entry (registers the element and re-exports helpers):
|
|
30
|
+
|
|
31
|
+
```ts
|
|
32
|
+
import 'char-flow'
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
### Attributes
|
|
36
|
+
|
|
37
|
+
| Attribute | Default | Description |
|
|
38
|
+
|---|---|---|
|
|
39
|
+
| `value` | `""` | Text to display |
|
|
40
|
+
| `preset` | `alnum` | `plate` (uppercase, tabular) or `alnum` |
|
|
41
|
+
| `animated` | `true` | Set to `false` to disable motion |
|
|
42
|
+
|
|
43
|
+
Animations respect `prefers-reduced-motion`.
|
|
44
|
+
|
|
45
|
+
### Styling
|
|
46
|
+
|
|
47
|
+
The component uses shadow DOM. Target the host or the exposed `part`:
|
|
48
|
+
|
|
49
|
+
```css
|
|
50
|
+
char-flow.plate {
|
|
51
|
+
font-size: 2.5rem;
|
|
52
|
+
font-weight: 700;
|
|
53
|
+
letter-spacing: 0.06em;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
char-flow::part(root) {
|
|
57
|
+
/* inner shell */
|
|
58
|
+
}
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
Timing can be adjusted from JavaScript:
|
|
62
|
+
|
|
63
|
+
```ts
|
|
64
|
+
const el = document.querySelector('char-flow')
|
|
65
|
+
el.spinTiming = { duration: 520, easing: 'cubic-bezier(0.32, 0.72, 0, 1)' }
|
|
66
|
+
el.slideTiming = { duration: 340 }
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
## React
|
|
70
|
+
|
|
71
|
+
Register the element first, then use the wrapper:
|
|
72
|
+
|
|
73
|
+
```tsx
|
|
74
|
+
import 'char-flow/element'
|
|
75
|
+
import { CharFlow } from 'char-flow/react'
|
|
76
|
+
|
|
77
|
+
export function Plate({ value }: { value: string }) {
|
|
78
|
+
return <CharFlow value={value} preset="plate" className="plate" />
|
|
79
|
+
}
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
React is an optional peer dependency (`>=18`).
|
|
83
|
+
|
|
84
|
+
## Low-level API
|
|
85
|
+
|
|
86
|
+
The main entry also exports diffing and classification utilities:
|
|
87
|
+
|
|
88
|
+
```ts
|
|
89
|
+
import { diff, classify } from 'char-flow'
|
|
90
|
+
|
|
91
|
+
diff('ABC-100', 'ABC-9')
|
|
92
|
+
classify('G')
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
## Demo
|
|
96
|
+
|
|
97
|
+
```sh
|
|
98
|
+
npm run demo
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
Opens a local demo at `http://localhost:3000/demo/`.
|
|
102
|
+
|
|
103
|
+
## Development
|
|
104
|
+
|
|
105
|
+
```sh
|
|
106
|
+
npm install
|
|
107
|
+
npm run build
|
|
108
|
+
npm run typecheck
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
## License
|
|
112
|
+
|
|
113
|
+
MIT
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
type CharKind = 'digit' | 'letter' | 'other';
|
|
2
|
+
type Preset = 'plate' | 'alnum';
|
|
3
|
+
/** How a changed character moves: roll through an alphabet, or a direct swap. */
|
|
4
|
+
type AnimKind = 'wheel-digit' | 'wheel-letter' | 'slide' | 'static';
|
|
5
|
+
interface EffectTiming {
|
|
6
|
+
duration?: number;
|
|
7
|
+
easing?: string;
|
|
8
|
+
delay?: number;
|
|
9
|
+
}
|
|
10
|
+
type DiffOp = {
|
|
11
|
+
type: 'keep';
|
|
12
|
+
index: number;
|
|
13
|
+
char: string;
|
|
14
|
+
prevKey: number;
|
|
15
|
+
region?: 'suffix';
|
|
16
|
+
} | {
|
|
17
|
+
type: 'replace';
|
|
18
|
+
index: number;
|
|
19
|
+
from: string;
|
|
20
|
+
to: string;
|
|
21
|
+
prevKey: number;
|
|
22
|
+
} | {
|
|
23
|
+
type: 'insert';
|
|
24
|
+
index: number;
|
|
25
|
+
char: string;
|
|
26
|
+
};
|
|
27
|
+
|
|
28
|
+
declare const TAG = "char-flow";
|
|
29
|
+
declare class CharFlowElement extends HTMLElement {
|
|
30
|
+
#private;
|
|
31
|
+
static observedAttributes: readonly ["value", "preset", "animated"];
|
|
32
|
+
connectedCallback(): void;
|
|
33
|
+
disconnectedCallback(): void;
|
|
34
|
+
attributeChangedCallback(name: string): void;
|
|
35
|
+
get value(): string;
|
|
36
|
+
set value(v: string);
|
|
37
|
+
get preset(): Preset;
|
|
38
|
+
set preset(v: Preset);
|
|
39
|
+
get animated(): boolean;
|
|
40
|
+
set animated(v: boolean);
|
|
41
|
+
set spinTiming(t: EffectTiming | undefined);
|
|
42
|
+
set slideTiming(t: EffectTiming | undefined);
|
|
43
|
+
}
|
|
44
|
+
declare function defineCharFlow(tag?: string): void;
|
|
45
|
+
declare global {
|
|
46
|
+
interface HTMLElementTagNameMap {
|
|
47
|
+
'char-flow': CharFlowElement;
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
export { type AnimKind as A, type CharKind as C, type DiffOp as D, type EffectTiming as E, type Preset as P, TAG as T, CharFlowElement as a, defineCharFlow as d };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { a as CharFlowElement, T as TAG, d as defineCharFlow } from './element-ohGNSSoB.js';
|
package/dist/element.js
ADDED
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
function T(e){let{letterSpacing:t}=getComputedStyle(e);e.style.setProperty("--cf-letter-gap",t==="normal"?"0px":t);}function A(e){let t=()=>T(e);t();let n=new ResizeObserver(t);return n.observe(e),document.fonts?.ready.then(t).catch(()=>{}),()=>n.disconnect()}var S="0123456789",v="ABCDEFGHIJKLMNOPQRSTUVWXYZ",x={duration:520,easing:"cubic-bezier(0.32, 0.72, 0, 1)",delay:0},b={duration:340,easing:"cubic-bezier(0.32, 0.72, 0, 1)",delay:0},R=16;function u(e){return e===" "?"\xA0":e}function H(e,t){return t>="a"&&t<="z"?e.toLowerCase():e}function d(e){if(!e)return "other";let t=e.charCodeAt(0);return t>=48&&t<=57?"digit":t>=65&&t<=90||t>=97&&t<=122?"letter":"other"}function g(e,t){return t==="digit"?e.charCodeAt(0)-48:e.toUpperCase().charCodeAt(0)-65}function I(e){let t=d(e);return t==="digit"?"wheel-digit":t==="letter"?"wheel-letter":"static"}function D(e,t){let n=d(e),i=d(t);return n==="digit"&&i==="digit"?"wheel-digit":n==="letter"&&i==="letter"?"wheel-letter":"slide"}function K(e,t,n){let i=g(e,n),r=g(t,n);if(i===r)return 1;let s=n==="letter"?26:10,o=(r-i+s)%s,a=(i-r+s)%s;return o<=a?1:-1}function Z(e,t,n){return t==="digit"?S[e]:H(v[e],n)}function O(e,t,n){let i=n==="letter"?v.length:S.length,r=g(e,n),s=g(t,n),o=K(e,t,n),a=[];for(let f=r;a.push(Z(f,n,t)),f!==s;f=(f+o+i)%i);return o===1?{chars:a,startIdx:0,endIdx:a.length-1}:{chars:[...a].reverse(),startIdx:a.length-1,endIdx:0}}function ee(e,t){return {chars:[u(e),u(t)],startIdx:0,endIdx:1}}function k(e){return e.fromChar==null||e.fromChar===e.char?null:e.anim==="wheel-digit"?O(e.fromChar,e.char,"digit"):e.anim==="wheel-letter"?O(e.fromChar,e.char,"letter"):ee(e.fromChar,e.char)}function F(e){return e.anim==="wheel-digit"||e.anim==="wheel-letter"}function C(e){let t=document.createElement("span");return t.className="cf-glyph",t.setAttribute("part","glyph"),t.textContent=u(e),t}function $(e,t=""){let n=document.createElement("span");return n.className=t?`cf-cell ${t}`:"cf-cell",n.dataset.key=e.key,n.dataset.char=e.char,n.setAttribute("part","segment"),n}function M(e){let t=$(e);return t.appendChild(C(e.char)),t}function te(e,t){let n=M(e),i=e.runLength&&e.runLength>1?(e.runIndex??0)*R:0;return t.push(r=>{n.animate([{opacity:0,transform:"translateY(0.25em)"},{opacity:1,transform:"translateY(0)"}],{duration:r.slide.duration,easing:r.slide.easing,delay:i,fill:"backwards"});}),n}function ne(e,t){let n=k(e),i=F(e),r=$(e,i?"cf-cell--rolling":""),s=C(e.char);s.style.visibility="hidden";let o=document.createElement("span");o.className="cf-stack";for(let a of n.chars)o.appendChild(C(a));return r.append(s,o),t.push(a=>{let f=-n.startIdx*a.cellHeight,p=-n.endIdx*a.cellHeight,l=i?a.spin:a.slide;o.style.transform=`translateY(${f}px)`;let c=o.animate([{transform:`translateY(${f}px)`},{transform:`translateY(${p}px)`}],{duration:l.duration,easing:l.easing,fill:"forwards"});c.onfinish=()=>{c.cancel(),o.remove(),s.style.visibility="",r.classList.remove("cf-cell--rolling");};}),r}function ie(e,t,n){return e.entering?t?te(e,n):M(e):t&&k(e)?ne(e,n):M(e)}function N(e,t,n,i){let r=n.get(e.key);return r&&!e.entering&&e.fromChar==null&&r.dataset.char===e.char?r:ie(e,t,i)}function Y(e){let t=new Map;for(let n of e.querySelectorAll(".cf-cell[data-key]"))n instanceof HTMLElement&&n.dataset.key&&t.set(n.dataset.key,n);return t}function G(e){let t=parseFloat(e);return Number.isFinite(t)?e.trim().endsWith("ms")?t:t*1e3:0}function re(e){let t=getComputedStyle(e),n=e.querySelector(".cf-glyph");return {cellHeight:n instanceof HTMLElement?n.offsetHeight:0,spin:{duration:G(t.getPropertyValue("--cf-spin-duration")),easing:t.getPropertyValue("--cf-spin-easing").trim()},slide:{duration:G(t.getPropertyValue("--cf-slide-duration")),easing:t.getPropertyValue("--cf-slide-easing").trim()}}}function U(e,t){let n=e.getBoundingClientRect().left,i=new Map;for(let r of t)r.dataset.key&&i.set(r.dataset.key,r.getBoundingClientRect().left-n);return i}function V(e,t,n){let i=Y(e),r=n?U(e,i.values()):new Map,s=[],o=[],a=new Set;for(let l of t){let c=N(l,n,i,s);a.add(l.key),o.push(c);}let f=[];if(n)for(let[l,c]of i)a.has(l)||f.push(c);if(e.replaceChildren(...o,...f),!s.length&&!f.length)return;let p=re(e);if(n){let l=U(e,o);for(let c of o){let m=c.dataset.key;if(!m)continue;let h=r.get(m),y=l.get(m);if(h===void 0||y===void 0)continue;let P=h-y;Math.abs(P)<.5||c.animate([{transform:`translateX(${P}px)`},{transform:"translateX(0)"}],{duration:p.slide.duration,easing:p.slide.easing});}for(let c of f){let m=r.get(c.dataset.key),h=c.offsetWidth;c.style.position="absolute",c.style.top="0",c.style.left=`${m??0}px`,c.style.width=`${h}px`,c.style.pointerEvents="none";let y=c.animate([{opacity:1,transform:"translateY(0)"},{opacity:0,transform:"translateY(-0.25em)"}],{duration:p.slide.duration,easing:p.slide.easing,fill:"forwards"});y.onfinish=()=>c.remove();}}for(let l of s)l(p);}function _(e,t){let n=e.length,i=t.length,r=Array.from({length:n+1},()=>Array.from({length:i+1},()=>0));for(let s=0;s<=n;s++)r[s][0]=s;for(let s=0;s<=i;s++)r[0][s]=s;for(let s=1;s<=n;s++)for(let o=1;o<=i;o++)e[s-1]===t[o-1]?r[s][o]=r[s-1][o-1]:r[s][o]=1+Math.min(r[s-1][o],r[s][o-1],r[s-1][o-1]);return r}function se(e,t,n,i){let r=[],s=t.length,o=n.length;for(;s>0||o>0;)s>0&&o>0&&t[s-1]===n[o-1]?(r.push("M"),s--,o--):s>0&&o>0&&e[s][o]===e[s-1][o-1]+1?(r.push("R"),s--,o--):o>0&&e[s][o]===e[s][o-1]+1?(r.push("I"),o--):(r.push("D"),s--);r.reverse();let a=[],f=0,p=0;for(let l of r)l==="M"?(a.push({type:"keep",index:p,char:n[p],prevKey:i+f}),f++,p++):l==="R"?(a.push({type:"replace",index:p,from:t[f],to:n[p],prevKey:i+f}),f++,p++):l==="I"?(a.push({type:"insert",index:p,char:n[p]}),p++):f++;return a}function oe(e,t,n=0){let i=[...e],r=[...t],s=_(i,r);return se(s,i,r,n)}function ae(e,t){let n=t,i=[];for(let r of e)if(r.type==="insert")i.push({type:"insert",index:n++,char:r.char});else if(r.type==="keep"){let s={type:"keep",index:n++,char:r.char,prevKey:r.prevKey};r.region&&(s.region=r.region),i.push(s);}else r.type==="replace"&&i.push({type:"replace",index:n++,from:r.from,to:r.to,prevKey:r.prevKey});return i}function le(e,t){let n=[];for(let i=0;i<t.length;i++){let r=e[i],s=t[i];r===s?n.push({type:"keep",index:i,char:s,prevKey:i}):n.push({type:"replace",index:i,from:r,to:s,prevKey:i});}return n}function X(e,t){if(e.length===t.length)return le(e,t);let n=0;for(;n<e.length&&n<t.length&&e[n]===t[n];)n++;let i=0;for(;i<e.length-n&&i<t.length-n&&e[e.length-1-i]===t[t.length-1-i];)i++;let r=[],s=0;for(let l=0;l<n;l++)r.push({type:"keep",index:s++,char:t[l],prevKey:l});let o=e.slice(n,e.length-i),a=t.slice(n,t.length-i),f=Math.max(o.length,a.length);if(f>0)if(_([...o],[...a])[o.length][a.length]/f>.4)for(let m=0;m<a.length;m++)r.push({type:"insert",index:s++,char:a[m]});else r.push(...ae(oe(o,a,n),s)),s+=a.length;let p=Math.max(n,t.length-i);for(let l=p;l<t.length;l++){let c=e.length-i+(l-(t.length-i));c<n||r.push({type:"keep",index:s++,char:t[l],prevKey:c,region:"suffix"});}return r}var ce=0;function w(e){return `${e}-${++ce}`}function q(e,t,n){return e[t]??w(n)}function fe(e){let t=e.map(i=>({...i})),n=0;for(;n<t.length;){if(!t[n].entering){n++;continue}let r=n+1;for(;r<t.length&&t[r].entering;)r++;let s=r-n;for(let o=n;o<r;o++)t[o]={...t[o],runIndex:o-n,runLength:s};n=r;}return t}function E(e,t,n={}){return {key:t,char:e,kind:d(e),anim:n.anim??I(e),...n}}function pe(e,t){let n=[];for(let i of e){if(i.type==="keep"){n.push(E(i.char,q(t,i.prevKey,"k")));continue}if(i.type==="replace"){n.push(E(i.to,q(t,i.prevKey,"r"),{anim:D(i.from,i.to),fromChar:i.from,fromKind:d(i.from)}));continue}i.type==="insert"&&n.push(E(i.char,w("i"),{entering:true}));}return fe(n)}function z(e,t,n){let i=pe(X(e,t),n);return {segments:i,keys:i.map(r=>r.key)}}function W(e){let t=[...e].map((n,i)=>E(n,w(`s${i}`)));return {segments:t,keys:t.map(n=>n.key)}}var j=`
|
|
2
|
+
:host {
|
|
3
|
+
display: inline-block;
|
|
4
|
+
line-height: inherit;
|
|
5
|
+
font-variant-numeric: tabular-nums;
|
|
6
|
+
--cf-cell-height: 1lh;
|
|
7
|
+
--cf-letter-gap: 0px;
|
|
8
|
+
--cf-spin-duration: ${x.duration}ms;
|
|
9
|
+
--cf-spin-easing: ${x.easing};
|
|
10
|
+
--cf-slide-duration: ${b.duration}ms;
|
|
11
|
+
--cf-slide-easing: ${b.easing};
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
.root {
|
|
15
|
+
display: inline;
|
|
16
|
+
position: relative;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
.sr {
|
|
20
|
+
position: absolute;
|
|
21
|
+
width: 1px;
|
|
22
|
+
height: 1px;
|
|
23
|
+
padding: 0;
|
|
24
|
+
margin: -1px;
|
|
25
|
+
overflow: hidden;
|
|
26
|
+
clip: rect(0, 0, 0, 0);
|
|
27
|
+
white-space: nowrap;
|
|
28
|
+
border: 0;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
.visual {
|
|
32
|
+
display: inline-block;
|
|
33
|
+
position: relative;
|
|
34
|
+
white-space: nowrap;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
.cf-cell {
|
|
38
|
+
display: inline-block;
|
|
39
|
+
height: var(--cf-cell-height);
|
|
40
|
+
line-height: var(--cf-cell-height);
|
|
41
|
+
vertical-align: baseline;
|
|
42
|
+
overflow: hidden;
|
|
43
|
+
position: relative;
|
|
44
|
+
text-align: center;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
.cf-cell + .cf-cell {
|
|
48
|
+
margin-left: var(--cf-letter-gap);
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
/* Soft top/bottom fade only while a wheel is mid-roll. */
|
|
52
|
+
.cf-cell--rolling {
|
|
53
|
+
-webkit-mask-image: linear-gradient(
|
|
54
|
+
to bottom,
|
|
55
|
+
transparent 0%,
|
|
56
|
+
#000 18%,
|
|
57
|
+
#000 82%,
|
|
58
|
+
transparent 100%
|
|
59
|
+
);
|
|
60
|
+
mask-image: linear-gradient(
|
|
61
|
+
to bottom,
|
|
62
|
+
transparent 0%,
|
|
63
|
+
#000 18%,
|
|
64
|
+
#000 82%,
|
|
65
|
+
transparent 100%
|
|
66
|
+
);
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
.cf-stack {
|
|
70
|
+
position: absolute;
|
|
71
|
+
top: 0;
|
|
72
|
+
left: 0;
|
|
73
|
+
width: 100%;
|
|
74
|
+
will-change: transform;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
.cf-glyph {
|
|
78
|
+
display: block;
|
|
79
|
+
height: var(--cf-cell-height);
|
|
80
|
+
line-height: var(--cf-cell-height);
|
|
81
|
+
text-align: center;
|
|
82
|
+
}
|
|
83
|
+
`.trim();function B(e,t){t==="plate"?(e.style.textTransform="uppercase",e.style.letterSpacing="0.04em"):(e.style.textTransform="",e.style.letterSpacing="");}function Q(e,t,n){let i={...x,...t},r={...b,...n};e.style.setProperty("--cf-spin-duration",`${i.duration}ms`),e.style.setProperty("--cf-spin-easing",i.easing),e.style.setProperty("--cf-slide-duration",`${r.duration}ms`),e.style.setProperty("--cf-slide-easing",r.easing);}function J(e){return e==="plate"?"plate":"alnum"}var me="char-flow",L=class extends HTMLElement{static observedAttributes=["value","preset","animated"];#e;#t;#n="";#s=[];#i=window.matchMedia("(prefers-reduced-motion: reduce)");#l=()=>this.#p();#o;#c;#f;connectedCallback(){if(!this.shadowRoot){let t=this.attachShadow({mode:"open"}),n=document.createElement("style");n.textContent=j;let i=document.createElement("div");i.className="root",i.setAttribute("part","root"),this.#e=document.createElement("span"),this.#e.className="sr",this.#e.setAttribute("aria-live","polite"),this.#e.setAttribute("aria-atomic","true"),this.#t=document.createElement("span"),this.#t.className="visual",this.#t.setAttribute("aria-hidden","true"),i.append(this.#e,this.#t),t.append(n,i);}this.#i.addEventListener("change",this.#l),this.#p(),this.#r(),this.#o=A(this),this.#a(true);}disconnectedCallback(){this.#i.removeEventListener("change",this.#l),this.#o?.(),this.#o=void 0;}attributeChangedCallback(t){if(this.isConnected){if(t==="value"){this.#a(false);return}this.#r(),t==="animated"&&this.#a(false);}}get value(){return this.getAttribute("value")??""}set value(t){this.setAttribute("value",t);}get preset(){return J(this.getAttribute("preset"))}set preset(t){this.setAttribute("preset",t);}get animated(){return this.getAttribute("animated")!=="false"}set animated(t){t?this.removeAttribute("animated"):this.setAttribute("animated","false");}set spinTiming(t){this.#c=t,this.#r();}set slideTiming(t){this.#f=t,this.#r();}#m(){return !(!this.animated||this.#i.matches)}#p(){this.#i.matches?this.dataset.reduced="":delete this.dataset.reduced;}#r(){B(this,this.preset),Q(this,this.#c,this.#f),T(this);}#a(t){let n=this.value;this.#e.textContent=n;let i=this.#m()&&!t,r;if(t||!this.#n){let s=W(n);r=s.segments,this.#s=s.keys;}else {if(this.#n===n)return;{let s=z(this.#n,n,this.#s);r=s.segments,this.#s=s.keys;}}V(this.#t,r,i),this.#n=n;}};function de(e=me){customElements.get(e)||customElements.define(e,L);}de();export{L as CharFlowElement,me as TAG,de as defineCharFlow};//# sourceMappingURL=element.js.map
|
|
84
|
+
//# sourceMappingURL=element.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/layout/metrics.ts","../src/types.ts","../src/render/format.ts","../src/classify.ts","../src/render/stack.ts","../src/render/cell.ts","../src/render/mount.ts","../src/diff.ts","../src/segments.ts","../src/styles.ts","../src/element.ts"],"names":["syncMetrics","host","letterSpacing","observeMetrics","run","ro","DIGITS","LETTERS","DEFAULT_SPIN","DEFAULT_SLIDE","STAGGER_STEP_MS","formatChar","char","displayLetter","stripChar","target","classify","code","wheelIndex","kind","animForChar","k","animForReplace","from","to","fk","tk","spinDirection","a","b","n","up","down","charForIndex","i","wheelPlan","dir","path","slidePlan","planFor","seg","isWheel","glyph","g","makeCell","extraClass","cell","staticCell","enteringCell","pending","delay","ctx","rollingCell","plan","wheel","sizer","stack","c","startY","endY","timing","anim","buildCell","animated","reuseCell","existing","existingCellMap","root","map","el","ms","value","readContext","visual","cs","sample","measureX","cells","base","out","mountVisual","segments","firstX","nodes","survivors","node","exiting","key","lastX","before","after","dx","x","width","levenshteinMatrix","m","dp","j","backtrackOps","keyOffset","raw","ops","ai","bi","step","diffChars","prev","next","reindexOps","startIdx","outIdx","result","op","keep","diffAligned","diff","pre","suf","midPrev","midNext","midMax","suffixStart","prevIdx","keySeq","nextKey","prefix","keyForPrev","prevKeys","prevKey","fallback","assignEnteringRuns","s","len","makeSegment","extra","opsToSegments","buildSegments","prevSegmentKeys","initialSegments","STYLES","applyPresetStyle","preset","applyTimings","spin","slide","l","parsePreset","v","TAG","CharFlowElement","#sr","#visual","#prevValue","#keys","#motionQuery","#onMotionChange","#syncReduced","#stopMetrics","#spinTiming","#slideTiming","style","shell","#applyOptions","#render","name","#canAnimate","initial","init","built","defineCharFlow","tag"],"mappings":"AACO,SAASA,CAAAA,CAAYC,CAAAA,CAAyB,CACnD,GAAM,CAAE,aAAA,CAAAC,CAAc,CAAA,CAAI,gBAAA,CAAiBD,CAAI,CAAA,CAC/CA,CAAAA,CAAK,KAAA,CAAM,WAAA,CAAY,iBAAA,CAAmBC,CAAAA,GAAkB,QAAA,CAAW,KAAA,CAAQA,CAAa,EAC9F,CAEO,SAASC,CAAAA,CAAeF,CAAAA,CAA+B,CAC5D,IAAMG,CAAAA,CAAM,IAAYJ,EAAYC,CAAI,CAAA,CAExCG,CAAAA,EAAI,CAEJ,IAAMC,CAAAA,CAAK,IAAI,cAAA,CAAeD,CAAG,CAAA,CACjC,OAAAC,CAAAA,CAAG,OAAA,CAAQJ,CAAI,CAAA,CAEf,QAAA,CAAS,KAAA,EAAO,KAAA,CAAM,IAAA,CAAKG,CAAG,CAAA,CAAE,KAAA,CAAM,IAAG,CAAA,CAAY,CAAA,CAE9C,IAAMC,CAAAA,CAAG,UAAA,EAClB,CCsBO,IAAMC,CAAAA,CAAS,aACTC,CAAAA,CAAU,4BAAA,CAEVC,CAAAA,CAAuC,CAClD,QAAA,CAAU,GAAA,CACV,MAAA,CAAQ,gCAAA,CACR,KAAA,CAAO,CACT,CAAA,CAGaC,CAAAA,CAAwC,CACnD,QAAA,CAAU,GAAA,CACV,MAAA,CAAQ,gCAAA,CACR,KAAA,CAAO,CACT,CAAA,CAGaC,CAAAA,CAAkB,EAAA,CCxDxB,SAASC,CAAAA,CAAWC,CAAAA,CAAsB,CAC/C,OAAOA,CAAAA,GAAS,GAAA,CAAM,MAAA,CAAWA,CACnC,CAEO,SAASC,CAAAA,CAAcC,CAAAA,CAAmBC,CAAAA,CAAwB,CACvE,OAAIA,CAAAA,EAAU,GAAA,EAAOA,CAAAA,EAAU,GAAA,CAAYD,CAAAA,CAAU,WAAA,EAAY,CAC1DA,CACT,CCLO,SAASE,CAAAA,CAASJ,EAAwB,CAC/C,GAAI,CAACA,CAAAA,CAAM,OAAO,OAAA,CAClB,IAAMK,CAAAA,CAAOL,CAAAA,CAAK,UAAA,CAAW,CAAC,CAAA,CAC9B,OAAIK,CAAAA,EAAQ,EAAA,EAAMA,CAAAA,EAAQ,GAAW,OAAA,CAChCA,CAAAA,EAAQ,EAAA,EAAMA,CAAAA,EAAQ,EAAA,EAAQA,CAAAA,EAAQ,EAAA,EAAMA,CAAAA,EAAQ,GAAA,CAAa,QAAA,CAC/D,OACT,CAEO,SAASC,CAAAA,CAAWN,CAAAA,CAAcO,CAAAA,CAAwB,CAC/D,OAAIA,CAAAA,GAAS,OAAA,CAAgBP,CAAAA,CAAK,UAAA,CAAW,CAAC,CAAA,CAAI,EAAA,CACpCA,CAAAA,CAAK,WAAA,EAAY,CAClB,UAAA,CAAW,CAAC,CAAA,CAAI,EAC/B,CAGO,SAASQ,CAAAA,CAAYR,CAAAA,CAAwB,CAClD,IAAMS,CAAAA,CAAIL,CAAAA,CAASJ,CAAI,CAAA,CACvB,OAAIS,CAAAA,GAAM,OAAA,CAAgB,aAAA,CACtBA,CAAAA,GAAM,QAAA,CAAiB,cAAA,CACpB,QACT,CAOO,SAASC,CAAAA,CAAeC,CAAAA,CAAcC,CAAAA,CAAsB,CACjE,IAAMC,CAAAA,CAAKT,CAAAA,CAASO,CAAI,CAAA,CAClBG,CAAAA,CAAKV,CAAAA,CAASQ,CAAE,CAAA,CACtB,OAAIC,CAAAA,GAAO,OAAA,EAAWC,CAAAA,GAAO,OAAA,CAAgB,aAAA,CACzCD,CAAAA,GAAO,QAAA,EAAYC,CAAAA,GAAO,QAAA,CAAiB,cAAA,CACxC,OACT,CAEO,SAASC,CAAAA,CAAcJ,CAAAA,CAAcC,CAAAA,CAAYL,CAAAA,CAAwB,CAC9E,IAAMS,CAAAA,CAAIV,CAAAA,CAAWK,CAAAA,CAAMJ,CAAI,CAAA,CACzBU,CAAAA,CAAIX,CAAAA,CAAWM,CAAAA,CAAIL,CAAI,CAAA,CAC7B,GAAIS,CAAAA,GAAMC,CAAAA,CAAG,OAAO,CAAA,CACpB,IAAMC,CAAAA,CAAIX,CAAAA,GAAS,QAAA,CAAW,EAAA,CAAK,EAAA,CAC7BY,CAAAA,CAAAA,CAAMF,CAAAA,CAAID,CAAAA,CAAIE,CAAAA,EAAKA,CAAAA,CACnBE,CAAAA,CAAAA,CAAQJ,CAAAA,CAAIC,CAAAA,CAAIC,CAAAA,EAAKA,EAC3B,OAAOC,CAAAA,EAAMC,CAAAA,CAAO,CAAA,CAAI,EAC1B,CC1BA,SAASC,CAAAA,CAAaC,CAAAA,CAAWf,CAAAA,CAA0BJ,CAAAA,CAAwB,CACjF,OAAII,CAAAA,GAAS,OAAA,CAAgBb,CAAAA,CAAO4B,CAAC,CAAA,CAC9BrB,CAAAA,CAAcN,CAAAA,CAAQ2B,CAAC,CAAA,CAAInB,CAAM,CAC1C,CAGA,SAASoB,CAAAA,CAAUZ,CAAAA,CAAcC,CAAAA,CAAYL,CAAAA,CAAqC,CAChF,IAAMW,CAAAA,CAAIX,CAAAA,GAAS,QAAA,CAAWZ,CAAAA,CAAQ,MAAA,CAASD,CAAAA,CAAO,MAAA,CAChDsB,CAAAA,CAAIV,CAAAA,CAAWK,CAAAA,CAAMJ,CAAI,CAAA,CACzBU,CAAAA,CAAIX,CAAAA,CAAWM,CAAAA,CAAIL,CAAI,CAAA,CACvBiB,EAAMT,CAAAA,CAAcJ,CAAAA,CAAMC,CAAAA,CAAIL,CAAI,CAAA,CAElCkB,CAAAA,CAAiB,EAAC,CACxB,IAAA,IAASH,CAAAA,CAAIN,CAAAA,CACXS,CAAAA,CAAK,IAAA,CAAKJ,CAAAA,CAAaC,CAAAA,CAAGf,CAAAA,CAAMK,CAAE,CAAC,CAAA,CAC/BU,CAAAA,GAAML,CAAAA,CAFMK,CAAAA,CAAAA,CAAKA,CAAAA,CAAIE,CAAAA,CAAMN,CAAAA,EAAKA,CAAAA,CAEpC,CAKF,OAAIM,CAAAA,GAAQ,CAAA,CAAU,CAAE,KAAA,CAAOC,EAAM,QAAA,CAAU,CAAA,CAAG,MAAA,CAAQA,CAAAA,CAAK,MAAA,CAAS,CAAE,CAAA,CACnE,CAAE,KAAA,CAAO,CAAC,GAAGA,CAAI,CAAA,CAAE,OAAA,EAAQ,CAAG,QAAA,CAAUA,CAAAA,CAAK,MAAA,CAAS,CAAA,CAAG,MAAA,CAAQ,CAAE,CAC5E,CAGA,SAASC,EAAAA,CAAUf,CAAAA,CAAcC,CAAAA,CAAuB,CACtD,OAAO,CAAE,KAAA,CAAO,CAACb,EAAWY,CAAI,CAAA,CAAGZ,CAAAA,CAAWa,CAAE,CAAC,CAAA,CAAG,QAAA,CAAU,CAAA,CAAG,MAAA,CAAQ,CAAE,CAC7E,CAGO,SAASe,CAAAA,CAAQC,CAAAA,CAAsC,CAC5D,OAAIA,CAAAA,CAAI,QAAA,EAAY,IAAA,EAAQA,CAAAA,CAAI,QAAA,GAAaA,CAAAA,CAAI,IAAA,CAAa,IAAA,CAC1DA,CAAAA,CAAI,IAAA,GAAS,aAAA,CAAsBL,CAAAA,CAAUK,CAAAA,CAAI,QAAA,CAAUA,CAAAA,CAAI,IAAA,CAAM,OAAO,CAAA,CAC5EA,CAAAA,CAAI,IAAA,GAAS,cAAA,CAAuBL,CAAAA,CAAUK,CAAAA,CAAI,QAAA,CAAUA,CAAAA,CAAI,IAAA,CAAM,QAAQ,CAAA,CAC3EF,EAAAA,CAAUE,CAAAA,CAAI,QAAA,CAAUA,CAAAA,CAAI,IAAI,CACzC,CAEO,SAASC,CAAAA,CAAQD,CAAAA,CAA6B,CACnD,OAAOA,CAAAA,CAAI,IAAA,GAAS,aAAA,EAAiBA,CAAAA,CAAI,IAAA,GAAS,cACpD,CC3CA,SAASE,CAAAA,CAAM9B,EAA2B,CACxC,IAAM+B,CAAAA,CAAI,QAAA,CAAS,aAAA,CAAc,MAAM,CAAA,CACvC,OAAAA,CAAAA,CAAE,SAAA,CAAY,UAAA,CACdA,CAAAA,CAAE,YAAA,CAAa,MAAA,CAAQ,OAAO,CAAA,CAC9BA,EAAE,WAAA,CAAchC,CAAAA,CAAWC,CAAI,CAAA,CACxB+B,CACT,CAEA,SAASC,CAAAA,CAASJ,CAAAA,CAAoBK,CAAAA,CAAa,EAAA,CAAiB,CAClE,IAAMC,CAAAA,CAAO,QAAA,CAAS,aAAA,CAAc,MAAM,CAAA,CAC1C,OAAAA,CAAAA,CAAK,SAAA,CAAYD,CAAAA,CAAa,CAAA,QAAA,EAAWA,CAAU,CAAA,CAAA,CAAK,SAAA,CACxDC,CAAAA,CAAK,OAAA,CAAQ,GAAA,CAAMN,CAAAA,CAAI,GAAA,CACvBM,CAAAA,CAAK,OAAA,CAAQ,IAAA,CAAON,CAAAA,CAAI,IAAA,CACxBM,CAAAA,CAAK,YAAA,CAAa,MAAA,CAAQ,SAAS,CAAA,CAC5BA,CACT,CAEA,SAASC,CAAAA,CAAWP,CAAAA,CAAiC,CACnD,IAAMM,CAAAA,CAAOF,EAASJ,CAAG,CAAA,CACzB,OAAAM,CAAAA,CAAK,WAAA,CAAYJ,CAAAA,CAAMF,CAAAA,CAAI,IAAI,CAAC,CAAA,CACzBM,CACT,CAEA,SAASE,EAAAA,CAAaR,CAAAA,CAAoBS,CAAAA,CAAiC,CACzE,IAAMH,CAAAA,CAAOC,CAAAA,CAAWP,CAAG,CAAA,CACrBU,CAAAA,CACJV,CAAAA,CAAI,SAAA,EAAaA,CAAAA,CAAI,SAAA,CAAY,CAAA,CAAA,CAAKA,CAAAA,CAAI,QAAA,EAAY,CAAA,EAAK9B,CAAAA,CAAkB,CAAA,CAE/E,OAAAuC,CAAAA,CAAQ,IAAA,CAAME,CAAAA,EAAQ,CACpBL,CAAAA,CAAK,OAAA,CACH,CACE,CAAE,OAAA,CAAS,CAAA,CAAG,SAAA,CAAW,oBAAqB,CAAA,CAC9C,CAAE,OAAA,CAAS,CAAA,CAAG,SAAA,CAAW,eAAgB,CAC3C,CAAA,CACA,CAAE,QAAA,CAAUK,CAAAA,CAAI,KAAA,CAAM,QAAA,CAAU,MAAA,CAAQA,CAAAA,CAAI,KAAA,CAAM,MAAA,CAAQ,KAAA,CAAAD,CAAAA,CAAO,IAAA,CAAM,WAAY,CACrF,EACF,CAAC,CAAA,CACMJ,CACT,CAEA,SAASM,EAAAA,CAAYZ,CAAAA,CAAoBS,CAAAA,CAAiC,CACxE,IAAMI,CAAAA,CAAOd,CAAAA,CAAQC,CAAG,CAAA,CAClBc,CAAAA,CAAQb,CAAAA,CAAQD,CAAG,CAAA,CACnBM,CAAAA,CAAOF,CAAAA,CAASJ,CAAAA,CAAKc,CAAAA,CAAQ,kBAAA,CAAqB,EAAE,CAAA,CAIpDC,CAAAA,CAAQb,CAAAA,CAAMF,CAAAA,CAAI,IAAI,CAAA,CAC5Be,EAAM,KAAA,CAAM,UAAA,CAAa,QAAA,CACzB,IAAMC,CAAAA,CAAQ,QAAA,CAAS,aAAA,CAAc,MAAM,CAAA,CAC3CA,CAAAA,CAAM,SAAA,CAAY,UAAA,CAClB,IAAA,IAAWC,CAAAA,IAAKJ,CAAAA,CAAK,KAAA,CAAOG,CAAAA,CAAM,WAAA,CAAYd,CAAAA,CAAMe,CAAC,CAAC,CAAA,CACtD,OAAAX,CAAAA,CAAK,MAAA,CAAOS,CAAAA,CAAOC,CAAK,CAAA,CAExBP,CAAAA,CAAQ,IAAA,CAAME,CAAAA,EAAQ,CACpB,IAAMO,CAAAA,CAAS,CAACL,CAAAA,CAAK,QAAA,CAAWF,CAAAA,CAAI,UAAA,CAC9BQ,CAAAA,CAAO,CAACN,CAAAA,CAAK,MAAA,CAASF,CAAAA,CAAI,UAAA,CAC1BS,CAAAA,CAASN,CAAAA,CAAQH,CAAAA,CAAI,IAAA,CAAOA,EAAI,KAAA,CAEtCK,CAAAA,CAAM,KAAA,CAAM,SAAA,CAAY,CAAA,WAAA,EAAcE,CAAM,CAAA,GAAA,CAAA,CAC5C,IAAMG,CAAAA,CAAOL,CAAAA,CAAM,OAAA,CACjB,CAAC,CAAE,SAAA,CAAW,CAAA,WAAA,EAAcE,CAAM,KAAM,CAAA,CAAG,CAAE,SAAA,CAAW,CAAA,WAAA,EAAcC,CAAI,CAAA,GAAA,CAAM,CAAC,CAAA,CACjF,CAAE,QAAA,CAAUC,CAAAA,CAAO,QAAA,CAAU,MAAA,CAAQA,CAAAA,CAAO,MAAA,CAAQ,IAAA,CAAM,UAAW,CACvE,CAAA,CAEAC,CAAAA,CAAK,QAAA,CAAW,IAAM,CACpBA,CAAAA,CAAK,MAAA,EAAO,CACZL,CAAAA,CAAM,MAAA,EAAO,CACbD,CAAAA,CAAM,KAAA,CAAM,UAAA,CAAa,GACzBT,CAAAA,CAAK,SAAA,CAAU,MAAA,CAAO,kBAAkB,EAC1C,EACF,CAAC,CAAA,CAEMA,CACT,CAEO,SAASgB,EAAAA,CACdtB,CAAAA,CACAuB,CAAAA,CACAd,CAAAA,CACa,CACb,OAAIT,CAAAA,CAAI,QAAA,CACCuB,CAAAA,CAAWf,EAAAA,CAAaR,CAAAA,CAAKS,CAAO,CAAA,CAAIF,CAAAA,CAAWP,CAAG,CAAA,CAE3DuB,CAAAA,EAAYxB,CAAAA,CAAQC,CAAG,CAAA,CAClBY,EAAAA,CAAYZ,EAAKS,CAAO,CAAA,CAE1BF,CAAAA,CAAWP,CAAG,CACvB,CAEO,SAASwB,CAAAA,CACdxB,CAAAA,CACAuB,CAAAA,CACAE,CAAAA,CACAhB,CAAAA,CACa,CACb,IAAMH,CAAAA,CAAOmB,CAAAA,CAAS,GAAA,CAAIzB,CAAAA,CAAI,GAAG,CAAA,CAEjC,OAAIM,CAAAA,EAAQ,CAACN,CAAAA,CAAI,QAAA,EAAYA,CAAAA,CAAI,QAAA,EAAY,IAAA,EAAQM,CAAAA,CAAK,OAAA,CAAQ,IAAA,GAASN,CAAAA,CAAI,KACtEM,CAAAA,CAEFgB,EAAAA,CAAUtB,CAAAA,CAAKuB,CAAAA,CAAUd,CAAO,CACzC,CAEO,SAASiB,CAAAA,CAAgBC,CAAAA,CAA6C,CAC3E,IAAMC,CAAAA,CAAM,IAAI,GAAA,CAChB,IAAA,IAAWC,KAAMF,CAAAA,CAAK,gBAAA,CAAiB,oBAAoB,CAAA,CACrDE,CAAAA,YAAc,WAAA,EAAeA,CAAAA,CAAG,OAAA,CAAQ,GAAA,EAAKD,CAAAA,CAAI,GAAA,CAAIC,CAAAA,CAAG,OAAA,CAAQ,GAAA,CAAKA,CAAE,CAAA,CAE7E,OAAOD,CACT,CC1HA,SAASE,CAAAA,CAAGC,CAAAA,CAAuB,CACjC,IAAMzC,CAAAA,CAAI,UAAA,CAAWyC,CAAK,CAAA,CAC1B,OAAK,MAAA,CAAO,QAAA,CAASzC,CAAC,CAAA,CACfyC,CAAAA,CAAM,IAAA,EAAK,CAAE,QAAA,CAAS,IAAI,CAAA,CAAIzC,CAAAA,CAAIA,CAAAA,CAAI,GAAA,CADb,CAElC,CAEA,SAAS0C,EAAAA,CAAYC,CAAAA,CAAkC,CACrD,IAAMC,EAAK,gBAAA,CAAiBD,CAAM,CAAA,CAC5BE,CAAAA,CAASF,CAAAA,CAAO,aAAA,CAAc,WAAW,CAAA,CAC/C,OAAO,CACL,UAAA,CAAYE,CAAAA,YAAkB,WAAA,CAAcA,CAAAA,CAAO,YAAA,CAAe,CAAA,CAClE,IAAA,CAAM,CACJ,QAAA,CAAUL,CAAAA,CAAGI,CAAAA,CAAG,gBAAA,CAAiB,oBAAoB,CAAC,CAAA,CACtD,MAAA,CAAQA,CAAAA,CAAG,gBAAA,CAAiB,kBAAkB,CAAA,CAAE,IAAA,EAClD,EACA,KAAA,CAAO,CACL,QAAA,CAAUJ,CAAAA,CAAGI,CAAAA,CAAG,gBAAA,CAAiB,qBAAqB,CAAC,CAAA,CACvD,MAAA,CAAQA,CAAAA,CAAG,gBAAA,CAAiB,mBAAmB,CAAA,CAAE,IAAA,EACnD,CACF,CACF,CAGA,SAASE,CAAAA,CAASH,CAAAA,CAAqBI,CAAAA,CAAmD,CACxF,IAAMC,CAAAA,CAAOL,CAAAA,CAAO,qBAAA,EAAsB,CAAE,IAAA,CACtCM,CAAAA,CAAM,IAAI,IAChB,IAAA,IAAWV,CAAAA,IAAMQ,CAAAA,CACXR,CAAAA,CAAG,OAAA,CAAQ,GAAA,EAAKU,CAAAA,CAAI,GAAA,CAAIV,CAAAA,CAAG,OAAA,CAAQ,GAAA,CAAKA,CAAAA,CAAG,qBAAA,EAAsB,CAAE,IAAA,CAAOS,CAAI,EAEpF,OAAOC,CACT,CAEO,SAASC,CAAAA,CACdP,CAAAA,CACAQ,CAAAA,CACAlB,CAAAA,CACM,CACN,IAAME,CAAAA,CAAWC,CAAAA,CAAgBO,CAAM,CAAA,CAGjCS,CAAAA,CAASnB,CAAAA,CAAWa,EAASH,CAAAA,CAAQR,CAAAA,CAAS,MAAA,EAAQ,CAAA,CAAI,IAAI,GAAA,CAE9DhB,CAAAA,CAAqB,EAAC,CACtBkC,CAAAA,CAAuB,EAAC,CACxBC,CAAAA,CAAY,IAAI,GAAA,CAEtB,IAAA,IAAW5C,CAAAA,IAAOyC,CAAAA,CAAU,CAC1B,IAAMI,CAAAA,CAAOrB,CAAAA,CAAUxB,CAAAA,CAAKuB,CAAAA,CAAUE,CAAAA,CAAUhB,CAAO,CAAA,CACvDmC,CAAAA,CAAU,GAAA,CAAI5C,CAAAA,CAAI,GAAG,EACrB2C,CAAAA,CAAM,IAAA,CAAKE,CAAI,EACjB,CAGA,IAAMC,CAAAA,CAAyB,EAAC,CAChC,GAAIvB,CAAAA,CACF,IAAA,GAAW,CAACwB,CAAAA,CAAKlB,CAAE,CAAA,GAAKJ,EACjBmB,CAAAA,CAAU,GAAA,CAAIG,CAAG,CAAA,EAAGD,CAAAA,CAAQ,IAAA,CAAKjB,CAAE,CAAA,CAO5C,GAFAI,CAAAA,CAAO,eAAA,CAAgB,GAAGU,CAAAA,CAAO,GAAGG,CAAO,CAAA,CAEvC,CAACrC,CAAAA,CAAQ,MAAA,EAAU,CAACqC,CAAAA,CAAQ,MAAA,CAAQ,OAExC,IAAMnC,CAAAA,CAAMqB,EAAAA,CAAYC,CAAM,CAAA,CAE9B,GAAIV,CAAAA,CAAU,CAEZ,IAAMyB,CAAAA,CAAQZ,CAAAA,CAASH,CAAAA,CAAQU,CAAK,CAAA,CACpC,IAAA,IAAWE,CAAAA,IAAQF,CAAAA,CAAO,CACxB,IAAMI,CAAAA,CAAMF,CAAAA,CAAK,OAAA,CAAQ,GAAA,CACzB,GAAI,CAACE,CAAAA,CAAK,SACV,IAAME,CAAAA,CAASP,CAAAA,CAAO,GAAA,CAAIK,CAAG,CAAA,CACvBG,CAAAA,CAAQF,CAAAA,CAAM,GAAA,CAAID,CAAG,CAAA,CAC3B,GAAIE,CAAAA,GAAW,MAAA,EAAaC,CAAAA,GAAU,MAAA,CAAW,SACjD,IAAMC,CAAAA,CAAKF,CAAAA,CAASC,CAAAA,CAChB,IAAA,CAAK,GAAA,CAAIC,CAAE,CAAA,CAAI,EAAA,EACnBN,CAAAA,CAAK,OAAA,CACH,CAAC,CAAE,SAAA,CAAW,CAAA,WAAA,EAAcM,CAAE,KAAM,CAAA,CAAG,CAAE,SAAA,CAAW,eAAgB,CAAC,CAAA,CACrE,CAAE,QAAA,CAAUxC,CAAAA,CAAI,KAAA,CAAM,QAAA,CAAU,MAAA,CAAQA,CAAAA,CAAI,KAAA,CAAM,MAAO,CAC3D,EACF,CAEA,IAAA,IAAWkB,CAAAA,IAAMiB,CAAAA,CAAS,CACxB,IAAMM,CAAAA,CAAIV,CAAAA,CAAO,GAAA,CAAIb,CAAAA,CAAG,OAAA,CAAQ,GAAI,CAAA,CAC9BwB,CAAAA,CAAQxB,CAAAA,CAAG,YACjBA,CAAAA,CAAG,KAAA,CAAM,QAAA,CAAW,UAAA,CACpBA,CAAAA,CAAG,KAAA,CAAM,GAAA,CAAM,GAAA,CACfA,CAAAA,CAAG,KAAA,CAAM,IAAA,CAAO,CAAA,EAAGuB,CAAAA,EAAK,CAAC,CAAA,EAAA,CAAA,CACzBvB,CAAAA,CAAG,KAAA,CAAM,KAAA,CAAQ,CAAA,EAAGwB,CAAK,CAAA,EAAA,CAAA,CACzBxB,CAAAA,CAAG,KAAA,CAAM,aAAA,CAAgB,MAAA,CACzB,IAAMU,CAAAA,CAAMV,CAAAA,CAAG,OAAA,CACb,CACE,CAAE,OAAA,CAAS,EAAG,SAAA,CAAW,eAAgB,CAAA,CACzC,CAAE,OAAA,CAAS,CAAA,CAAG,SAAA,CAAW,qBAAsB,CACjD,CAAA,CACA,CAAE,QAAA,CAAUlB,CAAAA,CAAI,KAAA,CAAM,QAAA,CAAU,MAAA,CAAQA,CAAAA,CAAI,KAAA,CAAM,MAAA,CAAQ,IAAA,CAAM,UAAW,CAC7E,CAAA,CACA4B,CAAAA,CAAI,QAAA,CAAW,IAAMV,CAAAA,CAAG,MAAA,GAC1B,CACF,CAEA,IAAA,IAAWjE,KAAO6C,CAAAA,CAAS7C,CAAAA,CAAI+C,CAAG,EACpC,CCzGA,SAAS2C,CAAAA,CAAkBlE,CAAAA,CAAaC,CAAAA,CAAyB,CAC/D,IAAMkE,CAAAA,CAAInE,CAAAA,CAAE,MAAA,CACNE,CAAAA,CAAID,CAAAA,CAAE,OACNmE,CAAAA,CAAiB,KAAA,CAAM,IAAA,CAAK,CAAE,MAAA,CAAQD,CAAAA,CAAI,CAAE,CAAA,CAAG,IACnD,KAAA,CAAM,IAAA,CAAK,CAAE,MAAA,CAAQjE,CAAAA,CAAI,CAAE,CAAA,CAAG,IAAM,CAAC,CACvC,CAAA,CACA,IAAA,IAASI,CAAAA,CAAI,CAAA,CAAGA,CAAAA,EAAK6D,CAAAA,CAAG7D,CAAAA,EAAAA,CAAK8D,CAAAA,CAAG9D,CAAC,CAAA,CAAG,CAAC,CAAA,CAAIA,CAAAA,CACzC,IAAA,IAAS+D,CAAAA,CAAI,CAAA,CAAGA,CAAAA,EAAKnE,CAAAA,CAAGmE,CAAAA,EAAAA,CAAKD,CAAAA,CAAG,CAAC,CAAA,CAAGC,CAAC,CAAA,CAAIA,CAAAA,CAEzC,IAAA,IAAS/D,CAAAA,CAAI,CAAA,CAAGA,CAAAA,EAAK6D,CAAAA,CAAG7D,IACtB,IAAA,IAAS+D,CAAAA,CAAI,CAAA,CAAGA,CAAAA,EAAKnE,CAAAA,CAAGmE,CAAAA,EAAAA,CAClBrE,CAAAA,CAAEM,CAAAA,CAAI,CAAC,CAAA,GAAML,CAAAA,CAAEoE,CAAAA,CAAI,CAAC,CAAA,CACtBD,CAAAA,CAAG9D,CAAC,CAAA,CAAG+D,CAAC,CAAA,CAAID,CAAAA,CAAG9D,CAAAA,CAAI,CAAC,CAAA,CAAG+D,CAAAA,CAAI,CAAC,CAAA,CAE5BD,CAAAA,CAAG9D,CAAC,CAAA,CAAG+D,CAAC,CAAA,CAAI,CAAA,CAAI,KAAK,GAAA,CAAID,CAAAA,CAAG9D,CAAAA,CAAI,CAAC,CAAA,CAAG+D,CAAC,CAAA,CAAID,CAAAA,CAAG9D,CAAC,CAAA,CAAG+D,CAAAA,CAAI,CAAC,CAAA,CAAID,CAAAA,CAAG9D,CAAAA,CAAI,CAAC,CAAA,CAAG+D,CAAAA,CAAI,CAAC,CAAE,CAAA,CAKjF,OAAOD,CACT,CAEA,SAASE,EAAAA,CAAaF,CAAAA,CAAgBpE,CAAAA,CAAaC,CAAAA,CAAasE,CAAAA,CAA6B,CAC3F,IAAMC,EAAoC,EAAC,CACvClE,CAAAA,CAAIN,CAAAA,CAAE,MAAA,CACNqE,CAAAA,CAAIpE,CAAAA,CAAE,MAAA,CAEV,KAAOK,CAAAA,CAAI,CAAA,EAAK+D,CAAAA,CAAI,CAAA,EACd/D,CAAAA,CAAI,CAAA,EAAK+D,CAAAA,CAAI,GAAKrE,CAAAA,CAAEM,CAAAA,CAAI,CAAC,CAAA,GAAML,CAAAA,CAAEoE,CAAAA,CAAI,CAAC,CAAA,EACxCG,CAAAA,CAAI,IAAA,CAAK,GAAG,CAAA,CACZlE,CAAAA,EAAAA,CACA+D,CAAAA,EAAAA,EACS/D,CAAAA,CAAI,CAAA,EAAK+D,EAAI,CAAA,EAAKD,CAAAA,CAAG9D,CAAC,CAAA,CAAG+D,CAAC,CAAA,GAAMD,CAAAA,CAAG9D,CAAAA,CAAI,CAAC,CAAA,CAAG+D,CAAAA,CAAI,CAAC,CAAA,CAAK,CAAA,EAC9DG,CAAAA,CAAI,IAAA,CAAK,GAAG,CAAA,CACZlE,CAAAA,EAAAA,CACA+D,CAAAA,EAAAA,EACSA,CAAAA,CAAI,CAAA,EAAKD,CAAAA,CAAG9D,CAAC,CAAA,CAAG+D,CAAC,CAAA,GAAMD,CAAAA,CAAG9D,CAAC,CAAA,CAAG+D,CAAAA,CAAI,CAAC,EAAK,CAAA,EACjDG,CAAAA,CAAI,IAAA,CAAK,GAAG,CAAA,CACZH,CAAAA,EAAAA,GAEAG,CAAAA,CAAI,IAAA,CAAK,GAAG,CAAA,CACZlE,CAAAA,EAAAA,CAAAA,CAGJkE,CAAAA,CAAI,OAAA,EAAQ,CAEZ,IAAMC,CAAAA,CAAgB,EAAC,CACnBC,CAAAA,CAAK,CAAA,CACLC,CAAAA,CAAK,CAAA,CACT,IAAA,IAAWC,CAAAA,IAAQJ,CAAAA,CACbI,CAAAA,GAAS,GAAA,EACXH,CAAAA,CAAI,IAAA,CAAK,CAAE,IAAA,CAAM,MAAA,CAAQ,MAAOE,CAAAA,CAAI,IAAA,CAAM1E,CAAAA,CAAE0E,CAAE,CAAA,CAAI,OAAA,CAASJ,CAAAA,CAAYG,CAAG,CAAC,CAAA,CAC3EA,CAAAA,EAAAA,CACAC,CAAAA,EAAAA,EACSC,CAAAA,GAAS,GAAA,EAClBH,CAAAA,CAAI,IAAA,CAAK,CACP,IAAA,CAAM,SAAA,CACN,KAAA,CAAOE,CAAAA,CACP,IAAA,CAAM3E,CAAAA,CAAE0E,CAAE,CAAA,CACV,EAAA,CAAIzE,CAAAA,CAAE0E,CAAE,CAAA,CACR,OAAA,CAASJ,CAAAA,CAAYG,CACvB,CAAC,CAAA,CACDA,CAAAA,EAAAA,CACAC,CAAAA,EAAAA,EACSC,CAAAA,GAAS,GAAA,EAClBH,CAAAA,CAAI,IAAA,CAAK,CAAE,IAAA,CAAM,QAAA,CAAU,KAAA,CAAOE,CAAAA,CAAI,IAAA,CAAM1E,CAAAA,CAAE0E,CAAE,CAAG,CAAC,CAAA,CACpDA,CAAAA,EAAAA,EAEAD,CAAAA,EAAAA,CAGJ,OAAOD,CACT,CAGO,SAASI,EAAAA,CAAUC,CAAAA,CAAcC,CAAAA,CAAcR,CAAAA,CAAY,CAAA,CAAa,CAC7E,IAAMvE,CAAAA,CAAI,CAAC,GAAG8E,CAAI,CAAA,CACZ7E,CAAAA,CAAI,CAAC,GAAG8E,CAAI,CAAA,CACZX,CAAAA,CAAKF,CAAAA,CAAkBlE,CAAAA,CAAGC,CAAC,CAAA,CACjC,OAAOqE,EAAAA,CAAaF,CAAAA,CAAIpE,CAAAA,CAAGC,CAAAA,CAAGsE,CAAS,CACzC,CAEA,SAASS,EAAAA,CAAWP,CAAAA,CAAeQ,CAAAA,CAA4B,CAC7D,IAAIC,CAAAA,CAASD,CAAAA,CACPE,CAAAA,CAAmB,EAAC,CAC1B,IAAA,IAAWC,KAAMX,CAAAA,CACf,GAAIW,CAAAA,CAAG,IAAA,GAAS,QAAA,CACdD,CAAAA,CAAO,IAAA,CAAK,CAAE,IAAA,CAAM,QAAA,CAAU,KAAA,CAAOD,CAAAA,EAAAA,CAAU,IAAA,CAAME,CAAAA,CAAG,IAAK,CAAC,UACrDA,CAAAA,CAAG,IAAA,GAAS,MAAA,CAAQ,CAC7B,IAAMC,CAAAA,CAAe,CACnB,IAAA,CAAM,MAAA,CACN,KAAA,CAAOH,CAAAA,EAAAA,CACP,IAAA,CAAME,CAAAA,CAAG,IAAA,CACT,OAAA,CAASA,CAAAA,CAAG,OACd,CAAA,CACIA,CAAAA,CAAG,MAAA,GAAQC,CAAAA,CAAK,MAAA,CAASD,CAAAA,CAAG,MAAA,CAAA,CAChCD,CAAAA,CAAO,IAAA,CAAKE,CAAI,EAClB,CAAA,KAAWD,CAAAA,CAAG,IAAA,GAAS,SAAA,EACrBD,CAAAA,CAAO,IAAA,CAAK,CACV,IAAA,CAAM,SAAA,CACN,KAAA,CAAOD,CAAAA,EAAAA,CACP,IAAA,CAAME,CAAAA,CAAG,IAAA,CACT,EAAA,CAAIA,CAAAA,CAAG,EAAA,CACP,OAAA,CAASA,CAAAA,CAAG,OACd,CAAC,EAGL,OAAOD,CACT,CAOA,SAASG,EAAAA,CAAYR,CAAAA,CAAcC,CAAAA,CAAwB,CACzD,IAAMN,CAAAA,CAAgB,EAAC,CACvB,IAAA,IAAS,CAAA,CAAI,CAAA,CAAG,CAAA,CAAIM,EAAK,MAAA,CAAQ,CAAA,EAAA,CAAK,CACpC,IAAMpF,CAAAA,CAAOmF,CAAAA,CAAK,CAAC,CAAA,CACblF,CAAAA,CAAKmF,CAAAA,CAAK,CAAC,CAAA,CACbpF,CAAAA,GAASC,CAAAA,CACX6E,CAAAA,CAAI,IAAA,CAAK,CAAE,IAAA,CAAM,MAAA,CAAQ,KAAA,CAAO,CAAA,CAAG,IAAA,CAAM7E,CAAAA,CAAI,OAAA,CAAS,CAAE,CAAC,CAAA,CAEzD6E,CAAAA,CAAI,IAAA,CAAK,CAAE,IAAA,CAAM,SAAA,CAAW,KAAA,CAAO,CAAA,CAAG,IAAA,CAAA9E,CAAAA,CAAM,EAAA,CAAAC,CAAAA,CAAI,OAAA,CAAS,CAAE,CAAC,EAEhE,CACA,OAAO6E,CACT,CAEO,SAASc,CAAAA,CAAKT,CAAAA,CAAcC,EAAwB,CACzD,GAAID,CAAAA,CAAK,MAAA,GAAWC,CAAAA,CAAK,MAAA,CAAQ,OAAOO,EAAAA,CAAYR,CAAAA,CAAMC,CAAI,CAAA,CAE9D,IAAIS,CAAAA,CAAM,CAAA,CACV,KAAOA,CAAAA,CAAMV,CAAAA,CAAK,MAAA,EAAUU,CAAAA,CAAMT,CAAAA,CAAK,MAAA,EAAUD,CAAAA,CAAKU,CAAG,CAAA,GAAMT,CAAAA,CAAKS,CAAG,CAAA,EAAGA,CAAAA,EAAAA,CAE1E,IAAIC,CAAAA,CAAM,CAAA,CACV,KACEA,EAAMX,CAAAA,CAAK,MAAA,CAASU,CAAAA,EACpBC,CAAAA,CAAMV,CAAAA,CAAK,MAAA,CAASS,CAAAA,EACpBV,CAAAA,CAAKA,CAAAA,CAAK,MAAA,CAAS,CAAA,CAAIW,CAAG,CAAA,GAAMV,CAAAA,CAAKA,CAAAA,CAAK,MAAA,CAAS,CAAA,CAAIU,CAAG,CAAA,EAE1DA,CAAAA,EAAAA,CAGF,IAAMhB,CAAAA,CAAgB,EAAC,CACnBS,CAAAA,CAAS,CAAA,CAEb,IAAA,IAAS5E,CAAAA,CAAI,CAAA,CAAGA,CAAAA,CAAIkF,CAAAA,CAAKlF,CAAAA,EAAAA,CACvBmE,EAAI,IAAA,CAAK,CAAE,IAAA,CAAM,MAAA,CAAQ,KAAA,CAAOS,CAAAA,EAAAA,CAAU,IAAA,CAAMH,CAAAA,CAAKzE,CAAC,CAAA,CAAI,OAAA,CAASA,CAAE,CAAC,CAAA,CAGxE,IAAMoF,CAAAA,CAAUZ,EAAK,KAAA,CAAMU,CAAAA,CAAKV,CAAAA,CAAK,MAAA,CAASW,CAAG,CAAA,CAC3CE,CAAAA,CAAUZ,CAAAA,CAAK,KAAA,CAAMS,CAAAA,CAAKT,CAAAA,CAAK,MAAA,CAASU,CAAG,CAAA,CAC3CG,CAAAA,CAAS,IAAA,CAAK,IAAIF,CAAAA,CAAQ,MAAA,CAAQC,CAAAA,CAAQ,MAAM,CAAA,CAEtD,GAAIC,CAAAA,CAAS,CAAA,CAIX,GAHgB1B,CAAAA,CAAkB,CAAC,GAAGwB,CAAO,CAAA,CAAG,CAAC,GAAGC,CAAO,CAAC,CAAA,CAAED,CAAAA,CAAQ,MAAM,CAAA,CAAGC,CAAAA,CAAQ,MAAM,CAAA,CAC3DC,CAAAA,CAAS,EAAA,CAGzC,IAAA,IAAStF,CAAAA,CAAI,CAAA,CAAGA,CAAAA,CAAIqF,CAAAA,CAAQ,OAAQrF,CAAAA,EAAAA,CAClCmE,CAAAA,CAAI,IAAA,CAAK,CAAE,IAAA,CAAM,QAAA,CAAU,KAAA,CAAOS,CAAAA,EAAAA,CAAU,IAAA,CAAMS,CAAAA,CAAQrF,CAAC,CAAG,CAAC,CAAA,CAAA,KAGjEmE,CAAAA,CAAI,IAAA,CAAK,GAAGO,EAAAA,CAAWH,EAAAA,CAAUa,CAAAA,CAASC,CAAAA,CAASH,CAAG,CAAA,CAAGN,CAAM,CAAC,CAAA,CAChEA,CAAAA,EAAUS,CAAAA,CAAQ,MAAA,CAItB,IAAME,CAAAA,CAAc,IAAA,CAAK,IAAIL,CAAAA,CAAKT,CAAAA,CAAK,MAAA,CAASU,CAAG,CAAA,CACnD,IAAA,IAASnF,CAAAA,CAAIuF,CAAAA,CAAavF,CAAAA,CAAIyE,CAAAA,CAAK,MAAA,CAAQzE,CAAAA,EAAAA,CAAK,CAC9C,IAAMwF,CAAAA,CAAUhB,CAAAA,CAAK,MAAA,CAASW,CAAAA,EAAOnF,CAAAA,EAAKyE,CAAAA,CAAK,MAAA,CAASU,CAAAA,CAAAA,CAAAA,CACpDK,CAAAA,CAAUN,CAAAA,EACdf,CAAAA,CAAI,IAAA,CAAK,CACP,IAAA,CAAM,MAAA,CACN,KAAA,CAAOS,CAAAA,EAAAA,CACP,IAAA,CAAMH,EAAKzE,CAAC,CAAA,CACZ,OAAA,CAASwF,CAAAA,CACT,MAAA,CAAQ,QACV,CAAC,EACH,CAEA,OAAOrB,CACT,CCrLA,IAAIsB,EAAAA,CAAS,CAAA,CACb,SAASC,EAAQC,CAAAA,CAAwB,CACvC,OAAO,CAAA,EAAGA,CAAM,CAAA,CAAA,EAAI,EAAEF,EAAM,CAAA,CAC9B,CAEA,SAASG,CAAAA,CAAWC,CAAAA,CAAoBC,CAAAA,CAAiBC,CAAAA,CAA0B,CACjF,OAAOF,CAAAA,CAASC,CAAO,CAAA,EAAKJ,CAAAA,CAAQK,CAAQ,CAC9C,CAEA,SAASC,EAAAA,CAAmBjD,CAAAA,CAA4C,CACtE,IAAMF,CAAAA,CAAME,CAAAA,CAAS,GAAA,CAAKkD,CAAAA,GAAO,CAAE,GAAGA,CAAE,CAAA,CAAE,CAAA,CACtCjG,CAAAA,CAAI,CAAA,CAER,KAAOA,CAAAA,CAAI6C,CAAAA,CAAI,MAAA,EAAQ,CAErB,GAAI,CADQA,CAAAA,CAAI7C,CAAC,EACR,QAAA,CAAU,CACjBA,CAAAA,EAAAA,CACA,QACF,CACA,IAAI+D,CAAAA,CAAI/D,CAAAA,CAAI,CAAA,CACZ,KAAO+D,CAAAA,CAAIlB,CAAAA,CAAI,MAAA,EAAUA,CAAAA,CAAIkB,CAAC,CAAA,CAAG,QAAA,EAAUA,CAAAA,EAAAA,CAC3C,IAAMmC,CAAAA,CAAMnC,CAAAA,CAAI/D,CAAAA,CAChB,IAAA,IAASb,CAAAA,CAAIa,CAAAA,CAAGb,CAAAA,CAAI4E,CAAAA,CAAG5E,CAAAA,EAAAA,CACrB0D,CAAAA,CAAI1D,CAAC,CAAA,CAAI,CAAE,GAAG0D,CAAAA,CAAI1D,CAAC,CAAA,CAAI,QAAA,CAAUA,CAAAA,CAAIa,CAAAA,CAAG,SAAA,CAAWkG,CAAI,CAAA,CAEzDlG,CAAAA,CAAI+D,EACN,CAEA,OAAOlB,CACT,CAEA,SAASsD,CAAAA,CACPzH,CAAAA,CACA2E,CAAAA,CACA+C,CAAAA,CAAgC,EAAC,CAClB,CACf,OAAO,CACL,GAAA,CAAA/C,CAAAA,CACA,IAAA,CAAA3E,CAAAA,CACA,IAAA,CAAMI,CAAAA,CAASJ,CAAI,EACnB,IAAA,CAAM0H,CAAAA,CAAM,IAAA,EAAQlH,CAAAA,CAAYR,CAAI,CAAA,CACpC,GAAG0H,CACL,CACF,CAEA,SAASC,EAAAA,CAAclC,CAAAA,CAAe0B,CAAAA,CAAqC,CACzE,IAAM9C,EAA4B,EAAC,CAEnC,IAAA,IAAW+B,CAAAA,IAAMX,CAAAA,CAAK,CACpB,GAAIW,CAAAA,CAAG,IAAA,GAAS,MAAA,CAAQ,CACtB/B,CAAAA,CAAS,IAAA,CAAKoD,CAAAA,CAAYrB,CAAAA,CAAG,IAAA,CAAMc,EAAWC,CAAAA,CAAUf,CAAAA,CAAG,OAAA,CAAS,GAAG,CAAC,CAAC,CAAA,CACzE,QACF,CAEA,GAAIA,CAAAA,CAAG,IAAA,GAAS,SAAA,CAAW,CACzB/B,CAAAA,CAAS,IAAA,CACPoD,CAAAA,CAAYrB,CAAAA,CAAG,EAAA,CAAIc,CAAAA,CAAWC,CAAAA,CAAUf,CAAAA,CAAG,OAAA,CAAS,GAAG,CAAA,CAAG,CACxD,IAAA,CAAM1F,CAAAA,CAAe0F,CAAAA,CAAG,IAAA,CAAMA,CAAAA,CAAG,EAAE,EACnC,QAAA,CAAUA,CAAAA,CAAG,IAAA,CACb,QAAA,CAAUhG,CAAAA,CAASgG,CAAAA,CAAG,IAAI,CAC5B,CAAC,CACH,CAAA,CACA,QACF,CAEIA,CAAAA,CAAG,IAAA,GAAS,QAAA,EACd/B,EAAS,IAAA,CAAKoD,CAAAA,CAAYrB,CAAAA,CAAG,IAAA,CAAMY,CAAAA,CAAQ,GAAG,CAAA,CAAG,CAAE,QAAA,CAAU,IAAK,CAAC,CAAC,EAExE,CAEA,OAAOM,EAAAA,CAAmBjD,CAAQ,CACpC,CAEO,SAASuD,CAAAA,CACd9B,CAAAA,CACAC,CAAAA,CACA8B,CAAAA,CAC+C,CAC/C,IAAMxD,CAAAA,CAAWsD,EAAAA,CAAcpB,CAAAA,CAAKT,CAAAA,CAAMC,CAAI,CAAA,CAAG8B,CAAe,CAAA,CAChE,OAAO,CAAE,QAAA,CAAAxD,CAAAA,CAAU,IAAA,CAAMA,CAAAA,CAAS,GAAA,CAAKkD,CAAAA,EAAMA,CAAAA,CAAE,GAAG,CAAE,CACtD,CAEO,SAASO,CAAAA,CAAgBnE,EAG9B,CACA,IAAMU,CAAAA,CAAW,CAAC,GAAGV,CAAK,CAAA,CAAE,GAAA,CAAI,CAAC3D,CAAAA,CAAM,CAAA,GAAMyH,CAAAA,CAAYzH,CAAAA,CAAMgH,CAAAA,CAAQ,CAAA,CAAA,EAAI,CAAC,EAAE,CAAC,CAAC,CAAA,CAChF,OAAO,CAAE,QAAA,CAAA3C,CAAAA,CAAU,IAAA,CAAMA,CAAAA,CAAS,GAAA,CAAKkD,CAAAA,EAAMA,CAAAA,CAAE,GAAG,CAAE,CACtD,CCzFO,IAAMQ,CAAAA,CAAS;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,sBAAA,EAOEnI,EAAa,QAAQ,CAAA;AAAA,oBAAA,EACvBA,EAAa,MAAM,CAAA;AAAA,uBAAA,EAChBC,EAAc,QAAQ,CAAA;AAAA,qBAAA,EACxBA,EAAc,MAAM,CAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,CAAA,CAwEzC,IAAA,EAAK,CAEA,SAASmI,CAAAA,CAAiB3I,CAAAA,CAAmB4I,CAAAA,CAAsB,CACpEA,CAAAA,GAAW,OAAA,EACb5I,CAAAA,CAAK,KAAA,CAAM,aAAA,CAAgB,WAAA,CAC3BA,CAAAA,CAAK,KAAA,CAAM,aAAA,CAAgB,QAAA,GAE3BA,CAAAA,CAAK,KAAA,CAAM,aAAA,CAAgB,EAAA,CAC3BA,CAAAA,CAAK,KAAA,CAAM,aAAA,CAAgB,EAAA,EAE/B,CAEO,SAAS6I,CAAAA,CACd7I,CAAAA,CACA8I,EACAC,CAAAA,CACM,CACN,IAAMb,CAAAA,CAAI,CAAE,GAAG3H,CAAAA,CAAc,GAAGuI,CAAK,CAAA,CAC/BE,CAAAA,CAAI,CAAE,GAAGxI,CAAAA,CAAe,GAAGuI,CAAM,CAAA,CACvC/I,CAAAA,CAAK,KAAA,CAAM,WAAA,CAAY,oBAAA,CAAsB,CAAA,EAAGkI,CAAAA,CAAE,QAAQ,CAAA,EAAA,CAAI,CAAA,CAC9DlI,CAAAA,CAAK,KAAA,CAAM,WAAA,CAAY,kBAAA,CAAoBkI,EAAE,MAAM,CAAA,CACnDlI,CAAAA,CAAK,KAAA,CAAM,WAAA,CAAY,qBAAA,CAAuB,CAAA,EAAGgJ,CAAAA,CAAE,QAAQ,CAAA,EAAA,CAAI,CAAA,CAC/DhJ,CAAAA,CAAK,KAAA,CAAM,WAAA,CAAY,mBAAA,CAAqBgJ,CAAAA,CAAE,MAAM,EACtD,CAEO,SAASC,CAAAA,CAAYC,CAAAA,CAA0B,CACpD,OAAOA,CAAAA,GAAM,OAAA,CAAU,OAAA,CAAU,OACnC,CC1GA,IAAMC,GAAM,WAAA,CAECC,CAAAA,CAAN,cAA8B,WAAY,CAC/C,OAAO,kBAAA,CAAqB,CAAC,OAAA,CAAS,QAAA,CAAU,UAAU,CAAA,CAE1DC,EAAAA,CACAC,EAAAA,CACAC,EAAAA,CAAa,EAAA,CACbC,EAAAA,CAAkB,EAAC,CACnBC,EAAAA,CAAe,MAAA,CAAO,UAAA,CAAW,kCAAkC,CAAA,CACnEC,EAAAA,CAAkB,IAAY,IAAA,CAAKC,EAAAA,EAAa,CAChDC,EAAAA,CAEAC,GACAC,EAAAA,CAEA,iBAAA,EAA0B,CACxB,GAAI,CAAC,IAAA,CAAK,UAAA,CAAY,CACpB,IAAM5F,CAAAA,CAAO,IAAA,CAAK,YAAA,CAAa,CAAE,IAAA,CAAM,MAAO,CAAC,CAAA,CACzC6F,CAAAA,CAAQ,QAAA,CAAS,aAAA,CAAc,OAAO,CAAA,CAC5CA,CAAAA,CAAM,WAAA,CAAcrB,CAAAA,CACpB,IAAMsB,CAAAA,CAAQ,QAAA,CAAS,aAAA,CAAc,KAAK,EAC1CA,CAAAA,CAAM,SAAA,CAAY,MAAA,CAClBA,CAAAA,CAAM,YAAA,CAAa,MAAA,CAAQ,MAAM,CAAA,CAEjC,IAAA,CAAKX,EAAAA,CAAM,QAAA,CAAS,aAAA,CAAc,MAAM,CAAA,CACxC,IAAA,CAAKA,EAAAA,CAAI,SAAA,CAAY,IAAA,CACrB,IAAA,CAAKA,EAAAA,CAAI,YAAA,CAAa,WAAA,CAAa,QAAQ,CAAA,CAC3C,IAAA,CAAKA,EAAAA,CAAI,YAAA,CAAa,aAAA,CAAe,MAAM,CAAA,CAE3C,KAAKC,EAAAA,CAAU,QAAA,CAAS,aAAA,CAAc,MAAM,CAAA,CAC5C,IAAA,CAAKA,EAAAA,CAAQ,SAAA,CAAY,QAAA,CACzB,IAAA,CAAKA,EAAAA,CAAQ,YAAA,CAAa,aAAA,CAAe,MAAM,CAAA,CAE/CU,CAAAA,CAAM,MAAA,CAAO,IAAA,CAAKX,EAAAA,CAAK,IAAA,CAAKC,EAAO,CAAA,CACnCpF,CAAAA,CAAK,MAAA,CAAO6F,CAAAA,CAAOC,CAAK,EAC1B,CAEA,IAAA,CAAKP,EAAAA,CAAa,gBAAA,CAAiB,QAAA,CAAU,IAAA,CAAKC,EAAe,CAAA,CACjE,IAAA,CAAKC,EAAAA,EAAa,CAClB,IAAA,CAAKM,EAAAA,EAAc,CACnB,IAAA,CAAKL,EAAAA,CAAe1J,CAAAA,CAAe,IAAI,CAAA,CACvC,IAAA,CAAKgK,EAAAA,CAAQ,IAAI,EACnB,CAEA,oBAAA,EAA6B,CAC3B,IAAA,CAAKT,EAAAA,CAAa,mBAAA,CAAoB,QAAA,CAAU,IAAA,CAAKC,EAAe,CAAA,CACpE,IAAA,CAAKE,EAAAA,KACL,IAAA,CAAKA,EAAAA,CAAe,OACtB,CAEA,wBAAA,CAAyBO,CAAAA,CAAoB,CAC3C,GAAK,IAAA,CAAK,WAAA,CACV,CAAA,GAAIA,CAAAA,GAAS,OAAA,CAAS,CACpB,IAAA,CAAKD,EAAAA,CAAQ,KAAK,CAAA,CAClB,MACF,CACA,IAAA,CAAKD,EAAAA,EAAc,CACfE,CAAAA,GAAS,UAAA,EAAY,IAAA,CAAKD,EAAAA,CAAQ,KAAK,EAAA,CAC7C,CAEA,IAAI,KAAA,EAAgB,CAClB,OAAO,IAAA,CAAK,YAAA,CAAa,OAAO,CAAA,EAAK,EACvC,CAEA,IAAI,KAAA,CAAMhB,CAAAA,CAAW,CACnB,IAAA,CAAK,YAAA,CAAa,OAAA,CAASA,CAAC,EAC9B,CAEA,IAAI,MAAA,EAAiB,CACnB,OAAOD,CAAAA,CAAY,IAAA,CAAK,YAAA,CAAa,QAAQ,CAAC,CAChD,CAEA,IAAI,MAAA,CAAOC,CAAAA,CAAW,CACpB,IAAA,CAAK,YAAA,CAAa,QAAA,CAAUA,CAAC,EAC/B,CAEA,IAAI,QAAA,EAAoB,CACtB,OAAO,IAAA,CAAK,YAAA,CAAa,UAAU,CAAA,GAAM,OAC3C,CAEA,IAAI,QAAA,CAASA,CAAAA,CAAY,CACnBA,CAAAA,CAAG,IAAA,CAAK,eAAA,CAAgB,UAAU,CAAA,CACjC,IAAA,CAAK,YAAA,CAAa,UAAA,CAAY,OAAO,EAC5C,CAEA,IAAI,UAAA,CAAW,CAAA,CAA6B,CAC1C,IAAA,CAAKW,EAAAA,CAAc,CAAA,CACnB,IAAA,CAAKI,EAAAA,GACP,CAEA,IAAI,WAAA,CAAY,CAAA,CAA6B,CAC3C,IAAA,CAAKH,EAAAA,CAAe,CAAA,CACpB,IAAA,CAAKG,EAAAA,GACP,CAEAG,EAAAA,EAAuB,CAErB,OADI,EAAA,CAAC,IAAA,CAAK,QAAA,EACN,KAAKX,EAAAA,CAAa,OAAA,CAExB,CAEAE,EAAAA,EAAqB,CACf,IAAA,CAAKF,EAAAA,CAAa,OAAA,CAAS,IAAA,CAAK,OAAA,CAAQ,OAAA,CAAU,EAAA,CACjD,OAAO,IAAA,CAAK,OAAA,CAAQ,QAC3B,CAEAQ,EAAAA,EAAsB,CACpBtB,CAAAA,CAAiB,IAAA,CAAM,IAAA,CAAK,MAAM,CAAA,CAClCE,CAAAA,CAAa,IAAA,CAAM,IAAA,CAAKgB,EAAAA,CAAa,IAAA,CAAKC,EAAY,EACtD/J,CAAAA,CAAY,IAAI,EAClB,CAEAmK,EAAAA,CAAQG,CAAAA,CAAwB,CAC9B,IAAM3D,CAAAA,CAAO,IAAA,CAAK,KAAA,CAClB,IAAA,CAAK2C,EAAAA,CAAI,WAAA,CAAc3C,CAAAA,CAEvB,IAAM5C,CAAAA,CAAW,IAAA,CAAKsG,EAAAA,EAAY,EAAK,CAACC,CAAAA,CAEpCrF,CAAAA,CACJ,GAAIqF,CAAAA,EAAW,CAAC,IAAA,CAAKd,EAAAA,CAAY,CAC/B,IAAMe,EAAO7B,CAAAA,CAAgB/B,CAAI,CAAA,CACjC1B,CAAAA,CAAWsF,CAAAA,CAAK,QAAA,CAChB,IAAA,CAAKd,EAAAA,CAAQc,CAAAA,CAAK,KACpB,CAAA,KAAO,CAAA,GAAI,IAAA,CAAKf,EAAAA,GAAe7C,CAAAA,CAC7B,OACK,CACL,IAAM6D,CAAAA,CAAQhC,CAAAA,CAAc,IAAA,CAAKgB,EAAAA,CAAY7C,CAAAA,CAAM,IAAA,CAAK8C,EAAK,CAAA,CAC7DxE,CAAAA,CAAWuF,CAAAA,CAAM,QAAA,CACjB,IAAA,CAAKf,EAAAA,CAAQe,CAAAA,CAAM,KACrB,CAAA,CAEAxF,CAAAA,CAAY,IAAA,CAAKuE,EAAAA,CAAStE,CAAAA,CAAUlB,CAAQ,CAAA,CAC5C,IAAA,CAAKyF,EAAAA,CAAa7C,EACpB,CACF,EAEO,SAAS8D,EAAAA,CAAeC,CAAAA,CAAMtB,EAAAA,CAAW,CACzC,cAAA,CAAe,GAAA,CAAIsB,CAAG,CAAA,EACzB,cAAA,CAAe,MAAA,CAAOA,CAAAA,CAAKrB,CAAe,EAE9C,CAEAoB,EAAAA,EAAe","file":"element.js","sourcesContent":["/** Sync layout CSS variables from computed host styles. */\nexport function syncMetrics(host: HTMLElement): void {\n const { letterSpacing } = getComputedStyle(host)\n host.style.setProperty('--cf-letter-gap', letterSpacing === 'normal' ? '0px' : letterSpacing)\n}\n\nexport function observeMetrics(host: HTMLElement): () => void {\n const run = (): void => syncMetrics(host)\n\n run()\n\n const ro = new ResizeObserver(run)\n ro.observe(host)\n\n document.fonts?.ready.then(run).catch(() => undefined)\n\n return () => ro.disconnect()\n}\n","export type CharKind = 'digit' | 'letter' | 'other'\n\nexport type Preset = 'plate' | 'alnum'\n\n/** How a changed character moves: roll through an alphabet, or a direct swap. */\nexport type AnimKind = 'wheel-digit' | 'wheel-letter' | 'slide' | 'static'\n\nexport interface EffectTiming {\n duration?: number\n easing?: string\n delay?: number\n}\n\nexport interface CharFlowOptions {\n preset?: Preset\n animated?: boolean\n spinTiming?: EffectTiming\n slideTiming?: EffectTiming\n}\n\nexport type DiffOp =\n | { type: 'keep'; index: number; char: string; prevKey: number; region?: 'suffix' }\n | { type: 'replace'; index: number; from: string; to: string; prevKey: number }\n | { type: 'insert'; index: number; char: string }\n\nexport interface RenderSegment {\n key: string\n char: string\n kind: CharKind\n anim: AnimKind\n fromChar?: string\n fromKind?: CharKind\n entering?: boolean\n /** Index inside a consecutive insert run (for stagger). */\n runIndex?: number\n /** Length of the current insert run. */\n runLength?: number\n}\n\nexport const DIGITS = '0123456789' as const\nexport const LETTERS = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' as const\n\nexport const DEFAULT_SPIN: Required<EffectTiming> = {\n duration: 520,\n easing: 'cubic-bezier(0.32, 0.72, 0, 1)',\n delay: 0,\n}\n\n/** Used for direct swaps (non-roll) and for entering/exiting/shifting cells. */\nexport const DEFAULT_SLIDE: Required<EffectTiming> = {\n duration: 340,\n easing: 'cubic-bezier(0.32, 0.72, 0, 1)',\n delay: 0,\n}\n\n/** Delay between cells in an insert run. */\nexport const STAGGER_STEP_MS = 16\n","export function formatChar(char: string): string {\n return char === ' ' ? '\\u00a0' : char\n}\n\nexport function displayLetter(stripChar: string, target: string): string {\n if (target >= 'a' && target <= 'z') return stripChar.toLowerCase()\n return stripChar\n}\n","import type { AnimKind, CharKind } from './types'\n\nexport function classify(char: string): CharKind {\n if (!char) return 'other'\n const code = char.charCodeAt(0)\n if (code >= 48 && code <= 57) return 'digit'\n if ((code >= 65 && code <= 90) || (code >= 97 && code <= 122)) return 'letter'\n return 'other'\n}\n\nexport function wheelIndex(char: string, kind: CharKind): number {\n if (kind === 'digit') return char.charCodeAt(0) - 48\n const upper = char.toUpperCase()\n return upper.charCodeAt(0) - 65\n}\n\n/** Resting animation tag for an unchanged character. */\nexport function animForChar(char: string): AnimKind {\n const k = classify(char)\n if (k === 'digit') return 'wheel-digit'\n if (k === 'letter') return 'wheel-letter'\n return 'static'\n}\n\n/**\n * Same alphabet (digit→digit, letter→letter) rolls through that alphabet.\n * Everything else (cross-kind, or any change involving punctuation) is a\n * direct two-glyph roll: old slides out, new slides in, no in-betweens.\n */\nexport function animForReplace(from: string, to: string): AnimKind {\n const fk = classify(from)\n const tk = classify(to)\n if (fk === 'digit' && tk === 'digit') return 'wheel-digit'\n if (fk === 'letter' && tk === 'letter') return 'wheel-letter'\n return 'slide'\n}\n\nexport function spinDirection(from: string, to: string, kind: CharKind): 1 | -1 {\n const a = wheelIndex(from, kind)\n const b = wheelIndex(to, kind)\n if (a === b) return 1\n const n = kind === 'letter' ? 26 : 10\n const up = (b - a + n) % n\n const down = (a - b + n) % n\n return up <= down ? 1 : -1\n}\n","import { spinDirection, wheelIndex } from '../classify'\nimport { DIGITS, LETTERS } from '../types'\nimport type { RenderSegment } from '../types'\nimport { displayLetter, formatChar } from './format'\n\n/**\n * A vertical column of glyphs plus the start/end positions to slide between.\n * Every animated transition — digit roll, letter roll, or text replacement —\n * is expressed as this one primitive: a stack translated along Y.\n */\nexport interface StackPlan {\n /** Glyphs in visual order, top to bottom. */\n chars: string[]\n /** Index showing at the start of the animation. */\n startIdx: number\n /** Index showing at the end of the animation. */\n endIdx: number\n}\n\nfunction charForIndex(i: number, kind: 'digit' | 'letter', target: string): string {\n if (kind === 'digit') return DIGITS[i]!\n return displayLetter(LETTERS[i]!, target)\n}\n\n/** Glyphs along the shortest path from `from` to `to` around the alphabet. */\nfunction wheelPlan(from: string, to: string, kind: 'digit' | 'letter'): StackPlan {\n const n = kind === 'letter' ? LETTERS.length : DIGITS.length\n const a = wheelIndex(from, kind)\n const b = wheelIndex(to, kind)\n const dir = spinDirection(from, to, kind)\n\n const path: string[] = []\n for (let i = a; ; i = (i + dir + n) % n) {\n path.push(charForIndex(i, kind, to))\n if (i === b) break\n }\n\n // dir +1 rolls up (content moves up, next glyph enters from below).\n // dir -1 rolls down, so reverse the column and start from the bottom.\n if (dir === 1) return { chars: path, startIdx: 0, endIdx: path.length - 1 }\n return { chars: [...path].reverse(), startIdx: path.length - 1, endIdx: 0 }\n}\n\n/** A single-step slide between two arbitrary glyphs (text replacement / morph). */\nfunction slidePlan(from: string, to: string): StackPlan {\n return { chars: [formatChar(from), formatChar(to)], startIdx: 0, endIdx: 1 }\n}\n\n/** Build the plan for a segment, or null if there is nothing to animate. */\nexport function planFor(seg: RenderSegment): StackPlan | null {\n if (seg.fromChar == null || seg.fromChar === seg.char) return null\n if (seg.anim === 'wheel-digit') return wheelPlan(seg.fromChar, seg.char, 'digit')\n if (seg.anim === 'wheel-letter') return wheelPlan(seg.fromChar, seg.char, 'letter')\n return slidePlan(seg.fromChar, seg.char)\n}\n\nexport function isWheel(seg: RenderSegment): boolean {\n return seg.anim === 'wheel-digit' || seg.anim === 'wheel-letter'\n}\n","import type { RenderSegment } from '../types'\nimport { STAGGER_STEP_MS } from '../types'\nimport { formatChar } from './format'\nimport { isWheel, planFor } from './stack'\n\nexport interface AnimContext {\n /** Measured cell height in px (one line of text). */\n cellHeight: number\n spin: { duration: number; easing: string }\n slide: { duration: number; easing: string }\n}\n\n/** Deferred animation: queued during build, launched once after layout. */\nexport type Pending = (ctx: AnimContext) => void\n\nfunction glyph(char: string): HTMLElement {\n const g = document.createElement('span')\n g.className = 'cf-glyph'\n g.setAttribute('part', 'glyph')\n g.textContent = formatChar(char)\n return g\n}\n\nfunction makeCell(seg: RenderSegment, extraClass = ''): HTMLElement {\n const cell = document.createElement('span')\n cell.className = extraClass ? `cf-cell ${extraClass}` : 'cf-cell'\n cell.dataset.key = seg.key\n cell.dataset.char = seg.char\n cell.setAttribute('part', 'segment')\n return cell\n}\n\nfunction staticCell(seg: RenderSegment): HTMLElement {\n const cell = makeCell(seg)\n cell.appendChild(glyph(seg.char))\n return cell\n}\n\nfunction enteringCell(seg: RenderSegment, pending: Pending[]): HTMLElement {\n const cell = staticCell(seg)\n const delay =\n seg.runLength && seg.runLength > 1 ? (seg.runIndex ?? 0) * STAGGER_STEP_MS : 0\n\n pending.push((ctx) => {\n cell.animate(\n [\n { opacity: 0, transform: 'translateY(0.25em)' },\n { opacity: 1, transform: 'translateY(0)' },\n ],\n { duration: ctx.slide.duration, easing: ctx.slide.easing, delay, fill: 'backwards' },\n )\n })\n return cell\n}\n\nfunction rollingCell(seg: RenderSegment, pending: Pending[]): HTMLElement {\n const plan = planFor(seg)!\n const wheel = isWheel(seg)\n const cell = makeCell(seg, wheel ? 'cf-cell--rolling' : '')\n\n // A normal-flow sizer (the resting glyph) owns the cell's width so it stays\n // constant; the multi-glyph stack floats above it and never affects layout.\n const sizer = glyph(seg.char)\n sizer.style.visibility = 'hidden'\n const stack = document.createElement('span')\n stack.className = 'cf-stack'\n for (const c of plan.chars) stack.appendChild(glyph(c))\n cell.append(sizer, stack)\n\n pending.push((ctx) => {\n const startY = -plan.startIdx * ctx.cellHeight\n const endY = -plan.endIdx * ctx.cellHeight\n const timing = wheel ? ctx.spin : ctx.slide\n\n stack.style.transform = `translateY(${startY}px)`\n const anim = stack.animate(\n [{ transform: `translateY(${startY}px)` }, { transform: `translateY(${endY}px)` }],\n { duration: timing.duration, easing: timing.easing, fill: 'forwards' },\n )\n // Drop the stack and reveal the resting sizer once the roll lands.\n anim.onfinish = () => {\n anim.cancel()\n stack.remove()\n sizer.style.visibility = ''\n cell.classList.remove('cf-cell--rolling')\n }\n })\n\n return cell\n}\n\nexport function buildCell(\n seg: RenderSegment,\n animated: boolean,\n pending: Pending[],\n): HTMLElement {\n if (seg.entering) {\n return animated ? enteringCell(seg, pending) : staticCell(seg)\n }\n if (animated && planFor(seg)) {\n return rollingCell(seg, pending)\n }\n return staticCell(seg)\n}\n\nexport function reuseCell(\n seg: RenderSegment,\n animated: boolean,\n existing: Map<string, HTMLElement>,\n pending: Pending[],\n): HTMLElement {\n const cell = existing.get(seg.key)\n // Unchanged, resting cells are reused untouched; anything that moves is rebuilt.\n if (cell && !seg.entering && seg.fromChar == null && cell.dataset.char === seg.char) {\n return cell\n }\n return buildCell(seg, animated, pending)\n}\n\nexport function existingCellMap(root: HTMLElement): Map<string, HTMLElement> {\n const map = new Map<string, HTMLElement>()\n for (const el of root.querySelectorAll('.cf-cell[data-key]')) {\n if (el instanceof HTMLElement && el.dataset.key) map.set(el.dataset.key, el)\n }\n return map\n}\n","import type { RenderSegment } from '../types'\nimport { existingCellMap, reuseCell, type AnimContext, type Pending } from './cell'\n\nfunction ms(value: string): number {\n const n = parseFloat(value)\n if (!Number.isFinite(n)) return 0\n return value.trim().endsWith('ms') ? n : n * 1000\n}\n\nfunction readContext(visual: HTMLElement): AnimContext {\n const cs = getComputedStyle(visual)\n const sample = visual.querySelector('.cf-glyph')\n return {\n cellHeight: sample instanceof HTMLElement ? sample.offsetHeight : 0,\n spin: {\n duration: ms(cs.getPropertyValue('--cf-spin-duration')),\n easing: cs.getPropertyValue('--cf-spin-easing').trim(),\n },\n slide: {\n duration: ms(cs.getPropertyValue('--cf-slide-duration')),\n easing: cs.getPropertyValue('--cf-slide-easing').trim(),\n },\n }\n}\n\n/** x offset (relative to the visual box) of each existing cell, keyed by data-key. */\nfunction measureX(visual: HTMLElement, cells: Iterable<HTMLElement>): Map<string, number> {\n const base = visual.getBoundingClientRect().left\n const out = new Map<string, number>()\n for (const el of cells) {\n if (el.dataset.key) out.set(el.dataset.key, el.getBoundingClientRect().left - base)\n }\n return out\n}\n\nexport function mountVisual(\n visual: HTMLElement,\n segments: RenderSegment[],\n animated: boolean,\n): void {\n const existing = existingCellMap(visual)\n\n // FLIP \"First\": record where every current cell sits before we touch the DOM.\n const firstX = animated ? measureX(visual, existing.values()) : new Map<string, number>()\n\n const pending: Pending[] = []\n const nodes: HTMLElement[] = []\n const survivors = new Set<string>()\n\n for (const seg of segments) {\n const node = reuseCell(seg, animated, existing, pending)\n survivors.add(seg.key)\n nodes.push(node)\n }\n\n // Cells present before but gone now: animate them out instead of popping.\n const exiting: HTMLElement[] = []\n if (animated) {\n for (const [key, el] of existing) {\n if (!survivors.has(key)) exiting.push(el)\n }\n }\n\n // Exiting cells stay in the DOM (absolutely positioned) so they don't affect width.\n visual.replaceChildren(...nodes, ...exiting)\n\n if (!pending.length && !exiting.length) return\n\n const ctx = readContext(visual)\n\n if (animated) {\n // FLIP \"Last/Invert/Play\": slide survivors from their old x back to the new one.\n const lastX = measureX(visual, nodes)\n for (const node of nodes) {\n const key = node.dataset.key\n if (!key) continue\n const before = firstX.get(key)\n const after = lastX.get(key)\n if (before === undefined || after === undefined) continue\n const dx = before - after\n if (Math.abs(dx) < 0.5) continue\n node.animate(\n [{ transform: `translateX(${dx}px)` }, { transform: 'translateX(0)' }],\n { duration: ctx.slide.duration, easing: ctx.slide.easing },\n )\n }\n\n for (const el of exiting) {\n const x = firstX.get(el.dataset.key!)\n const width = el.offsetWidth\n el.style.position = 'absolute'\n el.style.top = '0'\n el.style.left = `${x ?? 0}px`\n el.style.width = `${width}px`\n el.style.pointerEvents = 'none'\n const out = el.animate(\n [\n { opacity: 1, transform: 'translateY(0)' },\n { opacity: 0, transform: 'translateY(-0.25em)' },\n ],\n { duration: ctx.slide.duration, easing: ctx.slide.easing, fill: 'forwards' },\n )\n out.onfinish = () => el.remove()\n }\n }\n\n for (const run of pending) run(ctx)\n}\n","import type { DiffOp } from './types'\n\nfunction levenshteinMatrix(a: string[], b: string[]): number[][] {\n const m = a.length\n const n = b.length\n const dp: number[][] = Array.from({ length: m + 1 }, () =>\n Array.from({ length: n + 1 }, () => 0),\n )\n for (let i = 0; i <= m; i++) dp[i]![0] = i\n for (let j = 0; j <= n; j++) dp[0]![j] = j\n\n for (let i = 1; i <= m; i++) {\n for (let j = 1; j <= n; j++) {\n if (a[i - 1] === b[j - 1]) {\n dp[i]![j] = dp[i - 1]![j - 1]!\n } else {\n dp[i]![j] = 1 + Math.min(dp[i - 1]![j]!, dp[i]![j - 1]!, dp[i - 1]![j - 1]!)\n }\n }\n }\n\n return dp\n}\n\nfunction backtrackOps(dp: number[][], a: string[], b: string[], keyOffset: number): DiffOp[] {\n const raw: Array<'M' | 'I' | 'D' | 'R'> = []\n let i = a.length\n let j = b.length\n\n while (i > 0 || j > 0) {\n if (i > 0 && j > 0 && a[i - 1] === b[j - 1]) {\n raw.push('M')\n i--\n j--\n } else if (i > 0 && j > 0 && dp[i]![j] === dp[i - 1]![j - 1]! + 1) {\n raw.push('R')\n i--\n j--\n } else if (j > 0 && dp[i]![j] === dp[i]![j - 1]! + 1) {\n raw.push('I')\n j--\n } else {\n raw.push('D')\n i--\n }\n }\n raw.reverse()\n\n const ops: DiffOp[] = []\n let ai = 0\n let bi = 0\n for (const step of raw) {\n if (step === 'M') {\n ops.push({ type: 'keep', index: bi, char: b[bi]!, prevKey: keyOffset + ai })\n ai++\n bi++\n } else if (step === 'R') {\n ops.push({\n type: 'replace',\n index: bi,\n from: a[ai]!,\n to: b[bi]!,\n prevKey: keyOffset + ai,\n })\n ai++\n bi++\n } else if (step === 'I') {\n ops.push({ type: 'insert', index: bi, char: b[bi]! })\n bi++\n } else {\n ai++\n }\n }\n return ops\n}\n\n/** Shortest edit script via Wagner-Fischer. Deletes are omitted (cells simply disappear). */\nexport function diffChars(prev: string, next: string, keyOffset = 0): DiffOp[] {\n const a = [...prev]\n const b = [...next]\n const dp = levenshteinMatrix(a, b)\n return backtrackOps(dp, a, b, keyOffset)\n}\n\nfunction reindexOps(ops: DiffOp[], startIdx: number): DiffOp[] {\n let outIdx = startIdx\n const result: DiffOp[] = []\n for (const op of ops) {\n if (op.type === 'insert') {\n result.push({ type: 'insert', index: outIdx++, char: op.char })\n } else if (op.type === 'keep') {\n const keep: DiffOp = {\n type: 'keep',\n index: outIdx++,\n char: op.char,\n prevKey: op.prevKey,\n }\n if (op.region) keep.region = op.region\n result.push(keep)\n } else if (op.type === 'replace') {\n result.push({\n type: 'replace',\n index: outIdx++,\n from: op.from,\n to: op.to,\n prevKey: op.prevKey,\n })\n }\n }\n return result\n}\n\n/**\n * Slot-by-slot alignment for same-length values (e.g. license plates). Every\n * position rolls from its old char to its new one, so a dash moving from one\n * group to another rolls in place instead of being deleted and re-inserted.\n */\nfunction diffAligned(prev: string, next: string): DiffOp[] {\n const ops: DiffOp[] = []\n for (let i = 0; i < next.length; i++) {\n const from = prev[i]!\n const to = next[i]!\n if (from === to) {\n ops.push({ type: 'keep', index: i, char: to, prevKey: i })\n } else {\n ops.push({ type: 'replace', index: i, from, to, prevKey: i })\n }\n }\n return ops\n}\n\nexport function diff(prev: string, next: string): DiffOp[] {\n if (prev.length === next.length) return diffAligned(prev, next)\n\n let pre = 0\n while (pre < prev.length && pre < next.length && prev[pre] === next[pre]) pre++\n\n let suf = 0\n while (\n suf < prev.length - pre &&\n suf < next.length - pre &&\n prev[prev.length - 1 - suf] === next[next.length - 1 - suf]\n ) {\n suf++\n }\n\n const ops: DiffOp[] = []\n let outIdx = 0\n\n for (let i = 0; i < pre; i++) {\n ops.push({ type: 'keep', index: outIdx++, char: next[i]!, prevKey: i })\n }\n\n const midPrev = prev.slice(pre, prev.length - suf)\n const midNext = next.slice(pre, next.length - suf)\n const midMax = Math.max(midPrev.length, midNext.length)\n\n if (midMax > 0) {\n const midDist = levenshteinMatrix([...midPrev], [...midNext])[midPrev.length]![midNext.length]!\n const middleUnrelated = midDist / midMax > 0.4\n\n if (middleUnrelated) {\n for (let i = 0; i < midNext.length; i++) {\n ops.push({ type: 'insert', index: outIdx++, char: midNext[i]! })\n }\n } else {\n ops.push(...reindexOps(diffChars(midPrev, midNext, pre), outIdx))\n outIdx += midNext.length\n }\n }\n\n const suffixStart = Math.max(pre, next.length - suf)\n for (let i = suffixStart; i < next.length; i++) {\n const prevIdx = prev.length - suf + (i - (next.length - suf))\n if (prevIdx < pre) continue\n ops.push({\n type: 'keep',\n index: outIdx++,\n char: next[i]!,\n prevKey: prevIdx,\n region: 'suffix',\n })\n }\n\n return ops\n}\n","import { animForChar, animForReplace, classify } from './classify'\nimport { diff } from './diff'\nimport type { DiffOp, RenderSegment } from './types'\n\nlet keySeq = 0\nfunction nextKey(prefix: string): string {\n return `${prefix}-${++keySeq}`\n}\n\nfunction keyForPrev(prevKeys: string[], prevKey: number, fallback: string): string {\n return prevKeys[prevKey] ?? nextKey(fallback)\n}\n\nfunction assignEnteringRuns(segments: RenderSegment[]): RenderSegment[] {\n const out = segments.map((s) => ({ ...s }))\n let i = 0\n\n while (i < out.length) {\n const seg = out[i]!\n if (!seg.entering) {\n i++\n continue\n }\n let j = i + 1\n while (j < out.length && out[j]!.entering) j++\n const len = j - i\n for (let k = i; k < j; k++) {\n out[k] = { ...out[k]!, runIndex: k - i, runLength: len }\n }\n i = j\n }\n\n return out\n}\n\nfunction makeSegment(\n char: string,\n key: string,\n extra: Partial<RenderSegment> = {},\n): RenderSegment {\n return {\n key,\n char,\n kind: classify(char),\n anim: extra.anim ?? animForChar(char),\n ...extra,\n }\n}\n\nfunction opsToSegments(ops: DiffOp[], prevKeys: string[]): RenderSegment[] {\n const segments: RenderSegment[] = []\n\n for (const op of ops) {\n if (op.type === 'keep') {\n segments.push(makeSegment(op.char, keyForPrev(prevKeys, op.prevKey, 'k')))\n continue\n }\n\n if (op.type === 'replace') {\n segments.push(\n makeSegment(op.to, keyForPrev(prevKeys, op.prevKey, 'r'), {\n anim: animForReplace(op.from, op.to),\n fromChar: op.from,\n fromKind: classify(op.from),\n }),\n )\n continue\n }\n\n if (op.type === 'insert') {\n segments.push(makeSegment(op.char, nextKey('i'), { entering: true }))\n }\n }\n\n return assignEnteringRuns(segments)\n}\n\nexport function buildSegments(\n prev: string,\n next: string,\n prevSegmentKeys: string[],\n): { segments: RenderSegment[]; keys: string[] } {\n const segments = opsToSegments(diff(prev, next), prevSegmentKeys)\n return { segments, keys: segments.map((s) => s.key) }\n}\n\nexport function initialSegments(value: string): {\n segments: RenderSegment[]\n keys: string[]\n} {\n const segments = [...value].map((char, i) => makeSegment(char, nextKey(`s${i}`)))\n return { segments, keys: segments.map((s) => s.key) }\n}\n","import type { EffectTiming, Preset } from './types'\nimport { DEFAULT_SLIDE, DEFAULT_SPIN } from './types'\n\nexport const STYLES = `\n:host {\n display: inline-block;\n line-height: inherit;\n font-variant-numeric: tabular-nums;\n --cf-cell-height: 1lh;\n --cf-letter-gap: 0px;\n --cf-spin-duration: ${DEFAULT_SPIN.duration}ms;\n --cf-spin-easing: ${DEFAULT_SPIN.easing};\n --cf-slide-duration: ${DEFAULT_SLIDE.duration}ms;\n --cf-slide-easing: ${DEFAULT_SLIDE.easing};\n}\n\n.root {\n display: inline;\n position: relative;\n}\n\n.sr {\n position: absolute;\n width: 1px;\n height: 1px;\n padding: 0;\n margin: -1px;\n overflow: hidden;\n clip: rect(0, 0, 0, 0);\n white-space: nowrap;\n border: 0;\n}\n\n.visual {\n display: inline-block;\n position: relative;\n white-space: nowrap;\n}\n\n.cf-cell {\n display: inline-block;\n height: var(--cf-cell-height);\n line-height: var(--cf-cell-height);\n vertical-align: baseline;\n overflow: hidden;\n position: relative;\n text-align: center;\n}\n\n.cf-cell + .cf-cell {\n margin-left: var(--cf-letter-gap);\n}\n\n/* Soft top/bottom fade only while a wheel is mid-roll. */\n.cf-cell--rolling {\n -webkit-mask-image: linear-gradient(\n to bottom,\n transparent 0%,\n #000 18%,\n #000 82%,\n transparent 100%\n );\n mask-image: linear-gradient(\n to bottom,\n transparent 0%,\n #000 18%,\n #000 82%,\n transparent 100%\n );\n}\n\n.cf-stack {\n position: absolute;\n top: 0;\n left: 0;\n width: 100%;\n will-change: transform;\n}\n\n.cf-glyph {\n display: block;\n height: var(--cf-cell-height);\n line-height: var(--cf-cell-height);\n text-align: center;\n}\n`.trim()\n\nexport function applyPresetStyle(host: HTMLElement, preset: Preset): void {\n if (preset === 'plate') {\n host.style.textTransform = 'uppercase'\n host.style.letterSpacing = '0.04em'\n } else {\n host.style.textTransform = ''\n host.style.letterSpacing = ''\n }\n}\n\nexport function applyTimings(\n host: HTMLElement,\n spin?: EffectTiming,\n slide?: EffectTiming,\n): void {\n const s = { ...DEFAULT_SPIN, ...spin }\n const l = { ...DEFAULT_SLIDE, ...slide }\n host.style.setProperty('--cf-spin-duration', `${s.duration}ms`)\n host.style.setProperty('--cf-spin-easing', s.easing)\n host.style.setProperty('--cf-slide-duration', `${l.duration}ms`)\n host.style.setProperty('--cf-slide-easing', l.easing)\n}\n\nexport function parsePreset(v: string | null): Preset {\n return v === 'plate' ? 'plate' : 'alnum'\n}\n","import { observeMetrics, syncMetrics } from './layout/metrics'\nimport { mountVisual } from './render/mount'\nimport { buildSegments, initialSegments } from './segments'\nimport { applyPresetStyle, applyTimings, parsePreset, STYLES } from './styles'\nimport type { EffectTiming, Preset } from './types'\n\nconst TAG = 'char-flow'\n\nexport class CharFlowElement extends HTMLElement {\n static observedAttributes = ['value', 'preset', 'animated'] as const\n\n #sr!: HTMLElement\n #visual!: HTMLElement\n #prevValue = ''\n #keys: string[] = []\n #motionQuery = window.matchMedia('(prefers-reduced-motion: reduce)')\n #onMotionChange = (): void => this.#syncReduced()\n #stopMetrics: (() => void) | undefined\n\n #spinTiming: EffectTiming | undefined\n #slideTiming: EffectTiming | undefined\n\n connectedCallback(): void {\n if (!this.shadowRoot) {\n const root = this.attachShadow({ mode: 'open' })\n const style = document.createElement('style')\n style.textContent = STYLES\n const shell = document.createElement('div')\n shell.className = 'root'\n shell.setAttribute('part', 'root')\n\n this.#sr = document.createElement('span')\n this.#sr.className = 'sr'\n this.#sr.setAttribute('aria-live', 'polite')\n this.#sr.setAttribute('aria-atomic', 'true')\n\n this.#visual = document.createElement('span')\n this.#visual.className = 'visual'\n this.#visual.setAttribute('aria-hidden', 'true')\n\n shell.append(this.#sr, this.#visual)\n root.append(style, shell)\n }\n\n this.#motionQuery.addEventListener('change', this.#onMotionChange)\n this.#syncReduced()\n this.#applyOptions()\n this.#stopMetrics = observeMetrics(this)\n this.#render(true)\n }\n\n disconnectedCallback(): void {\n this.#motionQuery.removeEventListener('change', this.#onMotionChange)\n this.#stopMetrics?.()\n this.#stopMetrics = undefined\n }\n\n attributeChangedCallback(name: string): void {\n if (!this.isConnected) return\n if (name === 'value') {\n this.#render(false)\n return\n }\n this.#applyOptions()\n if (name === 'animated') this.#render(false)\n }\n\n get value(): string {\n return this.getAttribute('value') ?? ''\n }\n\n set value(v: string) {\n this.setAttribute('value', v)\n }\n\n get preset(): Preset {\n return parsePreset(this.getAttribute('preset'))\n }\n\n set preset(v: Preset) {\n this.setAttribute('preset', v)\n }\n\n get animated(): boolean {\n return this.getAttribute('animated') !== 'false'\n }\n\n set animated(v: boolean) {\n if (v) this.removeAttribute('animated')\n else this.setAttribute('animated', 'false')\n }\n\n set spinTiming(t: EffectTiming | undefined) {\n this.#spinTiming = t\n this.#applyOptions()\n }\n\n set slideTiming(t: EffectTiming | undefined) {\n this.#slideTiming = t\n this.#applyOptions()\n }\n\n #canAnimate(): boolean {\n if (!this.animated) return false\n if (this.#motionQuery.matches) return false\n return true\n }\n\n #syncReduced(): void {\n if (this.#motionQuery.matches) this.dataset.reduced = ''\n else delete this.dataset.reduced\n }\n\n #applyOptions(): void {\n applyPresetStyle(this, this.preset)\n applyTimings(this, this.#spinTiming, this.#slideTiming)\n syncMetrics(this)\n }\n\n #render(initial: boolean): void {\n const next = this.value\n this.#sr.textContent = next\n\n const animated = this.#canAnimate() && !initial\n\n let segments\n if (initial || !this.#prevValue) {\n const init = initialSegments(next)\n segments = init.segments\n this.#keys = init.keys\n } else if (this.#prevValue === next) {\n return\n } else {\n const built = buildSegments(this.#prevValue, next, this.#keys)\n segments = built.segments\n this.#keys = built.keys\n }\n\n mountVisual(this.#visual, segments, animated)\n this.#prevValue = next\n }\n}\n\nexport function defineCharFlow(tag = TAG): void {\n if (!customElements.get(tag)) {\n customElements.define(tag, CharFlowElement)\n }\n}\n\ndefineCharFlow()\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'char-flow': CharFlowElement\n }\n}\n\nexport { TAG }\n"]}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { D as DiffOp, C as CharKind } from './element-ohGNSSoB.js';
|
|
2
|
+
export { A as AnimKind, a as CharFlowElement, E as EffectTiming, P as Preset, T as TAG, d as defineCharFlow } from './element-ohGNSSoB.js';
|
|
3
|
+
export { CharFlow } from './react.js';
|
|
4
|
+
import 'react';
|
|
5
|
+
|
|
6
|
+
/** Shortest edit script via Wagner-Fischer. Deletes are omitted (cells simply disappear). */
|
|
7
|
+
declare function diffChars(prev: string, next: string, keyOffset?: number): DiffOp[];
|
|
8
|
+
declare function diff(prev: string, next: string): DiffOp[];
|
|
9
|
+
|
|
10
|
+
declare function classify(char: string): CharKind;
|
|
11
|
+
|
|
12
|
+
export { CharKind, classify, diff, diffChars };
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
import {useRef,useEffect,createElement}from'react';function C(e){let{letterSpacing:t}=getComputedStyle(e);e.style.setProperty("--cf-letter-gap",t==="normal"?"0px":t);}function H(e){let t=()=>C(e);t();let n=new ResizeObserver(t);return n.observe(e),document.fonts?.ready.then(t).catch(()=>{}),()=>n.disconnect()}var w="0123456789",v="ABCDEFGHIJKLMNOPQRSTUVWXYZ",x={duration:520,easing:"cubic-bezier(0.32, 0.72, 0, 1)",delay:0},b={duration:340,easing:"cubic-bezier(0.32, 0.72, 0, 1)",delay:0},I=16;function d(e){return e===" "?"\xA0":e}function K(e,t){return t>="a"&&t<="z"?e.toLowerCase():e}function u(e){if(!e)return "other";let t=e.charCodeAt(0);return t>=48&&t<=57?"digit":t>=65&&t<=90||t>=97&&t<=122?"letter":"other"}function h(e,t){return t==="digit"?e.charCodeAt(0)-48:e.toUpperCase().charCodeAt(0)-65}function D(e){let t=u(e);return t==="digit"?"wheel-digit":t==="letter"?"wheel-letter":"static"}function F(e,t){let n=u(e),r=u(t);return n==="digit"&&r==="digit"?"wheel-digit":n==="letter"&&r==="letter"?"wheel-letter":"slide"}function O(e,t,n){let r=h(e,n),i=h(t,n);if(r===i)return 1;let s=n==="letter"?26:10,o=(i-r+s)%s,l=(r-i+s)%s;return o<=l?1:-1}function re(e,t,n){return t==="digit"?w[e]:K(v[e],n)}function $(e,t,n){let r=n==="letter"?v.length:w.length,i=h(e,n),s=h(t,n),o=O(e,t,n),l=[];for(let c=i;l.push(re(c,n,t)),c!==s;c=(c+o+r)%r);return o===1?{chars:l,startIdx:0,endIdx:l.length-1}:{chars:[...l].reverse(),startIdx:l.length-1,endIdx:0}}function ie(e,t){return {chars:[d(e),d(t)],startIdx:0,endIdx:1}}function S(e){return e.fromChar==null||e.fromChar===e.char?null:e.anim==="wheel-digit"?$(e.fromChar,e.char,"digit"):e.anim==="wheel-letter"?$(e.fromChar,e.char,"letter"):ie(e.fromChar,e.char)}function N(e){return e.anim==="wheel-digit"||e.anim==="wheel-letter"}function k(e){let t=document.createElement("span");return t.className="cf-glyph",t.setAttribute("part","glyph"),t.textContent=d(e),t}function Y(e,t=""){let n=document.createElement("span");return n.className=t?`cf-cell ${t}`:"cf-cell",n.dataset.key=e.key,n.dataset.char=e.char,n.setAttribute("part","segment"),n}function M(e){let t=Y(e);return t.appendChild(k(e.char)),t}function se(e,t){let n=M(e),r=e.runLength&&e.runLength>1?(e.runIndex??0)*I:0;return t.push(i=>{n.animate([{opacity:0,transform:"translateY(0.25em)"},{opacity:1,transform:"translateY(0)"}],{duration:i.slide.duration,easing:i.slide.easing,delay:r,fill:"backwards"});}),n}function oe(e,t){let n=S(e),r=N(e),i=Y(e,r?"cf-cell--rolling":""),s=k(e.char);s.style.visibility="hidden";let o=document.createElement("span");o.className="cf-stack";for(let l of n.chars)o.appendChild(k(l));return i.append(s,o),t.push(l=>{let c=-n.startIdx*l.cellHeight,a=-n.endIdx*l.cellHeight,f=r?l.spin:l.slide;o.style.transform=`translateY(${c}px)`;let p=o.animate([{transform:`translateY(${c}px)`},{transform:`translateY(${a}px)`}],{duration:f.duration,easing:f.easing,fill:"forwards"});p.onfinish=()=>{p.cancel(),o.remove(),s.style.visibility="",i.classList.remove("cf-cell--rolling");};}),i}function le(e,t,n){return e.entering?t?se(e,n):M(e):t&&S(e)?oe(e,n):M(e)}function G(e,t,n,r){let i=n.get(e.key);return i&&!e.entering&&e.fromChar==null&&i.dataset.char===e.char?i:le(e,t,r)}function U(e){let t=new Map;for(let n of e.querySelectorAll(".cf-cell[data-key]"))n instanceof HTMLElement&&n.dataset.key&&t.set(n.dataset.key,n);return t}function V(e){let t=parseFloat(e);return Number.isFinite(t)?e.trim().endsWith("ms")?t:t*1e3:0}function ae(e){let t=getComputedStyle(e),n=e.querySelector(".cf-glyph");return {cellHeight:n instanceof HTMLElement?n.offsetHeight:0,spin:{duration:V(t.getPropertyValue("--cf-spin-duration")),easing:t.getPropertyValue("--cf-spin-easing").trim()},slide:{duration:V(t.getPropertyValue("--cf-slide-duration")),easing:t.getPropertyValue("--cf-slide-easing").trim()}}}function _(e,t){let n=e.getBoundingClientRect().left,r=new Map;for(let i of t)i.dataset.key&&r.set(i.dataset.key,i.getBoundingClientRect().left-n);return r}function X(e,t,n){let r=U(e),i=n?_(e,r.values()):new Map,s=[],o=[],l=new Set;for(let f of t){let p=G(f,n,r,s);l.add(f.key),o.push(p);}let c=[];if(n)for(let[f,p]of r)l.has(f)||c.push(p);if(e.replaceChildren(...o,...c),!s.length&&!c.length)return;let a=ae(e);if(n){let f=_(e,o);for(let p of o){let m=p.dataset.key;if(!m)continue;let g=i.get(m),y=f.get(m);if(g===void 0||y===void 0)continue;let R=g-y;Math.abs(R)<.5||p.animate([{transform:`translateX(${R}px)`},{transform:"translateX(0)"}],{duration:a.slide.duration,easing:a.slide.easing});}for(let p of c){let m=i.get(p.dataset.key),g=p.offsetWidth;p.style.position="absolute",p.style.top="0",p.style.left=`${m??0}px`,p.style.width=`${g}px`,p.style.pointerEvents="none";let y=p.animate([{opacity:1,transform:"translateY(0)"},{opacity:0,transform:"translateY(-0.25em)"}],{duration:a.slide.duration,easing:a.slide.easing,fill:"forwards"});y.onfinish=()=>p.remove();}}for(let f of s)f(a);}function q(e,t){let n=e.length,r=t.length,i=Array.from({length:n+1},()=>Array.from({length:r+1},()=>0));for(let s=0;s<=n;s++)i[s][0]=s;for(let s=0;s<=r;s++)i[0][s]=s;for(let s=1;s<=n;s++)for(let o=1;o<=r;o++)e[s-1]===t[o-1]?i[s][o]=i[s-1][o-1]:i[s][o]=1+Math.min(i[s-1][o],i[s][o-1],i[s-1][o-1]);return i}function ce(e,t,n,r){let i=[],s=t.length,o=n.length;for(;s>0||o>0;)s>0&&o>0&&t[s-1]===n[o-1]?(i.push("M"),s--,o--):s>0&&o>0&&e[s][o]===e[s-1][o-1]+1?(i.push("R"),s--,o--):o>0&&e[s][o]===e[s][o-1]+1?(i.push("I"),o--):(i.push("D"),s--);i.reverse();let l=[],c=0,a=0;for(let f of i)f==="M"?(l.push({type:"keep",index:a,char:n[a],prevKey:r+c}),c++,a++):f==="R"?(l.push({type:"replace",index:a,from:t[c],to:n[a],prevKey:r+c}),c++,a++):f==="I"?(l.push({type:"insert",index:a,char:n[a]}),a++):c++;return l}function z(e,t,n=0){let r=[...e],i=[...t],s=q(r,i);return ce(s,r,i,n)}function fe(e,t){let n=t,r=[];for(let i of e)if(i.type==="insert")r.push({type:"insert",index:n++,char:i.char});else if(i.type==="keep"){let s={type:"keep",index:n++,char:i.char,prevKey:i.prevKey};i.region&&(s.region=i.region),r.push(s);}else i.type==="replace"&&r.push({type:"replace",index:n++,from:i.from,to:i.to,prevKey:i.prevKey});return r}function pe(e,t){let n=[];for(let r=0;r<t.length;r++){let i=e[r],s=t[r];i===s?n.push({type:"keep",index:r,char:s,prevKey:r}):n.push({type:"replace",index:r,from:i,to:s,prevKey:r});}return n}function L(e,t){if(e.length===t.length)return pe(e,t);let n=0;for(;n<e.length&&n<t.length&&e[n]===t[n];)n++;let r=0;for(;r<e.length-n&&r<t.length-n&&e[e.length-1-r]===t[t.length-1-r];)r++;let i=[],s=0;for(let f=0;f<n;f++)i.push({type:"keep",index:s++,char:t[f],prevKey:f});let o=e.slice(n,e.length-r),l=t.slice(n,t.length-r),c=Math.max(o.length,l.length);if(c>0)if(q([...o],[...l])[o.length][l.length]/c>.4)for(let m=0;m<l.length;m++)i.push({type:"insert",index:s++,char:l[m]});else i.push(...fe(z(o,l,n),s)),s+=l.length;let a=Math.max(n,t.length-r);for(let f=a;f<t.length;f++){let p=e.length-r+(f-(t.length-r));p<n||i.push({type:"keep",index:s++,char:t[f],prevKey:p,region:"suffix"});}return i}var me=0;function P(e){return `${e}-${++me}`}function W(e,t,n){return e[t]??P(n)}function ue(e){let t=e.map(r=>({...r})),n=0;for(;n<t.length;){if(!t[n].entering){n++;continue}let i=n+1;for(;i<t.length&&t[i].entering;)i++;let s=i-n;for(let o=n;o<i;o++)t[o]={...t[o],runIndex:o-n,runLength:s};n=i;}return t}function E(e,t,n={}){return {key:t,char:e,kind:u(e),anim:n.anim??D(e),...n}}function de(e,t){let n=[];for(let r of e){if(r.type==="keep"){n.push(E(r.char,W(t,r.prevKey,"k")));continue}if(r.type==="replace"){n.push(E(r.to,W(t,r.prevKey,"r"),{anim:F(r.from,r.to),fromChar:r.from,fromKind:u(r.from)}));continue}r.type==="insert"&&n.push(E(r.char,P("i"),{entering:true}));}return ue(n)}function j(e,t,n){let r=de(L(e,t),n);return {segments:r,keys:r.map(i=>i.key)}}function B(e){let t=[...e].map((n,r)=>E(n,P(`s${r}`)));return {segments:t,keys:t.map(n=>n.key)}}var Q=`
|
|
2
|
+
:host {
|
|
3
|
+
display: inline-block;
|
|
4
|
+
line-height: inherit;
|
|
5
|
+
font-variant-numeric: tabular-nums;
|
|
6
|
+
--cf-cell-height: 1lh;
|
|
7
|
+
--cf-letter-gap: 0px;
|
|
8
|
+
--cf-spin-duration: ${x.duration}ms;
|
|
9
|
+
--cf-spin-easing: ${x.easing};
|
|
10
|
+
--cf-slide-duration: ${b.duration}ms;
|
|
11
|
+
--cf-slide-easing: ${b.easing};
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
.root {
|
|
15
|
+
display: inline;
|
|
16
|
+
position: relative;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
.sr {
|
|
20
|
+
position: absolute;
|
|
21
|
+
width: 1px;
|
|
22
|
+
height: 1px;
|
|
23
|
+
padding: 0;
|
|
24
|
+
margin: -1px;
|
|
25
|
+
overflow: hidden;
|
|
26
|
+
clip: rect(0, 0, 0, 0);
|
|
27
|
+
white-space: nowrap;
|
|
28
|
+
border: 0;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
.visual {
|
|
32
|
+
display: inline-block;
|
|
33
|
+
position: relative;
|
|
34
|
+
white-space: nowrap;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
.cf-cell {
|
|
38
|
+
display: inline-block;
|
|
39
|
+
height: var(--cf-cell-height);
|
|
40
|
+
line-height: var(--cf-cell-height);
|
|
41
|
+
vertical-align: baseline;
|
|
42
|
+
overflow: hidden;
|
|
43
|
+
position: relative;
|
|
44
|
+
text-align: center;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
.cf-cell + .cf-cell {
|
|
48
|
+
margin-left: var(--cf-letter-gap);
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
/* Soft top/bottom fade only while a wheel is mid-roll. */
|
|
52
|
+
.cf-cell--rolling {
|
|
53
|
+
-webkit-mask-image: linear-gradient(
|
|
54
|
+
to bottom,
|
|
55
|
+
transparent 0%,
|
|
56
|
+
#000 18%,
|
|
57
|
+
#000 82%,
|
|
58
|
+
transparent 100%
|
|
59
|
+
);
|
|
60
|
+
mask-image: linear-gradient(
|
|
61
|
+
to bottom,
|
|
62
|
+
transparent 0%,
|
|
63
|
+
#000 18%,
|
|
64
|
+
#000 82%,
|
|
65
|
+
transparent 100%
|
|
66
|
+
);
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
.cf-stack {
|
|
70
|
+
position: absolute;
|
|
71
|
+
top: 0;
|
|
72
|
+
left: 0;
|
|
73
|
+
width: 100%;
|
|
74
|
+
will-change: transform;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
.cf-glyph {
|
|
78
|
+
display: block;
|
|
79
|
+
height: var(--cf-cell-height);
|
|
80
|
+
line-height: var(--cf-cell-height);
|
|
81
|
+
text-align: center;
|
|
82
|
+
}
|
|
83
|
+
`.trim();function J(e,t){t==="plate"?(e.style.textTransform="uppercase",e.style.letterSpacing="0.04em"):(e.style.textTransform="",e.style.letterSpacing="");}function Z(e,t,n){let r={...x,...t},i={...b,...n};e.style.setProperty("--cf-spin-duration",`${r.duration}ms`),e.style.setProperty("--cf-spin-easing",r.easing),e.style.setProperty("--cf-slide-duration",`${i.duration}ms`),e.style.setProperty("--cf-slide-easing",i.easing);}function ee(e){return e==="plate"?"plate":"alnum"}var te="char-flow",T=class extends HTMLElement{static observedAttributes=["value","preset","animated"];#e;#t;#n="";#s=[];#r=window.matchMedia("(prefers-reduced-motion: reduce)");#a=()=>this.#p();#o;#c;#f;connectedCallback(){if(!this.shadowRoot){let t=this.attachShadow({mode:"open"}),n=document.createElement("style");n.textContent=Q;let r=document.createElement("div");r.className="root",r.setAttribute("part","root"),this.#e=document.createElement("span"),this.#e.className="sr",this.#e.setAttribute("aria-live","polite"),this.#e.setAttribute("aria-atomic","true"),this.#t=document.createElement("span"),this.#t.className="visual",this.#t.setAttribute("aria-hidden","true"),r.append(this.#e,this.#t),t.append(n,r);}this.#r.addEventListener("change",this.#a),this.#p(),this.#i(),this.#o=H(this),this.#l(true);}disconnectedCallback(){this.#r.removeEventListener("change",this.#a),this.#o?.(),this.#o=void 0;}attributeChangedCallback(t){if(this.isConnected){if(t==="value"){this.#l(false);return}this.#i(),t==="animated"&&this.#l(false);}}get value(){return this.getAttribute("value")??""}set value(t){this.setAttribute("value",t);}get preset(){return ee(this.getAttribute("preset"))}set preset(t){this.setAttribute("preset",t);}get animated(){return this.getAttribute("animated")!=="false"}set animated(t){t?this.removeAttribute("animated"):this.setAttribute("animated","false");}set spinTiming(t){this.#c=t,this.#i();}set slideTiming(t){this.#f=t,this.#i();}#m(){return !(!this.animated||this.#r.matches)}#p(){this.#r.matches?this.dataset.reduced="":delete this.dataset.reduced;}#i(){J(this,this.preset),Z(this,this.#c,this.#f),C(this);}#l(t){let n=this.value;this.#e.textContent=n;let r=this.#m()&&!t,i;if(t||!this.#n){let s=B(n);i=s.segments,this.#s=s.keys;}else {if(this.#n===n)return;{let s=j(this.#n,n,this.#s);i=s.segments,this.#s=s.keys;}}X(this.#t,i,r),this.#n=n;}};function ne(e=te){customElements.get(e)||customElements.define(e,T);}ne();function ye(){if(typeof customElements<"u"&&!customElements.get("char-flow"))throw new Error('CharFlow: import "char-flow/element" before using the React wrapper.')}function xe({value:e,preset:t="alnum",animated:n=true,spinTiming:r,slideTiming:i,className:s,style:o,...l}){let c=useRef(null);return useEffect(()=>{ye();},[]),useEffect(()=>{let a=c.current;a&&a.value!==e&&(a.value=e);},[e]),useEffect(()=>{let a=c.current;a&&(a.preset=t,a.animated=n,r!==void 0&&(a.spinTiming=r),i!==void 0&&(a.slideTiming=i));},[t,n,r,i]),createElement("char-flow",{ref:c,value:e,preset:t,...n?{}:{animated:"false"},class:s,style:o,...l})}export{xe as CharFlow,T as CharFlowElement,te as TAG,u as classify,ne as defineCharFlow,L as diff,z as diffChars};//# sourceMappingURL=index.js.map
|
|
84
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/layout/metrics.ts","../src/types.ts","../src/render/format.ts","../src/classify.ts","../src/render/stack.ts","../src/render/cell.ts","../src/render/mount.ts","../src/diff.ts","../src/segments.ts","../src/styles.ts","../src/element.ts","../src/react.tsx"],"names":["syncMetrics","host","letterSpacing","observeMetrics","run","ro","DIGITS","LETTERS","DEFAULT_SPIN","DEFAULT_SLIDE","STAGGER_STEP_MS","formatChar","char","displayLetter","stripChar","target","classify","code","wheelIndex","kind","animForChar","k","animForReplace","from","to","fk","tk","spinDirection","a","b","n","up","down","charForIndex","i","wheelPlan","dir","path","slidePlan","planFor","seg","isWheel","glyph","g","makeCell","extraClass","cell","staticCell","enteringCell","pending","delay","ctx","rollingCell","plan","wheel","sizer","stack","c","startY","endY","timing","anim","buildCell","animated","reuseCell","existing","existingCellMap","root","map","el","ms","value","readContext","visual","cs","sample","measureX","cells","base","out","mountVisual","segments","firstX","nodes","survivors","node","exiting","key","lastX","before","after","dx","x","width","levenshteinMatrix","m","dp","j","backtrackOps","keyOffset","raw","ops","ai","bi","step","diffChars","prev","next","reindexOps","startIdx","outIdx","result","op","keep","diffAligned","diff","pre","suf","midPrev","midNext","midMax","suffixStart","prevIdx","keySeq","nextKey","prefix","keyForPrev","prevKeys","prevKey","fallback","assignEnteringRuns","s","len","makeSegment","extra","opsToSegments","buildSegments","prevSegmentKeys","initialSegments","STYLES","applyPresetStyle","preset","applyTimings","spin","slide","l","parsePreset","v","TAG","CharFlowElement","#sr","#visual","#prevValue","#keys","#motionQuery","#onMotionChange","#syncReduced","#stopMetrics","#spinTiming","#slideTiming","style","shell","#applyOptions","#render","name","#canAnimate","initial","init","built","defineCharFlow","tag","assertRegistered","CharFlow","spinTiming","slideTiming","className","rest","ref","useRef","useEffect","createElement"],"mappings":"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","file":"index.js","sourcesContent":["/** Sync layout CSS variables from computed host styles. */\nexport function syncMetrics(host: HTMLElement): void {\n const { letterSpacing } = getComputedStyle(host)\n host.style.setProperty('--cf-letter-gap', letterSpacing === 'normal' ? '0px' : letterSpacing)\n}\n\nexport function observeMetrics(host: HTMLElement): () => void {\n const run = (): void => syncMetrics(host)\n\n run()\n\n const ro = new ResizeObserver(run)\n ro.observe(host)\n\n document.fonts?.ready.then(run).catch(() => undefined)\n\n return () => ro.disconnect()\n}\n","export type CharKind = 'digit' | 'letter' | 'other'\n\nexport type Preset = 'plate' | 'alnum'\n\n/** How a changed character moves: roll through an alphabet, or a direct swap. */\nexport type AnimKind = 'wheel-digit' | 'wheel-letter' | 'slide' | 'static'\n\nexport interface EffectTiming {\n duration?: number\n easing?: string\n delay?: number\n}\n\nexport interface CharFlowOptions {\n preset?: Preset\n animated?: boolean\n spinTiming?: EffectTiming\n slideTiming?: EffectTiming\n}\n\nexport type DiffOp =\n | { type: 'keep'; index: number; char: string; prevKey: number; region?: 'suffix' }\n | { type: 'replace'; index: number; from: string; to: string; prevKey: number }\n | { type: 'insert'; index: number; char: string }\n\nexport interface RenderSegment {\n key: string\n char: string\n kind: CharKind\n anim: AnimKind\n fromChar?: string\n fromKind?: CharKind\n entering?: boolean\n /** Index inside a consecutive insert run (for stagger). */\n runIndex?: number\n /** Length of the current insert run. */\n runLength?: number\n}\n\nexport const DIGITS = '0123456789' as const\nexport const LETTERS = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' as const\n\nexport const DEFAULT_SPIN: Required<EffectTiming> = {\n duration: 520,\n easing: 'cubic-bezier(0.32, 0.72, 0, 1)',\n delay: 0,\n}\n\n/** Used for direct swaps (non-roll) and for entering/exiting/shifting cells. */\nexport const DEFAULT_SLIDE: Required<EffectTiming> = {\n duration: 340,\n easing: 'cubic-bezier(0.32, 0.72, 0, 1)',\n delay: 0,\n}\n\n/** Delay between cells in an insert run. */\nexport const STAGGER_STEP_MS = 16\n","export function formatChar(char: string): string {\n return char === ' ' ? '\\u00a0' : char\n}\n\nexport function displayLetter(stripChar: string, target: string): string {\n if (target >= 'a' && target <= 'z') return stripChar.toLowerCase()\n return stripChar\n}\n","import type { AnimKind, CharKind } from './types'\n\nexport function classify(char: string): CharKind {\n if (!char) return 'other'\n const code = char.charCodeAt(0)\n if (code >= 48 && code <= 57) return 'digit'\n if ((code >= 65 && code <= 90) || (code >= 97 && code <= 122)) return 'letter'\n return 'other'\n}\n\nexport function wheelIndex(char: string, kind: CharKind): number {\n if (kind === 'digit') return char.charCodeAt(0) - 48\n const upper = char.toUpperCase()\n return upper.charCodeAt(0) - 65\n}\n\n/** Resting animation tag for an unchanged character. */\nexport function animForChar(char: string): AnimKind {\n const k = classify(char)\n if (k === 'digit') return 'wheel-digit'\n if (k === 'letter') return 'wheel-letter'\n return 'static'\n}\n\n/**\n * Same alphabet (digit→digit, letter→letter) rolls through that alphabet.\n * Everything else (cross-kind, or any change involving punctuation) is a\n * direct two-glyph roll: old slides out, new slides in, no in-betweens.\n */\nexport function animForReplace(from: string, to: string): AnimKind {\n const fk = classify(from)\n const tk = classify(to)\n if (fk === 'digit' && tk === 'digit') return 'wheel-digit'\n if (fk === 'letter' && tk === 'letter') return 'wheel-letter'\n return 'slide'\n}\n\nexport function spinDirection(from: string, to: string, kind: CharKind): 1 | -1 {\n const a = wheelIndex(from, kind)\n const b = wheelIndex(to, kind)\n if (a === b) return 1\n const n = kind === 'letter' ? 26 : 10\n const up = (b - a + n) % n\n const down = (a - b + n) % n\n return up <= down ? 1 : -1\n}\n","import { spinDirection, wheelIndex } from '../classify'\nimport { DIGITS, LETTERS } from '../types'\nimport type { RenderSegment } from '../types'\nimport { displayLetter, formatChar } from './format'\n\n/**\n * A vertical column of glyphs plus the start/end positions to slide between.\n * Every animated transition — digit roll, letter roll, or text replacement —\n * is expressed as this one primitive: a stack translated along Y.\n */\nexport interface StackPlan {\n /** Glyphs in visual order, top to bottom. */\n chars: string[]\n /** Index showing at the start of the animation. */\n startIdx: number\n /** Index showing at the end of the animation. */\n endIdx: number\n}\n\nfunction charForIndex(i: number, kind: 'digit' | 'letter', target: string): string {\n if (kind === 'digit') return DIGITS[i]!\n return displayLetter(LETTERS[i]!, target)\n}\n\n/** Glyphs along the shortest path from `from` to `to` around the alphabet. */\nfunction wheelPlan(from: string, to: string, kind: 'digit' | 'letter'): StackPlan {\n const n = kind === 'letter' ? LETTERS.length : DIGITS.length\n const a = wheelIndex(from, kind)\n const b = wheelIndex(to, kind)\n const dir = spinDirection(from, to, kind)\n\n const path: string[] = []\n for (let i = a; ; i = (i + dir + n) % n) {\n path.push(charForIndex(i, kind, to))\n if (i === b) break\n }\n\n // dir +1 rolls up (content moves up, next glyph enters from below).\n // dir -1 rolls down, so reverse the column and start from the bottom.\n if (dir === 1) return { chars: path, startIdx: 0, endIdx: path.length - 1 }\n return { chars: [...path].reverse(), startIdx: path.length - 1, endIdx: 0 }\n}\n\n/** A single-step slide between two arbitrary glyphs (text replacement / morph). */\nfunction slidePlan(from: string, to: string): StackPlan {\n return { chars: [formatChar(from), formatChar(to)], startIdx: 0, endIdx: 1 }\n}\n\n/** Build the plan for a segment, or null if there is nothing to animate. */\nexport function planFor(seg: RenderSegment): StackPlan | null {\n if (seg.fromChar == null || seg.fromChar === seg.char) return null\n if (seg.anim === 'wheel-digit') return wheelPlan(seg.fromChar, seg.char, 'digit')\n if (seg.anim === 'wheel-letter') return wheelPlan(seg.fromChar, seg.char, 'letter')\n return slidePlan(seg.fromChar, seg.char)\n}\n\nexport function isWheel(seg: RenderSegment): boolean {\n return seg.anim === 'wheel-digit' || seg.anim === 'wheel-letter'\n}\n","import type { RenderSegment } from '../types'\nimport { STAGGER_STEP_MS } from '../types'\nimport { formatChar } from './format'\nimport { isWheel, planFor } from './stack'\n\nexport interface AnimContext {\n /** Measured cell height in px (one line of text). */\n cellHeight: number\n spin: { duration: number; easing: string }\n slide: { duration: number; easing: string }\n}\n\n/** Deferred animation: queued during build, launched once after layout. */\nexport type Pending = (ctx: AnimContext) => void\n\nfunction glyph(char: string): HTMLElement {\n const g = document.createElement('span')\n g.className = 'cf-glyph'\n g.setAttribute('part', 'glyph')\n g.textContent = formatChar(char)\n return g\n}\n\nfunction makeCell(seg: RenderSegment, extraClass = ''): HTMLElement {\n const cell = document.createElement('span')\n cell.className = extraClass ? `cf-cell ${extraClass}` : 'cf-cell'\n cell.dataset.key = seg.key\n cell.dataset.char = seg.char\n cell.setAttribute('part', 'segment')\n return cell\n}\n\nfunction staticCell(seg: RenderSegment): HTMLElement {\n const cell = makeCell(seg)\n cell.appendChild(glyph(seg.char))\n return cell\n}\n\nfunction enteringCell(seg: RenderSegment, pending: Pending[]): HTMLElement {\n const cell = staticCell(seg)\n const delay =\n seg.runLength && seg.runLength > 1 ? (seg.runIndex ?? 0) * STAGGER_STEP_MS : 0\n\n pending.push((ctx) => {\n cell.animate(\n [\n { opacity: 0, transform: 'translateY(0.25em)' },\n { opacity: 1, transform: 'translateY(0)' },\n ],\n { duration: ctx.slide.duration, easing: ctx.slide.easing, delay, fill: 'backwards' },\n )\n })\n return cell\n}\n\nfunction rollingCell(seg: RenderSegment, pending: Pending[]): HTMLElement {\n const plan = planFor(seg)!\n const wheel = isWheel(seg)\n const cell = makeCell(seg, wheel ? 'cf-cell--rolling' : '')\n\n // A normal-flow sizer (the resting glyph) owns the cell's width so it stays\n // constant; the multi-glyph stack floats above it and never affects layout.\n const sizer = glyph(seg.char)\n sizer.style.visibility = 'hidden'\n const stack = document.createElement('span')\n stack.className = 'cf-stack'\n for (const c of plan.chars) stack.appendChild(glyph(c))\n cell.append(sizer, stack)\n\n pending.push((ctx) => {\n const startY = -plan.startIdx * ctx.cellHeight\n const endY = -plan.endIdx * ctx.cellHeight\n const timing = wheel ? ctx.spin : ctx.slide\n\n stack.style.transform = `translateY(${startY}px)`\n const anim = stack.animate(\n [{ transform: `translateY(${startY}px)` }, { transform: `translateY(${endY}px)` }],\n { duration: timing.duration, easing: timing.easing, fill: 'forwards' },\n )\n // Drop the stack and reveal the resting sizer once the roll lands.\n anim.onfinish = () => {\n anim.cancel()\n stack.remove()\n sizer.style.visibility = ''\n cell.classList.remove('cf-cell--rolling')\n }\n })\n\n return cell\n}\n\nexport function buildCell(\n seg: RenderSegment,\n animated: boolean,\n pending: Pending[],\n): HTMLElement {\n if (seg.entering) {\n return animated ? enteringCell(seg, pending) : staticCell(seg)\n }\n if (animated && planFor(seg)) {\n return rollingCell(seg, pending)\n }\n return staticCell(seg)\n}\n\nexport function reuseCell(\n seg: RenderSegment,\n animated: boolean,\n existing: Map<string, HTMLElement>,\n pending: Pending[],\n): HTMLElement {\n const cell = existing.get(seg.key)\n // Unchanged, resting cells are reused untouched; anything that moves is rebuilt.\n if (cell && !seg.entering && seg.fromChar == null && cell.dataset.char === seg.char) {\n return cell\n }\n return buildCell(seg, animated, pending)\n}\n\nexport function existingCellMap(root: HTMLElement): Map<string, HTMLElement> {\n const map = new Map<string, HTMLElement>()\n for (const el of root.querySelectorAll('.cf-cell[data-key]')) {\n if (el instanceof HTMLElement && el.dataset.key) map.set(el.dataset.key, el)\n }\n return map\n}\n","import type { RenderSegment } from '../types'\nimport { existingCellMap, reuseCell, type AnimContext, type Pending } from './cell'\n\nfunction ms(value: string): number {\n const n = parseFloat(value)\n if (!Number.isFinite(n)) return 0\n return value.trim().endsWith('ms') ? n : n * 1000\n}\n\nfunction readContext(visual: HTMLElement): AnimContext {\n const cs = getComputedStyle(visual)\n const sample = visual.querySelector('.cf-glyph')\n return {\n cellHeight: sample instanceof HTMLElement ? sample.offsetHeight : 0,\n spin: {\n duration: ms(cs.getPropertyValue('--cf-spin-duration')),\n easing: cs.getPropertyValue('--cf-spin-easing').trim(),\n },\n slide: {\n duration: ms(cs.getPropertyValue('--cf-slide-duration')),\n easing: cs.getPropertyValue('--cf-slide-easing').trim(),\n },\n }\n}\n\n/** x offset (relative to the visual box) of each existing cell, keyed by data-key. */\nfunction measureX(visual: HTMLElement, cells: Iterable<HTMLElement>): Map<string, number> {\n const base = visual.getBoundingClientRect().left\n const out = new Map<string, number>()\n for (const el of cells) {\n if (el.dataset.key) out.set(el.dataset.key, el.getBoundingClientRect().left - base)\n }\n return out\n}\n\nexport function mountVisual(\n visual: HTMLElement,\n segments: RenderSegment[],\n animated: boolean,\n): void {\n const existing = existingCellMap(visual)\n\n // FLIP \"First\": record where every current cell sits before we touch the DOM.\n const firstX = animated ? measureX(visual, existing.values()) : new Map<string, number>()\n\n const pending: Pending[] = []\n const nodes: HTMLElement[] = []\n const survivors = new Set<string>()\n\n for (const seg of segments) {\n const node = reuseCell(seg, animated, existing, pending)\n survivors.add(seg.key)\n nodes.push(node)\n }\n\n // Cells present before but gone now: animate them out instead of popping.\n const exiting: HTMLElement[] = []\n if (animated) {\n for (const [key, el] of existing) {\n if (!survivors.has(key)) exiting.push(el)\n }\n }\n\n // Exiting cells stay in the DOM (absolutely positioned) so they don't affect width.\n visual.replaceChildren(...nodes, ...exiting)\n\n if (!pending.length && !exiting.length) return\n\n const ctx = readContext(visual)\n\n if (animated) {\n // FLIP \"Last/Invert/Play\": slide survivors from their old x back to the new one.\n const lastX = measureX(visual, nodes)\n for (const node of nodes) {\n const key = node.dataset.key\n if (!key) continue\n const before = firstX.get(key)\n const after = lastX.get(key)\n if (before === undefined || after === undefined) continue\n const dx = before - after\n if (Math.abs(dx) < 0.5) continue\n node.animate(\n [{ transform: `translateX(${dx}px)` }, { transform: 'translateX(0)' }],\n { duration: ctx.slide.duration, easing: ctx.slide.easing },\n )\n }\n\n for (const el of exiting) {\n const x = firstX.get(el.dataset.key!)\n const width = el.offsetWidth\n el.style.position = 'absolute'\n el.style.top = '0'\n el.style.left = `${x ?? 0}px`\n el.style.width = `${width}px`\n el.style.pointerEvents = 'none'\n const out = el.animate(\n [\n { opacity: 1, transform: 'translateY(0)' },\n { opacity: 0, transform: 'translateY(-0.25em)' },\n ],\n { duration: ctx.slide.duration, easing: ctx.slide.easing, fill: 'forwards' },\n )\n out.onfinish = () => el.remove()\n }\n }\n\n for (const run of pending) run(ctx)\n}\n","import type { DiffOp } from './types'\n\nfunction levenshteinMatrix(a: string[], b: string[]): number[][] {\n const m = a.length\n const n = b.length\n const dp: number[][] = Array.from({ length: m + 1 }, () =>\n Array.from({ length: n + 1 }, () => 0),\n )\n for (let i = 0; i <= m; i++) dp[i]![0] = i\n for (let j = 0; j <= n; j++) dp[0]![j] = j\n\n for (let i = 1; i <= m; i++) {\n for (let j = 1; j <= n; j++) {\n if (a[i - 1] === b[j - 1]) {\n dp[i]![j] = dp[i - 1]![j - 1]!\n } else {\n dp[i]![j] = 1 + Math.min(dp[i - 1]![j]!, dp[i]![j - 1]!, dp[i - 1]![j - 1]!)\n }\n }\n }\n\n return dp\n}\n\nfunction backtrackOps(dp: number[][], a: string[], b: string[], keyOffset: number): DiffOp[] {\n const raw: Array<'M' | 'I' | 'D' | 'R'> = []\n let i = a.length\n let j = b.length\n\n while (i > 0 || j > 0) {\n if (i > 0 && j > 0 && a[i - 1] === b[j - 1]) {\n raw.push('M')\n i--\n j--\n } else if (i > 0 && j > 0 && dp[i]![j] === dp[i - 1]![j - 1]! + 1) {\n raw.push('R')\n i--\n j--\n } else if (j > 0 && dp[i]![j] === dp[i]![j - 1]! + 1) {\n raw.push('I')\n j--\n } else {\n raw.push('D')\n i--\n }\n }\n raw.reverse()\n\n const ops: DiffOp[] = []\n let ai = 0\n let bi = 0\n for (const step of raw) {\n if (step === 'M') {\n ops.push({ type: 'keep', index: bi, char: b[bi]!, prevKey: keyOffset + ai })\n ai++\n bi++\n } else if (step === 'R') {\n ops.push({\n type: 'replace',\n index: bi,\n from: a[ai]!,\n to: b[bi]!,\n prevKey: keyOffset + ai,\n })\n ai++\n bi++\n } else if (step === 'I') {\n ops.push({ type: 'insert', index: bi, char: b[bi]! })\n bi++\n } else {\n ai++\n }\n }\n return ops\n}\n\n/** Shortest edit script via Wagner-Fischer. Deletes are omitted (cells simply disappear). */\nexport function diffChars(prev: string, next: string, keyOffset = 0): DiffOp[] {\n const a = [...prev]\n const b = [...next]\n const dp = levenshteinMatrix(a, b)\n return backtrackOps(dp, a, b, keyOffset)\n}\n\nfunction reindexOps(ops: DiffOp[], startIdx: number): DiffOp[] {\n let outIdx = startIdx\n const result: DiffOp[] = []\n for (const op of ops) {\n if (op.type === 'insert') {\n result.push({ type: 'insert', index: outIdx++, char: op.char })\n } else if (op.type === 'keep') {\n const keep: DiffOp = {\n type: 'keep',\n index: outIdx++,\n char: op.char,\n prevKey: op.prevKey,\n }\n if (op.region) keep.region = op.region\n result.push(keep)\n } else if (op.type === 'replace') {\n result.push({\n type: 'replace',\n index: outIdx++,\n from: op.from,\n to: op.to,\n prevKey: op.prevKey,\n })\n }\n }\n return result\n}\n\n/**\n * Slot-by-slot alignment for same-length values (e.g. license plates). Every\n * position rolls from its old char to its new one, so a dash moving from one\n * group to another rolls in place instead of being deleted and re-inserted.\n */\nfunction diffAligned(prev: string, next: string): DiffOp[] {\n const ops: DiffOp[] = []\n for (let i = 0; i < next.length; i++) {\n const from = prev[i]!\n const to = next[i]!\n if (from === to) {\n ops.push({ type: 'keep', index: i, char: to, prevKey: i })\n } else {\n ops.push({ type: 'replace', index: i, from, to, prevKey: i })\n }\n }\n return ops\n}\n\nexport function diff(prev: string, next: string): DiffOp[] {\n if (prev.length === next.length) return diffAligned(prev, next)\n\n let pre = 0\n while (pre < prev.length && pre < next.length && prev[pre] === next[pre]) pre++\n\n let suf = 0\n while (\n suf < prev.length - pre &&\n suf < next.length - pre &&\n prev[prev.length - 1 - suf] === next[next.length - 1 - suf]\n ) {\n suf++\n }\n\n const ops: DiffOp[] = []\n let outIdx = 0\n\n for (let i = 0; i < pre; i++) {\n ops.push({ type: 'keep', index: outIdx++, char: next[i]!, prevKey: i })\n }\n\n const midPrev = prev.slice(pre, prev.length - suf)\n const midNext = next.slice(pre, next.length - suf)\n const midMax = Math.max(midPrev.length, midNext.length)\n\n if (midMax > 0) {\n const midDist = levenshteinMatrix([...midPrev], [...midNext])[midPrev.length]![midNext.length]!\n const middleUnrelated = midDist / midMax > 0.4\n\n if (middleUnrelated) {\n for (let i = 0; i < midNext.length; i++) {\n ops.push({ type: 'insert', index: outIdx++, char: midNext[i]! })\n }\n } else {\n ops.push(...reindexOps(diffChars(midPrev, midNext, pre), outIdx))\n outIdx += midNext.length\n }\n }\n\n const suffixStart = Math.max(pre, next.length - suf)\n for (let i = suffixStart; i < next.length; i++) {\n const prevIdx = prev.length - suf + (i - (next.length - suf))\n if (prevIdx < pre) continue\n ops.push({\n type: 'keep',\n index: outIdx++,\n char: next[i]!,\n prevKey: prevIdx,\n region: 'suffix',\n })\n }\n\n return ops\n}\n","import { animForChar, animForReplace, classify } from './classify'\nimport { diff } from './diff'\nimport type { DiffOp, RenderSegment } from './types'\n\nlet keySeq = 0\nfunction nextKey(prefix: string): string {\n return `${prefix}-${++keySeq}`\n}\n\nfunction keyForPrev(prevKeys: string[], prevKey: number, fallback: string): string {\n return prevKeys[prevKey] ?? nextKey(fallback)\n}\n\nfunction assignEnteringRuns(segments: RenderSegment[]): RenderSegment[] {\n const out = segments.map((s) => ({ ...s }))\n let i = 0\n\n while (i < out.length) {\n const seg = out[i]!\n if (!seg.entering) {\n i++\n continue\n }\n let j = i + 1\n while (j < out.length && out[j]!.entering) j++\n const len = j - i\n for (let k = i; k < j; k++) {\n out[k] = { ...out[k]!, runIndex: k - i, runLength: len }\n }\n i = j\n }\n\n return out\n}\n\nfunction makeSegment(\n char: string,\n key: string,\n extra: Partial<RenderSegment> = {},\n): RenderSegment {\n return {\n key,\n char,\n kind: classify(char),\n anim: extra.anim ?? animForChar(char),\n ...extra,\n }\n}\n\nfunction opsToSegments(ops: DiffOp[], prevKeys: string[]): RenderSegment[] {\n const segments: RenderSegment[] = []\n\n for (const op of ops) {\n if (op.type === 'keep') {\n segments.push(makeSegment(op.char, keyForPrev(prevKeys, op.prevKey, 'k')))\n continue\n }\n\n if (op.type === 'replace') {\n segments.push(\n makeSegment(op.to, keyForPrev(prevKeys, op.prevKey, 'r'), {\n anim: animForReplace(op.from, op.to),\n fromChar: op.from,\n fromKind: classify(op.from),\n }),\n )\n continue\n }\n\n if (op.type === 'insert') {\n segments.push(makeSegment(op.char, nextKey('i'), { entering: true }))\n }\n }\n\n return assignEnteringRuns(segments)\n}\n\nexport function buildSegments(\n prev: string,\n next: string,\n prevSegmentKeys: string[],\n): { segments: RenderSegment[]; keys: string[] } {\n const segments = opsToSegments(diff(prev, next), prevSegmentKeys)\n return { segments, keys: segments.map((s) => s.key) }\n}\n\nexport function initialSegments(value: string): {\n segments: RenderSegment[]\n keys: string[]\n} {\n const segments = [...value].map((char, i) => makeSegment(char, nextKey(`s${i}`)))\n return { segments, keys: segments.map((s) => s.key) }\n}\n","import type { EffectTiming, Preset } from './types'\nimport { DEFAULT_SLIDE, DEFAULT_SPIN } from './types'\n\nexport const STYLES = `\n:host {\n display: inline-block;\n line-height: inherit;\n font-variant-numeric: tabular-nums;\n --cf-cell-height: 1lh;\n --cf-letter-gap: 0px;\n --cf-spin-duration: ${DEFAULT_SPIN.duration}ms;\n --cf-spin-easing: ${DEFAULT_SPIN.easing};\n --cf-slide-duration: ${DEFAULT_SLIDE.duration}ms;\n --cf-slide-easing: ${DEFAULT_SLIDE.easing};\n}\n\n.root {\n display: inline;\n position: relative;\n}\n\n.sr {\n position: absolute;\n width: 1px;\n height: 1px;\n padding: 0;\n margin: -1px;\n overflow: hidden;\n clip: rect(0, 0, 0, 0);\n white-space: nowrap;\n border: 0;\n}\n\n.visual {\n display: inline-block;\n position: relative;\n white-space: nowrap;\n}\n\n.cf-cell {\n display: inline-block;\n height: var(--cf-cell-height);\n line-height: var(--cf-cell-height);\n vertical-align: baseline;\n overflow: hidden;\n position: relative;\n text-align: center;\n}\n\n.cf-cell + .cf-cell {\n margin-left: var(--cf-letter-gap);\n}\n\n/* Soft top/bottom fade only while a wheel is mid-roll. */\n.cf-cell--rolling {\n -webkit-mask-image: linear-gradient(\n to bottom,\n transparent 0%,\n #000 18%,\n #000 82%,\n transparent 100%\n );\n mask-image: linear-gradient(\n to bottom,\n transparent 0%,\n #000 18%,\n #000 82%,\n transparent 100%\n );\n}\n\n.cf-stack {\n position: absolute;\n top: 0;\n left: 0;\n width: 100%;\n will-change: transform;\n}\n\n.cf-glyph {\n display: block;\n height: var(--cf-cell-height);\n line-height: var(--cf-cell-height);\n text-align: center;\n}\n`.trim()\n\nexport function applyPresetStyle(host: HTMLElement, preset: Preset): void {\n if (preset === 'plate') {\n host.style.textTransform = 'uppercase'\n host.style.letterSpacing = '0.04em'\n } else {\n host.style.textTransform = ''\n host.style.letterSpacing = ''\n }\n}\n\nexport function applyTimings(\n host: HTMLElement,\n spin?: EffectTiming,\n slide?: EffectTiming,\n): void {\n const s = { ...DEFAULT_SPIN, ...spin }\n const l = { ...DEFAULT_SLIDE, ...slide }\n host.style.setProperty('--cf-spin-duration', `${s.duration}ms`)\n host.style.setProperty('--cf-spin-easing', s.easing)\n host.style.setProperty('--cf-slide-duration', `${l.duration}ms`)\n host.style.setProperty('--cf-slide-easing', l.easing)\n}\n\nexport function parsePreset(v: string | null): Preset {\n return v === 'plate' ? 'plate' : 'alnum'\n}\n","import { observeMetrics, syncMetrics } from './layout/metrics'\nimport { mountVisual } from './render/mount'\nimport { buildSegments, initialSegments } from './segments'\nimport { applyPresetStyle, applyTimings, parsePreset, STYLES } from './styles'\nimport type { EffectTiming, Preset } from './types'\n\nconst TAG = 'char-flow'\n\nexport class CharFlowElement extends HTMLElement {\n static observedAttributes = ['value', 'preset', 'animated'] as const\n\n #sr!: HTMLElement\n #visual!: HTMLElement\n #prevValue = ''\n #keys: string[] = []\n #motionQuery = window.matchMedia('(prefers-reduced-motion: reduce)')\n #onMotionChange = (): void => this.#syncReduced()\n #stopMetrics: (() => void) | undefined\n\n #spinTiming: EffectTiming | undefined\n #slideTiming: EffectTiming | undefined\n\n connectedCallback(): void {\n if (!this.shadowRoot) {\n const root = this.attachShadow({ mode: 'open' })\n const style = document.createElement('style')\n style.textContent = STYLES\n const shell = document.createElement('div')\n shell.className = 'root'\n shell.setAttribute('part', 'root')\n\n this.#sr = document.createElement('span')\n this.#sr.className = 'sr'\n this.#sr.setAttribute('aria-live', 'polite')\n this.#sr.setAttribute('aria-atomic', 'true')\n\n this.#visual = document.createElement('span')\n this.#visual.className = 'visual'\n this.#visual.setAttribute('aria-hidden', 'true')\n\n shell.append(this.#sr, this.#visual)\n root.append(style, shell)\n }\n\n this.#motionQuery.addEventListener('change', this.#onMotionChange)\n this.#syncReduced()\n this.#applyOptions()\n this.#stopMetrics = observeMetrics(this)\n this.#render(true)\n }\n\n disconnectedCallback(): void {\n this.#motionQuery.removeEventListener('change', this.#onMotionChange)\n this.#stopMetrics?.()\n this.#stopMetrics = undefined\n }\n\n attributeChangedCallback(name: string): void {\n if (!this.isConnected) return\n if (name === 'value') {\n this.#render(false)\n return\n }\n this.#applyOptions()\n if (name === 'animated') this.#render(false)\n }\n\n get value(): string {\n return this.getAttribute('value') ?? ''\n }\n\n set value(v: string) {\n this.setAttribute('value', v)\n }\n\n get preset(): Preset {\n return parsePreset(this.getAttribute('preset'))\n }\n\n set preset(v: Preset) {\n this.setAttribute('preset', v)\n }\n\n get animated(): boolean {\n return this.getAttribute('animated') !== 'false'\n }\n\n set animated(v: boolean) {\n if (v) this.removeAttribute('animated')\n else this.setAttribute('animated', 'false')\n }\n\n set spinTiming(t: EffectTiming | undefined) {\n this.#spinTiming = t\n this.#applyOptions()\n }\n\n set slideTiming(t: EffectTiming | undefined) {\n this.#slideTiming = t\n this.#applyOptions()\n }\n\n #canAnimate(): boolean {\n if (!this.animated) return false\n if (this.#motionQuery.matches) return false\n return true\n }\n\n #syncReduced(): void {\n if (this.#motionQuery.matches) this.dataset.reduced = ''\n else delete this.dataset.reduced\n }\n\n #applyOptions(): void {\n applyPresetStyle(this, this.preset)\n applyTimings(this, this.#spinTiming, this.#slideTiming)\n syncMetrics(this)\n }\n\n #render(initial: boolean): void {\n const next = this.value\n this.#sr.textContent = next\n\n const animated = this.#canAnimate() && !initial\n\n let segments\n if (initial || !this.#prevValue) {\n const init = initialSegments(next)\n segments = init.segments\n this.#keys = init.keys\n } else if (this.#prevValue === next) {\n return\n } else {\n const built = buildSegments(this.#prevValue, next, this.#keys)\n segments = built.segments\n this.#keys = built.keys\n }\n\n mountVisual(this.#visual, segments, animated)\n this.#prevValue = next\n }\n}\n\nexport function defineCharFlow(tag = TAG): void {\n if (!customElements.get(tag)) {\n customElements.define(tag, CharFlowElement)\n }\n}\n\ndefineCharFlow()\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'char-flow': CharFlowElement\n }\n}\n\nexport { TAG }\n","import { createElement, useEffect, useRef, type HTMLAttributes } from 'react'\nimport type { CharFlowElement } from './element'\nimport type { EffectTiming, Preset } from './types'\n\nexport type { CharFlowElement }\nexport type { Preset, EffectTiming } from './types'\n\nfunction assertRegistered(): void {\n if (typeof customElements !== 'undefined' && !customElements.get('char-flow')) {\n throw new Error(\n 'CharFlow: import \"char-flow/element\" before using the React wrapper.',\n )\n }\n}\n\nexport interface CharFlowProps extends Omit<HTMLAttributes<CharFlowElement>, 'value'> {\n value: string\n preset?: Preset\n animated?: boolean\n spinTiming?: EffectTiming\n slideTiming?: EffectTiming\n}\n\nexport function CharFlow({\n value,\n preset = 'alnum',\n animated = true,\n spinTiming,\n slideTiming,\n className,\n style,\n ...rest\n}: CharFlowProps) {\n const ref = useRef<CharFlowElement>(null)\n\n useEffect(() => {\n assertRegistered()\n }, [])\n\n useEffect(() => {\n const el = ref.current\n if (!el) return\n if (el.value !== value) el.value = value\n }, [value])\n\n useEffect(() => {\n const el = ref.current\n if (!el) return\n el.preset = preset\n el.animated = animated\n if (spinTiming !== undefined) el.spinTiming = spinTiming\n if (slideTiming !== undefined) el.slideTiming = slideTiming\n }, [preset, animated, spinTiming, slideTiming])\n\n return createElement('char-flow', {\n ref,\n value,\n preset,\n ...(animated ? {} : { animated: 'false' }),\n class: className,\n style,\n ...rest,\n })\n}\n"]}
|
package/dist/react.d.ts
ADDED
|
@@ -0,0 +1,299 @@
|
|
|
1
|
+
import * as react from 'react';
|
|
2
|
+
import { HTMLAttributes } from 'react';
|
|
3
|
+
import { a as CharFlowElement, P as Preset, E as EffectTiming } from './element-ohGNSSoB.js';
|
|
4
|
+
|
|
5
|
+
interface CharFlowProps extends Omit<HTMLAttributes<CharFlowElement>, 'value'> {
|
|
6
|
+
value: string;
|
|
7
|
+
preset?: Preset;
|
|
8
|
+
animated?: boolean;
|
|
9
|
+
spinTiming?: EffectTiming;
|
|
10
|
+
slideTiming?: EffectTiming;
|
|
11
|
+
}
|
|
12
|
+
declare function CharFlow({ value, preset, animated, spinTiming, slideTiming, className, style, ...rest }: CharFlowProps): react.DOMElement<{
|
|
13
|
+
slot?: string | undefined | undefined;
|
|
14
|
+
title?: string | undefined | undefined;
|
|
15
|
+
part?: string | undefined | undefined;
|
|
16
|
+
hidden?: boolean | undefined | undefined;
|
|
17
|
+
dir?: string | undefined | undefined;
|
|
18
|
+
"aria-live"?: "off" | "assertive" | "polite" | undefined | undefined;
|
|
19
|
+
"aria-atomic"?: (boolean | "true" | "false") | undefined;
|
|
20
|
+
"aria-hidden"?: (boolean | "true" | "false") | undefined;
|
|
21
|
+
defaultChecked?: boolean | undefined | undefined;
|
|
22
|
+
defaultValue?: string | number | readonly string[] | undefined;
|
|
23
|
+
suppressContentEditableWarning?: boolean | undefined | undefined;
|
|
24
|
+
suppressHydrationWarning?: boolean | undefined | undefined;
|
|
25
|
+
accessKey?: string | undefined | undefined;
|
|
26
|
+
autoCapitalize?: "off" | "none" | "on" | "sentences" | "words" | "characters" | undefined | (string & {}) | undefined;
|
|
27
|
+
autoFocus?: boolean | undefined | undefined;
|
|
28
|
+
contentEditable?: (boolean | "true" | "false") | "inherit" | "plaintext-only" | undefined;
|
|
29
|
+
contextMenu?: string | undefined | undefined;
|
|
30
|
+
draggable?: (boolean | "true" | "false") | undefined;
|
|
31
|
+
enterKeyHint?: "enter" | "done" | "go" | "next" | "previous" | "search" | "send" | undefined | undefined;
|
|
32
|
+
id?: string | undefined | undefined;
|
|
33
|
+
lang?: string | undefined | undefined;
|
|
34
|
+
nonce?: string | undefined | undefined;
|
|
35
|
+
spellCheck?: (boolean | "true" | "false") | undefined;
|
|
36
|
+
tabIndex?: number | undefined | undefined;
|
|
37
|
+
translate?: "yes" | "no" | undefined | undefined;
|
|
38
|
+
radioGroup?: string | undefined | undefined;
|
|
39
|
+
role?: react.AriaRole | undefined;
|
|
40
|
+
about?: string | undefined | undefined;
|
|
41
|
+
content?: string | undefined | undefined;
|
|
42
|
+
datatype?: string | undefined | undefined;
|
|
43
|
+
inlist?: any;
|
|
44
|
+
prefix?: string | undefined | undefined;
|
|
45
|
+
property?: string | undefined | undefined;
|
|
46
|
+
rel?: string | undefined | undefined;
|
|
47
|
+
resource?: string | undefined | undefined;
|
|
48
|
+
rev?: string | undefined | undefined;
|
|
49
|
+
typeof?: string | undefined | undefined;
|
|
50
|
+
vocab?: string | undefined | undefined;
|
|
51
|
+
autoCorrect?: string | undefined | undefined;
|
|
52
|
+
autoSave?: string | undefined | undefined;
|
|
53
|
+
color?: string | undefined | undefined;
|
|
54
|
+
itemProp?: string | undefined | undefined;
|
|
55
|
+
itemScope?: boolean | undefined | undefined;
|
|
56
|
+
itemType?: string | undefined | undefined;
|
|
57
|
+
itemID?: string | undefined | undefined;
|
|
58
|
+
itemRef?: string | undefined | undefined;
|
|
59
|
+
results?: number | undefined | undefined;
|
|
60
|
+
security?: string | undefined | undefined;
|
|
61
|
+
unselectable?: "on" | "off" | undefined | undefined;
|
|
62
|
+
popover?: "" | "auto" | "manual" | "hint" | undefined | undefined;
|
|
63
|
+
popoverTargetAction?: "toggle" | "show" | "hide" | undefined | undefined;
|
|
64
|
+
popoverTarget?: string | undefined | undefined;
|
|
65
|
+
inert?: boolean | undefined | undefined;
|
|
66
|
+
inputMode?: "none" | "text" | "tel" | "url" | "email" | "numeric" | "decimal" | "search" | undefined | undefined;
|
|
67
|
+
is?: string | undefined | undefined;
|
|
68
|
+
exportparts?: string | undefined | undefined;
|
|
69
|
+
"aria-activedescendant"?: string | undefined | undefined;
|
|
70
|
+
"aria-autocomplete"?: "none" | "inline" | "list" | "both" | undefined | undefined;
|
|
71
|
+
"aria-braillelabel"?: string | undefined | undefined;
|
|
72
|
+
"aria-brailleroledescription"?: string | undefined | undefined;
|
|
73
|
+
"aria-busy"?: (boolean | "true" | "false") | undefined;
|
|
74
|
+
"aria-checked"?: boolean | "false" | "mixed" | "true" | undefined | undefined;
|
|
75
|
+
"aria-colcount"?: number | undefined | undefined;
|
|
76
|
+
"aria-colindex"?: number | undefined | undefined;
|
|
77
|
+
"aria-colindextext"?: string | undefined | undefined;
|
|
78
|
+
"aria-colspan"?: number | undefined | undefined;
|
|
79
|
+
"aria-controls"?: string | undefined | undefined;
|
|
80
|
+
"aria-current"?: boolean | "false" | "true" | "page" | "step" | "location" | "date" | "time" | undefined | undefined;
|
|
81
|
+
"aria-describedby"?: string | undefined | undefined;
|
|
82
|
+
"aria-description"?: string | undefined | undefined;
|
|
83
|
+
"aria-details"?: string | undefined | undefined;
|
|
84
|
+
"aria-disabled"?: (boolean | "true" | "false") | undefined;
|
|
85
|
+
"aria-dropeffect"?: "none" | "copy" | "execute" | "link" | "move" | "popup" | undefined | undefined;
|
|
86
|
+
"aria-errormessage"?: string | undefined | undefined;
|
|
87
|
+
"aria-expanded"?: (boolean | "true" | "false") | undefined;
|
|
88
|
+
"aria-flowto"?: string | undefined | undefined;
|
|
89
|
+
"aria-grabbed"?: (boolean | "true" | "false") | undefined;
|
|
90
|
+
"aria-haspopup"?: boolean | "false" | "true" | "menu" | "listbox" | "tree" | "grid" | "dialog" | undefined | undefined;
|
|
91
|
+
"aria-invalid"?: boolean | "false" | "true" | "grammar" | "spelling" | undefined | undefined;
|
|
92
|
+
"aria-keyshortcuts"?: string | undefined | undefined;
|
|
93
|
+
"aria-label"?: string | undefined | undefined;
|
|
94
|
+
"aria-labelledby"?: string | undefined | undefined;
|
|
95
|
+
"aria-level"?: number | undefined | undefined;
|
|
96
|
+
"aria-modal"?: (boolean | "true" | "false") | undefined;
|
|
97
|
+
"aria-multiline"?: (boolean | "true" | "false") | undefined;
|
|
98
|
+
"aria-multiselectable"?: (boolean | "true" | "false") | undefined;
|
|
99
|
+
"aria-orientation"?: "horizontal" | "vertical" | undefined | undefined;
|
|
100
|
+
"aria-owns"?: string | undefined | undefined;
|
|
101
|
+
"aria-placeholder"?: string | undefined | undefined;
|
|
102
|
+
"aria-posinset"?: number | undefined | undefined;
|
|
103
|
+
"aria-pressed"?: boolean | "false" | "mixed" | "true" | undefined | undefined;
|
|
104
|
+
"aria-readonly"?: (boolean | "true" | "false") | undefined;
|
|
105
|
+
"aria-relevant"?: "additions" | "additions removals" | "additions text" | "all" | "removals" | "removals additions" | "removals text" | "text" | "text additions" | "text removals" | undefined | undefined;
|
|
106
|
+
"aria-required"?: (boolean | "true" | "false") | undefined;
|
|
107
|
+
"aria-roledescription"?: string | undefined | undefined;
|
|
108
|
+
"aria-rowcount"?: number | undefined | undefined;
|
|
109
|
+
"aria-rowindex"?: number | undefined | undefined;
|
|
110
|
+
"aria-rowindextext"?: string | undefined | undefined;
|
|
111
|
+
"aria-rowspan"?: number | undefined | undefined;
|
|
112
|
+
"aria-selected"?: (boolean | "true" | "false") | undefined;
|
|
113
|
+
"aria-setsize"?: number | undefined | undefined;
|
|
114
|
+
"aria-sort"?: "none" | "ascending" | "descending" | "other" | undefined | undefined;
|
|
115
|
+
"aria-valuemax"?: number | undefined | undefined;
|
|
116
|
+
"aria-valuemin"?: number | undefined | undefined;
|
|
117
|
+
"aria-valuenow"?: number | undefined | undefined;
|
|
118
|
+
"aria-valuetext"?: string | undefined | undefined;
|
|
119
|
+
children?: react.ReactNode;
|
|
120
|
+
dangerouslySetInnerHTML?: {
|
|
121
|
+
__html: string | TrustedHTML;
|
|
122
|
+
} | undefined | undefined;
|
|
123
|
+
onCopy?: react.ClipboardEventHandler<CharFlowElement> | undefined;
|
|
124
|
+
onCopyCapture?: react.ClipboardEventHandler<CharFlowElement> | undefined;
|
|
125
|
+
onCut?: react.ClipboardEventHandler<CharFlowElement> | undefined;
|
|
126
|
+
onCutCapture?: react.ClipboardEventHandler<CharFlowElement> | undefined;
|
|
127
|
+
onPaste?: react.ClipboardEventHandler<CharFlowElement> | undefined;
|
|
128
|
+
onPasteCapture?: react.ClipboardEventHandler<CharFlowElement> | undefined;
|
|
129
|
+
onCompositionEnd?: react.CompositionEventHandler<CharFlowElement> | undefined;
|
|
130
|
+
onCompositionEndCapture?: react.CompositionEventHandler<CharFlowElement> | undefined;
|
|
131
|
+
onCompositionStart?: react.CompositionEventHandler<CharFlowElement> | undefined;
|
|
132
|
+
onCompositionStartCapture?: react.CompositionEventHandler<CharFlowElement> | undefined;
|
|
133
|
+
onCompositionUpdate?: react.CompositionEventHandler<CharFlowElement> | undefined;
|
|
134
|
+
onCompositionUpdateCapture?: react.CompositionEventHandler<CharFlowElement> | undefined;
|
|
135
|
+
onFocus?: react.FocusEventHandler<CharFlowElement> | undefined;
|
|
136
|
+
onFocusCapture?: react.FocusEventHandler<CharFlowElement> | undefined;
|
|
137
|
+
onBlur?: react.FocusEventHandler<CharFlowElement> | undefined;
|
|
138
|
+
onBlurCapture?: react.FocusEventHandler<CharFlowElement> | undefined;
|
|
139
|
+
onChange?: react.ChangeEventHandler<CharFlowElement, Element> | undefined;
|
|
140
|
+
onChangeCapture?: react.ChangeEventHandler<CharFlowElement, Element> | undefined;
|
|
141
|
+
onBeforeInput?: react.InputEventHandler<CharFlowElement> | undefined;
|
|
142
|
+
onBeforeInputCapture?: react.InputEventHandler<CharFlowElement> | undefined;
|
|
143
|
+
onInput?: react.InputEventHandler<CharFlowElement> | undefined;
|
|
144
|
+
onInputCapture?: react.InputEventHandler<CharFlowElement> | undefined;
|
|
145
|
+
onReset?: react.ReactEventHandler<CharFlowElement> | undefined;
|
|
146
|
+
onResetCapture?: react.ReactEventHandler<CharFlowElement> | undefined;
|
|
147
|
+
onSubmit?: react.SubmitEventHandler<CharFlowElement> | undefined;
|
|
148
|
+
onSubmitCapture?: react.SubmitEventHandler<CharFlowElement> | undefined;
|
|
149
|
+
onInvalid?: react.ReactEventHandler<CharFlowElement> | undefined;
|
|
150
|
+
onInvalidCapture?: react.ReactEventHandler<CharFlowElement> | undefined;
|
|
151
|
+
onLoad?: react.ReactEventHandler<CharFlowElement> | undefined;
|
|
152
|
+
onLoadCapture?: react.ReactEventHandler<CharFlowElement> | undefined;
|
|
153
|
+
onError?: react.ReactEventHandler<CharFlowElement> | undefined;
|
|
154
|
+
onErrorCapture?: react.ReactEventHandler<CharFlowElement> | undefined;
|
|
155
|
+
onKeyDown?: react.KeyboardEventHandler<CharFlowElement> | undefined;
|
|
156
|
+
onKeyDownCapture?: react.KeyboardEventHandler<CharFlowElement> | undefined;
|
|
157
|
+
onKeyPress?: react.KeyboardEventHandler<CharFlowElement> | undefined;
|
|
158
|
+
onKeyPressCapture?: react.KeyboardEventHandler<CharFlowElement> | undefined;
|
|
159
|
+
onKeyUp?: react.KeyboardEventHandler<CharFlowElement> | undefined;
|
|
160
|
+
onKeyUpCapture?: react.KeyboardEventHandler<CharFlowElement> | undefined;
|
|
161
|
+
onAbort?: react.ReactEventHandler<CharFlowElement> | undefined;
|
|
162
|
+
onAbortCapture?: react.ReactEventHandler<CharFlowElement> | undefined;
|
|
163
|
+
onCanPlay?: react.ReactEventHandler<CharFlowElement> | undefined;
|
|
164
|
+
onCanPlayCapture?: react.ReactEventHandler<CharFlowElement> | undefined;
|
|
165
|
+
onCanPlayThrough?: react.ReactEventHandler<CharFlowElement> | undefined;
|
|
166
|
+
onCanPlayThroughCapture?: react.ReactEventHandler<CharFlowElement> | undefined;
|
|
167
|
+
onDurationChange?: react.ReactEventHandler<CharFlowElement> | undefined;
|
|
168
|
+
onDurationChangeCapture?: react.ReactEventHandler<CharFlowElement> | undefined;
|
|
169
|
+
onEmptied?: react.ReactEventHandler<CharFlowElement> | undefined;
|
|
170
|
+
onEmptiedCapture?: react.ReactEventHandler<CharFlowElement> | undefined;
|
|
171
|
+
onEncrypted?: react.ReactEventHandler<CharFlowElement> | undefined;
|
|
172
|
+
onEncryptedCapture?: react.ReactEventHandler<CharFlowElement> | undefined;
|
|
173
|
+
onEnded?: react.ReactEventHandler<CharFlowElement> | undefined;
|
|
174
|
+
onEndedCapture?: react.ReactEventHandler<CharFlowElement> | undefined;
|
|
175
|
+
onLoadedData?: react.ReactEventHandler<CharFlowElement> | undefined;
|
|
176
|
+
onLoadedDataCapture?: react.ReactEventHandler<CharFlowElement> | undefined;
|
|
177
|
+
onLoadedMetadata?: react.ReactEventHandler<CharFlowElement> | undefined;
|
|
178
|
+
onLoadedMetadataCapture?: react.ReactEventHandler<CharFlowElement> | undefined;
|
|
179
|
+
onLoadStart?: react.ReactEventHandler<CharFlowElement> | undefined;
|
|
180
|
+
onLoadStartCapture?: react.ReactEventHandler<CharFlowElement> | undefined;
|
|
181
|
+
onPause?: react.ReactEventHandler<CharFlowElement> | undefined;
|
|
182
|
+
onPauseCapture?: react.ReactEventHandler<CharFlowElement> | undefined;
|
|
183
|
+
onPlay?: react.ReactEventHandler<CharFlowElement> | undefined;
|
|
184
|
+
onPlayCapture?: react.ReactEventHandler<CharFlowElement> | undefined;
|
|
185
|
+
onPlaying?: react.ReactEventHandler<CharFlowElement> | undefined;
|
|
186
|
+
onPlayingCapture?: react.ReactEventHandler<CharFlowElement> | undefined;
|
|
187
|
+
onProgress?: react.ReactEventHandler<CharFlowElement> | undefined;
|
|
188
|
+
onProgressCapture?: react.ReactEventHandler<CharFlowElement> | undefined;
|
|
189
|
+
onRateChange?: react.ReactEventHandler<CharFlowElement> | undefined;
|
|
190
|
+
onRateChangeCapture?: react.ReactEventHandler<CharFlowElement> | undefined;
|
|
191
|
+
onSeeked?: react.ReactEventHandler<CharFlowElement> | undefined;
|
|
192
|
+
onSeekedCapture?: react.ReactEventHandler<CharFlowElement> | undefined;
|
|
193
|
+
onSeeking?: react.ReactEventHandler<CharFlowElement> | undefined;
|
|
194
|
+
onSeekingCapture?: react.ReactEventHandler<CharFlowElement> | undefined;
|
|
195
|
+
onStalled?: react.ReactEventHandler<CharFlowElement> | undefined;
|
|
196
|
+
onStalledCapture?: react.ReactEventHandler<CharFlowElement> | undefined;
|
|
197
|
+
onSuspend?: react.ReactEventHandler<CharFlowElement> | undefined;
|
|
198
|
+
onSuspendCapture?: react.ReactEventHandler<CharFlowElement> | undefined;
|
|
199
|
+
onTimeUpdate?: react.ReactEventHandler<CharFlowElement> | undefined;
|
|
200
|
+
onTimeUpdateCapture?: react.ReactEventHandler<CharFlowElement> | undefined;
|
|
201
|
+
onVolumeChange?: react.ReactEventHandler<CharFlowElement> | undefined;
|
|
202
|
+
onVolumeChangeCapture?: react.ReactEventHandler<CharFlowElement> | undefined;
|
|
203
|
+
onWaiting?: react.ReactEventHandler<CharFlowElement> | undefined;
|
|
204
|
+
onWaitingCapture?: react.ReactEventHandler<CharFlowElement> | undefined;
|
|
205
|
+
onAuxClick?: react.MouseEventHandler<CharFlowElement> | undefined;
|
|
206
|
+
onAuxClickCapture?: react.MouseEventHandler<CharFlowElement> | undefined;
|
|
207
|
+
onClick?: react.MouseEventHandler<CharFlowElement> | undefined;
|
|
208
|
+
onClickCapture?: react.MouseEventHandler<CharFlowElement> | undefined;
|
|
209
|
+
onContextMenu?: react.MouseEventHandler<CharFlowElement> | undefined;
|
|
210
|
+
onContextMenuCapture?: react.MouseEventHandler<CharFlowElement> | undefined;
|
|
211
|
+
onDoubleClick?: react.MouseEventHandler<CharFlowElement> | undefined;
|
|
212
|
+
onDoubleClickCapture?: react.MouseEventHandler<CharFlowElement> | undefined;
|
|
213
|
+
onDrag?: react.DragEventHandler<CharFlowElement> | undefined;
|
|
214
|
+
onDragCapture?: react.DragEventHandler<CharFlowElement> | undefined;
|
|
215
|
+
onDragEnd?: react.DragEventHandler<CharFlowElement> | undefined;
|
|
216
|
+
onDragEndCapture?: react.DragEventHandler<CharFlowElement> | undefined;
|
|
217
|
+
onDragEnter?: react.DragEventHandler<CharFlowElement> | undefined;
|
|
218
|
+
onDragEnterCapture?: react.DragEventHandler<CharFlowElement> | undefined;
|
|
219
|
+
onDragExit?: react.DragEventHandler<CharFlowElement> | undefined;
|
|
220
|
+
onDragExitCapture?: react.DragEventHandler<CharFlowElement> | undefined;
|
|
221
|
+
onDragLeave?: react.DragEventHandler<CharFlowElement> | undefined;
|
|
222
|
+
onDragLeaveCapture?: react.DragEventHandler<CharFlowElement> | undefined;
|
|
223
|
+
onDragOver?: react.DragEventHandler<CharFlowElement> | undefined;
|
|
224
|
+
onDragOverCapture?: react.DragEventHandler<CharFlowElement> | undefined;
|
|
225
|
+
onDragStart?: react.DragEventHandler<CharFlowElement> | undefined;
|
|
226
|
+
onDragStartCapture?: react.DragEventHandler<CharFlowElement> | undefined;
|
|
227
|
+
onDrop?: react.DragEventHandler<CharFlowElement> | undefined;
|
|
228
|
+
onDropCapture?: react.DragEventHandler<CharFlowElement> | undefined;
|
|
229
|
+
onMouseDown?: react.MouseEventHandler<CharFlowElement> | undefined;
|
|
230
|
+
onMouseDownCapture?: react.MouseEventHandler<CharFlowElement> | undefined;
|
|
231
|
+
onMouseEnter?: react.MouseEventHandler<CharFlowElement> | undefined;
|
|
232
|
+
onMouseLeave?: react.MouseEventHandler<CharFlowElement> | undefined;
|
|
233
|
+
onMouseMove?: react.MouseEventHandler<CharFlowElement> | undefined;
|
|
234
|
+
onMouseMoveCapture?: react.MouseEventHandler<CharFlowElement> | undefined;
|
|
235
|
+
onMouseOut?: react.MouseEventHandler<CharFlowElement> | undefined;
|
|
236
|
+
onMouseOutCapture?: react.MouseEventHandler<CharFlowElement> | undefined;
|
|
237
|
+
onMouseOver?: react.MouseEventHandler<CharFlowElement> | undefined;
|
|
238
|
+
onMouseOverCapture?: react.MouseEventHandler<CharFlowElement> | undefined;
|
|
239
|
+
onMouseUp?: react.MouseEventHandler<CharFlowElement> | undefined;
|
|
240
|
+
onMouseUpCapture?: react.MouseEventHandler<CharFlowElement> | undefined;
|
|
241
|
+
onSelect?: react.ReactEventHandler<CharFlowElement> | undefined;
|
|
242
|
+
onSelectCapture?: react.ReactEventHandler<CharFlowElement> | undefined;
|
|
243
|
+
onTouchCancel?: react.TouchEventHandler<CharFlowElement> | undefined;
|
|
244
|
+
onTouchCancelCapture?: react.TouchEventHandler<CharFlowElement> | undefined;
|
|
245
|
+
onTouchEnd?: react.TouchEventHandler<CharFlowElement> | undefined;
|
|
246
|
+
onTouchEndCapture?: react.TouchEventHandler<CharFlowElement> | undefined;
|
|
247
|
+
onTouchMove?: react.TouchEventHandler<CharFlowElement> | undefined;
|
|
248
|
+
onTouchMoveCapture?: react.TouchEventHandler<CharFlowElement> | undefined;
|
|
249
|
+
onTouchStart?: react.TouchEventHandler<CharFlowElement> | undefined;
|
|
250
|
+
onTouchStartCapture?: react.TouchEventHandler<CharFlowElement> | undefined;
|
|
251
|
+
onPointerDown?: react.PointerEventHandler<CharFlowElement> | undefined;
|
|
252
|
+
onPointerDownCapture?: react.PointerEventHandler<CharFlowElement> | undefined;
|
|
253
|
+
onPointerMove?: react.PointerEventHandler<CharFlowElement> | undefined;
|
|
254
|
+
onPointerMoveCapture?: react.PointerEventHandler<CharFlowElement> | undefined;
|
|
255
|
+
onPointerUp?: react.PointerEventHandler<CharFlowElement> | undefined;
|
|
256
|
+
onPointerUpCapture?: react.PointerEventHandler<CharFlowElement> | undefined;
|
|
257
|
+
onPointerCancel?: react.PointerEventHandler<CharFlowElement> | undefined;
|
|
258
|
+
onPointerCancelCapture?: react.PointerEventHandler<CharFlowElement> | undefined;
|
|
259
|
+
onPointerEnter?: react.PointerEventHandler<CharFlowElement> | undefined;
|
|
260
|
+
onPointerLeave?: react.PointerEventHandler<CharFlowElement> | undefined;
|
|
261
|
+
onPointerOver?: react.PointerEventHandler<CharFlowElement> | undefined;
|
|
262
|
+
onPointerOverCapture?: react.PointerEventHandler<CharFlowElement> | undefined;
|
|
263
|
+
onPointerOut?: react.PointerEventHandler<CharFlowElement> | undefined;
|
|
264
|
+
onPointerOutCapture?: react.PointerEventHandler<CharFlowElement> | undefined;
|
|
265
|
+
onGotPointerCapture?: react.PointerEventHandler<CharFlowElement> | undefined;
|
|
266
|
+
onGotPointerCaptureCapture?: react.PointerEventHandler<CharFlowElement> | undefined;
|
|
267
|
+
onLostPointerCapture?: react.PointerEventHandler<CharFlowElement> | undefined;
|
|
268
|
+
onLostPointerCaptureCapture?: react.PointerEventHandler<CharFlowElement> | undefined;
|
|
269
|
+
onScroll?: react.UIEventHandler<CharFlowElement> | undefined;
|
|
270
|
+
onScrollCapture?: react.UIEventHandler<CharFlowElement> | undefined;
|
|
271
|
+
onScrollEnd?: react.UIEventHandler<CharFlowElement> | undefined;
|
|
272
|
+
onScrollEndCapture?: react.UIEventHandler<CharFlowElement> | undefined;
|
|
273
|
+
onWheel?: react.WheelEventHandler<CharFlowElement> | undefined;
|
|
274
|
+
onWheelCapture?: react.WheelEventHandler<CharFlowElement> | undefined;
|
|
275
|
+
onAnimationStart?: react.AnimationEventHandler<CharFlowElement> | undefined;
|
|
276
|
+
onAnimationStartCapture?: react.AnimationEventHandler<CharFlowElement> | undefined;
|
|
277
|
+
onAnimationEnd?: react.AnimationEventHandler<CharFlowElement> | undefined;
|
|
278
|
+
onAnimationEndCapture?: react.AnimationEventHandler<CharFlowElement> | undefined;
|
|
279
|
+
onAnimationIteration?: react.AnimationEventHandler<CharFlowElement> | undefined;
|
|
280
|
+
onAnimationIterationCapture?: react.AnimationEventHandler<CharFlowElement> | undefined;
|
|
281
|
+
onToggle?: react.ToggleEventHandler<CharFlowElement> | undefined;
|
|
282
|
+
onBeforeToggle?: react.ToggleEventHandler<CharFlowElement> | undefined;
|
|
283
|
+
onTransitionCancel?: react.TransitionEventHandler<CharFlowElement> | undefined;
|
|
284
|
+
onTransitionCancelCapture?: react.TransitionEventHandler<CharFlowElement> | undefined;
|
|
285
|
+
onTransitionEnd?: react.TransitionEventHandler<CharFlowElement> | undefined;
|
|
286
|
+
onTransitionEndCapture?: react.TransitionEventHandler<CharFlowElement> | undefined;
|
|
287
|
+
onTransitionRun?: react.TransitionEventHandler<CharFlowElement> | undefined;
|
|
288
|
+
onTransitionRunCapture?: react.TransitionEventHandler<CharFlowElement> | undefined;
|
|
289
|
+
onTransitionStart?: react.TransitionEventHandler<CharFlowElement> | undefined;
|
|
290
|
+
onTransitionStartCapture?: react.TransitionEventHandler<CharFlowElement> | undefined;
|
|
291
|
+
class: string | undefined;
|
|
292
|
+
style: react.CSSProperties | undefined;
|
|
293
|
+
animated?: string;
|
|
294
|
+
ref: react.RefObject<CharFlowElement | null>;
|
|
295
|
+
value: string;
|
|
296
|
+
preset: Preset;
|
|
297
|
+
}, CharFlowElement>;
|
|
298
|
+
|
|
299
|
+
export { CharFlow, CharFlowElement, type CharFlowProps, EffectTiming, Preset };
|
package/dist/react.js
ADDED
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import {useRef,useEffect,createElement}from'react';function p(){if(typeof customElements<"u"&&!customElements.get("char-flow"))throw new Error('CharFlow: import "char-flow/element" before using the React wrapper.')}function h({value:t,preset:r="alnum",animated:n=true,spinTiming:o,slideTiming:f,className:s,style:m,...a}){let i=useRef(null);return useEffect(()=>{p();},[]),useEffect(()=>{let e=i.current;e&&e.value!==t&&(e.value=t);},[t]),useEffect(()=>{let e=i.current;e&&(e.preset=r,e.animated=n,o!==void 0&&(e.spinTiming=o),f!==void 0&&(e.slideTiming=f));},[r,n,o,f]),createElement("char-flow",{ref:i,value:t,preset:r,...n?{}:{animated:"false"},class:s,style:m,...a})}export{h as CharFlow};//# sourceMappingURL=react.js.map
|
|
2
|
+
//# sourceMappingURL=react.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/react.tsx"],"names":["assertRegistered","CharFlow","value","preset","animated","spinTiming","slideTiming","className","style","rest","ref","useRef","useEffect","el","createElement"],"mappings":"mDAOA,SAASA,CAAAA,EAAyB,CAChC,GAAI,OAAO,eAAmB,GAAA,EAAe,CAAC,cAAA,CAAe,GAAA,CAAI,WAAW,CAAA,CAC1E,MAAM,IAAI,MACR,sEACF,CAEJ,CAUO,SAASC,CAAAA,CAAS,CACvB,KAAA,CAAAC,CAAAA,CACA,OAAAC,CAAAA,CAAS,OAAA,CACT,QAAA,CAAAC,CAAAA,CAAW,IAAA,CACX,UAAA,CAAAC,CAAAA,CACA,WAAA,CAAAC,EACA,SAAA,CAAAC,CAAAA,CACA,KAAA,CAAAC,CAAAA,CACA,GAAGC,CACL,CAAA,CAAkB,CAChB,IAAMC,CAAAA,CAAMC,MAAAA,CAAwB,IAAI,CAAA,CAExC,OAAAC,SAAAA,CAAU,IAAM,CACdZ,IACF,CAAA,CAAG,EAAE,CAAA,CAELY,SAAAA,CAAU,IAAM,CACd,IAAMC,CAAAA,CAAKH,CAAAA,CAAI,OAAA,CACVG,CAAAA,EACDA,CAAAA,CAAG,KAAA,GAAUX,CAAAA,GAAOW,CAAAA,CAAG,KAAA,CAAQX,CAAAA,EACrC,CAAA,CAAG,CAACA,CAAK,CAAC,CAAA,CAEVU,SAAAA,CAAU,IAAM,CACd,IAAMC,CAAAA,CAAKH,CAAAA,CAAI,OAAA,CACVG,CAAAA,GACLA,CAAAA,CAAG,MAAA,CAASV,EACZU,CAAAA,CAAG,QAAA,CAAWT,CAAAA,CACVC,CAAAA,GAAe,MAAA,GAAWQ,CAAAA,CAAG,UAAA,CAAaR,CAAAA,CAAAA,CAC1CC,IAAgB,MAAA,GAAWO,CAAAA,CAAG,WAAA,CAAcP,CAAAA,CAAAA,EAClD,CAAA,CAAG,CAACH,CAAAA,CAAQC,CAAAA,CAAUC,EAAYC,CAAW,CAAC,CAAA,CAEvCQ,aAAAA,CAAc,WAAA,CAAa,CAChC,GAAA,CAAAJ,CAAAA,CACA,MAAAR,CAAAA,CACA,MAAA,CAAAC,CAAAA,CACA,GAAIC,CAAAA,CAAW,EAAC,CAAI,CAAE,SAAU,OAAQ,CAAA,CACxC,KAAA,CAAOG,CAAAA,CACP,KAAA,CAAAC,CAAAA,CACA,GAAGC,CACL,CAAC,CACH","file":"react.js","sourcesContent":["import { createElement, useEffect, useRef, type HTMLAttributes } from 'react'\nimport type { CharFlowElement } from './element'\nimport type { EffectTiming, Preset } from './types'\n\nexport type { CharFlowElement }\nexport type { Preset, EffectTiming } from './types'\n\nfunction assertRegistered(): void {\n if (typeof customElements !== 'undefined' && !customElements.get('char-flow')) {\n throw new Error(\n 'CharFlow: import \"char-flow/element\" before using the React wrapper.',\n )\n }\n}\n\nexport interface CharFlowProps extends Omit<HTMLAttributes<CharFlowElement>, 'value'> {\n value: string\n preset?: Preset\n animated?: boolean\n spinTiming?: EffectTiming\n slideTiming?: EffectTiming\n}\n\nexport function CharFlow({\n value,\n preset = 'alnum',\n animated = true,\n spinTiming,\n slideTiming,\n className,\n style,\n ...rest\n}: CharFlowProps) {\n const ref = useRef<CharFlowElement>(null)\n\n useEffect(() => {\n assertRegistered()\n }, [])\n\n useEffect(() => {\n const el = ref.current\n if (!el) return\n if (el.value !== value) el.value = value\n }, [value])\n\n useEffect(() => {\n const el = ref.current\n if (!el) return\n el.preset = preset\n el.animated = animated\n if (spinTiming !== undefined) el.spinTiming = spinTiming\n if (slideTiming !== undefined) el.slideTiming = slideTiming\n }, [preset, animated, spinTiming, slideTiming])\n\n return createElement('char-flow', {\n ref,\n value,\n preset,\n ...(animated ? {} : { animated: 'false' }),\n class: className,\n style,\n ...rest,\n })\n}\n"]}
|
package/package.json
ADDED
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "char-flow",
|
|
3
|
+
"version": "0.1.2",
|
|
4
|
+
"description": "CharFlow — lightweight animated alphanumeric text for license plates, codes, and flowing paragraphs",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"license": "MIT",
|
|
7
|
+
"author": "scankenteken",
|
|
8
|
+
"repository": {
|
|
9
|
+
"type": "git",
|
|
10
|
+
"url": "git+https://github.com/scan-kenteken/char-flow.git"
|
|
11
|
+
},
|
|
12
|
+
"bugs": {
|
|
13
|
+
"url": "https://github.com/scan-kenteken/char-flow/issues"
|
|
14
|
+
},
|
|
15
|
+
"homepage": "https://github.com/scan-kenteken/char-flow#readme",
|
|
16
|
+
"keywords": [
|
|
17
|
+
"animation",
|
|
18
|
+
"text",
|
|
19
|
+
"license-plate",
|
|
20
|
+
"kenteken",
|
|
21
|
+
"web-component",
|
|
22
|
+
"custom-element",
|
|
23
|
+
"react",
|
|
24
|
+
"alphanumeric",
|
|
25
|
+
"diff"
|
|
26
|
+
],
|
|
27
|
+
"engines": {
|
|
28
|
+
"node": ">=18"
|
|
29
|
+
},
|
|
30
|
+
"main": "./dist/index.js",
|
|
31
|
+
"module": "./dist/index.js",
|
|
32
|
+
"types": "./dist/index.d.ts",
|
|
33
|
+
"exports": {
|
|
34
|
+
".": {
|
|
35
|
+
"types": "./dist/index.d.ts",
|
|
36
|
+
"import": "./dist/index.js"
|
|
37
|
+
},
|
|
38
|
+
"./element": {
|
|
39
|
+
"types": "./dist/element.d.ts",
|
|
40
|
+
"import": "./dist/element.js"
|
|
41
|
+
},
|
|
42
|
+
"./react": {
|
|
43
|
+
"types": "./dist/react.d.ts",
|
|
44
|
+
"import": "./dist/react.js"
|
|
45
|
+
}
|
|
46
|
+
},
|
|
47
|
+
"files": [
|
|
48
|
+
"dist",
|
|
49
|
+
"README.md",
|
|
50
|
+
"LICENSE"
|
|
51
|
+
],
|
|
52
|
+
"sideEffects": true,
|
|
53
|
+
"scripts": {
|
|
54
|
+
"clean": "node -e \"import('node:fs').then(fs => fs.rmSync('dist', { recursive: true, force: true }))\"",
|
|
55
|
+
"build": "tsup",
|
|
56
|
+
"demo": "npm run build && cp dist/element.js demo/element.js && npx --yes serve . -p 3000",
|
|
57
|
+
"dev": "tsup --watch",
|
|
58
|
+
"typecheck": "tsc --noEmit",
|
|
59
|
+
"prepack": "npm run typecheck && npm run build",
|
|
60
|
+
"capture-demo": "node scripts/capture-demo.mjs"
|
|
61
|
+
},
|
|
62
|
+
"peerDependencies": {
|
|
63
|
+
"react": ">=18"
|
|
64
|
+
},
|
|
65
|
+
"peerDependenciesMeta": {
|
|
66
|
+
"react": {
|
|
67
|
+
"optional": true
|
|
68
|
+
}
|
|
69
|
+
},
|
|
70
|
+
"devDependencies": {
|
|
71
|
+
"@types/react": "^19.1.8",
|
|
72
|
+
"puppeteer-core": "^25.1.0",
|
|
73
|
+
"react": "^19.1.0",
|
|
74
|
+
"tsup": "^8.5.0",
|
|
75
|
+
"typescript": "^5.8.3"
|
|
76
|
+
}
|
|
77
|
+
}
|