@lukas_holdings/castdom 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (69) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +707 -0
  3. package/bin/castdom.js +2 -0
  4. package/dist/astro.cjs +86 -0
  5. package/dist/astro.cjs.map +1 -0
  6. package/dist/astro.d.cts +88 -0
  7. package/dist/astro.d.ts +88 -0
  8. package/dist/astro.js +80 -0
  9. package/dist/astro.js.map +1 -0
  10. package/dist/chunk-COLESJ66.js +57 -0
  11. package/dist/chunk-COLESJ66.js.map +1 -0
  12. package/dist/chunk-EJRNKHL5.js +31 -0
  13. package/dist/chunk-EJRNKHL5.js.map +1 -0
  14. package/dist/chunk-JRQ6EVQP.cjs +35 -0
  15. package/dist/chunk-JRQ6EVQP.cjs.map +1 -0
  16. package/dist/chunk-KGLTVTHU.js +73 -0
  17. package/dist/chunk-KGLTVTHU.js.map +1 -0
  18. package/dist/chunk-O4OOMGGM.cjs +198 -0
  19. package/dist/chunk-O4OOMGGM.cjs.map +1 -0
  20. package/dist/chunk-ONS533CQ.js +104 -0
  21. package/dist/chunk-ONS533CQ.js.map +1 -0
  22. package/dist/chunk-ORY4OMZ5.cjs +110 -0
  23. package/dist/chunk-ORY4OMZ5.cjs.map +1 -0
  24. package/dist/chunk-QLEBTZIB.cjs +64 -0
  25. package/dist/chunk-QLEBTZIB.cjs.map +1 -0
  26. package/dist/chunk-XS5HAU5E.cjs +109 -0
  27. package/dist/chunk-XS5HAU5E.cjs.map +1 -0
  28. package/dist/chunk-YDT4TPB7.cjs +84 -0
  29. package/dist/chunk-YDT4TPB7.cjs.map +1 -0
  30. package/dist/chunk-ZBJB7WVV.js +193 -0
  31. package/dist/chunk-ZBJB7WVV.js.map +1 -0
  32. package/dist/chunk-ZWZ5ZLJE.js +103 -0
  33. package/dist/chunk-ZWZ5ZLJE.js.map +1 -0
  34. package/dist/cli.js +135 -0
  35. package/dist/index.cjs +540 -0
  36. package/dist/index.cjs.map +1 -0
  37. package/dist/index.d.cts +176 -0
  38. package/dist/index.d.ts +176 -0
  39. package/dist/index.js +440 -0
  40. package/dist/index.js.map +1 -0
  41. package/dist/next.cjs +65 -0
  42. package/dist/next.cjs.map +1 -0
  43. package/dist/next.d.cts +72 -0
  44. package/dist/next.d.ts +72 -0
  45. package/dist/next.js +48 -0
  46. package/dist/next.js.map +1 -0
  47. package/dist/react.cjs +30 -0
  48. package/dist/react.cjs.map +1 -0
  49. package/dist/react.d.cts +70 -0
  50. package/dist/react.d.ts +70 -0
  51. package/dist/react.js +7 -0
  52. package/dist/react.js.map +1 -0
  53. package/dist/renderer-B1R7u2wm.d.ts +30 -0
  54. package/dist/renderer-Bfzjr6l9.d.cts +30 -0
  55. package/dist/ssr.cjs +46 -0
  56. package/dist/ssr.cjs.map +1 -0
  57. package/dist/ssr.d.cts +83 -0
  58. package/dist/ssr.d.ts +83 -0
  59. package/dist/ssr.js +5 -0
  60. package/dist/ssr.js.map +1 -0
  61. package/dist/types-ChD5jENU.d.cts +105 -0
  62. package/dist/types-ChD5jENU.d.ts +105 -0
  63. package/dist/vite.cjs +83 -0
  64. package/dist/vite.cjs.map +1 -0
  65. package/dist/vite.d.cts +81 -0
  66. package/dist/vite.d.ts +81 -0
  67. package/dist/vite.js +77 -0
  68. package/dist/vite.js.map +1 -0
  69. package/package.json +130 -0
