@microfox/remotion 1.2.2 → 1.2.3

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/dist/index.mjs CHANGED
@@ -4,21 +4,21 @@ var ComponentRegistryManager = class {
4
4
  this.registry = {};
5
5
  this.packageRegistry = {};
6
6
  }
7
- registerComponent(name, component, type, config15 = { displayName: "" }, packageName) {
8
- this.registry[name] = { component, config: config15 };
7
+ registerComponent(name, component, type, config18 = { displayName: "" }, packageName) {
8
+ this.registry[name] = { component, config: config18 };
9
9
  if (packageName) {
10
10
  if (!this.packageRegistry[packageName]) {
11
11
  this.packageRegistry[packageName] = {};
12
12
  }
13
- this.packageRegistry[packageName][name] = { component, config: config15 };
13
+ this.packageRegistry[packageName][name] = { component, config: config18 };
14
14
  }
15
15
  }
16
- registerEffect(name, component, config15 = { displayName: "" }, packageName) {
16
+ registerEffect(name, component, config18 = { displayName: "" }, packageName) {
17
17
  this.registerComponent(
18
18
  name?.includes("effect-") ? name : `effect-${name}`,
19
19
  component,
20
20
  "layout",
21
- config15,
21
+ config18,
22
22
  packageName
23
23
  );
24
24
  }
@@ -33,8 +33,8 @@ var ComponentRegistryManager = class {
33
33
  }
34
34
  registerPackage(packageName, components) {
35
35
  this.packageRegistry[packageName] = components;
36
- Object.entries(components).forEach(([name, { component, config: config15 }]) => {
37
- this.registry[`${packageName}:${name}`] = { component, config: config15 };
36
+ Object.entries(components).forEach(([name, { component, config: config18 }]) => {
37
+ this.registry[`${packageName}:${name}`] = { component, config: config18 };
38
38
  });
39
39
  }
40
40
  getPackageComponents(packageName) {
@@ -49,17 +49,17 @@ var ComponentRegistryManager = class {
49
49
  }
50
50
  };
51
51
  var componentRegistry = new ComponentRegistryManager();
52
- var registerComponent = (name, component, type, config15 = { displayName: "" }, packageName) => {
52
+ var registerComponent = (name, component, type, config18 = { displayName: "" }, packageName) => {
53
53
  componentRegistry.registerComponent(
54
54
  name,
55
55
  component,
56
56
  type,
57
- config15,
57
+ config18,
58
58
  packageName
59
59
  );
60
60
  };
61
- var registerEffect = (name, component, config15 = { displayName: "" }, packageName) => {
62
- componentRegistry.registerEffect(name, component, config15, packageName);
61
+ var registerEffect = (name, component, config18 = { displayName: "" }, packageName) => {
62
+ componentRegistry.registerEffect(name, component, config18, packageName);
63
63
  };
64
64
  var registerPackage = (packageName, components) => {
65
65
  componentRegistry.registerPackage(packageName, components);
@@ -142,9 +142,9 @@ var calculateComponentDuration = async (component) => {
142
142
  } else {
143
143
  }
144
144
  };
145
- var calculateDuration = async (childrenData, config15) => {
145
+ var calculateDuration = async (childrenData, config18) => {
146
146
  let calculatedDuration = void 0;
147
- const targetIds = Array.isArray(config15.fitDurationTo) ? config15.fitDurationTo : [config15.fitDurationTo];
147
+ const targetIds = Array.isArray(config18.fitDurationTo) ? config18.fitDurationTo : [config18.fitDurationTo];
148
148
  const matchingComponents = findMatchingComponents(
149
149
  childrenData || [],
150
150
  targetIds
@@ -498,8 +498,8 @@ var ComponentRenderer = ({
498
498
  context
499
499
  };
500
500
  if (type === "layout") {
501
- const config15 = getComponentConfig(componentId);
502
- const isInnerSequence = config15?.isInnerSequence;
501
+ const config18 = getComponentConfig(componentId);
502
+ const isInnerSequence = config18?.isInnerSequence;
503
503
  if (isInnerSequence) {
504
504
  return /* @__PURE__ */ React3.createElement(RenderContext.Provider, { value: newContext }, /* @__PURE__ */ React3.createElement(ComponentClass, { ...props }, effects && effects.length > 0 ? /* @__PURE__ */ React3.createElement(EffectWrapper, { effects, context: newContext }, childrenData?.map((child) => /* @__PURE__ */ React3.createElement(ComponentRenderer, { key: child.id, ...child }))) : childrenData?.map((child) => /* @__PURE__ */ React3.createElement(ComponentRenderer, { key: child.id, ...child }))));
505
505
  }
@@ -542,7 +542,7 @@ var SceneFrame = ({ children }) => {
542
542
  };
543
543
 
544
544
  // src/components/layouts/BaseLayout.tsx
545
- import React13, { Children, useMemo as useMemo7 } from "react";
545
+ import React19, { Children, useMemo as useMemo9 } from "react";
546
546
  import { AbsoluteFill as AbsoluteFill3 } from "remotion";
547
547
 
548
548
  // src/components/effects/BlurEffect.tsx
@@ -557,10 +557,45 @@ var parseFunctionsString = (functions) => {
557
557
  if (!functions) {
558
558
  return result;
559
559
  }
560
- const regex = /(\w+)\(([^)]*)\)/g;
561
- let match;
562
- while ((match = regex.exec(functions)) !== null) {
563
- result.set(match[1], match[0]);
560
+ let i = 0;
561
+ while (i < functions.length) {
562
+ while (i < functions.length && /\s/.test(functions[i])) {
563
+ i++;
564
+ }
565
+ if (i >= functions.length) break;
566
+ const nameStart = i;
567
+ while (i < functions.length && /[\w-]/.test(functions[i])) {
568
+ i++;
569
+ }
570
+ if (i === nameStart) break;
571
+ const functionName = functions.substring(nameStart, i);
572
+ while (i < functions.length && /\s/.test(functions[i])) {
573
+ i++;
574
+ }
575
+ if (i >= functions.length || functions[i] !== "(") {
576
+ break;
577
+ }
578
+ i++;
579
+ let depth = 1;
580
+ const contentStart = i;
581
+ while (i < functions.length && depth > 0) {
582
+ if (functions[i] === "(") {
583
+ depth++;
584
+ } else if (functions[i] === ")") {
585
+ depth--;
586
+ }
587
+ if (depth > 0) {
588
+ i++;
589
+ }
590
+ }
591
+ if (depth === 0) {
592
+ const content = functions.substring(contentStart, i);
593
+ const fullFunction = `${functionName}(${content})`;
594
+ result.set(functionName, fullFunction);
595
+ i++;
596
+ } else {
597
+ break;
598
+ }
564
599
  }
565
600
  return result;
566
601
  };
@@ -724,11 +759,20 @@ var parseHexColor = (hex) => {
724
759
  var parseRgbaColor = (rgba) => {
725
760
  const match = rgba.match(/rgba?\(\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*(?:,\s*([\d.]+))?\s*\)/);
726
761
  if (match) {
762
+ let alpha = 1;
763
+ if (match[4]) {
764
+ const alphaValue = parseFloat(match[4]);
765
+ if (alphaValue > 1) {
766
+ alpha = Math.max(0, Math.min(1, alphaValue / 100));
767
+ } else {
768
+ alpha = Math.max(0, Math.min(1, alphaValue));
769
+ }
770
+ }
727
771
  return {
728
772
  r: Math.max(0, Math.min(255, parseInt(match[1], 10))),
729
773
  g: Math.max(0, Math.min(255, parseInt(match[2], 10))),
730
774
  b: Math.max(0, Math.min(255, parseInt(match[3], 10))),
731
- a: match[4] ? Math.max(0, Math.min(1, parseFloat(match[4]))) : 1
775
+ a: alpha
732
776
  };
733
777
  }
734
778
  return { r: 0, g: 0, b: 0, a: 1 };
@@ -742,14 +786,21 @@ var parseColor = (color) => {
742
786
  }
743
787
  return { r: 0, g: 0, b: 0, a: 1 };
744
788
  };
745
- var rgbaToString = (color) => {
746
- if (color.a === 1) {
747
- return `rgb(${Math.round(color.r)}, ${Math.round(color.g)}, ${Math.round(color.b)})`;
748
- } else {
749
- return `rgba(${Math.round(color.r)}, ${Math.round(color.g)}, ${Math.round(color.b)}, ${color.a})`;
789
+ var rgbaToString = (color, preserveFormat) => {
790
+ const r = Math.round(color.r);
791
+ const g = Math.round(color.g);
792
+ const b = Math.round(color.b);
793
+ const a = color.a;
794
+ if (preserveFormat) {
795
+ if (preserveFormat.hasSpaces) {
796
+ return `rgba(${r}, ${g}, ${b}, ${a})`;
797
+ } else {
798
+ return `rgba(${r},${g},${b},${a})`;
799
+ }
750
800
  }
801
+ return `rgba(${r}, ${g}, ${b}, ${a})`;
751
802
  };
752
- var interpolateColors = (color1, color2, progress) => {
803
+ var interpolateColors = (color1, color2, progress, preserveFormat) => {
753
804
  const parsedColor1 = parseColor(color1);
754
805
  const parsedColor2 = parseColor(color2);
755
806
  const interpolatedColor = {
@@ -758,7 +809,75 @@ var interpolateColors = (color1, color2, progress) => {
758
809
  b: interpolate(progress, [0, 1], [parsedColor1.b, parsedColor2.b]),
759
810
  a: interpolate(progress, [0, 1], [parsedColor1.a, parsedColor2.a])
760
811
  };
761
- return rgbaToString(interpolatedColor);
812
+ return rgbaToString(interpolatedColor, preserveFormat);
813
+ };
814
+ var findColorsInString = (str) => {
815
+ const matches = [];
816
+ const rgbaPattern = /rgba?\(\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*(?:,\s*([\d.]+))?\s*\)/g;
817
+ let match;
818
+ rgbaPattern.lastIndex = 0;
819
+ while ((match = rgbaPattern.exec(str)) !== null) {
820
+ matches.push({
821
+ fullMatch: match[0],
822
+ color: match[0],
823
+ startIndex: match.index,
824
+ endIndex: match.index + match[0].length
825
+ });
826
+ }
827
+ const hexPattern = /#([0-9a-fA-F]{3}|[0-9a-fA-F]{6}|[0-9a-fA-F]{8})\b/g;
828
+ hexPattern.lastIndex = 0;
829
+ while ((match = hexPattern.exec(str)) !== null) {
830
+ matches.push({
831
+ fullMatch: match[0],
832
+ color: match[0],
833
+ startIndex: match.index,
834
+ endIndex: match.index + match[0].length
835
+ });
836
+ }
837
+ return matches.sort((a, b) => a.startIndex - b.startIndex);
838
+ };
839
+ var interpolateColorsInString = (str1, str2, progress) => {
840
+ const colors1 = findColorsInString(str1);
841
+ const colors2 = findColorsInString(str2);
842
+ if (colors1.length === 0 && colors2.length === 0) {
843
+ return str1;
844
+ }
845
+ if (colors1.length === 0 || colors2.length === 0) {
846
+ return str1;
847
+ }
848
+ const minLength = Math.min(colors1.length, colors2.length);
849
+ const replacements = [];
850
+ for (let i = 0; i < minLength; i++) {
851
+ const color1 = colors1[i];
852
+ const color2 = colors2[i];
853
+ const originalColor = color1.color;
854
+ const hasSpaces = originalColor.includes(", ");
855
+ const interpolatedColor = interpolateColors(color1.color, color2.color, progress, { hasSpaces });
856
+ replacements.push({
857
+ startIndex: color1.startIndex,
858
+ endIndex: color1.endIndex,
859
+ replacement: interpolatedColor
860
+ });
861
+ }
862
+ replacements.sort((a, b) => b.startIndex - a.startIndex);
863
+ let result = str1;
864
+ for (const replacement of replacements) {
865
+ const originalSubstring = result.substring(replacement.startIndex, replacement.endIndex);
866
+ const expectedColor = colors1.find((c) => c.startIndex === replacement.startIndex);
867
+ if (expectedColor && (originalSubstring === expectedColor.color || originalSubstring.trim().match(/^rgba?\(/i))) {
868
+ result = result.substring(0, replacement.startIndex) + replacement.replacement + result.substring(replacement.endIndex);
869
+ } else {
870
+ const currentColors = findColorsInString(result);
871
+ const matchingColor = currentColors.find(
872
+ (c) => Math.abs(c.startIndex - replacement.startIndex) < 30
873
+ // Allow some offset
874
+ );
875
+ if (matchingColor) {
876
+ result = result.substring(0, matchingColor.startIndex) + replacement.replacement + result.substring(matchingColor.endIndex);
877
+ }
878
+ }
879
+ }
880
+ return result;
762
881
  };
763
882
  var calculateAnimatedValue = (ranges, progress, key) => {
764
883
  const sortedRanges = [...ranges].sort((a, b) => a.prog - b.prog);
@@ -794,6 +913,11 @@ var calculateAnimatedValue = (ranges, progress, key) => {
794
913
  if (isColor(currentValue) && isColor(nextValue)) {
795
914
  return interpolateColors(currentValue, nextValue, localProgress);
796
915
  }
916
+ const colors1 = findColorsInString(currentValue);
917
+ const colors2 = findColorsInString(nextValue);
918
+ if (colors1.length > 0 || colors2.length > 0) {
919
+ return interpolateColorsInString(currentValue, nextValue, localProgress);
920
+ }
797
921
  const getUnitAndValue = (str) => {
798
922
  const units = ["vmax", "vmin", "rem", "deg", "bpm", "vh", "vw", "px", "em", "ms", "hz", "db", "fr", "s", "%"];
799
923
  for (const unit of units) {
@@ -842,7 +966,7 @@ var rangesToCSSProperties = (ranges, progress) => {
842
966
  const value = calculateAnimatedValue(keyRanges, progress, key);
843
967
  switch (key) {
844
968
  case "scale":
845
- styles.transform = `scale(${value})`;
969
+ styles.transform = `${styles.transform || ""} scale(${value})`.trim();
846
970
  break;
847
971
  case "rotate":
848
972
  const rotateValue = typeof value === "string" && value.includes("deg") ? value : `${value}deg`;
@@ -1748,229 +1872,1750 @@ var config7 = {
1748
1872
  }
1749
1873
  };
1750
1874
 
1751
- // src/components/effects/GenericPresets.ts
1752
- var fadeInPreset = [
1753
- { key: "opacity", val: 0, prog: 0 },
1754
- { key: "opacity", val: 1, prog: 1 }
1755
- ];
1756
- var fadeOutPreset = [
1757
- { key: "opacity", val: 1, prog: 0 },
1758
- { key: "opacity", val: 0, prog: 1 }
1759
- ];
1760
- var scaleInPreset = [
1761
- { key: "scale", val: 0, prog: 0 },
1762
- { key: "scale", val: 1, prog: 1 }
1763
- ];
1764
- var scaleOutPreset = [
1765
- { key: "scale", val: 1, prog: 0 },
1766
- { key: "scale", val: 0, prog: 1 }
1767
- ];
1768
- var slideInLeftPreset = [
1769
- { key: "translateX", val: -100, prog: 0 },
1770
- { key: "translateX", val: 0, prog: 1 }
1771
- ];
1772
- var slideInRightPreset = [
1773
- { key: "translateX", val: 100, prog: 0 },
1774
- { key: "translateX", val: 0, prog: 1 }
1775
- ];
1776
- var slideInTopPreset = [
1777
- { key: "translateY", val: -100, prog: 0 },
1778
- { key: "translateY", val: 0, prog: 1 }
1779
- ];
1780
- var slideInBottomPreset = [
1781
- { key: "translateY", val: 100, prog: 0 },
1782
- { key: "translateY", val: 0, prog: 1 }
1783
- ];
1784
- var bouncePreset = [
1785
- { key: "scale", val: 0, prog: 0 },
1786
- { key: "scale", val: 1.2, prog: 0.6 },
1787
- { key: "scale", val: 1, prog: 1 }
1788
- ];
1789
- var pulsePreset = [
1790
- { key: "scale", val: 1, prog: 0 },
1791
- { key: "scale", val: 1.1, prog: 0.5 },
1792
- { key: "scale", val: 1, prog: 1 }
1793
- ];
1794
- var rotateInPreset = [
1795
- { key: "rotate", val: -180, prog: 0 },
1796
- { key: "rotate", val: 0, prog: 1 }
1797
- ];
1798
- var blurInPreset = [
1799
- { key: "blur", val: 10, prog: 0 },
1800
- { key: "blur", val: 0, prog: 1 }
1801
- ];
1802
- var fadeInScalePreset = [
1803
- { key: "opacity", val: 0, prog: 0 },
1804
- { key: "opacity", val: 1, prog: 1 },
1805
- { key: "scale", val: 0.8, prog: 0 },
1806
- { key: "scale", val: 1, prog: 1 }
1807
- ];
1808
- var slideInFadePreset = [
1809
- { key: "translateX", val: -50, prog: 0 },
1810
- { key: "translateX", val: 0, prog: 1 },
1811
- { key: "opacity", val: 0, prog: 0 },
1812
- { key: "opacity", val: 1, prog: 1 }
1813
- ];
1814
- var slideInLeftStringPreset = [
1815
- { key: "translateX", val: "-100px", prog: 0 },
1816
- { key: "translateX", val: "0px", prog: 1 }
1817
- ];
1818
- var slideInRightStringPreset = [
1819
- { key: "translateX", val: "100px", prog: 0 },
1820
- { key: "translateX", val: "0px", prog: 1 }
1821
- ];
1822
- var slideInTopStringPreset = [
1823
- { key: "translateY", val: "-100px", prog: 0 },
1824
- { key: "translateY", val: "0px", prog: 1 }
1825
- ];
1826
- var slideInBottomStringPreset = [
1827
- { key: "translateY", val: "100px", prog: 0 },
1828
- { key: "translateY", val: "0px", prog: 1 }
1829
- ];
1830
- var rotateInStringPreset = [
1831
- { key: "rotate", val: "-180deg", prog: 0 },
1832
- { key: "rotate", val: "0deg", prog: 1 }
1833
- ];
1834
- var blurInStringPreset = [
1835
- { key: "blur", val: "10px", prog: 0 },
1836
- { key: "blur", val: "0px", prog: 1 }
1837
- ];
1838
- var scaleInStringPreset = [
1839
- { key: "scale", val: 0, prog: 0 },
1840
- { key: "scale", val: 1, prog: 1 }
1841
- ];
1842
- var slideInLeftResponsivePreset = [
1843
- { key: "translateX", val: "-50vw", prog: 0 },
1844
- { key: "translateX", val: "0vw", prog: 1 }
1845
- ];
1846
- var slideInTopResponsivePreset = [
1847
- { key: "translateY", val: "-50vh", prog: 0 },
1848
- { key: "translateY", val: "0vh", prog: 1 }
1849
- ];
1850
- var backgroundColorPreset = [
1851
- { key: "backgroundColor", val: "#ff0000", prog: 0 },
1852
- { key: "backgroundColor", val: "#0000ff", prog: 1 }
1853
- ];
1854
- var borderRadiusPreset = [
1855
- { key: "borderRadius", val: "0px", prog: 0 },
1856
- { key: "borderRadius", val: "50px", prog: 1 }
1857
- ];
1858
- var boxShadowPreset = [
1859
- { key: "boxShadow", val: "0px 0px 0px rgba(0,0,0,0)", prog: 0 },
1860
- { key: "boxShadow", val: "10px 10px 20px rgba(0,0,0,0.5)", prog: 1 }
1861
- ];
1862
- var fontSizePreset = [
1863
- { key: "fontSize", val: "12px", prog: 0 },
1864
- { key: "fontSize", val: "24px", prog: 1 }
1865
- ];
1866
- var letterSpacingPreset = [
1867
- { key: "letterSpacing", val: "0px", prog: 0 },
1868
- { key: "letterSpacing", val: "5px", prog: 1 }
1869
- ];
1870
- var lineHeightPreset = [
1871
- { key: "lineHeight", val: "1", prog: 0 },
1872
- { key: "lineHeight", val: "2", prog: 1 }
1873
- ];
1874
- var textShadowPreset = [
1875
- { key: "textShadow", val: "0px 0px 0px rgba(0,0,0,0)", prog: 0 },
1876
- { key: "textShadow", val: "2px 2px 4px rgba(0,0,0,0.5)", prog: 1 }
1877
- ];
1878
- var widthPreset = [
1879
- { key: "width", val: "0px", prog: 0 },
1880
- { key: "width", val: "100%", prog: 1 }
1881
- ];
1882
- var heightPreset = [
1883
- { key: "height", val: "0px", prog: 0 },
1884
- { key: "height", val: "100%", prog: 1 }
1885
- ];
1886
- var marginPreset = [
1887
- { key: "margin", val: "0px", prog: 0 },
1888
- { key: "margin", val: "20px", prog: 1 }
1889
- ];
1890
- var paddingPreset = [
1891
- { key: "padding", val: "0px", prog: 0 },
1892
- { key: "padding", val: "20px", prog: 1 }
1893
- ];
1894
- var morphingCardPreset = [
1895
- { key: "borderRadius", val: "0px", prog: 0 },
1896
- { key: "borderRadius", val: "20px", prog: 0.5 },
1897
- { key: "borderRadius", val: "50px", prog: 1 },
1898
- { key: "boxShadow", val: "0px 0px 0px rgba(0,0,0,0)", prog: 0 },
1899
- { key: "boxShadow", val: "0px 10px 30px rgba(0,0,0,0.3)", prog: 1 },
1900
- { key: "backgroundColor", val: "#ffffff", prog: 0 },
1901
- { key: "backgroundColor", val: "#f0f0f0", prog: 1 }
1902
- ];
1903
- var textRevealPreset = [
1904
- { key: "opacity", val: 0, prog: 0 },
1905
- { key: "opacity", val: 1, prog: 1 },
1906
- { key: "letterSpacing", val: "10px", prog: 0 },
1907
- { key: "letterSpacing", val: "0px", prog: 1 },
1908
- { key: "textShadow", val: "0px 0px 0px rgba(0,0,0,0)", prog: 0 },
1909
- { key: "textShadow", val: "2px 2px 4px rgba(0,0,0,0.5)", prog: 1 }
1910
- ];
1911
- var GenericEffectPresets = {
1912
- fadeInPreset,
1913
- fadeOutPreset,
1914
- scaleInPreset,
1915
- scaleOutPreset,
1916
- slideInLeftPreset,
1917
- slideInRightPreset,
1918
- slideInTopPreset,
1919
- slideInBottomPreset,
1920
- bouncePreset,
1921
- pulsePreset,
1922
- rotateInPreset,
1923
- blurInPreset,
1924
- fadeInScalePreset,
1925
- slideInFadePreset,
1926
- // String-based presets
1927
- slideInLeftStringPreset,
1928
- slideInRightStringPreset,
1929
- slideInTopStringPreset,
1930
- slideInBottomStringPreset,
1931
- rotateInStringPreset,
1932
- blurInStringPreset,
1933
- scaleInStringPreset,
1934
- slideInLeftResponsivePreset,
1935
- slideInTopResponsivePreset,
1936
- // Custom CSS property presets
1937
- backgroundColorPreset,
1938
- borderRadiusPreset,
1939
- boxShadowPreset,
1940
- fontSizePreset,
1941
- letterSpacingPreset,
1942
- lineHeightPreset,
1943
- textShadowPreset,
1944
- widthPreset,
1945
- heightPreset,
1946
- marginPreset,
1947
- paddingPreset,
1948
- morphingCardPreset,
1949
- textRevealPreset
1950
- };
1951
-
1952
- // src/components/effects/index.ts
1953
- registerEffect(config2.displayName, BlurEffect, config2);
1954
- registerEffect(config3.displayName, LoopEffect, config3);
1955
- registerEffect(config4.displayName, PanEffect, config4);
1956
- registerEffect(config5.displayName, ZoomEffect, config5);
1957
- registerEffect("generic", UniversalEffect, config);
1958
- registerEffect(config6.displayName, ShakeEffect, config6);
1959
- registerEffect(
1960
- config7.displayName,
1961
- StretchEffect,
1962
- config7
1963
- );
1875
+ // src/components/effects/WaveformEffect.tsx
1876
+ import React13, { useMemo as useMemo8 } from "react";
1964
1877
 
1965
- // src/components/layouts/BaseLayout.tsx
1966
- var Layout = ({ id, children, data, context }) => {
1967
- const { containerProps = {}, childrenProps = [], repeatChildrenProps = {} } = data;
1968
- const overrideStyles = useAnimatedStyles(id);
1969
- const childrenArray = Children.toArray(children);
1970
- const enhancedStyle = useMemo7(
1971
- () => ({
1972
- ...!context?.boundaries?.reset ? context?.boundaries : {},
1973
- ...containerProps.style,
1878
+ // src/templates/waveform/hooks/useWaveformData.ts
1879
+ import { useMemo as useMemo7 } from "react";
1880
+ import {
1881
+ useAudioData,
1882
+ visualizeAudioWaveform,
1883
+ visualizeAudio
1884
+ } from "@remotion/media-utils";
1885
+ import { staticFile } from "remotion";
1886
+ var isValidPowerOfTwo = (num) => {
1887
+ return num > 0 && (num & num - 1) === 0;
1888
+ };
1889
+ var getClosestPowerOfTwo = (num) => {
1890
+ if (num <= 0) return 32;
1891
+ let power = 1;
1892
+ while (power < num) {
1893
+ power *= 2;
1894
+ }
1895
+ const lower = power / 2;
1896
+ const upper = power;
1897
+ return Math.abs(num - lower) < Math.abs(num - upper) ? lower : upper;
1898
+ };
1899
+ var useWaveformData = (config18) => {
1900
+ const {
1901
+ audioSrc,
1902
+ numberOfSamples,
1903
+ windowInSeconds,
1904
+ dataOffsetInSeconds = 0,
1905
+ normalize = false,
1906
+ frame,
1907
+ fps,
1908
+ posterize,
1909
+ includeFrequencyData = false,
1910
+ minDb = -100,
1911
+ maxDb = -30,
1912
+ smoothNormalisation = 1
1913
+ } = config18;
1914
+ const { root } = useComposition();
1915
+ const validatedNumberOfSamples = useMemo7(() => {
1916
+ if (!isValidPowerOfTwo(numberOfSamples)) {
1917
+ console.warn(
1918
+ `numberOfSamples must be a power of 2. Adjusting ${numberOfSamples} to ${getClosestPowerOfTwo(numberOfSamples)}`
1919
+ );
1920
+ return getClosestPowerOfTwo(numberOfSamples);
1921
+ }
1922
+ return numberOfSamples;
1923
+ }, [numberOfSamples]);
1924
+ const { source, audioStartsFrom } = useMemo7(() => {
1925
+ if (audioSrc.startsWith("http")) {
1926
+ return { source: audioSrc, audioStartsFrom: void 0 };
1927
+ }
1928
+ if (audioSrc.startsWith("ref:")) {
1929
+ const matchingComponent = findMatchingComponents(root, [
1930
+ audioSrc.replace("ref:", "")
1931
+ ]);
1932
+ if (matchingComponent.length > 0) {
1933
+ const firstMatchingComponent = matchingComponent[0];
1934
+ if (firstMatchingComponent.componentId === "AudioAtom") {
1935
+ return {
1936
+ source: firstMatchingComponent.data.src,
1937
+ audioStartsFrom: firstMatchingComponent.data?.startFrom ?? void 0
1938
+ };
1939
+ }
1940
+ if (firstMatchingComponent.type === "layout" || firstMatchingComponent.type === "scene") {
1941
+ const audioComponents = findMatchingComponentsByQuery(
1942
+ firstMatchingComponent.childrenData,
1943
+ { componentId: "AudioAtom" }
1944
+ );
1945
+ if (audioComponents.length > 0) {
1946
+ return {
1947
+ source: audioComponents[0].data.src,
1948
+ audioStartsFrom: audioComponents[0].data?.startFrom ?? void 0
1949
+ };
1950
+ }
1951
+ }
1952
+ }
1953
+ }
1954
+ return { source: staticFile(audioSrc), audioStartsFrom: void 0 };
1955
+ }, [audioSrc]);
1956
+ const audioData = useAudioData(source);
1957
+ const adjustedFrame = useMemo7(() => {
1958
+ if (posterize && posterize > 1) {
1959
+ return Math.round(frame / posterize) * posterize;
1960
+ }
1961
+ let offset = 0;
1962
+ if (audioStartsFrom && audioStartsFrom != 0) {
1963
+ offset += Math.round(audioStartsFrom * fps);
1964
+ }
1965
+ if (dataOffsetInSeconds != 0) {
1966
+ offset += Math.round(dataOffsetInSeconds * fps);
1967
+ }
1968
+ return frame + offset;
1969
+ }, [frame, posterize, dataOffsetInSeconds, audioStartsFrom]);
1970
+ const waveformData = useMemo7(() => {
1971
+ if (!audioData) return null;
1972
+ try {
1973
+ const baseSmoothingFrames = 3;
1974
+ const smoothingFrames = smoothNormalisation > 0 ? Math.floor(smoothNormalisation * baseSmoothingFrames) : 0;
1975
+ const samples = [];
1976
+ if (smoothingFrames === 0) {
1977
+ const waveform = visualizeAudioWaveform({
1978
+ fps,
1979
+ frame: adjustedFrame,
1980
+ audioData,
1981
+ numberOfSamples: validatedNumberOfSamples,
1982
+ windowInSeconds,
1983
+ dataOffsetInSeconds: 0,
1984
+ normalize
1985
+ });
1986
+ return waveform;
1987
+ }
1988
+ for (let offset = -smoothingFrames; offset <= smoothingFrames; offset++) {
1989
+ const sampleFrame = adjustedFrame + offset;
1990
+ if (sampleFrame >= 0) {
1991
+ try {
1992
+ const waveform = visualizeAudioWaveform({
1993
+ fps,
1994
+ frame: sampleFrame,
1995
+ audioData,
1996
+ numberOfSamples: validatedNumberOfSamples,
1997
+ windowInSeconds,
1998
+ dataOffsetInSeconds: 0,
1999
+ normalize
2000
+ });
2001
+ if (waveform && waveform.length > 0) {
2002
+ samples.push(waveform);
2003
+ }
2004
+ } catch (e) {
2005
+ }
2006
+ }
2007
+ }
2008
+ if (samples.length === 0) {
2009
+ const waveform = visualizeAudioWaveform({
2010
+ fps,
2011
+ frame: adjustedFrame,
2012
+ audioData,
2013
+ numberOfSamples: validatedNumberOfSamples,
2014
+ windowInSeconds,
2015
+ dataOffsetInSeconds: 0,
2016
+ normalize
2017
+ });
2018
+ return waveform;
2019
+ }
2020
+ const averaged = new Array(validatedNumberOfSamples).fill(0);
2021
+ for (let i = 0; i < validatedNumberOfSamples; i++) {
2022
+ let sum = 0;
2023
+ let count = 0;
2024
+ for (const sample of samples) {
2025
+ if (sample[i] !== void 0) {
2026
+ sum += sample[i];
2027
+ count++;
2028
+ }
2029
+ }
2030
+ averaged[i] = count > 0 ? sum / count : 0;
2031
+ }
2032
+ return averaged;
2033
+ } catch (error2) {
2034
+ console.error("Error generating waveform:", error2);
2035
+ return null;
2036
+ }
2037
+ }, [
2038
+ audioData,
2039
+ adjustedFrame,
2040
+ fps,
2041
+ validatedNumberOfSamples,
2042
+ windowInSeconds,
2043
+ dataOffsetInSeconds,
2044
+ normalize,
2045
+ smoothNormalisation
2046
+ ]);
2047
+ const {
2048
+ frequencyData,
2049
+ amplitudes,
2050
+ bass,
2051
+ mid,
2052
+ treble,
2053
+ bassValues,
2054
+ midValues,
2055
+ trebleValues
2056
+ } = useMemo7(() => {
2057
+ if (!audioData || !includeFrequencyData) {
2058
+ return {
2059
+ frequencyData: null,
2060
+ amplitudes: null,
2061
+ bass: null,
2062
+ mid: null,
2063
+ treble: null,
2064
+ bassValues: null,
2065
+ midValues: null,
2066
+ trebleValues: null
2067
+ };
2068
+ }
2069
+ try {
2070
+ const baseSmoothingFrames = 3;
2071
+ const smoothingFrames = smoothNormalisation > 0 ? Math.floor(smoothNormalisation * baseSmoothingFrames) : 0;
2072
+ const frequencySamples = [];
2073
+ let frequencyData2;
2074
+ if (smoothingFrames === 0) {
2075
+ frequencyData2 = visualizeAudio({
2076
+ fps,
2077
+ frame: adjustedFrame,
2078
+ audioData,
2079
+ numberOfSamples: validatedNumberOfSamples
2080
+ });
2081
+ } else {
2082
+ for (let offset = -smoothingFrames; offset <= smoothingFrames; offset++) {
2083
+ const sampleFrame = adjustedFrame + offset;
2084
+ if (sampleFrame >= 0) {
2085
+ try {
2086
+ const freqData = visualizeAudio({
2087
+ fps,
2088
+ frame: sampleFrame,
2089
+ audioData,
2090
+ numberOfSamples: validatedNumberOfSamples
2091
+ });
2092
+ if (freqData && freqData.length > 0) {
2093
+ frequencySamples.push(freqData);
2094
+ }
2095
+ } catch (e) {
2096
+ }
2097
+ }
2098
+ }
2099
+ if (frequencySamples.length === 0) {
2100
+ frequencyData2 = visualizeAudio({
2101
+ fps,
2102
+ frame: adjustedFrame,
2103
+ audioData,
2104
+ numberOfSamples: validatedNumberOfSamples
2105
+ });
2106
+ } else {
2107
+ frequencyData2 = new Array(validatedNumberOfSamples).fill(0);
2108
+ for (let i = 0; i < validatedNumberOfSamples; i++) {
2109
+ let sum = 0;
2110
+ let count = 0;
2111
+ for (const sample of frequencySamples) {
2112
+ if (sample[i] !== void 0) {
2113
+ sum += sample[i];
2114
+ count++;
2115
+ }
2116
+ }
2117
+ frequencyData2[i] = count > 0 ? sum / count : 0;
2118
+ }
2119
+ }
2120
+ }
2121
+ const { sampleRate } = audioData;
2122
+ const bassValues2 = [];
2123
+ const midValues2 = [];
2124
+ const trebleValues2 = [];
2125
+ for (let i = 0; i < frequencyData2.length; i++) {
2126
+ const freq = i * sampleRate / (2 * frequencyData2.length);
2127
+ const value = frequencyData2[i];
2128
+ if (freq >= 0 && freq < 250) {
2129
+ bassValues2.push(value * 2.5);
2130
+ } else if (freq >= 250 && freq < 4e3) {
2131
+ midValues2.push(value * 3);
2132
+ midValues2.push(value * 4.5);
2133
+ midValues2.push(value * 5);
2134
+ } else if (freq >= 4e3 && freq < sampleRate / 2) {
2135
+ trebleValues2.push(value * 30);
2136
+ }
2137
+ }
2138
+ const getAverage = (arr) => arr.length > 0 ? arr.reduce((a, b) => a + b, 0) / arr.length : 0;
2139
+ const bass2 = getAverage(bassValues2);
2140
+ const mid2 = getAverage(midValues2);
2141
+ const treble2 = getAverage(trebleValues2);
2142
+ const amplitudes2 = frequencyData2.map((value) => {
2143
+ const db = 20 * Math.log10(value);
2144
+ const scaled = (db - minDb) / (maxDb - minDb);
2145
+ return Math.max(0, Math.min(1, scaled));
2146
+ });
2147
+ return {
2148
+ frequencyData: frequencyData2,
2149
+ amplitudes: amplitudes2,
2150
+ bass: bass2,
2151
+ mid: mid2,
2152
+ treble: treble2,
2153
+ bassValues: bassValues2,
2154
+ midValues: midValues2,
2155
+ trebleValues: trebleValues2.reverse()
2156
+ };
2157
+ } catch (error2) {
2158
+ console.error("Error generating frequency data:", error2);
2159
+ return {
2160
+ frequencyData: null,
2161
+ amplitudes: null,
2162
+ bass: null,
2163
+ mid: null,
2164
+ treble: null
2165
+ };
2166
+ }
2167
+ }, [
2168
+ audioData,
2169
+ includeFrequencyData,
2170
+ adjustedFrame,
2171
+ fps,
2172
+ validatedNumberOfSamples,
2173
+ windowInSeconds,
2174
+ dataOffsetInSeconds,
2175
+ minDb,
2176
+ maxDb,
2177
+ smoothNormalisation
2178
+ ]);
2179
+ const isLoading = !audioData;
2180
+ const error = audioData === null && !isLoading ? "Failed to load audio data" : null;
2181
+ return {
2182
+ waveformData,
2183
+ frequencyData,
2184
+ amplitudes,
2185
+ audioData,
2186
+ isLoading,
2187
+ error,
2188
+ bass,
2189
+ bassValues,
2190
+ mid,
2191
+ midValues,
2192
+ treble,
2193
+ trebleValues
2194
+ };
2195
+ };
2196
+
2197
+ // src/components/effects/WaveformEffect.tsx
2198
+ var WaveformEffect = ({
2199
+ id,
2200
+ componentId,
2201
+ type,
2202
+ data,
2203
+ children,
2204
+ context
2205
+ }) => {
2206
+ const { progress, frame, mode, targetIds, effectData, fps } = useUniversalAnimation(data, context);
2207
+ const {
2208
+ audioSrc,
2209
+ numberOfSamples = 128,
2210
+ windowInSeconds,
2211
+ dataOffsetInSeconds = 0,
2212
+ normalize = false,
2213
+ useFrequencyData = true,
2214
+ audioProperty = "bass",
2215
+ sensitivity = 1,
2216
+ threshold = 0,
2217
+ smoothing = 0.5,
2218
+ smoothNormalisation = 1,
2219
+ effectType = "zoom",
2220
+ intensity = 1,
2221
+ minValue,
2222
+ maxValue,
2223
+ shakeAxis = "both",
2224
+ baseScale = 1,
2225
+ baseBrightness = 1,
2226
+ rotationRange = 15
2227
+ } = effectData;
2228
+ const parentContext = useUniversalEffectOptional();
2229
+ const analysisWindow = smoothNormalisation === 0 ? windowInSeconds || 1 / fps : windowInSeconds || Math.max(1 / fps, 0.05);
2230
+ const { bass, mid, treble, waveformData } = useWaveformData({
2231
+ audioSrc,
2232
+ numberOfSamples,
2233
+ windowInSeconds: analysisWindow,
2234
+ dataOffsetInSeconds,
2235
+ normalize,
2236
+ frame,
2237
+ fps,
2238
+ includeFrequencyData: useFrequencyData,
2239
+ smoothNormalisation
2240
+ });
2241
+ const audioIntensity = useMemo8(() => {
2242
+ let rawValue = 0;
2243
+ switch (audioProperty) {
2244
+ case "bass":
2245
+ rawValue = bass || 0;
2246
+ break;
2247
+ case "mid":
2248
+ rawValue = mid || 0;
2249
+ break;
2250
+ case "treble":
2251
+ rawValue = treble || 0;
2252
+ break;
2253
+ case "waveform":
2254
+ if (waveformData && waveformData.length > 0) {
2255
+ rawValue = waveformData.reduce((sum, val) => sum + Math.abs(val), 0) / waveformData.length;
2256
+ }
2257
+ break;
2258
+ case "frequency":
2259
+ rawValue = bass || 0;
2260
+ break;
2261
+ default:
2262
+ rawValue = bass || 0;
2263
+ }
2264
+ const thresholdedValue = Math.max(0, rawValue - threshold);
2265
+ const sensitizedValue = thresholdedValue * sensitivity;
2266
+ return Math.min(1, Math.max(0, sensitizedValue));
2267
+ }, [audioProperty, bass, mid, treble, waveformData, threshold, sensitivity]);
2268
+ const smoothedIntensity = useMemo8(() => {
2269
+ if (smoothNormalisation === 0) {
2270
+ return audioIntensity;
2271
+ }
2272
+ const smoothingPower = 1 + smoothing * 2;
2273
+ const smoothed = Math.pow(audioIntensity, smoothingPower);
2274
+ const baseline = 0.1;
2275
+ const filtered = smoothed * (1 - baseline * smoothing) + baseline * smoothing;
2276
+ return Math.min(1, Math.max(0, filtered));
2277
+ }, [audioIntensity, smoothing, smoothNormalisation]);
2278
+ const animatedStyles = useMemo8(() => {
2279
+ const intensityValue = smoothedIntensity || audioIntensity;
2280
+ let effectValue = intensityValue * intensity;
2281
+ if (minValue !== void 0 || maxValue !== void 0) {
2282
+ const defaultMin = effectType === "zoom" || effectType === "scale" ? baseScale : 0;
2283
+ const defaultMax = effectType === "zoom" || effectType === "scale" ? baseScale + intensity : intensity;
2284
+ const min = minValue !== void 0 ? minValue : defaultMin;
2285
+ const max = maxValue !== void 0 ? maxValue : defaultMax;
2286
+ effectValue = min + intensityValue * (max - min);
2287
+ } else {
2288
+ switch (effectType) {
2289
+ case "zoom":
2290
+ case "scale":
2291
+ effectValue = baseScale + intensityValue * intensity;
2292
+ break;
2293
+ case "exposure":
2294
+ effectValue = baseBrightness + intensityValue * intensity;
2295
+ break;
2296
+ case "blur":
2297
+ effectValue = intensityValue * intensity * 10;
2298
+ break;
2299
+ case "rotate":
2300
+ effectValue = (intensityValue - 0.5) * 2 * rotationRange;
2301
+ break;
2302
+ case "translateX":
2303
+ case "translateY":
2304
+ effectValue = (intensityValue - 0.5) * 2 * intensity * 50;
2305
+ break;
2306
+ default:
2307
+ effectValue = intensityValue * intensity;
2308
+ }
2309
+ }
2310
+ const styles = {};
2311
+ switch (effectType) {
2312
+ case "zoom":
2313
+ case "scale":
2314
+ styles.transform = `scale(${effectValue})`;
2315
+ break;
2316
+ case "shake":
2317
+ const shakeFrequency = 0.1;
2318
+ const shakeTime = frame * shakeFrequency;
2319
+ const shakeAmplitude = intensityValue * intensity * 20;
2320
+ const shakeX = shakeAxis === "x" || shakeAxis === "both" ? Math.sin(shakeTime * 2.3) * shakeAmplitude : 0;
2321
+ const shakeY = shakeAxis === "y" || shakeAxis === "both" ? Math.cos(shakeTime * 1.7) * shakeAmplitude : 0;
2322
+ styles.transform = `translateX(${shakeX}px) translateY(${shakeY}px)`;
2323
+ break;
2324
+ case "exposure":
2325
+ styles.filter = `brightness(${effectValue})`;
2326
+ break;
2327
+ case "blur":
2328
+ styles.filter = `blur(${effectValue}px)`;
2329
+ break;
2330
+ case "rotate":
2331
+ styles.transform = `rotate(${effectValue}deg)`;
2332
+ break;
2333
+ case "translateX":
2334
+ styles.transform = `translateX(${effectValue}px)`;
2335
+ break;
2336
+ case "translateY":
2337
+ styles.transform = `translateY(${effectValue}px)`;
2338
+ break;
2339
+ default:
2340
+ styles.transform = `scale(${effectValue})`;
2341
+ }
2342
+ if (parentContext && mode === "provider") {
2343
+ const combinedStyles = mergeCSSStyles_default(parentContext.animatedStyles, styles);
2344
+ return combinedStyles;
2345
+ }
2346
+ return styles;
2347
+ }, [
2348
+ smoothedIntensity,
2349
+ audioIntensity,
2350
+ effectType,
2351
+ intensity,
2352
+ minValue,
2353
+ maxValue,
2354
+ baseScale,
2355
+ baseBrightness,
2356
+ rotationRange,
2357
+ shakeAxis,
2358
+ mode,
2359
+ parentContext?.animatedStyles,
2360
+ frame
2361
+ // Add frame dependency for shake effect
2362
+ ]);
2363
+ const contextValue = useMemo8(
2364
+ () => ({
2365
+ animatedStyles,
2366
+ targetIds,
2367
+ effectType: "waveform"
2368
+ }),
2369
+ [animatedStyles, targetIds]
2370
+ );
2371
+ if (mode === "provider") {
2372
+ return /* @__PURE__ */ React13.createElement(UniversalEffectContext.Provider, { value: contextValue }, children);
2373
+ }
2374
+ return /* @__PURE__ */ React13.createElement("div", { ...effectData.props, style: animatedStyles }, children);
2375
+ };
2376
+ var config8 = {
2377
+ displayName: "waveform",
2378
+ description: "Waveform-driven effect that reacts to audio data (bass, mid, treble, waveform)",
2379
+ isInnerSequence: false,
2380
+ props: {
2381
+ audioSrc: {
2382
+ type: "string",
2383
+ required: true,
2384
+ description: "Audio source URL or ref:componentId"
2385
+ },
2386
+ audioProperty: {
2387
+ type: "enum",
2388
+ values: ["bass", "mid", "treble", "waveform", "frequency"],
2389
+ default: "bass",
2390
+ description: "Which audio property to react to"
2391
+ },
2392
+ effectType: {
2393
+ type: "enum",
2394
+ values: ["zoom", "shake", "exposure", "blur", "scale", "rotate", "translateX", "translateY"],
2395
+ default: "zoom",
2396
+ description: "Type of effect to apply"
2397
+ },
2398
+ intensity: {
2399
+ type: "number",
2400
+ default: 1,
2401
+ description: "Effect intensity multiplier"
2402
+ },
2403
+ sensitivity: {
2404
+ type: "number",
2405
+ default: 1,
2406
+ description: "Sensitivity multiplier for audio detection"
2407
+ },
2408
+ threshold: {
2409
+ type: "number",
2410
+ default: 0,
2411
+ description: "Minimum audio value to trigger effect"
2412
+ },
2413
+ smoothing: {
2414
+ type: "number",
2415
+ default: 0.5,
2416
+ description: "Smoothing factor (0-1) for audio data"
2417
+ },
2418
+ smoothNormalisation: {
2419
+ type: "number",
2420
+ default: 1,
2421
+ description: "Frame-based smoothing control (0 = no smoothing, 1 = default, >1 = more smoothing)"
2422
+ }
2423
+ }
2424
+ };
2425
+
2426
+ // src/components/effects/CanvasWipeReveal.tsx
2427
+ import React15, { useEffect, useRef, useState } from "react";
2428
+ import { useCurrentFrame as useCurrentFrame4, useVideoConfig as useVideoConfig5 } from "remotion";
2429
+ import { z as z2 } from "zod";
2430
+
2431
+ // src/components/atoms/CanvasAtom.tsx
2432
+ import React14 from "react";
2433
+ import { z } from "zod";
2434
+ var CanvasAtomDataProps = z.object({
2435
+ className: z.string().optional(),
2436
+ style: z.record(z.string(), z.any()).optional()
2437
+ });
2438
+ var Atom = React14.forwardRef(({ data, id }, ref) => {
2439
+ const { className, style } = data;
2440
+ return /* @__PURE__ */ React14.createElement("canvas", { ref, className, style, id });
2441
+ });
2442
+ var config9 = {
2443
+ displayName: "CanvasAtom",
2444
+ type: "atom",
2445
+ isInnerSequence: false,
2446
+ props: CanvasAtomDataProps
2447
+ // The config points to the Zod schema for data
2448
+ };
2449
+
2450
+ // src/components/effects/CanvasWipeReveal.tsx
2451
+ var mulberry32 = (seed) => {
2452
+ return () => {
2453
+ let t = seed += 1831565813;
2454
+ t = Math.imul(t ^ t >>> 15, t | 1);
2455
+ t ^= t + Math.imul(t ^ t >>> 7, t | 61);
2456
+ return ((t ^ t >>> 14) >>> 0) / 4294967296;
2457
+ };
2458
+ };
2459
+ var CanvasWipeRevealProps = z2.object({
2460
+ imageUrl: z2.string().url(),
2461
+ revealDurationInFrames: z2.number().min(1),
2462
+ revealType: z2.enum(["wipe", "radial"]).default("wipe"),
2463
+ angle: z2.number().default(0),
2464
+ fit: z2.enum(["cover", "contain"]).default("cover"),
2465
+ edgeStyle: z2.enum(["straight", "organic", "burn"]).default("straight"),
2466
+ edgeWaviness: z2.number().default(30),
2467
+ edgeFrequency: z2.number().default(4),
2468
+ backgroundColor: z2.string().default("rgba(0,0,0,0)"),
2469
+ burnGlow: z2.boolean().default(true),
2470
+ burnGlowColor: z2.string().default("#ff6600"),
2471
+ burnGlowIntensity: z2.number().default(1),
2472
+ organicRandomAmplitude: z2.boolean().default(true),
2473
+ organicRandomWavelength: z2.boolean().default(false)
2474
+ });
2475
+ var CanvasWipeReveal = ({ data, id }) => {
2476
+ const {
2477
+ imageUrl,
2478
+ revealDurationInFrames,
2479
+ revealType,
2480
+ angle,
2481
+ fit,
2482
+ edgeStyle,
2483
+ edgeWaviness,
2484
+ edgeFrequency,
2485
+ backgroundColor,
2486
+ burnGlow,
2487
+ burnGlowColor,
2488
+ burnGlowIntensity,
2489
+ organicRandomAmplitude,
2490
+ organicRandomWavelength
2491
+ } = data;
2492
+ const frame = useCurrentFrame4();
2493
+ const { width, height } = useVideoConfig5();
2494
+ const canvasRef = useRef(null);
2495
+ const [image, setImage] = useState(null);
2496
+ useEffect(() => {
2497
+ const img = new window.Image();
2498
+ img.crossOrigin = "Anonymous";
2499
+ img.src = imageUrl;
2500
+ img.onload = () => setImage(img);
2501
+ }, [imageUrl]);
2502
+ useEffect(() => {
2503
+ if (!canvasRef.current || !image) return;
2504
+ const context = canvasRef.current.getContext("2d");
2505
+ if (!context) return;
2506
+ context.canvas.width = width;
2507
+ context.canvas.height = height;
2508
+ context.fillStyle = backgroundColor;
2509
+ context.fillRect(0, 0, width, height);
2510
+ const progress = Math.min(frame / revealDurationInFrames, 1);
2511
+ if (progress === 0 && backgroundColor === "rgba(0,0,0,0)") return;
2512
+ const seed = id.split("").reduce((acc, char) => acc + char.charCodeAt(0), 0);
2513
+ context.save();
2514
+ context.beginPath();
2515
+ if (revealType === "radial") {
2516
+ const baseRadius = Math.sqrt(width * width + height * height) / 2 * progress;
2517
+ if (edgeStyle === "organic") {
2518
+ const points = 120;
2519
+ const random = mulberry32(seed);
2520
+ const amplitudes = Array.from(
2521
+ { length: points + 1 },
2522
+ () => organicRandomAmplitude ? 0.5 + random() : 1
2523
+ );
2524
+ const wavelengths = Array.from(
2525
+ { length: points + 1 },
2526
+ () => organicRandomWavelength ? 0.5 + random() * 1.5 : 1
2527
+ );
2528
+ for (let i = 0; i <= points; i++) {
2529
+ const p = i / points;
2530
+ const angle2 = p * Math.PI * 2;
2531
+ const wave = Math.sin(
2532
+ p * Math.PI * edgeFrequency * wavelengths[i] + frame * 0.1
2533
+ ) * edgeWaviness * progress * amplitudes[i];
2534
+ const radius = baseRadius + wave;
2535
+ const x = width / 2 + Math.cos(angle2) * radius;
2536
+ const y = height / 2 + Math.sin(angle2) * radius;
2537
+ if (i === 0) context.moveTo(x, y);
2538
+ else context.lineTo(x, y);
2539
+ }
2540
+ context.closePath();
2541
+ } else if (edgeStyle === "burn") {
2542
+ const points = 120;
2543
+ const random = mulberry32(seed);
2544
+ const randomValues = Array.from({ length: points + 1 }, () => random());
2545
+ const phaseOffsets = Array.from(
2546
+ { length: points + 1 },
2547
+ () => random() * Math.PI * 2
2548
+ );
2549
+ const sparklePoints = [];
2550
+ for (let i = 0; i <= points; i++) {
2551
+ const p = i / points;
2552
+ const angle2 = p * Math.PI * 2;
2553
+ const flicker = Math.sin(frame * 0.3 + phaseOffsets[i]);
2554
+ const burnOffset = (randomValues[i] * 2 - 1) * flicker * edgeWaviness * progress;
2555
+ const radius = baseRadius + burnOffset;
2556
+ const x = width / 2 + Math.cos(angle2) * radius;
2557
+ const y = height / 2 + Math.sin(angle2) * radius;
2558
+ if (burnGlow && i % 5 === 0 && flicker > 0.3) {
2559
+ sparklePoints.push({ x, y, intensity: flicker });
2560
+ }
2561
+ if (i === 0) context.moveTo(x, y);
2562
+ else context.lineTo(x, y);
2563
+ }
2564
+ context.closePath();
2565
+ if (burnGlow && sparklePoints.length > 0) {
2566
+ sparklePoints.forEach((point) => {
2567
+ const glowSize = 3 + point.intensity * 5 * burnGlowIntensity;
2568
+ if (isFinite(point.x) && isFinite(point.y) && isFinite(glowSize) && glowSize > 0) {
2569
+ const gradient = context.createRadialGradient(
2570
+ point.x,
2571
+ point.y,
2572
+ 0,
2573
+ point.x,
2574
+ point.y,
2575
+ glowSize
2576
+ );
2577
+ gradient.addColorStop(0, burnGlowColor);
2578
+ gradient.addColorStop(0.5, burnGlowColor + "80");
2579
+ gradient.addColorStop(1, burnGlowColor + "00");
2580
+ context.fillStyle = gradient;
2581
+ context.fillRect(
2582
+ point.x - glowSize,
2583
+ point.y - glowSize,
2584
+ glowSize * 2,
2585
+ glowSize * 2
2586
+ );
2587
+ }
2588
+ });
2589
+ }
2590
+ } else {
2591
+ context.arc(width / 2, height / 2, baseRadius, 0, Math.PI * 2);
2592
+ }
2593
+ } else {
2594
+ const angleInRadians = angle * Math.PI / 180;
2595
+ const diagonal = Math.sqrt(width * width + height * height);
2596
+ context.translate(width / 2, height / 2);
2597
+ context.rotate(angleInRadians);
2598
+ const wipeEdgePosition = progress * diagonal - diagonal / 2;
2599
+ if (edgeStyle === "burn") {
2600
+ const points = 100;
2601
+ const random = mulberry32(seed);
2602
+ const randomValues = Array.from({ length: points + 1 }, () => random());
2603
+ const phaseOffsets = Array.from(
2604
+ { length: points + 1 },
2605
+ () => random() * Math.PI * 2
2606
+ );
2607
+ const edgePoints = [];
2608
+ context.moveTo(wipeEdgePosition, -diagonal / 2);
2609
+ for (let i = 0; i <= points; i++) {
2610
+ const p = i / points;
2611
+ const y = (p - 0.5) * diagonal;
2612
+ const flicker = Math.sin(frame * 0.3 + phaseOffsets[i]);
2613
+ const x = wipeEdgePosition + (randomValues[i] * 2 - 1) * flicker * edgeWaviness;
2614
+ context.lineTo(x, y);
2615
+ edgePoints.push({ x, y });
2616
+ }
2617
+ context.lineTo(wipeEdgePosition, diagonal / 2);
2618
+ context.lineTo(-diagonal / 2, diagonal / 2);
2619
+ context.lineTo(-diagonal / 2, -diagonal / 2);
2620
+ context.closePath();
2621
+ if (burnGlow && progress > 0.01) {
2622
+ const random2 = mulberry32(seed + frame);
2623
+ for (let i = 0; i < edgePoints.length; i += 3) {
2624
+ const point = edgePoints[i];
2625
+ const flicker = Math.sin(frame * 0.3 + phaseOffsets[i]);
2626
+ if (flicker > 0.2) {
2627
+ const glowSize = 4 + random2() * 6 * flicker * burnGlowIntensity;
2628
+ if (isFinite(point.x) && isFinite(point.y) && isFinite(glowSize) && glowSize > 0) {
2629
+ const gradient = context.createRadialGradient(
2630
+ point.x,
2631
+ point.y,
2632
+ 0,
2633
+ point.x,
2634
+ point.y,
2635
+ glowSize
2636
+ );
2637
+ gradient.addColorStop(0, burnGlowColor);
2638
+ gradient.addColorStop(0.4, burnGlowColor + "CC");
2639
+ gradient.addColorStop(1, burnGlowColor + "00");
2640
+ context.fillStyle = gradient;
2641
+ context.fillRect(
2642
+ point.x - glowSize,
2643
+ point.y - glowSize,
2644
+ glowSize * 2,
2645
+ glowSize * 2
2646
+ );
2647
+ if (random2() > 0.85) {
2648
+ const sparkleSize = 2 + random2() * 3;
2649
+ context.fillStyle = "#ffffff";
2650
+ context.fillRect(
2651
+ point.x - sparkleSize / 2,
2652
+ point.y - sparkleSize / 2,
2653
+ sparkleSize,
2654
+ sparkleSize
2655
+ );
2656
+ }
2657
+ }
2658
+ }
2659
+ }
2660
+ }
2661
+ } else if (edgeStyle === "organic") {
2662
+ const points = 100;
2663
+ const random = mulberry32(seed);
2664
+ const amplitudes = Array.from(
2665
+ { length: points + 1 },
2666
+ () => organicRandomAmplitude ? 0.5 + random() : 1
2667
+ );
2668
+ const wavelengths = Array.from(
2669
+ { length: points + 1 },
2670
+ () => organicRandomWavelength ? 0.5 + random() * 1.5 : 1
2671
+ );
2672
+ context.moveTo(wipeEdgePosition, -diagonal / 2);
2673
+ for (let i = 0; i <= points; i++) {
2674
+ const p = i / points;
2675
+ const y = (p - 0.5) * diagonal;
2676
+ const wave = Math.sin(
2677
+ p * edgeFrequency * wavelengths[i] * Math.PI + frame * 0.1
2678
+ ) * edgeWaviness * amplitudes[i];
2679
+ context.lineTo(wipeEdgePosition + wave, y);
2680
+ }
2681
+ context.lineTo(wipeEdgePosition, diagonal / 2);
2682
+ context.lineTo(-diagonal / 2, diagonal / 2);
2683
+ context.lineTo(-diagonal / 2, -diagonal / 2);
2684
+ context.closePath();
2685
+ } else {
2686
+ context.rect(
2687
+ -diagonal / 2,
2688
+ -diagonal / 2,
2689
+ wipeEdgePosition + diagonal / 2,
2690
+ diagonal
2691
+ );
2692
+ }
2693
+ context.rotate(-angleInRadians);
2694
+ context.translate(-width / 2, -height / 2);
2695
+ }
2696
+ context.clip();
2697
+ let sx = 0, sy = 0, sWidth = image.width, sHeight = image.height;
2698
+ if (fit === "cover") {
2699
+ const imgAspect = image.width / image.height;
2700
+ const canvasAspect = width / height;
2701
+ if (imgAspect > canvasAspect) {
2702
+ sWidth = image.height * canvasAspect;
2703
+ sx = (image.width - sWidth) / 2;
2704
+ } else {
2705
+ sHeight = image.width / canvasAspect;
2706
+ sy = (image.height - sHeight) / 2;
2707
+ }
2708
+ }
2709
+ context.drawImage(image, sx, sy, sWidth, sHeight, 0, 0, width, height);
2710
+ context.restore();
2711
+ }, [
2712
+ frame,
2713
+ image,
2714
+ width,
2715
+ height,
2716
+ revealDurationInFrames,
2717
+ fit,
2718
+ revealType,
2719
+ angle,
2720
+ edgeStyle,
2721
+ edgeWaviness,
2722
+ edgeFrequency,
2723
+ id,
2724
+ backgroundColor,
2725
+ burnGlow,
2726
+ burnGlowColor,
2727
+ burnGlowIntensity,
2728
+ organicRandomAmplitude,
2729
+ organicRandomWavelength
2730
+ ]);
2731
+ return /* @__PURE__ */ React15.createElement(Atom, { ref: canvasRef, data: { className: "w-full h-full" }, id });
2732
+ };
2733
+
2734
+ // src/components/effects/CanvasContentAwareReveal.tsx
2735
+ import React16, { useEffect as useEffect2, useRef as useRef2, useState as useState2 } from "react";
2736
+ import { useCurrentFrame as useCurrentFrame5, useVideoConfig as useVideoConfig6 } from "remotion";
2737
+ import { z as z3 } from "zod";
2738
+ var CanvasContentAwareRevealProps = z3.object({
2739
+ imageUrl: z3.string().url(),
2740
+ revealDurationInFrames: z3.number().min(1),
2741
+ fit: z3.enum(["cover", "contain"]).default("cover"),
2742
+ backgroundColor: z3.string().default("rgba(0,0,0,0)"),
2743
+ burnColorOrder: z3.enum(["vibgyor", "luminance", "random"]).default("vibgyor"),
2744
+ revealMode: z3.enum(["color", "direction", "combined"]).default("combined").describe("Reveal mode: color-only, direction-only, or combined"),
2745
+ direction: z3.enum(["horizontal", "vertical", "diagonal-down", "diagonal-up", "top-to-bottom"]).default("top-to-bottom"),
2746
+ directionLayers: z3.number().default(10).describe("Number of layers for horizontal/vertical patterns")
2747
+ });
2748
+ var CanvasContentAwareReveal = ({ data, id }) => {
2749
+ const {
2750
+ imageUrl,
2751
+ revealDurationInFrames,
2752
+ fit,
2753
+ backgroundColor,
2754
+ burnColorOrder,
2755
+ revealMode,
2756
+ direction,
2757
+ directionLayers
2758
+ } = data;
2759
+ const frame = useCurrentFrame5();
2760
+ const { width, height } = useVideoConfig6();
2761
+ const canvasRef = useRef2(null);
2762
+ const [image, setImage] = useState2(null);
2763
+ const [pixelBurnMap, setPixelBurnMap] = useState2(null);
2764
+ const [isProcessing, setIsProcessing] = useState2(false);
2765
+ const burnMapGeneratedRef = useRef2(false);
2766
+ const rgbToHsv = (r, g, b) => {
2767
+ r /= 255;
2768
+ g /= 255;
2769
+ b /= 255;
2770
+ const max = Math.max(r, g, b), min = Math.min(r, g, b), delta = max - min;
2771
+ let h = 0;
2772
+ if (delta !== 0) {
2773
+ if (max === r) h = (g - b) / delta % 6;
2774
+ else if (max === g) h = (b - r) / delta + 2;
2775
+ else h = (r - g) / delta + 4;
2776
+ h *= 60;
2777
+ if (h < 0) h += 360;
2778
+ }
2779
+ return [h, max === 0 ? 0 : delta / max, max];
2780
+ };
2781
+ const getLuminance = (r, g, b) => 0.299 * r + 0.587 * g + 0.114 * b;
2782
+ const hueToVibgyorOrder = (hue) => {
2783
+ if (hue >= 260 && hue <= 290) return 0;
2784
+ if (hue >= 240 && hue < 260) return 0.15;
2785
+ if (hue >= 200 && hue < 240) return 0.3;
2786
+ if (hue >= 120 && hue < 200) return 0.5;
2787
+ if (hue >= 50 && hue < 120) return 0.65;
2788
+ if (hue >= 20 && hue < 50) return 0.8;
2789
+ if (hue >= 290 || hue < 20) return 1;
2790
+ return hue / 360;
2791
+ };
2792
+ useEffect2(() => {
2793
+ const img = new window.Image();
2794
+ img.crossOrigin = "Anonymous";
2795
+ img.src = imageUrl;
2796
+ img.onload = () => {
2797
+ setImage(img);
2798
+ burnMapGeneratedRef.current = false;
2799
+ };
2800
+ }, [imageUrl]);
2801
+ useEffect2(() => {
2802
+ if (!image || isProcessing || burnMapGeneratedRef.current) return;
2803
+ setIsProcessing(true);
2804
+ setTimeout(() => {
2805
+ try {
2806
+ const canvas = document.createElement("canvas");
2807
+ const ctx = canvas.getContext("2d");
2808
+ if (!ctx) return;
2809
+ canvas.width = image.width;
2810
+ canvas.height = image.height;
2811
+ ctx.drawImage(image, 0, 0);
2812
+ const imageData = ctx.getImageData(0, 0, image.width, image.height);
2813
+ const pixels = imageData.data;
2814
+ const burnMap = new Float32Array(image.width * image.height);
2815
+ const rawValues = [];
2816
+ for (let i = 0; i < pixels.length; i += 4) {
2817
+ const pixelIndex = i / 4;
2818
+ const [r, g, b] = [pixels[i], pixels[i + 1], pixels[i + 2]];
2819
+ let burnValue = 0;
2820
+ if (burnColorOrder === "vibgyor") {
2821
+ const [h, s] = rgbToHsv(r, g, b);
2822
+ burnValue = hueToVibgyorOrder(h) * s + 0.5 * (1 - s);
2823
+ } else if (burnColorOrder === "luminance") {
2824
+ burnValue = getLuminance(r, g, b) / 255;
2825
+ } else {
2826
+ burnValue = pixelIndex * 2654435761 % 2147483648 / 2147483648;
2827
+ }
2828
+ rawValues.push(burnValue);
2829
+ }
2830
+ const numBuckets = 200;
2831
+ const buckets = new Array(numBuckets).fill(0);
2832
+ rawValues.forEach((val) => {
2833
+ buckets[Math.min(Math.floor(val * numBuckets), numBuckets - 1)]++;
2834
+ });
2835
+ const cumulative = new Array(numBuckets);
2836
+ cumulative[0] = buckets[0];
2837
+ for (let i = 1; i < numBuckets; i++) {
2838
+ cumulative[i] = cumulative[i - 1] + buckets[i];
2839
+ }
2840
+ rawValues.forEach((val, idx) => {
2841
+ const bucket = Math.min(Math.floor(val * numBuckets), numBuckets - 1);
2842
+ burnMap[idx] = cumulative[bucket] / (image.width * image.height);
2843
+ });
2844
+ if (revealMode === "direction" || revealMode === "combined") {
2845
+ for (let idx = 0; idx < image.width * image.height; idx++) {
2846
+ const x = idx % image.width;
2847
+ const y = Math.floor(idx / image.width);
2848
+ let directionValue = 0;
2849
+ if (direction === "horizontal") {
2850
+ const layer = Math.floor(y / (image.height / directionLayers));
2851
+ const isReverse = layer % 2 === 1;
2852
+ const xNorm = isReverse ? (image.width - x) / image.width : x / image.width;
2853
+ directionValue = layer / directionLayers + xNorm / directionLayers;
2854
+ } else if (direction === "vertical") {
2855
+ const layer = Math.floor(x / (image.width / directionLayers));
2856
+ const isReverse = layer % 2 === 1;
2857
+ const yNorm = isReverse ? (image.height - y) / image.height : y / image.height;
2858
+ directionValue = layer / directionLayers + yNorm / directionLayers;
2859
+ } else if (direction === "top-to-bottom") {
2860
+ directionValue = y / image.height;
2861
+ } else if (direction === "diagonal-down") {
2862
+ directionValue = (x + y) / (image.width + image.height);
2863
+ } else {
2864
+ directionValue = (x + (image.height - y)) / (image.width + image.height);
2865
+ }
2866
+ burnMap[idx] = revealMode === "combined" ? burnMap[idx] * 0.6 + directionValue * 0.4 : directionValue;
2867
+ }
2868
+ let minVal = burnMap[0];
2869
+ let maxVal = burnMap[0];
2870
+ for (let i = 1; i < burnMap.length; i++) {
2871
+ if (burnMap[i] < minVal) minVal = burnMap[i];
2872
+ if (burnMap[i] > maxVal) maxVal = burnMap[i];
2873
+ }
2874
+ const range = maxVal - minVal;
2875
+ if (range > 0) {
2876
+ for (let i = 0; i < burnMap.length; i++) {
2877
+ burnMap[i] = (burnMap[i] - minVal) / range;
2878
+ }
2879
+ }
2880
+ }
2881
+ setPixelBurnMap(burnMap);
2882
+ burnMapGeneratedRef.current = true;
2883
+ } finally {
2884
+ setIsProcessing(false);
2885
+ }
2886
+ }, 0);
2887
+ }, [
2888
+ image,
2889
+ burnColorOrder,
2890
+ revealMode,
2891
+ direction,
2892
+ directionLayers
2893
+ ]);
2894
+ useEffect2(() => {
2895
+ if (!canvasRef.current || !image || !pixelBurnMap) return;
2896
+ const context = canvasRef.current.getContext("2d");
2897
+ if (!context) return;
2898
+ context.canvas.width = width;
2899
+ context.canvas.height = height;
2900
+ context.fillStyle = backgroundColor;
2901
+ context.fillRect(0, 0, width, height);
2902
+ const progress = Math.min(frame / revealDurationInFrames, 1);
2903
+ if (progress >= 1) {
2904
+ let sx2 = 0, sy2 = 0, sWidth2 = image.width, sHeight2 = image.height;
2905
+ if (fit === "cover") {
2906
+ const imgAspect = image.width / image.height;
2907
+ const canvasAspect = width / height;
2908
+ if (imgAspect > canvasAspect) {
2909
+ sWidth2 = image.height * canvasAspect;
2910
+ sx2 = (image.width - sWidth2) / 2;
2911
+ } else {
2912
+ sHeight2 = image.width / canvasAspect;
2913
+ sy2 = (image.height - sHeight2) / 2;
2914
+ }
2915
+ }
2916
+ context.drawImage(image, sx2, sy2, sWidth2, sHeight2, 0, 0, width, height);
2917
+ return;
2918
+ }
2919
+ const tempCanvas = document.createElement("canvas");
2920
+ tempCanvas.width = image.width;
2921
+ tempCanvas.height = image.height;
2922
+ const tempCtx = tempCanvas.getContext("2d");
2923
+ if (!tempCtx) return;
2924
+ tempCtx.drawImage(image, 0, 0);
2925
+ const imageData = tempCtx.getImageData(0, 0, image.width, image.height);
2926
+ const pixels = imageData.data;
2927
+ const transitionWidth = Math.max(
2928
+ 0.02,
2929
+ Math.min(0.15, 3 / (revealDurationInFrames / 100))
2930
+ );
2931
+ for (let i = 0; i < pixels.length; i += 4) {
2932
+ const pixelIndex = i / 4;
2933
+ const burnProgress = (progress - pixelBurnMap[pixelIndex]) / transitionWidth;
2934
+ pixels[i + 3] = Math.floor(
2935
+ pixels[i + 3] * Math.max(0, Math.min(1, burnProgress))
2936
+ );
2937
+ }
2938
+ tempCtx.putImageData(imageData, 0, 0);
2939
+ let sx = 0, sy = 0, sWidth = image.width, sHeight = image.height;
2940
+ if (fit === "cover") {
2941
+ const imgAspect = image.width / image.height;
2942
+ const canvasAspect = width / height;
2943
+ if (imgAspect > canvasAspect) {
2944
+ sWidth = image.height * canvasAspect;
2945
+ sx = (image.width - sWidth) / 2;
2946
+ } else {
2947
+ sHeight = image.width / canvasAspect;
2948
+ sy = (image.height - sHeight) / 2;
2949
+ }
2950
+ }
2951
+ context.drawImage(tempCanvas, sx, sy, sWidth, sHeight, 0, 0, width, height);
2952
+ }, [
2953
+ frame,
2954
+ image,
2955
+ width,
2956
+ height,
2957
+ pixelBurnMap,
2958
+ revealDurationInFrames,
2959
+ fit,
2960
+ backgroundColor
2961
+ ]);
2962
+ return /* @__PURE__ */ React16.createElement(Atom, { ref: canvasRef, data: { className: "w-full h-full" }, id });
2963
+ };
2964
+
2965
+ // src/components/effects/CanvasGlitchEffect.tsx
2966
+ import React17, { useEffect as useEffect3, useRef as useRef3, useState as useState3 } from "react";
2967
+ import { useCurrentFrame as useCurrentFrame6, useVideoConfig as useVideoConfig7 } from "remotion";
2968
+ import { z as z4 } from "zod";
2969
+ var CanvasGlitchEffectProps = z4.object({
2970
+ imageUrl: z4.string().url(),
2971
+ durationInFrames: z4.number().min(1),
2972
+ fit: z4.enum(["cover", "contain"]).default("cover"),
2973
+ backgroundColor: z4.string().default("rgba(0,0,0,0)"),
2974
+ glitchType: z4.enum(["rgb-shift", "slice", "corrupt", "static", "scan"]).default("rgb-shift"),
2975
+ intensity: z4.number().default(10).describe("Intensity of glitch effect"),
2976
+ frequency: z4.number().default(0.3).describe("How often glitches occur (0-1)"),
2977
+ continuous: z4.boolean().default(false).describe("Continuous glitch vs periodic"),
2978
+ glitchStartFrame: z4.number().default(0).describe("Frame to start glitching"),
2979
+ glitchEndFrame: z4.number().default(-1).describe("Frame to end glitching (-1 = duration)")
2980
+ });
2981
+ var CanvasGlitchEffect = ({ data, id }) => {
2982
+ const {
2983
+ imageUrl,
2984
+ durationInFrames,
2985
+ fit,
2986
+ backgroundColor,
2987
+ glitchType,
2988
+ intensity,
2989
+ frequency,
2990
+ continuous,
2991
+ glitchStartFrame,
2992
+ glitchEndFrame
2993
+ } = data;
2994
+ const frame = useCurrentFrame6();
2995
+ const { width, height } = useVideoConfig7();
2996
+ const canvasRef = useRef3(null);
2997
+ const [image, setImage] = useState3(null);
2998
+ useEffect3(() => {
2999
+ const img = new window.Image();
3000
+ img.crossOrigin = "Anonymous";
3001
+ img.src = imageUrl;
3002
+ img.onload = () => setImage(img);
3003
+ }, [imageUrl]);
3004
+ useEffect3(() => {
3005
+ if (!canvasRef.current || !image) return;
3006
+ const context = canvasRef.current.getContext("2d");
3007
+ if (!context) return;
3008
+ context.canvas.width = width;
3009
+ context.canvas.height = height;
3010
+ context.fillStyle = backgroundColor;
3011
+ context.fillRect(0, 0, width, height);
3012
+ const endFrame = glitchEndFrame === -1 ? durationInFrames : glitchEndFrame;
3013
+ const isInGlitchRange = frame >= glitchStartFrame && frame <= endFrame;
3014
+ const seed = Math.floor(frame / 3);
3015
+ const random = (seed * 9301 + 49297) % 233280 / 233280;
3016
+ const isGlitching = isInGlitchRange && (continuous || random < frequency);
3017
+ let sx = 0, sy = 0, sWidth = image.width, sHeight = image.height;
3018
+ if (fit === "cover") {
3019
+ const imgAspect = image.width / image.height;
3020
+ const canvasAspect = width / height;
3021
+ if (imgAspect > canvasAspect) {
3022
+ sWidth = image.height * canvasAspect;
3023
+ sx = (image.width - sWidth) / 2;
3024
+ } else {
3025
+ sHeight = image.width / canvasAspect;
3026
+ sy = (image.height - sHeight) / 2;
3027
+ }
3028
+ }
3029
+ if (!isGlitching) {
3030
+ context.drawImage(image, sx, sy, sWidth, sHeight, 0, 0, width, height);
3031
+ return;
3032
+ }
3033
+ if (glitchType === "rgb-shift") {
3034
+ const tempCanvas = document.createElement("canvas");
3035
+ tempCanvas.width = image.width;
3036
+ tempCanvas.height = image.height;
3037
+ const tempCtx = tempCanvas.getContext("2d");
3038
+ if (!tempCtx) return;
3039
+ tempCtx.drawImage(image, 0, 0);
3040
+ const imageData = tempCtx.getImageData(0, 0, image.width, image.height);
3041
+ const pixels = imageData.data;
3042
+ const shift = intensity * (random * 2 - 1);
3043
+ const redData = tempCtx.createImageData(image.width, image.height);
3044
+ const greenData = tempCtx.createImageData(image.width, image.height);
3045
+ const blueData = tempCtx.createImageData(image.width, image.height);
3046
+ for (let i = 0; i < pixels.length; i += 4) {
3047
+ redData.data[i] = pixels[i];
3048
+ redData.data[i + 3] = pixels[i + 3];
3049
+ greenData.data[i + 1] = pixels[i + 1];
3050
+ greenData.data[i + 3] = pixels[i + 3];
3051
+ blueData.data[i + 2] = pixels[i + 2];
3052
+ blueData.data[i + 3] = pixels[i + 3];
3053
+ }
3054
+ context.save();
3055
+ context.globalCompositeOperation = "screen";
3056
+ tempCtx.putImageData(redData, 0, 0);
3057
+ context.drawImage(
3058
+ tempCanvas,
3059
+ sx + shift,
3060
+ sy,
3061
+ sWidth,
3062
+ sHeight,
3063
+ shift,
3064
+ 0,
3065
+ width,
3066
+ height
3067
+ );
3068
+ tempCtx.putImageData(greenData, 0, 0);
3069
+ context.drawImage(
3070
+ tempCanvas,
3071
+ sx,
3072
+ sy,
3073
+ sWidth,
3074
+ sHeight,
3075
+ 0,
3076
+ 0,
3077
+ width,
3078
+ height
3079
+ );
3080
+ tempCtx.putImageData(blueData, 0, 0);
3081
+ context.drawImage(
3082
+ tempCanvas,
3083
+ sx - shift,
3084
+ sy,
3085
+ sWidth,
3086
+ sHeight,
3087
+ -shift,
3088
+ 0,
3089
+ width,
3090
+ height
3091
+ );
3092
+ context.restore();
3093
+ } else if (glitchType === "slice") {
3094
+ const sliceCount = 20;
3095
+ const sliceHeight = height / sliceCount;
3096
+ for (let i = 0; i < sliceCount; i++) {
3097
+ const offset = (random * 2 - 1) * intensity * (i % 2 === 0 ? 1 : -1);
3098
+ const sy_slice = sy + sHeight / sliceCount * i;
3099
+ const dy = sliceHeight * i;
3100
+ context.drawImage(
3101
+ image,
3102
+ sx,
3103
+ sy_slice,
3104
+ sWidth,
3105
+ sHeight / sliceCount,
3106
+ offset,
3107
+ dy,
3108
+ width,
3109
+ sliceHeight
3110
+ );
3111
+ }
3112
+ } else if (glitchType === "corrupt") {
3113
+ context.drawImage(image, sx, sy, sWidth, sHeight, 0, 0, width, height);
3114
+ const blockCount = Math.floor(intensity / 2);
3115
+ for (let i = 0; i < blockCount; i++) {
3116
+ const blockW = Math.random() * width * 0.3;
3117
+ const blockH = Math.random() * height * 0.2;
3118
+ const blockX = Math.random() * (width - blockW);
3119
+ const blockY = Math.random() * (height - blockH);
3120
+ const sourceX = Math.random() * (width - blockW);
3121
+ const sourceY = Math.random() * (height - blockH);
3122
+ try {
3123
+ const imgData = context.getImageData(
3124
+ sourceX,
3125
+ sourceY,
3126
+ blockW,
3127
+ blockH
3128
+ );
3129
+ context.putImageData(imgData, blockX, blockY);
3130
+ } catch (e) {
3131
+ }
3132
+ }
3133
+ } else if (glitchType === "static") {
3134
+ context.drawImage(image, sx, sy, sWidth, sHeight, 0, 0, width, height);
3135
+ const imageData = context.getImageData(0, 0, width, height);
3136
+ const pixels = imageData.data;
3137
+ for (let i = 0; i < pixels.length; i += 4) {
3138
+ if (Math.random() < intensity / 100) {
3139
+ const noise = Math.random() * 255;
3140
+ pixels[i] = noise;
3141
+ pixels[i + 1] = noise;
3142
+ pixels[i + 2] = noise;
3143
+ }
3144
+ }
3145
+ context.putImageData(imageData, 0, 0);
3146
+ } else if (glitchType === "scan") {
3147
+ context.drawImage(image, sx, sy, sWidth, sHeight, 0, 0, width, height);
3148
+ const scanY = frame * 5 % height;
3149
+ context.fillStyle = `rgba(255, 255, 255, ${intensity / 100})`;
3150
+ context.fillRect(0, scanY, width, 3);
3151
+ const distortY = Math.max(0, scanY - 10);
3152
+ const distortHeight = Math.min(20, height - distortY);
3153
+ if (distortHeight > 0) {
3154
+ try {
3155
+ const imgData = context.getImageData(
3156
+ 0,
3157
+ distortY,
3158
+ width,
3159
+ distortHeight
3160
+ );
3161
+ const shiftAmount = intensity * (random * 2 - 1);
3162
+ context.putImageData(imgData, shiftAmount, distortY);
3163
+ } catch (e) {
3164
+ }
3165
+ }
3166
+ }
3167
+ }, [
3168
+ frame,
3169
+ image,
3170
+ width,
3171
+ height,
3172
+ durationInFrames,
3173
+ fit,
3174
+ backgroundColor,
3175
+ glitchType,
3176
+ intensity,
3177
+ frequency,
3178
+ continuous,
3179
+ glitchStartFrame,
3180
+ glitchEndFrame
3181
+ ]);
3182
+ return /* @__PURE__ */ React17.createElement(Atom, { ref: canvasRef, data: { className: "w-full h-full" }, id });
3183
+ };
3184
+
3185
+ // src/components/effects/CanvasParticleEffect.tsx
3186
+ import React18, { useEffect as useEffect4, useRef as useRef4, useState as useState4 } from "react";
3187
+ import { useCurrentFrame as useCurrentFrame7, useVideoConfig as useVideoConfig8 } from "remotion";
3188
+ import { z as z5 } from "zod";
3189
+ var CanvasParticleEffectProps = z5.object({
3190
+ imageUrl: z5.string().url(),
3191
+ revealDurationInFrames: z5.number().min(1),
3192
+ fit: z5.enum(["cover", "contain"]).default("cover"),
3193
+ backgroundColor: z5.string().default("rgba(0,0,0,0)"),
3194
+ particleCount: z5.number().default(2e3).describe("Number of particles"),
3195
+ particleSize: z5.number().default(3).describe("Size of each particle"),
3196
+ particleEffect: z5.enum(["assemble", "disassemble", "explode", "pixelate"]).default("assemble"),
3197
+ assembleFrom: z5.enum(["center", "edges", "random", "bottom"]).default("random"),
3198
+ speed: z5.number().default(1).describe("Animation speed multiplier"),
3199
+ rotation: z5.boolean().default(false).describe("Add rotation to particles")
3200
+ });
3201
+ var CanvasParticleEffect = ({ data, id }) => {
3202
+ const {
3203
+ imageUrl,
3204
+ revealDurationInFrames,
3205
+ fit,
3206
+ backgroundColor,
3207
+ particleCount,
3208
+ particleSize,
3209
+ particleEffect,
3210
+ assembleFrom,
3211
+ speed,
3212
+ rotation
3213
+ } = data;
3214
+ const frame = useCurrentFrame7();
3215
+ const { width, height } = useVideoConfig8();
3216
+ const canvasRef = useRef4(null);
3217
+ const [image, setImage] = useState4(null);
3218
+ const [particles, setParticles] = useState4(null);
3219
+ useEffect4(() => {
3220
+ const img = new window.Image();
3221
+ img.crossOrigin = "Anonymous";
3222
+ img.src = imageUrl;
3223
+ img.onload = () => setImage(img);
3224
+ }, [imageUrl]);
3225
+ useEffect4(() => {
3226
+ if (!image) return;
3227
+ const canvas = document.createElement("canvas");
3228
+ const ctx = canvas.getContext("2d");
3229
+ if (!ctx) return;
3230
+ canvas.width = image.width;
3231
+ canvas.height = image.height;
3232
+ ctx.drawImage(image, 0, 0);
3233
+ const imageData = ctx.getImageData(0, 0, image.width, image.height);
3234
+ const pixels = imageData.data;
3235
+ const particleArray = [];
3236
+ const step = Math.floor(
3237
+ Math.sqrt(image.width * image.height / particleCount)
3238
+ );
3239
+ for (let y = 0; y < image.height; y += step) {
3240
+ for (let x = 0; x < image.width; x += step) {
3241
+ const i = (y * image.width + x) * 4;
3242
+ const [r, g, b, a] = [
3243
+ pixels[i],
3244
+ pixels[i + 1],
3245
+ pixels[i + 2],
3246
+ pixels[i + 3]
3247
+ ];
3248
+ if (a > 128) {
3249
+ const targetX = x;
3250
+ const targetY = y;
3251
+ let startX = targetX, startY = targetY;
3252
+ if (particleEffect === "assemble") {
3253
+ if (assembleFrom === "center") {
3254
+ startX = image.width / 2;
3255
+ startY = image.height / 2;
3256
+ } else if (assembleFrom === "edges") {
3257
+ const edge = Math.floor(Math.random() * 4);
3258
+ if (edge === 0) {
3259
+ startX = 0;
3260
+ startY = Math.random() * image.height;
3261
+ } else if (edge === 1) {
3262
+ startX = image.width;
3263
+ startY = Math.random() * image.height;
3264
+ } else if (edge === 2) {
3265
+ startX = Math.random() * image.width;
3266
+ startY = 0;
3267
+ } else {
3268
+ startX = Math.random() * image.width;
3269
+ startY = image.height;
3270
+ }
3271
+ } else if (assembleFrom === "bottom") {
3272
+ startX = targetX;
3273
+ startY = image.height + Math.random() * 200;
3274
+ } else {
3275
+ startX = Math.random() * image.width;
3276
+ startY = Math.random() * image.height;
3277
+ }
3278
+ }
3279
+ particleArray.push({
3280
+ x: startX,
3281
+ y: startY,
3282
+ targetX,
3283
+ targetY,
3284
+ color: `rgba(${r},${g},${b},${a / 255})`,
3285
+ startX,
3286
+ startY,
3287
+ angle: Math.random() * Math.PI * 2
3288
+ });
3289
+ }
3290
+ }
3291
+ }
3292
+ setParticles(particleArray);
3293
+ }, [image, particleCount, particleEffect, assembleFrom]);
3294
+ useEffect4(() => {
3295
+ if (!canvasRef.current || !image || !particles) return;
3296
+ const context = canvasRef.current.getContext("2d");
3297
+ if (!context) return;
3298
+ context.canvas.width = width;
3299
+ context.canvas.height = height;
3300
+ context.fillStyle = backgroundColor;
3301
+ context.fillRect(0, 0, width, height);
3302
+ const progress = Math.min(frame / revealDurationInFrames * speed, 1);
3303
+ if (progress >= 1 && particleEffect === "assemble") {
3304
+ const scaleX2 = width / image.width;
3305
+ const scaleY2 = height / image.height;
3306
+ let scale2 = scaleX2;
3307
+ let offsetX2 = 0, offsetY2 = 0;
3308
+ if (fit === "cover") {
3309
+ scale2 = Math.max(scaleX2, scaleY2);
3310
+ offsetX2 = (width - image.width * scale2) / 2;
3311
+ offsetY2 = (height - image.height * scale2) / 2;
3312
+ } else {
3313
+ scale2 = Math.min(scaleX2, scaleY2);
3314
+ offsetX2 = (width - image.width * scale2) / 2;
3315
+ offsetY2 = (height - image.height * scale2) / 2;
3316
+ }
3317
+ context.save();
3318
+ context.translate(offsetX2, offsetY2);
3319
+ context.scale(scale2, scale2);
3320
+ context.drawImage(image, 0, 0);
3321
+ context.restore();
3322
+ return;
3323
+ }
3324
+ const easeProgress = particleEffect === "explode" ? progress * progress * (3 - 2 * progress) : 1 - Math.pow(1 - progress, 3);
3325
+ const scaleX = width / image.width;
3326
+ const scaleY = height / image.height;
3327
+ let scale = scaleX;
3328
+ let offsetX = 0, offsetY = 0;
3329
+ if (fit === "cover") {
3330
+ scale = Math.max(scaleX, scaleY);
3331
+ offsetX = (width - image.width * scale) / 2;
3332
+ offsetY = (height - image.height * scale) / 2;
3333
+ } else {
3334
+ scale = Math.min(scaleX, scaleY);
3335
+ offsetX = (width - image.width * scale) / 2;
3336
+ offsetY = (height - image.height * scale) / 2;
3337
+ }
3338
+ particles.forEach((particle) => {
3339
+ let x, y;
3340
+ if (particleEffect === "assemble") {
3341
+ x = particle.startX + (particle.targetX - particle.startX) * easeProgress;
3342
+ y = particle.startY + (particle.targetY - particle.startY) * easeProgress;
3343
+ } else if (particleEffect === "disassemble") {
3344
+ const reverseProgress = 1 - easeProgress;
3345
+ x = particle.targetX + (particle.startX - particle.targetX) * (1 - reverseProgress);
3346
+ y = particle.targetY + (particle.startY - particle.targetY) * (1 - reverseProgress);
3347
+ } else if (particleEffect === "explode") {
3348
+ const dx = particle.targetX - image.width / 2;
3349
+ const dy = particle.targetY - image.height / 2;
3350
+ const dist = Math.sqrt(dx * dx + dy * dy);
3351
+ const explosionDist = dist * easeProgress * 3;
3352
+ x = particle.targetX + dx / dist * explosionDist;
3353
+ y = particle.targetY + dy / dist * explosionDist;
3354
+ } else {
3355
+ x = particle.targetX;
3356
+ y = particle.targetY;
3357
+ }
3358
+ const finalX = x * scale + offsetX;
3359
+ const finalY = y * scale + offsetY;
3360
+ context.save();
3361
+ context.translate(finalX, finalY);
3362
+ if (rotation && particleEffect !== "pixelate") {
3363
+ context.rotate(particle.angle * easeProgress);
3364
+ }
3365
+ const size = particleEffect === "pixelate" ? particleSize * (1 + (1 - easeProgress) * 3) : particleSize;
3366
+ context.fillStyle = particle.color;
3367
+ context.fillRect(-size / 2, -size / 2, size, size);
3368
+ context.restore();
3369
+ });
3370
+ }, [
3371
+ frame,
3372
+ image,
3373
+ width,
3374
+ height,
3375
+ particles,
3376
+ revealDurationInFrames,
3377
+ fit,
3378
+ backgroundColor,
3379
+ particleSize,
3380
+ particleEffect,
3381
+ speed,
3382
+ rotation
3383
+ ]);
3384
+ return /* @__PURE__ */ React18.createElement(Atom, { ref: canvasRef, data: { className: "w-full h-full" }, id });
3385
+ };
3386
+
3387
+ // src/components/effects/GenericPresets.ts
3388
+ var fadeInPreset = [
3389
+ { key: "opacity", val: 0, prog: 0 },
3390
+ { key: "opacity", val: 1, prog: 1 }
3391
+ ];
3392
+ var fadeOutPreset = [
3393
+ { key: "opacity", val: 1, prog: 0 },
3394
+ { key: "opacity", val: 0, prog: 1 }
3395
+ ];
3396
+ var scaleInPreset = [
3397
+ { key: "scale", val: 0, prog: 0 },
3398
+ { key: "scale", val: 1, prog: 1 }
3399
+ ];
3400
+ var scaleOutPreset = [
3401
+ { key: "scale", val: 1, prog: 0 },
3402
+ { key: "scale", val: 0, prog: 1 }
3403
+ ];
3404
+ var slideInLeftPreset = [
3405
+ { key: "translateX", val: -100, prog: 0 },
3406
+ { key: "translateX", val: 0, prog: 1 }
3407
+ ];
3408
+ var slideInRightPreset = [
3409
+ { key: "translateX", val: 100, prog: 0 },
3410
+ { key: "translateX", val: 0, prog: 1 }
3411
+ ];
3412
+ var slideInTopPreset = [
3413
+ { key: "translateY", val: -100, prog: 0 },
3414
+ { key: "translateY", val: 0, prog: 1 }
3415
+ ];
3416
+ var slideInBottomPreset = [
3417
+ { key: "translateY", val: 100, prog: 0 },
3418
+ { key: "translateY", val: 0, prog: 1 }
3419
+ ];
3420
+ var bouncePreset = [
3421
+ { key: "scale", val: 0, prog: 0 },
3422
+ { key: "scale", val: 1.2, prog: 0.6 },
3423
+ { key: "scale", val: 1, prog: 1 }
3424
+ ];
3425
+ var pulsePreset = [
3426
+ { key: "scale", val: 1, prog: 0 },
3427
+ { key: "scale", val: 1.1, prog: 0.5 },
3428
+ { key: "scale", val: 1, prog: 1 }
3429
+ ];
3430
+ var rotateInPreset = [
3431
+ { key: "rotate", val: -180, prog: 0 },
3432
+ { key: "rotate", val: 0, prog: 1 }
3433
+ ];
3434
+ var blurInPreset = [
3435
+ { key: "blur", val: 10, prog: 0 },
3436
+ { key: "blur", val: 0, prog: 1 }
3437
+ ];
3438
+ var fadeInScalePreset = [
3439
+ { key: "opacity", val: 0, prog: 0 },
3440
+ { key: "opacity", val: 1, prog: 1 },
3441
+ { key: "scale", val: 0.8, prog: 0 },
3442
+ { key: "scale", val: 1, prog: 1 }
3443
+ ];
3444
+ var slideInFadePreset = [
3445
+ { key: "translateX", val: -50, prog: 0 },
3446
+ { key: "translateX", val: 0, prog: 1 },
3447
+ { key: "opacity", val: 0, prog: 0 },
3448
+ { key: "opacity", val: 1, prog: 1 }
3449
+ ];
3450
+ var slideInLeftStringPreset = [
3451
+ { key: "translateX", val: "-100px", prog: 0 },
3452
+ { key: "translateX", val: "0px", prog: 1 }
3453
+ ];
3454
+ var slideInRightStringPreset = [
3455
+ { key: "translateX", val: "100px", prog: 0 },
3456
+ { key: "translateX", val: "0px", prog: 1 }
3457
+ ];
3458
+ var slideInTopStringPreset = [
3459
+ { key: "translateY", val: "-100px", prog: 0 },
3460
+ { key: "translateY", val: "0px", prog: 1 }
3461
+ ];
3462
+ var slideInBottomStringPreset = [
3463
+ { key: "translateY", val: "100px", prog: 0 },
3464
+ { key: "translateY", val: "0px", prog: 1 }
3465
+ ];
3466
+ var rotateInStringPreset = [
3467
+ { key: "rotate", val: "-180deg", prog: 0 },
3468
+ { key: "rotate", val: "0deg", prog: 1 }
3469
+ ];
3470
+ var blurInStringPreset = [
3471
+ { key: "blur", val: "10px", prog: 0 },
3472
+ { key: "blur", val: "0px", prog: 1 }
3473
+ ];
3474
+ var scaleInStringPreset = [
3475
+ { key: "scale", val: 0, prog: 0 },
3476
+ { key: "scale", val: 1, prog: 1 }
3477
+ ];
3478
+ var slideInLeftResponsivePreset = [
3479
+ { key: "translateX", val: "-50vw", prog: 0 },
3480
+ { key: "translateX", val: "0vw", prog: 1 }
3481
+ ];
3482
+ var slideInTopResponsivePreset = [
3483
+ { key: "translateY", val: "-50vh", prog: 0 },
3484
+ { key: "translateY", val: "0vh", prog: 1 }
3485
+ ];
3486
+ var backgroundColorPreset = [
3487
+ { key: "backgroundColor", val: "#ff0000", prog: 0 },
3488
+ { key: "backgroundColor", val: "#0000ff", prog: 1 }
3489
+ ];
3490
+ var borderRadiusPreset = [
3491
+ { key: "borderRadius", val: "0px", prog: 0 },
3492
+ { key: "borderRadius", val: "50px", prog: 1 }
3493
+ ];
3494
+ var boxShadowPreset = [
3495
+ { key: "boxShadow", val: "0px 0px 0px rgba(0,0,0,0)", prog: 0 },
3496
+ { key: "boxShadow", val: "10px 10px 20px rgba(0,0,0,0.5)", prog: 1 }
3497
+ ];
3498
+ var fontSizePreset = [
3499
+ { key: "fontSize", val: "12px", prog: 0 },
3500
+ { key: "fontSize", val: "24px", prog: 1 }
3501
+ ];
3502
+ var letterSpacingPreset = [
3503
+ { key: "letterSpacing", val: "0px", prog: 0 },
3504
+ { key: "letterSpacing", val: "5px", prog: 1 }
3505
+ ];
3506
+ var lineHeightPreset = [
3507
+ { key: "lineHeight", val: "1", prog: 0 },
3508
+ { key: "lineHeight", val: "2", prog: 1 }
3509
+ ];
3510
+ var textShadowPreset = [
3511
+ { key: "textShadow", val: "0px 0px 0px rgba(0,0,0,0)", prog: 0 },
3512
+ { key: "textShadow", val: "2px 2px 4px rgba(0,0,0,0.5)", prog: 1 }
3513
+ ];
3514
+ var widthPreset = [
3515
+ { key: "width", val: "0px", prog: 0 },
3516
+ { key: "width", val: "100%", prog: 1 }
3517
+ ];
3518
+ var heightPreset = [
3519
+ { key: "height", val: "0px", prog: 0 },
3520
+ { key: "height", val: "100%", prog: 1 }
3521
+ ];
3522
+ var marginPreset = [
3523
+ { key: "margin", val: "0px", prog: 0 },
3524
+ { key: "margin", val: "20px", prog: 1 }
3525
+ ];
3526
+ var paddingPreset = [
3527
+ { key: "padding", val: "0px", prog: 0 },
3528
+ { key: "padding", val: "20px", prog: 1 }
3529
+ ];
3530
+ var morphingCardPreset = [
3531
+ { key: "borderRadius", val: "0px", prog: 0 },
3532
+ { key: "borderRadius", val: "20px", prog: 0.5 },
3533
+ { key: "borderRadius", val: "50px", prog: 1 },
3534
+ { key: "boxShadow", val: "0px 0px 0px rgba(0,0,0,0)", prog: 0 },
3535
+ { key: "boxShadow", val: "0px 10px 30px rgba(0,0,0,0.3)", prog: 1 },
3536
+ { key: "backgroundColor", val: "#ffffff", prog: 0 },
3537
+ { key: "backgroundColor", val: "#f0f0f0", prog: 1 }
3538
+ ];
3539
+ var textRevealPreset = [
3540
+ { key: "opacity", val: 0, prog: 0 },
3541
+ { key: "opacity", val: 1, prog: 1 },
3542
+ { key: "letterSpacing", val: "10px", prog: 0 },
3543
+ { key: "letterSpacing", val: "0px", prog: 1 },
3544
+ { key: "textShadow", val: "0px 0px 0px rgba(0,0,0,0)", prog: 0 },
3545
+ { key: "textShadow", val: "2px 2px 4px rgba(0,0,0,0.5)", prog: 1 }
3546
+ ];
3547
+ var GenericEffectPresets = {
3548
+ fadeInPreset,
3549
+ fadeOutPreset,
3550
+ scaleInPreset,
3551
+ scaleOutPreset,
3552
+ slideInLeftPreset,
3553
+ slideInRightPreset,
3554
+ slideInTopPreset,
3555
+ slideInBottomPreset,
3556
+ bouncePreset,
3557
+ pulsePreset,
3558
+ rotateInPreset,
3559
+ blurInPreset,
3560
+ fadeInScalePreset,
3561
+ slideInFadePreset,
3562
+ // String-based presets
3563
+ slideInLeftStringPreset,
3564
+ slideInRightStringPreset,
3565
+ slideInTopStringPreset,
3566
+ slideInBottomStringPreset,
3567
+ rotateInStringPreset,
3568
+ blurInStringPreset,
3569
+ scaleInStringPreset,
3570
+ slideInLeftResponsivePreset,
3571
+ slideInTopResponsivePreset,
3572
+ // Custom CSS property presets
3573
+ backgroundColorPreset,
3574
+ borderRadiusPreset,
3575
+ boxShadowPreset,
3576
+ fontSizePreset,
3577
+ letterSpacingPreset,
3578
+ lineHeightPreset,
3579
+ textShadowPreset,
3580
+ widthPreset,
3581
+ heightPreset,
3582
+ marginPreset,
3583
+ paddingPreset,
3584
+ morphingCardPreset,
3585
+ textRevealPreset
3586
+ };
3587
+
3588
+ // src/components/effects/index.ts
3589
+ registerEffect(config2.displayName, BlurEffect, config2);
3590
+ registerEffect(config3.displayName, LoopEffect, config3);
3591
+ registerEffect(config4.displayName, PanEffect, config4);
3592
+ registerEffect(config5.displayName, ZoomEffect, config5);
3593
+ registerEffect("generic", UniversalEffect, config);
3594
+ registerEffect(config6.displayName, ShakeEffect, config6);
3595
+ registerEffect(
3596
+ config7.displayName,
3597
+ StretchEffect,
3598
+ config7
3599
+ );
3600
+ registerEffect(
3601
+ config8.displayName,
3602
+ WaveformEffect,
3603
+ config8
3604
+ );
3605
+ registerEffect("CanvasWipeReveal", CanvasWipeReveal);
3606
+ registerEffect("CanvasContentAwareReveal", CanvasContentAwareReveal);
3607
+ registerEffect("CanvasParticleEffect", CanvasParticleEffect);
3608
+ registerEffect("CanvasGlitchEffect", CanvasGlitchEffect);
3609
+
3610
+ // src/components/layouts/BaseLayout.tsx
3611
+ var Layout = ({ id, children, data, context }) => {
3612
+ const { containerProps = {}, childrenProps = [], repeatChildrenProps = {} } = data;
3613
+ const overrideStyles = useAnimatedStyles(id);
3614
+ const childrenArray = Children.toArray(children);
3615
+ const enhancedStyle = useMemo9(
3616
+ () => ({
3617
+ ...!context?.boundaries?.reset ? context?.boundaries : {},
3618
+ ...containerProps.style,
1974
3619
  ...overrideStyles
1975
3620
  }),
1976
3621
  [
@@ -1981,7 +3626,7 @@ var Layout = ({ id, children, data, context }) => {
1981
3626
  );
1982
3627
  if (Object.keys(repeatChildrenProps).length <= 0 && childrenProps.length <= 0) {
1983
3628
  if (data.isAbsoluteFill) {
1984
- return /* @__PURE__ */ React13.createElement(
3629
+ return /* @__PURE__ */ React19.createElement(
1985
3630
  AbsoluteFill3,
1986
3631
  {
1987
3632
  ...containerProps,
@@ -1990,25 +3635,25 @@ var Layout = ({ id, children, data, context }) => {
1990
3635
  childrenArray
1991
3636
  );
1992
3637
  }
1993
- return /* @__PURE__ */ React13.createElement(
3638
+ return /* @__PURE__ */ React19.createElement(
1994
3639
  "div",
1995
3640
  {
1996
3641
  id,
1997
3642
  ...containerProps,
1998
3643
  style: enhancedStyle
1999
3644
  },
2000
- childrenArray.map((child, index) => /* @__PURE__ */ React13.createElement(React13.Fragment, { key: index }, child))
3645
+ childrenArray.map((child, index) => /* @__PURE__ */ React19.createElement(React19.Fragment, { key: index }, child))
2001
3646
  );
2002
3647
  }
2003
3648
  if (data.isAbsoluteFill) {
2004
- return /* @__PURE__ */ React13.createElement(
3649
+ return /* @__PURE__ */ React19.createElement(
2005
3650
  AbsoluteFill3,
2006
3651
  {
2007
3652
  id,
2008
3653
  ...containerProps,
2009
3654
  style: enhancedStyle
2010
3655
  },
2011
- childrenArray.map((child, index) => /* @__PURE__ */ React13.createElement(
3656
+ childrenArray.map((child, index) => /* @__PURE__ */ React19.createElement(
2012
3657
  "div",
2013
3658
  {
2014
3659
  key: index,
@@ -2018,14 +3663,14 @@ var Layout = ({ id, children, data, context }) => {
2018
3663
  ))
2019
3664
  );
2020
3665
  }
2021
- return /* @__PURE__ */ React13.createElement(
3666
+ return /* @__PURE__ */ React19.createElement(
2022
3667
  "div",
2023
3668
  {
2024
3669
  id,
2025
3670
  ...containerProps,
2026
3671
  style: enhancedStyle
2027
3672
  },
2028
- childrenArray.map((child, index) => /* @__PURE__ */ React13.createElement(
3673
+ childrenArray.map((child, index) => /* @__PURE__ */ React19.createElement(
2029
3674
  "div",
2030
3675
  {
2031
3676
  key: index,
@@ -2035,7 +3680,7 @@ var Layout = ({ id, children, data, context }) => {
2035
3680
  ))
2036
3681
  );
2037
3682
  };
2038
- var config8 = {
3683
+ var config10 = {
2039
3684
  displayName: "BaseLayout",
2040
3685
  type: "layout",
2041
3686
  isInnerSequence: false
@@ -2043,17 +3688,17 @@ var config8 = {
2043
3688
 
2044
3689
  // src/components/layouts/index.ts
2045
3690
  registerComponent(
2046
- config8.displayName,
3691
+ config10.displayName,
2047
3692
  Layout,
2048
3693
  "layout",
2049
- config8
3694
+ config10
2050
3695
  );
2051
3696
 
2052
3697
  // src/components/atoms/ShapeAtom.tsx
2053
- import React14 from "react";
2054
- import { Easing as Easing4, interpolate as interpolate4, useCurrentFrame as useCurrentFrame4 } from "remotion";
2055
- var Atom = ({ data }) => {
2056
- const frame = useCurrentFrame4();
3698
+ import React20 from "react";
3699
+ import { Easing as Easing4, interpolate as interpolate4, useCurrentFrame as useCurrentFrame8 } from "remotion";
3700
+ var Atom2 = ({ data }) => {
3701
+ const frame = useCurrentFrame8();
2057
3702
  const { shape, color, rotation, style } = data;
2058
3703
  const rotationStyle = rotation ? {
2059
3704
  transform: `rotate(${interpolate4(
@@ -2075,22 +3720,22 @@ var Atom = ({ data }) => {
2075
3720
  };
2076
3721
  switch (shape) {
2077
3722
  case "circle":
2078
- return /* @__PURE__ */ React14.createElement("div", { style: { ...baseStyle, backgroundColor: color, borderRadius: "50%" } });
3723
+ return /* @__PURE__ */ React20.createElement("div", { style: { ...baseStyle, backgroundColor: color, borderRadius: "50%" } });
2079
3724
  case "rectangle":
2080
- return /* @__PURE__ */ React14.createElement("div", { style: { ...baseStyle, backgroundColor: color } });
3725
+ return /* @__PURE__ */ React20.createElement("div", { style: { ...baseStyle, backgroundColor: color } });
2081
3726
  default:
2082
3727
  return null;
2083
3728
  }
2084
3729
  };
2085
- var config9 = {
3730
+ var config11 = {
2086
3731
  displayName: "ShapeAtom",
2087
3732
  type: "atom",
2088
3733
  isInnerSequence: false
2089
3734
  };
2090
3735
 
2091
3736
  // src/components/atoms/ImageAtom.tsx
2092
- import React15, { useMemo as useMemo8, useState, useEffect } from "react";
2093
- import { continueRender, delayRender, Img, staticFile } from "remotion";
3737
+ import React21, { useMemo as useMemo10, useState as useState5, useEffect as useEffect5 } from "react";
3738
+ import { continueRender, delayRender, Img, staticFile as staticFile2 } from "remotion";
2094
3739
  var CORS_PROXIES = [
2095
3740
  "https://thingproxy.freeboard.io/fetch/",
2096
3741
  "https://api.allorigins.win/raw?url=",
@@ -2100,11 +3745,11 @@ var getCorsProxyUrl = (url) => {
2100
3745
  return `${CORS_PROXIES[0]}${encodeURIComponent(url)}`;
2101
3746
  };
2102
3747
  var useImageSource = (src, proxySrc) => {
2103
- const [imageSource, setImageSource] = useState(src);
2104
- const [isLoading, setIsLoading] = useState(false);
2105
- const [hasError, setHasError] = useState(false);
2106
- const [handle] = useState(() => delayRender("Loading image"));
2107
- useEffect(() => {
3748
+ const [imageSource, setImageSource] = useState5(src);
3749
+ const [isLoading, setIsLoading] = useState5(false);
3750
+ const [hasError, setHasError] = useState5(false);
3751
+ const [handle] = useState5(() => delayRender("Loading image"));
3752
+ useEffect5(() => {
2108
3753
  if (!src.startsWith("http")) {
2109
3754
  setImageSource(src);
2110
3755
  continueRender(handle);
@@ -2140,20 +3785,20 @@ var useImageSource = (src, proxySrc) => {
2140
3785
  }, [src, proxySrc, handle]);
2141
3786
  return { imageSource, isLoading, hasError };
2142
3787
  };
2143
- var Atom2 = ({ data, id }) => {
3788
+ var Atom3 = ({ data, id }) => {
2144
3789
  const overrideStyles = useAnimatedStyles(id);
2145
3790
  const { imageSource, isLoading, hasError } = useImageSource(data.src, data.proxySrc);
2146
- const source = useMemo8(() => {
3791
+ const source = useMemo10(() => {
2147
3792
  if (data.src.startsWith("http")) {
2148
3793
  return imageSource;
2149
3794
  }
2150
- return staticFile(data.src);
3795
+ return staticFile2(data.src);
2151
3796
  }, [data.src, imageSource]);
2152
- const enhancedStyle = useMemo8(() => ({
3797
+ const enhancedStyle = useMemo10(() => ({
2153
3798
  ...data.style,
2154
3799
  ...overrideStyles
2155
3800
  }), [data.style, overrideStyles, isLoading, hasError]);
2156
- return /* @__PURE__ */ React15.createElement(
3801
+ return /* @__PURE__ */ React21.createElement(
2157
3802
  Img,
2158
3803
  {
2159
3804
  className: data.className,
@@ -2167,18 +3812,18 @@ var Atom2 = ({ data, id }) => {
2167
3812
  }
2168
3813
  );
2169
3814
  };
2170
- var config10 = {
3815
+ var config12 = {
2171
3816
  displayName: "ImageAtom",
2172
3817
  type: "atom",
2173
3818
  isInnerSequence: false
2174
3819
  };
2175
3820
 
2176
3821
  // src/components/atoms/TextAtom.tsx
2177
- import React16, { useEffect as useEffect3, useMemo as useMemo9, useState as useState3 } from "react";
3822
+ import React22, { useEffect as useEffect7, useMemo as useMemo11, useState as useState7 } from "react";
2178
3823
  import { delayRender as delayRender3, continueRender as continueRender3 } from "remotion";
2179
3824
 
2180
3825
  // src/hooks/useFontLoader.ts
2181
- import { useState as useState2, useEffect as useEffect2, useCallback } from "react";
3826
+ import { useState as useState6, useEffect as useEffect6, useCallback } from "react";
2182
3827
  import { delayRender as delayRender2, continueRender as continueRender2 } from "remotion";
2183
3828
 
2184
3829
  // src/utils/fontUtils.ts
@@ -2320,7 +3965,7 @@ var getNormalizedFontName = (fontFamily) => {
2320
3965
 
2321
3966
  // src/hooks/useFontLoader.ts
2322
3967
  var useFontLoader = (options = {}) => {
2323
- const [state, setState] = useState2({
3968
+ const [state, setState] = useState6({
2324
3969
  loadedFonts: /* @__PURE__ */ new Map(),
2325
3970
  loadingFonts: /* @__PURE__ */ new Set(),
2326
3971
  errorFonts: /* @__PURE__ */ new Map()
@@ -2479,14 +4124,14 @@ var useFontLoader = (options = {}) => {
2479
4124
  };
2480
4125
  var useFont = (fontFamily, options = {}) => {
2481
4126
  const { loadFont, isFontReady, getFontFamily, getFontError, ...rest } = useFontLoader(options);
2482
- const [isLoaded, setIsLoaded] = useState2(false);
2483
- const [error, setError] = useState2(null);
2484
- const [renderHandle] = useState2(
4127
+ const [isLoaded, setIsLoaded] = useState6(false);
4128
+ const [error, setError] = useState6(null);
4129
+ const [renderHandle] = useState6(
2485
4130
  () => delayRender2(`Loading font: ${fontFamily}`)
2486
4131
  );
2487
4132
  const initialFontFamily = getFontFamily(fontFamily, options) || `"${fontFamily}", sans-serif`;
2488
- const [fontFamilyValue, setFontFamilyValue] = useState2(initialFontFamily);
2489
- useEffect2(() => {
4133
+ const [fontFamilyValue, setFontFamilyValue] = useState6(initialFontFamily);
4134
+ useEffect6(() => {
2490
4135
  const loadFontAsync = async () => {
2491
4136
  try {
2492
4137
  const cssValue = await loadFont(fontFamily, options);
@@ -2521,10 +4166,10 @@ var useFont = (fontFamily, options = {}) => {
2521
4166
  };
2522
4167
 
2523
4168
  // src/components/atoms/TextAtom.tsx
2524
- var Atom3 = ({ id, data }) => {
4169
+ var Atom4 = ({ id, data }) => {
2525
4170
  const overrideStyles = useAnimatedStyles(id);
2526
- const [isFontLoading, setIsFontLoading] = useState3(false);
2527
- const [renderHandle] = useState3(
4171
+ const [isFontLoading, setIsFontLoading] = useState7(false);
4172
+ const [renderHandle] = useState7(
2528
4173
  () => delayRender3(`Loading font: ${data.font?.family}`)
2529
4174
  );
2530
4175
  const { isLoaded, error, isReady, fontFamily } = useFont(
@@ -2544,7 +4189,7 @@ var Atom3 = ({ id, data }) => {
2544
4189
  }
2545
4190
  }
2546
4191
  );
2547
- useEffect3(() => {
4192
+ useEffect7(() => {
2548
4193
  if (data.font?.family) {
2549
4194
  if (isReady || isLoaded) {
2550
4195
  setIsFontLoading(false);
@@ -2553,7 +4198,7 @@ var Atom3 = ({ id, data }) => {
2553
4198
  }
2554
4199
  }
2555
4200
  }, [data.font, isReady, isLoaded, error]);
2556
- const enhancedStyle = useMemo9(() => {
4201
+ const enhancedStyle = useMemo11(() => {
2557
4202
  const baseStyle = {
2558
4203
  fontFamily,
2559
4204
  ...data.style
@@ -2574,12 +4219,12 @@ var Atom3 = ({ id, data }) => {
2574
4219
  };
2575
4220
  }, [fontFamily, data.style, data.gradient, overrideStyles]);
2576
4221
  if (isFontLoading && data.loadingState?.showLoadingIndicator) {
2577
- return /* @__PURE__ */ React16.createElement("div", { style: enhancedStyle, className: data.className }, /* @__PURE__ */ React16.createElement("span", { style: data.loadingState.loadingStyle }, data.loadingState.loadingText || "Loading..."));
4222
+ return /* @__PURE__ */ React22.createElement("div", { style: enhancedStyle, className: data.className }, /* @__PURE__ */ React22.createElement("span", { style: data.loadingState.loadingStyle }, data.loadingState.loadingText || "Loading..."));
2578
4223
  }
2579
4224
  if (error && data.errorState?.showErrorIndicator) {
2580
- return /* @__PURE__ */ React16.createElement("div", { style: enhancedStyle, className: data.className }, /* @__PURE__ */ React16.createElement("span", { style: data.errorState.errorStyle }, data.errorState.errorText || data.text));
4225
+ return /* @__PURE__ */ React22.createElement("div", { style: enhancedStyle, className: data.className }, /* @__PURE__ */ React22.createElement("span", { style: data.errorState.errorStyle }, data.errorState.errorText || data.text));
2581
4226
  }
2582
- return /* @__PURE__ */ React16.createElement(
4227
+ return /* @__PURE__ */ React22.createElement(
2583
4228
  "div",
2584
4229
  {
2585
4230
  style: enhancedStyle,
@@ -2592,59 +4237,59 @@ var Atom3 = ({ id, data }) => {
2592
4237
  data.text
2593
4238
  );
2594
4239
  };
2595
- var config11 = {
4240
+ var config13 = {
2596
4241
  displayName: "TextAtom",
2597
4242
  type: "atom",
2598
4243
  isInnerSequence: false
2599
4244
  };
2600
4245
 
2601
4246
  // src/components/atoms/VideoAtom.tsx
2602
- import React17, { useMemo as useMemo10 } from "react";
2603
- import { staticFile as staticFile2, useCurrentFrame as useCurrentFrame5, useVideoConfig as useVideoConfig5, OffthreadVideo, Loop as Loop2 } from "remotion";
2604
- import { z } from "zod";
2605
- var VideoAtomDataProps = z.object({
2606
- src: z.string(),
4247
+ import React23, { useMemo as useMemo12 } from "react";
4248
+ import { staticFile as staticFile3, useCurrentFrame as useCurrentFrame9, useVideoConfig as useVideoConfig9, OffthreadVideo, Loop as Loop2 } from "remotion";
4249
+ import { z as z6 } from "zod";
4250
+ var VideoAtomDataProps = z6.object({
4251
+ src: z6.string(),
2607
4252
  // Video source URL
2608
- srcDuration: z.number().optional(),
4253
+ srcDuration: z6.number().optional(),
2609
4254
  // Video duration in seconds (or to say it more accurately, each iteration duration in a loop))
2610
- style: z.record(z.string(), z.any()).optional(),
4255
+ style: z6.record(z6.string(), z6.any()).optional(),
2611
4256
  // CSS styles object
2612
- containerClassName: z.string().optional(),
4257
+ containerClassName: z6.string().optional(),
2613
4258
  // CSS class names
2614
- className: z.string().optional(),
4259
+ className: z6.string().optional(),
2615
4260
  // CSS class names
2616
- startFrom: z.number().optional(),
4261
+ startFrom: z6.number().optional(),
2617
4262
  // Start playback from this time (seconds)
2618
- endAt: z.number().optional(),
4263
+ endAt: z6.number().optional(),
2619
4264
  // End playback at this time (seconds)
2620
- playbackRate: z.number().optional(),
4265
+ playbackRate: z6.number().optional(),
2621
4266
  // Playback speed multiplier
2622
- volume: z.number().optional(),
4267
+ volume: z6.number().optional(),
2623
4268
  // Volume level (0-1)
2624
- muted: z.boolean().optional(),
4269
+ muted: z6.boolean().optional(),
2625
4270
  // Mute video audio
2626
- loop: z.boolean().optional(),
4271
+ loop: z6.boolean().optional(),
2627
4272
  // Whether to loop the video
2628
- fit: z.enum(["contain", "cover", "fill", "none", "scale-down"]).optional()
4273
+ fit: z6.enum(["contain", "cover", "fill", "none", "scale-down"]).optional()
2629
4274
  // Object fit style
2630
4275
  });
2631
- var Atom4 = ({ data, id, context }) => {
2632
- const { fps } = useVideoConfig5();
4276
+ var Atom5 = ({ data, id, context }) => {
4277
+ const { fps } = useVideoConfig9();
2633
4278
  const overrideStyles = useAnimatedStyles(id);
2634
- const frame = useCurrentFrame5();
2635
- const source = useMemo10(() => {
4279
+ const frame = useCurrentFrame9();
4280
+ const source = useMemo12(() => {
2636
4281
  if (data.src.startsWith("http")) {
2637
4282
  return data.src;
2638
4283
  }
2639
- return staticFile2(data.src);
4284
+ return staticFile3(data.src);
2640
4285
  }, [data.src]);
2641
- const trimBefore = useMemo10(() => {
4286
+ const trimBefore = useMemo12(() => {
2642
4287
  return data.startFrom ? data.startFrom * fps : void 0;
2643
4288
  }, [data.startFrom, fps]);
2644
- const trimAfter = useMemo10(() => {
4289
+ const trimAfter = useMemo12(() => {
2645
4290
  return data.endAt ? data.endAt * fps : void 0;
2646
4291
  }, [data.endAt, fps]);
2647
- const videoComponent = /* @__PURE__ */ React17.createElement(
4292
+ const videoComponent = /* @__PURE__ */ React23.createElement(
2648
4293
  OffthreadVideo,
2649
4294
  {
2650
4295
  className: data.className,
@@ -2657,7 +4302,7 @@ var Atom4 = ({ data, id, context }) => {
2657
4302
  muted: data.muted
2658
4303
  }
2659
4304
  );
2660
- const videoWithStyles = data.containerClassName ? videoComponent : /* @__PURE__ */ React17.createElement(
4305
+ const videoWithStyles = data.containerClassName ? videoComponent : /* @__PURE__ */ React23.createElement(
2661
4306
  OffthreadVideo,
2662
4307
  {
2663
4308
  className: data.className,
@@ -2671,53 +4316,53 @@ var Atom4 = ({ data, id, context }) => {
2671
4316
  }
2672
4317
  );
2673
4318
  if (data.loop) {
2674
- return /* @__PURE__ */ React17.createElement(Loop2, { times: Infinity, durationInFrames: data.srcDuration ? data.srcDuration * fps : context.timing?.durationInFrames, layout: "none" }, data.containerClassName ? /* @__PURE__ */ React17.createElement("div", { className: data.containerClassName, style: overrideStyles }, videoComponent) : videoWithStyles);
4319
+ return /* @__PURE__ */ React23.createElement(Loop2, { times: Infinity, durationInFrames: data.srcDuration ? data.srcDuration * fps : context.timing?.durationInFrames, layout: "none" }, data.containerClassName ? /* @__PURE__ */ React23.createElement("div", { className: data.containerClassName, style: overrideStyles }, videoComponent) : videoWithStyles);
2675
4320
  }
2676
- return data.containerClassName ? /* @__PURE__ */ React17.createElement("div", { className: data.containerClassName, style: overrideStyles }, videoComponent) : videoWithStyles;
4321
+ return data.containerClassName ? /* @__PURE__ */ React23.createElement("div", { className: data.containerClassName, style: overrideStyles }, videoComponent) : videoWithStyles;
2677
4322
  };
2678
- var config12 = {
4323
+ var config14 = {
2679
4324
  displayName: "VideoAtom",
2680
4325
  type: "atom",
2681
4326
  isInnerSequence: false
2682
4327
  };
2683
4328
 
2684
4329
  // src/components/atoms/AudioAtom.tsx
2685
- import React18, { useMemo as useMemo11 } from "react";
2686
- import { Audio, staticFile as staticFile3, useCurrentFrame as useCurrentFrame6, useVideoConfig as useVideoConfig6 } from "remotion";
2687
- import { z as z2 } from "zod";
2688
- var AudioAtomMutedRangeProps = z2.object({
2689
- type: z2.literal("range"),
2690
- values: z2.array(z2.object({
2691
- start: z2.number(),
4330
+ import React24, { useMemo as useMemo13 } from "react";
4331
+ import { Audio, staticFile as staticFile4, useCurrentFrame as useCurrentFrame10, useVideoConfig as useVideoConfig10 } from "remotion";
4332
+ import { z as z7 } from "zod";
4333
+ var AudioAtomMutedRangeProps = z7.object({
4334
+ type: z7.literal("range"),
4335
+ values: z7.array(z7.object({
4336
+ start: z7.number(),
2692
4337
  // Start time in seconds
2693
- end: z2.number()
4338
+ end: z7.number()
2694
4339
  // End time in seconds
2695
4340
  }))
2696
4341
  });
2697
- var AudioAtomMutedFullProps = z2.object({
2698
- type: z2.literal("full"),
2699
- value: z2.boolean()
4342
+ var AudioAtomMutedFullProps = z7.object({
4343
+ type: z7.literal("full"),
4344
+ value: z7.boolean()
2700
4345
  // true = muted, false = unmuted
2701
4346
  });
2702
- var AudioAtomDataProps = z2.object({
2703
- src: z2.string(),
4347
+ var AudioAtomDataProps = z7.object({
4348
+ src: z7.string(),
2704
4349
  // Audio source URL
2705
- startFrom: z2.number().optional(),
4350
+ startFrom: z7.number().optional(),
2706
4351
  // Start playback from this time (seconds)
2707
- endAt: z2.number().optional(),
4352
+ endAt: z7.number().optional(),
2708
4353
  // End playback at this time (seconds)
2709
- volume: z2.number().optional(),
4354
+ volume: z7.number().optional(),
2710
4355
  // Volume level (0-1)
2711
- playbackRate: z2.number().optional(),
4356
+ playbackRate: z7.number().optional(),
2712
4357
  // Playback speed multiplier
2713
- muted: z2.union([AudioAtomMutedFullProps, AudioAtomMutedRangeProps]).optional()
4358
+ muted: z7.union([AudioAtomMutedFullProps, AudioAtomMutedRangeProps]).optional()
2714
4359
  // Mute configuration
2715
4360
  });
2716
- var Atom5 = ({ data }) => {
2717
- const { fps } = useVideoConfig6();
4361
+ var Atom6 = ({ data }) => {
4362
+ const { fps } = useVideoConfig10();
2718
4363
  const { muted } = data;
2719
- const frame = useCurrentFrame6();
2720
- const isMuted = useMemo11(() => {
4364
+ const frame = useCurrentFrame10();
4365
+ const isMuted = useMemo13(() => {
2721
4366
  if (muted?.type === "full") {
2722
4367
  return muted.value;
2723
4368
  }
@@ -2728,15 +4373,15 @@ var Atom5 = ({ data }) => {
2728
4373
  }
2729
4374
  return false;
2730
4375
  }, [muted, frame, fps]);
2731
- const source = useMemo11(() => {
4376
+ const source = useMemo13(() => {
2732
4377
  if (data.src.startsWith("http")) {
2733
4378
  return data.src;
2734
4379
  }
2735
- return staticFile3(data.src);
4380
+ return staticFile4(data.src);
2736
4381
  }, [data.src]);
2737
4382
  return (
2738
4383
  // @ts-ignore
2739
- /* @__PURE__ */ React18.createElement(
4384
+ /* @__PURE__ */ React24.createElement(
2740
4385
  Audio,
2741
4386
  {
2742
4387
  src: source,
@@ -2749,37 +4394,37 @@ var Atom5 = ({ data }) => {
2749
4394
  )
2750
4395
  );
2751
4396
  };
2752
- var config13 = {
4397
+ var config15 = {
2753
4398
  displayName: "AudioAtom",
2754
4399
  type: "atom",
2755
4400
  isInnerSequence: false
2756
4401
  };
2757
4402
 
2758
4403
  // src/components/atoms/LottieAtom.tsx
2759
- import React19, { useMemo as useMemo12, useState as useState4, useEffect as useEffect4 } from "react";
2760
- import { continueRender as continueRender4, delayRender as delayRender5, staticFile as staticFile4, useCurrentFrame as useCurrentFrame7, useVideoConfig as useVideoConfig7 } from "remotion";
4404
+ import React25, { useMemo as useMemo14, useState as useState8, useEffect as useEffect8 } from "react";
4405
+ import { continueRender as continueRender4, delayRender as delayRender5, staticFile as staticFile5, useCurrentFrame as useCurrentFrame11, useVideoConfig as useVideoConfig11 } from "remotion";
2761
4406
  import { Lottie } from "@remotion/lottie";
2762
- import { z as z3 } from "zod";
2763
- var LottieAtomDataProps = z3.object({
2764
- src: z3.string(),
4407
+ import { z as z8 } from "zod";
4408
+ var LottieAtomDataProps = z8.object({
4409
+ src: z8.string(),
2765
4410
  // Lottie JSON source URL or local path
2766
- style: z3.record(z3.string(), z3.any()).optional(),
4411
+ style: z8.record(z8.string(), z8.any()).optional(),
2767
4412
  // CSS styles object
2768
- className: z3.string().optional(),
4413
+ className: z8.string().optional(),
2769
4414
  // CSS class names
2770
- loop: z3.boolean().optional(),
4415
+ loop: z8.boolean().optional(),
2771
4416
  // Whether to loop the animation (handled by Remotion timeline)
2772
- playbackRate: z3.number().optional(),
4417
+ playbackRate: z8.number().optional(),
2773
4418
  // Playback speed multiplier (default: 1)
2774
- direction: z3.enum(["forward", "reverse"]).optional()
4419
+ direction: z8.enum(["forward", "reverse"]).optional()
2775
4420
  // Animation direction
2776
4421
  });
2777
4422
  var useLottieData = (src) => {
2778
- const [animationData, setAnimationData] = useState4(null);
2779
- const [isLoading, setIsLoading] = useState4(true);
2780
- const [hasError, setHasError] = useState4(false);
2781
- const [handle] = useState4(() => delayRender5("Loading Lottie animation"));
2782
- useEffect4(() => {
4423
+ const [animationData, setAnimationData] = useState8(null);
4424
+ const [isLoading, setIsLoading] = useState8(true);
4425
+ const [hasError, setHasError] = useState8(false);
4426
+ const [handle] = useState8(() => delayRender5("Loading Lottie animation"));
4427
+ useEffect8(() => {
2783
4428
  if (!src) {
2784
4429
  console.error("LottieAtom: No source provided");
2785
4430
  setHasError(true);
@@ -2789,7 +4434,7 @@ var useLottieData = (src) => {
2789
4434
  }
2790
4435
  setIsLoading(true);
2791
4436
  setHasError(false);
2792
- const sourceUrl = src.startsWith("http") ? src : staticFile4(src);
4437
+ const sourceUrl = src.startsWith("http") ? src : staticFile5(src);
2793
4438
  fetch(sourceUrl, {
2794
4439
  mode: "cors",
2795
4440
  credentials: "omit"
@@ -2816,12 +4461,12 @@ var useLottieData = (src) => {
2816
4461
  }, [src, handle]);
2817
4462
  return { animationData, isLoading, hasError };
2818
4463
  };
2819
- var Atom6 = ({ data, id }) => {
2820
- const { fps } = useVideoConfig7();
2821
- const frame = useCurrentFrame7();
4464
+ var Atom7 = ({ data, id }) => {
4465
+ const { fps } = useVideoConfig11();
4466
+ const frame = useCurrentFrame11();
2822
4467
  const overrideStyles = useAnimatedStyles(id);
2823
4468
  const { animationData, isLoading, hasError } = useLottieData(data.src);
2824
- const effectiveFrame = useMemo12(() => {
4469
+ const effectiveFrame = useMemo14(() => {
2825
4470
  const playbackRate = data.playbackRate || 1;
2826
4471
  const direction = data.direction || "forward";
2827
4472
  if (direction === "reverse") {
@@ -2829,12 +4474,12 @@ var Atom6 = ({ data, id }) => {
2829
4474
  }
2830
4475
  return frame * playbackRate;
2831
4476
  }, [frame, data.playbackRate, data.direction]);
2832
- const enhancedStyle = useMemo12(() => ({
4477
+ const enhancedStyle = useMemo14(() => ({
2833
4478
  ...data.style,
2834
4479
  ...overrideStyles
2835
4480
  }), [data.style, overrideStyles]);
2836
4481
  if (isLoading) {
2837
- return /* @__PURE__ */ React19.createElement(
4482
+ return /* @__PURE__ */ React25.createElement(
2838
4483
  "div",
2839
4484
  {
2840
4485
  className: data.className,
@@ -2850,7 +4495,7 @@ var Atom6 = ({ data, id }) => {
2850
4495
  }
2851
4496
  if (hasError || !animationData) {
2852
4497
  console.warn(`LottieAtom: Failed to render animation from ${data.src}`);
2853
- return /* @__PURE__ */ React19.createElement(
4498
+ return /* @__PURE__ */ React25.createElement(
2854
4499
  "div",
2855
4500
  {
2856
4501
  className: data.className,
@@ -2870,7 +4515,7 @@ var Atom6 = ({ data, id }) => {
2870
4515
  "\u26A0\uFE0F Lottie Error"
2871
4516
  );
2872
4517
  }
2873
- return /* @__PURE__ */ React19.createElement(
4518
+ return /* @__PURE__ */ React25.createElement(
2874
4519
  Lottie,
2875
4520
  {
2876
4521
  animationData,
@@ -2879,49 +4524,84 @@ var Atom6 = ({ data, id }) => {
2879
4524
  }
2880
4525
  );
2881
4526
  };
2882
- var config14 = {
4527
+ var config16 = {
2883
4528
  displayName: "LottieAtom",
2884
4529
  type: "atom",
2885
4530
  isInnerSequence: false
2886
4531
  };
2887
4532
 
4533
+ // src/components/atoms/HTMLBlockAtom.tsx
4534
+ import React26 from "react";
4535
+ var Atom8 = ({ id, data }) => {
4536
+ const overrideStyles = useAnimatedStyles(id);
4537
+ const combinedStyle = {
4538
+ ...data.style,
4539
+ ...overrideStyles
4540
+ };
4541
+ return /* @__PURE__ */ React26.createElement(
4542
+ "div",
4543
+ {
4544
+ className: data.className,
4545
+ style: combinedStyle,
4546
+ dangerouslySetInnerHTML: { __html: data.html }
4547
+ }
4548
+ );
4549
+ };
4550
+ var config17 = {
4551
+ displayName: "HTMLBlockAtom",
4552
+ type: "atom",
4553
+ isInnerSequence: false
4554
+ };
4555
+
2888
4556
  // src/components/atoms/index.ts
2889
4557
  registerComponent(
2890
- config9.displayName,
2891
- Atom,
2892
- "atom",
2893
- config9
2894
- );
2895
- registerComponent(
2896
- config10.displayName,
4558
+ config11.displayName,
2897
4559
  Atom2,
2898
4560
  "atom",
2899
- config10
4561
+ config11
2900
4562
  );
2901
- registerComponent(config11.displayName, Atom3, "atom", config11);
2902
4563
  registerComponent(
2903
4564
  config12.displayName,
2904
- Atom4,
4565
+ Atom3,
2905
4566
  "atom",
2906
4567
  config12
2907
4568
  );
4569
+ registerComponent(config13.displayName, Atom4, "atom", config13);
2908
4570
  registerComponent(
2909
- config13.displayName,
4571
+ config14.displayName,
2910
4572
  Atom5,
2911
4573
  "atom",
2912
- config13
4574
+ config14
2913
4575
  );
2914
4576
  registerComponent(
2915
- config14.displayName,
4577
+ config15.displayName,
2916
4578
  Atom6,
2917
4579
  "atom",
2918
- config14
4580
+ config15
4581
+ );
4582
+ registerComponent(
4583
+ config16.displayName,
4584
+ Atom7,
4585
+ "atom",
4586
+ config16
4587
+ );
4588
+ registerComponent(
4589
+ config9.displayName,
4590
+ Atom,
4591
+ "atom",
4592
+ config9
4593
+ );
4594
+ registerComponent(
4595
+ config17.displayName,
4596
+ Atom8,
4597
+ "atom",
4598
+ config17
2919
4599
  );
2920
4600
 
2921
4601
  // src/hooks/useComponentRegistry.ts
2922
- import { useMemo as useMemo13 } from "react";
4602
+ import { useMemo as useMemo15 } from "react";
2923
4603
  var useComponentRegistry = () => {
2924
- return useMemo13(() => {
4604
+ return useMemo15(() => {
2925
4605
  return {
2926
4606
  registerComponent: componentRegistry.registerComponent.bind(componentRegistry),
2927
4607
  registerPackage: componentRegistry.registerPackage.bind(componentRegistry),
@@ -2932,13 +4612,13 @@ var useComponentRegistry = () => {
2932
4612
  };
2933
4613
 
2934
4614
  // src/hooks/useBoundaryCalculation.ts
2935
- import { useMemo as useMemo14 } from "react";
4615
+ import { useMemo as useMemo16 } from "react";
2936
4616
  var useBoundaryCalculation = ({
2937
4617
  parentBoundaries,
2938
4618
  constraints,
2939
4619
  layout
2940
4620
  }) => {
2941
- return useMemo14(() => {
4621
+ return useMemo16(() => {
2942
4622
  const { x, y, width, height } = parentBoundaries;
2943
4623
  const calculatedX = typeof constraints.x === "number" ? constraints.x : x;
2944
4624
  const calculatedY = typeof constraints.y === "number" ? constraints.y : y;
@@ -3049,16 +4729,16 @@ var needsProxying = (url) => {
3049
4729
 
3050
4730
  // src/templates/rings/NextjsLogo.tsx
3051
4731
  import { evolvePath } from "@remotion/paths";
3052
- import React22, { useMemo as useMemo15 } from "react";
3053
- import { interpolate as interpolate5, spring as spring5, useCurrentFrame as useCurrentFrame9, useVideoConfig as useVideoConfig9 } from "remotion";
4732
+ import React29, { useMemo as useMemo17 } from "react";
4733
+ import { interpolate as interpolate5, spring as spring5, useCurrentFrame as useCurrentFrame13, useVideoConfig as useVideoConfig13 } from "remotion";
3054
4734
 
3055
4735
  // src/templates/rings/RippleOutLayout.tsx
3056
- import React21 from "react";
3057
- import { spring as spring4, useCurrentFrame as useCurrentFrame8, useVideoConfig as useVideoConfig8, Sequence as Sequence2, AbsoluteFill as AbsoluteFill4 } from "remotion";
3058
- import { z as z4 } from "zod";
3059
- var RippleOutTransitionSchema = z4.object({
3060
- progress: z4.number().min(0).max(1),
3061
- logoOut: z4.number().min(0).max(1)
4736
+ import React28 from "react";
4737
+ import { spring as spring4, useCurrentFrame as useCurrentFrame12, useVideoConfig as useVideoConfig12, Sequence as Sequence2, AbsoluteFill as AbsoluteFill4 } from "remotion";
4738
+ import { z as z9 } from "zod";
4739
+ var RippleOutTransitionSchema = z9.object({
4740
+ progress: z9.number().min(0).max(1),
4741
+ logoOut: z9.number().min(0).max(1)
3062
4742
  });
3063
4743
  var defaultRippleOutData = {
3064
4744
  progress: 0,
@@ -3076,10 +4756,10 @@ var RippleOutLayout = ({ data, context, children }) => {
3076
4756
  transitionStart,
3077
4757
  transitionDuration
3078
4758
  } = data || { transitionStart: 2, transitionDuration: 1 };
3079
- const frame = useCurrentFrame8();
3080
- const { fps } = useVideoConfig8();
4759
+ const frame = useCurrentFrame12();
4760
+ const { fps } = useVideoConfig12();
3081
4761
  const { hierarchy } = useRenderContext();
3082
- React21.useEffect(() => {
4762
+ React28.useEffect(() => {
3083
4763
  loadGoogleFont("Inter", {
3084
4764
  subsets: ["latin"],
3085
4765
  weights: ["400", "700"]
@@ -3100,14 +4780,14 @@ var RippleOutLayout = ({ data, context, children }) => {
3100
4780
  progress: logoOut,
3101
4781
  logoOut
3102
4782
  };
3103
- const childrenArray = React21.Children.toArray(children).filter(
3104
- (child) => React21.isValidElement(child)
4783
+ const childrenArray = React28.Children.toArray(children).filter(
4784
+ (child) => React28.isValidElement(child)
3105
4785
  );
3106
4786
  const [from, to] = childrenArray;
3107
- return /* @__PURE__ */ React21.createElement(LayoutContext.Provider, { value: transitionData }, /* @__PURE__ */ React21.createElement(AbsoluteFill4, { style: {
4787
+ return /* @__PURE__ */ React28.createElement(LayoutContext.Provider, { value: transitionData }, /* @__PURE__ */ React28.createElement(AbsoluteFill4, { style: {
3108
4788
  ...container,
3109
4789
  ...context?.boundaries
3110
- } }, /* @__PURE__ */ React21.createElement(Sequence2, { name: from.props.componentId + " - " + from.props.id, from: 0, durationInFrames: transitionStartFrame + transitionDurationFrames }, from), /* @__PURE__ */ React21.createElement(Sequence2, { name: to.props.componentId + " - " + to.props.id, from: transitionStartFrame + transitionDurationFrames / 2 }, to)));
4790
+ } }, /* @__PURE__ */ React28.createElement(Sequence2, { name: from.props.componentId + " - " + from.props.id, from: 0, durationInFrames: transitionStartFrame + transitionDurationFrames }, from), /* @__PURE__ */ React28.createElement(Sequence2, { name: to.props.componentId + " - " + to.props.id, from: transitionStartFrame + transitionDurationFrames / 2 }, to)));
3111
4791
  };
3112
4792
  var rippleOutLayoutConfig = {
3113
4793
  displayName: "RippleOutLayout",
@@ -3123,8 +4803,8 @@ var nStroke = "M149.508 157.52L69.142 54H54V125.97H66.1136V69.3836L139.999 164.8
3123
4803
  var NextjsLogo = () => {
3124
4804
  const { logoOut } = useRippleOutLayout();
3125
4805
  const outProgress = logoOut;
3126
- const { fps } = useVideoConfig9();
3127
- const frame = useCurrentFrame9();
4806
+ const { fps } = useVideoConfig13();
4807
+ const frame = useCurrentFrame13();
3128
4808
  const evolve1 = spring5({
3129
4809
  fps,
3130
4810
  frame,
@@ -3148,7 +4828,7 @@ var NextjsLogo = () => {
3148
4828
  },
3149
4829
  durationInFrames: 30
3150
4830
  });
3151
- const style = useMemo15(() => {
4831
+ const style = useMemo17(() => {
3152
4832
  return {
3153
4833
  height: 140,
3154
4834
  borderRadius: 70,
@@ -3164,7 +4844,7 @@ var NextjsLogo = () => {
3164
4844
  interpolate5(evolve3, [0, 1], [0, 0.7]),
3165
4845
  thirdPath
3166
4846
  );
3167
- return /* @__PURE__ */ React22.createElement("svg", { style, fill: "none", viewBox: "0 0 180 180" }, /* @__PURE__ */ React22.createElement("mask", { height: "180", id: "mask", style: mask, width: "180", x: "0", y: "0" }, /* @__PURE__ */ React22.createElement("circle", { cx: "90", cy: "90", fill: "black", r: "90" })), /* @__PURE__ */ React22.createElement("mask", { id: "n-mask", style: mask }, /* @__PURE__ */ React22.createElement("path", { d: nStroke, fill: "black" })), /* @__PURE__ */ React22.createElement("g", { mask: "url(#mask)" }, /* @__PURE__ */ React22.createElement("circle", { cx: "90", cy: "90", fill: "black", r: "90" }), /* @__PURE__ */ React22.createElement("g", { stroke: "url(#gradient0)", mask: "url(#n-mask)" }, /* @__PURE__ */ React22.createElement(
4847
+ return /* @__PURE__ */ React29.createElement("svg", { style, fill: "none", viewBox: "0 0 180 180" }, /* @__PURE__ */ React29.createElement("mask", { height: "180", id: "mask", style: mask, width: "180", x: "0", y: "0" }, /* @__PURE__ */ React29.createElement("circle", { cx: "90", cy: "90", fill: "black", r: "90" })), /* @__PURE__ */ React29.createElement("mask", { id: "n-mask", style: mask }, /* @__PURE__ */ React29.createElement("path", { d: nStroke, fill: "black" })), /* @__PURE__ */ React29.createElement("g", { mask: "url(#mask)" }, /* @__PURE__ */ React29.createElement("circle", { cx: "90", cy: "90", fill: "black", r: "90" }), /* @__PURE__ */ React29.createElement("g", { stroke: "url(#gradient0)", mask: "url(#n-mask)" }, /* @__PURE__ */ React29.createElement(
3168
4848
  "path",
3169
4849
  {
3170
4850
  strokeWidth: "12.1136",
@@ -3172,7 +4852,7 @@ var NextjsLogo = () => {
3172
4852
  strokeDasharray: evolution1.strokeDasharray,
3173
4853
  strokeDashoffset: evolution1.strokeDashoffset
3174
4854
  }
3175
- ), /* @__PURE__ */ React22.createElement(
4855
+ ), /* @__PURE__ */ React29.createElement(
3176
4856
  "path",
3177
4857
  {
3178
4858
  strokeWidth: 12.1136,
@@ -3180,7 +4860,7 @@ var NextjsLogo = () => {
3180
4860
  strokeDasharray: evolution2.strokeDasharray,
3181
4861
  strokeDashoffset: evolution2.strokeDashoffset
3182
4862
  }
3183
- )), /* @__PURE__ */ React22.createElement(
4863
+ )), /* @__PURE__ */ React29.createElement(
3184
4864
  "path",
3185
4865
  {
3186
4866
  stroke: "url(#gradient1)",
@@ -3189,7 +4869,7 @@ var NextjsLogo = () => {
3189
4869
  strokeDashoffset: evolution3.strokeDashoffset,
3190
4870
  strokeWidth: "12"
3191
4871
  }
3192
- )), /* @__PURE__ */ React22.createElement("defs", null, /* @__PURE__ */ React22.createElement(
4872
+ )), /* @__PURE__ */ React29.createElement("defs", null, /* @__PURE__ */ React29.createElement(
3193
4873
  "linearGradient",
3194
4874
  {
3195
4875
  gradientUnits: "userSpaceOnUse",
@@ -3199,9 +4879,9 @@ var NextjsLogo = () => {
3199
4879
  y1: "116.5",
3200
4880
  y2: "160.5"
3201
4881
  },
3202
- /* @__PURE__ */ React22.createElement("stop", { stopColor: "white" }),
3203
- /* @__PURE__ */ React22.createElement("stop", { offset: "1", stopColor: "white", stopOpacity: "0" })
3204
- ), /* @__PURE__ */ React22.createElement(
4882
+ /* @__PURE__ */ React29.createElement("stop", { stopColor: "white" }),
4883
+ /* @__PURE__ */ React29.createElement("stop", { offset: "1", stopColor: "white", stopOpacity: "0" })
4884
+ ), /* @__PURE__ */ React29.createElement(
3205
4885
  "linearGradient",
3206
4886
  {
3207
4887
  gradientUnits: "userSpaceOnUse",
@@ -3211,8 +4891,8 @@ var NextjsLogo = () => {
3211
4891
  y1: "54",
3212
4892
  y2: "106.875"
3213
4893
  },
3214
- /* @__PURE__ */ React22.createElement("stop", { stopColor: "white" }),
3215
- /* @__PURE__ */ React22.createElement("stop", { offset: "1", stopColor: "white", stopOpacity: "0" })
4894
+ /* @__PURE__ */ React29.createElement("stop", { stopColor: "white" }),
4895
+ /* @__PURE__ */ React29.createElement("stop", { offset: "1", stopColor: "white", stopOpacity: "0" })
3216
4896
  )));
3217
4897
  };
3218
4898
  var nextjsLogoConfig = {
@@ -3222,14 +4902,14 @@ var nextjsLogoConfig = {
3222
4902
  };
3223
4903
 
3224
4904
  // src/templates/rings/Rings.tsx
3225
- import React23 from "react";
3226
- import { AbsoluteFill as AbsoluteFill5, interpolateColors as interpolateColors2, useVideoConfig as useVideoConfig10 } from "remotion";
4905
+ import React30 from "react";
4906
+ import { AbsoluteFill as AbsoluteFill5, interpolateColors as interpolateColors2, useVideoConfig as useVideoConfig14 } from "remotion";
3227
4907
  var RadialGradient = ({ radius, color }) => {
3228
4908
  const height = radius * 2;
3229
4909
  const width = radius * 2;
3230
4910
  return (
3231
4911
  // @ts-ignore
3232
- /* @__PURE__ */ React23.createElement(
4912
+ /* @__PURE__ */ React30.createElement(
3233
4913
  AbsoluteFill5,
3234
4914
  {
3235
4915
  style: {
@@ -3237,7 +4917,7 @@ var RadialGradient = ({ radius, color }) => {
3237
4917
  alignItems: "center"
3238
4918
  }
3239
4919
  },
3240
- /* @__PURE__ */ React23.createElement(
4920
+ /* @__PURE__ */ React30.createElement(
3241
4921
  "div",
3242
4922
  {
3243
4923
  style: {
@@ -3257,10 +4937,10 @@ var Rings = ({ context, data }) => {
3257
4937
  const { logoOut } = useRippleOutLayout();
3258
4938
  const outProgress = logoOut;
3259
4939
  const scale = 1 / (1 - outProgress);
3260
- const { height } = useVideoConfig10();
4940
+ const { height } = useVideoConfig14();
3261
4941
  return (
3262
4942
  // @ts-ignore
3263
- /* @__PURE__ */ React23.createElement(
4943
+ /* @__PURE__ */ React30.createElement(
3264
4944
  AbsoluteFill5,
3265
4945
  {
3266
4946
  style: {
@@ -3269,7 +4949,7 @@ var Rings = ({ context, data }) => {
3269
4949
  }
3270
4950
  },
3271
4951
  new Array(5).fill(true).map((_, i) => {
3272
- return /* @__PURE__ */ React23.createElement(
4952
+ return /* @__PURE__ */ React30.createElement(
3273
4953
  RadialGradient,
3274
4954
  {
3275
4955
  key: i,
@@ -3288,13 +4968,13 @@ var ringsConfig = {
3288
4968
  };
3289
4969
 
3290
4970
  // src/templates/rings/TextFade.tsx
3291
- import React24, { useMemo as useMemo16 } from "react";
4971
+ import React31, { useMemo as useMemo18 } from "react";
3292
4972
  import {
3293
4973
  AbsoluteFill as AbsoluteFill6,
3294
4974
  interpolate as interpolate6,
3295
4975
  spring as spring6,
3296
- useCurrentFrame as useCurrentFrame10,
3297
- useVideoConfig as useVideoConfig11
4976
+ useCurrentFrame as useCurrentFrame14,
4977
+ useVideoConfig as useVideoConfig15
3298
4978
  } from "remotion";
3299
4979
  var TextFade = (props) => {
3300
4980
  const { children, context, data } = props;
@@ -3303,8 +4983,8 @@ var TextFade = (props) => {
3303
4983
  duration: 1
3304
4984
  }
3305
4985
  };
3306
- const { fps } = useVideoConfig11();
3307
- const frame = useCurrentFrame10();
4986
+ const { fps } = useVideoConfig15();
4987
+ const frame = useCurrentFrame14();
3308
4988
  const progress = spring6({
3309
4989
  fps,
3310
4990
  frame,
@@ -3316,7 +4996,7 @@ var TextFade = (props) => {
3316
4996
  const rightStop = interpolate6(progress, [0, 1], [200, 0]);
3317
4997
  const leftStop = Math.max(0, rightStop - 60);
3318
4998
  const maskImage = `linear-gradient(-45deg, transparent ${leftStop}%, black ${rightStop}%)`;
3319
- const container2 = useMemo16(() => {
4999
+ const container2 = useMemo18(() => {
3320
5000
  return {
3321
5001
  width: "100%",
3322
5002
  height: "100%",
@@ -3324,7 +5004,7 @@ var TextFade = (props) => {
3324
5004
  alignItems: "center"
3325
5005
  };
3326
5006
  }, []);
3327
- const content = useMemo16(() => {
5007
+ const content = useMemo18(() => {
3328
5008
  return {
3329
5009
  ...context?.boundaries,
3330
5010
  maskImage,
@@ -3336,7 +5016,7 @@ var TextFade = (props) => {
3336
5016
  }, [maskImage]);
3337
5017
  return (
3338
5018
  // @ts-ignore
3339
- /* @__PURE__ */ React24.createElement(AbsoluteFill6, { style: container2 }, /* @__PURE__ */ React24.createElement("div", { style: content }, children))
5019
+ /* @__PURE__ */ React31.createElement(AbsoluteFill6, { style: container2 }, /* @__PURE__ */ React31.createElement("div", { style: content }, children))
3340
5020
  );
3341
5021
  };
3342
5022
  var textFadeConfig = {
@@ -3367,234 +5047,11 @@ registerComponent(
3367
5047
  );
3368
5048
 
3369
5049
  // src/templates/waveform/components/WaveformCircle.tsx
3370
- import React26, { useMemo as useMemo18 } from "react";
3371
-
3372
- // src/templates/waveform/Waveform.tsx
3373
- import React25, { createContext as createContext5, useContext as useContext6 } from "react";
3374
- import { useCurrentFrame as useCurrentFrame11, useVideoConfig as useVideoConfig12 } from "remotion";
3375
-
3376
- // src/templates/waveform/hooks/useWaveformData.ts
3377
- import { useMemo as useMemo17 } from "react";
3378
- import {
3379
- useAudioData,
3380
- visualizeAudioWaveform,
3381
- visualizeAudio
3382
- } from "@remotion/media-utils";
3383
- import { staticFile as staticFile5 } from "remotion";
3384
- var isValidPowerOfTwo = (num) => {
3385
- return num > 0 && (num & num - 1) === 0;
3386
- };
3387
- var getClosestPowerOfTwo = (num) => {
3388
- if (num <= 0) return 32;
3389
- let power = 1;
3390
- while (power < num) {
3391
- power *= 2;
3392
- }
3393
- const lower = power / 2;
3394
- const upper = power;
3395
- return Math.abs(num - lower) < Math.abs(num - upper) ? lower : upper;
3396
- };
3397
- var useWaveformData = (config15) => {
3398
- const {
3399
- audioSrc,
3400
- numberOfSamples,
3401
- windowInSeconds,
3402
- dataOffsetInSeconds = 0,
3403
- normalize = false,
3404
- frame,
3405
- fps,
3406
- posterize,
3407
- includeFrequencyData = false,
3408
- minDb = -100,
3409
- maxDb = -30
3410
- } = config15;
3411
- const { root } = useComposition();
3412
- const validatedNumberOfSamples = useMemo17(() => {
3413
- if (!isValidPowerOfTwo(numberOfSamples)) {
3414
- console.warn(
3415
- `numberOfSamples must be a power of 2. Adjusting ${numberOfSamples} to ${getClosestPowerOfTwo(numberOfSamples)}`
3416
- );
3417
- return getClosestPowerOfTwo(numberOfSamples);
3418
- }
3419
- return numberOfSamples;
3420
- }, [numberOfSamples]);
3421
- const { source, audioStartsFrom } = useMemo17(() => {
3422
- if (audioSrc.startsWith("http")) {
3423
- return { source: audioSrc, audioStartsFrom: void 0 };
3424
- }
3425
- if (audioSrc.startsWith("ref:")) {
3426
- const matchingComponent = findMatchingComponents(root, [
3427
- audioSrc.replace("ref:", "")
3428
- ]);
3429
- if (matchingComponent.length > 0) {
3430
- const firstMatchingComponent = matchingComponent[0];
3431
- if (firstMatchingComponent.componentId === "AudioAtom") {
3432
- return {
3433
- source: firstMatchingComponent.data.src,
3434
- audioStartsFrom: firstMatchingComponent.data?.startFrom ?? void 0
3435
- };
3436
- }
3437
- if (firstMatchingComponent.type === "layout" || firstMatchingComponent.type === "scene") {
3438
- const audioComponents = findMatchingComponentsByQuery(
3439
- firstMatchingComponent.childrenData,
3440
- { componentId: "AudioAtom" }
3441
- );
3442
- if (audioComponents.length > 0) {
3443
- return {
3444
- source: audioComponents[0].data.src,
3445
- audioStartsFrom: audioComponents[0].data?.startFrom ?? void 0
3446
- };
3447
- }
3448
- }
3449
- }
3450
- }
3451
- return { source: staticFile5(audioSrc), audioStartsFrom: void 0 };
3452
- }, [audioSrc]);
3453
- const audioData = useAudioData(source);
3454
- const adjustedFrame = useMemo17(() => {
3455
- if (posterize && posterize > 1) {
3456
- return Math.round(frame / posterize) * posterize;
3457
- }
3458
- let offset = 0;
3459
- if (audioStartsFrom && audioStartsFrom != 0) {
3460
- offset += Math.round(audioStartsFrom * fps);
3461
- }
3462
- if (dataOffsetInSeconds != 0) {
3463
- offset += Math.round(dataOffsetInSeconds * fps);
3464
- }
3465
- return frame + offset;
3466
- }, [frame, posterize, dataOffsetInSeconds, audioStartsFrom]);
3467
- const waveformData = useMemo17(() => {
3468
- if (!audioData) return null;
3469
- try {
3470
- const waveform = visualizeAudioWaveform({
3471
- fps,
3472
- frame: adjustedFrame,
3473
- audioData,
3474
- numberOfSamples: validatedNumberOfSamples,
3475
- windowInSeconds,
3476
- dataOffsetInSeconds: 0,
3477
- normalize
3478
- });
3479
- return waveform;
3480
- } catch (error2) {
3481
- console.error("Error generating waveform:", error2);
3482
- return null;
3483
- }
3484
- }, [
3485
- audioData,
3486
- adjustedFrame,
3487
- fps,
3488
- validatedNumberOfSamples,
3489
- windowInSeconds,
3490
- dataOffsetInSeconds,
3491
- normalize
3492
- ]);
3493
- const {
3494
- frequencyData,
3495
- amplitudes,
3496
- bass,
3497
- mid,
3498
- treble,
3499
- bassValues,
3500
- midValues,
3501
- trebleValues
3502
- } = useMemo17(() => {
3503
- if (!audioData || !includeFrequencyData) {
3504
- return {
3505
- frequencyData: null,
3506
- amplitudes: null,
3507
- bass: null,
3508
- mid: null,
3509
- treble: null,
3510
- bassValues: null,
3511
- midValues: null,
3512
- trebleValues: null
3513
- };
3514
- }
3515
- try {
3516
- const frequencyData2 = visualizeAudio({
3517
- fps,
3518
- frame: adjustedFrame,
3519
- audioData,
3520
- numberOfSamples: validatedNumberOfSamples
3521
- });
3522
- const { sampleRate } = audioData;
3523
- const bassValues2 = [];
3524
- const midValues2 = [];
3525
- const trebleValues2 = [];
3526
- for (let i = 0; i < frequencyData2.length; i++) {
3527
- const freq = i * sampleRate / (2 * frequencyData2.length);
3528
- const value = frequencyData2[i];
3529
- if (freq >= 0 && freq < 250) {
3530
- bassValues2.push(value * 2.5);
3531
- } else if (freq >= 250 && freq < 4e3) {
3532
- midValues2.push(value * 3);
3533
- midValues2.push(value * 4.5);
3534
- midValues2.push(value * 5);
3535
- } else if (freq >= 4e3 && freq < sampleRate / 2) {
3536
- trebleValues2.push(value * 30);
3537
- }
3538
- }
3539
- const getAverage = (arr) => arr.length > 0 ? arr.reduce((a, b) => a + b, 0) / arr.length : 0;
3540
- const bass2 = getAverage(bassValues2);
3541
- const mid2 = getAverage(midValues2);
3542
- const treble2 = getAverage(trebleValues2);
3543
- const amplitudes2 = frequencyData2.map((value) => {
3544
- const db = 20 * Math.log10(value);
3545
- const scaled = (db - minDb) / (maxDb - minDb);
3546
- return Math.max(0, Math.min(1, scaled));
3547
- });
3548
- return {
3549
- frequencyData: frequencyData2,
3550
- amplitudes: amplitudes2,
3551
- bass: bass2,
3552
- mid: mid2,
3553
- treble: treble2,
3554
- bassValues: bassValues2,
3555
- midValues: midValues2,
3556
- trebleValues: trebleValues2.reverse()
3557
- };
3558
- } catch (error2) {
3559
- console.error("Error generating frequency data:", error2);
3560
- return {
3561
- frequencyData: null,
3562
- amplitudes: null,
3563
- bass: null,
3564
- mid: null,
3565
- treble: null
3566
- };
3567
- }
3568
- }, [
3569
- audioData,
3570
- includeFrequencyData,
3571
- adjustedFrame,
3572
- fps,
3573
- validatedNumberOfSamples,
3574
- windowInSeconds,
3575
- dataOffsetInSeconds,
3576
- minDb,
3577
- maxDb
3578
- ]);
3579
- const isLoading = !audioData;
3580
- const error = audioData === null && !isLoading ? "Failed to load audio data" : null;
3581
- return {
3582
- waveformData,
3583
- frequencyData,
3584
- amplitudes,
3585
- audioData,
3586
- isLoading,
3587
- error,
3588
- bass,
3589
- bassValues,
3590
- mid,
3591
- midValues,
3592
- treble,
3593
- trebleValues
3594
- };
3595
- };
5050
+ import React33, { useMemo as useMemo19 } from "react";
3596
5051
 
3597
5052
  // src/templates/waveform/Waveform.tsx
5053
+ import React32, { createContext as createContext5, useContext as useContext6 } from "react";
5054
+ import { useCurrentFrame as useCurrentFrame15, useVideoConfig as useVideoConfig16 } from "remotion";
3598
5055
  var WaveformContext = createContext5(null);
3599
5056
  var useWaveformContext = () => {
3600
5057
  const context = useContext6(WaveformContext);
@@ -3604,26 +5061,27 @@ var useWaveformContext = () => {
3604
5061
  return context;
3605
5062
  };
3606
5063
  var Waveform = ({
3607
- config: config15,
5064
+ config: config18,
3608
5065
  children,
3609
5066
  className = "",
3610
5067
  style = {}
3611
5068
  }) => {
3612
- const frame = useCurrentFrame11();
3613
- const { width: videoWidth, height: videoHeight, fps } = useVideoConfig12();
5069
+ const frame = useCurrentFrame15();
5070
+ const { width: videoWidth, height: videoHeight, fps } = useVideoConfig16();
3614
5071
  const { waveformData, frequencyData, amplitudes, audioData, bass, mid, treble, bassValues, midValues, trebleValues } = useWaveformData({
3615
- audioSrc: config15.audioSrc,
3616
- numberOfSamples: config15.numberOfSamples || 128,
3617
- windowInSeconds: config15.windowInSeconds || 1 / fps,
3618
- dataOffsetInSeconds: config15.dataOffsetInSeconds || 0,
3619
- normalize: config15.normalize || false,
5072
+ audioSrc: config18.audioSrc,
5073
+ numberOfSamples: config18.numberOfSamples || 128,
5074
+ windowInSeconds: config18.windowInSeconds || 1 / fps,
5075
+ dataOffsetInSeconds: config18.dataOffsetInSeconds || 0,
5076
+ normalize: config18.normalize || false,
3620
5077
  frame,
3621
5078
  fps,
3622
- posterize: config15.posterize,
3623
- includeFrequencyData: config15.useFrequencyData || false
5079
+ posterize: config18.posterize,
5080
+ includeFrequencyData: config18.useFrequencyData || false,
5081
+ smoothNormalisation: config18.smoothNormalisation
3624
5082
  });
3625
- const width = config15.width || videoWidth;
3626
- const height = config15.height || videoHeight;
5083
+ const width = config18.width || videoWidth;
5084
+ const height = config18.height || videoHeight;
3627
5085
  const contextValue = {
3628
5086
  waveformData,
3629
5087
  frequencyData,
@@ -3631,7 +5089,7 @@ var Waveform = ({
3631
5089
  audioData,
3632
5090
  frame,
3633
5091
  fps,
3634
- config: config15,
5092
+ config: config18,
3635
5093
  width,
3636
5094
  height,
3637
5095
  bass,
@@ -3641,7 +5099,7 @@ var Waveform = ({
3641
5099
  midValues,
3642
5100
  trebleValues
3643
5101
  };
3644
- return /* @__PURE__ */ React25.createElement(WaveformContext.Provider, { value: contextValue }, /* @__PURE__ */ React25.createElement(
5102
+ return /* @__PURE__ */ React32.createElement(WaveformContext.Provider, { value: contextValue }, /* @__PURE__ */ React32.createElement(
3645
5103
  "div",
3646
5104
  {
3647
5105
  className: `relative ${className}`,
@@ -3649,7 +5107,7 @@ var Waveform = ({
3649
5107
  width,
3650
5108
  height,
3651
5109
  position: "relative",
3652
- backgroundColor: config15.backgroundColor || "transparent",
5110
+ backgroundColor: config18.backgroundColor || "transparent",
3653
5111
  ...style
3654
5112
  }
3655
5113
  },
@@ -3660,7 +5118,7 @@ var Waveform = ({
3660
5118
  // src/templates/waveform/components/WaveformCircle.tsx
3661
5119
  var WaveformCircle = ({ data }) => {
3662
5120
  const {
3663
- config: config15,
5121
+ config: config18,
3664
5122
  className = "",
3665
5123
  style = {},
3666
5124
  strokeColor = "#FF6B6B",
@@ -3677,7 +5135,7 @@ var WaveformCircle = ({ data }) => {
3677
5135
  gradientStartColor,
3678
5136
  gradientEndColor
3679
5137
  } = data;
3680
- return /* @__PURE__ */ React26.createElement(Waveform, { config: config15, className, style }, /* @__PURE__ */ React26.createElement(
5138
+ return /* @__PURE__ */ React33.createElement(Waveform, { config: config18, className, style }, /* @__PURE__ */ React33.createElement(
3681
5139
  WaveformCircleContent,
3682
5140
  {
3683
5141
  strokeColor,
@@ -3716,7 +5174,7 @@ var WaveformCircleContent = ({
3716
5174
  const circleCenterX = width * (centerX || 50) / 100;
3717
5175
  const circleCenterY = height * (centerY || 50) / 100;
3718
5176
  const rotation = frame * (rotationSpeed || 0) % 360;
3719
- const circularPath = useMemo18(() => {
5177
+ const circularPath = useMemo19(() => {
3720
5178
  if (!waveformData) return "";
3721
5179
  const totalAngle = (endAngle || 360) - (startAngle || 0);
3722
5180
  const angleStep = totalAngle / waveformData.length;
@@ -3738,11 +5196,11 @@ var WaveformCircleContent = ({
3738
5196
  return path;
3739
5197
  }, [waveformData, circleRadius, circleCenterX, circleCenterY, startAngle, endAngle, rotation, amplitude]);
3740
5198
  if (!waveformData) {
3741
- return /* @__PURE__ */ React26.createElement("div", { className: "flex items-center justify-center w-full h-full text-gray-500" }, "Loading circular waveform...");
5199
+ return /* @__PURE__ */ React33.createElement("div", { className: "flex items-center justify-center w-full h-full text-gray-500" }, "Loading circular waveform...");
3742
5200
  }
3743
5201
  const gradientId = "circle-waveform-gradient";
3744
5202
  const hasGradient = gradientStartColor && gradientEndColor;
3745
- return /* @__PURE__ */ React26.createElement(
5203
+ return /* @__PURE__ */ React33.createElement(
3746
5204
  "svg",
3747
5205
  {
3748
5206
  width,
@@ -3750,8 +5208,8 @@ var WaveformCircleContent = ({
3750
5208
  className: "absolute inset-0",
3751
5209
  style: { pointerEvents: "none" }
3752
5210
  },
3753
- hasGradient && /* @__PURE__ */ React26.createElement("defs", null, /* @__PURE__ */ React26.createElement("linearGradient", { id: gradientId, x1: "0%", y1: "0%", x2: "100%", y2: "0%" }, /* @__PURE__ */ React26.createElement("stop", { offset: "0%", stopColor: gradientStartColor }), /* @__PURE__ */ React26.createElement("stop", { offset: "100%", stopColor: gradientEndColor }))),
3754
- /* @__PURE__ */ React26.createElement(
5211
+ hasGradient && /* @__PURE__ */ React33.createElement("defs", null, /* @__PURE__ */ React33.createElement("linearGradient", { id: gradientId, x1: "0%", y1: "0%", x2: "100%", y2: "0%" }, /* @__PURE__ */ React33.createElement("stop", { offset: "0%", stopColor: gradientStartColor }), /* @__PURE__ */ React33.createElement("stop", { offset: "100%", stopColor: gradientEndColor }))),
5212
+ /* @__PURE__ */ React33.createElement(
3755
5213
  "path",
3756
5214
  {
3757
5215
  d: circularPath,
@@ -3767,10 +5225,10 @@ var WaveformCircleContent = ({
3767
5225
  };
3768
5226
 
3769
5227
  // src/templates/waveform/components/WaveformHistogram.tsx
3770
- import React27 from "react";
5228
+ import React34 from "react";
3771
5229
  var WaveformHistogram = ({ data }) => {
3772
5230
  const {
3773
- config: config15,
5231
+ config: config18,
3774
5232
  className = "",
3775
5233
  style = {},
3776
5234
  barColor = "#FF6B6B",
@@ -3789,7 +5247,7 @@ var WaveformHistogram = ({ data }) => {
3789
5247
  gradientStyle = "normal",
3790
5248
  waveDirection = "right-to-left"
3791
5249
  } = data;
3792
- return /* @__PURE__ */ React27.createElement(Waveform, { config: config15, className, style }, /* @__PURE__ */ React27.createElement(
5250
+ return /* @__PURE__ */ React34.createElement(Waveform, { config: config18, className, style }, /* @__PURE__ */ React34.createElement(
3793
5251
  WaveformHistogramContent,
3794
5252
  {
3795
5253
  barColor,
@@ -3830,7 +5288,7 @@ var WaveformHistogramContent = ({
3830
5288
  const { waveformData, frequencyData, amplitudes, width, height } = useWaveformContext();
3831
5289
  const dataToUse = amplitudes || waveformData;
3832
5290
  if (!dataToUse) {
3833
- return /* @__PURE__ */ React27.createElement("div", { className: "flex items-center justify-center w-full h-full text-gray-500" }, "Loading histogram...");
5291
+ return /* @__PURE__ */ React34.createElement("div", { className: "flex items-center justify-center w-full h-full text-gray-500" }, "Loading histogram...");
3834
5292
  }
3835
5293
  let directedData = waveDirection === "left-to-right" ? dataToUse.slice(1).reverse() : dataToUse;
3836
5294
  const frequencies = horizontalSymmetry ? [...directedData, ...directedData.slice(1).reverse()] : Array(multiplier).fill(directedData).flat();
@@ -3854,7 +5312,7 @@ var WaveformHistogramContent = ({
3854
5312
  },
3855
5313
  opacity: gradientStyle === "mirrored" && !growUpwards ? 0.25 : 1
3856
5314
  };
3857
- return /* @__PURE__ */ React27.createElement("div", { style: containerStyle2 }, frequencies.map((value, index) => /* @__PURE__ */ React27.createElement(
5315
+ return /* @__PURE__ */ React34.createElement("div", { style: containerStyle2 }, frequencies.map((value, index) => /* @__PURE__ */ React34.createElement(
3858
5316
  "div",
3859
5317
  {
3860
5318
  key: index,
@@ -3886,7 +5344,7 @@ var WaveformHistogramContent = ({
3886
5344
  width: "100%",
3887
5345
  left: 0
3888
5346
  };
3889
- return /* @__PURE__ */ React27.createElement(React27.Fragment, null, /* @__PURE__ */ React27.createElement("div", { style: topHalfStyle }, /* @__PURE__ */ React27.createElement(Bars, { growUpwards: true })), /* @__PURE__ */ React27.createElement("div", { style: bottomHalfStyle }, /* @__PURE__ */ React27.createElement(Bars, { growUpwards: false })));
5347
+ return /* @__PURE__ */ React34.createElement(React34.Fragment, null, /* @__PURE__ */ React34.createElement("div", { style: topHalfStyle }, /* @__PURE__ */ React34.createElement(Bars, { growUpwards: true })), /* @__PURE__ */ React34.createElement("div", { style: bottomHalfStyle }, /* @__PURE__ */ React34.createElement(Bars, { growUpwards: false })));
3890
5348
  }
3891
5349
  const containerStyle = {
3892
5350
  width: "100%",
@@ -3895,14 +5353,14 @@ var WaveformHistogramContent = ({
3895
5353
  height: `${height / 2}px`,
3896
5354
  left: 0
3897
5355
  };
3898
- return /* @__PURE__ */ React27.createElement("div", { style: containerStyle }, /* @__PURE__ */ React27.createElement(Bars, { growUpwards: true }));
5356
+ return /* @__PURE__ */ React34.createElement("div", { style: containerStyle }, /* @__PURE__ */ React34.createElement(Bars, { growUpwards: true }));
3899
5357
  };
3900
5358
 
3901
5359
  // src/templates/waveform/components/WaveformHistogramRanged.tsx
3902
- import React28 from "react";
5360
+ import React35 from "react";
3903
5361
  var WaveformHistogramRanged = ({ data }) => {
3904
5362
  const {
3905
- config: config15,
5363
+ config: config18,
3906
5364
  className = "",
3907
5365
  style = {},
3908
5366
  barColor = "#FF6B6B",
@@ -3926,7 +5384,7 @@ var WaveformHistogramRanged = ({ data }) => {
3926
5384
  horizontalSymmetry = false,
3927
5385
  waveDirection = "right-to-left"
3928
5386
  } = data;
3929
- return /* @__PURE__ */ React28.createElement(Waveform, { config: config15, className, style }, /* @__PURE__ */ React28.createElement(
5387
+ return /* @__PURE__ */ React35.createElement(Waveform, { config: config18, className, style }, /* @__PURE__ */ React35.createElement(
3930
5388
  WaveformHistogramRangedContent,
3931
5389
  {
3932
5390
  barColor,
@@ -3976,7 +5434,7 @@ var WaveformHistogramRangedContent = ({
3976
5434
  }) => {
3977
5435
  const { amplitudes, bassValues, midValues, trebleValues, height } = useWaveformContext();
3978
5436
  if (!amplitudes || !bassValues || !midValues || !trebleValues) {
3979
- return /* @__PURE__ */ React28.createElement("div", { className: "flex items-center justify-center w-full h-full text-gray-500" }, "Loading frequency data...");
5437
+ return /* @__PURE__ */ React35.createElement("div", { className: "flex items-center justify-center w-full h-full text-gray-500" }, "Loading frequency data...");
3980
5438
  }
3981
5439
  const bassFrequencies = bassValues;
3982
5440
  const midFrequencies = midValues;
@@ -4000,12 +5458,12 @@ var WaveformHistogramRangedContent = ({
4000
5458
  },
4001
5459
  opacity: gradientStyle === "mirrored" && !growUpwards ? 0.25 : 1
4002
5460
  };
4003
- return /* @__PURE__ */ React28.createElement("div", { style: containerStyle2 }, unifiedWaveform.map((value, index) => {
5461
+ return /* @__PURE__ */ React35.createElement("div", { style: containerStyle2 }, unifiedWaveform.map((value, index) => {
4004
5462
  const rangeName = index === 0 ? "Bass" : index === 1 ? "Mid" : "Treble";
4005
5463
  const styleGradientProp = gradientStartColor && gradientEndColor ? {
4006
5464
  background: `linear-gradient(${gradientDirection === "horizontal" ? gradientStyle === "mirrored" ? "to right" : growUpwards ? "to right" : "to left" : gradientStyle === "normal" ? growUpwards ? "to top" : "to bottom" : "to bottom"}, ${gradientStartColor}, ${gradientEndColor})`
4007
5465
  } : { backgroundColor: barColor };
4008
- return /* @__PURE__ */ React28.createElement(
5466
+ return /* @__PURE__ */ React35.createElement(
4009
5467
  "div",
4010
5468
  {
4011
5469
  key: index,
@@ -4023,7 +5481,7 @@ var WaveformHistogramRangedContent = ({
4023
5481
  },
4024
5482
  title: `${rangeName}: ${(value * 100).toFixed(1)}%`
4025
5483
  },
4026
- rangeLabels && /* @__PURE__ */ React28.createElement("div", { style: {
5484
+ rangeLabels && /* @__PURE__ */ React35.createElement("div", { style: {
4027
5485
  position: "absolute",
4028
5486
  bottom: growUpwards ? "-20px" : "auto",
4029
5487
  top: growUpwards ? "auto" : "-20px",
@@ -4051,7 +5509,7 @@ var WaveformHistogramRangedContent = ({
4051
5509
  width: "100%",
4052
5510
  left: 0
4053
5511
  };
4054
- return /* @__PURE__ */ React28.createElement(React28.Fragment, null, /* @__PURE__ */ React28.createElement("div", { style: topHalfStyle }, /* @__PURE__ */ React28.createElement(Bars, { growUpwards: true })), /* @__PURE__ */ React28.createElement("div", { style: bottomHalfStyle }, /* @__PURE__ */ React28.createElement(Bars, { growUpwards: false })));
5512
+ return /* @__PURE__ */ React35.createElement(React35.Fragment, null, /* @__PURE__ */ React35.createElement("div", { style: topHalfStyle }, /* @__PURE__ */ React35.createElement(Bars, { growUpwards: true })), /* @__PURE__ */ React35.createElement("div", { style: bottomHalfStyle }, /* @__PURE__ */ React35.createElement(Bars, { growUpwards: false })));
4055
5513
  }
4056
5514
  const containerStyle = {
4057
5515
  width: "100%",
@@ -4060,13 +5518,13 @@ var WaveformHistogramRangedContent = ({
4060
5518
  height: `${height / 2}px`,
4061
5519
  left: 0
4062
5520
  };
4063
- return /* @__PURE__ */ React28.createElement("div", { style: containerStyle }, /* @__PURE__ */ React28.createElement(Bars, { growUpwards: true }));
5521
+ return /* @__PURE__ */ React35.createElement("div", { style: containerStyle }, /* @__PURE__ */ React35.createElement(Bars, { growUpwards: true }));
4064
5522
  };
4065
5523
 
4066
5524
  // src/templates/waveform/components/WaveformLine.tsx
4067
- import React29, { useMemo as useMemo19 } from "react";
5525
+ import React36, { useMemo as useMemo20 } from "react";
4068
5526
  import { createSmoothSvgPath } from "@remotion/media-utils";
4069
- import { useCurrentFrame as useCurrentFrame12, useVideoConfig as useVideoConfig13 } from "remotion";
5527
+ import { useCurrentFrame as useCurrentFrame16, useVideoConfig as useVideoConfig17 } from "remotion";
4070
5528
  var detectBeat = (frequencyData, amplitudes, threshold = 0.7, bpm, frame = 0, fps = 30) => {
4071
5529
  if (!frequencyData || !amplitudes || frequencyData.length === 0) return false;
4072
5530
  if (bpm) {
@@ -4098,7 +5556,7 @@ var easingFunctions = {
4098
5556
  };
4099
5557
  var WaveformLine = ({ data }) => {
4100
5558
  const {
4101
- config: config15,
5559
+ config: config18,
4102
5560
  className = "",
4103
5561
  style = {},
4104
5562
  strokeColor = "#FF6B6B",
@@ -4126,7 +5584,7 @@ var WaveformLine = ({ data }) => {
4126
5584
  pulseColor = "#FFD700",
4127
5585
  pulseScale = 1.2
4128
5586
  } = data;
4129
- return /* @__PURE__ */ React29.createElement(Waveform, { config: config15, className, style }, /* @__PURE__ */ React29.createElement(
5587
+ return /* @__PURE__ */ React36.createElement(Waveform, { config: config18, className, style }, /* @__PURE__ */ React36.createElement(
4130
5588
  WaveformLineContent,
4131
5589
  {
4132
5590
  strokeColor,
@@ -4182,14 +5640,14 @@ var WaveformLineContent = ({
4182
5640
  pulseColor,
4183
5641
  pulseScale
4184
5642
  }) => {
4185
- const { waveformData, frequencyData, amplitudes, width, height, config: config15, frame, fps } = useWaveformContext();
4186
- const currentFrame = useCurrentFrame12();
4187
- const videoConfig = useVideoConfig13();
4188
- const isBeat = useMemo19(() => {
5643
+ const { waveformData, frequencyData, amplitudes, width, height, config: config18, frame, fps } = useWaveformContext();
5644
+ const currentFrame = useCurrentFrame16();
5645
+ const videoConfig = useVideoConfig17();
5646
+ const isBeat = useMemo20(() => {
4189
5647
  if (!beatSync || !frequencyData || !amplitudes) return false;
4190
5648
  return detectBeat(frequencyData, amplitudes, beatThreshold, bpm, currentFrame, fps);
4191
5649
  }, [beatSync, frequencyData, amplitudes, beatThreshold, bpm, currentFrame, fps]);
4192
- const beatProgress = useMemo19(() => {
5650
+ const beatProgress = useMemo20(() => {
4193
5651
  if (!isBeat || !beatAnimationDuration) return 0;
4194
5652
  const beatStartFrame = Math.floor(currentFrame / beatAnimationDuration) * beatAnimationDuration;
4195
5653
  const progress = (currentFrame - beatStartFrame) / beatAnimationDuration;
@@ -4199,19 +5657,19 @@ var WaveformLineContent = ({
4199
5657
  }
4200
5658
  return clampedProgress;
4201
5659
  }, [isBeat, currentFrame, beatAnimationDuration, smoothAnimation]);
4202
- const currentBeatMultiplier = useMemo19(() => {
5660
+ const currentBeatMultiplier = useMemo20(() => {
4203
5661
  if (!beatSync || !isBeat || !beatAmplitudeMultiplier || !amplitudeCurve) return 1;
4204
5662
  const easing = easingFunctions[amplitudeCurve];
4205
5663
  const easedProgress = easing(beatProgress);
4206
5664
  return 1 + (beatAmplitudeMultiplier - 1) * (1 - easedProgress);
4207
5665
  }, [beatSync, isBeat, beatProgress, beatAmplitudeMultiplier, amplitudeCurve]);
4208
- const smoothFactor = useMemo19(() => {
5666
+ const smoothFactor = useMemo20(() => {
4209
5667
  if (!beatSync) {
4210
5668
  return 0.3;
4211
5669
  }
4212
5670
  return smoothAnimation ? 0.7 : 1;
4213
5671
  }, [beatSync, smoothAnimation]);
4214
- const waveformPaths = useMemo19(() => {
5672
+ const waveformPaths = useMemo20(() => {
4215
5673
  if (!waveformData) return [];
4216
5674
  const paths = [];
4217
5675
  const segments = waveSegments || 1;
@@ -4227,8 +5685,8 @@ var WaveformLineContent = ({
4227
5685
  const points = waveformData.map((y, index) => {
4228
5686
  const progress = index / (waveformData.length - 1);
4229
5687
  const x = segmentStart + progress * segmentDataWidth + offset;
4230
- let animatedAmplitude = y * (config15.amplitude || 1) * currentBeatMultiplier * speed;
4231
- const baseAmplitude = y * (config15.amplitude || 1) * speed;
5688
+ let animatedAmplitude = y * (config18.amplitude || 1) * currentBeatMultiplier * speed;
5689
+ const baseAmplitude = y * (config18.amplitude || 1) * speed;
4232
5690
  const beatAmplitude = animatedAmplitude - baseAmplitude;
4233
5691
  animatedAmplitude = baseAmplitude + beatAmplitude * smoothFactor;
4234
5692
  const yPos = waveDirection === "horizontal" ? animatedAmplitude * height / 2 + height / 2 : animatedAmplitude * width / 2 + width / 2;
@@ -4238,11 +5696,11 @@ var WaveformLineContent = ({
4238
5696
  paths.push({ path, segmentIndex: i });
4239
5697
  }
4240
5698
  return paths;
4241
- }, [waveformData, width, height, config15.amplitude, currentBeatMultiplier, animationSpeed, waveSegments, waveSpacing, waveOffset, waveDirection, smoothFactor]);
5699
+ }, [waveformData, width, height, config18.amplitude, currentBeatMultiplier, animationSpeed, waveSegments, waveSpacing, waveOffset, waveDirection, smoothFactor]);
4242
5700
  if (!waveformData) {
4243
- return /* @__PURE__ */ React29.createElement("div", { className: "flex items-center justify-center w-full h-full text-gray-500" }, "Loading waveform...");
5701
+ return /* @__PURE__ */ React36.createElement("div", { className: "flex items-center justify-center w-full h-full text-gray-500" }, "Loading waveform...");
4244
5702
  }
4245
- return /* @__PURE__ */ React29.createElement(
5703
+ return /* @__PURE__ */ React36.createElement(
4246
5704
  "svg",
4247
5705
  {
4248
5706
  width,
@@ -4250,7 +5708,7 @@ var WaveformLineContent = ({
4250
5708
  className: "absolute inset-0",
4251
5709
  style: { pointerEvents: "none" }
4252
5710
  },
4253
- centerLine && /* @__PURE__ */ React29.createElement(
5711
+ centerLine && /* @__PURE__ */ React36.createElement(
4254
5712
  "line",
4255
5713
  {
4256
5714
  x1: waveDirection === "horizontal" ? 0 : width / 2,
@@ -4262,7 +5720,7 @@ var WaveformLineContent = ({
4262
5720
  opacity: 0.3
4263
5721
  }
4264
5722
  ),
4265
- waveformPaths.map(({ path, segmentIndex }) => /* @__PURE__ */ React29.createElement("g", { key: segmentIndex }, pulseOnBeat && isBeat && /* @__PURE__ */ React29.createElement(
5723
+ waveformPaths.map(({ path, segmentIndex }) => /* @__PURE__ */ React36.createElement("g", { key: segmentIndex }, pulseOnBeat && isBeat && /* @__PURE__ */ React36.createElement(
4266
5724
  "path",
4267
5725
  {
4268
5726
  d: path,
@@ -4273,7 +5731,7 @@ var WaveformLineContent = ({
4273
5731
  fill: "none",
4274
5732
  opacity: (opacity || 1) * (1 - beatProgress)
4275
5733
  }
4276
- ), /* @__PURE__ */ React29.createElement(
5734
+ ), /* @__PURE__ */ React36.createElement(
4277
5735
  "path",
4278
5736
  {
4279
5737
  d: path,
@@ -4334,19 +5792,19 @@ registerComponent("WaveformCircle", WaveformCircle, "atom", {
4334
5792
 
4335
5793
  // src/components/Composition.tsx
4336
5794
  import { Player as RemotionPlayer } from "@remotion/player";
4337
- import React30 from "react";
5795
+ import React37 from "react";
4338
5796
  import { AbsoluteFill as AbsoluteFill7, Composition as RemotionComposition } from "remotion";
4339
- import z5 from "zod";
4340
- var CompositionLayout = ({ childrenData, style, config: config15 }) => {
4341
- return /* @__PURE__ */ React30.createElement(
5797
+ import z10 from "zod";
5798
+ var CompositionLayout = ({ childrenData, style, config: config18 }) => {
5799
+ return /* @__PURE__ */ React37.createElement(
4342
5800
  CompositionProvider,
4343
5801
  {
4344
5802
  value: {
4345
5803
  root: childrenData,
4346
- duration: config15.duration
5804
+ duration: config18.duration
4347
5805
  }
4348
5806
  },
4349
- /* @__PURE__ */ React30.createElement(AbsoluteFill7, { style }, childrenData?.map((component) => /* @__PURE__ */ React30.createElement(
5807
+ /* @__PURE__ */ React37.createElement(AbsoluteFill7, { style }, childrenData?.map((component) => /* @__PURE__ */ React37.createElement(
4350
5808
  ComponentRenderer,
4351
5809
  {
4352
5810
  key: component.id,
@@ -4386,26 +5844,26 @@ var calculateCompositionLayoutMetadata = async ({ props, defaultProps, abortSign
4386
5844
  var Composition = ({
4387
5845
  id,
4388
5846
  childrenData,
4389
- config: config15,
5847
+ config: config18,
4390
5848
  style
4391
5849
  }) => {
4392
- return /* @__PURE__ */ React30.createElement(
5850
+ return /* @__PURE__ */ React37.createElement(
4393
5851
  RemotionComposition,
4394
5852
  {
4395
5853
  id,
4396
5854
  component: CompositionLayout,
4397
- durationInFrames: Math.round(config15.duration * config15.fps),
4398
- fps: config15.fps,
4399
- width: config15.width ?? 1080,
4400
- height: config15.height ?? 1920,
4401
- defaultProps: { childrenData, style, config: config15 },
5855
+ durationInFrames: Math.round(config18.duration * config18.fps),
5856
+ fps: config18.fps,
5857
+ width: config18.width ?? 1080,
5858
+ height: config18.height ?? 1920,
5859
+ defaultProps: { childrenData, style, config: config18 },
4402
5860
  calculateMetadata: calculateCompositionLayoutMetadata,
4403
- schema: z5.object({})
5861
+ schema: z10.object({})
4404
5862
  }
4405
5863
  );
4406
5864
  };
4407
5865
  var Player = (props) => {
4408
- return /* @__PURE__ */ React30.createElement(
5866
+ return /* @__PURE__ */ React37.createElement(
4409
5867
  RemotionPlayer,
4410
5868
  {
4411
5869
  component: CompositionLayout,
@@ -4418,24 +5876,32 @@ var Player = (props) => {
4418
5876
  );
4419
5877
  };
4420
5878
  export {
4421
- Atom5 as AudioAtom,
4422
- config13 as AudioAtomConfig,
5879
+ Atom6 as AudioAtom,
5880
+ config15 as AudioAtomConfig,
4423
5881
  Layout as BaseLayout,
4424
- config8 as BaseLayoutConfig,
5882
+ config10 as BaseLayoutConfig,
4425
5883
  BlurEffect,
4426
5884
  config2 as BlurEffectConfig,
5885
+ Atom as CanvasAtom,
5886
+ config9 as CanvasAtomConfig,
5887
+ CanvasContentAwareReveal,
5888
+ CanvasGlitchEffect,
5889
+ CanvasParticleEffect,
5890
+ CanvasWipeReveal,
4427
5891
  ComponentRenderer,
4428
5892
  Composition,
4429
5893
  CompositionLayout,
4430
5894
  CompositionProvider,
4431
5895
  Frame,
4432
5896
  GenericEffectPresets,
4433
- Atom2 as ImageAtom,
4434
- config10 as ImageAtomConfig,
5897
+ Atom8 as HTMLBlockAtom,
5898
+ config17 as HTMLBlockAtomConfig,
5899
+ Atom3 as ImageAtom,
5900
+ config12 as ImageAtomConfig,
4435
5901
  LoopEffect,
4436
5902
  config3 as LoopEffectConfig,
4437
- Atom6 as LottieAtom,
4438
- config14 as LottieAtomConfig,
5903
+ Atom7 as LottieAtom,
5904
+ config16 as LottieAtomConfig,
4439
5905
  NextjsLogo,
4440
5906
  PanEffect,
4441
5907
  config4 as PanEffectConfig,
@@ -4445,19 +5911,21 @@ export {
4445
5911
  SceneFrame,
4446
5912
  ShakeEffect,
4447
5913
  config6 as ShakeEffectConfig,
4448
- Atom as ShapeAtom,
4449
- config9 as ShapeAtomConfig,
5914
+ Atom2 as ShapeAtom,
5915
+ config11 as ShapeAtomConfig,
4450
5916
  StretchEffect,
4451
5917
  config7 as StretchEffectConfig,
4452
- Atom3 as TextAtom,
4453
- config11 as TextAtomConfig,
5918
+ Atom4 as TextAtom,
5919
+ config13 as TextAtomConfig,
4454
5920
  TextFade,
4455
5921
  UniversalEffect,
4456
5922
  UniversalEffectProvider,
4457
- Atom4 as VideoAtom,
4458
- config12 as VideoAtomConfig,
5923
+ Atom5 as VideoAtom,
5924
+ config14 as VideoAtomConfig,
4459
5925
  Waveform,
4460
5926
  WaveformCircle,
5927
+ WaveformEffect,
5928
+ config8 as WaveformEffectConfig,
4461
5929
  WaveformHistogram,
4462
5930
  WaveformHistogramRanged,
4463
5931
  WaveformLine,