@microfox/remotion 1.2.2 → 1.2.5

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.js CHANGED
@@ -29,24 +29,32 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
29
29
  // src/index.ts
30
30
  var index_exports = {};
31
31
  __export(index_exports, {
32
- AudioAtom: () => Atom5,
33
- AudioAtomConfig: () => config13,
32
+ AudioAtom: () => Atom6,
33
+ AudioAtomConfig: () => config15,
34
34
  BaseLayout: () => Layout,
35
- BaseLayoutConfig: () => config8,
35
+ BaseLayoutConfig: () => config10,
36
36
  BlurEffect: () => BlurEffect,
37
37
  BlurEffectConfig: () => config2,
38
+ CanvasAtom: () => Atom,
39
+ CanvasAtomConfig: () => config9,
40
+ CanvasContentAwareReveal: () => CanvasContentAwareReveal,
41
+ CanvasGlitchEffect: () => CanvasGlitchEffect,
42
+ CanvasParticleEffect: () => CanvasParticleEffect,
43
+ CanvasWipeReveal: () => CanvasWipeReveal,
38
44
  ComponentRenderer: () => ComponentRenderer,
39
45
  Composition: () => Composition,
40
46
  CompositionLayout: () => CompositionLayout,
41
47
  CompositionProvider: () => CompositionProvider,
42
48
  Frame: () => Frame,
43
49
  GenericEffectPresets: () => GenericEffectPresets,
44
- ImageAtom: () => Atom2,
45
- ImageAtomConfig: () => config10,
50
+ HTMLBlockAtom: () => Atom8,
51
+ HTMLBlockAtomConfig: () => config17,
52
+ ImageAtom: () => Atom3,
53
+ ImageAtomConfig: () => config12,
46
54
  LoopEffect: () => LoopEffect,
47
55
  LoopEffectConfig: () => config3,
48
- LottieAtom: () => Atom6,
49
- LottieAtomConfig: () => config14,
56
+ LottieAtom: () => Atom7,
57
+ LottieAtomConfig: () => config16,
50
58
  NextjsLogo: () => NextjsLogo,
51
59
  PanEffect: () => PanEffect,
52
60
  PanEffectConfig: () => config4,
@@ -56,19 +64,21 @@ __export(index_exports, {
56
64
  SceneFrame: () => SceneFrame,
57
65
  ShakeEffect: () => ShakeEffect,
58
66
  ShakeEffectConfig: () => config6,
59
- ShapeAtom: () => Atom,
60
- ShapeAtomConfig: () => config9,
67
+ ShapeAtom: () => Atom2,
68
+ ShapeAtomConfig: () => config11,
61
69
  StretchEffect: () => StretchEffect,
62
70
  StretchEffectConfig: () => config7,
63
- TextAtom: () => Atom3,
64
- TextAtomConfig: () => config11,
71
+ TextAtom: () => Atom4,
72
+ TextAtomConfig: () => config13,
65
73
  TextFade: () => TextFade,
66
74
  UniversalEffect: () => UniversalEffect,
67
75
  UniversalEffectProvider: () => UniversalEffectProvider,
68
- VideoAtom: () => Atom4,
69
- VideoAtomConfig: () => config12,
76
+ VideoAtom: () => Atom5,
77
+ VideoAtomConfig: () => config14,
70
78
  Waveform: () => Waveform,
71
79
  WaveformCircle: () => WaveformCircle,
80
+ WaveformEffect: () => WaveformEffect,
81
+ WaveformEffectConfig: () => config8,
72
82
  WaveformHistogram: () => WaveformHistogram,
73
83
  WaveformHistogramRanged: () => WaveformHistogramRanged,
74
84
  WaveformLine: () => WaveformLine,
@@ -135,21 +145,21 @@ var ComponentRegistryManager = class {
135
145
  this.registry = {};
136
146
  this.packageRegistry = {};
137
147
  }
138
- registerComponent(name, component, type, config15 = { displayName: "" }, packageName) {
139
- this.registry[name] = { component, config: config15 };
148
+ registerComponent(name, component, type, config18 = { displayName: "" }, packageName) {
149
+ this.registry[name] = { component, config: config18 };
140
150
  if (packageName) {
141
151
  if (!this.packageRegistry[packageName]) {
142
152
  this.packageRegistry[packageName] = {};
143
153
  }
144
- this.packageRegistry[packageName][name] = { component, config: config15 };
154
+ this.packageRegistry[packageName][name] = { component, config: config18 };
145
155
  }
146
156
  }
147
- registerEffect(name, component, config15 = { displayName: "" }, packageName) {
157
+ registerEffect(name, component, config18 = { displayName: "" }, packageName) {
148
158
  this.registerComponent(
149
159
  name?.includes("effect-") ? name : `effect-${name}`,
150
160
  component,
151
161
  "layout",
152
- config15,
162
+ config18,
153
163
  packageName
154
164
  );
155
165
  }
@@ -164,8 +174,8 @@ var ComponentRegistryManager = class {
164
174
  }
165
175
  registerPackage(packageName, components) {
166
176
  this.packageRegistry[packageName] = components;
167
- Object.entries(components).forEach(([name, { component, config: config15 }]) => {
168
- this.registry[`${packageName}:${name}`] = { component, config: config15 };
177
+ Object.entries(components).forEach(([name, { component, config: config18 }]) => {
178
+ this.registry[`${packageName}:${name}`] = { component, config: config18 };
169
179
  });
170
180
  }
171
181
  getPackageComponents(packageName) {
@@ -180,17 +190,17 @@ var ComponentRegistryManager = class {
180
190
  }
181
191
  };
182
192
  var componentRegistry = new ComponentRegistryManager();
183
- var registerComponent = (name, component, type, config15 = { displayName: "" }, packageName) => {
193
+ var registerComponent = (name, component, type, config18 = { displayName: "" }, packageName) => {
184
194
  componentRegistry.registerComponent(
185
195
  name,
186
196
  component,
187
197
  type,
188
- config15,
198
+ config18,
189
199
  packageName
190
200
  );
191
201
  };
192
- var registerEffect = (name, component, config15 = { displayName: "" }, packageName) => {
193
- componentRegistry.registerEffect(name, component, config15, packageName);
202
+ var registerEffect = (name, component, config18 = { displayName: "" }, packageName) => {
203
+ componentRegistry.registerEffect(name, component, config18, packageName);
194
204
  };
195
205
  var registerPackage = (packageName, components) => {
196
206
  componentRegistry.registerPackage(packageName, components);
@@ -215,6 +225,13 @@ var useComposition = () => {
215
225
 
216
226
  // src/core/context/timing.ts
217
227
  var import_mediabunny = require("mediabunny");
228
+ var durationCache = /* @__PURE__ */ new Map();
229
+ var getDurationCacheKey = (src, startFrom, endAt, playbackRate) => {
230
+ const startFromStr = startFrom === void 0 ? "undefined" : String(startFrom);
231
+ const endAtStr = endAt === void 0 ? "undefined" : String(endAt);
232
+ const playbackRateStr = playbackRate === void 0 ? "1" : String(playbackRate);
233
+ return `${src}|${startFromStr}|${endAtStr}|${playbackRateStr}`;
234
+ };
218
235
  var findMatchingComponents = (childrenData, targetIds) => {
219
236
  const matches = [];
220
237
  const searchRecursively = (components) => {
@@ -257,34 +274,48 @@ var findMatchingComponentsByQuery = (childrenData, query) => {
257
274
  };
258
275
  var calculateComponentDuration = async (component) => {
259
276
  const src = component.data.src;
260
- if (src.startsWith("http")) {
261
- const audioInput = new import_mediabunny.Input({
262
- formats: import_mediabunny.ALL_FORMATS,
263
- source: new import_mediabunny.UrlSource(src)
264
- });
265
- const audioDuration = await audioInput.computeDuration();
266
- let trimmedDuration = audioDuration;
267
- if (component.data.startFrom || component.data.endAt) {
268
- trimmedDuration = audioDuration - (component.data.startFrom || 0) - (component.data.endAt ? audioDuration - (component.data.endAt || 0) : 0);
269
- }
277
+ if (src?.startsWith("http")) {
278
+ const startFrom = component.data.startFrom;
279
+ const endAt = component.data.endAt;
270
280
  const playbackRate = component.data.playbackRate || 1;
271
- const effectiveDuration = trimmedDuration / playbackRate;
272
- return effectiveDuration;
281
+ const cacheKey = getDurationCacheKey(src, startFrom, endAt, playbackRate);
282
+ if (durationCache.has(cacheKey)) {
283
+ return durationCache.get(cacheKey);
284
+ }
285
+ const calculationPromise = (async () => {
286
+ const audioInput = new import_mediabunny.Input({
287
+ formats: import_mediabunny.ALL_FORMATS,
288
+ source: new import_mediabunny.UrlSource(src)
289
+ });
290
+ const audioDuration = await audioInput.computeDuration();
291
+ let trimmedDuration = audioDuration;
292
+ if (startFrom || endAt) {
293
+ trimmedDuration = audioDuration - (startFrom || 0) - (endAt ? audioDuration - (endAt || 0) : 0);
294
+ }
295
+ const effectiveDuration = trimmedDuration / playbackRate;
296
+ return effectiveDuration;
297
+ })();
298
+ durationCache.set(cacheKey, calculationPromise);
299
+ return calculationPromise;
273
300
  } else {
274
301
  }
275
302
  };
276
- var calculateDuration = async (childrenData, config15) => {
303
+ var calculateDuration = async (childrenData, config18) => {
277
304
  let calculatedDuration = void 0;
278
- const targetIds = Array.isArray(config15.fitDurationTo) ? config15.fitDurationTo : [config15.fitDurationTo];
305
+ const targetIds = Array.isArray(config18.fitDurationTo) ? config18.fitDurationTo : [config18.fitDurationTo];
279
306
  const matchingComponents = findMatchingComponents(
280
307
  childrenData || [],
281
308
  targetIds
282
309
  );
283
310
  if (matchingComponents.length === 1) {
284
311
  if (matchingComponents[0].type === "atom" && (matchingComponents[0].componentId === "AudioAtom" || matchingComponents[0].componentId === "VideoAtom")) {
285
- calculatedDuration = await calculateComponentDuration(
286
- matchingComponents[0]
287
- );
312
+ if (matchingComponents[0].context?.timing?.duration) {
313
+ calculatedDuration = matchingComponents[0].context.timing.duration;
314
+ } else {
315
+ calculatedDuration = await calculateComponentDuration(
316
+ matchingComponents[0]
317
+ );
318
+ }
288
319
  }
289
320
  if ((matchingComponents[0].type === "scene" || matchingComponents[0].type === "layout") && matchingComponents[0].context?.timing?.duration) {
290
321
  calculatedDuration = matchingComponents[0].context.timing.duration;
@@ -293,6 +324,7 @@ var calculateDuration = async (childrenData, config15) => {
293
324
  return calculatedDuration;
294
325
  };
295
326
  var setDurationsInContext = async (root) => {
327
+ durationCache.clear();
296
328
  const iterateRecursively = async (components, onlyScene = false) => {
297
329
  const updatedComponents = [];
298
330
  for (const component of components) {
@@ -304,12 +336,15 @@ var setDurationsInContext = async (root) => {
304
336
  );
305
337
  }
306
338
  if (updatedComponent.context?.timing?.fitDurationTo?.length > 0 && !onlyScene && updatedComponent.context?.timing?.fitDurationTo != updatedComponent.id && updatedComponent.context?.timing?.fitDurationTo != "this" && updatedComponent.context?.timing?.fitDurationTo != "fill") {
307
- const duration = await calculateDuration(
308
- updatedComponent.childrenData,
309
- {
310
- fitDurationTo: updatedComponent.context?.timing?.fitDurationTo
311
- }
312
- );
339
+ let duration = updatedComponent.context?.timing?.duration;
340
+ if (!duration) {
341
+ duration = await calculateDuration(
342
+ updatedComponent.childrenData,
343
+ {
344
+ fitDurationTo: updatedComponent.context?.timing?.fitDurationTo
345
+ }
346
+ );
347
+ }
313
348
  updatedComponent = {
314
349
  ...updatedComponent,
315
350
  context: {
@@ -332,6 +367,8 @@ var setDurationsInContext = async (root) => {
332
367
  (acc, child) => acc + (child.context?.timing?.duration ?? 0),
333
368
  0
334
369
  ) ?? 10;
370
+ } else {
371
+ duration = updatedComponent.context.timing.duration;
335
372
  }
336
373
  if (duration !== void 0) {
337
374
  updatedComponent.context = {
@@ -345,7 +382,13 @@ var setDurationsInContext = async (root) => {
345
382
  }
346
383
  if (updatedComponent.type === "atom" && !onlyScene) {
347
384
  if (updatedComponent.componentId === "VideoAtom" || updatedComponent.componentId === "AudioAtom") {
348
- const mediaDuration = await calculateComponentDuration(updatedComponent);
385
+ const needsDurationCalculation = !updatedComponent.context?.timing?.duration || updatedComponent.data?.loop && !updatedComponent.data?.srcDuration;
386
+ let mediaDuration;
387
+ if (needsDurationCalculation) {
388
+ mediaDuration = await calculateComponentDuration(updatedComponent);
389
+ } else {
390
+ mediaDuration = updatedComponent.context?.timing?.duration;
391
+ }
349
392
  if (!updatedComponent.context?.timing?.fitDurationTo) {
350
393
  updatedComponent.context = {
351
394
  ...updatedComponent.context || {},
@@ -356,9 +399,9 @@ var setDurationsInContext = async (root) => {
356
399
  };
357
400
  updatedComponent.data = {
358
401
  ...updatedComponent.data,
359
- ...updatedComponent.data.loop ? { srcDuration: mediaDuration } : {}
402
+ ...updatedComponent.data.loop && mediaDuration ? { srcDuration: mediaDuration } : {}
360
403
  };
361
- } else if (updatedComponent.context?.timing?.fitDurationTo) {
404
+ } else if (updatedComponent.context?.timing?.fitDurationTo && mediaDuration) {
362
405
  updatedComponent.data = {
363
406
  ...updatedComponent.data,
364
407
  srcDuration: mediaDuration
@@ -629,8 +672,8 @@ var ComponentRenderer = ({
629
672
  context
630
673
  };
631
674
  if (type === "layout") {
632
- const config15 = getComponentConfig(componentId);
633
- const isInnerSequence = config15?.isInnerSequence;
675
+ const config18 = getComponentConfig(componentId);
676
+ const isInnerSequence = config18?.isInnerSequence;
634
677
  if (isInnerSequence) {
635
678
  return /* @__PURE__ */ import_react3.default.createElement(RenderContext.Provider, { value: newContext }, /* @__PURE__ */ import_react3.default.createElement(ComponentClass, { ...props }, effects && effects.length > 0 ? /* @__PURE__ */ import_react3.default.createElement(EffectWrapper, { effects, context: newContext }, childrenData?.map((child) => /* @__PURE__ */ import_react3.default.createElement(ComponentRenderer, { key: child.id, ...child }))) : childrenData?.map((child) => /* @__PURE__ */ import_react3.default.createElement(ComponentRenderer, { key: child.id, ...child }))));
636
679
  }
@@ -673,8 +716,8 @@ var SceneFrame = ({ children }) => {
673
716
  };
674
717
 
675
718
  // src/components/layouts/BaseLayout.tsx
676
- var import_react13 = __toESM(require("react"));
677
- var import_remotion9 = require("remotion");
719
+ var import_react20 = __toESM(require("react"));
720
+ var import_remotion14 = require("remotion");
678
721
 
679
722
  // src/components/effects/BlurEffect.tsx
680
723
  var import_react7 = __toESM(require("react"));
@@ -688,10 +731,45 @@ var parseFunctionsString = (functions) => {
688
731
  if (!functions) {
689
732
  return result;
690
733
  }
691
- const regex = /(\w+)\(([^)]*)\)/g;
692
- let match;
693
- while ((match = regex.exec(functions)) !== null) {
694
- result.set(match[1], match[0]);
734
+ let i = 0;
735
+ while (i < functions.length) {
736
+ while (i < functions.length && /\s/.test(functions[i])) {
737
+ i++;
738
+ }
739
+ if (i >= functions.length) break;
740
+ const nameStart = i;
741
+ while (i < functions.length && /[\w-]/.test(functions[i])) {
742
+ i++;
743
+ }
744
+ if (i === nameStart) break;
745
+ const functionName = functions.substring(nameStart, i);
746
+ while (i < functions.length && /\s/.test(functions[i])) {
747
+ i++;
748
+ }
749
+ if (i >= functions.length || functions[i] !== "(") {
750
+ break;
751
+ }
752
+ i++;
753
+ let depth = 1;
754
+ const contentStart = i;
755
+ while (i < functions.length && depth > 0) {
756
+ if (functions[i] === "(") {
757
+ depth++;
758
+ } else if (functions[i] === ")") {
759
+ depth--;
760
+ }
761
+ if (depth > 0) {
762
+ i++;
763
+ }
764
+ }
765
+ if (depth === 0) {
766
+ const content = functions.substring(contentStart, i);
767
+ const fullFunction = `${functionName}(${content})`;
768
+ result.set(functionName, fullFunction);
769
+ i++;
770
+ } else {
771
+ break;
772
+ }
695
773
  }
696
774
  return result;
697
775
  };
@@ -855,11 +933,20 @@ var parseHexColor = (hex) => {
855
933
  var parseRgbaColor = (rgba) => {
856
934
  const match = rgba.match(/rgba?\(\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*(?:,\s*([\d.]+))?\s*\)/);
857
935
  if (match) {
936
+ let alpha = 1;
937
+ if (match[4]) {
938
+ const alphaValue = parseFloat(match[4]);
939
+ if (alphaValue > 1) {
940
+ alpha = Math.max(0, Math.min(1, alphaValue / 100));
941
+ } else {
942
+ alpha = Math.max(0, Math.min(1, alphaValue));
943
+ }
944
+ }
858
945
  return {
859
946
  r: Math.max(0, Math.min(255, parseInt(match[1], 10))),
860
947
  g: Math.max(0, Math.min(255, parseInt(match[2], 10))),
861
948
  b: Math.max(0, Math.min(255, parseInt(match[3], 10))),
862
- a: match[4] ? Math.max(0, Math.min(1, parseFloat(match[4]))) : 1
949
+ a: alpha
863
950
  };
864
951
  }
865
952
  return { r: 0, g: 0, b: 0, a: 1 };
@@ -873,14 +960,21 @@ var parseColor = (color) => {
873
960
  }
874
961
  return { r: 0, g: 0, b: 0, a: 1 };
875
962
  };
876
- var rgbaToString = (color) => {
877
- if (color.a === 1) {
878
- return `rgb(${Math.round(color.r)}, ${Math.round(color.g)}, ${Math.round(color.b)})`;
879
- } else {
880
- return `rgba(${Math.round(color.r)}, ${Math.round(color.g)}, ${Math.round(color.b)}, ${color.a})`;
963
+ var rgbaToString = (color, preserveFormat) => {
964
+ const r = Math.round(color.r);
965
+ const g = Math.round(color.g);
966
+ const b = Math.round(color.b);
967
+ const a = color.a;
968
+ if (preserveFormat) {
969
+ if (preserveFormat.hasSpaces) {
970
+ return `rgba(${r}, ${g}, ${b}, ${a})`;
971
+ } else {
972
+ return `rgba(${r},${g},${b},${a})`;
973
+ }
881
974
  }
975
+ return `rgba(${r}, ${g}, ${b}, ${a})`;
882
976
  };
883
- var interpolateColors = (color1, color2, progress) => {
977
+ var interpolateColors = (color1, color2, progress, preserveFormat) => {
884
978
  const parsedColor1 = parseColor(color1);
885
979
  const parsedColor2 = parseColor(color2);
886
980
  const interpolatedColor = {
@@ -889,7 +983,75 @@ var interpolateColors = (color1, color2, progress) => {
889
983
  b: (0, import_remotion4.interpolate)(progress, [0, 1], [parsedColor1.b, parsedColor2.b]),
890
984
  a: (0, import_remotion4.interpolate)(progress, [0, 1], [parsedColor1.a, parsedColor2.a])
891
985
  };
892
- return rgbaToString(interpolatedColor);
986
+ return rgbaToString(interpolatedColor, preserveFormat);
987
+ };
988
+ var findColorsInString = (str) => {
989
+ const matches = [];
990
+ const rgbaPattern = /rgba?\(\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*(?:,\s*([\d.]+))?\s*\)/g;
991
+ let match;
992
+ rgbaPattern.lastIndex = 0;
993
+ while ((match = rgbaPattern.exec(str)) !== null) {
994
+ matches.push({
995
+ fullMatch: match[0],
996
+ color: match[0],
997
+ startIndex: match.index,
998
+ endIndex: match.index + match[0].length
999
+ });
1000
+ }
1001
+ const hexPattern = /#([0-9a-fA-F]{3}|[0-9a-fA-F]{6}|[0-9a-fA-F]{8})\b/g;
1002
+ hexPattern.lastIndex = 0;
1003
+ while ((match = hexPattern.exec(str)) !== null) {
1004
+ matches.push({
1005
+ fullMatch: match[0],
1006
+ color: match[0],
1007
+ startIndex: match.index,
1008
+ endIndex: match.index + match[0].length
1009
+ });
1010
+ }
1011
+ return matches.sort((a, b) => a.startIndex - b.startIndex);
1012
+ };
1013
+ var interpolateColorsInString = (str1, str2, progress) => {
1014
+ const colors1 = findColorsInString(str1);
1015
+ const colors2 = findColorsInString(str2);
1016
+ if (colors1.length === 0 && colors2.length === 0) {
1017
+ return str1;
1018
+ }
1019
+ if (colors1.length === 0 || colors2.length === 0) {
1020
+ return str1;
1021
+ }
1022
+ const minLength = Math.min(colors1.length, colors2.length);
1023
+ const replacements = [];
1024
+ for (let i = 0; i < minLength; i++) {
1025
+ const color1 = colors1[i];
1026
+ const color2 = colors2[i];
1027
+ const originalColor = color1.color;
1028
+ const hasSpaces = originalColor.includes(", ");
1029
+ const interpolatedColor = interpolateColors(color1.color, color2.color, progress, { hasSpaces });
1030
+ replacements.push({
1031
+ startIndex: color1.startIndex,
1032
+ endIndex: color1.endIndex,
1033
+ replacement: interpolatedColor
1034
+ });
1035
+ }
1036
+ replacements.sort((a, b) => b.startIndex - a.startIndex);
1037
+ let result = str1;
1038
+ for (const replacement of replacements) {
1039
+ const originalSubstring = result.substring(replacement.startIndex, replacement.endIndex);
1040
+ const expectedColor = colors1.find((c) => c.startIndex === replacement.startIndex);
1041
+ if (expectedColor && (originalSubstring === expectedColor.color || originalSubstring.trim().match(/^rgba?\(/i))) {
1042
+ result = result.substring(0, replacement.startIndex) + replacement.replacement + result.substring(replacement.endIndex);
1043
+ } else {
1044
+ const currentColors = findColorsInString(result);
1045
+ const matchingColor = currentColors.find(
1046
+ (c) => Math.abs(c.startIndex - replacement.startIndex) < 30
1047
+ // Allow some offset
1048
+ );
1049
+ if (matchingColor) {
1050
+ result = result.substring(0, matchingColor.startIndex) + replacement.replacement + result.substring(matchingColor.endIndex);
1051
+ }
1052
+ }
1053
+ }
1054
+ return result;
893
1055
  };
894
1056
  var calculateAnimatedValue = (ranges, progress, key) => {
895
1057
  const sortedRanges = [...ranges].sort((a, b) => a.prog - b.prog);
@@ -925,6 +1087,11 @@ var calculateAnimatedValue = (ranges, progress, key) => {
925
1087
  if (isColor(currentValue) && isColor(nextValue)) {
926
1088
  return interpolateColors(currentValue, nextValue, localProgress);
927
1089
  }
1090
+ const colors1 = findColorsInString(currentValue);
1091
+ const colors2 = findColorsInString(nextValue);
1092
+ if (colors1.length > 0 || colors2.length > 0) {
1093
+ return interpolateColorsInString(currentValue, nextValue, localProgress);
1094
+ }
928
1095
  const getUnitAndValue = (str) => {
929
1096
  const units = ["vmax", "vmin", "rem", "deg", "bpm", "vh", "vw", "px", "em", "ms", "hz", "db", "fr", "s", "%"];
930
1097
  for (const unit of units) {
@@ -973,7 +1140,7 @@ var rangesToCSSProperties = (ranges, progress) => {
973
1140
  const value = calculateAnimatedValue(keyRanges, progress, key);
974
1141
  switch (key) {
975
1142
  case "scale":
976
- styles.transform = `scale(${value})`;
1143
+ styles.transform = `${styles.transform || ""} scale(${value})`.trim();
977
1144
  break;
978
1145
  case "rotate":
979
1146
  const rotateValue = typeof value === "string" && value.includes("deg") ? value : `${value}deg`;
@@ -1879,205 +2046,1713 @@ var config7 = {
1879
2046
  }
1880
2047
  };
1881
2048
 
1882
- // src/components/effects/GenericPresets.ts
1883
- var fadeInPreset = [
1884
- { key: "opacity", val: 0, prog: 0 },
1885
- { key: "opacity", val: 1, prog: 1 }
1886
- ];
1887
- var fadeOutPreset = [
1888
- { key: "opacity", val: 1, prog: 0 },
1889
- { key: "opacity", val: 0, prog: 1 }
1890
- ];
1891
- var scaleInPreset = [
1892
- { key: "scale", val: 0, prog: 0 },
1893
- { key: "scale", val: 1, prog: 1 }
1894
- ];
1895
- var scaleOutPreset = [
1896
- { key: "scale", val: 1, prog: 0 },
1897
- { key: "scale", val: 0, prog: 1 }
1898
- ];
1899
- var slideInLeftPreset = [
1900
- { key: "translateX", val: -100, prog: 0 },
1901
- { key: "translateX", val: 0, prog: 1 }
1902
- ];
1903
- var slideInRightPreset = [
1904
- { key: "translateX", val: 100, prog: 0 },
1905
- { key: "translateX", val: 0, prog: 1 }
1906
- ];
1907
- var slideInTopPreset = [
1908
- { key: "translateY", val: -100, prog: 0 },
1909
- { key: "translateY", val: 0, prog: 1 }
1910
- ];
1911
- var slideInBottomPreset = [
1912
- { key: "translateY", val: 100, prog: 0 },
1913
- { key: "translateY", val: 0, prog: 1 }
1914
- ];
1915
- var bouncePreset = [
1916
- { key: "scale", val: 0, prog: 0 },
1917
- { key: "scale", val: 1.2, prog: 0.6 },
1918
- { key: "scale", val: 1, prog: 1 }
1919
- ];
1920
- var pulsePreset = [
1921
- { key: "scale", val: 1, prog: 0 },
1922
- { key: "scale", val: 1.1, prog: 0.5 },
1923
- { key: "scale", val: 1, prog: 1 }
1924
- ];
1925
- var rotateInPreset = [
1926
- { key: "rotate", val: -180, prog: 0 },
1927
- { key: "rotate", val: 0, prog: 1 }
1928
- ];
1929
- var blurInPreset = [
1930
- { key: "blur", val: 10, prog: 0 },
1931
- { key: "blur", val: 0, prog: 1 }
1932
- ];
1933
- var fadeInScalePreset = [
1934
- { key: "opacity", val: 0, prog: 0 },
1935
- { key: "opacity", val: 1, prog: 1 },
1936
- { key: "scale", val: 0.8, prog: 0 },
1937
- { key: "scale", val: 1, prog: 1 }
1938
- ];
1939
- var slideInFadePreset = [
1940
- { key: "translateX", val: -50, prog: 0 },
1941
- { key: "translateX", val: 0, prog: 1 },
1942
- { key: "opacity", val: 0, prog: 0 },
1943
- { key: "opacity", val: 1, prog: 1 }
1944
- ];
1945
- var slideInLeftStringPreset = [
1946
- { key: "translateX", val: "-100px", prog: 0 },
1947
- { key: "translateX", val: "0px", prog: 1 }
1948
- ];
1949
- var slideInRightStringPreset = [
1950
- { key: "translateX", val: "100px", prog: 0 },
1951
- { key: "translateX", val: "0px", prog: 1 }
1952
- ];
1953
- var slideInTopStringPreset = [
1954
- { key: "translateY", val: "-100px", prog: 0 },
1955
- { key: "translateY", val: "0px", prog: 1 }
1956
- ];
1957
- var slideInBottomStringPreset = [
1958
- { key: "translateY", val: "100px", prog: 0 },
1959
- { key: "translateY", val: "0px", prog: 1 }
1960
- ];
1961
- var rotateInStringPreset = [
1962
- { key: "rotate", val: "-180deg", prog: 0 },
1963
- { key: "rotate", val: "0deg", prog: 1 }
1964
- ];
1965
- var blurInStringPreset = [
1966
- { key: "blur", val: "10px", prog: 0 },
1967
- { key: "blur", val: "0px", prog: 1 }
1968
- ];
1969
- var scaleInStringPreset = [
1970
- { key: "scale", val: 0, prog: 0 },
1971
- { key: "scale", val: 1, prog: 1 }
1972
- ];
1973
- var slideInLeftResponsivePreset = [
1974
- { key: "translateX", val: "-50vw", prog: 0 },
1975
- { key: "translateX", val: "0vw", prog: 1 }
1976
- ];
1977
- var slideInTopResponsivePreset = [
1978
- { key: "translateY", val: "-50vh", prog: 0 },
1979
- { key: "translateY", val: "0vh", prog: 1 }
1980
- ];
1981
- var backgroundColorPreset = [
1982
- { key: "backgroundColor", val: "#ff0000", prog: 0 },
1983
- { key: "backgroundColor", val: "#0000ff", prog: 1 }
1984
- ];
1985
- var borderRadiusPreset = [
1986
- { key: "borderRadius", val: "0px", prog: 0 },
1987
- { key: "borderRadius", val: "50px", prog: 1 }
1988
- ];
1989
- var boxShadowPreset = [
1990
- { key: "boxShadow", val: "0px 0px 0px rgba(0,0,0,0)", prog: 0 },
1991
- { key: "boxShadow", val: "10px 10px 20px rgba(0,0,0,0.5)", prog: 1 }
1992
- ];
1993
- var fontSizePreset = [
1994
- { key: "fontSize", val: "12px", prog: 0 },
1995
- { key: "fontSize", val: "24px", prog: 1 }
1996
- ];
1997
- var letterSpacingPreset = [
1998
- { key: "letterSpacing", val: "0px", prog: 0 },
1999
- { key: "letterSpacing", val: "5px", prog: 1 }
2000
- ];
2001
- var lineHeightPreset = [
2002
- { key: "lineHeight", val: "1", prog: 0 },
2003
- { key: "lineHeight", val: "2", prog: 1 }
2004
- ];
2005
- var textShadowPreset = [
2006
- { key: "textShadow", val: "0px 0px 0px rgba(0,0,0,0)", prog: 0 },
2007
- { key: "textShadow", val: "2px 2px 4px rgba(0,0,0,0.5)", prog: 1 }
2008
- ];
2009
- var widthPreset = [
2010
- { key: "width", val: "0px", prog: 0 },
2011
- { key: "width", val: "100%", prog: 1 }
2012
- ];
2013
- var heightPreset = [
2014
- { key: "height", val: "0px", prog: 0 },
2015
- { key: "height", val: "100%", prog: 1 }
2016
- ];
2017
- var marginPreset = [
2018
- { key: "margin", val: "0px", prog: 0 },
2019
- { key: "margin", val: "20px", prog: 1 }
2020
- ];
2021
- var paddingPreset = [
2022
- { key: "padding", val: "0px", prog: 0 },
2023
- { key: "padding", val: "20px", prog: 1 }
2024
- ];
2025
- var morphingCardPreset = [
2026
- { key: "borderRadius", val: "0px", prog: 0 },
2027
- { key: "borderRadius", val: "20px", prog: 0.5 },
2028
- { key: "borderRadius", val: "50px", prog: 1 },
2029
- { key: "boxShadow", val: "0px 0px 0px rgba(0,0,0,0)", prog: 0 },
2030
- { key: "boxShadow", val: "0px 10px 30px rgba(0,0,0,0.3)", prog: 1 },
2031
- { key: "backgroundColor", val: "#ffffff", prog: 0 },
2032
- { key: "backgroundColor", val: "#f0f0f0", prog: 1 }
2033
- ];
2034
- var textRevealPreset = [
2035
- { key: "opacity", val: 0, prog: 0 },
2036
- { key: "opacity", val: 1, prog: 1 },
2037
- { key: "letterSpacing", val: "10px", prog: 0 },
2038
- { key: "letterSpacing", val: "0px", prog: 1 },
2039
- { key: "textShadow", val: "0px 0px 0px rgba(0,0,0,0)", prog: 0 },
2040
- { key: "textShadow", val: "2px 2px 4px rgba(0,0,0,0.5)", prog: 1 }
2041
- ];
2042
- var GenericEffectPresets = {
2043
- fadeInPreset,
2044
- fadeOutPreset,
2045
- scaleInPreset,
2046
- scaleOutPreset,
2047
- slideInLeftPreset,
2048
- slideInRightPreset,
2049
- slideInTopPreset,
2050
- slideInBottomPreset,
2051
- bouncePreset,
2052
- pulsePreset,
2053
- rotateInPreset,
2054
- blurInPreset,
2055
- fadeInScalePreset,
2056
- slideInFadePreset,
2057
- // String-based presets
2058
- slideInLeftStringPreset,
2059
- slideInRightStringPreset,
2060
- slideInTopStringPreset,
2061
- slideInBottomStringPreset,
2062
- rotateInStringPreset,
2063
- blurInStringPreset,
2064
- scaleInStringPreset,
2065
- slideInLeftResponsivePreset,
2066
- slideInTopResponsivePreset,
2067
- // Custom CSS property presets
2068
- backgroundColorPreset,
2069
- borderRadiusPreset,
2070
- boxShadowPreset,
2071
- fontSizePreset,
2072
- letterSpacingPreset,
2073
- lineHeightPreset,
2074
- textShadowPreset,
2075
- widthPreset,
2076
- heightPreset,
2077
- marginPreset,
2078
- paddingPreset,
2079
- morphingCardPreset,
2080
- textRevealPreset
2049
+ // src/components/effects/WaveformEffect.tsx
2050
+ var import_react14 = __toESM(require("react"));
2051
+
2052
+ // src/templates/waveform/hooks/useWaveformData.ts
2053
+ var import_react13 = require("react");
2054
+ var import_media_utils = require("@remotion/media-utils");
2055
+ var import_remotion9 = require("remotion");
2056
+ var isValidPowerOfTwo = (num) => {
2057
+ return num > 0 && (num & num - 1) === 0;
2058
+ };
2059
+ var getClosestPowerOfTwo = (num) => {
2060
+ if (num <= 0) return 32;
2061
+ let power = 1;
2062
+ while (power < num) {
2063
+ power *= 2;
2064
+ }
2065
+ const lower = power / 2;
2066
+ const upper = power;
2067
+ return Math.abs(num - lower) < Math.abs(num - upper) ? lower : upper;
2068
+ };
2069
+ var useWaveformData = (config18) => {
2070
+ const {
2071
+ audioSrc,
2072
+ numberOfSamples,
2073
+ windowInSeconds,
2074
+ dataOffsetInSeconds = 0,
2075
+ normalize = false,
2076
+ frame,
2077
+ fps,
2078
+ posterize,
2079
+ includeFrequencyData = false,
2080
+ minDb = -100,
2081
+ maxDb = -30,
2082
+ smoothNormalisation = 1
2083
+ } = config18;
2084
+ const { root } = useComposition();
2085
+ const validatedNumberOfSamples = (0, import_react13.useMemo)(() => {
2086
+ if (!isValidPowerOfTwo(numberOfSamples)) {
2087
+ console.warn(
2088
+ `numberOfSamples must be a power of 2. Adjusting ${numberOfSamples} to ${getClosestPowerOfTwo(numberOfSamples)}`
2089
+ );
2090
+ return getClosestPowerOfTwo(numberOfSamples);
2091
+ }
2092
+ return numberOfSamples;
2093
+ }, [numberOfSamples]);
2094
+ const { source, audioStartsFrom } = (0, import_react13.useMemo)(() => {
2095
+ if (audioSrc.startsWith("http")) {
2096
+ return { source: audioSrc, audioStartsFrom: void 0 };
2097
+ }
2098
+ if (audioSrc.startsWith("ref:")) {
2099
+ const matchingComponent = findMatchingComponents(root, [
2100
+ audioSrc.replace("ref:", "")
2101
+ ]);
2102
+ if (matchingComponent.length > 0) {
2103
+ const firstMatchingComponent = matchingComponent[0];
2104
+ if (firstMatchingComponent.componentId === "AudioAtom") {
2105
+ return {
2106
+ source: firstMatchingComponent.data.src,
2107
+ audioStartsFrom: firstMatchingComponent.data?.startFrom ?? void 0
2108
+ };
2109
+ }
2110
+ if (firstMatchingComponent.type === "layout" || firstMatchingComponent.type === "scene") {
2111
+ const audioComponents = findMatchingComponentsByQuery(
2112
+ firstMatchingComponent.childrenData,
2113
+ { componentId: "AudioAtom" }
2114
+ );
2115
+ if (audioComponents.length > 0) {
2116
+ return {
2117
+ source: audioComponents[0].data.src,
2118
+ audioStartsFrom: audioComponents[0].data?.startFrom ?? void 0
2119
+ };
2120
+ }
2121
+ }
2122
+ }
2123
+ }
2124
+ return { source: (0, import_remotion9.staticFile)(audioSrc), audioStartsFrom: void 0 };
2125
+ }, [audioSrc]);
2126
+ const audioData = (0, import_media_utils.useAudioData)(source);
2127
+ const adjustedFrame = (0, import_react13.useMemo)(() => {
2128
+ if (posterize && posterize > 1) {
2129
+ return Math.round(frame / posterize) * posterize;
2130
+ }
2131
+ let offset = 0;
2132
+ if (audioStartsFrom && audioStartsFrom != 0) {
2133
+ offset += Math.round(audioStartsFrom * fps);
2134
+ }
2135
+ if (dataOffsetInSeconds != 0) {
2136
+ offset += Math.round(dataOffsetInSeconds * fps);
2137
+ }
2138
+ return frame + offset;
2139
+ }, [frame, posterize, dataOffsetInSeconds, audioStartsFrom]);
2140
+ const waveformData = (0, import_react13.useMemo)(() => {
2141
+ if (!audioData) return null;
2142
+ try {
2143
+ const baseSmoothingFrames = 3;
2144
+ const smoothingFrames = smoothNormalisation > 0 ? Math.floor(smoothNormalisation * baseSmoothingFrames) : 0;
2145
+ const samples = [];
2146
+ if (smoothingFrames === 0) {
2147
+ const waveform = (0, import_media_utils.visualizeAudioWaveform)({
2148
+ fps,
2149
+ frame: adjustedFrame,
2150
+ audioData,
2151
+ numberOfSamples: validatedNumberOfSamples,
2152
+ windowInSeconds,
2153
+ dataOffsetInSeconds: 0,
2154
+ normalize
2155
+ });
2156
+ return waveform;
2157
+ }
2158
+ for (let offset = -smoothingFrames; offset <= smoothingFrames; offset++) {
2159
+ const sampleFrame = adjustedFrame + offset;
2160
+ if (sampleFrame >= 0) {
2161
+ try {
2162
+ const waveform = (0, import_media_utils.visualizeAudioWaveform)({
2163
+ fps,
2164
+ frame: sampleFrame,
2165
+ audioData,
2166
+ numberOfSamples: validatedNumberOfSamples,
2167
+ windowInSeconds,
2168
+ dataOffsetInSeconds: 0,
2169
+ normalize
2170
+ });
2171
+ if (waveform && waveform.length > 0) {
2172
+ samples.push(waveform);
2173
+ }
2174
+ } catch (e) {
2175
+ }
2176
+ }
2177
+ }
2178
+ if (samples.length === 0) {
2179
+ const waveform = (0, import_media_utils.visualizeAudioWaveform)({
2180
+ fps,
2181
+ frame: adjustedFrame,
2182
+ audioData,
2183
+ numberOfSamples: validatedNumberOfSamples,
2184
+ windowInSeconds,
2185
+ dataOffsetInSeconds: 0,
2186
+ normalize
2187
+ });
2188
+ return waveform;
2189
+ }
2190
+ const averaged = new Array(validatedNumberOfSamples).fill(0);
2191
+ for (let i = 0; i < validatedNumberOfSamples; i++) {
2192
+ let sum = 0;
2193
+ let count = 0;
2194
+ for (const sample of samples) {
2195
+ if (sample[i] !== void 0) {
2196
+ sum += sample[i];
2197
+ count++;
2198
+ }
2199
+ }
2200
+ averaged[i] = count > 0 ? sum / count : 0;
2201
+ }
2202
+ return averaged;
2203
+ } catch (error2) {
2204
+ console.error("Error generating waveform:", error2);
2205
+ return null;
2206
+ }
2207
+ }, [
2208
+ audioData,
2209
+ adjustedFrame,
2210
+ fps,
2211
+ validatedNumberOfSamples,
2212
+ windowInSeconds,
2213
+ dataOffsetInSeconds,
2214
+ normalize,
2215
+ smoothNormalisation
2216
+ ]);
2217
+ const {
2218
+ frequencyData,
2219
+ amplitudes,
2220
+ bass,
2221
+ mid,
2222
+ treble,
2223
+ bassValues,
2224
+ midValues,
2225
+ trebleValues
2226
+ } = (0, import_react13.useMemo)(() => {
2227
+ if (!audioData || !includeFrequencyData) {
2228
+ return {
2229
+ frequencyData: null,
2230
+ amplitudes: null,
2231
+ bass: null,
2232
+ mid: null,
2233
+ treble: null,
2234
+ bassValues: null,
2235
+ midValues: null,
2236
+ trebleValues: null
2237
+ };
2238
+ }
2239
+ try {
2240
+ const baseSmoothingFrames = 3;
2241
+ const smoothingFrames = smoothNormalisation > 0 ? Math.floor(smoothNormalisation * baseSmoothingFrames) : 0;
2242
+ const frequencySamples = [];
2243
+ let frequencyData2;
2244
+ if (smoothingFrames === 0) {
2245
+ frequencyData2 = (0, import_media_utils.visualizeAudio)({
2246
+ fps,
2247
+ frame: adjustedFrame,
2248
+ audioData,
2249
+ numberOfSamples: validatedNumberOfSamples
2250
+ });
2251
+ } else {
2252
+ for (let offset = -smoothingFrames; offset <= smoothingFrames; offset++) {
2253
+ const sampleFrame = adjustedFrame + offset;
2254
+ if (sampleFrame >= 0) {
2255
+ try {
2256
+ const freqData = (0, import_media_utils.visualizeAudio)({
2257
+ fps,
2258
+ frame: sampleFrame,
2259
+ audioData,
2260
+ numberOfSamples: validatedNumberOfSamples
2261
+ });
2262
+ if (freqData && freqData.length > 0) {
2263
+ frequencySamples.push(freqData);
2264
+ }
2265
+ } catch (e) {
2266
+ }
2267
+ }
2268
+ }
2269
+ if (frequencySamples.length === 0) {
2270
+ frequencyData2 = (0, import_media_utils.visualizeAudio)({
2271
+ fps,
2272
+ frame: adjustedFrame,
2273
+ audioData,
2274
+ numberOfSamples: validatedNumberOfSamples
2275
+ });
2276
+ } else {
2277
+ frequencyData2 = new Array(validatedNumberOfSamples).fill(0);
2278
+ for (let i = 0; i < validatedNumberOfSamples; i++) {
2279
+ let sum = 0;
2280
+ let count = 0;
2281
+ for (const sample of frequencySamples) {
2282
+ if (sample[i] !== void 0) {
2283
+ sum += sample[i];
2284
+ count++;
2285
+ }
2286
+ }
2287
+ frequencyData2[i] = count > 0 ? sum / count : 0;
2288
+ }
2289
+ }
2290
+ }
2291
+ const { sampleRate } = audioData;
2292
+ const bassValues2 = [];
2293
+ const midValues2 = [];
2294
+ const trebleValues2 = [];
2295
+ for (let i = 0; i < frequencyData2.length; i++) {
2296
+ const freq = i * sampleRate / (2 * frequencyData2.length);
2297
+ const value = frequencyData2[i];
2298
+ if (freq >= 0 && freq < 250) {
2299
+ bassValues2.push(value * 2.5);
2300
+ } else if (freq >= 250 && freq < 4e3) {
2301
+ midValues2.push(value * 3);
2302
+ midValues2.push(value * 4.5);
2303
+ midValues2.push(value * 5);
2304
+ } else if (freq >= 4e3 && freq < sampleRate / 2) {
2305
+ trebleValues2.push(value * 30);
2306
+ }
2307
+ }
2308
+ const getAverage = (arr) => arr.length > 0 ? arr.reduce((a, b) => a + b, 0) / arr.length : 0;
2309
+ const bass2 = getAverage(bassValues2);
2310
+ const mid2 = getAverage(midValues2);
2311
+ const treble2 = getAverage(trebleValues2);
2312
+ const amplitudes2 = frequencyData2.map((value) => {
2313
+ const db = 20 * Math.log10(value);
2314
+ const scaled = (db - minDb) / (maxDb - minDb);
2315
+ return Math.max(0, Math.min(1, scaled));
2316
+ });
2317
+ return {
2318
+ frequencyData: frequencyData2,
2319
+ amplitudes: amplitudes2,
2320
+ bass: bass2,
2321
+ mid: mid2,
2322
+ treble: treble2,
2323
+ bassValues: bassValues2,
2324
+ midValues: midValues2,
2325
+ trebleValues: trebleValues2.reverse()
2326
+ };
2327
+ } catch (error2) {
2328
+ console.error("Error generating frequency data:", error2);
2329
+ return {
2330
+ frequencyData: null,
2331
+ amplitudes: null,
2332
+ bass: null,
2333
+ mid: null,
2334
+ treble: null
2335
+ };
2336
+ }
2337
+ }, [
2338
+ audioData,
2339
+ includeFrequencyData,
2340
+ adjustedFrame,
2341
+ fps,
2342
+ validatedNumberOfSamples,
2343
+ windowInSeconds,
2344
+ dataOffsetInSeconds,
2345
+ minDb,
2346
+ maxDb,
2347
+ smoothNormalisation
2348
+ ]);
2349
+ const isLoading = !audioData;
2350
+ const error = audioData === null && !isLoading ? "Failed to load audio data" : null;
2351
+ return {
2352
+ waveformData,
2353
+ frequencyData,
2354
+ amplitudes,
2355
+ audioData,
2356
+ isLoading,
2357
+ error,
2358
+ bass,
2359
+ bassValues,
2360
+ mid,
2361
+ midValues,
2362
+ treble,
2363
+ trebleValues
2364
+ };
2365
+ };
2366
+
2367
+ // src/components/effects/WaveformEffect.tsx
2368
+ var WaveformEffect = ({
2369
+ id,
2370
+ componentId,
2371
+ type,
2372
+ data,
2373
+ children,
2374
+ context
2375
+ }) => {
2376
+ const { progress, frame, mode, targetIds, effectData, fps } = useUniversalAnimation(data, context);
2377
+ const {
2378
+ audioSrc,
2379
+ numberOfSamples = 128,
2380
+ windowInSeconds,
2381
+ dataOffsetInSeconds = 0,
2382
+ normalize = false,
2383
+ useFrequencyData = true,
2384
+ audioProperty = "bass",
2385
+ sensitivity = 1,
2386
+ threshold = 0,
2387
+ smoothing = 0.5,
2388
+ smoothNormalisation = 1,
2389
+ effectType = "zoom",
2390
+ intensity = 1,
2391
+ minValue,
2392
+ maxValue,
2393
+ shakeAxis = "both",
2394
+ baseScale = 1,
2395
+ baseBrightness = 1,
2396
+ rotationRange = 15
2397
+ } = effectData;
2398
+ const parentContext = useUniversalEffectOptional();
2399
+ const analysisWindow = smoothNormalisation === 0 ? windowInSeconds || 1 / fps : windowInSeconds || Math.max(1 / fps, 0.05);
2400
+ const { bass, mid, treble, waveformData } = useWaveformData({
2401
+ audioSrc,
2402
+ numberOfSamples,
2403
+ windowInSeconds: analysisWindow,
2404
+ dataOffsetInSeconds,
2405
+ normalize,
2406
+ frame,
2407
+ fps,
2408
+ includeFrequencyData: useFrequencyData,
2409
+ smoothNormalisation
2410
+ });
2411
+ const audioIntensity = (0, import_react14.useMemo)(() => {
2412
+ let rawValue = 0;
2413
+ switch (audioProperty) {
2414
+ case "bass":
2415
+ rawValue = bass || 0;
2416
+ break;
2417
+ case "mid":
2418
+ rawValue = mid || 0;
2419
+ break;
2420
+ case "treble":
2421
+ rawValue = treble || 0;
2422
+ break;
2423
+ case "waveform":
2424
+ if (waveformData && waveformData.length > 0) {
2425
+ rawValue = waveformData.reduce((sum, val) => sum + Math.abs(val), 0) / waveformData.length;
2426
+ }
2427
+ break;
2428
+ case "frequency":
2429
+ rawValue = bass || 0;
2430
+ break;
2431
+ default:
2432
+ rawValue = bass || 0;
2433
+ }
2434
+ const thresholdedValue = Math.max(0, rawValue - threshold);
2435
+ const sensitizedValue = thresholdedValue * sensitivity;
2436
+ return Math.min(1, Math.max(0, sensitizedValue));
2437
+ }, [audioProperty, bass, mid, treble, waveformData, threshold, sensitivity]);
2438
+ const smoothedIntensity = (0, import_react14.useMemo)(() => {
2439
+ if (smoothNormalisation === 0) {
2440
+ return audioIntensity;
2441
+ }
2442
+ const smoothingPower = 1 + smoothing * 2;
2443
+ const smoothed = Math.pow(audioIntensity, smoothingPower);
2444
+ const baseline = 0.1;
2445
+ const filtered = smoothed * (1 - baseline * smoothing) + baseline * smoothing;
2446
+ return Math.min(1, Math.max(0, filtered));
2447
+ }, [audioIntensity, smoothing, smoothNormalisation]);
2448
+ const animatedStyles = (0, import_react14.useMemo)(() => {
2449
+ const intensityValue = smoothedIntensity || audioIntensity;
2450
+ let effectValue = intensityValue * intensity;
2451
+ if (minValue !== void 0 || maxValue !== void 0) {
2452
+ const defaultMin = effectType === "zoom" || effectType === "scale" ? baseScale : 0;
2453
+ const defaultMax = effectType === "zoom" || effectType === "scale" ? baseScale + intensity : intensity;
2454
+ const min = minValue !== void 0 ? minValue : defaultMin;
2455
+ const max = maxValue !== void 0 ? maxValue : defaultMax;
2456
+ effectValue = min + intensityValue * (max - min);
2457
+ } else {
2458
+ switch (effectType) {
2459
+ case "zoom":
2460
+ case "scale":
2461
+ effectValue = baseScale + intensityValue * intensity;
2462
+ break;
2463
+ case "exposure":
2464
+ effectValue = baseBrightness + intensityValue * intensity;
2465
+ break;
2466
+ case "blur":
2467
+ effectValue = intensityValue * intensity * 10;
2468
+ break;
2469
+ case "rotate":
2470
+ effectValue = (intensityValue - 0.5) * 2 * rotationRange;
2471
+ break;
2472
+ case "translateX":
2473
+ case "translateY":
2474
+ effectValue = (intensityValue - 0.5) * 2 * intensity * 50;
2475
+ break;
2476
+ default:
2477
+ effectValue = intensityValue * intensity;
2478
+ }
2479
+ }
2480
+ const styles = {};
2481
+ switch (effectType) {
2482
+ case "zoom":
2483
+ case "scale":
2484
+ styles.transform = `scale(${effectValue})`;
2485
+ break;
2486
+ case "shake":
2487
+ const shakeFrequency = 0.1;
2488
+ const shakeTime = frame * shakeFrequency;
2489
+ const shakeAmplitude = intensityValue * intensity * 20;
2490
+ const shakeX = shakeAxis === "x" || shakeAxis === "both" ? Math.sin(shakeTime * 2.3) * shakeAmplitude : 0;
2491
+ const shakeY = shakeAxis === "y" || shakeAxis === "both" ? Math.cos(shakeTime * 1.7) * shakeAmplitude : 0;
2492
+ styles.transform = `translateX(${shakeX}px) translateY(${shakeY}px)`;
2493
+ break;
2494
+ case "exposure":
2495
+ styles.filter = `brightness(${effectValue})`;
2496
+ break;
2497
+ case "blur":
2498
+ styles.filter = `blur(${effectValue}px)`;
2499
+ break;
2500
+ case "rotate":
2501
+ styles.transform = `rotate(${effectValue}deg)`;
2502
+ break;
2503
+ case "translateX":
2504
+ styles.transform = `translateX(${effectValue}px)`;
2505
+ break;
2506
+ case "translateY":
2507
+ styles.transform = `translateY(${effectValue}px)`;
2508
+ break;
2509
+ default:
2510
+ styles.transform = `scale(${effectValue})`;
2511
+ }
2512
+ if (parentContext && mode === "provider") {
2513
+ const combinedStyles = mergeCSSStyles_default(parentContext.animatedStyles, styles);
2514
+ return combinedStyles;
2515
+ }
2516
+ return styles;
2517
+ }, [
2518
+ smoothedIntensity,
2519
+ audioIntensity,
2520
+ effectType,
2521
+ intensity,
2522
+ minValue,
2523
+ maxValue,
2524
+ baseScale,
2525
+ baseBrightness,
2526
+ rotationRange,
2527
+ shakeAxis,
2528
+ mode,
2529
+ parentContext?.animatedStyles,
2530
+ frame
2531
+ // Add frame dependency for shake effect
2532
+ ]);
2533
+ const contextValue = (0, import_react14.useMemo)(
2534
+ () => ({
2535
+ animatedStyles,
2536
+ targetIds,
2537
+ effectType: "waveform"
2538
+ }),
2539
+ [animatedStyles, targetIds]
2540
+ );
2541
+ if (mode === "provider") {
2542
+ return /* @__PURE__ */ import_react14.default.createElement(UniversalEffectContext.Provider, { value: contextValue }, children);
2543
+ }
2544
+ return /* @__PURE__ */ import_react14.default.createElement("div", { ...effectData.props, style: animatedStyles }, children);
2545
+ };
2546
+ var config8 = {
2547
+ displayName: "waveform",
2548
+ description: "Waveform-driven effect that reacts to audio data (bass, mid, treble, waveform)",
2549
+ isInnerSequence: false,
2550
+ props: {
2551
+ audioSrc: {
2552
+ type: "string",
2553
+ required: true,
2554
+ description: "Audio source URL or ref:componentId"
2555
+ },
2556
+ audioProperty: {
2557
+ type: "enum",
2558
+ values: ["bass", "mid", "treble", "waveform", "frequency"],
2559
+ default: "bass",
2560
+ description: "Which audio property to react to"
2561
+ },
2562
+ effectType: {
2563
+ type: "enum",
2564
+ values: ["zoom", "shake", "exposure", "blur", "scale", "rotate", "translateX", "translateY"],
2565
+ default: "zoom",
2566
+ description: "Type of effect to apply"
2567
+ },
2568
+ intensity: {
2569
+ type: "number",
2570
+ default: 1,
2571
+ description: "Effect intensity multiplier"
2572
+ },
2573
+ sensitivity: {
2574
+ type: "number",
2575
+ default: 1,
2576
+ description: "Sensitivity multiplier for audio detection"
2577
+ },
2578
+ threshold: {
2579
+ type: "number",
2580
+ default: 0,
2581
+ description: "Minimum audio value to trigger effect"
2582
+ },
2583
+ smoothing: {
2584
+ type: "number",
2585
+ default: 0.5,
2586
+ description: "Smoothing factor (0-1) for audio data"
2587
+ },
2588
+ smoothNormalisation: {
2589
+ type: "number",
2590
+ default: 1,
2591
+ description: "Frame-based smoothing control (0 = no smoothing, 1 = default, >1 = more smoothing)"
2592
+ }
2593
+ }
2594
+ };
2595
+
2596
+ // src/components/effects/CanvasWipeReveal.tsx
2597
+ var import_react16 = __toESM(require("react"));
2598
+ var import_remotion10 = require("remotion");
2599
+ var import_zod3 = require("zod");
2600
+
2601
+ // src/components/atoms/CanvasAtom.tsx
2602
+ var import_react15 = __toESM(require("react"));
2603
+ var import_zod2 = require("zod");
2604
+ var CanvasAtomDataProps = import_zod2.z.object({
2605
+ className: import_zod2.z.string().optional(),
2606
+ style: import_zod2.z.record(import_zod2.z.string(), import_zod2.z.any()).optional()
2607
+ });
2608
+ var Atom = import_react15.default.forwardRef(({ data, id }, ref) => {
2609
+ const { className, style } = data;
2610
+ return /* @__PURE__ */ import_react15.default.createElement("canvas", { ref, className, style, id });
2611
+ });
2612
+ var config9 = {
2613
+ displayName: "CanvasAtom",
2614
+ type: "atom",
2615
+ isInnerSequence: false,
2616
+ props: CanvasAtomDataProps
2617
+ // The config points to the Zod schema for data
2618
+ };
2619
+
2620
+ // src/components/effects/CanvasWipeReveal.tsx
2621
+ var mulberry32 = (seed) => {
2622
+ return () => {
2623
+ let t = seed += 1831565813;
2624
+ t = Math.imul(t ^ t >>> 15, t | 1);
2625
+ t ^= t + Math.imul(t ^ t >>> 7, t | 61);
2626
+ return ((t ^ t >>> 14) >>> 0) / 4294967296;
2627
+ };
2628
+ };
2629
+ var CanvasWipeRevealProps = import_zod3.z.object({
2630
+ imageUrl: import_zod3.z.string().url(),
2631
+ revealDurationInFrames: import_zod3.z.number().min(1),
2632
+ revealType: import_zod3.z.enum(["wipe", "radial"]).default("wipe"),
2633
+ angle: import_zod3.z.number().default(0),
2634
+ fit: import_zod3.z.enum(["cover", "contain"]).default("cover"),
2635
+ edgeStyle: import_zod3.z.enum(["straight", "organic", "burn"]).default("straight"),
2636
+ edgeWaviness: import_zod3.z.number().default(30),
2637
+ edgeFrequency: import_zod3.z.number().default(4),
2638
+ backgroundColor: import_zod3.z.string().default("rgba(0,0,0,0)"),
2639
+ burnGlow: import_zod3.z.boolean().default(true),
2640
+ burnGlowColor: import_zod3.z.string().default("#ff6600"),
2641
+ burnGlowIntensity: import_zod3.z.number().default(1),
2642
+ organicRandomAmplitude: import_zod3.z.boolean().default(true),
2643
+ organicRandomWavelength: import_zod3.z.boolean().default(false)
2644
+ });
2645
+ var CanvasWipeReveal = ({ data, id }) => {
2646
+ const {
2647
+ imageUrl,
2648
+ revealDurationInFrames,
2649
+ revealType,
2650
+ angle,
2651
+ fit,
2652
+ edgeStyle,
2653
+ edgeWaviness,
2654
+ edgeFrequency,
2655
+ backgroundColor,
2656
+ burnGlow,
2657
+ burnGlowColor,
2658
+ burnGlowIntensity,
2659
+ organicRandomAmplitude,
2660
+ organicRandomWavelength
2661
+ } = data;
2662
+ const frame = (0, import_remotion10.useCurrentFrame)();
2663
+ const { width, height } = (0, import_remotion10.useVideoConfig)();
2664
+ const canvasRef = (0, import_react16.useRef)(null);
2665
+ const [image, setImage] = (0, import_react16.useState)(null);
2666
+ (0, import_react16.useEffect)(() => {
2667
+ const img = new window.Image();
2668
+ img.crossOrigin = "Anonymous";
2669
+ img.src = imageUrl;
2670
+ img.onload = () => setImage(img);
2671
+ }, [imageUrl]);
2672
+ (0, import_react16.useEffect)(() => {
2673
+ if (!canvasRef.current || !image) return;
2674
+ const context = canvasRef.current.getContext("2d");
2675
+ if (!context) return;
2676
+ context.canvas.width = width;
2677
+ context.canvas.height = height;
2678
+ context.fillStyle = backgroundColor;
2679
+ context.fillRect(0, 0, width, height);
2680
+ const progress = Math.min(frame / revealDurationInFrames, 1);
2681
+ if (progress === 0 && backgroundColor === "rgba(0,0,0,0)") return;
2682
+ const seed = id.split("").reduce((acc, char) => acc + char.charCodeAt(0), 0);
2683
+ context.save();
2684
+ context.beginPath();
2685
+ if (revealType === "radial") {
2686
+ const baseRadius = Math.sqrt(width * width + height * height) / 2 * progress;
2687
+ if (edgeStyle === "organic") {
2688
+ const points = 120;
2689
+ const random = mulberry32(seed);
2690
+ const amplitudes = Array.from(
2691
+ { length: points + 1 },
2692
+ () => organicRandomAmplitude ? 0.5 + random() : 1
2693
+ );
2694
+ const wavelengths = Array.from(
2695
+ { length: points + 1 },
2696
+ () => organicRandomWavelength ? 0.5 + random() * 1.5 : 1
2697
+ );
2698
+ for (let i = 0; i <= points; i++) {
2699
+ const p = i / points;
2700
+ const angle2 = p * Math.PI * 2;
2701
+ const wave = Math.sin(
2702
+ p * Math.PI * edgeFrequency * wavelengths[i] + frame * 0.1
2703
+ ) * edgeWaviness * progress * amplitudes[i];
2704
+ const radius = baseRadius + wave;
2705
+ const x = width / 2 + Math.cos(angle2) * radius;
2706
+ const y = height / 2 + Math.sin(angle2) * radius;
2707
+ if (i === 0) context.moveTo(x, y);
2708
+ else context.lineTo(x, y);
2709
+ }
2710
+ context.closePath();
2711
+ } else if (edgeStyle === "burn") {
2712
+ const points = 120;
2713
+ const random = mulberry32(seed);
2714
+ const randomValues = Array.from({ length: points + 1 }, () => random());
2715
+ const phaseOffsets = Array.from(
2716
+ { length: points + 1 },
2717
+ () => random() * Math.PI * 2
2718
+ );
2719
+ const sparklePoints = [];
2720
+ for (let i = 0; i <= points; i++) {
2721
+ const p = i / points;
2722
+ const angle2 = p * Math.PI * 2;
2723
+ const flicker = Math.sin(frame * 0.3 + phaseOffsets[i]);
2724
+ const burnOffset = (randomValues[i] * 2 - 1) * flicker * edgeWaviness * progress;
2725
+ const radius = baseRadius + burnOffset;
2726
+ const x = width / 2 + Math.cos(angle2) * radius;
2727
+ const y = height / 2 + Math.sin(angle2) * radius;
2728
+ if (burnGlow && i % 5 === 0 && flicker > 0.3) {
2729
+ sparklePoints.push({ x, y, intensity: flicker });
2730
+ }
2731
+ if (i === 0) context.moveTo(x, y);
2732
+ else context.lineTo(x, y);
2733
+ }
2734
+ context.closePath();
2735
+ if (burnGlow && sparklePoints.length > 0) {
2736
+ sparklePoints.forEach((point) => {
2737
+ const glowSize = 3 + point.intensity * 5 * burnGlowIntensity;
2738
+ if (isFinite(point.x) && isFinite(point.y) && isFinite(glowSize) && glowSize > 0) {
2739
+ const gradient = context.createRadialGradient(
2740
+ point.x,
2741
+ point.y,
2742
+ 0,
2743
+ point.x,
2744
+ point.y,
2745
+ glowSize
2746
+ );
2747
+ gradient.addColorStop(0, burnGlowColor);
2748
+ gradient.addColorStop(0.5, burnGlowColor + "80");
2749
+ gradient.addColorStop(1, burnGlowColor + "00");
2750
+ context.fillStyle = gradient;
2751
+ context.fillRect(
2752
+ point.x - glowSize,
2753
+ point.y - glowSize,
2754
+ glowSize * 2,
2755
+ glowSize * 2
2756
+ );
2757
+ }
2758
+ });
2759
+ }
2760
+ } else {
2761
+ context.arc(width / 2, height / 2, baseRadius, 0, Math.PI * 2);
2762
+ }
2763
+ } else {
2764
+ const angleInRadians = angle * Math.PI / 180;
2765
+ const diagonal = Math.sqrt(width * width + height * height);
2766
+ context.translate(width / 2, height / 2);
2767
+ context.rotate(angleInRadians);
2768
+ const wipeEdgePosition = progress * diagonal - diagonal / 2;
2769
+ if (edgeStyle === "burn") {
2770
+ const points = 100;
2771
+ const random = mulberry32(seed);
2772
+ const randomValues = Array.from({ length: points + 1 }, () => random());
2773
+ const phaseOffsets = Array.from(
2774
+ { length: points + 1 },
2775
+ () => random() * Math.PI * 2
2776
+ );
2777
+ const edgePoints = [];
2778
+ context.moveTo(wipeEdgePosition, -diagonal / 2);
2779
+ for (let i = 0; i <= points; i++) {
2780
+ const p = i / points;
2781
+ const y = (p - 0.5) * diagonal;
2782
+ const flicker = Math.sin(frame * 0.3 + phaseOffsets[i]);
2783
+ const x = wipeEdgePosition + (randomValues[i] * 2 - 1) * flicker * edgeWaviness;
2784
+ context.lineTo(x, y);
2785
+ edgePoints.push({ x, y });
2786
+ }
2787
+ context.lineTo(wipeEdgePosition, diagonal / 2);
2788
+ context.lineTo(-diagonal / 2, diagonal / 2);
2789
+ context.lineTo(-diagonal / 2, -diagonal / 2);
2790
+ context.closePath();
2791
+ if (burnGlow && progress > 0.01) {
2792
+ const random2 = mulberry32(seed + frame);
2793
+ for (let i = 0; i < edgePoints.length; i += 3) {
2794
+ const point = edgePoints[i];
2795
+ const flicker = Math.sin(frame * 0.3 + phaseOffsets[i]);
2796
+ if (flicker > 0.2) {
2797
+ const glowSize = 4 + random2() * 6 * flicker * burnGlowIntensity;
2798
+ if (isFinite(point.x) && isFinite(point.y) && isFinite(glowSize) && glowSize > 0) {
2799
+ const gradient = context.createRadialGradient(
2800
+ point.x,
2801
+ point.y,
2802
+ 0,
2803
+ point.x,
2804
+ point.y,
2805
+ glowSize
2806
+ );
2807
+ gradient.addColorStop(0, burnGlowColor);
2808
+ gradient.addColorStop(0.4, burnGlowColor + "CC");
2809
+ gradient.addColorStop(1, burnGlowColor + "00");
2810
+ context.fillStyle = gradient;
2811
+ context.fillRect(
2812
+ point.x - glowSize,
2813
+ point.y - glowSize,
2814
+ glowSize * 2,
2815
+ glowSize * 2
2816
+ );
2817
+ if (random2() > 0.85) {
2818
+ const sparkleSize = 2 + random2() * 3;
2819
+ context.fillStyle = "#ffffff";
2820
+ context.fillRect(
2821
+ point.x - sparkleSize / 2,
2822
+ point.y - sparkleSize / 2,
2823
+ sparkleSize,
2824
+ sparkleSize
2825
+ );
2826
+ }
2827
+ }
2828
+ }
2829
+ }
2830
+ }
2831
+ } else if (edgeStyle === "organic") {
2832
+ const points = 100;
2833
+ const random = mulberry32(seed);
2834
+ const amplitudes = Array.from(
2835
+ { length: points + 1 },
2836
+ () => organicRandomAmplitude ? 0.5 + random() : 1
2837
+ );
2838
+ const wavelengths = Array.from(
2839
+ { length: points + 1 },
2840
+ () => organicRandomWavelength ? 0.5 + random() * 1.5 : 1
2841
+ );
2842
+ context.moveTo(wipeEdgePosition, -diagonal / 2);
2843
+ for (let i = 0; i <= points; i++) {
2844
+ const p = i / points;
2845
+ const y = (p - 0.5) * diagonal;
2846
+ const wave = Math.sin(
2847
+ p * edgeFrequency * wavelengths[i] * Math.PI + frame * 0.1
2848
+ ) * edgeWaviness * amplitudes[i];
2849
+ context.lineTo(wipeEdgePosition + wave, y);
2850
+ }
2851
+ context.lineTo(wipeEdgePosition, diagonal / 2);
2852
+ context.lineTo(-diagonal / 2, diagonal / 2);
2853
+ context.lineTo(-diagonal / 2, -diagonal / 2);
2854
+ context.closePath();
2855
+ } else {
2856
+ context.rect(
2857
+ -diagonal / 2,
2858
+ -diagonal / 2,
2859
+ wipeEdgePosition + diagonal / 2,
2860
+ diagonal
2861
+ );
2862
+ }
2863
+ context.rotate(-angleInRadians);
2864
+ context.translate(-width / 2, -height / 2);
2865
+ }
2866
+ context.clip();
2867
+ let sx = 0, sy = 0, sWidth = image.width, sHeight = image.height;
2868
+ if (fit === "cover") {
2869
+ const imgAspect = image.width / image.height;
2870
+ const canvasAspect = width / height;
2871
+ if (imgAspect > canvasAspect) {
2872
+ sWidth = image.height * canvasAspect;
2873
+ sx = (image.width - sWidth) / 2;
2874
+ } else {
2875
+ sHeight = image.width / canvasAspect;
2876
+ sy = (image.height - sHeight) / 2;
2877
+ }
2878
+ }
2879
+ context.drawImage(image, sx, sy, sWidth, sHeight, 0, 0, width, height);
2880
+ context.restore();
2881
+ }, [
2882
+ frame,
2883
+ image,
2884
+ width,
2885
+ height,
2886
+ revealDurationInFrames,
2887
+ fit,
2888
+ revealType,
2889
+ angle,
2890
+ edgeStyle,
2891
+ edgeWaviness,
2892
+ edgeFrequency,
2893
+ id,
2894
+ backgroundColor,
2895
+ burnGlow,
2896
+ burnGlowColor,
2897
+ burnGlowIntensity,
2898
+ organicRandomAmplitude,
2899
+ organicRandomWavelength
2900
+ ]);
2901
+ return /* @__PURE__ */ import_react16.default.createElement(Atom, { ref: canvasRef, data: { className: "w-full h-full" }, id });
2902
+ };
2903
+
2904
+ // src/components/effects/CanvasContentAwareReveal.tsx
2905
+ var import_react17 = __toESM(require("react"));
2906
+ var import_remotion11 = require("remotion");
2907
+ var import_zod4 = require("zod");
2908
+ var CanvasContentAwareRevealProps = import_zod4.z.object({
2909
+ imageUrl: import_zod4.z.string().url(),
2910
+ revealDurationInFrames: import_zod4.z.number().min(1),
2911
+ fit: import_zod4.z.enum(["cover", "contain"]).default("cover"),
2912
+ backgroundColor: import_zod4.z.string().default("rgba(0,0,0,0)"),
2913
+ burnColorOrder: import_zod4.z.enum(["vibgyor", "luminance", "random"]).default("vibgyor"),
2914
+ revealMode: import_zod4.z.enum(["color", "direction", "combined"]).default("combined").describe("Reveal mode: color-only, direction-only, or combined"),
2915
+ direction: import_zod4.z.enum(["horizontal", "vertical", "diagonal-down", "diagonal-up", "top-to-bottom"]).default("top-to-bottom"),
2916
+ directionLayers: import_zod4.z.number().default(10).describe("Number of layers for horizontal/vertical patterns")
2917
+ });
2918
+ var CanvasContentAwareReveal = ({ data, id }) => {
2919
+ const {
2920
+ imageUrl,
2921
+ revealDurationInFrames,
2922
+ fit,
2923
+ backgroundColor,
2924
+ burnColorOrder,
2925
+ revealMode,
2926
+ direction,
2927
+ directionLayers
2928
+ } = data;
2929
+ const frame = (0, import_remotion11.useCurrentFrame)();
2930
+ const { width, height } = (0, import_remotion11.useVideoConfig)();
2931
+ const canvasRef = (0, import_react17.useRef)(null);
2932
+ const [image, setImage] = (0, import_react17.useState)(null);
2933
+ const [pixelBurnMap, setPixelBurnMap] = (0, import_react17.useState)(null);
2934
+ const [isProcessing, setIsProcessing] = (0, import_react17.useState)(false);
2935
+ const burnMapGeneratedRef = (0, import_react17.useRef)(false);
2936
+ const rgbToHsv = (r, g, b) => {
2937
+ r /= 255;
2938
+ g /= 255;
2939
+ b /= 255;
2940
+ const max = Math.max(r, g, b), min = Math.min(r, g, b), delta = max - min;
2941
+ let h = 0;
2942
+ if (delta !== 0) {
2943
+ if (max === r) h = (g - b) / delta % 6;
2944
+ else if (max === g) h = (b - r) / delta + 2;
2945
+ else h = (r - g) / delta + 4;
2946
+ h *= 60;
2947
+ if (h < 0) h += 360;
2948
+ }
2949
+ return [h, max === 0 ? 0 : delta / max, max];
2950
+ };
2951
+ const getLuminance = (r, g, b) => 0.299 * r + 0.587 * g + 0.114 * b;
2952
+ const hueToVibgyorOrder = (hue) => {
2953
+ if (hue >= 260 && hue <= 290) return 0;
2954
+ if (hue >= 240 && hue < 260) return 0.15;
2955
+ if (hue >= 200 && hue < 240) return 0.3;
2956
+ if (hue >= 120 && hue < 200) return 0.5;
2957
+ if (hue >= 50 && hue < 120) return 0.65;
2958
+ if (hue >= 20 && hue < 50) return 0.8;
2959
+ if (hue >= 290 || hue < 20) return 1;
2960
+ return hue / 360;
2961
+ };
2962
+ (0, import_react17.useEffect)(() => {
2963
+ const img = new window.Image();
2964
+ img.crossOrigin = "Anonymous";
2965
+ img.src = imageUrl;
2966
+ img.onload = () => {
2967
+ setImage(img);
2968
+ burnMapGeneratedRef.current = false;
2969
+ };
2970
+ }, [imageUrl]);
2971
+ (0, import_react17.useEffect)(() => {
2972
+ if (!image || isProcessing || burnMapGeneratedRef.current) return;
2973
+ setIsProcessing(true);
2974
+ setTimeout(() => {
2975
+ try {
2976
+ const canvas = document.createElement("canvas");
2977
+ const ctx = canvas.getContext("2d");
2978
+ if (!ctx) return;
2979
+ canvas.width = image.width;
2980
+ canvas.height = image.height;
2981
+ ctx.drawImage(image, 0, 0);
2982
+ const imageData = ctx.getImageData(0, 0, image.width, image.height);
2983
+ const pixels = imageData.data;
2984
+ const burnMap = new Float32Array(image.width * image.height);
2985
+ const rawValues = [];
2986
+ for (let i = 0; i < pixels.length; i += 4) {
2987
+ const pixelIndex = i / 4;
2988
+ const [r, g, b] = [pixels[i], pixels[i + 1], pixels[i + 2]];
2989
+ let burnValue = 0;
2990
+ if (burnColorOrder === "vibgyor") {
2991
+ const [h, s] = rgbToHsv(r, g, b);
2992
+ burnValue = hueToVibgyorOrder(h) * s + 0.5 * (1 - s);
2993
+ } else if (burnColorOrder === "luminance") {
2994
+ burnValue = getLuminance(r, g, b) / 255;
2995
+ } else {
2996
+ burnValue = pixelIndex * 2654435761 % 2147483648 / 2147483648;
2997
+ }
2998
+ rawValues.push(burnValue);
2999
+ }
3000
+ const numBuckets = 200;
3001
+ const buckets = new Array(numBuckets).fill(0);
3002
+ rawValues.forEach((val) => {
3003
+ buckets[Math.min(Math.floor(val * numBuckets), numBuckets - 1)]++;
3004
+ });
3005
+ const cumulative = new Array(numBuckets);
3006
+ cumulative[0] = buckets[0];
3007
+ for (let i = 1; i < numBuckets; i++) {
3008
+ cumulative[i] = cumulative[i - 1] + buckets[i];
3009
+ }
3010
+ rawValues.forEach((val, idx) => {
3011
+ const bucket = Math.min(Math.floor(val * numBuckets), numBuckets - 1);
3012
+ burnMap[idx] = cumulative[bucket] / (image.width * image.height);
3013
+ });
3014
+ if (revealMode === "direction" || revealMode === "combined") {
3015
+ for (let idx = 0; idx < image.width * image.height; idx++) {
3016
+ const x = idx % image.width;
3017
+ const y = Math.floor(idx / image.width);
3018
+ let directionValue = 0;
3019
+ if (direction === "horizontal") {
3020
+ const layer = Math.floor(y / (image.height / directionLayers));
3021
+ const isReverse = layer % 2 === 1;
3022
+ const xNorm = isReverse ? (image.width - x) / image.width : x / image.width;
3023
+ directionValue = layer / directionLayers + xNorm / directionLayers;
3024
+ } else if (direction === "vertical") {
3025
+ const layer = Math.floor(x / (image.width / directionLayers));
3026
+ const isReverse = layer % 2 === 1;
3027
+ const yNorm = isReverse ? (image.height - y) / image.height : y / image.height;
3028
+ directionValue = layer / directionLayers + yNorm / directionLayers;
3029
+ } else if (direction === "top-to-bottom") {
3030
+ directionValue = y / image.height;
3031
+ } else if (direction === "diagonal-down") {
3032
+ directionValue = (x + y) / (image.width + image.height);
3033
+ } else {
3034
+ directionValue = (x + (image.height - y)) / (image.width + image.height);
3035
+ }
3036
+ burnMap[idx] = revealMode === "combined" ? burnMap[idx] * 0.6 + directionValue * 0.4 : directionValue;
3037
+ }
3038
+ let minVal = burnMap[0];
3039
+ let maxVal = burnMap[0];
3040
+ for (let i = 1; i < burnMap.length; i++) {
3041
+ if (burnMap[i] < minVal) minVal = burnMap[i];
3042
+ if (burnMap[i] > maxVal) maxVal = burnMap[i];
3043
+ }
3044
+ const range = maxVal - minVal;
3045
+ if (range > 0) {
3046
+ for (let i = 0; i < burnMap.length; i++) {
3047
+ burnMap[i] = (burnMap[i] - minVal) / range;
3048
+ }
3049
+ }
3050
+ }
3051
+ setPixelBurnMap(burnMap);
3052
+ burnMapGeneratedRef.current = true;
3053
+ } finally {
3054
+ setIsProcessing(false);
3055
+ }
3056
+ }, 0);
3057
+ }, [
3058
+ image,
3059
+ burnColorOrder,
3060
+ revealMode,
3061
+ direction,
3062
+ directionLayers
3063
+ ]);
3064
+ (0, import_react17.useEffect)(() => {
3065
+ if (!canvasRef.current || !image || !pixelBurnMap) return;
3066
+ const context = canvasRef.current.getContext("2d");
3067
+ if (!context) return;
3068
+ context.canvas.width = width;
3069
+ context.canvas.height = height;
3070
+ context.fillStyle = backgroundColor;
3071
+ context.fillRect(0, 0, width, height);
3072
+ const progress = Math.min(frame / revealDurationInFrames, 1);
3073
+ if (progress >= 1) {
3074
+ let sx2 = 0, sy2 = 0, sWidth2 = image.width, sHeight2 = image.height;
3075
+ if (fit === "cover") {
3076
+ const imgAspect = image.width / image.height;
3077
+ const canvasAspect = width / height;
3078
+ if (imgAspect > canvasAspect) {
3079
+ sWidth2 = image.height * canvasAspect;
3080
+ sx2 = (image.width - sWidth2) / 2;
3081
+ } else {
3082
+ sHeight2 = image.width / canvasAspect;
3083
+ sy2 = (image.height - sHeight2) / 2;
3084
+ }
3085
+ }
3086
+ context.drawImage(image, sx2, sy2, sWidth2, sHeight2, 0, 0, width, height);
3087
+ return;
3088
+ }
3089
+ const tempCanvas = document.createElement("canvas");
3090
+ tempCanvas.width = image.width;
3091
+ tempCanvas.height = image.height;
3092
+ const tempCtx = tempCanvas.getContext("2d");
3093
+ if (!tempCtx) return;
3094
+ tempCtx.drawImage(image, 0, 0);
3095
+ const imageData = tempCtx.getImageData(0, 0, image.width, image.height);
3096
+ const pixels = imageData.data;
3097
+ const transitionWidth = Math.max(
3098
+ 0.02,
3099
+ Math.min(0.15, 3 / (revealDurationInFrames / 100))
3100
+ );
3101
+ for (let i = 0; i < pixels.length; i += 4) {
3102
+ const pixelIndex = i / 4;
3103
+ const burnProgress = (progress - pixelBurnMap[pixelIndex]) / transitionWidth;
3104
+ pixels[i + 3] = Math.floor(
3105
+ pixels[i + 3] * Math.max(0, Math.min(1, burnProgress))
3106
+ );
3107
+ }
3108
+ tempCtx.putImageData(imageData, 0, 0);
3109
+ let sx = 0, sy = 0, sWidth = image.width, sHeight = image.height;
3110
+ if (fit === "cover") {
3111
+ const imgAspect = image.width / image.height;
3112
+ const canvasAspect = width / height;
3113
+ if (imgAspect > canvasAspect) {
3114
+ sWidth = image.height * canvasAspect;
3115
+ sx = (image.width - sWidth) / 2;
3116
+ } else {
3117
+ sHeight = image.width / canvasAspect;
3118
+ sy = (image.height - sHeight) / 2;
3119
+ }
3120
+ }
3121
+ context.drawImage(tempCanvas, sx, sy, sWidth, sHeight, 0, 0, width, height);
3122
+ }, [
3123
+ frame,
3124
+ image,
3125
+ width,
3126
+ height,
3127
+ pixelBurnMap,
3128
+ revealDurationInFrames,
3129
+ fit,
3130
+ backgroundColor
3131
+ ]);
3132
+ return /* @__PURE__ */ import_react17.default.createElement(Atom, { ref: canvasRef, data: { className: "w-full h-full" }, id });
3133
+ };
3134
+
3135
+ // src/components/effects/CanvasGlitchEffect.tsx
3136
+ var import_react18 = __toESM(require("react"));
3137
+ var import_remotion12 = require("remotion");
3138
+ var import_zod5 = require("zod");
3139
+ var CanvasGlitchEffectProps = import_zod5.z.object({
3140
+ imageUrl: import_zod5.z.string().url(),
3141
+ durationInFrames: import_zod5.z.number().min(1),
3142
+ fit: import_zod5.z.enum(["cover", "contain"]).default("cover"),
3143
+ backgroundColor: import_zod5.z.string().default("rgba(0,0,0,0)"),
3144
+ glitchType: import_zod5.z.enum(["rgb-shift", "slice", "corrupt", "static", "scan"]).default("rgb-shift"),
3145
+ intensity: import_zod5.z.number().default(10).describe("Intensity of glitch effect"),
3146
+ frequency: import_zod5.z.number().default(0.3).describe("How often glitches occur (0-1)"),
3147
+ continuous: import_zod5.z.boolean().default(false).describe("Continuous glitch vs periodic"),
3148
+ glitchStartFrame: import_zod5.z.number().default(0).describe("Frame to start glitching"),
3149
+ glitchEndFrame: import_zod5.z.number().default(-1).describe("Frame to end glitching (-1 = duration)")
3150
+ });
3151
+ var CanvasGlitchEffect = ({ data, id }) => {
3152
+ const {
3153
+ imageUrl,
3154
+ durationInFrames,
3155
+ fit,
3156
+ backgroundColor,
3157
+ glitchType,
3158
+ intensity,
3159
+ frequency,
3160
+ continuous,
3161
+ glitchStartFrame,
3162
+ glitchEndFrame
3163
+ } = data;
3164
+ const frame = (0, import_remotion12.useCurrentFrame)();
3165
+ const { width, height } = (0, import_remotion12.useVideoConfig)();
3166
+ const canvasRef = (0, import_react18.useRef)(null);
3167
+ const [image, setImage] = (0, import_react18.useState)(null);
3168
+ (0, import_react18.useEffect)(() => {
3169
+ const img = new window.Image();
3170
+ img.crossOrigin = "Anonymous";
3171
+ img.src = imageUrl;
3172
+ img.onload = () => setImage(img);
3173
+ }, [imageUrl]);
3174
+ (0, import_react18.useEffect)(() => {
3175
+ if (!canvasRef.current || !image) return;
3176
+ const context = canvasRef.current.getContext("2d");
3177
+ if (!context) return;
3178
+ context.canvas.width = width;
3179
+ context.canvas.height = height;
3180
+ context.fillStyle = backgroundColor;
3181
+ context.fillRect(0, 0, width, height);
3182
+ const endFrame = glitchEndFrame === -1 ? durationInFrames : glitchEndFrame;
3183
+ const isInGlitchRange = frame >= glitchStartFrame && frame <= endFrame;
3184
+ const seed = Math.floor(frame / 3);
3185
+ const random = (seed * 9301 + 49297) % 233280 / 233280;
3186
+ const isGlitching = isInGlitchRange && (continuous || random < frequency);
3187
+ let sx = 0, sy = 0, sWidth = image.width, sHeight = image.height;
3188
+ if (fit === "cover") {
3189
+ const imgAspect = image.width / image.height;
3190
+ const canvasAspect = width / height;
3191
+ if (imgAspect > canvasAspect) {
3192
+ sWidth = image.height * canvasAspect;
3193
+ sx = (image.width - sWidth) / 2;
3194
+ } else {
3195
+ sHeight = image.width / canvasAspect;
3196
+ sy = (image.height - sHeight) / 2;
3197
+ }
3198
+ }
3199
+ if (!isGlitching) {
3200
+ context.drawImage(image, sx, sy, sWidth, sHeight, 0, 0, width, height);
3201
+ return;
3202
+ }
3203
+ if (glitchType === "rgb-shift") {
3204
+ const tempCanvas = document.createElement("canvas");
3205
+ tempCanvas.width = image.width;
3206
+ tempCanvas.height = image.height;
3207
+ const tempCtx = tempCanvas.getContext("2d");
3208
+ if (!tempCtx) return;
3209
+ tempCtx.drawImage(image, 0, 0);
3210
+ const imageData = tempCtx.getImageData(0, 0, image.width, image.height);
3211
+ const pixels = imageData.data;
3212
+ const shift = intensity * (random * 2 - 1);
3213
+ const redData = tempCtx.createImageData(image.width, image.height);
3214
+ const greenData = tempCtx.createImageData(image.width, image.height);
3215
+ const blueData = tempCtx.createImageData(image.width, image.height);
3216
+ for (let i = 0; i < pixels.length; i += 4) {
3217
+ redData.data[i] = pixels[i];
3218
+ redData.data[i + 3] = pixels[i + 3];
3219
+ greenData.data[i + 1] = pixels[i + 1];
3220
+ greenData.data[i + 3] = pixels[i + 3];
3221
+ blueData.data[i + 2] = pixels[i + 2];
3222
+ blueData.data[i + 3] = pixels[i + 3];
3223
+ }
3224
+ context.save();
3225
+ context.globalCompositeOperation = "screen";
3226
+ tempCtx.putImageData(redData, 0, 0);
3227
+ context.drawImage(
3228
+ tempCanvas,
3229
+ sx + shift,
3230
+ sy,
3231
+ sWidth,
3232
+ sHeight,
3233
+ shift,
3234
+ 0,
3235
+ width,
3236
+ height
3237
+ );
3238
+ tempCtx.putImageData(greenData, 0, 0);
3239
+ context.drawImage(
3240
+ tempCanvas,
3241
+ sx,
3242
+ sy,
3243
+ sWidth,
3244
+ sHeight,
3245
+ 0,
3246
+ 0,
3247
+ width,
3248
+ height
3249
+ );
3250
+ tempCtx.putImageData(blueData, 0, 0);
3251
+ context.drawImage(
3252
+ tempCanvas,
3253
+ sx - shift,
3254
+ sy,
3255
+ sWidth,
3256
+ sHeight,
3257
+ -shift,
3258
+ 0,
3259
+ width,
3260
+ height
3261
+ );
3262
+ context.restore();
3263
+ } else if (glitchType === "slice") {
3264
+ const sliceCount = 20;
3265
+ const sliceHeight = height / sliceCount;
3266
+ for (let i = 0; i < sliceCount; i++) {
3267
+ const offset = (random * 2 - 1) * intensity * (i % 2 === 0 ? 1 : -1);
3268
+ const sy_slice = sy + sHeight / sliceCount * i;
3269
+ const dy = sliceHeight * i;
3270
+ context.drawImage(
3271
+ image,
3272
+ sx,
3273
+ sy_slice,
3274
+ sWidth,
3275
+ sHeight / sliceCount,
3276
+ offset,
3277
+ dy,
3278
+ width,
3279
+ sliceHeight
3280
+ );
3281
+ }
3282
+ } else if (glitchType === "corrupt") {
3283
+ context.drawImage(image, sx, sy, sWidth, sHeight, 0, 0, width, height);
3284
+ const blockCount = Math.floor(intensity / 2);
3285
+ for (let i = 0; i < blockCount; i++) {
3286
+ const blockW = Math.random() * width * 0.3;
3287
+ const blockH = Math.random() * height * 0.2;
3288
+ const blockX = Math.random() * (width - blockW);
3289
+ const blockY = Math.random() * (height - blockH);
3290
+ const sourceX = Math.random() * (width - blockW);
3291
+ const sourceY = Math.random() * (height - blockH);
3292
+ try {
3293
+ const imgData = context.getImageData(
3294
+ sourceX,
3295
+ sourceY,
3296
+ blockW,
3297
+ blockH
3298
+ );
3299
+ context.putImageData(imgData, blockX, blockY);
3300
+ } catch (e) {
3301
+ }
3302
+ }
3303
+ } else if (glitchType === "static") {
3304
+ context.drawImage(image, sx, sy, sWidth, sHeight, 0, 0, width, height);
3305
+ const imageData = context.getImageData(0, 0, width, height);
3306
+ const pixels = imageData.data;
3307
+ for (let i = 0; i < pixels.length; i += 4) {
3308
+ if (Math.random() < intensity / 100) {
3309
+ const noise = Math.random() * 255;
3310
+ pixels[i] = noise;
3311
+ pixels[i + 1] = noise;
3312
+ pixels[i + 2] = noise;
3313
+ }
3314
+ }
3315
+ context.putImageData(imageData, 0, 0);
3316
+ } else if (glitchType === "scan") {
3317
+ context.drawImage(image, sx, sy, sWidth, sHeight, 0, 0, width, height);
3318
+ const scanY = frame * 5 % height;
3319
+ context.fillStyle = `rgba(255, 255, 255, ${intensity / 100})`;
3320
+ context.fillRect(0, scanY, width, 3);
3321
+ const distortY = Math.max(0, scanY - 10);
3322
+ const distortHeight = Math.min(20, height - distortY);
3323
+ if (distortHeight > 0) {
3324
+ try {
3325
+ const imgData = context.getImageData(
3326
+ 0,
3327
+ distortY,
3328
+ width,
3329
+ distortHeight
3330
+ );
3331
+ const shiftAmount = intensity * (random * 2 - 1);
3332
+ context.putImageData(imgData, shiftAmount, distortY);
3333
+ } catch (e) {
3334
+ }
3335
+ }
3336
+ }
3337
+ }, [
3338
+ frame,
3339
+ image,
3340
+ width,
3341
+ height,
3342
+ durationInFrames,
3343
+ fit,
3344
+ backgroundColor,
3345
+ glitchType,
3346
+ intensity,
3347
+ frequency,
3348
+ continuous,
3349
+ glitchStartFrame,
3350
+ glitchEndFrame
3351
+ ]);
3352
+ return /* @__PURE__ */ import_react18.default.createElement(Atom, { ref: canvasRef, data: { className: "w-full h-full" }, id });
3353
+ };
3354
+
3355
+ // src/components/effects/CanvasParticleEffect.tsx
3356
+ var import_react19 = __toESM(require("react"));
3357
+ var import_remotion13 = require("remotion");
3358
+ var import_zod6 = require("zod");
3359
+ var CanvasParticleEffectProps = import_zod6.z.object({
3360
+ imageUrl: import_zod6.z.string().url(),
3361
+ revealDurationInFrames: import_zod6.z.number().min(1),
3362
+ fit: import_zod6.z.enum(["cover", "contain"]).default("cover"),
3363
+ backgroundColor: import_zod6.z.string().default("rgba(0,0,0,0)"),
3364
+ particleCount: import_zod6.z.number().default(2e3).describe("Number of particles"),
3365
+ particleSize: import_zod6.z.number().default(3).describe("Size of each particle"),
3366
+ particleEffect: import_zod6.z.enum(["assemble", "disassemble", "explode", "pixelate"]).default("assemble"),
3367
+ assembleFrom: import_zod6.z.enum(["center", "edges", "random", "bottom"]).default("random"),
3368
+ speed: import_zod6.z.number().default(1).describe("Animation speed multiplier"),
3369
+ rotation: import_zod6.z.boolean().default(false).describe("Add rotation to particles")
3370
+ });
3371
+ var CanvasParticleEffect = ({ data, id }) => {
3372
+ const {
3373
+ imageUrl,
3374
+ revealDurationInFrames,
3375
+ fit,
3376
+ backgroundColor,
3377
+ particleCount,
3378
+ particleSize,
3379
+ particleEffect,
3380
+ assembleFrom,
3381
+ speed,
3382
+ rotation
3383
+ } = data;
3384
+ const frame = (0, import_remotion13.useCurrentFrame)();
3385
+ const { width, height } = (0, import_remotion13.useVideoConfig)();
3386
+ const canvasRef = (0, import_react19.useRef)(null);
3387
+ const [image, setImage] = (0, import_react19.useState)(null);
3388
+ const [particles, setParticles] = (0, import_react19.useState)(null);
3389
+ (0, import_react19.useEffect)(() => {
3390
+ const img = new window.Image();
3391
+ img.crossOrigin = "Anonymous";
3392
+ img.src = imageUrl;
3393
+ img.onload = () => setImage(img);
3394
+ }, [imageUrl]);
3395
+ (0, import_react19.useEffect)(() => {
3396
+ if (!image) return;
3397
+ const canvas = document.createElement("canvas");
3398
+ const ctx = canvas.getContext("2d");
3399
+ if (!ctx) return;
3400
+ canvas.width = image.width;
3401
+ canvas.height = image.height;
3402
+ ctx.drawImage(image, 0, 0);
3403
+ const imageData = ctx.getImageData(0, 0, image.width, image.height);
3404
+ const pixels = imageData.data;
3405
+ const particleArray = [];
3406
+ const step = Math.floor(
3407
+ Math.sqrt(image.width * image.height / particleCount)
3408
+ );
3409
+ for (let y = 0; y < image.height; y += step) {
3410
+ for (let x = 0; x < image.width; x += step) {
3411
+ const i = (y * image.width + x) * 4;
3412
+ const [r, g, b, a] = [
3413
+ pixels[i],
3414
+ pixels[i + 1],
3415
+ pixels[i + 2],
3416
+ pixels[i + 3]
3417
+ ];
3418
+ if (a > 128) {
3419
+ const targetX = x;
3420
+ const targetY = y;
3421
+ let startX = targetX, startY = targetY;
3422
+ if (particleEffect === "assemble") {
3423
+ if (assembleFrom === "center") {
3424
+ startX = image.width / 2;
3425
+ startY = image.height / 2;
3426
+ } else if (assembleFrom === "edges") {
3427
+ const edge = Math.floor(Math.random() * 4);
3428
+ if (edge === 0) {
3429
+ startX = 0;
3430
+ startY = Math.random() * image.height;
3431
+ } else if (edge === 1) {
3432
+ startX = image.width;
3433
+ startY = Math.random() * image.height;
3434
+ } else if (edge === 2) {
3435
+ startX = Math.random() * image.width;
3436
+ startY = 0;
3437
+ } else {
3438
+ startX = Math.random() * image.width;
3439
+ startY = image.height;
3440
+ }
3441
+ } else if (assembleFrom === "bottom") {
3442
+ startX = targetX;
3443
+ startY = image.height + Math.random() * 200;
3444
+ } else {
3445
+ startX = Math.random() * image.width;
3446
+ startY = Math.random() * image.height;
3447
+ }
3448
+ }
3449
+ particleArray.push({
3450
+ x: startX,
3451
+ y: startY,
3452
+ targetX,
3453
+ targetY,
3454
+ color: `rgba(${r},${g},${b},${a / 255})`,
3455
+ startX,
3456
+ startY,
3457
+ angle: Math.random() * Math.PI * 2
3458
+ });
3459
+ }
3460
+ }
3461
+ }
3462
+ setParticles(particleArray);
3463
+ }, [image, particleCount, particleEffect, assembleFrom]);
3464
+ (0, import_react19.useEffect)(() => {
3465
+ if (!canvasRef.current || !image || !particles) return;
3466
+ const context = canvasRef.current.getContext("2d");
3467
+ if (!context) return;
3468
+ context.canvas.width = width;
3469
+ context.canvas.height = height;
3470
+ context.fillStyle = backgroundColor;
3471
+ context.fillRect(0, 0, width, height);
3472
+ const progress = Math.min(frame / revealDurationInFrames * speed, 1);
3473
+ if (progress >= 1 && particleEffect === "assemble") {
3474
+ const scaleX2 = width / image.width;
3475
+ const scaleY2 = height / image.height;
3476
+ let scale2 = scaleX2;
3477
+ let offsetX2 = 0, offsetY2 = 0;
3478
+ if (fit === "cover") {
3479
+ scale2 = Math.max(scaleX2, scaleY2);
3480
+ offsetX2 = (width - image.width * scale2) / 2;
3481
+ offsetY2 = (height - image.height * scale2) / 2;
3482
+ } else {
3483
+ scale2 = Math.min(scaleX2, scaleY2);
3484
+ offsetX2 = (width - image.width * scale2) / 2;
3485
+ offsetY2 = (height - image.height * scale2) / 2;
3486
+ }
3487
+ context.save();
3488
+ context.translate(offsetX2, offsetY2);
3489
+ context.scale(scale2, scale2);
3490
+ context.drawImage(image, 0, 0);
3491
+ context.restore();
3492
+ return;
3493
+ }
3494
+ const easeProgress = particleEffect === "explode" ? progress * progress * (3 - 2 * progress) : 1 - Math.pow(1 - progress, 3);
3495
+ const scaleX = width / image.width;
3496
+ const scaleY = height / image.height;
3497
+ let scale = scaleX;
3498
+ let offsetX = 0, offsetY = 0;
3499
+ if (fit === "cover") {
3500
+ scale = Math.max(scaleX, scaleY);
3501
+ offsetX = (width - image.width * scale) / 2;
3502
+ offsetY = (height - image.height * scale) / 2;
3503
+ } else {
3504
+ scale = Math.min(scaleX, scaleY);
3505
+ offsetX = (width - image.width * scale) / 2;
3506
+ offsetY = (height - image.height * scale) / 2;
3507
+ }
3508
+ particles.forEach((particle) => {
3509
+ let x, y;
3510
+ if (particleEffect === "assemble") {
3511
+ x = particle.startX + (particle.targetX - particle.startX) * easeProgress;
3512
+ y = particle.startY + (particle.targetY - particle.startY) * easeProgress;
3513
+ } else if (particleEffect === "disassemble") {
3514
+ const reverseProgress = 1 - easeProgress;
3515
+ x = particle.targetX + (particle.startX - particle.targetX) * (1 - reverseProgress);
3516
+ y = particle.targetY + (particle.startY - particle.targetY) * (1 - reverseProgress);
3517
+ } else if (particleEffect === "explode") {
3518
+ const dx = particle.targetX - image.width / 2;
3519
+ const dy = particle.targetY - image.height / 2;
3520
+ const dist = Math.sqrt(dx * dx + dy * dy);
3521
+ const explosionDist = dist * easeProgress * 3;
3522
+ x = particle.targetX + dx / dist * explosionDist;
3523
+ y = particle.targetY + dy / dist * explosionDist;
3524
+ } else {
3525
+ x = particle.targetX;
3526
+ y = particle.targetY;
3527
+ }
3528
+ const finalX = x * scale + offsetX;
3529
+ const finalY = y * scale + offsetY;
3530
+ context.save();
3531
+ context.translate(finalX, finalY);
3532
+ if (rotation && particleEffect !== "pixelate") {
3533
+ context.rotate(particle.angle * easeProgress);
3534
+ }
3535
+ const size = particleEffect === "pixelate" ? particleSize * (1 + (1 - easeProgress) * 3) : particleSize;
3536
+ context.fillStyle = particle.color;
3537
+ context.fillRect(-size / 2, -size / 2, size, size);
3538
+ context.restore();
3539
+ });
3540
+ }, [
3541
+ frame,
3542
+ image,
3543
+ width,
3544
+ height,
3545
+ particles,
3546
+ revealDurationInFrames,
3547
+ fit,
3548
+ backgroundColor,
3549
+ particleSize,
3550
+ particleEffect,
3551
+ speed,
3552
+ rotation
3553
+ ]);
3554
+ return /* @__PURE__ */ import_react19.default.createElement(Atom, { ref: canvasRef, data: { className: "w-full h-full" }, id });
3555
+ };
3556
+
3557
+ // src/components/effects/GenericPresets.ts
3558
+ var fadeInPreset = [
3559
+ { key: "opacity", val: 0, prog: 0 },
3560
+ { key: "opacity", val: 1, prog: 1 }
3561
+ ];
3562
+ var fadeOutPreset = [
3563
+ { key: "opacity", val: 1, prog: 0 },
3564
+ { key: "opacity", val: 0, prog: 1 }
3565
+ ];
3566
+ var scaleInPreset = [
3567
+ { key: "scale", val: 0, prog: 0 },
3568
+ { key: "scale", val: 1, prog: 1 }
3569
+ ];
3570
+ var scaleOutPreset = [
3571
+ { key: "scale", val: 1, prog: 0 },
3572
+ { key: "scale", val: 0, prog: 1 }
3573
+ ];
3574
+ var slideInLeftPreset = [
3575
+ { key: "translateX", val: -100, prog: 0 },
3576
+ { key: "translateX", val: 0, prog: 1 }
3577
+ ];
3578
+ var slideInRightPreset = [
3579
+ { key: "translateX", val: 100, prog: 0 },
3580
+ { key: "translateX", val: 0, prog: 1 }
3581
+ ];
3582
+ var slideInTopPreset = [
3583
+ { key: "translateY", val: -100, prog: 0 },
3584
+ { key: "translateY", val: 0, prog: 1 }
3585
+ ];
3586
+ var slideInBottomPreset = [
3587
+ { key: "translateY", val: 100, prog: 0 },
3588
+ { key: "translateY", val: 0, prog: 1 }
3589
+ ];
3590
+ var bouncePreset = [
3591
+ { key: "scale", val: 0, prog: 0 },
3592
+ { key: "scale", val: 1.2, prog: 0.6 },
3593
+ { key: "scale", val: 1, prog: 1 }
3594
+ ];
3595
+ var pulsePreset = [
3596
+ { key: "scale", val: 1, prog: 0 },
3597
+ { key: "scale", val: 1.1, prog: 0.5 },
3598
+ { key: "scale", val: 1, prog: 1 }
3599
+ ];
3600
+ var rotateInPreset = [
3601
+ { key: "rotate", val: -180, prog: 0 },
3602
+ { key: "rotate", val: 0, prog: 1 }
3603
+ ];
3604
+ var blurInPreset = [
3605
+ { key: "blur", val: 10, prog: 0 },
3606
+ { key: "blur", val: 0, prog: 1 }
3607
+ ];
3608
+ var fadeInScalePreset = [
3609
+ { key: "opacity", val: 0, prog: 0 },
3610
+ { key: "opacity", val: 1, prog: 1 },
3611
+ { key: "scale", val: 0.8, prog: 0 },
3612
+ { key: "scale", val: 1, prog: 1 }
3613
+ ];
3614
+ var slideInFadePreset = [
3615
+ { key: "translateX", val: -50, prog: 0 },
3616
+ { key: "translateX", val: 0, prog: 1 },
3617
+ { key: "opacity", val: 0, prog: 0 },
3618
+ { key: "opacity", val: 1, prog: 1 }
3619
+ ];
3620
+ var slideInLeftStringPreset = [
3621
+ { key: "translateX", val: "-100px", prog: 0 },
3622
+ { key: "translateX", val: "0px", prog: 1 }
3623
+ ];
3624
+ var slideInRightStringPreset = [
3625
+ { key: "translateX", val: "100px", prog: 0 },
3626
+ { key: "translateX", val: "0px", prog: 1 }
3627
+ ];
3628
+ var slideInTopStringPreset = [
3629
+ { key: "translateY", val: "-100px", prog: 0 },
3630
+ { key: "translateY", val: "0px", prog: 1 }
3631
+ ];
3632
+ var slideInBottomStringPreset = [
3633
+ { key: "translateY", val: "100px", prog: 0 },
3634
+ { key: "translateY", val: "0px", prog: 1 }
3635
+ ];
3636
+ var rotateInStringPreset = [
3637
+ { key: "rotate", val: "-180deg", prog: 0 },
3638
+ { key: "rotate", val: "0deg", prog: 1 }
3639
+ ];
3640
+ var blurInStringPreset = [
3641
+ { key: "blur", val: "10px", prog: 0 },
3642
+ { key: "blur", val: "0px", prog: 1 }
3643
+ ];
3644
+ var scaleInStringPreset = [
3645
+ { key: "scale", val: 0, prog: 0 },
3646
+ { key: "scale", val: 1, prog: 1 }
3647
+ ];
3648
+ var slideInLeftResponsivePreset = [
3649
+ { key: "translateX", val: "-50vw", prog: 0 },
3650
+ { key: "translateX", val: "0vw", prog: 1 }
3651
+ ];
3652
+ var slideInTopResponsivePreset = [
3653
+ { key: "translateY", val: "-50vh", prog: 0 },
3654
+ { key: "translateY", val: "0vh", prog: 1 }
3655
+ ];
3656
+ var backgroundColorPreset = [
3657
+ { key: "backgroundColor", val: "#ff0000", prog: 0 },
3658
+ { key: "backgroundColor", val: "#0000ff", prog: 1 }
3659
+ ];
3660
+ var borderRadiusPreset = [
3661
+ { key: "borderRadius", val: "0px", prog: 0 },
3662
+ { key: "borderRadius", val: "50px", prog: 1 }
3663
+ ];
3664
+ var boxShadowPreset = [
3665
+ { key: "boxShadow", val: "0px 0px 0px rgba(0,0,0,0)", prog: 0 },
3666
+ { key: "boxShadow", val: "10px 10px 20px rgba(0,0,0,0.5)", prog: 1 }
3667
+ ];
3668
+ var fontSizePreset = [
3669
+ { key: "fontSize", val: "12px", prog: 0 },
3670
+ { key: "fontSize", val: "24px", prog: 1 }
3671
+ ];
3672
+ var letterSpacingPreset = [
3673
+ { key: "letterSpacing", val: "0px", prog: 0 },
3674
+ { key: "letterSpacing", val: "5px", prog: 1 }
3675
+ ];
3676
+ var lineHeightPreset = [
3677
+ { key: "lineHeight", val: "1", prog: 0 },
3678
+ { key: "lineHeight", val: "2", prog: 1 }
3679
+ ];
3680
+ var textShadowPreset = [
3681
+ { key: "textShadow", val: "0px 0px 0px rgba(0,0,0,0)", prog: 0 },
3682
+ { key: "textShadow", val: "2px 2px 4px rgba(0,0,0,0.5)", prog: 1 }
3683
+ ];
3684
+ var widthPreset = [
3685
+ { key: "width", val: "0px", prog: 0 },
3686
+ { key: "width", val: "100%", prog: 1 }
3687
+ ];
3688
+ var heightPreset = [
3689
+ { key: "height", val: "0px", prog: 0 },
3690
+ { key: "height", val: "100%", prog: 1 }
3691
+ ];
3692
+ var marginPreset = [
3693
+ { key: "margin", val: "0px", prog: 0 },
3694
+ { key: "margin", val: "20px", prog: 1 }
3695
+ ];
3696
+ var paddingPreset = [
3697
+ { key: "padding", val: "0px", prog: 0 },
3698
+ { key: "padding", val: "20px", prog: 1 }
3699
+ ];
3700
+ var morphingCardPreset = [
3701
+ { key: "borderRadius", val: "0px", prog: 0 },
3702
+ { key: "borderRadius", val: "20px", prog: 0.5 },
3703
+ { key: "borderRadius", val: "50px", prog: 1 },
3704
+ { key: "boxShadow", val: "0px 0px 0px rgba(0,0,0,0)", prog: 0 },
3705
+ { key: "boxShadow", val: "0px 10px 30px rgba(0,0,0,0.3)", prog: 1 },
3706
+ { key: "backgroundColor", val: "#ffffff", prog: 0 },
3707
+ { key: "backgroundColor", val: "#f0f0f0", prog: 1 }
3708
+ ];
3709
+ var textRevealPreset = [
3710
+ { key: "opacity", val: 0, prog: 0 },
3711
+ { key: "opacity", val: 1, prog: 1 },
3712
+ { key: "letterSpacing", val: "10px", prog: 0 },
3713
+ { key: "letterSpacing", val: "0px", prog: 1 },
3714
+ { key: "textShadow", val: "0px 0px 0px rgba(0,0,0,0)", prog: 0 },
3715
+ { key: "textShadow", val: "2px 2px 4px rgba(0,0,0,0.5)", prog: 1 }
3716
+ ];
3717
+ var GenericEffectPresets = {
3718
+ fadeInPreset,
3719
+ fadeOutPreset,
3720
+ scaleInPreset,
3721
+ scaleOutPreset,
3722
+ slideInLeftPreset,
3723
+ slideInRightPreset,
3724
+ slideInTopPreset,
3725
+ slideInBottomPreset,
3726
+ bouncePreset,
3727
+ pulsePreset,
3728
+ rotateInPreset,
3729
+ blurInPreset,
3730
+ fadeInScalePreset,
3731
+ slideInFadePreset,
3732
+ // String-based presets
3733
+ slideInLeftStringPreset,
3734
+ slideInRightStringPreset,
3735
+ slideInTopStringPreset,
3736
+ slideInBottomStringPreset,
3737
+ rotateInStringPreset,
3738
+ blurInStringPreset,
3739
+ scaleInStringPreset,
3740
+ slideInLeftResponsivePreset,
3741
+ slideInTopResponsivePreset,
3742
+ // Custom CSS property presets
3743
+ backgroundColorPreset,
3744
+ borderRadiusPreset,
3745
+ boxShadowPreset,
3746
+ fontSizePreset,
3747
+ letterSpacingPreset,
3748
+ lineHeightPreset,
3749
+ textShadowPreset,
3750
+ widthPreset,
3751
+ heightPreset,
3752
+ marginPreset,
3753
+ paddingPreset,
3754
+ morphingCardPreset,
3755
+ textRevealPreset
2081
3756
  };
2082
3757
 
2083
3758
  // src/components/effects/index.ts
@@ -2092,13 +3767,22 @@ registerEffect(
2092
3767
  StretchEffect,
2093
3768
  config7
2094
3769
  );
3770
+ registerEffect(
3771
+ config8.displayName,
3772
+ WaveformEffect,
3773
+ config8
3774
+ );
3775
+ registerEffect("CanvasWipeReveal", CanvasWipeReveal);
3776
+ registerEffect("CanvasContentAwareReveal", CanvasContentAwareReveal);
3777
+ registerEffect("CanvasParticleEffect", CanvasParticleEffect);
3778
+ registerEffect("CanvasGlitchEffect", CanvasGlitchEffect);
2095
3779
 
2096
3780
  // src/components/layouts/BaseLayout.tsx
2097
3781
  var Layout = ({ id, children, data, context }) => {
2098
3782
  const { containerProps = {}, childrenProps = [], repeatChildrenProps = {} } = data;
2099
3783
  const overrideStyles = useAnimatedStyles(id);
2100
- const childrenArray = import_react13.Children.toArray(children);
2101
- const enhancedStyle = (0, import_react13.useMemo)(
3784
+ const childrenArray = import_react20.Children.toArray(children);
3785
+ const enhancedStyle = (0, import_react20.useMemo)(
2102
3786
  () => ({
2103
3787
  ...!context?.boundaries?.reset ? context?.boundaries : {},
2104
3788
  ...containerProps.style,
@@ -2112,8 +3796,8 @@ var Layout = ({ id, children, data, context }) => {
2112
3796
  );
2113
3797
  if (Object.keys(repeatChildrenProps).length <= 0 && childrenProps.length <= 0) {
2114
3798
  if (data.isAbsoluteFill) {
2115
- return /* @__PURE__ */ import_react13.default.createElement(
2116
- import_remotion9.AbsoluteFill,
3799
+ return /* @__PURE__ */ import_react20.default.createElement(
3800
+ import_remotion14.AbsoluteFill,
2117
3801
  {
2118
3802
  ...containerProps,
2119
3803
  style: enhancedStyle
@@ -2121,25 +3805,25 @@ var Layout = ({ id, children, data, context }) => {
2121
3805
  childrenArray
2122
3806
  );
2123
3807
  }
2124
- return /* @__PURE__ */ import_react13.default.createElement(
3808
+ return /* @__PURE__ */ import_react20.default.createElement(
2125
3809
  "div",
2126
3810
  {
2127
3811
  id,
2128
3812
  ...containerProps,
2129
3813
  style: enhancedStyle
2130
3814
  },
2131
- childrenArray.map((child, index) => /* @__PURE__ */ import_react13.default.createElement(import_react13.default.Fragment, { key: index }, child))
3815
+ childrenArray.map((child, index) => /* @__PURE__ */ import_react20.default.createElement(import_react20.default.Fragment, { key: index }, child))
2132
3816
  );
2133
3817
  }
2134
3818
  if (data.isAbsoluteFill) {
2135
- return /* @__PURE__ */ import_react13.default.createElement(
2136
- import_remotion9.AbsoluteFill,
3819
+ return /* @__PURE__ */ import_react20.default.createElement(
3820
+ import_remotion14.AbsoluteFill,
2137
3821
  {
2138
3822
  id,
2139
3823
  ...containerProps,
2140
3824
  style: enhancedStyle
2141
3825
  },
2142
- childrenArray.map((child, index) => /* @__PURE__ */ import_react13.default.createElement(
3826
+ childrenArray.map((child, index) => /* @__PURE__ */ import_react20.default.createElement(
2143
3827
  "div",
2144
3828
  {
2145
3829
  key: index,
@@ -2149,14 +3833,14 @@ var Layout = ({ id, children, data, context }) => {
2149
3833
  ))
2150
3834
  );
2151
3835
  }
2152
- return /* @__PURE__ */ import_react13.default.createElement(
3836
+ return /* @__PURE__ */ import_react20.default.createElement(
2153
3837
  "div",
2154
3838
  {
2155
3839
  id,
2156
3840
  ...containerProps,
2157
3841
  style: enhancedStyle
2158
3842
  },
2159
- childrenArray.map((child, index) => /* @__PURE__ */ import_react13.default.createElement(
3843
+ childrenArray.map((child, index) => /* @__PURE__ */ import_react20.default.createElement(
2160
3844
  "div",
2161
3845
  {
2162
3846
  key: index,
@@ -2166,7 +3850,7 @@ var Layout = ({ id, children, data, context }) => {
2166
3850
  ))
2167
3851
  );
2168
3852
  };
2169
- var config8 = {
3853
+ var config10 = {
2170
3854
  displayName: "BaseLayout",
2171
3855
  type: "layout",
2172
3856
  isInnerSequence: false
@@ -2174,27 +3858,27 @@ var config8 = {
2174
3858
 
2175
3859
  // src/components/layouts/index.ts
2176
3860
  registerComponent(
2177
- config8.displayName,
3861
+ config10.displayName,
2178
3862
  Layout,
2179
3863
  "layout",
2180
- config8
3864
+ config10
2181
3865
  );
2182
3866
 
2183
3867
  // src/components/atoms/ShapeAtom.tsx
2184
- var import_react14 = __toESM(require("react"));
2185
- var import_remotion10 = require("remotion");
2186
- var Atom = ({ data }) => {
2187
- const frame = (0, import_remotion10.useCurrentFrame)();
3868
+ var import_react21 = __toESM(require("react"));
3869
+ var import_remotion15 = require("remotion");
3870
+ var Atom2 = ({ data }) => {
3871
+ const frame = (0, import_remotion15.useCurrentFrame)();
2188
3872
  const { shape, color, rotation, style } = data;
2189
3873
  const rotationStyle = rotation ? {
2190
- transform: `rotate(${(0, import_remotion10.interpolate)(
3874
+ transform: `rotate(${(0, import_remotion15.interpolate)(
2191
3875
  frame % rotation.duration,
2192
3876
  [0, rotation.duration],
2193
3877
  [0, 360],
2194
3878
  {
2195
3879
  extrapolateLeft: "clamp",
2196
3880
  extrapolateRight: "clamp",
2197
- easing: import_remotion10.Easing.linear
3881
+ easing: import_remotion15.Easing.linear
2198
3882
  }
2199
3883
  )}deg)`
2200
3884
  } : {};
@@ -2206,22 +3890,22 @@ var Atom = ({ data }) => {
2206
3890
  };
2207
3891
  switch (shape) {
2208
3892
  case "circle":
2209
- return /* @__PURE__ */ import_react14.default.createElement("div", { style: { ...baseStyle, backgroundColor: color, borderRadius: "50%" } });
3893
+ return /* @__PURE__ */ import_react21.default.createElement("div", { style: { ...baseStyle, backgroundColor: color, borderRadius: "50%" } });
2210
3894
  case "rectangle":
2211
- return /* @__PURE__ */ import_react14.default.createElement("div", { style: { ...baseStyle, backgroundColor: color } });
3895
+ return /* @__PURE__ */ import_react21.default.createElement("div", { style: { ...baseStyle, backgroundColor: color } });
2212
3896
  default:
2213
3897
  return null;
2214
3898
  }
2215
3899
  };
2216
- var config9 = {
3900
+ var config11 = {
2217
3901
  displayName: "ShapeAtom",
2218
3902
  type: "atom",
2219
3903
  isInnerSequence: false
2220
3904
  };
2221
3905
 
2222
3906
  // src/components/atoms/ImageAtom.tsx
2223
- var import_react15 = __toESM(require("react"));
2224
- var import_remotion11 = require("remotion");
3907
+ var import_react22 = __toESM(require("react"));
3908
+ var import_remotion16 = require("remotion");
2225
3909
  var CORS_PROXIES = [
2226
3910
  "https://thingproxy.freeboard.io/fetch/",
2227
3911
  "https://api.allorigins.win/raw?url=",
@@ -2231,14 +3915,14 @@ var getCorsProxyUrl = (url) => {
2231
3915
  return `${CORS_PROXIES[0]}${encodeURIComponent(url)}`;
2232
3916
  };
2233
3917
  var useImageSource = (src, proxySrc) => {
2234
- const [imageSource, setImageSource] = (0, import_react15.useState)(src);
2235
- const [isLoading, setIsLoading] = (0, import_react15.useState)(false);
2236
- const [hasError, setHasError] = (0, import_react15.useState)(false);
2237
- const [handle] = (0, import_react15.useState)(() => (0, import_remotion11.delayRender)("Loading image"));
2238
- (0, import_react15.useEffect)(() => {
3918
+ const [imageSource, setImageSource] = (0, import_react22.useState)(src);
3919
+ const [isLoading, setIsLoading] = (0, import_react22.useState)(false);
3920
+ const [hasError, setHasError] = (0, import_react22.useState)(false);
3921
+ const [handle] = (0, import_react22.useState)(() => (0, import_remotion16.delayRender)("Loading image"));
3922
+ (0, import_react22.useEffect)(() => {
2239
3923
  if (!src.startsWith("http")) {
2240
3924
  setImageSource(src);
2241
- (0, import_remotion11.continueRender)(handle);
3925
+ (0, import_remotion16.continueRender)(handle);
2242
3926
  return;
2243
3927
  }
2244
3928
  setIsLoading(true);
@@ -2248,7 +3932,7 @@ var useImageSource = (src, proxySrc) => {
2248
3932
  const handleSuccess = () => {
2249
3933
  setImageSource(src);
2250
3934
  setIsLoading(false);
2251
- (0, import_remotion11.continueRender)(handle);
3935
+ (0, import_remotion16.continueRender)(handle);
2252
3936
  };
2253
3937
  const handleError = () => {
2254
3938
  let proxyUrl;
@@ -2259,7 +3943,7 @@ var useImageSource = (src, proxySrc) => {
2259
3943
  }
2260
3944
  setImageSource(proxyUrl);
2261
3945
  setIsLoading(false);
2262
- (0, import_remotion11.continueRender)(handle);
3946
+ (0, import_remotion16.continueRender)(handle);
2263
3947
  };
2264
3948
  testImage.onload = handleSuccess;
2265
3949
  testImage.onerror = handleError;
@@ -2271,21 +3955,21 @@ var useImageSource = (src, proxySrc) => {
2271
3955
  }, [src, proxySrc, handle]);
2272
3956
  return { imageSource, isLoading, hasError };
2273
3957
  };
2274
- var Atom2 = ({ data, id }) => {
3958
+ var Atom3 = ({ data, id }) => {
2275
3959
  const overrideStyles = useAnimatedStyles(id);
2276
3960
  const { imageSource, isLoading, hasError } = useImageSource(data.src, data.proxySrc);
2277
- const source = (0, import_react15.useMemo)(() => {
3961
+ const source = (0, import_react22.useMemo)(() => {
2278
3962
  if (data.src.startsWith("http")) {
2279
3963
  return imageSource;
2280
3964
  }
2281
- return (0, import_remotion11.staticFile)(data.src);
3965
+ return (0, import_remotion16.staticFile)(data.src);
2282
3966
  }, [data.src, imageSource]);
2283
- const enhancedStyle = (0, import_react15.useMemo)(() => ({
3967
+ const enhancedStyle = (0, import_react22.useMemo)(() => ({
2284
3968
  ...data.style,
2285
3969
  ...overrideStyles
2286
3970
  }), [data.style, overrideStyles, isLoading, hasError]);
2287
- return /* @__PURE__ */ import_react15.default.createElement(
2288
- import_remotion11.Img,
3971
+ return /* @__PURE__ */ import_react22.default.createElement(
3972
+ import_remotion16.Img,
2289
3973
  {
2290
3974
  className: data.className,
2291
3975
  src: source,
@@ -2298,19 +3982,19 @@ var Atom2 = ({ data, id }) => {
2298
3982
  }
2299
3983
  );
2300
3984
  };
2301
- var config10 = {
3985
+ var config12 = {
2302
3986
  displayName: "ImageAtom",
2303
3987
  type: "atom",
2304
3988
  isInnerSequence: false
2305
3989
  };
2306
3990
 
2307
3991
  // src/components/atoms/TextAtom.tsx
2308
- var import_react17 = __toESM(require("react"));
2309
- var import_remotion13 = require("remotion");
3992
+ var import_react24 = __toESM(require("react"));
3993
+ var import_remotion18 = require("remotion");
2310
3994
 
2311
3995
  // src/hooks/useFontLoader.ts
2312
- var import_react16 = require("react");
2313
- var import_remotion12 = require("remotion");
3996
+ var import_react23 = require("react");
3997
+ var import_remotion17 = require("remotion");
2314
3998
 
2315
3999
  // src/utils/fontUtils.ts
2316
4000
  var fontUtils = __toESM(require("@remotion/google-fonts"));
@@ -2451,12 +4135,12 @@ var getNormalizedFontName = (fontFamily) => {
2451
4135
 
2452
4136
  // src/hooks/useFontLoader.ts
2453
4137
  var useFontLoader = (options = {}) => {
2454
- const [state, setState] = (0, import_react16.useState)({
4138
+ const [state, setState] = (0, import_react23.useState)({
2455
4139
  loadedFonts: /* @__PURE__ */ new Map(),
2456
4140
  loadingFonts: /* @__PURE__ */ new Set(),
2457
4141
  errorFonts: /* @__PURE__ */ new Map()
2458
4142
  });
2459
- const loadFont = (0, import_react16.useCallback)(
4143
+ const loadFont = (0, import_react23.useCallback)(
2460
4144
  async (fontFamily, fontOptions = {}) => {
2461
4145
  const fontKey = `${fontFamily}-${JSON.stringify(fontOptions)}`;
2462
4146
  if (state.loadedFonts.has(fontKey) || state.loadingFonts.has(fontFamily)) {
@@ -2499,7 +4183,7 @@ var useFontLoader = (options = {}) => {
2499
4183
  },
2500
4184
  [state.loadedFonts, state.loadingFonts, options]
2501
4185
  );
2502
- const loadMultipleFonts2 = (0, import_react16.useCallback)(
4186
+ const loadMultipleFonts2 = (0, import_react23.useCallback)(
2503
4187
  async (fonts) => {
2504
4188
  const fontsToLoad = fonts.filter(({ family, options: options2 = {} }) => {
2505
4189
  const fontKey = `${family}-${JSON.stringify(options2)}`;
@@ -2558,14 +4242,14 @@ var useFontLoader = (options = {}) => {
2558
4242
  },
2559
4243
  [state.loadedFonts, state.loadingFonts, options]
2560
4244
  );
2561
- const isFontReady = (0, import_react16.useCallback)(
4245
+ const isFontReady = (0, import_react23.useCallback)(
2562
4246
  (fontFamily, options2 = {}) => {
2563
4247
  const fontKey = `${fontFamily}-${JSON.stringify(options2)}`;
2564
4248
  return state.loadedFonts.has(fontKey);
2565
4249
  },
2566
4250
  [state.loadedFonts]
2567
4251
  );
2568
- const areFontsReady = (0, import_react16.useCallback)(
4252
+ const areFontsReady = (0, import_react23.useCallback)(
2569
4253
  (fontFamilies) => {
2570
4254
  return fontFamilies.every(({ family, options: options2 = {} }) => {
2571
4255
  const fontKey = `${family}-${JSON.stringify(options2)}`;
@@ -2574,20 +4258,20 @@ var useFontLoader = (options = {}) => {
2574
4258
  },
2575
4259
  [state.loadedFonts]
2576
4260
  );
2577
- const getFontFamily = (0, import_react16.useCallback)(
4261
+ const getFontFamily = (0, import_react23.useCallback)(
2578
4262
  (fontFamily, options2 = {}) => {
2579
4263
  const fontKey = `${fontFamily}-${JSON.stringify(options2)}`;
2580
4264
  return state.loadedFonts.get(fontKey);
2581
4265
  },
2582
4266
  [state.loadedFonts]
2583
4267
  );
2584
- const getFontError = (0, import_react16.useCallback)(
4268
+ const getFontError = (0, import_react23.useCallback)(
2585
4269
  (fontFamily) => {
2586
4270
  return state.errorFonts.get(fontFamily);
2587
4271
  },
2588
4272
  [state.errorFonts]
2589
4273
  );
2590
- const clearErrors = (0, import_react16.useCallback)(() => {
4274
+ const clearErrors = (0, import_react23.useCallback)(() => {
2591
4275
  setState((prev) => ({
2592
4276
  ...prev,
2593
4277
  errorFonts: /* @__PURE__ */ new Map()
@@ -2610,25 +4294,25 @@ var useFontLoader = (options = {}) => {
2610
4294
  };
2611
4295
  var useFont = (fontFamily, options = {}) => {
2612
4296
  const { loadFont, isFontReady, getFontFamily, getFontError, ...rest } = useFontLoader(options);
2613
- const [isLoaded, setIsLoaded] = (0, import_react16.useState)(false);
2614
- const [error, setError] = (0, import_react16.useState)(null);
2615
- const [renderHandle] = (0, import_react16.useState)(
2616
- () => (0, import_remotion12.delayRender)(`Loading font: ${fontFamily}`)
4297
+ const [isLoaded, setIsLoaded] = (0, import_react23.useState)(false);
4298
+ const [error, setError] = (0, import_react23.useState)(null);
4299
+ const [renderHandle] = (0, import_react23.useState)(
4300
+ () => (0, import_remotion17.delayRender)(`Loading font: ${fontFamily}`)
2617
4301
  );
2618
4302
  const initialFontFamily = getFontFamily(fontFamily, options) || `"${fontFamily}", sans-serif`;
2619
- const [fontFamilyValue, setFontFamilyValue] = (0, import_react16.useState)(initialFontFamily);
2620
- (0, import_react16.useEffect)(() => {
4303
+ const [fontFamilyValue, setFontFamilyValue] = (0, import_react23.useState)(initialFontFamily);
4304
+ (0, import_react23.useEffect)(() => {
2621
4305
  const loadFontAsync = async () => {
2622
4306
  try {
2623
4307
  const cssValue = await loadFont(fontFamily, options);
2624
4308
  setFontFamilyValue(cssValue);
2625
4309
  setIsLoaded(true);
2626
4310
  setError(null);
2627
- (0, import_remotion12.continueRender)(renderHandle);
4311
+ (0, import_remotion17.continueRender)(renderHandle);
2628
4312
  } catch (err) {
2629
4313
  setError(err instanceof Error ? err : new Error(String(err)));
2630
4314
  setIsLoaded(false);
2631
- (0, import_remotion12.continueRender)(renderHandle);
4315
+ (0, import_remotion17.continueRender)(renderHandle);
2632
4316
  }
2633
4317
  };
2634
4318
  if (!isFontReady(fontFamily, options)) {
@@ -2639,7 +4323,7 @@ var useFont = (fontFamily, options = {}) => {
2639
4323
  setFontFamilyValue(cachedValue);
2640
4324
  }
2641
4325
  setIsLoaded(true);
2642
- (0, import_remotion12.continueRender)(renderHandle);
4326
+ (0, import_remotion17.continueRender)(renderHandle);
2643
4327
  }
2644
4328
  }, [fontFamily, loadFont, isFontReady, getFontFamily, options, renderHandle]);
2645
4329
  return {
@@ -2652,11 +4336,11 @@ var useFont = (fontFamily, options = {}) => {
2652
4336
  };
2653
4337
 
2654
4338
  // src/components/atoms/TextAtom.tsx
2655
- var Atom3 = ({ id, data }) => {
4339
+ var Atom4 = ({ id, data }) => {
2656
4340
  const overrideStyles = useAnimatedStyles(id);
2657
- const [isFontLoading, setIsFontLoading] = (0, import_react17.useState)(false);
2658
- const [renderHandle] = (0, import_react17.useState)(
2659
- () => (0, import_remotion13.delayRender)(`Loading font: ${data.font?.family}`)
4341
+ const [isFontLoading, setIsFontLoading] = (0, import_react24.useState)(false);
4342
+ const [renderHandle] = (0, import_react24.useState)(
4343
+ () => (0, import_remotion18.delayRender)(`Loading font: ${data.font?.family}`)
2660
4344
  );
2661
4345
  const { isLoaded, error, isReady, fontFamily } = useFont(
2662
4346
  data.font?.family || "Inter",
@@ -2667,15 +4351,15 @@ var Atom3 = ({ id, data }) => {
2667
4351
  preload: data.font?.preload !== false,
2668
4352
  onLoad: (family, cssValue) => {
2669
4353
  setIsFontLoading(false);
2670
- (0, import_remotion13.continueRender)(renderHandle);
4354
+ (0, import_remotion18.continueRender)(renderHandle);
2671
4355
  },
2672
4356
  onError: (family, error2) => {
2673
4357
  setIsFontLoading(false);
2674
- (0, import_remotion13.continueRender)(renderHandle);
4358
+ (0, import_remotion18.continueRender)(renderHandle);
2675
4359
  }
2676
4360
  }
2677
4361
  );
2678
- (0, import_react17.useEffect)(() => {
4362
+ (0, import_react24.useEffect)(() => {
2679
4363
  if (data.font?.family) {
2680
4364
  if (isReady || isLoaded) {
2681
4365
  setIsFontLoading(false);
@@ -2684,7 +4368,7 @@ var Atom3 = ({ id, data }) => {
2684
4368
  }
2685
4369
  }
2686
4370
  }, [data.font, isReady, isLoaded, error]);
2687
- const enhancedStyle = (0, import_react17.useMemo)(() => {
4371
+ const enhancedStyle = (0, import_react24.useMemo)(() => {
2688
4372
  const baseStyle = {
2689
4373
  fontFamily,
2690
4374
  ...data.style
@@ -2705,12 +4389,12 @@ var Atom3 = ({ id, data }) => {
2705
4389
  };
2706
4390
  }, [fontFamily, data.style, data.gradient, overrideStyles]);
2707
4391
  if (isFontLoading && data.loadingState?.showLoadingIndicator) {
2708
- return /* @__PURE__ */ import_react17.default.createElement("div", { style: enhancedStyle, className: data.className }, /* @__PURE__ */ import_react17.default.createElement("span", { style: data.loadingState.loadingStyle }, data.loadingState.loadingText || "Loading..."));
4392
+ return /* @__PURE__ */ import_react24.default.createElement("div", { style: enhancedStyle, className: data.className }, /* @__PURE__ */ import_react24.default.createElement("span", { style: data.loadingState.loadingStyle }, data.loadingState.loadingText || "Loading..."));
2709
4393
  }
2710
4394
  if (error && data.errorState?.showErrorIndicator) {
2711
- return /* @__PURE__ */ import_react17.default.createElement("div", { style: enhancedStyle, className: data.className }, /* @__PURE__ */ import_react17.default.createElement("span", { style: data.errorState.errorStyle }, data.errorState.errorText || data.text));
4395
+ return /* @__PURE__ */ import_react24.default.createElement("div", { style: enhancedStyle, className: data.className }, /* @__PURE__ */ import_react24.default.createElement("span", { style: data.errorState.errorStyle }, data.errorState.errorText || data.text));
2712
4396
  }
2713
- return /* @__PURE__ */ import_react17.default.createElement(
4397
+ return /* @__PURE__ */ import_react24.default.createElement(
2714
4398
  "div",
2715
4399
  {
2716
4400
  style: enhancedStyle,
@@ -2723,60 +4407,60 @@ var Atom3 = ({ id, data }) => {
2723
4407
  data.text
2724
4408
  );
2725
4409
  };
2726
- var config11 = {
4410
+ var config13 = {
2727
4411
  displayName: "TextAtom",
2728
4412
  type: "atom",
2729
4413
  isInnerSequence: false
2730
4414
  };
2731
4415
 
2732
4416
  // src/components/atoms/VideoAtom.tsx
2733
- var import_react18 = __toESM(require("react"));
2734
- var import_remotion14 = require("remotion");
2735
- var import_zod2 = require("zod");
2736
- var VideoAtomDataProps = import_zod2.z.object({
2737
- src: import_zod2.z.string(),
4417
+ var import_react25 = __toESM(require("react"));
4418
+ var import_remotion19 = require("remotion");
4419
+ var import_zod7 = require("zod");
4420
+ var VideoAtomDataProps = import_zod7.z.object({
4421
+ src: import_zod7.z.string(),
2738
4422
  // Video source URL
2739
- srcDuration: import_zod2.z.number().optional(),
4423
+ srcDuration: import_zod7.z.number().optional(),
2740
4424
  // Video duration in seconds (or to say it more accurately, each iteration duration in a loop))
2741
- style: import_zod2.z.record(import_zod2.z.string(), import_zod2.z.any()).optional(),
4425
+ style: import_zod7.z.record(import_zod7.z.string(), import_zod7.z.any()).optional(),
2742
4426
  // CSS styles object
2743
- containerClassName: import_zod2.z.string().optional(),
4427
+ containerClassName: import_zod7.z.string().optional(),
2744
4428
  // CSS class names
2745
- className: import_zod2.z.string().optional(),
4429
+ className: import_zod7.z.string().optional(),
2746
4430
  // CSS class names
2747
- startFrom: import_zod2.z.number().optional(),
4431
+ startFrom: import_zod7.z.number().optional(),
2748
4432
  // Start playback from this time (seconds)
2749
- endAt: import_zod2.z.number().optional(),
4433
+ endAt: import_zod7.z.number().optional(),
2750
4434
  // End playback at this time (seconds)
2751
- playbackRate: import_zod2.z.number().optional(),
4435
+ playbackRate: import_zod7.z.number().optional(),
2752
4436
  // Playback speed multiplier
2753
- volume: import_zod2.z.number().optional(),
4437
+ volume: import_zod7.z.number().optional(),
2754
4438
  // Volume level (0-1)
2755
- muted: import_zod2.z.boolean().optional(),
4439
+ muted: import_zod7.z.boolean().optional(),
2756
4440
  // Mute video audio
2757
- loop: import_zod2.z.boolean().optional(),
4441
+ loop: import_zod7.z.boolean().optional(),
2758
4442
  // Whether to loop the video
2759
- fit: import_zod2.z.enum(["contain", "cover", "fill", "none", "scale-down"]).optional()
4443
+ fit: import_zod7.z.enum(["contain", "cover", "fill", "none", "scale-down"]).optional()
2760
4444
  // Object fit style
2761
4445
  });
2762
- var Atom4 = ({ data, id, context }) => {
2763
- const { fps } = (0, import_remotion14.useVideoConfig)();
4446
+ var Atom5 = ({ data, id, context }) => {
4447
+ const { fps } = (0, import_remotion19.useVideoConfig)();
2764
4448
  const overrideStyles = useAnimatedStyles(id);
2765
- const frame = (0, import_remotion14.useCurrentFrame)();
2766
- const source = (0, import_react18.useMemo)(() => {
4449
+ const frame = (0, import_remotion19.useCurrentFrame)();
4450
+ const source = (0, import_react25.useMemo)(() => {
2767
4451
  if (data.src.startsWith("http")) {
2768
4452
  return data.src;
2769
4453
  }
2770
- return (0, import_remotion14.staticFile)(data.src);
4454
+ return (0, import_remotion19.staticFile)(data.src);
2771
4455
  }, [data.src]);
2772
- const trimBefore = (0, import_react18.useMemo)(() => {
4456
+ const trimBefore = (0, import_react25.useMemo)(() => {
2773
4457
  return data.startFrom ? data.startFrom * fps : void 0;
2774
4458
  }, [data.startFrom, fps]);
2775
- const trimAfter = (0, import_react18.useMemo)(() => {
4459
+ const trimAfter = (0, import_react25.useMemo)(() => {
2776
4460
  return data.endAt ? data.endAt * fps : void 0;
2777
4461
  }, [data.endAt, fps]);
2778
- const videoComponent = /* @__PURE__ */ import_react18.default.createElement(
2779
- import_remotion14.OffthreadVideo,
4462
+ const videoComponent = /* @__PURE__ */ import_react25.default.createElement(
4463
+ import_remotion19.OffthreadVideo,
2780
4464
  {
2781
4465
  className: data.className,
2782
4466
  src: source,
@@ -2788,8 +4472,8 @@ var Atom4 = ({ data, id, context }) => {
2788
4472
  muted: data.muted
2789
4473
  }
2790
4474
  );
2791
- const videoWithStyles = data.containerClassName ? videoComponent : /* @__PURE__ */ import_react18.default.createElement(
2792
- import_remotion14.OffthreadVideo,
4475
+ const videoWithStyles = data.containerClassName ? videoComponent : /* @__PURE__ */ import_react25.default.createElement(
4476
+ import_remotion19.OffthreadVideo,
2793
4477
  {
2794
4478
  className: data.className,
2795
4479
  src: source,
@@ -2802,53 +4486,53 @@ var Atom4 = ({ data, id, context }) => {
2802
4486
  }
2803
4487
  );
2804
4488
  if (data.loop) {
2805
- return /* @__PURE__ */ import_react18.default.createElement(import_remotion14.Loop, { times: Infinity, durationInFrames: data.srcDuration ? data.srcDuration * fps : context.timing?.durationInFrames, layout: "none" }, data.containerClassName ? /* @__PURE__ */ import_react18.default.createElement("div", { className: data.containerClassName, style: overrideStyles }, videoComponent) : videoWithStyles);
4489
+ return /* @__PURE__ */ import_react25.default.createElement(import_remotion19.Loop, { times: Infinity, durationInFrames: data.srcDuration ? data.srcDuration * fps : context.timing?.durationInFrames, layout: "none" }, data.containerClassName ? /* @__PURE__ */ import_react25.default.createElement("div", { className: data.containerClassName, style: overrideStyles }, videoComponent) : videoWithStyles);
2806
4490
  }
2807
- return data.containerClassName ? /* @__PURE__ */ import_react18.default.createElement("div", { className: data.containerClassName, style: overrideStyles }, videoComponent) : videoWithStyles;
4491
+ return data.containerClassName ? /* @__PURE__ */ import_react25.default.createElement("div", { className: data.containerClassName, style: overrideStyles }, videoComponent) : videoWithStyles;
2808
4492
  };
2809
- var config12 = {
4493
+ var config14 = {
2810
4494
  displayName: "VideoAtom",
2811
4495
  type: "atom",
2812
4496
  isInnerSequence: false
2813
4497
  };
2814
4498
 
2815
4499
  // src/components/atoms/AudioAtom.tsx
2816
- var import_react19 = __toESM(require("react"));
2817
- var import_remotion15 = require("remotion");
2818
- var import_zod3 = require("zod");
2819
- var AudioAtomMutedRangeProps = import_zod3.z.object({
2820
- type: import_zod3.z.literal("range"),
2821
- values: import_zod3.z.array(import_zod3.z.object({
2822
- start: import_zod3.z.number(),
4500
+ var import_react26 = __toESM(require("react"));
4501
+ var import_remotion20 = require("remotion");
4502
+ var import_zod8 = require("zod");
4503
+ var AudioAtomMutedRangeProps = import_zod8.z.object({
4504
+ type: import_zod8.z.literal("range"),
4505
+ values: import_zod8.z.array(import_zod8.z.object({
4506
+ start: import_zod8.z.number(),
2823
4507
  // Start time in seconds
2824
- end: import_zod3.z.number()
4508
+ end: import_zod8.z.number()
2825
4509
  // End time in seconds
2826
4510
  }))
2827
4511
  });
2828
- var AudioAtomMutedFullProps = import_zod3.z.object({
2829
- type: import_zod3.z.literal("full"),
2830
- value: import_zod3.z.boolean()
4512
+ var AudioAtomMutedFullProps = import_zod8.z.object({
4513
+ type: import_zod8.z.literal("full"),
4514
+ value: import_zod8.z.boolean()
2831
4515
  // true = muted, false = unmuted
2832
4516
  });
2833
- var AudioAtomDataProps = import_zod3.z.object({
2834
- src: import_zod3.z.string(),
4517
+ var AudioAtomDataProps = import_zod8.z.object({
4518
+ src: import_zod8.z.string(),
2835
4519
  // Audio source URL
2836
- startFrom: import_zod3.z.number().optional(),
4520
+ startFrom: import_zod8.z.number().optional(),
2837
4521
  // Start playback from this time (seconds)
2838
- endAt: import_zod3.z.number().optional(),
4522
+ endAt: import_zod8.z.number().optional(),
2839
4523
  // End playback at this time (seconds)
2840
- volume: import_zod3.z.number().optional(),
4524
+ volume: import_zod8.z.number().optional(),
2841
4525
  // Volume level (0-1)
2842
- playbackRate: import_zod3.z.number().optional(),
4526
+ playbackRate: import_zod8.z.number().optional(),
2843
4527
  // Playback speed multiplier
2844
- muted: import_zod3.z.union([AudioAtomMutedFullProps, AudioAtomMutedRangeProps]).optional()
4528
+ muted: import_zod8.z.union([AudioAtomMutedFullProps, AudioAtomMutedRangeProps]).optional()
2845
4529
  // Mute configuration
2846
4530
  });
2847
- var Atom5 = ({ data }) => {
2848
- const { fps } = (0, import_remotion15.useVideoConfig)();
4531
+ var Atom6 = ({ data }) => {
4532
+ const { fps } = (0, import_remotion20.useVideoConfig)();
2849
4533
  const { muted } = data;
2850
- const frame = (0, import_remotion15.useCurrentFrame)();
2851
- const isMuted = (0, import_react19.useMemo)(() => {
4534
+ const frame = (0, import_remotion20.useCurrentFrame)();
4535
+ const isMuted = (0, import_react26.useMemo)(() => {
2852
4536
  if (muted?.type === "full") {
2853
4537
  return muted.value;
2854
4538
  }
@@ -2859,16 +4543,16 @@ var Atom5 = ({ data }) => {
2859
4543
  }
2860
4544
  return false;
2861
4545
  }, [muted, frame, fps]);
2862
- const source = (0, import_react19.useMemo)(() => {
4546
+ const source = (0, import_react26.useMemo)(() => {
2863
4547
  if (data.src.startsWith("http")) {
2864
4548
  return data.src;
2865
4549
  }
2866
- return (0, import_remotion15.staticFile)(data.src);
4550
+ return (0, import_remotion20.staticFile)(data.src);
2867
4551
  }, [data.src]);
2868
4552
  return (
2869
4553
  // @ts-ignore
2870
- /* @__PURE__ */ import_react19.default.createElement(
2871
- import_remotion15.Audio,
4554
+ /* @__PURE__ */ import_react26.default.createElement(
4555
+ import_remotion20.Audio,
2872
4556
  {
2873
4557
  src: source,
2874
4558
  trimBefore: data.startFrom ? data.startFrom * fps : void 0,
@@ -2880,47 +4564,47 @@ var Atom5 = ({ data }) => {
2880
4564
  )
2881
4565
  );
2882
4566
  };
2883
- var config13 = {
4567
+ var config15 = {
2884
4568
  displayName: "AudioAtom",
2885
4569
  type: "atom",
2886
4570
  isInnerSequence: false
2887
4571
  };
2888
4572
 
2889
4573
  // src/components/atoms/LottieAtom.tsx
2890
- var import_react20 = __toESM(require("react"));
2891
- var import_remotion16 = require("remotion");
4574
+ var import_react27 = __toESM(require("react"));
4575
+ var import_remotion21 = require("remotion");
2892
4576
  var import_lottie = require("@remotion/lottie");
2893
- var import_zod4 = require("zod");
2894
- var LottieAtomDataProps = import_zod4.z.object({
2895
- src: import_zod4.z.string(),
4577
+ var import_zod9 = require("zod");
4578
+ var LottieAtomDataProps = import_zod9.z.object({
4579
+ src: import_zod9.z.string(),
2896
4580
  // Lottie JSON source URL or local path
2897
- style: import_zod4.z.record(import_zod4.z.string(), import_zod4.z.any()).optional(),
4581
+ style: import_zod9.z.record(import_zod9.z.string(), import_zod9.z.any()).optional(),
2898
4582
  // CSS styles object
2899
- className: import_zod4.z.string().optional(),
4583
+ className: import_zod9.z.string().optional(),
2900
4584
  // CSS class names
2901
- loop: import_zod4.z.boolean().optional(),
4585
+ loop: import_zod9.z.boolean().optional(),
2902
4586
  // Whether to loop the animation (handled by Remotion timeline)
2903
- playbackRate: import_zod4.z.number().optional(),
4587
+ playbackRate: import_zod9.z.number().optional(),
2904
4588
  // Playback speed multiplier (default: 1)
2905
- direction: import_zod4.z.enum(["forward", "reverse"]).optional()
4589
+ direction: import_zod9.z.enum(["forward", "reverse"]).optional()
2906
4590
  // Animation direction
2907
4591
  });
2908
4592
  var useLottieData = (src) => {
2909
- const [animationData, setAnimationData] = (0, import_react20.useState)(null);
2910
- const [isLoading, setIsLoading] = (0, import_react20.useState)(true);
2911
- const [hasError, setHasError] = (0, import_react20.useState)(false);
2912
- const [handle] = (0, import_react20.useState)(() => (0, import_remotion16.delayRender)("Loading Lottie animation"));
2913
- (0, import_react20.useEffect)(() => {
4593
+ const [animationData, setAnimationData] = (0, import_react27.useState)(null);
4594
+ const [isLoading, setIsLoading] = (0, import_react27.useState)(true);
4595
+ const [hasError, setHasError] = (0, import_react27.useState)(false);
4596
+ const [handle] = (0, import_react27.useState)(() => (0, import_remotion21.delayRender)("Loading Lottie animation"));
4597
+ (0, import_react27.useEffect)(() => {
2914
4598
  if (!src) {
2915
4599
  console.error("LottieAtom: No source provided");
2916
4600
  setHasError(true);
2917
4601
  setIsLoading(false);
2918
- (0, import_remotion16.continueRender)(handle);
4602
+ (0, import_remotion21.continueRender)(handle);
2919
4603
  return;
2920
4604
  }
2921
4605
  setIsLoading(true);
2922
4606
  setHasError(false);
2923
- const sourceUrl = src.startsWith("http") ? src : (0, import_remotion16.staticFile)(src);
4607
+ const sourceUrl = src.startsWith("http") ? src : (0, import_remotion21.staticFile)(src);
2924
4608
  fetch(sourceUrl, {
2925
4609
  mode: "cors",
2926
4610
  credentials: "omit"
@@ -2935,24 +4619,24 @@ var useLottieData = (src) => {
2935
4619
  }
2936
4620
  setAnimationData(json);
2937
4621
  setIsLoading(false);
2938
- (0, import_remotion16.continueRender)(handle);
4622
+ (0, import_remotion21.continueRender)(handle);
2939
4623
  }).catch((error) => {
2940
4624
  console.error(`Failed to load Lottie animation from ${sourceUrl}:`, error.message || error);
2941
4625
  setHasError(true);
2942
4626
  setIsLoading(false);
2943
- (0, import_remotion16.continueRender)(handle);
4627
+ (0, import_remotion21.continueRender)(handle);
2944
4628
  });
2945
4629
  return () => {
2946
4630
  };
2947
4631
  }, [src, handle]);
2948
4632
  return { animationData, isLoading, hasError };
2949
4633
  };
2950
- var Atom6 = ({ data, id }) => {
2951
- const { fps } = (0, import_remotion16.useVideoConfig)();
2952
- const frame = (0, import_remotion16.useCurrentFrame)();
4634
+ var Atom7 = ({ data, id }) => {
4635
+ const { fps } = (0, import_remotion21.useVideoConfig)();
4636
+ const frame = (0, import_remotion21.useCurrentFrame)();
2953
4637
  const overrideStyles = useAnimatedStyles(id);
2954
4638
  const { animationData, isLoading, hasError } = useLottieData(data.src);
2955
- const effectiveFrame = (0, import_react20.useMemo)(() => {
4639
+ const effectiveFrame = (0, import_react27.useMemo)(() => {
2956
4640
  const playbackRate = data.playbackRate || 1;
2957
4641
  const direction = data.direction || "forward";
2958
4642
  if (direction === "reverse") {
@@ -2960,12 +4644,12 @@ var Atom6 = ({ data, id }) => {
2960
4644
  }
2961
4645
  return frame * playbackRate;
2962
4646
  }, [frame, data.playbackRate, data.direction]);
2963
- const enhancedStyle = (0, import_react20.useMemo)(() => ({
4647
+ const enhancedStyle = (0, import_react27.useMemo)(() => ({
2964
4648
  ...data.style,
2965
4649
  ...overrideStyles
2966
4650
  }), [data.style, overrideStyles]);
2967
4651
  if (isLoading) {
2968
- return /* @__PURE__ */ import_react20.default.createElement(
4652
+ return /* @__PURE__ */ import_react27.default.createElement(
2969
4653
  "div",
2970
4654
  {
2971
4655
  className: data.className,
@@ -2981,7 +4665,7 @@ var Atom6 = ({ data, id }) => {
2981
4665
  }
2982
4666
  if (hasError || !animationData) {
2983
4667
  console.warn(`LottieAtom: Failed to render animation from ${data.src}`);
2984
- return /* @__PURE__ */ import_react20.default.createElement(
4668
+ return /* @__PURE__ */ import_react27.default.createElement(
2985
4669
  "div",
2986
4670
  {
2987
4671
  className: data.className,
@@ -3001,58 +4685,93 @@ var Atom6 = ({ data, id }) => {
3001
4685
  "\u26A0\uFE0F Lottie Error"
3002
4686
  );
3003
4687
  }
3004
- return /* @__PURE__ */ import_react20.default.createElement(
4688
+ return /* @__PURE__ */ import_react27.default.createElement(
3005
4689
  import_lottie.Lottie,
3006
4690
  {
3007
- animationData,
3008
- style: enhancedStyle,
3009
- className: data.className
4691
+ animationData,
4692
+ style: enhancedStyle,
4693
+ className: data.className
4694
+ }
4695
+ );
4696
+ };
4697
+ var config16 = {
4698
+ displayName: "LottieAtom",
4699
+ type: "atom",
4700
+ isInnerSequence: false
4701
+ };
4702
+
4703
+ // src/components/atoms/HTMLBlockAtom.tsx
4704
+ var import_react28 = __toESM(require("react"));
4705
+ var Atom8 = ({ id, data }) => {
4706
+ const overrideStyles = useAnimatedStyles(id);
4707
+ const combinedStyle = {
4708
+ ...data.style,
4709
+ ...overrideStyles
4710
+ };
4711
+ return /* @__PURE__ */ import_react28.default.createElement(
4712
+ "div",
4713
+ {
4714
+ className: data.className,
4715
+ style: combinedStyle,
4716
+ dangerouslySetInnerHTML: { __html: data.html }
3010
4717
  }
3011
4718
  );
3012
4719
  };
3013
- var config14 = {
3014
- displayName: "LottieAtom",
4720
+ var config17 = {
4721
+ displayName: "HTMLBlockAtom",
3015
4722
  type: "atom",
3016
4723
  isInnerSequence: false
3017
4724
  };
3018
4725
 
3019
4726
  // src/components/atoms/index.ts
3020
4727
  registerComponent(
3021
- config9.displayName,
3022
- Atom,
3023
- "atom",
3024
- config9
3025
- );
3026
- registerComponent(
3027
- config10.displayName,
4728
+ config11.displayName,
3028
4729
  Atom2,
3029
4730
  "atom",
3030
- config10
4731
+ config11
3031
4732
  );
3032
- registerComponent(config11.displayName, Atom3, "atom", config11);
3033
4733
  registerComponent(
3034
4734
  config12.displayName,
3035
- Atom4,
4735
+ Atom3,
3036
4736
  "atom",
3037
4737
  config12
3038
4738
  );
4739
+ registerComponent(config13.displayName, Atom4, "atom", config13);
3039
4740
  registerComponent(
3040
- config13.displayName,
4741
+ config14.displayName,
3041
4742
  Atom5,
3042
4743
  "atom",
3043
- config13
4744
+ config14
3044
4745
  );
3045
4746
  registerComponent(
3046
- config14.displayName,
4747
+ config15.displayName,
3047
4748
  Atom6,
3048
4749
  "atom",
3049
- config14
4750
+ config15
4751
+ );
4752
+ registerComponent(
4753
+ config16.displayName,
4754
+ Atom7,
4755
+ "atom",
4756
+ config16
4757
+ );
4758
+ registerComponent(
4759
+ config9.displayName,
4760
+ Atom,
4761
+ "atom",
4762
+ config9
4763
+ );
4764
+ registerComponent(
4765
+ config17.displayName,
4766
+ Atom8,
4767
+ "atom",
4768
+ config17
3050
4769
  );
3051
4770
 
3052
4771
  // src/hooks/useComponentRegistry.ts
3053
- var import_react21 = require("react");
4772
+ var import_react29 = require("react");
3054
4773
  var useComponentRegistry = () => {
3055
- return (0, import_react21.useMemo)(() => {
4774
+ return (0, import_react29.useMemo)(() => {
3056
4775
  return {
3057
4776
  registerComponent: componentRegistry.registerComponent.bind(componentRegistry),
3058
4777
  registerPackage: componentRegistry.registerPackage.bind(componentRegistry),
@@ -3063,13 +4782,13 @@ var useComponentRegistry = () => {
3063
4782
  };
3064
4783
 
3065
4784
  // src/hooks/useBoundaryCalculation.ts
3066
- var import_react22 = require("react");
4785
+ var import_react30 = require("react");
3067
4786
  var useBoundaryCalculation = ({
3068
4787
  parentBoundaries,
3069
4788
  constraints,
3070
4789
  layout
3071
4790
  }) => {
3072
- return (0, import_react22.useMemo)(() => {
4791
+ return (0, import_react30.useMemo)(() => {
3073
4792
  const { x, y, width, height } = parentBoundaries;
3074
4793
  const calculatedX = typeof constraints.x === "number" ? constraints.x : x;
3075
4794
  const calculatedY = typeof constraints.y === "number" ? constraints.y : y;
@@ -3086,16 +4805,16 @@ var useBoundaryCalculation = ({
3086
4805
  };
3087
4806
 
3088
4807
  // src/hooks/buildTransitionHook.ts
3089
- var import_react24 = require("react");
4808
+ var import_react32 = require("react");
3090
4809
 
3091
4810
  // src/core/types/transition.types.ts
3092
- var import_react23 = require("react");
3093
- var LayoutContext = (0, import_react23.createContext)(null);
4811
+ var import_react31 = require("react");
4812
+ var LayoutContext = (0, import_react31.createContext)(null);
3094
4813
 
3095
4814
  // src/hooks/buildTransitionHook.ts
3096
4815
  function buildLayoutHook(schema, defaultValue) {
3097
4816
  return () => {
3098
- const context = (0, import_react24.useContext)(LayoutContext);
4817
+ const context = (0, import_react32.useContext)(LayoutContext);
3099
4818
  if (!context) {
3100
4819
  return defaultValue;
3101
4820
  }
@@ -3180,16 +4899,16 @@ var needsProxying = (url) => {
3180
4899
 
3181
4900
  // src/templates/rings/NextjsLogo.tsx
3182
4901
  var import_paths = require("@remotion/paths");
3183
- var import_react26 = __toESM(require("react"));
3184
- var import_remotion18 = require("remotion");
4902
+ var import_react34 = __toESM(require("react"));
4903
+ var import_remotion23 = require("remotion");
3185
4904
 
3186
4905
  // src/templates/rings/RippleOutLayout.tsx
3187
- var import_react25 = __toESM(require("react"));
3188
- var import_remotion17 = require("remotion");
3189
- var import_zod5 = require("zod");
3190
- var RippleOutTransitionSchema = import_zod5.z.object({
3191
- progress: import_zod5.z.number().min(0).max(1),
3192
- logoOut: import_zod5.z.number().min(0).max(1)
4906
+ var import_react33 = __toESM(require("react"));
4907
+ var import_remotion22 = require("remotion");
4908
+ var import_zod10 = require("zod");
4909
+ var RippleOutTransitionSchema = import_zod10.z.object({
4910
+ progress: import_zod10.z.number().min(0).max(1),
4911
+ logoOut: import_zod10.z.number().min(0).max(1)
3193
4912
  });
3194
4913
  var defaultRippleOutData = {
3195
4914
  progress: 0,
@@ -3207,10 +4926,10 @@ var RippleOutLayout = ({ data, context, children }) => {
3207
4926
  transitionStart,
3208
4927
  transitionDuration
3209
4928
  } = data || { transitionStart: 2, transitionDuration: 1 };
3210
- const frame = (0, import_remotion17.useCurrentFrame)();
3211
- const { fps } = (0, import_remotion17.useVideoConfig)();
4929
+ const frame = (0, import_remotion22.useCurrentFrame)();
4930
+ const { fps } = (0, import_remotion22.useVideoConfig)();
3212
4931
  const { hierarchy } = useRenderContext();
3213
- import_react25.default.useEffect(() => {
4932
+ import_react33.default.useEffect(() => {
3214
4933
  loadGoogleFont("Inter", {
3215
4934
  subsets: ["latin"],
3216
4935
  weights: ["400", "700"]
@@ -3218,7 +4937,7 @@ var RippleOutLayout = ({ data, context, children }) => {
3218
4937
  }, []);
3219
4938
  const transitionStartFrame = transitionStart * fps;
3220
4939
  const transitionDurationFrames = transitionDuration * fps;
3221
- const logoOut = (0, import_remotion17.spring)({
4940
+ const logoOut = (0, import_remotion22.spring)({
3222
4941
  fps,
3223
4942
  frame,
3224
4943
  config: {
@@ -3231,14 +4950,14 @@ var RippleOutLayout = ({ data, context, children }) => {
3231
4950
  progress: logoOut,
3232
4951
  logoOut
3233
4952
  };
3234
- const childrenArray = import_react25.default.Children.toArray(children).filter(
3235
- (child) => import_react25.default.isValidElement(child)
4953
+ const childrenArray = import_react33.default.Children.toArray(children).filter(
4954
+ (child) => import_react33.default.isValidElement(child)
3236
4955
  );
3237
4956
  const [from, to] = childrenArray;
3238
- return /* @__PURE__ */ import_react25.default.createElement(LayoutContext.Provider, { value: transitionData }, /* @__PURE__ */ import_react25.default.createElement(import_remotion17.AbsoluteFill, { style: {
4957
+ return /* @__PURE__ */ import_react33.default.createElement(LayoutContext.Provider, { value: transitionData }, /* @__PURE__ */ import_react33.default.createElement(import_remotion22.AbsoluteFill, { style: {
3239
4958
  ...container,
3240
4959
  ...context?.boundaries
3241
- } }, /* @__PURE__ */ import_react25.default.createElement(import_remotion17.Sequence, { name: from.props.componentId + " - " + from.props.id, from: 0, durationInFrames: transitionStartFrame + transitionDurationFrames }, from), /* @__PURE__ */ import_react25.default.createElement(import_remotion17.Sequence, { name: to.props.componentId + " - " + to.props.id, from: transitionStartFrame + transitionDurationFrames / 2 }, to)));
4960
+ } }, /* @__PURE__ */ import_react33.default.createElement(import_remotion22.Sequence, { name: from.props.componentId + " - " + from.props.id, from: 0, durationInFrames: transitionStartFrame + transitionDurationFrames }, from), /* @__PURE__ */ import_react33.default.createElement(import_remotion22.Sequence, { name: to.props.componentId + " - " + to.props.id, from: transitionStartFrame + transitionDurationFrames / 2 }, to)));
3242
4961
  };
3243
4962
  var rippleOutLayoutConfig = {
3244
4963
  displayName: "RippleOutLayout",
@@ -3254,23 +4973,23 @@ var nStroke = "M149.508 157.52L69.142 54H54V125.97H66.1136V69.3836L139.999 164.8
3254
4973
  var NextjsLogo = () => {
3255
4974
  const { logoOut } = useRippleOutLayout();
3256
4975
  const outProgress = logoOut;
3257
- const { fps } = (0, import_remotion18.useVideoConfig)();
3258
- const frame = (0, import_remotion18.useCurrentFrame)();
3259
- const evolve1 = (0, import_remotion18.spring)({
4976
+ const { fps } = (0, import_remotion23.useVideoConfig)();
4977
+ const frame = (0, import_remotion23.useCurrentFrame)();
4978
+ const evolve1 = (0, import_remotion23.spring)({
3260
4979
  fps,
3261
4980
  frame,
3262
4981
  config: {
3263
4982
  damping: 200
3264
4983
  }
3265
4984
  });
3266
- const evolve2 = (0, import_remotion18.spring)({
4985
+ const evolve2 = (0, import_remotion23.spring)({
3267
4986
  fps,
3268
4987
  frame: frame - 15,
3269
4988
  config: {
3270
4989
  damping: 200
3271
4990
  }
3272
4991
  });
3273
- const evolve3 = (0, import_remotion18.spring)({
4992
+ const evolve3 = (0, import_remotion23.spring)({
3274
4993
  fps,
3275
4994
  frame: frame - 30,
3276
4995
  config: {
@@ -3279,7 +4998,7 @@ var NextjsLogo = () => {
3279
4998
  },
3280
4999
  durationInFrames: 30
3281
5000
  });
3282
- const style = (0, import_react26.useMemo)(() => {
5001
+ const style = (0, import_react34.useMemo)(() => {
3283
5002
  return {
3284
5003
  height: 140,
3285
5004
  borderRadius: 70,
@@ -3292,10 +5011,10 @@ var NextjsLogo = () => {
3292
5011
  const evolution1 = (0, import_paths.evolvePath)(evolve1, firstPath);
3293
5012
  const evolution2 = (0, import_paths.evolvePath)(evolve2, secondPath);
3294
5013
  const evolution3 = (0, import_paths.evolvePath)(
3295
- (0, import_remotion18.interpolate)(evolve3, [0, 1], [0, 0.7]),
5014
+ (0, import_remotion23.interpolate)(evolve3, [0, 1], [0, 0.7]),
3296
5015
  thirdPath
3297
5016
  );
3298
- return /* @__PURE__ */ import_react26.default.createElement("svg", { style, fill: "none", viewBox: "0 0 180 180" }, /* @__PURE__ */ import_react26.default.createElement("mask", { height: "180", id: "mask", style: mask, width: "180", x: "0", y: "0" }, /* @__PURE__ */ import_react26.default.createElement("circle", { cx: "90", cy: "90", fill: "black", r: "90" })), /* @__PURE__ */ import_react26.default.createElement("mask", { id: "n-mask", style: mask }, /* @__PURE__ */ import_react26.default.createElement("path", { d: nStroke, fill: "black" })), /* @__PURE__ */ import_react26.default.createElement("g", { mask: "url(#mask)" }, /* @__PURE__ */ import_react26.default.createElement("circle", { cx: "90", cy: "90", fill: "black", r: "90" }), /* @__PURE__ */ import_react26.default.createElement("g", { stroke: "url(#gradient0)", mask: "url(#n-mask)" }, /* @__PURE__ */ import_react26.default.createElement(
5017
+ return /* @__PURE__ */ import_react34.default.createElement("svg", { style, fill: "none", viewBox: "0 0 180 180" }, /* @__PURE__ */ import_react34.default.createElement("mask", { height: "180", id: "mask", style: mask, width: "180", x: "0", y: "0" }, /* @__PURE__ */ import_react34.default.createElement("circle", { cx: "90", cy: "90", fill: "black", r: "90" })), /* @__PURE__ */ import_react34.default.createElement("mask", { id: "n-mask", style: mask }, /* @__PURE__ */ import_react34.default.createElement("path", { d: nStroke, fill: "black" })), /* @__PURE__ */ import_react34.default.createElement("g", { mask: "url(#mask)" }, /* @__PURE__ */ import_react34.default.createElement("circle", { cx: "90", cy: "90", fill: "black", r: "90" }), /* @__PURE__ */ import_react34.default.createElement("g", { stroke: "url(#gradient0)", mask: "url(#n-mask)" }, /* @__PURE__ */ import_react34.default.createElement(
3299
5018
  "path",
3300
5019
  {
3301
5020
  strokeWidth: "12.1136",
@@ -3303,7 +5022,7 @@ var NextjsLogo = () => {
3303
5022
  strokeDasharray: evolution1.strokeDasharray,
3304
5023
  strokeDashoffset: evolution1.strokeDashoffset
3305
5024
  }
3306
- ), /* @__PURE__ */ import_react26.default.createElement(
5025
+ ), /* @__PURE__ */ import_react34.default.createElement(
3307
5026
  "path",
3308
5027
  {
3309
5028
  strokeWidth: 12.1136,
@@ -3311,7 +5030,7 @@ var NextjsLogo = () => {
3311
5030
  strokeDasharray: evolution2.strokeDasharray,
3312
5031
  strokeDashoffset: evolution2.strokeDashoffset
3313
5032
  }
3314
- )), /* @__PURE__ */ import_react26.default.createElement(
5033
+ )), /* @__PURE__ */ import_react34.default.createElement(
3315
5034
  "path",
3316
5035
  {
3317
5036
  stroke: "url(#gradient1)",
@@ -3320,7 +5039,7 @@ var NextjsLogo = () => {
3320
5039
  strokeDashoffset: evolution3.strokeDashoffset,
3321
5040
  strokeWidth: "12"
3322
5041
  }
3323
- )), /* @__PURE__ */ import_react26.default.createElement("defs", null, /* @__PURE__ */ import_react26.default.createElement(
5042
+ )), /* @__PURE__ */ import_react34.default.createElement("defs", null, /* @__PURE__ */ import_react34.default.createElement(
3324
5043
  "linearGradient",
3325
5044
  {
3326
5045
  gradientUnits: "userSpaceOnUse",
@@ -3330,9 +5049,9 @@ var NextjsLogo = () => {
3330
5049
  y1: "116.5",
3331
5050
  y2: "160.5"
3332
5051
  },
3333
- /* @__PURE__ */ import_react26.default.createElement("stop", { stopColor: "white" }),
3334
- /* @__PURE__ */ import_react26.default.createElement("stop", { offset: "1", stopColor: "white", stopOpacity: "0" })
3335
- ), /* @__PURE__ */ import_react26.default.createElement(
5052
+ /* @__PURE__ */ import_react34.default.createElement("stop", { stopColor: "white" }),
5053
+ /* @__PURE__ */ import_react34.default.createElement("stop", { offset: "1", stopColor: "white", stopOpacity: "0" })
5054
+ ), /* @__PURE__ */ import_react34.default.createElement(
3336
5055
  "linearGradient",
3337
5056
  {
3338
5057
  gradientUnits: "userSpaceOnUse",
@@ -3342,8 +5061,8 @@ var NextjsLogo = () => {
3342
5061
  y1: "54",
3343
5062
  y2: "106.875"
3344
5063
  },
3345
- /* @__PURE__ */ import_react26.default.createElement("stop", { stopColor: "white" }),
3346
- /* @__PURE__ */ import_react26.default.createElement("stop", { offset: "1", stopColor: "white", stopOpacity: "0" })
5064
+ /* @__PURE__ */ import_react34.default.createElement("stop", { stopColor: "white" }),
5065
+ /* @__PURE__ */ import_react34.default.createElement("stop", { offset: "1", stopColor: "white", stopOpacity: "0" })
3347
5066
  )));
3348
5067
  };
3349
5068
  var nextjsLogoConfig = {
@@ -3353,22 +5072,22 @@ var nextjsLogoConfig = {
3353
5072
  };
3354
5073
 
3355
5074
  // src/templates/rings/Rings.tsx
3356
- var import_react27 = __toESM(require("react"));
3357
- var import_remotion19 = require("remotion");
5075
+ var import_react35 = __toESM(require("react"));
5076
+ var import_remotion24 = require("remotion");
3358
5077
  var RadialGradient = ({ radius, color }) => {
3359
5078
  const height = radius * 2;
3360
5079
  const width = radius * 2;
3361
5080
  return (
3362
5081
  // @ts-ignore
3363
- /* @__PURE__ */ import_react27.default.createElement(
3364
- import_remotion19.AbsoluteFill,
5082
+ /* @__PURE__ */ import_react35.default.createElement(
5083
+ import_remotion24.AbsoluteFill,
3365
5084
  {
3366
5085
  style: {
3367
5086
  justifyContent: "center",
3368
5087
  alignItems: "center"
3369
5088
  }
3370
5089
  },
3371
- /* @__PURE__ */ import_react27.default.createElement(
5090
+ /* @__PURE__ */ import_react35.default.createElement(
3372
5091
  "div",
3373
5092
  {
3374
5093
  style: {
@@ -3388,11 +5107,11 @@ var Rings = ({ context, data }) => {
3388
5107
  const { logoOut } = useRippleOutLayout();
3389
5108
  const outProgress = logoOut;
3390
5109
  const scale = 1 / (1 - outProgress);
3391
- const { height } = (0, import_remotion19.useVideoConfig)();
5110
+ const { height } = (0, import_remotion24.useVideoConfig)();
3392
5111
  return (
3393
5112
  // @ts-ignore
3394
- /* @__PURE__ */ import_react27.default.createElement(
3395
- import_remotion19.AbsoluteFill,
5113
+ /* @__PURE__ */ import_react35.default.createElement(
5114
+ import_remotion24.AbsoluteFill,
3396
5115
  {
3397
5116
  style: {
3398
5117
  transform: `scale(${scale})`,
@@ -3400,12 +5119,12 @@ var Rings = ({ context, data }) => {
3400
5119
  }
3401
5120
  },
3402
5121
  new Array(5).fill(true).map((_, i) => {
3403
- return /* @__PURE__ */ import_react27.default.createElement(
5122
+ return /* @__PURE__ */ import_react35.default.createElement(
3404
5123
  RadialGradient,
3405
5124
  {
3406
5125
  key: i,
3407
5126
  radius: height * 0.3 * i,
3408
- color: (0, import_remotion19.interpolateColors)(i, [0, 4], ["#fff", "#fff"])
5127
+ color: (0, import_remotion24.interpolateColors)(i, [0, 4], ["#fff", "#fff"])
3409
5128
  }
3410
5129
  );
3411
5130
  }).reverse()
@@ -3419,8 +5138,8 @@ var ringsConfig = {
3419
5138
  };
3420
5139
 
3421
5140
  // src/templates/rings/TextFade.tsx
3422
- var import_react28 = __toESM(require("react"));
3423
- var import_remotion20 = require("remotion");
5141
+ var import_react36 = __toESM(require("react"));
5142
+ var import_remotion25 = require("remotion");
3424
5143
  var TextFade = (props) => {
3425
5144
  const { children, context, data } = props;
3426
5145
  const { animation } = data || {
@@ -3428,9 +5147,9 @@ var TextFade = (props) => {
3428
5147
  duration: 1
3429
5148
  }
3430
5149
  };
3431
- const { fps } = (0, import_remotion20.useVideoConfig)();
3432
- const frame = (0, import_remotion20.useCurrentFrame)();
3433
- const progress = (0, import_remotion20.spring)({
5150
+ const { fps } = (0, import_remotion25.useVideoConfig)();
5151
+ const frame = (0, import_remotion25.useCurrentFrame)();
5152
+ const progress = (0, import_remotion25.spring)({
3434
5153
  fps,
3435
5154
  frame,
3436
5155
  config: {
@@ -3438,10 +5157,10 @@ var TextFade = (props) => {
3438
5157
  },
3439
5158
  durationInFrames: animation.duration * fps
3440
5159
  });
3441
- const rightStop = (0, import_remotion20.interpolate)(progress, [0, 1], [200, 0]);
5160
+ const rightStop = (0, import_remotion25.interpolate)(progress, [0, 1], [200, 0]);
3442
5161
  const leftStop = Math.max(0, rightStop - 60);
3443
5162
  const maskImage = `linear-gradient(-45deg, transparent ${leftStop}%, black ${rightStop}%)`;
3444
- const container2 = (0, import_react28.useMemo)(() => {
5163
+ const container2 = (0, import_react36.useMemo)(() => {
3445
5164
  return {
3446
5165
  width: "100%",
3447
5166
  height: "100%",
@@ -3449,7 +5168,7 @@ var TextFade = (props) => {
3449
5168
  alignItems: "center"
3450
5169
  };
3451
5170
  }, []);
3452
- const content = (0, import_react28.useMemo)(() => {
5171
+ const content = (0, import_react36.useMemo)(() => {
3453
5172
  return {
3454
5173
  ...context?.boundaries,
3455
5174
  maskImage,
@@ -3461,7 +5180,7 @@ var TextFade = (props) => {
3461
5180
  }, [maskImage]);
3462
5181
  return (
3463
5182
  // @ts-ignore
3464
- /* @__PURE__ */ import_react28.default.createElement(import_remotion20.AbsoluteFill, { style: container2 }, /* @__PURE__ */ import_react28.default.createElement("div", { style: content }, children))
5183
+ /* @__PURE__ */ import_react36.default.createElement(import_remotion25.AbsoluteFill, { style: container2 }, /* @__PURE__ */ import_react36.default.createElement("div", { style: content }, children))
3465
5184
  );
3466
5185
  };
3467
5186
  var textFadeConfig = {
@@ -3492,259 +5211,41 @@ registerComponent(
3492
5211
  );
3493
5212
 
3494
5213
  // src/templates/waveform/components/WaveformCircle.tsx
3495
- var import_react31 = __toESM(require("react"));
3496
-
3497
- // src/templates/waveform/Waveform.tsx
3498
- var import_react30 = __toESM(require("react"));
3499
- var import_remotion22 = require("remotion");
3500
-
3501
- // src/templates/waveform/hooks/useWaveformData.ts
3502
- var import_react29 = require("react");
3503
- var import_media_utils = require("@remotion/media-utils");
3504
- var import_remotion21 = require("remotion");
3505
- var isValidPowerOfTwo = (num) => {
3506
- return num > 0 && (num & num - 1) === 0;
3507
- };
3508
- var getClosestPowerOfTwo = (num) => {
3509
- if (num <= 0) return 32;
3510
- let power = 1;
3511
- while (power < num) {
3512
- power *= 2;
3513
- }
3514
- const lower = power / 2;
3515
- const upper = power;
3516
- return Math.abs(num - lower) < Math.abs(num - upper) ? lower : upper;
3517
- };
3518
- var useWaveformData = (config15) => {
3519
- const {
3520
- audioSrc,
3521
- numberOfSamples,
3522
- windowInSeconds,
3523
- dataOffsetInSeconds = 0,
3524
- normalize = false,
3525
- frame,
3526
- fps,
3527
- posterize,
3528
- includeFrequencyData = false,
3529
- minDb = -100,
3530
- maxDb = -30
3531
- } = config15;
3532
- const { root } = useComposition();
3533
- const validatedNumberOfSamples = (0, import_react29.useMemo)(() => {
3534
- if (!isValidPowerOfTwo(numberOfSamples)) {
3535
- console.warn(
3536
- `numberOfSamples must be a power of 2. Adjusting ${numberOfSamples} to ${getClosestPowerOfTwo(numberOfSamples)}`
3537
- );
3538
- return getClosestPowerOfTwo(numberOfSamples);
3539
- }
3540
- return numberOfSamples;
3541
- }, [numberOfSamples]);
3542
- const { source, audioStartsFrom } = (0, import_react29.useMemo)(() => {
3543
- if (audioSrc.startsWith("http")) {
3544
- return { source: audioSrc, audioStartsFrom: void 0 };
3545
- }
3546
- if (audioSrc.startsWith("ref:")) {
3547
- const matchingComponent = findMatchingComponents(root, [
3548
- audioSrc.replace("ref:", "")
3549
- ]);
3550
- if (matchingComponent.length > 0) {
3551
- const firstMatchingComponent = matchingComponent[0];
3552
- if (firstMatchingComponent.componentId === "AudioAtom") {
3553
- return {
3554
- source: firstMatchingComponent.data.src,
3555
- audioStartsFrom: firstMatchingComponent.data?.startFrom ?? void 0
3556
- };
3557
- }
3558
- if (firstMatchingComponent.type === "layout" || firstMatchingComponent.type === "scene") {
3559
- const audioComponents = findMatchingComponentsByQuery(
3560
- firstMatchingComponent.childrenData,
3561
- { componentId: "AudioAtom" }
3562
- );
3563
- if (audioComponents.length > 0) {
3564
- return {
3565
- source: audioComponents[0].data.src,
3566
- audioStartsFrom: audioComponents[0].data?.startFrom ?? void 0
3567
- };
3568
- }
3569
- }
3570
- }
3571
- }
3572
- return { source: (0, import_remotion21.staticFile)(audioSrc), audioStartsFrom: void 0 };
3573
- }, [audioSrc]);
3574
- const audioData = (0, import_media_utils.useAudioData)(source);
3575
- const adjustedFrame = (0, import_react29.useMemo)(() => {
3576
- if (posterize && posterize > 1) {
3577
- return Math.round(frame / posterize) * posterize;
3578
- }
3579
- let offset = 0;
3580
- if (audioStartsFrom && audioStartsFrom != 0) {
3581
- offset += Math.round(audioStartsFrom * fps);
3582
- }
3583
- if (dataOffsetInSeconds != 0) {
3584
- offset += Math.round(dataOffsetInSeconds * fps);
3585
- }
3586
- return frame + offset;
3587
- }, [frame, posterize, dataOffsetInSeconds, audioStartsFrom]);
3588
- const waveformData = (0, import_react29.useMemo)(() => {
3589
- if (!audioData) return null;
3590
- try {
3591
- const waveform = (0, import_media_utils.visualizeAudioWaveform)({
3592
- fps,
3593
- frame: adjustedFrame,
3594
- audioData,
3595
- numberOfSamples: validatedNumberOfSamples,
3596
- windowInSeconds,
3597
- dataOffsetInSeconds: 0,
3598
- normalize
3599
- });
3600
- return waveform;
3601
- } catch (error2) {
3602
- console.error("Error generating waveform:", error2);
3603
- return null;
3604
- }
3605
- }, [
3606
- audioData,
3607
- adjustedFrame,
3608
- fps,
3609
- validatedNumberOfSamples,
3610
- windowInSeconds,
3611
- dataOffsetInSeconds,
3612
- normalize
3613
- ]);
3614
- const {
3615
- frequencyData,
3616
- amplitudes,
3617
- bass,
3618
- mid,
3619
- treble,
3620
- bassValues,
3621
- midValues,
3622
- trebleValues
3623
- } = (0, import_react29.useMemo)(() => {
3624
- if (!audioData || !includeFrequencyData) {
3625
- return {
3626
- frequencyData: null,
3627
- amplitudes: null,
3628
- bass: null,
3629
- mid: null,
3630
- treble: null,
3631
- bassValues: null,
3632
- midValues: null,
3633
- trebleValues: null
3634
- };
3635
- }
3636
- try {
3637
- const frequencyData2 = (0, import_media_utils.visualizeAudio)({
3638
- fps,
3639
- frame: adjustedFrame,
3640
- audioData,
3641
- numberOfSamples: validatedNumberOfSamples
3642
- });
3643
- const { sampleRate } = audioData;
3644
- const bassValues2 = [];
3645
- const midValues2 = [];
3646
- const trebleValues2 = [];
3647
- for (let i = 0; i < frequencyData2.length; i++) {
3648
- const freq = i * sampleRate / (2 * frequencyData2.length);
3649
- const value = frequencyData2[i];
3650
- if (freq >= 0 && freq < 250) {
3651
- bassValues2.push(value * 2.5);
3652
- } else if (freq >= 250 && freq < 4e3) {
3653
- midValues2.push(value * 3);
3654
- midValues2.push(value * 4.5);
3655
- midValues2.push(value * 5);
3656
- } else if (freq >= 4e3 && freq < sampleRate / 2) {
3657
- trebleValues2.push(value * 30);
3658
- }
3659
- }
3660
- const getAverage = (arr) => arr.length > 0 ? arr.reduce((a, b) => a + b, 0) / arr.length : 0;
3661
- const bass2 = getAverage(bassValues2);
3662
- const mid2 = getAverage(midValues2);
3663
- const treble2 = getAverage(trebleValues2);
3664
- const amplitudes2 = frequencyData2.map((value) => {
3665
- const db = 20 * Math.log10(value);
3666
- const scaled = (db - minDb) / (maxDb - minDb);
3667
- return Math.max(0, Math.min(1, scaled));
3668
- });
3669
- return {
3670
- frequencyData: frequencyData2,
3671
- amplitudes: amplitudes2,
3672
- bass: bass2,
3673
- mid: mid2,
3674
- treble: treble2,
3675
- bassValues: bassValues2,
3676
- midValues: midValues2,
3677
- trebleValues: trebleValues2.reverse()
3678
- };
3679
- } catch (error2) {
3680
- console.error("Error generating frequency data:", error2);
3681
- return {
3682
- frequencyData: null,
3683
- amplitudes: null,
3684
- bass: null,
3685
- mid: null,
3686
- treble: null
3687
- };
3688
- }
3689
- }, [
3690
- audioData,
3691
- includeFrequencyData,
3692
- adjustedFrame,
3693
- fps,
3694
- validatedNumberOfSamples,
3695
- windowInSeconds,
3696
- dataOffsetInSeconds,
3697
- minDb,
3698
- maxDb
3699
- ]);
3700
- const isLoading = !audioData;
3701
- const error = audioData === null && !isLoading ? "Failed to load audio data" : null;
3702
- return {
3703
- waveformData,
3704
- frequencyData,
3705
- amplitudes,
3706
- audioData,
3707
- isLoading,
3708
- error,
3709
- bass,
3710
- bassValues,
3711
- mid,
3712
- midValues,
3713
- treble,
3714
- trebleValues
3715
- };
3716
- };
5214
+ var import_react38 = __toESM(require("react"));
3717
5215
 
3718
5216
  // src/templates/waveform/Waveform.tsx
3719
- var WaveformContext = (0, import_react30.createContext)(null);
5217
+ var import_react37 = __toESM(require("react"));
5218
+ var import_remotion26 = require("remotion");
5219
+ var WaveformContext = (0, import_react37.createContext)(null);
3720
5220
  var useWaveformContext = () => {
3721
- const context = (0, import_react30.useContext)(WaveformContext);
5221
+ const context = (0, import_react37.useContext)(WaveformContext);
3722
5222
  if (!context) {
3723
5223
  throw new Error("useWaveformContext must be used within a Waveform component");
3724
5224
  }
3725
5225
  return context;
3726
5226
  };
3727
5227
  var Waveform = ({
3728
- config: config15,
5228
+ config: config18,
3729
5229
  children,
3730
5230
  className = "",
3731
5231
  style = {}
3732
5232
  }) => {
3733
- const frame = (0, import_remotion22.useCurrentFrame)();
3734
- const { width: videoWidth, height: videoHeight, fps } = (0, import_remotion22.useVideoConfig)();
5233
+ const frame = (0, import_remotion26.useCurrentFrame)();
5234
+ const { width: videoWidth, height: videoHeight, fps } = (0, import_remotion26.useVideoConfig)();
3735
5235
  const { waveformData, frequencyData, amplitudes, audioData, bass, mid, treble, bassValues, midValues, trebleValues } = useWaveformData({
3736
- audioSrc: config15.audioSrc,
3737
- numberOfSamples: config15.numberOfSamples || 128,
3738
- windowInSeconds: config15.windowInSeconds || 1 / fps,
3739
- dataOffsetInSeconds: config15.dataOffsetInSeconds || 0,
3740
- normalize: config15.normalize || false,
5236
+ audioSrc: config18.audioSrc,
5237
+ numberOfSamples: config18.numberOfSamples || 128,
5238
+ windowInSeconds: config18.windowInSeconds || 1 / fps,
5239
+ dataOffsetInSeconds: config18.dataOffsetInSeconds || 0,
5240
+ normalize: config18.normalize || false,
3741
5241
  frame,
3742
5242
  fps,
3743
- posterize: config15.posterize,
3744
- includeFrequencyData: config15.useFrequencyData || false
5243
+ posterize: config18.posterize,
5244
+ includeFrequencyData: config18.useFrequencyData || false,
5245
+ smoothNormalisation: config18.smoothNormalisation
3745
5246
  });
3746
- const width = config15.width || videoWidth;
3747
- const height = config15.height || videoHeight;
5247
+ const width = config18.width || videoWidth;
5248
+ const height = config18.height || videoHeight;
3748
5249
  const contextValue = {
3749
5250
  waveformData,
3750
5251
  frequencyData,
@@ -3752,7 +5253,7 @@ var Waveform = ({
3752
5253
  audioData,
3753
5254
  frame,
3754
5255
  fps,
3755
- config: config15,
5256
+ config: config18,
3756
5257
  width,
3757
5258
  height,
3758
5259
  bass,
@@ -3762,7 +5263,7 @@ var Waveform = ({
3762
5263
  midValues,
3763
5264
  trebleValues
3764
5265
  };
3765
- return /* @__PURE__ */ import_react30.default.createElement(WaveformContext.Provider, { value: contextValue }, /* @__PURE__ */ import_react30.default.createElement(
5266
+ return /* @__PURE__ */ import_react37.default.createElement(WaveformContext.Provider, { value: contextValue }, /* @__PURE__ */ import_react37.default.createElement(
3766
5267
  "div",
3767
5268
  {
3768
5269
  className: `relative ${className}`,
@@ -3770,7 +5271,7 @@ var Waveform = ({
3770
5271
  width,
3771
5272
  height,
3772
5273
  position: "relative",
3773
- backgroundColor: config15.backgroundColor || "transparent",
5274
+ backgroundColor: config18.backgroundColor || "transparent",
3774
5275
  ...style
3775
5276
  }
3776
5277
  },
@@ -3781,7 +5282,7 @@ var Waveform = ({
3781
5282
  // src/templates/waveform/components/WaveformCircle.tsx
3782
5283
  var WaveformCircle = ({ data }) => {
3783
5284
  const {
3784
- config: config15,
5285
+ config: config18,
3785
5286
  className = "",
3786
5287
  style = {},
3787
5288
  strokeColor = "#FF6B6B",
@@ -3798,7 +5299,7 @@ var WaveformCircle = ({ data }) => {
3798
5299
  gradientStartColor,
3799
5300
  gradientEndColor
3800
5301
  } = data;
3801
- return /* @__PURE__ */ import_react31.default.createElement(Waveform, { config: config15, className, style }, /* @__PURE__ */ import_react31.default.createElement(
5302
+ return /* @__PURE__ */ import_react38.default.createElement(Waveform, { config: config18, className, style }, /* @__PURE__ */ import_react38.default.createElement(
3802
5303
  WaveformCircleContent,
3803
5304
  {
3804
5305
  strokeColor,
@@ -3837,7 +5338,7 @@ var WaveformCircleContent = ({
3837
5338
  const circleCenterX = width * (centerX || 50) / 100;
3838
5339
  const circleCenterY = height * (centerY || 50) / 100;
3839
5340
  const rotation = frame * (rotationSpeed || 0) % 360;
3840
- const circularPath = (0, import_react31.useMemo)(() => {
5341
+ const circularPath = (0, import_react38.useMemo)(() => {
3841
5342
  if (!waveformData) return "";
3842
5343
  const totalAngle = (endAngle || 360) - (startAngle || 0);
3843
5344
  const angleStep = totalAngle / waveformData.length;
@@ -3859,11 +5360,11 @@ var WaveformCircleContent = ({
3859
5360
  return path;
3860
5361
  }, [waveformData, circleRadius, circleCenterX, circleCenterY, startAngle, endAngle, rotation, amplitude]);
3861
5362
  if (!waveformData) {
3862
- return /* @__PURE__ */ import_react31.default.createElement("div", { className: "flex items-center justify-center w-full h-full text-gray-500" }, "Loading circular waveform...");
5363
+ return /* @__PURE__ */ import_react38.default.createElement("div", { className: "flex items-center justify-center w-full h-full text-gray-500" }, "Loading circular waveform...");
3863
5364
  }
3864
5365
  const gradientId = "circle-waveform-gradient";
3865
5366
  const hasGradient = gradientStartColor && gradientEndColor;
3866
- return /* @__PURE__ */ import_react31.default.createElement(
5367
+ return /* @__PURE__ */ import_react38.default.createElement(
3867
5368
  "svg",
3868
5369
  {
3869
5370
  width,
@@ -3871,8 +5372,8 @@ var WaveformCircleContent = ({
3871
5372
  className: "absolute inset-0",
3872
5373
  style: { pointerEvents: "none" }
3873
5374
  },
3874
- hasGradient && /* @__PURE__ */ import_react31.default.createElement("defs", null, /* @__PURE__ */ import_react31.default.createElement("linearGradient", { id: gradientId, x1: "0%", y1: "0%", x2: "100%", y2: "0%" }, /* @__PURE__ */ import_react31.default.createElement("stop", { offset: "0%", stopColor: gradientStartColor }), /* @__PURE__ */ import_react31.default.createElement("stop", { offset: "100%", stopColor: gradientEndColor }))),
3875
- /* @__PURE__ */ import_react31.default.createElement(
5375
+ hasGradient && /* @__PURE__ */ import_react38.default.createElement("defs", null, /* @__PURE__ */ import_react38.default.createElement("linearGradient", { id: gradientId, x1: "0%", y1: "0%", x2: "100%", y2: "0%" }, /* @__PURE__ */ import_react38.default.createElement("stop", { offset: "0%", stopColor: gradientStartColor }), /* @__PURE__ */ import_react38.default.createElement("stop", { offset: "100%", stopColor: gradientEndColor }))),
5376
+ /* @__PURE__ */ import_react38.default.createElement(
3876
5377
  "path",
3877
5378
  {
3878
5379
  d: circularPath,
@@ -3888,10 +5389,10 @@ var WaveformCircleContent = ({
3888
5389
  };
3889
5390
 
3890
5391
  // src/templates/waveform/components/WaveformHistogram.tsx
3891
- var import_react32 = __toESM(require("react"));
5392
+ var import_react39 = __toESM(require("react"));
3892
5393
  var WaveformHistogram = ({ data }) => {
3893
5394
  const {
3894
- config: config15,
5395
+ config: config18,
3895
5396
  className = "",
3896
5397
  style = {},
3897
5398
  barColor = "#FF6B6B",
@@ -3904,13 +5405,14 @@ var WaveformHistogram = ({ data }) => {
3904
5405
  histogramStyle = "centered",
3905
5406
  amplitude = 1,
3906
5407
  multiplier = 1,
5408
+ barSlant = 0,
3907
5409
  gradientStartColor,
3908
5410
  gradientEndColor,
3909
5411
  gradientDirection = "vertical",
3910
5412
  gradientStyle = "normal",
3911
5413
  waveDirection = "right-to-left"
3912
5414
  } = data;
3913
- return /* @__PURE__ */ import_react32.default.createElement(Waveform, { config: config15, className, style }, /* @__PURE__ */ import_react32.default.createElement(
5415
+ return /* @__PURE__ */ import_react39.default.createElement(Waveform, { config: config18, className, style }, /* @__PURE__ */ import_react39.default.createElement(
3914
5416
  WaveformHistogramContent,
3915
5417
  {
3916
5418
  barColor,
@@ -3927,7 +5429,8 @@ var WaveformHistogram = ({ data }) => {
3927
5429
  gradientDirection,
3928
5430
  multiplier,
3929
5431
  gradientStyle,
3930
- waveDirection
5432
+ waveDirection,
5433
+ barSlant
3931
5434
  }
3932
5435
  ));
3933
5436
  };
@@ -3946,12 +5449,13 @@ var WaveformHistogramContent = ({
3946
5449
  gradientDirection,
3947
5450
  multiplier,
3948
5451
  gradientStyle,
3949
- waveDirection
5452
+ waveDirection,
5453
+ barSlant
3950
5454
  }) => {
3951
5455
  const { waveformData, frequencyData, amplitudes, width, height } = useWaveformContext();
3952
5456
  const dataToUse = amplitudes || waveformData;
3953
5457
  if (!dataToUse) {
3954
- return /* @__PURE__ */ import_react32.default.createElement("div", { className: "flex items-center justify-center w-full h-full text-gray-500" }, "Loading histogram...");
5458
+ return /* @__PURE__ */ import_react39.default.createElement("div", { className: "flex items-center justify-center w-full h-full text-gray-500" }, "Loading histogram...");
3955
5459
  }
3956
5460
  let directedData = waveDirection === "left-to-right" ? dataToUse.slice(1).reverse() : dataToUse;
3957
5461
  const frequencies = horizontalSymmetry ? [...directedData, ...directedData.slice(1).reverse()] : Array(multiplier).fill(directedData).flat();
@@ -3975,7 +5479,7 @@ var WaveformHistogramContent = ({
3975
5479
  },
3976
5480
  opacity: gradientStyle === "mirrored" && !growUpwards ? 0.25 : 1
3977
5481
  };
3978
- return /* @__PURE__ */ import_react32.default.createElement("div", { style: containerStyle2 }, frequencies.map((value, index) => /* @__PURE__ */ import_react32.default.createElement(
5482
+ return /* @__PURE__ */ import_react39.default.createElement("div", { style: containerStyle2 }, frequencies.map((value, index) => /* @__PURE__ */ import_react39.default.createElement(
3979
5483
  "div",
3980
5484
  {
3981
5485
  key: index,
@@ -3987,7 +5491,9 @@ var WaveformHistogramContent = ({
3987
5491
  Math.abs(value) * (height / 2) * (amplitude || 1)
3988
5492
  )}px`,
3989
5493
  borderRadius: growUpwards ? `${barBorderRadius}px ${barBorderRadius}px 0 0` : `0 0 ${barBorderRadius}px ${barBorderRadius}px`,
3990
- opacity
5494
+ opacity,
5495
+ transform: barSlant ? `rotate(${barSlant}deg)` : void 0,
5496
+ transformOrigin: "center bottom"
3991
5497
  }
3992
5498
  }
3993
5499
  )));
@@ -4007,7 +5513,7 @@ var WaveformHistogramContent = ({
4007
5513
  width: "100%",
4008
5514
  left: 0
4009
5515
  };
4010
- return /* @__PURE__ */ import_react32.default.createElement(import_react32.default.Fragment, null, /* @__PURE__ */ import_react32.default.createElement("div", { style: topHalfStyle }, /* @__PURE__ */ import_react32.default.createElement(Bars, { growUpwards: true })), /* @__PURE__ */ import_react32.default.createElement("div", { style: bottomHalfStyle }, /* @__PURE__ */ import_react32.default.createElement(Bars, { growUpwards: false })));
5516
+ return /* @__PURE__ */ import_react39.default.createElement(import_react39.default.Fragment, null, /* @__PURE__ */ import_react39.default.createElement("div", { style: topHalfStyle }, /* @__PURE__ */ import_react39.default.createElement(Bars, { growUpwards: true })), /* @__PURE__ */ import_react39.default.createElement("div", { style: bottomHalfStyle }, /* @__PURE__ */ import_react39.default.createElement(Bars, { growUpwards: false })));
4011
5517
  }
4012
5518
  const containerStyle = {
4013
5519
  width: "100%",
@@ -4016,14 +5522,14 @@ var WaveformHistogramContent = ({
4016
5522
  height: `${height / 2}px`,
4017
5523
  left: 0
4018
5524
  };
4019
- return /* @__PURE__ */ import_react32.default.createElement("div", { style: containerStyle }, /* @__PURE__ */ import_react32.default.createElement(Bars, { growUpwards: true }));
5525
+ return /* @__PURE__ */ import_react39.default.createElement("div", { style: containerStyle }, /* @__PURE__ */ import_react39.default.createElement(Bars, { growUpwards: true }));
4020
5526
  };
4021
5527
 
4022
5528
  // src/templates/waveform/components/WaveformHistogramRanged.tsx
4023
- var import_react33 = __toESM(require("react"));
5529
+ var import_react40 = __toESM(require("react"));
4024
5530
  var WaveformHistogramRanged = ({ data }) => {
4025
5531
  const {
4026
- config: config15,
5532
+ config: config18,
4027
5533
  className = "",
4028
5534
  style = {},
4029
5535
  barColor = "#FF6B6B",
@@ -4045,9 +5551,10 @@ var WaveformHistogramRanged = ({ data }) => {
4045
5551
  gradientDirection = "vertical",
4046
5552
  gradientStyle = "normal",
4047
5553
  horizontalSymmetry = false,
4048
- waveDirection = "right-to-left"
5554
+ waveDirection = "right-to-left",
5555
+ barSlant = 0
4049
5556
  } = data;
4050
- return /* @__PURE__ */ import_react33.default.createElement(Waveform, { config: config15, className, style }, /* @__PURE__ */ import_react33.default.createElement(
5557
+ return /* @__PURE__ */ import_react40.default.createElement(Waveform, { config: config18, className, style }, /* @__PURE__ */ import_react40.default.createElement(
4051
5558
  WaveformHistogramRangedContent,
4052
5559
  {
4053
5560
  barColor,
@@ -4069,7 +5576,8 @@ var WaveformHistogramRanged = ({ data }) => {
4069
5576
  gradientDirection,
4070
5577
  gradientStyle,
4071
5578
  horizontalSymmetry,
4072
- waveDirection
5579
+ waveDirection,
5580
+ barSlant
4073
5581
  }
4074
5582
  ));
4075
5583
  };
@@ -4093,11 +5601,12 @@ var WaveformHistogramRangedContent = ({
4093
5601
  gradientDirection,
4094
5602
  gradientStyle,
4095
5603
  horizontalSymmetry,
4096
- waveDirection
5604
+ waveDirection,
5605
+ barSlant
4097
5606
  }) => {
4098
5607
  const { amplitudes, bassValues, midValues, trebleValues, height } = useWaveformContext();
4099
5608
  if (!amplitudes || !bassValues || !midValues || !trebleValues) {
4100
- return /* @__PURE__ */ import_react33.default.createElement("div", { className: "flex items-center justify-center w-full h-full text-gray-500" }, "Loading frequency data...");
5609
+ return /* @__PURE__ */ import_react40.default.createElement("div", { className: "flex items-center justify-center w-full h-full text-gray-500" }, "Loading frequency data...");
4101
5610
  }
4102
5611
  const bassFrequencies = bassValues;
4103
5612
  const midFrequencies = midValues;
@@ -4121,12 +5630,12 @@ var WaveformHistogramRangedContent = ({
4121
5630
  },
4122
5631
  opacity: gradientStyle === "mirrored" && !growUpwards ? 0.25 : 1
4123
5632
  };
4124
- return /* @__PURE__ */ import_react33.default.createElement("div", { style: containerStyle2 }, unifiedWaveform.map((value, index) => {
5633
+ return /* @__PURE__ */ import_react40.default.createElement("div", { style: containerStyle2 }, unifiedWaveform.map((value, index) => {
4125
5634
  const rangeName = index === 0 ? "Bass" : index === 1 ? "Mid" : "Treble";
4126
5635
  const styleGradientProp = gradientStartColor && gradientEndColor ? {
4127
5636
  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})`
4128
5637
  } : { backgroundColor: barColor };
4129
- return /* @__PURE__ */ import_react33.default.createElement(
5638
+ return /* @__PURE__ */ import_react40.default.createElement(
4130
5639
  "div",
4131
5640
  {
4132
5641
  key: index,
@@ -4140,11 +5649,13 @@ var WaveformHistogramRangedContent = ({
4140
5649
  )}px`,
4141
5650
  borderRadius: growUpwards ? `${barBorderRadius}px ${barBorderRadius}px 0 0` : `0 0 ${barBorderRadius}px ${barBorderRadius}px`,
4142
5651
  opacity,
4143
- position: "relative"
5652
+ position: "relative",
5653
+ transform: barSlant ? `rotate(${barSlant}deg)` : void 0,
5654
+ transformOrigin: "center bottom"
4144
5655
  },
4145
5656
  title: `${rangeName}: ${(value * 100).toFixed(1)}%`
4146
5657
  },
4147
- rangeLabels && /* @__PURE__ */ import_react33.default.createElement("div", { style: {
5658
+ rangeLabels && /* @__PURE__ */ import_react40.default.createElement("div", { style: {
4148
5659
  position: "absolute",
4149
5660
  bottom: growUpwards ? "-20px" : "auto",
4150
5661
  top: growUpwards ? "auto" : "-20px",
@@ -4172,7 +5683,7 @@ var WaveformHistogramRangedContent = ({
4172
5683
  width: "100%",
4173
5684
  left: 0
4174
5685
  };
4175
- return /* @__PURE__ */ import_react33.default.createElement(import_react33.default.Fragment, null, /* @__PURE__ */ import_react33.default.createElement("div", { style: topHalfStyle }, /* @__PURE__ */ import_react33.default.createElement(Bars, { growUpwards: true })), /* @__PURE__ */ import_react33.default.createElement("div", { style: bottomHalfStyle }, /* @__PURE__ */ import_react33.default.createElement(Bars, { growUpwards: false })));
5686
+ return /* @__PURE__ */ import_react40.default.createElement(import_react40.default.Fragment, null, /* @__PURE__ */ import_react40.default.createElement("div", { style: topHalfStyle }, /* @__PURE__ */ import_react40.default.createElement(Bars, { growUpwards: true })), /* @__PURE__ */ import_react40.default.createElement("div", { style: bottomHalfStyle }, /* @__PURE__ */ import_react40.default.createElement(Bars, { growUpwards: false })));
4176
5687
  }
4177
5688
  const containerStyle = {
4178
5689
  width: "100%",
@@ -4181,13 +5692,13 @@ var WaveformHistogramRangedContent = ({
4181
5692
  height: `${height / 2}px`,
4182
5693
  left: 0
4183
5694
  };
4184
- return /* @__PURE__ */ import_react33.default.createElement("div", { style: containerStyle }, /* @__PURE__ */ import_react33.default.createElement(Bars, { growUpwards: true }));
5695
+ return /* @__PURE__ */ import_react40.default.createElement("div", { style: containerStyle }, /* @__PURE__ */ import_react40.default.createElement(Bars, { growUpwards: true }));
4185
5696
  };
4186
5697
 
4187
5698
  // src/templates/waveform/components/WaveformLine.tsx
4188
- var import_react34 = __toESM(require("react"));
5699
+ var import_react41 = __toESM(require("react"));
4189
5700
  var import_media_utils2 = require("@remotion/media-utils");
4190
- var import_remotion23 = require("remotion");
5701
+ var import_remotion27 = require("remotion");
4191
5702
  var detectBeat = (frequencyData, amplitudes, threshold = 0.7, bpm, frame = 0, fps = 30) => {
4192
5703
  if (!frequencyData || !amplitudes || frequencyData.length === 0) return false;
4193
5704
  if (bpm) {
@@ -4219,7 +5730,7 @@ var easingFunctions = {
4219
5730
  };
4220
5731
  var WaveformLine = ({ data }) => {
4221
5732
  const {
4222
- config: config15,
5733
+ config: config18,
4223
5734
  className = "",
4224
5735
  style = {},
4225
5736
  strokeColor = "#FF6B6B",
@@ -4247,7 +5758,7 @@ var WaveformLine = ({ data }) => {
4247
5758
  pulseColor = "#FFD700",
4248
5759
  pulseScale = 1.2
4249
5760
  } = data;
4250
- return /* @__PURE__ */ import_react34.default.createElement(Waveform, { config: config15, className, style }, /* @__PURE__ */ import_react34.default.createElement(
5761
+ return /* @__PURE__ */ import_react41.default.createElement(Waveform, { config: config18, className, style }, /* @__PURE__ */ import_react41.default.createElement(
4251
5762
  WaveformLineContent,
4252
5763
  {
4253
5764
  strokeColor,
@@ -4303,14 +5814,14 @@ var WaveformLineContent = ({
4303
5814
  pulseColor,
4304
5815
  pulseScale
4305
5816
  }) => {
4306
- const { waveformData, frequencyData, amplitudes, width, height, config: config15, frame, fps } = useWaveformContext();
4307
- const currentFrame = (0, import_remotion23.useCurrentFrame)();
4308
- const videoConfig = (0, import_remotion23.useVideoConfig)();
4309
- const isBeat = (0, import_react34.useMemo)(() => {
5817
+ const { waveformData, frequencyData, amplitudes, width, height, config: config18, frame, fps } = useWaveformContext();
5818
+ const currentFrame = (0, import_remotion27.useCurrentFrame)();
5819
+ const videoConfig = (0, import_remotion27.useVideoConfig)();
5820
+ const isBeat = (0, import_react41.useMemo)(() => {
4310
5821
  if (!beatSync || !frequencyData || !amplitudes) return false;
4311
5822
  return detectBeat(frequencyData, amplitudes, beatThreshold, bpm, currentFrame, fps);
4312
5823
  }, [beatSync, frequencyData, amplitudes, beatThreshold, bpm, currentFrame, fps]);
4313
- const beatProgress = (0, import_react34.useMemo)(() => {
5824
+ const beatProgress = (0, import_react41.useMemo)(() => {
4314
5825
  if (!isBeat || !beatAnimationDuration) return 0;
4315
5826
  const beatStartFrame = Math.floor(currentFrame / beatAnimationDuration) * beatAnimationDuration;
4316
5827
  const progress = (currentFrame - beatStartFrame) / beatAnimationDuration;
@@ -4320,19 +5831,19 @@ var WaveformLineContent = ({
4320
5831
  }
4321
5832
  return clampedProgress;
4322
5833
  }, [isBeat, currentFrame, beatAnimationDuration, smoothAnimation]);
4323
- const currentBeatMultiplier = (0, import_react34.useMemo)(() => {
5834
+ const currentBeatMultiplier = (0, import_react41.useMemo)(() => {
4324
5835
  if (!beatSync || !isBeat || !beatAmplitudeMultiplier || !amplitudeCurve) return 1;
4325
5836
  const easing = easingFunctions[amplitudeCurve];
4326
5837
  const easedProgress = easing(beatProgress);
4327
5838
  return 1 + (beatAmplitudeMultiplier - 1) * (1 - easedProgress);
4328
5839
  }, [beatSync, isBeat, beatProgress, beatAmplitudeMultiplier, amplitudeCurve]);
4329
- const smoothFactor = (0, import_react34.useMemo)(() => {
5840
+ const smoothFactor = (0, import_react41.useMemo)(() => {
4330
5841
  if (!beatSync) {
4331
5842
  return 0.3;
4332
5843
  }
4333
5844
  return smoothAnimation ? 0.7 : 1;
4334
5845
  }, [beatSync, smoothAnimation]);
4335
- const waveformPaths = (0, import_react34.useMemo)(() => {
5846
+ const waveformPaths = (0, import_react41.useMemo)(() => {
4336
5847
  if (!waveformData) return [];
4337
5848
  const paths = [];
4338
5849
  const segments = waveSegments || 1;
@@ -4348,8 +5859,8 @@ var WaveformLineContent = ({
4348
5859
  const points = waveformData.map((y, index) => {
4349
5860
  const progress = index / (waveformData.length - 1);
4350
5861
  const x = segmentStart + progress * segmentDataWidth + offset;
4351
- let animatedAmplitude = y * (config15.amplitude || 1) * currentBeatMultiplier * speed;
4352
- const baseAmplitude = y * (config15.amplitude || 1) * speed;
5862
+ let animatedAmplitude = y * (config18.amplitude || 1) * currentBeatMultiplier * speed;
5863
+ const baseAmplitude = y * (config18.amplitude || 1) * speed;
4353
5864
  const beatAmplitude = animatedAmplitude - baseAmplitude;
4354
5865
  animatedAmplitude = baseAmplitude + beatAmplitude * smoothFactor;
4355
5866
  const yPos = waveDirection === "horizontal" ? animatedAmplitude * height / 2 + height / 2 : animatedAmplitude * width / 2 + width / 2;
@@ -4359,11 +5870,11 @@ var WaveformLineContent = ({
4359
5870
  paths.push({ path, segmentIndex: i });
4360
5871
  }
4361
5872
  return paths;
4362
- }, [waveformData, width, height, config15.amplitude, currentBeatMultiplier, animationSpeed, waveSegments, waveSpacing, waveOffset, waveDirection, smoothFactor]);
5873
+ }, [waveformData, width, height, config18.amplitude, currentBeatMultiplier, animationSpeed, waveSegments, waveSpacing, waveOffset, waveDirection, smoothFactor]);
4363
5874
  if (!waveformData) {
4364
- return /* @__PURE__ */ import_react34.default.createElement("div", { className: "flex items-center justify-center w-full h-full text-gray-500" }, "Loading waveform...");
5875
+ return /* @__PURE__ */ import_react41.default.createElement("div", { className: "flex items-center justify-center w-full h-full text-gray-500" }, "Loading waveform...");
4365
5876
  }
4366
- return /* @__PURE__ */ import_react34.default.createElement(
5877
+ return /* @__PURE__ */ import_react41.default.createElement(
4367
5878
  "svg",
4368
5879
  {
4369
5880
  width,
@@ -4371,7 +5882,7 @@ var WaveformLineContent = ({
4371
5882
  className: "absolute inset-0",
4372
5883
  style: { pointerEvents: "none" }
4373
5884
  },
4374
- centerLine && /* @__PURE__ */ import_react34.default.createElement(
5885
+ centerLine && /* @__PURE__ */ import_react41.default.createElement(
4375
5886
  "line",
4376
5887
  {
4377
5888
  x1: waveDirection === "horizontal" ? 0 : width / 2,
@@ -4383,7 +5894,7 @@ var WaveformLineContent = ({
4383
5894
  opacity: 0.3
4384
5895
  }
4385
5896
  ),
4386
- waveformPaths.map(({ path, segmentIndex }) => /* @__PURE__ */ import_react34.default.createElement("g", { key: segmentIndex }, pulseOnBeat && isBeat && /* @__PURE__ */ import_react34.default.createElement(
5897
+ waveformPaths.map(({ path, segmentIndex }) => /* @__PURE__ */ import_react41.default.createElement("g", { key: segmentIndex }, pulseOnBeat && isBeat && /* @__PURE__ */ import_react41.default.createElement(
4387
5898
  "path",
4388
5899
  {
4389
5900
  d: path,
@@ -4394,7 +5905,7 @@ var WaveformLineContent = ({
4394
5905
  fill: "none",
4395
5906
  opacity: (opacity || 1) * (1 - beatProgress)
4396
5907
  }
4397
- ), /* @__PURE__ */ import_react34.default.createElement(
5908
+ ), /* @__PURE__ */ import_react41.default.createElement(
4398
5909
  "path",
4399
5910
  {
4400
5911
  d: path,
@@ -4455,19 +5966,19 @@ registerComponent("WaveformCircle", WaveformCircle, "atom", {
4455
5966
 
4456
5967
  // src/components/Composition.tsx
4457
5968
  var import_player = require("@remotion/player");
4458
- var import_react35 = __toESM(require("react"));
4459
- var import_remotion24 = require("remotion");
4460
- var import_zod6 = __toESM(require("zod"));
4461
- var CompositionLayout = ({ childrenData, style, config: config15 }) => {
4462
- return /* @__PURE__ */ import_react35.default.createElement(
5969
+ var import_react42 = __toESM(require("react"));
5970
+ var import_remotion28 = require("remotion");
5971
+ var import_zod11 = __toESM(require("zod"));
5972
+ var CompositionLayout = ({ childrenData, style, config: config18 }) => {
5973
+ return /* @__PURE__ */ import_react42.default.createElement(
4463
5974
  CompositionProvider,
4464
5975
  {
4465
5976
  value: {
4466
5977
  root: childrenData,
4467
- duration: config15.duration
5978
+ duration: config18.duration
4468
5979
  }
4469
5980
  },
4470
- /* @__PURE__ */ import_react35.default.createElement(import_remotion24.AbsoluteFill, { style }, childrenData?.map((component) => /* @__PURE__ */ import_react35.default.createElement(
5981
+ /* @__PURE__ */ import_react42.default.createElement(import_remotion28.AbsoluteFill, { style }, childrenData?.map((component) => /* @__PURE__ */ import_react42.default.createElement(
4471
5982
  ComponentRenderer,
4472
5983
  {
4473
5984
  key: component.id,
@@ -4507,26 +6018,26 @@ var calculateCompositionLayoutMetadata = async ({ props, defaultProps, abortSign
4507
6018
  var Composition = ({
4508
6019
  id,
4509
6020
  childrenData,
4510
- config: config15,
6021
+ config: config18,
4511
6022
  style
4512
6023
  }) => {
4513
- return /* @__PURE__ */ import_react35.default.createElement(
4514
- import_remotion24.Composition,
6024
+ return /* @__PURE__ */ import_react42.default.createElement(
6025
+ import_remotion28.Composition,
4515
6026
  {
4516
6027
  id,
4517
6028
  component: CompositionLayout,
4518
- durationInFrames: Math.round(config15.duration * config15.fps),
4519
- fps: config15.fps,
4520
- width: config15.width ?? 1080,
4521
- height: config15.height ?? 1920,
4522
- defaultProps: { childrenData, style, config: config15 },
6029
+ durationInFrames: Math.round(config18.duration * config18.fps),
6030
+ fps: config18.fps,
6031
+ width: config18.width ?? 1080,
6032
+ height: config18.height ?? 1920,
6033
+ defaultProps: { childrenData, style, config: config18 },
4523
6034
  calculateMetadata: calculateCompositionLayoutMetadata,
4524
- schema: import_zod6.default.object({})
6035
+ schema: import_zod11.default.object({})
4525
6036
  }
4526
6037
  );
4527
6038
  };
4528
6039
  var Player = (props) => {
4529
- return /* @__PURE__ */ import_react35.default.createElement(
6040
+ return /* @__PURE__ */ import_react42.default.createElement(
4530
6041
  import_player.Player,
4531
6042
  {
4532
6043
  component: CompositionLayout,
@@ -4546,12 +6057,20 @@ var Player = (props) => {
4546
6057
  BaseLayoutConfig,
4547
6058
  BlurEffect,
4548
6059
  BlurEffectConfig,
6060
+ CanvasAtom,
6061
+ CanvasAtomConfig,
6062
+ CanvasContentAwareReveal,
6063
+ CanvasGlitchEffect,
6064
+ CanvasParticleEffect,
6065
+ CanvasWipeReveal,
4549
6066
  ComponentRenderer,
4550
6067
  Composition,
4551
6068
  CompositionLayout,
4552
6069
  CompositionProvider,
4553
6070
  Frame,
4554
6071
  GenericEffectPresets,
6072
+ HTMLBlockAtom,
6073
+ HTMLBlockAtomConfig,
4555
6074
  ImageAtom,
4556
6075
  ImageAtomConfig,
4557
6076
  LoopEffect,
@@ -4580,6 +6099,8 @@ var Player = (props) => {
4580
6099
  VideoAtomConfig,
4581
6100
  Waveform,
4582
6101
  WaveformCircle,
6102
+ WaveformEffect,
6103
+ WaveformEffectConfig,
4583
6104
  WaveformHistogram,
4584
6105
  WaveformHistogramRanged,
4585
6106
  WaveformLine,