package/dist/cli.js ADDED
@@ -0,0 +1,135 @@
1
+ #!/usr/bin/env node
2
+ var V=(e=>typeof require<"u"?require:typeof Proxy<"u"?new Proxy(e,{get:(t,n)=>(typeof require<"u"?require:t)[n]}):e)(function(e){if(typeof require<"u")return require.apply(this,arguments);throw Error('Dynamic require of "'+e+'" is not supported')});import{resolve as S,join as ae}from"path";import{readFileSync as _,writeFileSync as H,mkdirSync as ce,existsSync as C}from"fs";var p={outDir:".castdom",breakpoints:[375,768,1280],color:"#e0e0e0",shimmerColor:"#f0f0f0",animationDuration:1500,contentAware:!0,minBoneSize:4,classPrefix:"castdom",inlineStyles:!1,ssr:!0},v={text:1,heading:2,image:3,avatar:4,button:5,input:6,icon:7,divider:8,block:0},W=Object.fromEntries(Object.entries(v).map(([e,t])=>[t,e]));var B=new Set(["A","ABBR","B","BDO","BR","CITE","CODE","DFN","EM","I","KBD","MARK","Q","S","SAMP","SMALL","SPAN","STRONG","SUB","SUP","TIME","U","VAR","WBR"]),E=new Set(["SCRIPT","STYLE","NOSCRIPT","TEMPLATE","SVG","CANVAS","VIDEO","AUDIO","IFRAME","OBJECT","EMBED"]);function T(e){let t=e.tagName;if(t==="IMG"||t==="PICTURE"){let c=e.getBoundingClientRect().width,r=e.getBoundingClientRect().height;return Math.min(c,r)/Math.max(c,r)>.85&&c<120?"avatar":"image"}if(t==="INPUT"||t==="TEXTAREA"||t==="SELECT")return"input";if(t==="BUTTON"||e.getAttribute("role")==="button")return"button";if(t==="HR")return"divider";if(/^H[1-6]$/.test(t))return"heading";if(t==="SVG"||t==="svg")return"icon";let n=getComputedStyle(e),o=parseInt(n.borderRadius,10),a=e.getBoundingClientRect();if(o>=a.width/2&&a.width<120&&a.width>16)return"avatar";if(e.childNodes.length>0){let c=Array.from(e.childNodes).some(r=>r.nodeType===Node.TEXT_NODE&&r.textContent?.trim());if(c&&B.has(t)||c&&t==="P")return"text"}return"block"}function A(e,t){if(t==="avatar")return 9999;if(t==="button"){let a=getComputedStyle(e);return Math.min(parseInt(a.borderRadius,10)||6,9999)}let n=getComputedStyle(e),o=parseInt(n.borderRadius,10);return isNaN(o)?0:Math.min(o,9999)}function N(e){let t=getComputedStyle(e);if(t.display==="none"||t.visibility==="hidden"||parseFloat(t.opacity)===0)return!1;let n=e.getBoundingClientRect();return n.width>0&&n.height>0}function R(e,t){let n=e.tagName;return!!(n==="IMG"||n==="PICTURE"||n==="INPUT"||n==="TEXTAREA"||n==="SELECT"||n==="BUTTON"||n==="HR"||n==="SVG"||n==="svg"||t&&Array.from(e.childNodes).every(a=>a.nodeType===Node.TEXT_NODE||B.has(a.tagName))&&e.textContent?.trim()||e.children.length===0)}function X(e,t={}){let n=t.contentAware??p.contentAware,o=t.minBoneSize??p.minBoneSize,a=e.getBoundingClientRect(),c=[];function r(i){if(!E.has(i.tagName)&&N(i)){if(R(i,n)){let l=i.getBoundingClientRect();if(l.width<o||l.height<o)return;let s=n?T(i):"block",u=A(i,s);c.push({x:Math.round((l.left-a.left)*2)/2,y:Math.round((l.top-a.top)*2)/2,w:Math.round(l.width*2)/2,h:Math.round(l.height*2)/2,r:u,kind:s});return}for(let l of i.children)r(l)}}return r(e),{viewport:window.innerWidth,containerWidth:Math.round(a.width*2)/2,containerHeight:Math.round(a.height*2)/2,bones:c}}function I(e,t={}){return`
3
+ (function() {
4
+ ${N.toString()}
5
+ ${R.toString()}
6
+ ${T.toString()}
7
+ ${A.toString()}
8
+
9
+ var INLINE_TAGS = new Set(${JSON.stringify([...B])});
10
+ var SKIP_TAGS = new Set(${JSON.stringify([...E])});
11
+ var DEFAULTS = { contentAware: true, minBoneSize: 4 };
12
+
13
+ ${X.toString()}
14
+
15
+ var container = document.querySelector(${JSON.stringify(e)});
16
+ if (!container) throw new Error('CastDOM: Container not found: ' + ${JSON.stringify(e)});
17
+ return extractBones(container, ${JSON.stringify(t)});
18
+ })()
19
+ `.trim()}async function q(){try{return await import("playwright")}catch{throw new Error(`CastDOM: Playwright is required for extraction. Install it with:
20
+ npm install -D playwright
21
+ npx playwright install chromium`)}}function Y(e){let t=JSON.stringify(e),n=0;for(let o=0;o<t.length;o++){let a=t.charCodeAt(o);n=(n<<5)-n+a|0}return Math.abs(n).toString(36).padStart(8,"0")}async function j(e){let t=await q(),n=e.breakpoints??p.breakpoints,o=e.headless??!0,a=e.timeout??3e4,c=e.targets.length*n.length,r=0,i=await t.chromium.launch({headless:o}),l=[];try{for(let s of e.targets){let u=s.route?`${e.baseURL}${s.route}`:e.baseURL,d=[];for(let h of n){r++,e.onProgress?.(`Extracting "${s.name}" at ${h}px`,r,c);let m=await i.newPage();try{await m.setViewportSize({width:h,height:900}),await m.goto(u,{waitUntil:"networkidle",timeout:a}),e.waitFor&&await m.waitForSelector(e.waitFor,{timeout:a}),await m.waitForSelector(s.selector,{timeout:a});let g=I(s.selector,{contentAware:e.contentAware??p.contentAware,minBoneSize:e.minBoneSize??p.minBoneSize}),x=await m.evaluate(g);d.push(x)}finally{await m.close()}}let b={name:s.name,hash:Y(d),breakpoints:d,extractedAt:Date.now()};l.push({target:s,skeleton:b})}}finally{await i.close()}return l}function F(e){let t=[...e.bones].sort((c,r)=>c.y-r.y||c.x-r.x),n=[],o=0,a=0;for(let c of t){let r=Math.round(c.x*2),i=Math.round(c.y*2),l=Math.round(c.w*2),s=Math.round(c.h*2),u=Math.round(c.r*2),d=v[c.kind??"block"];n.push(r-o,i-a,l,s,u,d),o=r,a=i}return{v:1,vw:e.viewport,c:[Math.round(e.containerWidth*2),Math.round(e.containerHeight*2)],d:n}}function L(e){let n=[...[e.v,e.vw,e.c[0],e.c[1]],e.d.length,...e.d],o=[];for(let a of n){let r=a>=0?a*2:-a*2-1;for(;r>=128;)o.push(r&127|128),r>>>=7;o.push(r&127)}return typeof Buffer<"u"?Buffer.from(new Uint8Array(o)).toString("base64"):btoa(String.fromCharCode(...o))}function z(e){return{color:e?.color??p.color,shimmerColor:e?.shimmerColor??p.shimmerColor,animationDuration:e?.animationDuration??p.animationDuration,classPrefix:e?.classPrefix??p.classPrefix,inlineStyles:e?.inlineStyles??p.inlineStyles}}function Q(e,t){let n=z(t),{classPrefix:o,color:a,shimmerColor:c,animationDuration:r}=n,i=[...e.breakpoints].sort((u,d)=>u.viewport-d.viewport),l=e.name,s=[];if(s.push(`.${o}-${l} .${o}-bone{position:absolute;background:linear-gradient(90deg,${a} 25%,${c} 50%,${a} 75%);background-size:200% 100%;animation:${o}-shimmer ${r}ms ease-in-out infinite}`),i.length>1)for(let u=0;u<i.length;u++){let d=i[u],b=i[u+1],h=i[u-1],m;if(u===0)m=`@media(max-width:${Math.floor((d.viewport+b.viewport)/2)-1}px)`;else if(u===i.length-1)m=`@media(min-width:${Math.floor((h.viewport+d.viewport)/2)}px)`;else{let g=Math.floor((h.viewport+d.viewport)/2),x=Math.floor((d.viewport+b.viewport)/2)-1;m=`@media(min-width:${g}px) and (max-width:${x}px)`}s.push(`${m}{.${o}-${l} .${o}-bp-${d.viewport}{display:block}}`)}else i.length===1&&s.push(`.${o}-${l} .${o}-bp-${i[0].viewport}{display:block}`);return s.join(`
22
+ `)}function k(e,t){let n=z(t),o=[];o.push(`@keyframes ${n.classPrefix}-shimmer{0%{background-position:-200% 0}100%{background-position:200% 0}}`),o.push(`@media(prefers-reduced-motion:reduce){.${n.classPrefix}-bone{animation:none!important}}`);for(let a of e)o.push(Q(a,t));return o.join(`
23
+ `)}function Z(e,t){return{...e,breakpoints:e.breakpoints.map(o=>{let a=[...o.bones],c=new Array(a.length).fill(!0);for(let r=0;r<a.length;r++)if(c[r])for(let i=r+1;i<a.length;i++){if(!c[i])continue;let l=a[r],s=a[i];s.x>=l.x-t&&s.y>=l.y-t&&s.x+s.w<=l.x+l.w+t&&s.y+s.h<=l.y+l.h+t&&(l.w*l.h>s.w*s.h*4||(c[i]=!1)),l.x>=s.x-t&&l.y>=s.y-t&&l.x+l.w<=s.x+s.w+t&&l.y+l.h<=s.y+s.h+t&&(s.w*s.h>l.w*l.h*4||(c[r]=!1))}return{...o,bones:a.filter((r,i)=>c[i])}})}}function ee(e){return{...e,breakpoints:e.breakpoints.map(t=>({...t,bones:t.bones.filter(n=>isFinite(n.x)&&isFinite(n.y)&&n.w>0&&n.h>0&&isFinite(n.r))}))}}function U(e,t={}){let n=t.dedupe??!0,o=t.overlapThreshold??2,a=t.compress??!0,c=t.generateTypes??!0,r=t.base64??!1,i=e.map(f=>f.skeleton);i=i.map(ee),n&&(i=i.map(f=>Z(f,o)));let s=JSON.stringify(i).length,u=s,d={};if(a||r)for(let f of i){let w=[],y=0;for(let $ of f.breakpoints){let M=F($);y+=JSON.stringify(M).length,r&&w.push(L(M))}u=y,r&&(d[f.name]=w)}let b=k(i),h;c&&(h=te(i));let m=i.reduce((f,w)=>f+w.breakpoints.reduce((y,$)=>y+$.bones.length,0),0),g=[...new Set(i.flatMap(f=>f.breakpoints.map(w=>w.viewport)))].sort((f,w)=>f-w),x={skeletonCount:i.length,totalBones:m,rawSize:s,compressedSize:u,compressionRatio:s>0?1-u/s:0,breakpoints:g};return{manifest:{version:1,generatedAt:Date.now(),skeletons:i},css:b,types:h,encoded:r?d:void 0,stats:x}}function te(e){return`// Auto-generated by CastDOM \u2014 do not edit
24
+ // Regenerate with: npx castdom build
25
+
26
+ export type CastDOMSkeletonName =
27
+ ${e.map(n=>` | "${n.name}"`).join(`
28
+ `)};
29
+
30
+ declare module "castdom" {
31
+ interface CastDOMRegistry {
32
+ ${e.map(n=>` "${n.name}": true;`).join(`
33
+ `)}
34
+ }
35
+ }
36
+ `}function J(e,t={}){let n=t.outDir??".castdom",o=t.splitFiles??!0,a=t.esm??!0,c=t.cjs??!1,r=[],i={version:1,generatedAt:Date.now(),skeletons:e};r.push({path:`${n}/manifest.json`,content:JSON.stringify(i,null,2)});let l=k(e,t.config);if(r.push({path:`${n}/castdom.css`,content:l}),a&&r.push({path:`${n}/index.js`,content:ne(e)}),c&&r.push({path:`${n}/index.cjs`,content:oe(e)}),r.push({path:`${n}/index.d.ts`,content:re(e)}),o)for(let s of e)r.push({path:`${n}/skeletons/${s.name}.json`,content:JSON.stringify(s,null,2)}),a&&r.push({path:`${n}/skeletons/${s.name}.js`,content:`export default ${JSON.stringify(s)};
37
+ `});return r.push({path:`${n}/loader.js`,content:ie(e)}),r.push({path:`${n}/nextjs-loading.tsx`,content:se(e)}),r}function ne(e){let t=e.map(o=>`import ${K(o.name)} from "./skeletons/${o.name}.json" with { type: "json" };`).join(`
38
+ `),n=e.map(o=>` "${o.name}": ${K(o.name)},`).join(`
39
+ `);return`// Auto-generated by CastDOM \u2014 do not edit
40
+ ${t}
41
+
42
+ export const skeletons = {
43
+ ${n}
44
+ };
45
+
46
+ export const manifest = {
47
+ version: 1,
48
+ skeletons: Object.values(skeletons),
49
+ };
50
+
51
+ export default manifest;
52
+ `}function oe(e){return`// Auto-generated by CastDOM \u2014 do not edit
53
+ "use strict";
54
+
55
+ const manifest = ${JSON.stringify({version:1,skeletons:e},null,2)};
56
+
57
+ module.exports = manifest;
58
+ module.exports.default = manifest;
59
+ module.exports.skeletons = manifest.skeletons.reduce((acc, s) => {
60
+ acc[s.name] = s;
61
+ return acc;
62
+ }, {});
63
+ `}function re(e){return`// Auto-generated by CastDOM \u2014 do not edit
64
+ import type { SkeletonData } from "castdom";
65
+
66
+ export type SkeletonName =
67
+ ${e.map(n=>` | "${n.name}"`).join(`
68
+ `)};
69
+
70
+ export declare const skeletons: Record<SkeletonName, SkeletonData>;
71
+
72
+ export declare const manifest: {
73
+ version: number;
74
+ skeletons: SkeletonData[];
75
+ };
76
+
77
+ export default manifest;
78
+ `}function ie(e){return`// Auto-generated by CastDOM \u2014 do not edit
79
+ // Import this file once at your app's entry point to register all skeletons.
80
+ //
81
+ // import ".castdom/loader.js";
82
+
83
+ import { loadManifest } from "castdom";
84
+ import manifest from "./manifest.json" with { type: "json" };
85
+
86
+ loadManifest(manifest);
87
+ `}function se(e){return e.length===0?`export default function Loading() { return null; }
88
+ `:`// Auto-generated by CastDOM \u2014 do not edit
89
+ // Copy this to your app/loading.tsx or page-specific loading.tsx
90
+ //
91
+ // For multiple skeletons, use <CastDOM name="..."> directly.
92
+
93
+ import { CastDOM, CastDOMStyle } from "castdom/react";
94
+
95
+ export default function Loading() {
96
+ return (
97
+ <>
98
+ <CastDOMStyle />
99
+ <CastDOM name="${e[0].name}" loading={true}>
100
+ {null}
101
+ </CastDOM>
102
+ </>
103
+ );
104
+ }
105
+ `}function K(e){return e.replace(/[^a-zA-Z0-9_$]/g,"_")}var O=`
106
+ CastDOM \u2014 Pixel-perfect skeleton screens from your real DOM
107
+
108
+ Usage:
109
+ castdom build [options] Extract skeletons and generate files
110
+ castdom init Create a castdom.config.json template
111
+ castdom list List skeletons in the manifest
112
+ castdom clean Remove generated output directory
113
+ castdom --help Show this help message
114
+ castdom --version Show version
115
+
116
+ Build options:
117
+ --url <url> Dev server URL (default: http://localhost:3000)
118
+ --config <path> Config file path (default: castdom.config.json)
119
+ --out <dir> Output directory (default: .castdom)
120
+ --breakpoints Comma-separated breakpoints (default: 375,768,1280)
121
+ --headless Run browser in headless mode (default: true)
122
+ --no-headless Run browser with visible UI (for debugging)
123
+ --verbose Show detailed progress output
124
+ `.trim(),G="1.0.0";function le(e){let t={command:e[0]??"build",url:"http://localhost:3000",configPath:"castdom.config.json",outDir:p.outDir,breakpoints:[...p.breakpoints],headless:!0,verbose:!1};for(let n=1;n<e.length;n++)switch(e[n]){case"--url":t.url=e[++n]??t.url;break;case"--config":t.configPath=e[++n]??t.configPath;break;case"--out":t.outDir=e[++n]??t.outDir;break;case"--breakpoints":t.breakpoints=(e[++n]??"").split(",").map(Number).filter(a=>a>0);break;case"--headless":t.headless=!0;break;case"--no-headless":t.headless=!1;break;case"--verbose":t.verbose=!0;break;case"--help":case"-h":console.log(O),process.exit(0);case"--version":case"-v":console.log(G),process.exit(0)}return t}function P(e){let t=S(e);if(!C(t))return{};try{let n=_(t,"utf-8");return JSON.parse(n)}catch{return console.error(`Failed to parse config: ${t}`),{}}}function D(e,...t){e&&console.log(...t)}async function ue(e){let t=P(e.configPath),n=S(t.outDir??e.outDir),o=t.breakpoints??e.breakpoints,a=t.devServer??e.url,c=t.targets??[];c.length===0&&(console.log("No targets configured. Scanning for [data-castdom] elements..."),c.push({name:"auto",selector:"[data-castdom]"})),console.log(`
125
+ CastDOM Build`),console.log(` Server: ${a}`),console.log(` Breakpoints: ${o.join(", ")}px`),console.log(` Targets: ${c.length}`),console.log(` Output: ${n}
126
+ `);let r=Date.now(),i=await j({baseURL:a,targets:c,breakpoints:o,headless:e.headless,contentAware:t.contentAware??!0,minBoneSize:t.minBoneSize??p.minBoneSize,onProgress(m,g,x){D(e.verbose,` [${g}/${x}] ${m}`)}}),l=Date.now()-r;D(e.verbose,`
127
+ Extraction: ${l}ms`);let s=Date.now(),u=U(i),d=Date.now()-s;D(e.verbose,` Compilation: ${d}ms`);let b=J(u.manifest.skeletons,{outDir:n,config:t});for(let m of b){let g=m.path.substring(0,m.path.lastIndexOf("/"));ce(g,{recursive:!0}),H(m.path,m.content,"utf-8"),D(e.verbose,` Written: ${m.path}`)}let h=Date.now()-r;console.log(` Skeletons: ${u.stats.skeletonCount}`),console.log(` Bones: ${u.stats.totalBones}`),console.log(` Raw size: ${(u.stats.rawSize/1024).toFixed(1)} KB`),console.log(` Compressed: ${(u.stats.compressedSize/1024).toFixed(1)} KB (${(u.stats.compressionRatio*100).toFixed(0)}% smaller)`),console.log(` Files: ${b.length}`),console.log(` Total time: ${h}ms`),console.log(`
128
+ Done. Import the loader to register:
129
+ `),console.log(` import "${n}/loader.js";
130
+ `)}function me(e){let t=S(e.configPath);if(C(t)){console.log(`Config already exists: ${t}`);return}H(t,JSON.stringify({devServer:"http://localhost:3000",outDir:".castdom",breakpoints:[375,768,1280],color:"#e0e0e0",shimmerColor:"#f0f0f0",animationDuration:1500,contentAware:!0,minBoneSize:4,targets:[{name:"example-card",selector:'[data-castdom="example-card"]',route:"/"}]},null,2)+`
131
+ `,"utf-8"),console.log(`Created: ${t}`),console.log(`
132
+ Edit the "targets" array to define your skeleton targets.`),console.log(`Then run: npx castdom build
133
+ `)}function de(e){let t=P(e.configPath),n=S(t.outDir??e.outDir),o=ae(n,"manifest.json");if(!C(o)){console.log('No manifest found. Run "npx castdom build" first.');return}let c=JSON.parse(_(o,"utf-8")).skeletons??[];console.log(`
134
+ CastDOM Skeletons (${c.length}):
135
+ `);for(let r of c){let i=r.breakpoints.reduce((s,u)=>s+u.bones.length,0),l=r.breakpoints.map(s=>`${s.viewport}px`).join(", ");console.log(` ${r.name}`),console.log(` Bones: ${i} | Breakpoints: ${l} | Hash: ${r.hash}`)}console.log()}function pe(e){let t=P(e.configPath),n=S(t.outDir??e.outDir);if(!C(n)){console.log("Nothing to clean.");return}let{rmSync:o}=V("fs");o(n,{recursive:!0,force:!0}),console.log(`Removed: ${n}`)}async function fe(){let e=process.argv.slice(2);if(e.length===0||e[0]==="--help"||e[0]==="-h"){console.log(O);return}if(e[0]==="--version"||e[0]==="-v"){console.log(G);return}let t=le(e);switch(t.command){case"build":await ue(t);break;case"init":me(t);break;case"list":de(t);break;case"clean":pe(t);break;default:console.error(`Unknown command: ${t.command}`),console.log(O),process.exit(1)}}fe().catch(e=>{console.error("CastDOM error:",e.message??e),process.exit(1)});
package/dist/index.cjs ADDED
@@ -0,0 +1,540 @@
1
+ 'use strict';
2
+
3
+ var chunkORY4OMZ5_cjs = require('./chunk-ORY4OMZ5.cjs');
4
+ var chunkYDT4TPB7_cjs = require('./chunk-YDT4TPB7.cjs');
5
+ var chunkXS5HAU5E_cjs = require('./chunk-XS5HAU5E.cjs');
6
+ var chunkJRQ6EVQP_cjs = require('./chunk-JRQ6EVQP.cjs');
7
+
8
+ // src/core/compress.ts
9
+ function compressBones(bp) {
10
+ const sorted = [...bp.bones].sort((a, b) => a.y - b.y || a.x - b.x);
11
+ const data = [];
12
+ let prevX = 0;
13
+ let prevY = 0;
14
+ for (const bone of sorted) {
15
+ const x = Math.round(bone.x * 2);
16
+ const y = Math.round(bone.y * 2);
17
+ const w = Math.round(bone.w * 2);
18
+ const h = Math.round(bone.h * 2);
19
+ const r = Math.round(bone.r * 2);
20
+ const kind = chunkJRQ6EVQP_cjs.BONE_KIND_INDEX[bone.kind ?? "block"];
21
+ data.push(x - prevX, y - prevY, w, h, r, kind);
22
+ prevX = x;
23
+ prevY = y;
24
+ }
25
+ return {
26
+ v: 1,
27
+ vw: bp.viewport,
28
+ c: [
29
+ Math.round(bp.containerWidth * 2),
30
+ Math.round(bp.containerHeight * 2)
31
+ ],
32
+ d: data
33
+ };
34
+ }
35
+ function decompressBones(compressed) {
36
+ const bones = [];
37
+ const d = compressed.d;
38
+ let prevX = 0;
39
+ let prevY = 0;
40
+ for (let i = 0; i < d.length; i += 6) {
41
+ const dx = d[i];
42
+ const dy = d[i + 1];
43
+ const w = d[i + 2];
44
+ const h = d[i + 3];
45
+ const r = d[i + 4];
46
+ const kindIdx = d[i + 5];
47
+ prevX += dx;
48
+ prevY += dy;
49
+ bones.push({
50
+ x: prevX / 2,
51
+ y: prevY / 2,
52
+ w: w / 2,
53
+ h: h / 2,
54
+ r: r / 2,
55
+ kind: chunkJRQ6EVQP_cjs.BONE_KIND_FROM_INDEX[kindIdx] ?? "block"
56
+ });
57
+ }
58
+ return {
59
+ viewport: compressed.vw,
60
+ containerWidth: compressed.c[0] / 2,
61
+ containerHeight: compressed.c[1] / 2,
62
+ bones
63
+ };
64
+ }
65
+ function encodeBonesToBase64(compressed) {
66
+ const header = [compressed.v, compressed.vw, compressed.c[0], compressed.c[1]];
67
+ const allNums = [...header, compressed.d.length, ...compressed.d];
68
+ const bytes = [];
69
+ for (const n of allNums) {
70
+ const z = n >= 0 ? n * 2 : -n * 2 - 1;
71
+ let val = z;
72
+ while (val >= 128) {
73
+ bytes.push(val & 127 | 128);
74
+ val >>>= 7;
75
+ }
76
+ bytes.push(val & 127);
77
+ }
78
+ if (typeof Buffer !== "undefined") {
79
+ return Buffer.from(new Uint8Array(bytes)).toString("base64");
80
+ }
81
+ return btoa(String.fromCharCode(...bytes));
82
+ }
83
+ function decodeBonesToBase64(b64) {
84
+ let bytes;
85
+ if (typeof Buffer !== "undefined") {
86
+ bytes = Buffer.from(b64, "base64");
87
+ } else {
88
+ const raw = atob(b64);
89
+ bytes = new Uint8Array(raw.length);
90
+ for (let i = 0; i < raw.length; i++) bytes[i] = raw.charCodeAt(i);
91
+ }
92
+ const nums = [];
93
+ let pos = 0;
94
+ while (pos < bytes.length) {
95
+ let val = 0;
96
+ let shift = 0;
97
+ let b;
98
+ do {
99
+ b = bytes[pos++];
100
+ val |= (b & 127) << shift;
101
+ shift += 7;
102
+ } while (b & 128);
103
+ nums.push(val & 1 ? -(val >>> 1) - 1 : val >>> 1);
104
+ }
105
+ const v = nums[0];
106
+ const vw = nums[1];
107
+ const c = [nums[2], nums[3]];
108
+ const dLen = nums[4];
109
+ const d = nums.slice(5, 5 + dLen);
110
+ return { v, vw, c, d };
111
+ }
112
+
113
+ // src/core/animation.ts
114
+ function generateKeyframes(config) {
115
+ const type = config?.type ?? "shimmer";
116
+ const prefix = config?.classPrefix ?? chunkJRQ6EVQP_cjs.DEFAULTS.classPrefix;
117
+ config?.duration ?? chunkJRQ6EVQP_cjs.DEFAULTS.animationDuration;
118
+ switch (type) {
119
+ case "shimmer":
120
+ return `@keyframes ${prefix}-shimmer{0%{background-position:-200% 0}100%{background-position:200% 0}}`;
121
+ case "pulse":
122
+ return `@keyframes ${prefix}-pulse{0%,100%{opacity:1}50%{opacity:0.4}}`;
123
+ case "wave":
124
+ return `@keyframes ${prefix}-wave{0%{opacity:0.4}50%{opacity:1}100%{opacity:0.4}}`;
125
+ case "none":
126
+ return "";
127
+ }
128
+ }
129
+ function generateBoneAnimation(config) {
130
+ const type = config?.type ?? "shimmer";
131
+ const prefix = config?.classPrefix ?? chunkJRQ6EVQP_cjs.DEFAULTS.classPrefix;
132
+ const duration = config?.duration ?? chunkJRQ6EVQP_cjs.DEFAULTS.animationDuration;
133
+ const color = config?.color ?? chunkJRQ6EVQP_cjs.DEFAULTS.color;
134
+ const shimmerColor = config?.shimmerColor ?? chunkJRQ6EVQP_cjs.DEFAULTS.shimmerColor;
135
+ switch (type) {
136
+ case "shimmer":
137
+ return `background:linear-gradient(90deg,${color} 25%,${shimmerColor} 50%,${color} 75%);background-size:200% 100%;animation:${prefix}-shimmer ${duration}ms ease-in-out infinite`;
138
+ case "pulse":
139
+ return `background:${color};animation:${prefix}-pulse ${duration}ms ease-in-out infinite`;
140
+ case "wave":
141
+ return `background:${color};animation:${prefix}-wave ${duration}ms ease-in-out infinite`;
142
+ case "none":
143
+ return `background:${color}`;
144
+ }
145
+ }
146
+ function generateStaggerCSS(skeletonName, boneCount, config) {
147
+ const prefix = config?.classPrefix ?? chunkJRQ6EVQP_cjs.DEFAULTS.classPrefix;
148
+ const stagger = config?.stagger ?? 50;
149
+ const rules = [];
150
+ for (let i = 0; i < boneCount; i++) {
151
+ rules.push(
152
+ `.${prefix}-${skeletonName} .${prefix}-bone:nth-child(${i + 1}){animation-delay:${i * stagger}ms}`
153
+ );
154
+ }
155
+ return rules.join("");
156
+ }
157
+ function generateAnimationCSS(skeletonName, boneCount, config) {
158
+ const prefix = config?.classPrefix ?? chunkJRQ6EVQP_cjs.DEFAULTS.classPrefix;
159
+ const type = config?.type ?? "shimmer";
160
+ const parts = [];
161
+ const kf = generateKeyframes(config);
162
+ if (kf) parts.push(kf);
163
+ const anim = generateBoneAnimation(config);
164
+ parts.push(`.${prefix}-${skeletonName} .${prefix}-bone{position:absolute;${anim}}`);
165
+ if (type === "wave") {
166
+ parts.push(generateStaggerCSS(skeletonName, boneCount, config));
167
+ }
168
+ parts.push(
169
+ `@media(prefers-reduced-motion:reduce){.${prefix}-${skeletonName} .${prefix}-bone{animation:none!important}}`
170
+ );
171
+ return parts.join("\n");
172
+ }
173
+
174
+ // src/core/extractor.ts
175
+ var INLINE_TAGS = /* @__PURE__ */ new Set([
176
+ "A",
177
+ "ABBR",
178
+ "B",
179
+ "BDO",
180
+ "BR",
181
+ "CITE",
182
+ "CODE",
183
+ "DFN",
184
+ "EM",
185
+ "I",
186
+ "KBD",
187
+ "MARK",
188
+ "Q",
189
+ "S",
190
+ "SAMP",
191
+ "SMALL",
192
+ "SPAN",
193
+ "STRONG",
194
+ "SUB",
195
+ "SUP",
196
+ "TIME",
197
+ "U",
198
+ "VAR",
199
+ "WBR"
200
+ ]);
201
+ var SKIP_TAGS = /* @__PURE__ */ new Set([
202
+ "SCRIPT",
203
+ "STYLE",
204
+ "NOSCRIPT",
205
+ "TEMPLATE",
206
+ "SVG",
207
+ "CANVAS",
208
+ "VIDEO",
209
+ "AUDIO",
210
+ "IFRAME",
211
+ "OBJECT",
212
+ "EMBED"
213
+ ]);
214
+ function detectKind(el) {
215
+ const tag = el.tagName;
216
+ if (tag === "IMG" || tag === "PICTURE") {
217
+ const w = el.getBoundingClientRect().width;
218
+ const h = el.getBoundingClientRect().height;
219
+ const ratio = Math.min(w, h) / Math.max(w, h);
220
+ if (ratio > 0.85 && w < 120) return "avatar";
221
+ return "image";
222
+ }
223
+ if (tag === "INPUT" || tag === "TEXTAREA" || tag === "SELECT") return "input";
224
+ if (tag === "BUTTON" || el.getAttribute("role") === "button") return "button";
225
+ if (tag === "HR") return "divider";
226
+ if (/^H[1-6]$/.test(tag)) return "heading";
227
+ if (tag === "SVG" || tag === "svg") return "icon";
228
+ const style = getComputedStyle(el);
229
+ const borderRadius = parseInt(style.borderRadius, 10);
230
+ const rect = el.getBoundingClientRect();
231
+ if (borderRadius >= rect.width / 2 && rect.width < 120 && rect.width > 16) {
232
+ return "avatar";
233
+ }
234
+ if (el.childNodes.length > 0) {
235
+ const hasDirectText = Array.from(el.childNodes).some(
236
+ (n) => n.nodeType === Node.TEXT_NODE && n.textContent?.trim()
237
+ );
238
+ if (hasDirectText && INLINE_TAGS.has(tag)) return "text";
239
+ if (hasDirectText && tag === "P") return "text";
240
+ }
241
+ return "block";
242
+ }
243
+ function computeRadius(el, kind) {
244
+ if (kind === "avatar") return 9999;
245
+ if (kind === "button") {
246
+ const style2 = getComputedStyle(el);
247
+ return Math.min(parseInt(style2.borderRadius, 10) || 6, 9999);
248
+ }
249
+ const style = getComputedStyle(el);
250
+ const r = parseInt(style.borderRadius, 10);
251
+ return isNaN(r) ? 0 : Math.min(r, 9999);
252
+ }
253
+ function isVisible(el) {
254
+ const style = getComputedStyle(el);
255
+ if (style.display === "none") return false;
256
+ if (style.visibility === "hidden") return false;
257
+ if (parseFloat(style.opacity) === 0) return false;
258
+ const rect = el.getBoundingClientRect();
259
+ return rect.width > 0 && rect.height > 0;
260
+ }
261
+ function isLeaf(el, contentAware) {
262
+ const tag = el.tagName;
263
+ if (tag === "IMG" || tag === "PICTURE" || tag === "INPUT" || tag === "TEXTAREA" || tag === "SELECT" || tag === "BUTTON" || tag === "HR" || tag === "SVG" || tag === "svg") {
264
+ return true;
265
+ }
266
+ if (contentAware) {
267
+ const hasOnlyText = Array.from(el.childNodes).every(
268
+ (n) => n.nodeType === Node.TEXT_NODE || INLINE_TAGS.has(n.tagName)
269
+ );
270
+ if (hasOnlyText && el.textContent?.trim()) return true;
271
+ }
272
+ if (el.children.length === 0) return true;
273
+ return false;
274
+ }
275
+ function extractBones(container, options = {}) {
276
+ const contentAware = options.contentAware ?? chunkJRQ6EVQP_cjs.DEFAULTS.contentAware;
277
+ const minSize = options.minBoneSize ?? chunkJRQ6EVQP_cjs.DEFAULTS.minBoneSize;
278
+ const containerRect = container.getBoundingClientRect();
279
+ const bones = [];
280
+ function walk(el) {
281
+ if (SKIP_TAGS.has(el.tagName)) return;
282
+ if (!isVisible(el)) return;
283
+ if (isLeaf(el, contentAware)) {
284
+ const rect = el.getBoundingClientRect();
285
+ if (rect.width < minSize || rect.height < minSize) return;
286
+ const kind = contentAware ? detectKind(el) : "block";
287
+ const r = computeRadius(el, kind);
288
+ bones.push({
289
+ x: Math.round((rect.left - containerRect.left) * 2) / 2,
290
+ y: Math.round((rect.top - containerRect.top) * 2) / 2,
291
+ w: Math.round(rect.width * 2) / 2,
292
+ h: Math.round(rect.height * 2) / 2,
293
+ r,
294
+ kind
295
+ });
296
+ return;
297
+ }
298
+ for (const child of el.children) {
299
+ walk(child);
300
+ }
301
+ }
302
+ walk(container);
303
+ return {
304
+ viewport: window.innerWidth,
305
+ containerWidth: Math.round(containerRect.width * 2) / 2,
306
+ containerHeight: Math.round(containerRect.height * 2) / 2,
307
+ bones
308
+ };
309
+ }
310
+ function getExtractorScript(selector, options = {}) {
311
+ return `
312
+ (function() {
313
+ ${isVisible.toString()}
314
+ ${isLeaf.toString()}
315
+ ${detectKind.toString()}
316
+ ${computeRadius.toString()}
317
+
318
+ var INLINE_TAGS = new Set(${JSON.stringify([...INLINE_TAGS])});
319
+ var SKIP_TAGS = new Set(${JSON.stringify([...SKIP_TAGS])});
320
+ var DEFAULTS = { contentAware: true, minBoneSize: 4 };
321
+
322
+ ${extractBones.toString()}
323
+
324
+ var container = document.querySelector(${JSON.stringify(selector)});
325
+ if (!container) throw new Error('CastDOM: Container not found: ' + ${JSON.stringify(selector)});
326
+ return extractBones(container, ${JSON.stringify(options)});
327
+ })()
328
+ `.trim();
329
+ }
330
+
331
+ // src/components/vanilla.ts
332
+ var ACTIVE_ATTR = "data-castdom-active";
333
+ var SKELETON_ATTR = "data-castdom-skeleton";
334
+ function createCastDOM(config) {
335
+ let styleEl = null;
336
+ let cssInjected = false;
337
+ const activeContainers = /* @__PURE__ */ new Set();
338
+ function ensureCSS() {
339
+ if (cssInjected || typeof document === "undefined") return;
340
+ styleEl = document.createElement("style");
341
+ styleEl.setAttribute("data-castdom", "critical");
342
+ styleEl.textContent = [
343
+ `@keyframes castdom-shimmer{0%{background-position:-200% 0}100%{background-position:200% 0}}`,
344
+ `@keyframes castdom-pulse{0%,100%{opacity:1}50%{opacity:0.4}}`,
345
+ `@keyframes castdom-wave{0%{opacity:0.4}50%{opacity:1}100%{opacity:0.4}}`,
346
+ `@media(prefers-reduced-motion:reduce){.castdom-bone{animation:none!important}}`
347
+ ].join("");
348
+ document.head.appendChild(styleEl);
349
+ cssInjected = true;
350
+ }
351
+ return {
352
+ loadManifest(manifest) {
353
+ chunkYDT4TPB7_cjs.loadManifest(manifest);
354
+ },
355
+ register(data) {
356
+ chunkYDT4TPB7_cjs.register(data);
357
+ },
358
+ show(name, container) {
359
+ const entry = chunkYDT4TPB7_cjs.get(name);
360
+ if (!entry) {
361
+ console.warn(`CastDOM: Skeleton "${name}" not found in registry`);
362
+ return;
363
+ }
364
+ ensureCSS();
365
+ if (!container.hasAttribute(ACTIVE_ATTR)) {
366
+ container.setAttribute(ACTIVE_ATTR, "true");
367
+ for (const child of Array.from(container.children)) {
368
+ if (!child.hasAttribute(SKELETON_ATTR)) {
369
+ child.style.display = "none";
370
+ }
371
+ }
372
+ }
373
+ const vw = typeof window !== "undefined" ? window.innerWidth : 1280;
374
+ const bp = chunkORY4OMZ5_cjs.selectBreakpoint(entry.data, vw);
375
+ if (!bp) return;
376
+ const skeletonDiv = document.createElement("div");
377
+ skeletonDiv.setAttribute(SKELETON_ATTR, name);
378
+ skeletonDiv.innerHTML = chunkXS5HAU5E_cjs.renderStandalone(entry.data, config);
379
+ container.appendChild(skeletonDiv);
380
+ activeContainers.add(container);
381
+ },
382
+ hide(name, container) {
383
+ const skeleton = container.querySelector(`[${SKELETON_ATTR}="${name}"]`);
384
+ if (skeleton) skeleton.remove();
385
+ container.removeAttribute(ACTIVE_ATTR);
386
+ for (const child of Array.from(container.children)) {
387
+ if (!child.hasAttribute(SKELETON_ATTR)) {
388
+ child.style.display = "";
389
+ }
390
+ }
391
+ activeContainers.delete(container);
392
+ },
393
+ toggle(name, container, loading) {
394
+ if (loading) {
395
+ this.show(name, container);
396
+ } else {
397
+ this.hide(name, container);
398
+ }
399
+ },
400
+ html(name, viewportWidth) {
401
+ const entry = chunkYDT4TPB7_cjs.get(name);
402
+ if (!entry) return "";
403
+ return chunkXS5HAU5E_cjs.renderStandalone(entry.data, config);
404
+ },
405
+ css() {
406
+ return chunkXS5HAU5E_cjs.generateCriticalCSS(
407
+ Array.from(activeContainers).map((c) => {
408
+ const name = c.querySelector(`[${SKELETON_ATTR}]`)?.getAttribute(SKELETON_ATTR);
409
+ return name ? chunkYDT4TPB7_cjs.get(name)?.data : void 0;
410
+ }).filter(Boolean),
411
+ config
412
+ );
413
+ },
414
+ injectCSS() {
415
+ ensureCSS();
416
+ },
417
+ destroy() {
418
+ for (const container of activeContainers) {
419
+ const skeletons = container.querySelectorAll(`[${SKELETON_ATTR}]`);
420
+ for (const s of skeletons) s.remove();
421
+ container.removeAttribute(ACTIVE_ATTR);
422
+ for (const child of Array.from(container.children)) {
423
+ child.style.display = "";
424
+ }
425
+ }
426
+ activeContainers.clear();
427
+ if (styleEl) {
428
+ styleEl.remove();
429
+ styleEl = null;
430
+ cssInjected = false;
431
+ }
432
+ }
433
+ };
434
+ }
435
+
436
+ Object.defineProperty(exports, "diffBreakpoints", {
437
+ enumerable: true,
438
+ get: function () { return chunkORY4OMZ5_cjs.diffBreakpoints; }
439
+ });
440
+ Object.defineProperty(exports, "getStaleBreakpoints", {
441
+ enumerable: true,
442
+ get: function () { return chunkORY4OMZ5_cjs.getStaleBreakpoints; }
443
+ });
444
+ Object.defineProperty(exports, "interpolateBones", {
445
+ enumerable: true,
446
+ get: function () { return chunkORY4OMZ5_cjs.interpolateBones; }
447
+ });
448
+ Object.defineProperty(exports, "selectBreakpoint", {
449
+ enumerable: true,
450
+ get: function () { return chunkORY4OMZ5_cjs.selectBreakpoint; }
451
+ });
452
+ Object.defineProperty(exports, "validateBreakpoints", {
453
+ enumerable: true,
454
+ get: function () { return chunkORY4OMZ5_cjs.validateBreakpoints; }
455
+ });
456
+ Object.defineProperty(exports, "clear", {
457
+ enumerable: true,
458
+ get: function () { return chunkYDT4TPB7_cjs.clear; }
459
+ });
460
+ Object.defineProperty(exports, "configure", {
461
+ enumerable: true,
462
+ get: function () { return chunkYDT4TPB7_cjs.configure; }
463
+ });
464
+ Object.defineProperty(exports, "get", {
465
+ enumerable: true,
466
+ get: function () { return chunkYDT4TPB7_cjs.get; }
467
+ });
468
+ Object.defineProperty(exports, "getAllCSS", {
469
+ enumerable: true,
470
+ get: function () { return chunkYDT4TPB7_cjs.getAllCSS; }
471
+ });
472
+ Object.defineProperty(exports, "has", {
473
+ enumerable: true,
474
+ get: function () { return chunkYDT4TPB7_cjs.has; }
475
+ });
476
+ Object.defineProperty(exports, "loadManifest", {
477
+ enumerable: true,
478
+ get: function () { return chunkYDT4TPB7_cjs.loadManifest; }
479
+ });
480
+ Object.defineProperty(exports, "names", {
481
+ enumerable: true,
482
+ get: function () { return chunkYDT4TPB7_cjs.names; }
483
+ });
484
+ Object.defineProperty(exports, "register", {
485
+ enumerable: true,
486
+ get: function () { return chunkYDT4TPB7_cjs.register; }
487
+ });
488
+ Object.defineProperty(exports, "registerAll", {
489
+ enumerable: true,
490
+ get: function () { return chunkYDT4TPB7_cjs.registerAll; }
491
+ });
492
+ Object.defineProperty(exports, "remove", {
493
+ enumerable: true,
494
+ get: function () { return chunkYDT4TPB7_cjs.remove; }
495
+ });
496
+ Object.defineProperty(exports, "generateCSS", {
497
+ enumerable: true,
498
+ get: function () { return chunkXS5HAU5E_cjs.generateCSS; }
499
+ });
500
+ Object.defineProperty(exports, "generateCriticalCSS", {
501
+ enumerable: true,
502
+ get: function () { return chunkXS5HAU5E_cjs.generateCriticalCSS; }
503
+ });
504
+ Object.defineProperty(exports, "renderBonesHTML", {
505
+ enumerable: true,
506
+ get: function () { return chunkXS5HAU5E_cjs.renderBonesHTML; }
507
+ });
508
+ Object.defineProperty(exports, "renderResponsiveHTML", {
509
+ enumerable: true,
510
+ get: function () { return chunkXS5HAU5E_cjs.renderResponsiveHTML; }
511
+ });
512
+ Object.defineProperty(exports, "renderStandalone", {
513
+ enumerable: true,
514
+ get: function () { return chunkXS5HAU5E_cjs.renderStandalone; }
515
+ });
516
+ Object.defineProperty(exports, "BONE_KIND_FROM_INDEX", {
517
+ enumerable: true,
518
+ get: function () { return chunkJRQ6EVQP_cjs.BONE_KIND_FROM_INDEX; }
519
+ });
520
+ Object.defineProperty(exports, "BONE_KIND_INDEX", {
521
+ enumerable: true,
522
+ get: function () { return chunkJRQ6EVQP_cjs.BONE_KIND_INDEX; }
523
+ });
524
+ Object.defineProperty(exports, "DEFAULTS", {
525
+ enumerable: true,
526
+ get: function () { return chunkJRQ6EVQP_cjs.DEFAULTS; }
527
+ });
528
+ exports.compressBones = compressBones;
529
+ exports.createCastDOM = createCastDOM;
530
+ exports.decodeBonesToBase64 = decodeBonesToBase64;
531
+ exports.decompressBones = decompressBones;
532
+ exports.encodeBonesToBase64 = encodeBonesToBase64;
533
+ exports.extractBones = extractBones;
534
+ exports.generateAnimationCSS = generateAnimationCSS;
535
+ exports.generateBoneAnimation = generateBoneAnimation;
536
+ exports.generateKeyframes = generateKeyframes;
537
+ exports.generateStaggerCSS = generateStaggerCSS;
538
+ exports.getExtractorScript = getExtractorScript;
539
+ //# sourceMappingURL=index.cjs.map
540
+ //# sourceMappingURL=index.cjs.map