openvideo 0.2.14 → 0.2.15

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.
@@ -1,5 +1,5 @@
1
- import { e as a, A as e, C as i, a as s, E as t, F as n, D as d } from "./index-xULbfbWy.js";
2
- import "./webworkerAll-BVuwnC-Q.js";
1
+ import { e as a, A as e, C as i, a as s, E as t, F as n, D as d } from "./index-CqBdAdbt.js";
2
+ import "./webworkerAll-05Hpn3rq.js";
3
3
  a.add(e);
4
4
  a.mixin(i, s);
5
5
  a.add(t);
@@ -18385,7 +18385,7 @@ const Lv = (r) => {
18385
18385
  },
18386
18386
  test: () => !0,
18387
18387
  load: async () => {
18388
- await import("./browserAll-D7ROm3gc.js");
18388
+ await import("./browserAll-1klNNaYF.js");
18389
18389
  }
18390
18390
  }, gC = {
18391
18391
  extension: {
@@ -18395,7 +18395,7 @@ const Lv = (r) => {
18395
18395
  },
18396
18396
  test: () => typeof self < "u" && self.WorkerGlobalScope !== void 0,
18397
18397
  load: async () => {
18398
- await import("./webworkerAll-BVuwnC-Q.js");
18398
+ await import("./webworkerAll-05Hpn3rq.js");
18399
18399
  }
18400
18400
  };
18401
18401
  class at {
@@ -90882,23 +90882,23 @@ class yte {
90882
90882
  async setupClipVisuals(e, t) {
90883
90883
  const i = this.studio.spriteRenderers.get(e);
90884
90884
  if (i) {
90885
- const s = this.studio.clipsNormalContainer, o = i.getRoot();
90886
- o && !o.parent && s.addChild(o);
90887
- return;
90888
- }
90889
- const n = await e.ready;
90890
- if (await this.setupPlaybackForClip(e, t), n.width > 0 && n.height > 0) {
90891
- const s = this.studio.clipsNormalContainer, o = e.type === "Video" && this.isPlaybackCapable(e);
90892
- if (!o || o && e.tickInterceptor != null) {
90893
- const a = new QR(
90894
- this.studio.pixiApp,
90895
- e,
90896
- s
90897
- );
90898
- this.studio.spriteRenderers.set(e, a);
90885
+ const n = this.studio.clipsNormalContainer, s = i.getRoot();
90886
+ s && !s.parent && n.addChild(s);
90887
+ } else {
90888
+ const n = await e.ready;
90889
+ if (n.width > 0 && n.height > 0) {
90890
+ const s = this.studio.clipsNormalContainer, o = e.type === "Video" && this.isPlaybackCapable(e);
90891
+ if (!o || o && e.tickInterceptor != null) {
90892
+ const a = new QR(
90893
+ this.studio.pixiApp,
90894
+ e,
90895
+ s
90896
+ );
90897
+ this.studio.spriteRenderers.set(e, a);
90898
+ }
90899
90899
  }
90900
90900
  }
90901
- this.studio.opts.interactivity && this.studio.selection.setupSpriteInteractivity(e);
90901
+ await this.setupPlaybackForClip(e, t), this.studio.opts.interactivity && this.studio.selection.setupSpriteInteractivity(e);
90902
90902
  }
90903
90903
  emitAddClipEvents(e, t) {
90904
90904
  if (e.length !== 0)
@@ -90935,11 +90935,7 @@ class yte {
90935
90935
  const h = c.clipIds.indexOf(e.id);
90936
90936
  h !== -1 && (c.clipIds.splice(h, 1), s.push(c.id));
90937
90937
  }
90938
- for (const c of s) {
90939
- const h = this.tracks.findIndex((d) => d.id === c);
90940
- h !== -1 && this.tracks[h].clipIds.length === 0 && (this.tracks.splice(h, 1), this.studio.emit("track:removed", { trackId: c }));
90941
- }
90942
- this.studio.selection.interactiveClips.delete(e);
90938
+ this.reconcileTracks(), this.studio.selection.interactiveClips.delete(e);
90943
90939
  const o = this.studio.clipListeners.get(e);
90944
90940
  o && (e.off("propsChange", o), this.studio.clipListeners.delete(e));
90945
90941
  const a = this.studio.spriteRenderers.get(e);
@@ -91076,6 +91072,7 @@ class yte {
91076
91072
  * Export current project state to JSON
91077
91073
  */
91078
91074
  exportToJSON() {
91075
+ this.reconcileTracks();
91079
91076
  const e = this.clips.map((n) => Zu(n, !1)), t = this.tracks.map((n) => ({
91080
91077
  id: n.id,
91081
91078
  name: n.name,
@@ -91185,7 +91182,10 @@ class yte {
91185
91182
  try {
91186
91183
  await i.ready, await this.setupClipVisuals(i), await this.studio.updateFrame(this.studio.currentTime);
91187
91184
  } catch (s) {
91188
- console.warn(`[Studio] Failed to setup visuals for clip ${i.id}:`, s);
91185
+ console.warn(
91186
+ `[Studio] Failed to setup visuals for clip ${i.id}:`,
91187
+ s
91188
+ );
91189
91189
  }
91190
91190
  })();
91191
91191
  });
@@ -91355,7 +91355,22 @@ class yte {
91355
91355
  await this.updateClip(i.id, e);
91356
91356
  }
91357
91357
  async setTracks(e) {
91358
- this.tracks = JSON.parse(JSON.stringify(e)), await this.recalculateMaxDuration(), await this.studio.updateFrame(this.studio.currentTime);
91358
+ const t = JSON.parse(JSON.stringify(this.tracks));
91359
+ this.tracks = JSON.parse(JSON.stringify(e)), this.reconcileTracks(), this.tracks.length === 0 && this.clips.length > 0 && (this.tracks = t, this.reconcileTracks()), await this.recalculateMaxDuration(), this.studio.isRestoring || this.studio.emit("track:order-changed", { tracks: this.tracks }), await this.studio.updateFrame(this.studio.currentTime);
91360
+ }
91361
+ /**
91362
+ * Reconciles the tracks list with the available clips.
91363
+ * 1. Filters each track's clipIds to only include IDs present in this.clips.
91364
+ * 2. Removes any tracks that are then empty.
91365
+ * This is used as a safety net to ensure no orphaned empty tracks or dangling references remain.
91366
+ */
91367
+ reconcileTracks() {
91368
+ const e = new Set(this.clips.map((t) => t.id));
91369
+ for (let t = this.tracks.length - 1; t >= 0; t--) {
91370
+ const i = this.tracks[t], n = i.clipIds.filter((s) => e.has(s));
91371
+ n.length !== i.clipIds.length && (i.clipIds = n), i.clipIds.length === 0 && (this.tracks.splice(t, 1), this.studio.isRestoring || this.studio.emit("track:removed", { trackId: i.id }));
91372
+ }
91373
+ this.tracks.length === 0 && !this.studio.isRestoring && this.studio.emit("track:order-changed", { tracks: this.tracks });
91359
91374
  }
91360
91375
  async ensureFontsForClips(e) {
91361
91376
  const t = /* @__PURE__ */ new Map();
@@ -91729,6 +91744,10 @@ class Yte extends vy {
91729
91744
  renderingSuspended = !1;
91730
91745
  historyPaused = !1;
91731
91746
  processingHistory = !1;
91747
+ /**
91748
+ * Indicates if the studio is currently restoring state from history (undo/redo)
91749
+ */
91750
+ isRestoring = !1;
91732
91751
  historyGroupDepth = 0;
91733
91752
  clipCache = /* @__PURE__ */ new Map();
91734
91753
  _isUpdatingLayout = !1;
@@ -91792,10 +91811,10 @@ class Yte extends vy {
91792
91811
  }));
91793
91812
  }
91794
91813
  beginHistoryGroup() {
91795
- this.historyGroupDepth++, this.historyPaused = !0;
91814
+ this.processingHistory || this.isRestoring || (this.historyGroupDepth++, this.historyPaused = !0);
91796
91815
  }
91797
91816
  endHistoryGroup() {
91798
- this.historyGroupDepth = Math.max(0, this.historyGroupDepth - 1), this.historyGroupDepth === 0 && (this.historyPaused = !1, this.saveHistory());
91817
+ this.processingHistory || this.isRestoring || (this.historyGroupDepth = Math.max(0, this.historyGroupDepth - 1), this.historyGroupDepth === 0 && (this.historyPaused = !1, this.saveHistory()));
91799
91818
  }
91800
91819
  setPath(e, t, i) {
91801
91820
  let n = e;
@@ -91851,7 +91870,7 @@ class Yte extends vy {
91851
91870
  }
91852
91871
  async undo() {
91853
91872
  if (!(!this.history.canUndo() || this.processingHistory)) {
91854
- this.processingHistory = !0, this.historyPaused = !0;
91873
+ this.processingHistory = !0, this.isRestoring = !0, this.historyPaused = !0;
91855
91874
  try {
91856
91875
  const e = this.history.undo(this.exportToJSON());
91857
91876
  e && await this.applyHistoryPatches(e.patches, e.state, !0), this.emit("history:changed", {
@@ -91859,13 +91878,13 @@ class Yte extends vy {
91859
91878
  canRedo: this.history.canRedo()
91860
91879
  });
91861
91880
  } finally {
91862
- this.historyPaused = !1, this.processingHistory = !1;
91881
+ this.historyPaused = !1, this.isRestoring = !1, this.processingHistory = !1;
91863
91882
  }
91864
91883
  }
91865
91884
  }
91866
91885
  async redo() {
91867
91886
  if (!(!this.history.canRedo() || this.processingHistory)) {
91868
- this.processingHistory = !0, this.historyPaused = !0;
91887
+ this.processingHistory = !0, this.isRestoring = !0, this.historyPaused = !0;
91869
91888
  try {
91870
91889
  const e = this.history.redo(this.exportToJSON());
91871
91890
  e && await this.applyHistoryPatches(e.patches, e.state, !1), this.emit("history:changed", {
@@ -91873,7 +91892,7 @@ class Yte extends vy {
91873
91892
  canRedo: this.history.canRedo()
91874
91893
  });
91875
91894
  } finally {
91876
- this.historyPaused = !1, this.processingHistory = !1;
91895
+ this.historyPaused = !1, this.isRestoring = !1, this.processingHistory = !1;
91877
91896
  }
91878
91897
  }
91879
91898
  }
@@ -92023,7 +92042,12 @@ class Yte extends vy {
92023
92042
  return this.timeline.addTrack(e, t);
92024
92043
  }
92025
92044
  async setTracks(e) {
92026
- return this.timeline.setTracks(e);
92045
+ if (this.isRestoring) return;
92046
+ const t = new Set(this.timeline.clips.map((i) => i.id));
92047
+ if (!(e.length === 0 && t.size > 0) && !(e.length > 0 && t.size > 0 && !e.some(
92048
+ (n) => n.clipIds.some((s) => t.has(s))
92049
+ )))
92050
+ return this.timeline.setTracks(e);
92027
92051
  }
92028
92052
  /**
92029
92053
  * Move a track to a new index
package/dist/index.es.js CHANGED
@@ -1,4 +1,4 @@
1
- import { a4 as t, p as e, q as i, w as o, v as n, t as r, Y as T, a2 as E, I as m, a9 as f, L as g, V as A, P as I, S as C, s as L, u as P, K as S, O as _, V as l, a8 as O, x as c, o as p, a6 as u, a5 as M, l as d, m as F, z as N, W as x, a0 as R, a7 as U, X as V, a3 as y, a1 as k, y as D, J as h, Z as w, n as B, Q as G, _ as J, r as K, U as j, $ as q } from "./index-xULbfbWy.js";
1
+ import { a4 as t, p as e, q as i, w as o, v as n, t as r, Y as T, a2 as E, I as m, a9 as f, L as g, V as A, P as I, S as C, s as L, u as P, K as S, O as _, V as l, a8 as O, x as c, o as p, a6 as u, a5 as M, l as d, m as F, z as N, W as x, a0 as R, a7 as U, X as V, a3 as y, a1 as k, y as D, J as h, Z as w, n as B, Q as G, _ as J, r as K, U as j, $ as q } from "./index-CqBdAdbt.js";
2
2
  export {
3
3
  t as ANIMATABLE_PROPERTIES,
4
4
  e as Audio,
package/dist/index.umd.js CHANGED
@@ -14342,4 +14342,4 @@ vec4 transition(vec2 uv) {
14342
14342
  bool nextImage = distance(fract(uv * dots), vec2(0.5, 0.5)) < ( progress / distance(uv, center));
14343
14343
  return nextImage ? getToColor(uv) : getFromColor(uv);
14344
14344
  }
14345
- `,hte={radialSwipe:{label:"Radial Swipe",fragment:vee}},Ah={};function dte(r,e){Ah[r]=e}function fte(r){delete Ah[r]}function qo(){return{...Yo.reduce((r,e)=>(r[e.name]={label:e.name,fragment:e.glsl,uniforms:e.defaultParams,previewDynamic:""},r),{}),...hte,...Ah}}qo();function D4(){const r=Object.keys(Ah);return Object.entries(qo()).map(([e,t])=>({key:e,label:t.label,isCustom:r.includes(e),previewStatic:t.previewStatic||`https://cdn.subgen.co/previews/static/transition_${e}_static.webp`,previewDynamic:t.previewDynamic||`https://cdn.subgen.co/previews/dynamic/transition_${e}_dynamic.webp`}))}const pte=D4();function c1({name:r,renderer:e}){let t=Yo.find(G=>G.name===r);if(!t){const G=qo(),ne=Object.keys(G).find(oe=>oe.toLowerCase()===r.toLowerCase());ne&&(t=G[ne])}if(t||(t=Yo.find(G=>G.name.toLowerCase()===r.toLowerCase())),!t){const G=[r,r.toLowerCase(),r.charAt(0).toUpperCase()+r.slice(1).toLowerCase(),r.replace(/([A-Z])/g,"_$1").toLowerCase().replace(/^_/,""),r.replace(/_/g,"")],ne=qo();for(const oe of G){if(t=Yo.find(be=>be.name.toLowerCase()===oe.toLowerCase()),t)break;const te=Object.keys(ne).find(be=>be.toLowerCase()===oe.toLowerCase());if(te){t=ne[te];break}}}if(!t){const G=Yo.length,ne=Yo.slice(0,5).map(be=>be.name).join(", "),oe=qo(),te=Object.keys(oe).slice(0,3).join(", ");throw console.error(`Transition not found: "${r}". Available in gl-transitions (${G} total):`,ne+"..."),console.error("Available locally:",te+"..."),new Error(`Transition "${r}" not found in gl-transitions library or local definitions`)}const i=new Je(Q.WHITE),n=Ot.create({width:e.width,height:e.height}),s=new jr({}),o=new jr({}),a=t.name==="displacement"||r.toLowerCase()==="displacement"||t.label==="displacement",l=a?new jr({}):void 0;let u=null;if(a){u=document.createElement("canvas"),u.width=256,u.height=256;const G=u.getContext("2d");if(G){const ne=G.createImageData(256,256);for(let oe=0;oe<ne.data.length;oe+=4){const te=Math.random();ne.data[oe]=te*255,ne.data[oe+1]=te*255,ne.data[oe+2]=te*255,ne.data[oe+3]=255}G.putImageData(ne,0,0)}}let c=t.glsl||t.fragment;if(!c)throw new Error(`Transition "${r}" has no glsl or fragment code`);let h={...st.basics,...st.custom(t)};Object.entries(h).forEach(([,G])=>{G.type==="int<f32>"&&(G.type="i32",typeof G.value=="number"&&(G.value=Math.trunc(G.value))),G.type==="ivec2<f32>"&&(G.type="vec2<f32>")});const d=t.name==="GridFlip"||r.toLowerCase()==="gridflip"||t.label==="gridflip",f=t.name==="circle"||r.toLowerCase()==="circle"||t.label==="circle",p=t.name==="directional"||r.toLowerCase()==="directional"||t.label==="directional",m=t.name==="UndulatingBurnOut"||r.toLowerCase()==="undulatingburnout"||t.label==="undulatingBurnOut",g=t.name==="SquaresWire"||r.toLowerCase()==="squareswire"||t.label==="squaresWire",v=t.name==="rotate_scale_fade"||r.toLowerCase()==="rotatescalefade"||t.label==="rotateScaleFade",x=t.name==="RandomSquares"||r.toLowerCase()==="randomsquares"||t.label==="randomSquares",y=t.name==="polar_function"||r.toLowerCase()==="polar_function"||t.label==="polar_function",b=t.name==="pixelate"||r.toLowerCase()==="pixelate"||t.label==="pixelate",T=t.name==="perlin"||r.toLowerCase()==="perlin"||t.label==="perlin",P=t.name==="luma"||r.toLowerCase()==="luma"||t.label==="luma",A=t.name==="luminance_melt"||r.toLowerCase()==="luminance_melt"||r.toLowerCase()==="luminancemelt"||t.label==="luminance_melt",E=t.name==="hexagonalize"||r.toLowerCase()==="hexagonalize"||t.label==="hexagonalize",_=t.name==="heart"||r.toLowerCase()==="heart"||t.label==="heart",S=t.name==="displacement"||r.toLowerCase()==="displacement"||t.label==="displacement",I=t.name==="directionalwipe"||r.toLowerCase()==="directionalwipe"||r.toLowerCase()==="directional_wipe"||t.label==="directionalwipe",M=t.name==="directionalwarp"||r.toLowerCase()==="directionalwarp"||r.toLowerCase()==="directional_warp"||t.label==="directionalwarp",O=t.name==="crosshatch"||r.toLowerCase()==="crosshatch"||t.label==="crosshatch",U=t.name==="circleopen"||r.toLowerCase()==="circleopen"||r.toLowerCase()==="circle_open"||t.label==="circleopen",X=t.name==="cannabisleaf"||r.toLowerCase()==="cannabisleaf"||r.toLowerCase()==="cannabis_leaf"||t.label==="cannabisleaf",D=t.name==="StereoViewer"||r.toLowerCase()==="stereoviewer"||r.toLowerCase()==="stereo_viewer"||t.label==="StereoViewer",k=t.name==="GlitchDisplace"||r.toLowerCase()==="glitchDisplace"||t.label==="GlitchDisplace",Y=t.name==="CrossZoom"||r.toLowerCase()==="crosszoom"||t.label==="CrossZoom",H=t.name==="CrazyParametricFun"||r.toLowerCase()==="crazyparametricfun"||t.label==="CrazyParametricFun",$=t.name==="BowTieHorizontal"||r.toLowerCase()==="bowtiehorizontal"||t.label==="BowTieHorizontal",K=t.name==="PolkaDotsCurtain"||r.toLowerCase()==="polkadotscurtain"||t.label==="PolkaDotsCurtain",we=t.name==="Pixelize"||r.toLowerCase()==="pixelize"||t.label==="Pixelize";d&&(c=xee,h={...st.basics,...yee}),f&&(c=bee,h={...st.basics,...M4}),p&&(c=_ee,h={...st.basics,...wee}),m&&(c=See,h={...st.basics,...Tee}),g&&(c=Cee,h={...st.basics,...Aee}),v&&(c=Eee,h={...st.basics,...Pee}),x&&(c=Iee,h={...st.basics,...Bee}),y&&(c=kee,h={...st.basics,...Ree}),b&&(c=Wk,h={...st.basics,...Vk}),T&&(c=Dee,h={...st.basics,...Oee}),P&&(c=Uee,h={...st.basics,...zee}),A&&(c=Lee,h={...st.basics,...Nee}),E&&(c=Gee,h={...st.basics,...Hee}),_&&(c=Wee,h={...st.basics,...Vee}),S&&(c=Xee,h={...st.basics,...Yee}),I&&(c=qee,h={...st.basics,...jee}),M&&(c=Kee,h={...st.basics,...Qee}),O&&(c=Zee,h={...st.basics,...Jee}),U&&(c=$ee,h={...st.basics,...M4}),X&&(c=ete,h={...st.basics,...tte}),D&&(c=rte,h={...st.basics,...ite}),k&&(c=nte),Y&&(c=ste,h={...st.basics,...ote}),H&&(c=ate,h={...st.basics,...lte}),$&&(c=ute),K&&(c=cte),we&&(c=Fee,h={...st.basics,...Mee});const Ie={from:s,to:o,uniforms:h};a&&l&&(Ie.displacementMap=l,u&&(l.resource=u,l.update()));const ve=new ge({glProgram:new ue({vertex:pee,fragment:gee(c)}),resources:Ie});return i.filters=[ve],{render({width:G,height:ne,from:oe,to:te,progress:be}){if((i.width!==G||i.height!==ne)&&(i.setSize({width:G,height:ne}),n.resize(G,ne)),oe instanceof Q?ve.resources.from=oe.source:(s.resource=oe,s.update(),ve.resources.from=s),te instanceof Q?ve.resources.to=te.source:(o.resource=te,o.update(),ve.resources.to=o),a&&l&&u){if(u.width!==G||u.height!==ne){u.width=G,u.height=ne;const Le=u.getContext("2d");if(Le){const ke=Le.createImageData(G,ne);for(let Ae=0;Ae<ke.data.length;Ae+=4){const je=Math.random();ke.data[Ae]=je*255,ke.data[Ae+1]=je*255,ke.data[Ae+2]=je*255,ke.data[Ae+3]=255}Le.putImageData(ke,0,0)}}l.resource=u,l.update()}return ve.resources.uniforms.uniforms.progress=be,e.render({container:i,target:n,clear:!0,width:G,height:ne}),n},destroy(){n.destroy(),i.destroy({children:!0})}}}let mte=0;async function O4(r){r()>50&&(await wu(15),await O4(r))}class gte extends X0{static async isSupported(e={}){return(self.OffscreenCanvas!=null&&self.VideoEncoder!=null&&self.VideoDecoder!=null&&self.VideoFrame!=null&&self.AudioEncoder!=null&&self.AudioDecoder!=null&&self.AudioData!=null&&((await self.VideoEncoder.isConfigSupported({codec:e.videoCodec??"avc1.42E032",width:e.width??1920,height:e.height??1080,bitrate:e.bitrate??7e6})).supported??!1)&&(await self.AudioEncoder.isConfigSupported({codec:(await kk()).codec,sampleRate:rt.sampleRate,numberOfChannels:rt.channelCount})).supported)??!1}logger=Ue.create(`id:${mte++},`);destroyed=!1;sprites=[];canvas;pixiApp=null;stopOutput=null;opts;hasVideoTrack;constructor(e={}){super(),console.log("Compositor constructor",e);const{width:t=0,height:i=0}=e;this.canvas=new OffscreenCanvas(t,i),this.opts=Object.assign({bgColor:"#000",width:0,height:0,format:"mp4",videoCodec:"avc1.42E032",audio:!0,audioCodec:"aac",audioSampleRate:48e3,bitrate:5e6,fps:30,metaDataTags:null},e),console.log("Compositor opts",this.opts),this.hasVideoTrack=t*i>0,kk().catch(n=>{this.logger.warn("Failed to detect audio codec:",n)})}async initPixiApp(){const{width:e,height:t}=this.opts;if(this.pixiApp=new gc,await this.pixiApp.init({canvas:this.canvas,width:e,height:t,backgroundColor:0,antialias:!1,autoDensity:!1,resolution:1,preference:"webgl"}),this.pixiApp.renderer==null||this.pixiApp.stage==null)throw new Error("Pixi.js Application failed to initialize properly");try{const i=this.pixiApp;i.ticker&&typeof i.ticker.stop=="function"&&i.ticker.stop()}catch{}}async addSprite(e,t={}){const i={rect:{x:e.left,y:e.top,w:e.width,h:e.height},display:{...e.display},duration:e.duration,playbackRate:e.playbackRate,zIndex:e.zIndex};this.logger.info("Compositor add clip",i);const n=await e.clone();this.pixiApp!=null&&this.pixiApp.renderer!=null&&typeof n.setRenderer=="function"&&n.setRenderer(this.pixiApp.renderer),this.logger.info("Compositor add clip ready"),this.sprites.push(Object.assign(n,{main:t.main??!1,expired:!1})),this.sprites.sort((s,o)=>s.zIndex-o.zIndex)}initMuxer(e){const{fps:t,width:i,height:n,videoCodec:s,bitrate:o,audio:a,metaDataTags:l,format:u,audioCodec:c,audioSampleRate:h}=this.opts,d=this.sprites.some(m=>m.width>0&&m.height>0),f=this.hasVideoTrack&&d;return UO({format:u||"mp4",video:f?{width:i,height:n,expectFPS:t,codec:s,bitrate:o,__unsafe_hardwareAcceleration__:this.opts.__unsafe_hardwareAcceleration__}:null,audio:a===!1?null:{codec:c||rt.codecType,sampleRate:h||rt.sampleRate,channelCount:rt.channelCount},duration:e,metaDataTags:l})}output(e={}){if(console.log("Compositor output",e),this.sprites.length===0)throw Error("No sprite added");const t=this.sprites.find(u=>u.main),n=this.sprites.map(u=>u.display.from+u.duration).filter(u=>u!==1/0),s=e.maxTime??(t!=null?t.display.from+t.duration:n.length>0?Math.max(...n):0);if(s===1/0||s<=0)throw Error("Unable to determine the end time, please specify a main sprite, or limit the duration of Image, Audio");s===-1&&this.logger.warn("Unable to determine the end time, process value don't update"),this.logger.info(`start combinate video, maxTime:${s}`);const o=this.initMuxer(s);let a=performance.now();const l=this.runEncoding(o,s,{onProgress:u=>{this.logger.debug("OutputProgress:",u),this.emit("OutputProgress",u)},onEnded:async()=>{await o.flush(),this.logger.info("===== output ended =====, cost:",performance.now()-a),this.emit("OutputProgress",1),this.destroy()},onError:u=>{this.emit("error",u),o.close(),this.destroy()}});return this.stopOutput=()=>{l(),o.close()},o.stream}destroy(){if(!this.destroyed&&(this.destroyed=!0,this.stopOutput?.(),this.off("OutputProgress"),this.off("error"),this.pixiApp!=null))try{const e=this.pixiApp;if(e.destroyed===!0){this.pixiApp=null;return}if(e.ticker&&typeof e.ticker.stop=="function")try{e.ticker.stop()}catch{}if(e.renderer!=null){const t=e.renderer.gl;if(t&&t.isContextLost()){this.pixiApp=null;return}this.pixiApp.destroy()}}catch(e){console.warn("Error while destroying Pixi application:",e)}finally{this.pixiApp=null}}runEncoding(e,t,{onProgress:i,onEnded:n,onError:s}){let o=0;const a={aborted:!1};let l=null,u=null;const c=async()=>{const{fps:f,bgColor:p,audio:m}=this.opts,g=Math.round(1e6/f),v=this.sprites.some(b=>b.width>0&&b.height>0);u=vte({pixiApp:this.pixiApp,sprites:this.sprites,aborter:a});const x=xte({muxer:e,canvas:this.canvas,outputAudio:m,hasVideoTrack:this.hasVideoTrack&&v,timeSlice:g,fps:f});let y=0;for(;;){if(l!=null)return;if(a.aborted||t!==-1&&y>t||this.sprites.length===0){h(),await n();return}o=y/t;const{audios:b,mainSprDone:T}=await u.render(y);if(T){h(),await n();return}if(a.aborted)return;this.hasVideoTrack&&await wu(0),x(y,b,!0),y+=g,await O4(e.getEncodeQueueSize)}},h=()=>{a.aborted||(a.aborted=!0,clearInterval(d),u?.cleanup(),this.sprites.forEach(f=>{f.destroy()}))};c().catch(f=>{l=f,this.logger.error(f),h(),s(f)});const d=setInterval(()=>{i(o)},500);return h}exportToJSON(){const e=this.sprites.map(i=>Rl(i,i.main)),t=[];return this.sprites.forEach(i=>{if(i.transition){const n=this.sprites.filter(s=>s.id!==i.id&&s.zIndex===i.zIndex&&s.display.from<i.display.from&&(s instanceof br||s instanceof Bl)).sort((s,o)=>o.display.to-s.display.to)[0];n&&t.push({key:i.transition.name,duration:i.transition.duration,clips:[n.id,i.id]})}}),{clips:e,settings:{width:this.opts.width,height:this.opts.height,fps:this.opts.fps,bgColor:this.opts.bgColor,format:this.opts.format,videoCodec:this.opts.videoCodec,bitrate:this.opts.bitrate,audio:this.opts.audio,audioCodec:this.opts.audioCodec,audioSampleRate:this.opts.audioSampleRate,metaDataTags:this.opts.metaDataTags}}}async loadFromJSON(e){this.sprites.forEach(t=>{t.destroy()}),this.sprites=[],e.settings&&(e.settings.width!==void 0&&(this.opts.width=e.settings.width),e.settings.height!==void 0&&(this.opts.height=e.settings.height),e.settings.fps!==void 0&&(this.opts.fps=e.settings.fps),e.settings.bgColor!==void 0&&(this.opts.bgColor=e.settings.bgColor),e.settings.format!==void 0&&(this.opts.format=e.settings.format),e.settings.videoCodec!==void 0&&(this.opts.videoCodec=e.settings.videoCodec),e.settings.bitrate!==void 0&&(this.opts.bitrate=e.settings.bitrate),e.settings.audio!==void 0&&(this.opts.audio=e.settings.audio===!1?!1:void 0),e.settings.audioCodec!==void 0&&(this.opts.audioCodec=e.settings.audioCodec),e.settings.audioSampleRate!==void 0&&(this.opts.audioSampleRate=e.settings.audioSampleRate),e.settings.metaDataTags!==void 0&&(this.opts.metaDataTags=e.settings.metaDataTags));for(const t of e.clips){const i=await Xo(t);await this.addSprite(i,{main:t.main||!1})}}}function vte(r){const{pixiApp:e,sprites:t,aborter:i}=r,n=e!=null,s=new Map,o=new Map,a=new Map,l=Ot.create({width:e?.renderer.width||0,height:e?.renderer.height||0}),u=Ot.create({width:e?.renderer.width||0,height:e?.renderer.height||0}),c=new Ze().rect(0,0,e?.renderer.width||0,e?.renderer.height||0).fill({color:0}),h=new Map,d=async(b,T,P)=>{const A=Math.max(0,Math.min(T-b.display.from,b.duration));b.animate(A*b.playbackRate);const{video:E}=await P(b,A);return E},f=(b,T,P)=>{if(!e)return;const A=b.style||{},{renderTransform:E}=b,_=(E?.mirror??0)>.5,S=T instanceof Q?T:Q.from(T),I=E?.x??0,M=E?.y??0,O=E?.angle??0,U=E?.scale??1,X=E?.scaleX??1,D=E?.scaleY??1,k=E?.opacity??1,Y=E?.blur??0,H=E?.brightness??1,$=S.width||1,K=S.height||1,we=b.type==="Caption",Ie=!we&&b.width&&b.width!==0?Math.abs(b.width)/$:1,ve=!we&&b.height&&b.height!==0?Math.abs(b.height)/K:1,G=Ie*U*X,ne=ve*U*D,oe=new Pe;oe.x=b.center.x+I,oe.y=b.center.y+M,oe.rotation=(b.flip==null?1:-1)*((b.angle+O)*Math.PI)/180,oe.alpha=b.opacity*k;const te=new Je(S);te.anchor.set(.5,.5);let be=[];if(_){const Re=G,nt=ne,Bt=$*Re,Vt=K*nt;te.position.set(0,0),te.scale.set(Re,nt);const Qe=[[Bt,0,-Re,nt],[-Bt,0,-Re,nt],[0,Vt,Re,-nt],[0,-Vt,Re,-nt],[Bt,Vt,-Re,-nt],[-Bt,Vt,-Re,-nt],[Bt,-Vt,-Re,-nt],[-Bt,-Vt,-Re,-nt]];for(const[Oe,Ri,As,Fl]of Qe){const Un=new Je(S);Un.anchor.set(.5,.5),Un.position.set(Oe,Ri),Un.scale.set(As,Fl),be.push(Un)}if(b.flip==="horizontal"){te.scale.x=-Re;for(let Oe=0;Oe<8;Oe++)be[Oe].scale.x=-Qe[Oe][2]}else if(b.flip==="vertical"){te.scale.y=-nt;for(let Oe=0;Oe<8;Oe++)be[Oe].scale.y=-Qe[Oe][3]}oe.addChild(te);for(const Oe of be)oe.addChild(Oe)}else b.flip==="horizontal"?(te.scale.x=-G,te.scale.y=ne):b.flip==="vertical"?(te.scale.x=G,te.scale.y=-ne):(te.scale.x=G,te.scale.y=ne),oe.addChild(te);const Le=[];if(Y>0){const Re=new ys;Re.strength=Y,Re.quality=4,Re.repeatEdgePixels=!0,Le.push(Re)}if(H!==1){const Re=new Ro;Re.brightness(H,!1),Le.push(Re)}if(b.chromaKey&&b.chromaKey.enabled){const Re=new ft({uKeyColor:{value:[0,1,0],type:"vec3<f32>"},uSimilarity:{value:.1,type:"f32"},uSpill:{value:0,type:"f32"}}),nt=Fk(b.chromaKey.color);nt&&(Re.uniforms.uKeyColor[0]=nt.r/255,Re.uniforms.uKeyColor[1]=nt.g/255,Re.uniforms.uKeyColor[2]=nt.b/255),Re.uniforms.uSimilarity=b.chromaKey.similarity,Re.uniforms.uSpill=b.chromaKey.spill;const Bt=new ge({glProgram:new ue({vertex:qb,fragment:Xk,name:"ChromaKeyShader"}),resources:{chromaUniforms:Re}});Le.push(Bt)}oe.filters=Le;const ke=A.borderRadius||0;let Ae=null;ke>0&&(Ae=new Ze,Ae.roundRect(-$/2,-K/2,$,K,Math.min(ke,$/2,K/2)),Ae.fill({color:16777215,alpha:1}),te.addChild(Ae),te.mask=Ae);const je=A.stroke;let Fe=null;if(je&&je.width>0){Fe=new Ze;const Re=yt(je.color)??16777215;if(Fe.setStrokeStyle({width:je.width,color:Re,alignment:1}),ke>0){const nt=Math.min(ke,$/2,K/2);Fe.roundRect(-$/2,-K/2,$,K,nt)}else Fe.rect(-$/2,-K/2,$,K);Fe.stroke(),te.addChild(Fe)}const at=A.dropShadow;let it=null;if(at&&(at.blur>0||at.distance>0)){it=new Ze;const Re=yt(at.color)??0,nt=at.alpha??.5,Bt=at.distance??0,Vt=at.angle??0,Qe=Math.cos(Vt)*Bt,Oe=Math.sin(Vt)*Bt;if(ke>0){const Ri=Math.min(ke,$/2,K/2);it.roundRect(-$/2+Qe,-K/2+Oe,$,K,Ri)}else it.rect(-$/2+Qe,-K/2+Oe,$,K);it.fill({color:Re,alpha:nt}),oe.addChildAt(it,0)}e.renderer.render({container:oe,target:P,clear:!0}),T instanceof Q||te.texture.destroy(!0),Fe&&Fe.destroy(),Ae&&Ae.destroy(),it&&it.destroy();for(const Re of be)Re.destroy();te.destroy(),oe.destroy()};let p=null,m=null,g=null;n&&e!=null&&(p=new Pe,m=new Pe,g=new Pe,m.sortableChildren=!0,g.sortableChildren=!0,e.stage.addChild(m),e.stage.addChild(g),p.visible=!1,e.stage.addChild(p));const v=[...t].sort((b,T)=>b.zIndex-T.zIndex);return{render:async b=>{const T=[];let P=!1,A=!1;const E=new Map,_=async(S,I)=>{if(E.has(S))return E.get(S);const M=await S.getFrame(I);return E.set(S,M),M};for(const S of a.values())S.visible=!1;for(const S of v){if(i.aborted)break;if(b<S.display.from||S.expired){if(n&&e!=null){const D=s.get(S);D&&await D.updateFrame(null)}continue}const I=b-S.display.from,M=I*S.playbackRate;S.animate(M);const{video:O,audio:U,done:X}=await _(S,I);if(T.push(U),n&&e!=null&&m!=null){if(S instanceof Bi){const k=t.find(H=>H.id===S.fromClipId),Y=t.find(H=>H.id===S.toClipId);if(k&&Y){const H=b-S.display.from;if(H>=S.duration){S.expired=!0;const $=a.get(S.id);$&&($.visible=!1)}else{const $=await d(k,b,_),K=await d(Y,b,_);if($&&K){const we=Math.min(Math.max(H/S.duration,0),1);f(k,$,l),f(Y,K,u);let Ie=o.get(S.id);Ie||(Ie=c1({name:S.transitionEffect.key,renderer:e.renderer}),o.set(S.id,Ie));const ve=Ie.render({width:e.renderer.width,height:e.renderer.height,from:l,to:u,progress:we});let G=a.get(S.id);G||(G=new Je,G.label=`TransitionSprite_${S.id}`,a.set(S.id,G),m.addChild(G)),G.texture=ve,G.visible=!0,G.x=0,G.y=0,G.width=e.renderer.width,G.height=e.renderer.height,G.anchor.set(0,0),G.zIndex=S.zIndex,A=!0;const ne=s.get(k);if(ne){const te=ne.getRoot();te&&(te.visible=!1)}const oe=s.get(Y);if(oe){const te=oe.getRoot();te&&(te.visible=!1)}continue}}}}let D=s.get(S);if(D==null&&O!=null&&(D=new R4(e,S,m),s.set(S,D)),D!=null){const k=D.getRoot();O!=null?(A=!0,k&&(k.visible=!0),await D.updateFrame(O)):(k&&(k.visible=!1),await D.updateFrame(null)),D.updateTransforms()}}if(S.duration>0&&I>S.duration||X){if(S.main&&(P=!0),S.expired=!0,n){const D=s.get(S);if(D!=null){const k=D.getRoot();k&&(k.visible=!1)}}}else if(n){const D=s.get(S);D?.updateTransforms()}}if(n&&e!=null&&p!=null&&m!=null&&g!=null){const S=[];for(const I of t)if(I instanceof Qi&&b>=I.display.from&&b<I.display.from+I.duration&&S.push({id:I.id,key:I.effect.key,startTime:I.display.from,duration:I.duration,zIndex:I.zIndex,values:I.effect.values}),I.effects&&I.effects.length>0)for(const M of I.effects)b>=M.startTime&&b<M.startTime+M.duration&&S.push({...M,zIndex:I.zIndex});S.sort((I,M)=>I.zIndex-M.zIndex),g.removeChildren();for(const I of s.values()){const M=I.getRoot();M&&M.parent!==m&&(M.parent&&M.parent.removeChild(M),m.addChild(M))}if(S.length>0){const I=e.renderer.width,M=e.renderer.height;let O=null;const U=new Set,X=[];for(const D of S){const{key:k,startTime:Y,duration:H,id:$,zIndex:K}=D,we=b-Y,Ie=H>0?Math.min(Math.max(we/H,0),1):0,ve=t.some(G=>G.id===$&&G instanceof Qi);if(p.removeChildren(),O){const G=new Je(O);G.width=I,G.height=M,p.addChild(G)}for(const G of t){if(U.has(G.id))continue;let ne=!1;if(ve?ne=G.id!==$&&G.zIndex<K:ne=!!G.effects&&G.effects.some(oe=>oe.id===$),ne){const oe=s.get(G);if(oe){const be=oe.getRoot();be&&(be.parent&&be.parent.removeChild(be),p.addChild(be),U.add(G.id))}const te=a.get(G.id);te&&(te.parent&&te.parent.removeChild(te),p.addChild(te),U.add(G.id))}}if(p.children.length>0){let G=h.get($);if(!G)try{const ne=await l1({name:k,renderer:e.renderer,values:D.values});ne&&ne.filter&&(G={filter:ne.filter,render:ne.render},h.set($,G))}catch(ne){console.warn("Failed to create effect",k,ne)}if(G){const{filter:ne,render:oe}=G;ne.resources&&ne.resources.effectUniforms&&(ne.resources.effectUniforms.uniforms.uTime=Ie);const te=Ot.create({width:I,height:M});X.push(te),p.visible=!0,e.renderer.render({container:p,target:te,clear:!0}),p.visible=!1,oe&&(O=oe({canvasTexture:te,progress:Ie,width:I,height:M}))}}}if(O){const D=new Je(O);D.width=I,D.height=M,g.addChild(D)}for(const D of X)D.destroy(!0)}}return n&&e!=null&&e.render(),{audios:T,mainSprDone:P,hasVideo:A}},cleanup:()=>{l&&l.destroy(!0),u&&u.destroy(!0),c&&c.destroy(!0);for(const b of a.values())b.destroy();a.clear(),o.clear(),p&&p.destroy({children:!0}),m&&m.destroy({children:!0}),g&&g.destroy({children:!0}),s.forEach(b=>{b.destroy()}),s.clear()}}}function xte(r){const{canvas:e,outputAudio:t,muxer:i,hasVideoTrack:n,timeSlice:s}=r;let o=0;const a=Math.floor(3*r.fps),l=yte(1024);return(u,c,h)=>{if(t!==!1)for(const d of l(u,c))i.encodeAudio(d);if(n&&h)try{const d=new VideoFrame(e,{duration:s,timestamp:u});i.encodeVideo(d,{keyFrame:o%a===0}),o+=1}catch(d){console.warn("Failed to create VideoFrame from canvas, skipping frame:",d)}}}function yte(r){const e=r*rt.channelCount,t=new Float32Array(e*3);let i=0,n=0;const s=r/rt.sampleRate*1e6,o=new Float32Array(e),a=l=>{let u=0;const c=Math.floor(i/e),h=[];for(let d=0;d<c;d++)h.push(new AudioData({timestamp:n,numberOfChannels:rt.channelCount,numberOfFrames:r,sampleRate:rt.sampleRate,format:"f32",data:t.subarray(u,u+e)})),u+=e,n+=s;for(t.set(t.subarray(u,i),0),i-=u;l-n>s;)h.push(new AudioData({timestamp:n,numberOfChannels:rt.channelCount,numberOfFrames:r,sampleRate:rt.sampleRate,format:"f32",data:o})),n+=s;return h};return(l,u)=>{const c=Math.max(...u.map(h=>h[0]?.length??0));for(let h=0;h<c;h++){let d=0,f=0;for(let p=0;p<u.length;p++){const m=u[p][0]?.[h]??0,g=u[p][1]?.[h]??m;d+=m,f+=g}t[i]=d,t[i+1]=f,i+=2}return a(l)}}class bte extends Ze{constructor(){super(),this.eventMode="static",this.cursor="move"}draw(e,t=1){const n=1.5*t;this.clear(),this.setStrokeStyle({width:n,color:165063}).rect(e.x,e.y,e.width,e.height).stroke(),this.hitArea=e}}class Ji extends Ze{#e=!1;handle;cursor;callbacks;constructor(e,t,i){super(),this.handle=e,this.cursor=t,this.callbacks=i,this.eventMode="static",this.#l(),this.on("pointerdown",this.#r),this.on("globalpointermove",this.#n),this.on("pointerup",this.#u),this.on("pointerupoutside",this.#u)}#l(){this.clear();const e=165063;if(this.handle==="rot")this.circle(0,0,8),this.fill({color:"#ffffff"}),this.stroke({width:1,color:13421772}),this.moveTo(0,-4),this.arc(0,0,4,-Math.PI/2,Math.PI,!1),this.stroke({width:1,color:0}),this.moveTo(0,-8),this.lineTo(-3,-5),this.lineTo(0,-2),this.stroke({width:1,color:0,cap:"round",join:"round"}),this.hitArea=new sl(0,0,24);else if(["ml","mr","mt","mb"].includes(this.handle)){const t=this.handle==="ml"||this.handle==="mr",i=t?6:24,n=t?24:6;this.roundRect(-i/2,-n/2,i,n,3),this.fill({color:"#ffffff"}),this.stroke({width:1,color:e}),this.hitArea=new he(-15,-15,30,30)}else this.rect(-4,-4,8,8),this.fill({color:"#ffffff"}),this.stroke({width:1,color:e}),this.hitArea=new he(-15,-15,30,30)}#r=e=>{this.#e=!0,this.cursor="grabbing",this.callbacks.beginDrag(this.handle,e.global)};#n=e=>{this.#e&&this.callbacks.updateDrag(this.handle,e.global)};#u=e=>{this.#e&&(this.#e=!1,this.cursor="pointer",this.callbacks.endDrag())}}class Eh{constructor(e,t,i=1){this.artboardWidth=e,this.artboardHeight=t,this.scale=i}static SNAP_THRESHOLD=5;updateContext(e,t,i){this.artboardWidth=e,this.artboardHeight=t,this.scale=i}snapMove(e){const t=[];let i=0,n=0;const s=Eh.SNAP_THRESHOLD/this.scale,o=[{value:this.artboardWidth/2,label:"center"},{value:0,label:"start"},{value:this.artboardWidth,label:"end"}],a=[{value:e.x,type:"start"},{value:e.x+e.width/2,type:"center"},{value:e.x+e.width,type:"end"}];let l=!1;for(const d of o){if(l)break;for(const f of a){const p=d.value-f.value;if(Math.abs(p)<s){i=p,l=!0,t.push({type:"vertical",position:d.value,start:Math.min(0,e.y),end:Math.max(this.artboardHeight,e.y+e.height)});break}}}const u=[{value:this.artboardHeight/2,label:"center"},{value:0,label:"start"},{value:this.artboardHeight,label:"end"}],c=[{value:e.y,type:"start"},{value:e.y+e.height/2,type:"center"},{value:e.y+e.height,type:"end"}];let h=!1;for(const d of u){if(h)break;for(const f of c){const p=d.value-f.value;if(Math.abs(p)<s){n=p,h=!0,t.push({type:"horizontal",position:d.value,start:Math.min(0,e.x),end:Math.max(this.artboardWidth,e.x+e.width)});break}}}return{dx:i,dy:n,guides:t}}snapResize(e){const t=e.clone(),{dx:i,dy:n,guides:s}=this.snapMove(t);return t.x+=i,t.y+=n,{corrected:t,guides:s}}snapPoint(e){const t=Eh.SNAP_THRESHOLD/this.scale,i=[],n=e.clone(),s=[0,this.artboardWidth/2,this.artboardWidth];for(const a of s)if(Math.abs(a-e.x)<t){n.x=a,i.push({type:"vertical",position:a,start:0,end:this.artboardHeight});break}const o=[0,this.artboardHeight/2,this.artboardHeight];for(const a of o)if(Math.abs(a-e.y)<t){n.y=a,i.push({type:"horizontal",position:a,start:0,end:this.artboardWidth});break}return{p:n,guides:i}}}const U4={delta:new ae};class z4 extends Pe{group;wireframe=new bte;selectionOutlines=new Ze;isDragging=!1;lastPointer=new me;activeHandle=null;#e;#l=new Map;#r=new me;#n=0;#u=0;#c=new he;#i=new me;#s=new he;#t=[new me,new me,new me,new me];#o=1;#a=1;#h;#d=new Ze;#m=new me;opts;constructor(e){super(),this.opts=e,this.group=e.group,this.eventMode="static",this.#h=new Eh(e.artboardWidth??1920,e.artboardHeight??1080),this.addChild(this.#d);const t={beginDrag:(i,n)=>this.#A(i,n),updateDrag:(i,n)=>this.#E(i,n),endDrag:()=>this.#v()};this.#e={tl:new Ji("tl","nwse-resize",t),tr:new Ji("tr","nesw-resize",t),bl:new Ji("bl","nesw-resize",t),br:new Ji("br","nwse-resize",t),ml:new Ji("ml","ew-resize",t),mr:new Ji("mr","ew-resize",t),mt:new Ji("mt","ns-resize",t),mb:new Ji("mb","ns-resize",t),rot:new Ji("rot","crosshair",{beginDrag:(i,n)=>this.#B(n),updateDrag:(i,n)=>this.#k(n),endDrag:()=>this.#v()})},this.addChild(this.selectionOutlines,this.wireframe,...Object.values(this.#e)),this.#w(),this.visible=!1,Ft.shared.addOnce(()=>{this.showImmediate()})}#x=!1;showImmediate(){this.#x||this.destroyed||!this.parent||(this.#f(),this.visible=!0,this.#x=!0)}#w(){this.on("pointerdown",this.#S),this.on("pointerup",this.#y),this.on("pointerupoutside",this.#y),this.on("globalpointermove",this.#T)}#f(){if(this.group.length===1){const e=this.group[0];this.#n=e.rotation;const t=this.#g(e);let i,n;this.opts.clip?(i=this.opts.clip.width,n=this.opts.clip.height):(i=t.width,n=t.height);const s=e.toGlobal(new me(0,0));this.#r.set(s.x,s.y),this.#s.copyFrom(new he(-i/2,-n/2,i,n))}else{let e=1/0,t=1/0,i=-1/0,n=-1/0;if(this.parent)for(const u of this.group){const c=this.#g(u);this.#t[0].set(c.x,c.y),this.#t[1].set(c.x+c.width,c.y),this.#t[2].set(c.x+c.width,c.y+c.height),this.#t[3].set(c.x,c.y+c.height);for(const h of this.#t)u.toGlobal(h,h),this.toLocal(h,void 0,h),e=Math.min(e,h.x),t=Math.min(t,h.y),i=Math.max(i,h.x),n=Math.max(n,h.y)}const s=i-e,o=n-t,a=e+s/2,l=t+o/2;if(this.#s.copyFrom(new he(-s/2,-o/2,s,o)),this.parent){const u=this.toGlobal(new me(a,l));this.#r.set(u.x,u.y)}}this.#p()}#g(e){let t=null;const i=u=>{if(u.label==="MainSprite"&&u instanceof Je)return u;for(const c of u.children)if(c instanceof Pe){const h=i(c);if(h)return h}return null};if(t=i(e),t){const u=t.getLocalBounds(),c=t.localTransform.clone(),h=c.apply(new me(u.x,u.y)),d=c.apply(new me(u.x+u.width,u.y)),f=c.apply(new me(u.x+u.width,u.y+u.height)),p=c.apply(new me(u.x,u.y+u.height)),m=Math.min(h.x,d.x,f.x,p.x),g=Math.max(h.x,d.x,f.x,p.x),v=Math.min(h.y,d.y,f.y,p.y),x=Math.max(h.y,d.y,f.y,p.y);return new he(m,v,g-m,x-v)}let n=1/0,s=1/0,o=-1/0,a=-1/0;const l=e.children.filter(u=>u.label!=="ShadowContainer"&&u.label!=="AnimationContainer");if(l.length===0&&e.children.length>0){const u=e.children.find(c=>c.label==="AnimationContainer");if(u){const c=u.getLocalBounds();return new he(c.minX,c.minY,c.maxX-c.minX,c.maxY-c.minY)}}for(const u of l){const c=u.getBounds(),h=e.toLocal(new me(c.minX,c.minY)),d=e.toLocal(new me(c.maxX,c.maxY));n=Math.min(n,h.x,d.x),s=Math.min(s,h.y,d.y),o=Math.max(o,h.x,d.x),a=Math.max(a,h.y,d.y)}if(n===1/0){const u=e.getLocalBounds();return new he(u.minX,u.minY,u.maxX-u.minX,u.maxY-u.minY)}return new he(n,s,o-n,a-s)}updateBounds(){this.#f()}#S=e=>{e.button===0&&(this.opts.locked||(this.#f(),this.#m.copyFrom(this.#r),this.isDragging=!0,this.lastPointer.copyFrom(e.global),this.cursor="grabbing"))};#y=()=>{this.isDragging&&this.#v(),this.cursor="default"};#T=e=>{if(!this.isDragging||this.activeHandle||!this.parent)return;const{moveDx:t,moveDy:i,newPivotWorld:n}=this.#C(e);for(const s of this.group)s.x+=t,s.y+=i;this.#r.copyFrom(n),this.lastPointer.copyFrom(e.global),this.#p(),this.emit("transforming")};#C(e){const t=Math.abs(this.parent.worldTransform.a);this.#h.updateContext(this.opts.artboardWidth??1920,this.opts.artboardHeight??1080,t);const i=e.global.x-this.lastPointer.x,n=e.global.y-this.lastPointer.y;this.#m.x+=i,this.#m.y+=n;const s=this.parent.toLocal(this.#m),o=new he(s.x+this.#s.x,s.y+this.#s.y,this.#s.width,this.#s.height),{dx:a,dy:l,guides:u}=this.#h.snapMove(o);this.#b(u,t);const c=s.x+a,h=s.y+l,d=this.parent.toLocal(this.#r),f=c-d.x,p=h-d.y,m=this.parent.toGlobal(new me(c,h));return{moveDx:f,moveDy:p,newPivotWorld:m}}#A(e,t){this.#f(),this.isDragging=!0,this.activeHandle=e,this.#l.clear();for(const i of this.group)this.#l.set(i,i.localTransform.clone());this.rotation=this.#n,this.#c.copyFrom(this.#s),this.#F(e)}#E(e,t){this.#P(e,t)}async#P(e,t){const{proposed:i,sx:n,sy:s,pivotWorld:o}=await this.#I(e,t),a=this.opts.clip&&this.opts.clip.type==="Text",l=this.opts.clip&&this.opts.clip.type==="Caption";a||l?this.emit("textClipResize",{handle:e,newWidth:i.width,newHeight:i.height,pivotWorld:o,proposed:i,sx:n,sy:s}):this.#_(this.#D(o,this.#n,n,s)),this.#s.copyFrom(i),this.#p(),this.emit("transforming")}async#I(e,t){const i=this.#i,n=this.#M(e,this.toLocal(t),i),s=this.parent?Math.abs(this.parent.worldTransform.a):1;this.#h.updateContext(this.opts.artboardWidth??1920,this.opts.artboardHeight??1080,s);const{dx:o,dy:a,guides:l}=this.#h.snapMove(n);n.x+=o,n.y+=a,this.#b(l,s);const u=n.width/this.#c.width,c=n.height/this.#c.height,h=this.toGlobal(i);return{proposed:n,sx:u,sy:c,pivotWorld:h}}#B(e){this.#f(),this.isDragging=!0,this.activeHandle="rot",this.#l.clear();for(const t of this.group)this.#l.set(t,t.localTransform.clone());this.#u=Math.atan2(e.y-this.#r.y,e.x-this.#r.x)}#k(e){const i=Math.atan2(e.y-this.#r.y,e.x-this.#r.x)-this.#u,n=this.#n+i;this.#_(this.#O(this.#r,i)),this.rotation=n,this.#p(n),this.emit("transforming")}#v(){this.isDragging=!1,this.#n=this.rotation,this.activeHandle=null,this.#d.clear(),this.#p(this.#n),this.emit("transformEnd")}#b(e,t){if(this.#d.clear(),!(!e.length||!this.parent)){this.#d.stroke({width:1/t,color:4774907});for(const i of e){let n,s;i.type==="vertical"?(n=new me(i.position,i.start),s=new me(i.position,i.end)):(n=new me(i.start,i.position),s=new me(i.end,i.position)),this.toLocal(n,this.parent,n),this.toLocal(s,this.parent,s),this.#d.moveTo(n.x,n.y).lineTo(s.x,s.y).stroke({width:1/t,color:4774907})}}}#p(e=this.#n){this.parent&&this.position.copyFrom(this.parent.toLocal(this.#r)),this.rotation=e;const i=1/((this.parent?Math.abs(this.parent.worldTransform.a):1)||1),n=this.#s;this.wireframe.draw(n,i);const s=n.x+n.width/2,o=n.y+n.height/2,l=this.opts.locked?[]:this.opts.clip?.getVisibleHandles?.()??["tl","tr","bl","br","ml","mr","mt","mb","rot"],u=[this.#e.tl,this.#e.tr,this.#e.bl,this.#e.br,this.#e.ml,this.#e.mr,this.#e.mt,this.#e.mb,this.#e.rot];for(const c of u)c.scale.set(i);this.#e.tl.visible=l.includes("tl"),this.#e.tr.visible=l.includes("tr"),this.#e.bl.visible=l.includes("bl"),this.#e.br.visible=l.includes("br"),this.#e.ml.visible=l.includes("ml"),this.#e.mr.visible=l.includes("mr"),this.#e.mt.visible=l.includes("mt"),this.#e.mb.visible=l.includes("mb"),this.#e.rot.visible=l.includes("rot"),this.#e.tl.position.set(n.x,n.y),this.#e.tr.position.set(n.x+n.width,n.y),this.#e.bl.position.set(n.x,n.y+n.height),this.#e.br.position.set(n.x+n.width,n.y+n.height),this.#e.ml.position.set(n.x,o),this.#e.mr.position.set(n.x+n.width,o),this.#e.mt.position.set(s,n.y),this.#e.mb.position.set(s,n.y+n.height),this.#e.rot.position.set(s,n.y-30*i),this.#R(i)}#R(e){if(this.selectionOutlines.clear(),this.group.length<=1||!this.parent)return;const t={width:1*e,color:43775,alpha:1};for(const i of this.group){const n=this.#g(i);this.#t[0].set(n.x,n.y),this.#t[1].set(n.x+n.width,n.y),this.#t[2].set(n.x+n.width,n.y+n.height),this.#t[3].set(n.x,n.y+n.height);for(const s of this.#t)i.toGlobal(s,s),this.toLocal(s,void 0,s);this.selectionOutlines.moveTo(this.#t[0].x,this.#t[0].y).lineTo(this.#t[1].x,this.#t[1].y).lineTo(this.#t[2].x,this.#t[2].y).lineTo(this.#t[3].x,this.#t[3].y).closePath().stroke(t)}}#F(e){const t=this.#c;if(this.opts.centeredScaling){this.#i.set(t.x+t.width/2,t.y+t.height/2);return}e==="tl"?this.#i.set(t.x+t.width,t.y+t.height):e==="tr"?this.#i.set(t.x,t.y+t.height):e==="bl"?this.#i.set(t.x+t.width,t.y):e==="br"?this.#i.set(t.x,t.y):e==="ml"?this.#i.set(t.x+t.width,t.y+t.height/2):e==="mr"?this.#i.set(t.x,t.y+t.height/2):e==="mt"?this.#i.set(t.x+t.width/2,t.y+t.height):e==="mb"&&this.#i.set(t.x+t.width/2,t.y)}#M(e,t,i){if(this.opts.centeredScaling){const s=Math.max(this.#o,Math.abs(t.x-i.x)*2),o=Math.max(this.#a,Math.abs(t.y-i.y)*2);return new he(i.x-s/2,i.y-o/2,s,o)}if(e==="tl"){const s=Math.min(t.x,i.x-this.#o),o=Math.min(t.y,i.y-this.#a);return new he(s,o,i.x-s,i.y-o)}if(e==="tr"){const s=Math.max(t.x,i.x+this.#o),o=Math.min(t.y,i.y-this.#a);return new he(i.x,o,s-i.x,i.y-o)}if(e==="bl"){const s=Math.min(t.x,i.x-this.#o),o=Math.max(t.y,i.y+this.#a);return new he(s,i.y,i.x-s,o-i.y)}if(e==="br"){const s=Math.max(t.x,i.x+this.#o),o=Math.max(t.y,i.y+this.#a);return new he(i.x,i.y,s-i.x,o-i.y)}const n=this.#c;if(e==="ml"){const s=Math.min(t.x,i.x-this.#o);return new he(s,n.y,i.x-s,n.height)}if(e==="mr"){const s=Math.max(t.x,i.x+this.#o);return new he(i.x,n.y,s-i.x,n.height)}if(e==="mt"){const s=Math.min(t.y,i.y-this.#a);return new he(n.x,s,n.width,i.y-s)}if(e==="mb"){const s=Math.max(t.y,i.y+this.#a);return new he(n.x,i.y,n.width,s-i.y)}return new he(i.x,i.y,this.#o,this.#a)}#D(e,t,i,n){return U4.delta.identity().translate(-e.x,-e.y).rotate(-t).scale(i,n).rotate(t).translate(e.x,e.y)}#O(e,t){return U4.delta.identity().translate(-e.x,-e.y).rotate(t).translate(e.x,e.y)}#_(e){for(const t of this.group){const i=this.#l.get(t),n=t.parent;if(!i||!n)continue;const s=n.worldTransform.clone().invert(),o=n.worldTransform.clone().append(i),a=e.clone().append(o),l=s.clone().append(a);t.setFromMatrix(l)}}}class _te{constructor(e){this.studio=e}selectedClips=new Set;activeTransformer=null;interactiveClips=new Set;selectionGraphics=null;isDragSelecting=!1;dragSelectionStart=new me;isUpdatingTextRealtime=!1;textClipResizedWidth=null;textClipResizeHandle=null;textClipResizedSx=null;textClipResizedSy=null;lastPointerDownTime=0;lastPointerDownClip=null;init(e,t){this.selectionGraphics=new Ze,this.selectionGraphics.visible=!1,this.selectionGraphics.zIndex=1e3,t.addChild(this.selectionGraphics),e.stage.eventMode="static",e.stage.hitArea=e.screen,e.stage.on("pointerdown",i=>this.onStagePointerDown(i)),e.stage.on("globalpointermove",i=>this.onStagePointerMove(i)),e.stage.on("pointerup",()=>this.onStagePointerUp()),e.stage.on("pointerupoutside",()=>this.onStagePointerUp())}onStagePointerDown(e){e.target===this.studio.pixiApp?.stage&&(e.shiftKey||this.deselectClip(),this.isDragSelecting=!0,this.studio.artboard?.toLocal(e.global,void 0,this.dragSelectionStart),this.selectionGraphics&&(this.selectionGraphics.clear(),this.selectionGraphics.visible=!0))}onStagePointerMove(e){if(this.isDragSelecting&&this.selectionGraphics&&this.studio.artboard){const t=this.studio.artboard.toLocal(e.global),i=Math.min(this.dragSelectionStart.x,t.x),n=Math.min(this.dragSelectionStart.y,t.y),s=Math.abs(t.x-this.dragSelectionStart.x),o=Math.abs(t.y-this.dragSelectionStart.y);this.selectionGraphics.clear(),this.selectionGraphics.rect(i,n,s,o).fill({color:703971,alpha:.3}),this.selectionGraphics.rect(i,n,s,o).stroke({width:2,color:703971});const a=this.selectionGraphics.getBounds(),l=new he(a.x,a.y,a.width,a.height);if(l.width>2||l.height>2){const u=this.getIntersectingClips(l);this.updatePreviewSelection(u)}else this.selectedClips.size===0&&this.destroyTransformer();this.studio.pixiApp?.render()}}onStagePointerUp(){if(this.isDragSelecting&&this.selectionGraphics&&this.studio.artboard){const e=this.selectionGraphics.getBounds(),t=new he(e.x,e.y,e.width,e.height);if(t.width>2||t.height>2){const i=this.getIntersectingClips(t);if(i.length>0){for(const n of i)this.selectedClips.add(n);this.recreateTransformer(),this.studio.emit("selection:created",{selected:Array.from(this.selectedClips)})}else this.selectedClips.size===0&&this.destroyTransformer()}else this.selectedClips.size===0&&this.destroyTransformer();this.selectionGraphics.clear(),this.selectionGraphics.visible=!1,this.isDragSelecting=!1,this.studio.pixiApp?.render()}}getIntersectingClips(e){const t=[];for(const i of this.studio.clips){const n=this.studio.spriteRenderers.get(i);if(!n)continue;const s=n.getRoot();if(!s||!s.visible)continue;const o=s.getBounds();e.x<o.x+o.width&&e.x+e.width>o.x&&e.y<o.y+o.height&&e.y+e.height>o.y&&t.push(i)}return t}updatePreviewSelection(e){if(e.length===0){this.selectedClips.size===0?this.destroyTransformer():this.recreateTransformer();return}const t=new Set(e),i=[];let n=null;for(const s of t){const o=this.studio.spriteRenderers.get(s);if(o==null)continue;const a=o.getRoot();a!=null&&(i.push(a),t.size===1&&(n=s))}if(i.length===0){this.selectedClips.size===0&&this.destroyTransformer();return}this.activeTransformer?(this.activeTransformer.group=i,this.activeTransformer.opts.group=i,this.activeTransformer.opts.clip=n,this.activeTransformer.updateBounds(),this.activeTransformer.showImmediate()):(this.activeTransformer=new z4({group:i,clip:n,artboardWidth:this.studio.opts.width,artboardHeight:this.studio.opts.height}),this.studio.artboard?.addChild(this.activeTransformer),this.activeTransformer.showImmediate()),this.studio.pixiApp?.render()}setupSpriteInteractivity(e){if(this.interactiveClips.has(e))return;const t=this.studio.spriteRenderers.get(e);if(t==null)return;const i=t.getRoot();i!=null&&(i.eventMode="static",i.cursor="pointer",i.on("pointerdown",n=>{const s=Date.now(),o=this.getTopmostClipAtPoint(n.global);o===e&&o===this.lastPointerDownClip&&s-this.lastPointerDownTime<350&&(o.type==="Text"||o.type==="Caption")&&this.studio.emit("clip:dblclick",{clip:o}),this.lastPointerDownTime=s,this.lastPointerDownClip=o,o&&this.selectClip(o,n.shiftKey)}),this.interactiveClips.add(e))}getTopmostClipAtPoint(e){if(!this.studio.pixiApp)return null;let t=null,i=-1/0;for(const n of this.interactiveClips){const s=this.studio.spriteRenderers.get(n);if(!s)continue;const o=s.getRoot();if(!o||!o.visible)continue;const a=o.toLocal(e),l=o.getLocalBounds();a.x>=l.minX&&a.x<=l.maxX&&a.y>=l.minY&&a.y<=l.maxY&&n.zIndex>i&&(i=n.zIndex,t=n)}return t}selectClip(e,t=!1){if(!(this.studio.destroyed||this.studio.pixiApp==null)){if(t||this.deselectClip(),t&&this.selectedClips.has(e)){this.selectedClips.delete(e),this.recreateTransformer(),this.studio.emit("selection:updated",{selected:Array.from(this.selectedClips)}),this.studio.pixiApp?.render();return}this.selectedClips.add(e),this.recreateTransformer(),t?this.studio.emit("selection:updated",{selected:Array.from(this.selectedClips)}):this.studio.emit("selection:created",{selected:Array.from(this.selectedClips)}),this.studio.pixiApp?.render()}}selectClipsByIds(e){const t=this.studio.clips.filter(i=>e.includes(i.id));this.setSelection(t)}setSelection(e){if(!(this.studio.destroyed||this.studio.pixiApp==null)&&!(this.selectedClips.size===e.length&&e.every(t=>this.selectedClips.has(t)))){for(const t of this.selectedClips)this.syncSpriteToClipProperties(t);this.destroyTransformer(),this.selectedClips.clear();for(const t of e)this.selectedClips.add(t);this.selectedClips.size>0?(this.createTransformer(),this.studio.emit("selection:updated",{selected:Array.from(this.selectedClips)})):this.studio.emit("selection:cleared",{deselected:[]}),this.studio.pixiApp?.render()}}deselectClip(){if(this.selectedClips.size>0)for(const t of this.selectedClips)this.syncSpriteToClipProperties(t);this.destroyTransformer();const e=Array.from(this.selectedClips);this.selectedClips.clear(),e.length>0&&this.studio.emit("selection:cleared",{deselected:e}),this.studio.pixiApp?.render()}async move(e,t){if(this.selectedClips.size===0)return;const i=[];for(const n of this.selectedClips)i.push({id:n.id,updates:{left:(n.left??0)+e,top:(n.top??0)+t}});await this.studio.updateClips(i),this.activeTransformer&&this.activeTransformer.updateBounds()}clear(){this.deselectClip(),this.interactiveClips.clear()}recreateTransformer(){this.destroyTransformer(),this.selectedClips.size>0&&this.createTransformer()}destroyTransformer(){this.activeTransformer!=null&&(this.activeTransformer.parent!=null&&this.activeTransformer.parent.removeChild(this.activeTransformer),this.activeTransformer.destroy(),this.activeTransformer=null)}createTransformer(){if(this.studio.destroyed||this.studio.artboard==null||this.selectedClips.size===0)return;const e=[];let t=null;for(const s of this.selectedClips){const o=this.studio.spriteRenderers.get(s);if(o==null)continue;const a=o.getRoot();a!=null&&(e.push(a),this.selectedClips.size===1&&(t=s))}if(e.length===0){console.warn("Cannot create transformer: no sprites found");return}const i=t?.locked??!1;this.activeTransformer=new z4({group:e,clip:t,artboardWidth:this.studio.opts.width,artboardHeight:this.studio.opts.height,locked:i});let n=null;this.activeTransformer.on("transforming",()=>{n===null&&(n=requestAnimationFrame(()=>{n=null,this.syncSelectedClipsTransformsRealtime(),this.studio.pixiApp?.render()}))}),this.activeTransformer.on("textClipResize",s=>{this.textClipResizedWidth=s.newWidth,this.textClipResizeHandle=s.handle,this.textClipResizedSx=s.sx,this.textClipResizedSy=s.sy}),this.activeTransformer.on("transformEnd",async()=>{n!==null&&(cancelAnimationFrame(n),n=null),await this.syncSelectedClipsTransforms();for(const s of this.selectedClips)this.studio.emit("clip:updated",{clip:s});this.studio.emit("transform:end",{transformer:this.activeTransformer})}),this.activeTransformer.on("pointerdown",s=>{if(s.button!==0)return;this.studio.emit("transform:start",{transformer:this.activeTransformer});const o=this.getTopmostClipAtPoint(s.global),a=Date.now();o&&o===this.lastPointerDownClip&&a-this.lastPointerDownTime<350&&(o.type==="Text"||o.type==="Caption")&&this.studio.emit("clip:dblclick",{clip:o}),this.lastPointerDownTime=a,this.lastPointerDownClip=o,o&&!this.selectedClips.has(o)&&(this.selectClip(o,s.shiftKey),s.stopPropagation())}),this.studio.artboard.addChild(this.activeTransformer),this.activeTransformer.showImmediate(),this.studio.pixiApp?.render()}async syncSelectedClipsTransformsRealtime(){if(this.selectedClips.size===0||this.activeTransformer==null)return;const e=this.activeTransformer.activeHandle;if(e===null){for(const t of this.selectedClips){const i=this.studio.spriteRenderers.get(t);if(i==null)continue;const n=i.getRoot(),s=i.getSprite();if(n==null||s==null||s.texture==null)continue;const o=Math.abs(n.scale.x*s.scale.x)*s.texture.width,a=Math.abs(n.scale.y*s.scale.y)*s.texture.height;t.left=n.x-o/2,t.top=n.y-a/2}return}if(e==="mr"||e==="ml"){if(this.isUpdatingTextRealtime)return;this.isUpdatingTextRealtime=!0;try{for(const t of this.selectedClips){if(!(t instanceof Ki))continue;const i=this.studio.spriteRenderers.get(t);if(i==null)continue;const n=i.getRoot(),s=i.getSprite();if(n==null||s==null||s.texture==null)continue;const o=Math.abs(n.scale.x*s.scale.x);if(o===1)continue;const a=t.left,l=t.top,u=t.width,c=s.texture.width,h=o*c;await t.updateStyle({wordWrap:!0,wordWrapWidth:h});const d=await t.getTexture();d&&(await i.updateFrame(d),s.scale.set(1,1),n.scale.set(1,1),e==="ml"?t.left=a+u-t.width:t.left=a,t.top=l,n.x=t.left+t.width/2,n.y=t.top+t.height/2,this.activeTransformer.updateBounds())}}finally{this.isUpdatingTextRealtime=!1}}}async syncSelectedClipsTransforms(){if(!(this.selectedClips.size===0||this.activeTransformer==null)){for(const e of this.selectedClips){const t=this.studio.spriteRenderers.get(e);if(t==null)continue;const i=t.getRoot(),n=t.getSprite();if(i==null||n==null||n.texture==null)continue;const s=n.texture.width,o=n.texture.height,a=Math.abs(i.scale.x*n.scale.x)*s,l=Math.abs(i.scale.y*n.scale.y)*o,u=(e instanceof Ki||e instanceof On)&&this.textClipResizedWidth!==null?this.textClipResizedWidth:a,c=e.width,d=(e.style?.fontSize??16)*Math.max(this.textClipResizedSx||1,this.textClipResizedSy||1);let f=i.x;if((e instanceof Ki||e instanceof On)&&this.textClipResizedWidth!==null){const m={wordWrap:!0,wordWrapWidth:u};this.textClipResizeHandle==="mr"?(f=e.left+u/2,i.x=f):this.textClipResizeHandle==="ml"?(f=e.left+u/2-(u-c),i.x=f):["br","tr"].includes(this.textClipResizeHandle)?(f=e.left+u/2,m.fontSize=d):["bl","tl"].includes(this.textClipResizeHandle)&&(f=e.left+u/2-(u-c),m.fontSize=d),await e.updateStyle(m);const g=await e.getTexture();g&&(await t.updateFrame(g),e.width=u,e.height=g.height,this.textClipResizedWidth=null,e.left=f-e.width/2,e.top=i.y-e.height/2,n.scale.set(1,1),i.scale.set(1,1))}else{let m=a,g=l;e.left=i.x-m/2,e.top=i.y-g/2,e.width=m,e.height=g;const v=e.flip==null?1:-1;e.angle=v*i.angle}}this.activeTransformer!=null&&this.activeTransformer.updateBounds();for(const e of this.selectedClips){const t=this.studio.spriteRenderers.get(e);t?.updateTransforms()}}}syncSpriteToClipProperties(e){const t=this.studio.spriteRenderers.get(e);if(t!=null){const i=t.getRoot(),n=t.getSprite();if(i!=null&&n!=null&&n.texture!=null){const s=n.texture.width,o=n.texture.height,a=Math.abs(i.scale.x*n.scale.x)*s,l=Math.abs(i.scale.y*n.scale.y)*o;let u=a,c=l;const h=i.x-u/2,d=i.y-c/2;e.left=h,e.top=d,e.width=u,e.height=c;const f=e.flip==null?1:-1;e.angle=f*i.angle,t.updateTransforms(),this.studio.emit("clip:updated",{clip:e})}}}async deleteSelected(){return this.studio.deleteSelected()}}class wte{constructor(e){this.studio=e}isPlaying=!1;currentTime=0;maxDuration=0;playStartTime=0;playStartTimestamp=0;rafId=null;playbackElements=new Map;setMaxDuration(e){this.maxDuration=e}async play(){if(!(this.isPlaying||this.studio.destroyed)){if(this.maxDuration<=0||this.maxDuration===1/0||isNaN(this.maxDuration)){console.warn("Cannot play: invalid duration",this.maxDuration);return}this.isPlaying||(this.isPlaying=!0),this.playStartTime=this.currentTime,this.playStartTimestamp=performance.now();for(const[e,{element:t}]of this.playbackElements.entries()){if(!(this.currentTime>=e.display.from&&(e.display.to===0||this.currentTime<=e.display.to))){this.isPlaybackCapable(e)&&e.pause(t);continue}const n=(this.currentTime-e.display.from)/1e6;this.isPlaybackCapable(e)&&await e.play(t,n)}this.renderLoop(),this.studio.emit("play",{isPlaying:!0})}}pause(){this.isPlaying=!1,this.rafId!=null&&(cancelAnimationFrame(this.rafId),this.rafId=null);for(const[e,{element:t}]of this.playbackElements.entries())this.isPlaybackCapable(e)&&e.pause(t);this.studio.emit("pause",{isPlaying:!1})}async stop(){this.pause(),await this.seek(0)}async seek(e){if(this.studio.destroyed)return;const t=this.isPlaying;this.playStartTime=Math.max(0,Math.min(e,this.maxDuration)),this.playStartTimestamp=performance.now(),this.currentTime=this.playStartTime;for(const[i,{element:n}]of this.playbackElements.entries()){if(!(this.currentTime>=i.display.from&&(i.display.to===0||this.currentTime<=i.display.to))){this.isPlaybackCapable(i)&&i.pause(n);continue}const o=(this.currentTime-i.display.from)/1e6;this.isPlaybackCapable(i)&&await i.seek(n,o)}if(await this.studio.updateFrame(this.currentTime),this.studio.emit("currentTime",{currentTime:this.currentTime}),t){this.isPlaying=!0;for(const[i,{element:n}]of this.playbackElements.entries()){if(!(this.currentTime>=i.display.from&&(i.display.to===0||this.currentTime<=i.display.to)))continue;const o=(this.currentTime-i.display.from)/1e6;this.isPlaybackCapable(i)&&await i.play(n,o)}}}async frameNext(){const t=1e6/(this.studio.opts.fps||30),i=Math.min(this.currentTime+t,this.maxDuration);await this.seek(i)}async framePrev(){const t=1e6/(this.studio.opts.fps||30),i=Math.max(0,this.currentTime-t);await this.seek(i)}async renderLoop(){if(!this.isPlaying||this.studio.destroyed||this.studio.pixiApp==null)return;if(this.maxDuration<=0||this.maxDuration===1/0||isNaN(this.maxDuration)){this.pause();return}const e=async()=>{if(!this.isPlaying||this.studio.destroyed||this.studio.pixiApp==null)return;if(this.currentTime>=this.maxDuration){this.currentTime=this.maxDuration,this.pause();return}const i=(performance.now()-this.playStartTimestamp)*1e3;this.currentTime=Math.min(this.playStartTime+i,this.maxDuration),this.studio.emit("currentTime",{currentTime:this.currentTime});try{await this.studio.updateFrame(this.currentTime)}catch(n){console.warn("Error updating frame:",n)}this.isPlaying&&(this.rafId=requestAnimationFrame(e))};e()}isPlaybackCapable(e){return"play"in e&&"pause"in e&&"seek"in e}}class jo{static instance;fonts=new Map;constructor(){}static getInstance(){return jo.instance||(jo.instance=new jo),jo.instance}async addFont(e){if(!this.fonts.has(e.name))try{const i=await new FontFace(e.name,`url(${e.url})`).load();document.fonts.add(i),this.fonts.set(e.name,i)}catch(t){console.error(`Failed to load font ${e.name}:`,t)}}async loadFonts(e){await Promise.all(e.map(t=>this.addFont(t)))}removeFont(e){const t=this.fonts.get(e);t&&(document.fonts.delete(t),this.fonts.delete(e))}clear(){this.fonts.forEach(e=>{document.fonts.delete(e)}),this.fonts.clear()}getLoadedFonts(){return Array.from(this.fonts.keys())}}const L4=jo.getInstance();class Ste{constructor(e){this.studio=e}tracks=[];clips=[];getTrackById(e){return this.tracks.find(t=>t.id===e)}getClipById(e){return this.clips.find(t=>t.id===e)}findTrackIdByClipId(e){for(const t of this.tracks)if(t.clipIds.includes(e))return t.id}getTrackIndex(e){return this.tracks.findIndex(t=>t.id===e)}addTrack(e,t){const i={id:e.id||`track_${Date.now()}_${Math.random().toString(36).substr(2,9)}`,name:e.name,type:e.type,clipIds:[]};return typeof t=="number"?this.tracks.splice(t,0,i):this.tracks.unshift(i),this.studio.emit("track:added",{track:i,index:t??0}),this.studio.emit("track:order-changed",{tracks:this.tracks}),i}async removeTrack(e){const t=this.tracks.findIndex(s=>s.id===e);if(t===-1)return;const n=[...this.tracks[t].clipIds];for(const s of n)await this.removeClipById(s);this.tracks.splice(t,1),this.studio.emit("track:removed",{trackId:e}),this.studio.emit("track:order-changed",{tracks:this.tracks})}async moveTrack(e,t){const i=this.tracks.findIndex(s=>s.id===e);if(i===-1)return;const n=this.tracks[i];this.tracks.splice(i,1),this.tracks.splice(t,0,n),this.studio.emit("track:order-changed",{tracks:this.tracks}),await this.studio.updateFrame(this.studio.currentTime)}async setTrackOrder(e){const t=[],i=new Map(this.tracks.map(n=>[n.id,n]));for(const n of e){const s=i.get(n);s&&t.push(s)}t.length!==this.tracks.length&&console.warn("[Studio] setTrackOrder: invalid track IDs provided, order not updated fully"),this.tracks=t,this.studio.emit("track:order-changed",{tracks:this.tracks}),await this.studio.updateFrame(this.studio.currentTime)}async addTransition(e,t=2e6,i,n){if(this.studio.destroyed)return;let s=null,o=null;if(i&&n&&(s=this.getClipById(i)??null,o=this.getClipById(n)??null),!s||!o){console.warn("[Studio] Invalid fromClipId or toClipId",{fromClipId:i,toClipId:n});return}await Promise.all([s.ready,o.ready]);const a=t,l=o.display.from-a/2,u=l+a,c={key:e,name:e,duration:a,fromClipId:s.id,toClipId:o.id,start:Math.max(0,l),end:u},h=this.findTrackIdByClipId(o.id);if(h){const p=this.tracks.find(m=>m.id===h);if(p){const m=p.clipIds.map(g=>this.getClipById(g)).filter(g=>{if(!g||g.type!=="Transition")return!1;const v=g;return v.fromClipId===s.id&&v.toClipId===o.id});for(const g of m)await this.removeClip(g)}}const d=`${s.id}_${o.id}`;this.studio.transitionRenderers.has(d)&&(this.studio.transitionRenderers.get(d)?.destroy(),this.studio.transitionRenderers.delete(d)),s.transition={...c},o.transition={...c};const f=new Bi(e);f.duration=a,f.fromClipId=Math.max(0,l)===0?null:s.id,f.toClipId=o.id,f.fromClipId===null&&s&&(f.fromClipId=s.id),f.display.from=Math.max(0,l),f.display.to=u,await this.addClip(f,{trackId:h}),this.studio.seek(this.studio.currentTime)}async addClip(e,t){const i=Array.isArray(e)?e:[e];if(i.length===0)return;const{trackId:n,audioSource:s}=this.normalizeAddClipOptions(t);if(this.studio.destroyed)return;if(this.studio.pixiApp==null)throw new Error("Failed to initialize Pixi.js Application");const o=[];for(const a of i)await this.prepareClipForTimeline(a,n),o.push(a);await this.recalculateMaxDuration();for(const a of o)await this.setupClipVisuals(a,s);await this.studio.updateFrame(this.studio.currentTime),this.emitAddClipEvents(o,n)}normalizeAddClipOptions(e){let t,i;if(e&&(typeof e=="string"||e instanceof File||e instanceof Blob))t=e;else if(typeof e=="object"&&e!==null&&!("size"in e)){const n=e;t=n.audioSource,i=n.trackId}return{trackId:i,audioSource:t}}async prepareClipForTimeline(e,t){e.id||(e.id=`clip_${Date.now()}_${Math.random().toString(36).substr(2,9)}`),this.clips.includes(e)||this.clips.push(e),this.addClipToTrack(e,t);const i=async()=>{await this.studio.updateFrame(this.studio.currentTime);const n=this.studio.selection;n.activeTransformer!=null&&n.selectedClips.has(e)&&typeof n.activeTransformer.updateBounds=="function"&&n.activeTransformer.updateBounds()};e.on("propsChange",i),this.studio.clipListeners.set(e,i),this.studio.pixiApp!=null&&typeof e.setRenderer=="function"&&e.setRenderer(this.studio.pixiApp.renderer),await e.ready}addClipToTrack(e,t){if(t){const i=this.tracks.find(n=>n.id===t);if(i)i.clipIds.includes(e.id)||i.clipIds.push(e.id);else{const n={id:t,name:`Track ${this.tracks.length+1}`,type:e.type,clipIds:[e.id]};this.tracks.unshift(n),this.studio.emit("track:added",{track:n,index:0}),this.studio.emit("track:order-changed",{tracks:this.tracks})}}else{const n={id:`track_${Date.now()}_${Math.random().toString(36).substr(2,9)}`,name:`Track ${this.tracks.length+1}`,type:e.type,clipIds:[e.id]};this.tracks.unshift(n),this.studio.emit("track:added",{track:n,index:0}),this.studio.emit("track:order-changed",{tracks:this.tracks})}}async setupClipVisuals(e,t){const i=this.studio.spriteRenderers.get(e);if(i){const s=this.studio.clipsNormalContainer,o=i.getRoot();o&&!o.parent&&s.addChild(o);return}const n=await e.ready;if(await this.setupPlaybackForClip(e,t),n.width>0&&n.height>0){const s=this.studio.clipsNormalContainer,o=e.type==="Video"&&this.isPlaybackCapable(e);if(!o||o&&e.tickInterceptor!=null){const a=new R4(this.studio.pixiApp,e,s);this.studio.spriteRenderers.set(e,a)}}this.studio.opts.interactivity&&this.studio.selection.setupSpriteInteractivity(e)}emitAddClipEvents(e,t){if(e.length!==0)if(e.length===1){const i=e[0],n=t||this.tracks.find(s=>s.clipIds.includes(i.id))?.id||"";this.studio.emit("clip:added",{clip:i,trackId:n})}else this.studio.emit("clips:added",{clips:e,trackId:t})}async removeClip(e,t={permanent:!0}){const{permanent:i}=t;if(e.locked)return;const n=this.clips.findIndex(c=>c===e);if(n===-1)return;if(e instanceof Bi){if(e.fromClipId){const c=this.getClipById(e.fromClipId);c&&"transition"in c&&delete c.transition}if(e.toClipId){const c=this.getClipById(e.toClipId);c&&"transition"in c&&delete c.transition}}this.studio.selection.selectedClips.has(e)&&this.studio.selection.deselectClip(),this.clips.splice(n,1);const s=[];for(const c of this.tracks){const h=c.clipIds.indexOf(e.id);h!==-1&&(c.clipIds.splice(h,1),s.push(c.id))}for(const c of s){const h=this.tracks.findIndex(d=>d.id===c);h!==-1&&this.tracks[h].clipIds.length===0&&(this.tracks.splice(h,1),this.studio.emit("track:removed",{trackId:c}))}this.studio.selection.interactiveClips.delete(e);const o=this.studio.clipListeners.get(e);o&&(e.off("propsChange",o),this.studio.clipListeners.delete(e));const a=this.studio.spriteRenderers.get(e);if(a!=null)if(i)a.destroy(),this.studio.spriteRenderers.delete(e);else{const c=a.getRoot();c&&c.parent&&c.parent.removeChild(c)}const l=this.studio.transport.playbackElements.get(e);l!=null&&(this.isPlaybackCapable(e)&&e.pause(l.element),this.studio.transport.playbackElements.delete(e),i&&this.isPlaybackCapable(e)&&e.cleanupPlayback(l.element,l.objectUrl));const u=this.studio.videoSprites.get(e);u!=null&&this.studio.pixiApp!=null&&(u.parent&&u.parent.removeChild(u),i&&(u.destroy(),this.studio.videoSprites.delete(e))),await this.recalculateMaxDuration(),this.studio.emit("clip:removed",{clipId:e.id})}async removeClips(e,t={permanent:!0}){if(e.length!==0){for(const i of e){if(i.locked)continue;const n=this.clips.findIndex(u=>u===i);if(n===-1)continue;if(i instanceof Bi){if(i.fromClipId){const u=this.getClipById(i.fromClipId);u&&"transition"in u&&delete u.transition}if(i.toClipId){const u=this.getClipById(i.toClipId);u&&"transition"in u&&delete u.transition}}this.studio.selection.selectedClips.has(i)&&this.studio.selection.deselectClip(),this.clips.splice(n,1);for(const u of this.tracks){const c=u.clipIds.indexOf(i.id);c!==-1&&u.clipIds.splice(c,1)}this.studio.selection.interactiveClips.delete(i);const s=this.studio.clipListeners.get(i);s&&(i.off("propsChange",s),this.studio.clipListeners.delete(i));const o=this.studio.spriteRenderers.get(i);if(o!=null)if(t.permanent)o.destroy(),this.studio.spriteRenderers.delete(i);else{const u=o.getRoot();u&&u.parent&&u.parent.removeChild(u)}const a=this.studio.transport.playbackElements.get(i);a!=null&&(this.isPlaybackCapable(i)&&i.pause(a.element),this.studio.transport.playbackElements.delete(i),t.permanent&&this.isPlaybackCapable(i)&&i.cleanupPlayback(a.element,a.objectUrl));const l=this.studio.videoSprites.get(i);l!=null&&this.studio.pixiApp!=null&&(l.parent&&l.parent.removeChild(l),t.permanent&&(l.destroy(),this.studio.videoSprites.delete(i)))}for(let i=this.tracks.length-1;i>=0;i--)if(this.tracks[i].clipIds.length===0){const n=this.tracks[i].id;this.tracks.splice(i,1),this.studio.emit("track:removed",{trackId:n})}await this.recalculateMaxDuration(),this.studio.emit("clips:removed",{clipIds:e.map(i=>i.id)})}}async removeClipById(e){const t=this.clips.find(i=>i.id===e);t&&await this.removeClip(t)}async updateClip(e,t){const i=this.clips.find(n=>n.id===e);i&&(i.locked&&!("locked"in t)||(i.locked&&"locked"in t&&(Object.keys(t).length===1||(t={locked:t.locked})),await this.applyClipUpdate(i,t),await this.recalculateMaxDuration(),await this.studio.updateFrame(this.studio.currentTime),this.updateTransformer(i),this.studio.emit("clip:updated",{clip:i})))}async updateClips(e){const t=[];for(const{id:i,updates:n}of e){const s=this.clips.find(o=>o.id===i);s&&(await this.applyClipUpdate(s,n),t.push(s))}if(t.length!==0){await this.recalculateMaxDuration(),await this.studio.updateFrame(this.studio.currentTime);for(const i of t)this.updateTransformer(i),this.studio.emit("clip:updated",{clip:i})}}async replaceClipsBySource(e,t){const i=this.clips.filter(n=>n.src===e);if(i.length!==0){this.studio.suspendRendering();for(const n of i){if(!this.clips.includes(n))continue;const s=this.findTrackIdByClipId(n.id);if(!s)continue;const o=this.getTrackById(s);if(!o)continue;const a=await t(n),l=async()=>{await this.studio.updateFrame(this.studio.currentTime),this.updateTransformer(a)};a.on("propsChange",l),this.studio.clipListeners.set(a,l),this.studio.pixiApp!=null&&typeof a.setRenderer=="function"&&a.setRenderer(this.studio.pixiApp.renderer),await a.ready;const u=this.clips.indexOf(n);u!==-1&&(this.clips[u]=a);const c=o.clipIds.indexOf(n.id);c!==-1&&(o.clipIds[c]=a.id),await this.setupClipVisuals(a);const h=this.studio.spriteRenderers.get(n);h&&(h.destroy(),this.studio.spriteRenderers.delete(n));const d=this.studio.videoSprites.get(n);d&&(d.parent&&d.parent.removeChild(d),d.destroy(),this.studio.videoSprites.delete(n));const f=this.studio.clipListeners.get(n);f&&(n.off("propsChange",f),this.studio.clipListeners.delete(n)),this.studio.selection.selectedClips.has(n)&&(this.studio.selection.selectedClips.delete(n),this.studio.selection.selectedClips.add(a)),this.studio.emit("clip:replaced",{oldClip:n,newClip:a,trackId:s})}await this.recalculateMaxDuration(),this.studio.resumeRendering(),await this.studio.updateFrame(this.studio.currentTime)}}async applyClipUpdate(e,t){if(e.type==="Text"||e.type==="Caption"){const i=e;typeof i.updateStyle=="function"&&await i.updateStyle(t),"style"in t&&delete t.style}if(Object.assign(e,t),t.display&&!t.duration?e.duration=t.display.to-t.display.from:t.duration&&(!t.display||!t.display.to)&&(e.display||(e.display={from:0,to:t.duration}),e.display.to=e.display.from+t.duration),t.display&&t.duration){const i=t.display.to-t.display.from;i!==t.duration&&(e.duration=i)}else e.display&&(e.display.to=e.display.from+e.duration)}updateTransformer(e){const t=this.studio.selection;t.selectedClips.has(e)&&t.activeTransformer&&t.activeTransformer.updateBounds()}exportToJSON(){const e=this.clips.map(n=>Rl(n,!1)),t=this.tracks.map(n=>({id:n.id,name:n.name,type:n.type,clipIds:[...n.clipIds]})),i=[];return this.clips.forEach(n=>{if(n.transition){const s=this.tracks.find(o=>o.clipIds.includes(n.id));if(s){const o=s.clipIds.indexOf(n.id);if(o>0){const a=s.clipIds[o-1];i.push({key:n.transition.name,duration:n.transition.duration,clips:[a,n.id]})}}}}),{tracks:t,clips:e,settings:{width:this.studio.opts.width,height:this.studio.opts.height,fps:this.studio.opts.fps,bgColor:this.studio.opts.bgColor}}}async loadFromJSON(e){if(await this.clear(),e.settings){const i=e.settings.width&&e.settings.width!==this.studio.opts.width||e.settings.height&&e.settings.height!==this.studio.opts.height;if(e.settings.width&&(this.studio.opts.width=e.settings.width),e.settings.height&&(this.studio.opts.height=e.settings.height),e.settings.fps&&(this.studio.opts.fps=e.settings.fps),e.settings.bgColor&&(this.studio.opts.bgColor=e.settings.bgColor),i&&this.studio.pixiApp!=null){const n=this.studio.opts.width,s=this.studio.opts.height;this.studio.pixiApp.renderer.resize(n,s),this.studio.opts.canvas&&(this.studio.opts.canvas.width=n,this.studio.opts.canvas.height=s)}}const t=[];if(e.clips){await this.ensureFontsForClips(e.clips);const i=e.clips.map(o=>o.src).filter(o=>o&&o.trim()!=="");this.studio.resourceManager.preload(i);const n=new Map;if(e.tracks){for(const o of e.tracks)if(o.clipIds)for(const a of o.clipIds)n.set(a,o.id)}if(e.tracks)for(const o of e.tracks)this.tracks.push({id:o.id,name:o.name,type:o.type,clipIds:[]});for(const o of e.clips)t.push((async()=>{try{let a=o.id?n.get(o.id):void 0;if(o.type==="Transition"){const u=o,c=u.toClipId||u.fromClipId;c&&(a=n.get(c))}if(o.type!=="Text"&&o.type!=="Caption"&&o.type!=="Effect"&&o.type!=="Transition"&&(!o.src||o.src.trim()===""))return console.warn(`Skipping clip ${o.type} with empty source`,o),{clip:null};const l=await Xo(o);return(l.type==="Video"||l.type==="Image")&&(!o.width||!o.height)&&this.studio.opts.width&&this.studio.opts.height&&(typeof l.scaleToFit=="function"&&await l.scaleToFit(this.studio.opts.width,this.studio.opts.height),typeof l.centerInScene=="function"&&l.centerInScene(this.studio.opts.width,this.studio.opts.height)),{clip:l,intendedTrackId:a}}catch(a){return console.error(`Failed to load clip ${o.id||"unknown"}:`,a),{clip:null}}})());const s=await Promise.all(t);for(const{clip:o,intendedTrackId:a}of s)o&&(o.id||(o.id=`clip_${Date.now()}_${Math.random().toString(36).substr(2,9)}`),this.clips.push(o),this.addClipToTrack(o,a))}this.studio.pixiApp&&this.clips.forEach(i=>{const n=async()=>{await this.studio.updateFrame(this.studio.currentTime);const s=this.studio.selection;s.activeTransformer!=null&&s.selectedClips.has(i)&&typeof s.activeTransformer.updateBounds=="function"&&s.activeTransformer.updateBounds()};i.on("propsChange",n),this.studio.clipListeners.set(i,n),typeof i.setRenderer=="function"&&i.setRenderer(this.studio.pixiApp.renderer),(async()=>{try{await i.ready,await this.setupClipVisuals(i),await this.studio.updateFrame(this.studio.currentTime)}catch(s){console.warn(`[Studio] Failed to setup visuals for clip ${i.id}:`,s)}})()});for(const i of this.clips){const n=i.effects;if(Array.isArray(n))for(const s of n)this.studio.globalEffects.has(s.id)||this.studio.globalEffects.set(s.id,{id:s.id,key:s.key,startTime:s.startTime,duration:s.duration})}for(const i of this.clips)if(i instanceof Bi){const n={name:i.transitionEffect.key,key:i.transitionEffect.key,duration:i.duration,fromClipId:i.fromClipId,toClipId:i.toClipId,start:i.display.from,end:i.display.to};if(i.fromClipId){const s=this.getClipById(i.fromClipId);s&&(s.transition={...n})}if(i.toClipId){const s=this.getClipById(i.toClipId);s&&(s.transition={...n})}}await this.recalculateMaxDuration();try{await this.studio.updateFrame(this.studio.currentTime)}catch(i){console.error("[Studio] Failed to update initial frame:",i)}this.studio.emit("studio:restored",{clips:this.clips,tracks:this.tracks,settings:this.studio.opts})}async deleteSelected(){const e=this.studio.selection.selectedClips,t=Array.from(e);if(t.length!==0)for(const i of t)await this.removeClip(i)}async duplicateSelected(){const e=this.studio.selection.selectedClips,t=Array.from(e).filter(n=>!n.locked);if(t.length===0)return;const i=[];for(const n of t){const s=this.findTrackIdByClipId(n.id);if(!s)continue;const o=this.tracks.find(h=>h.id===s);if(!o)continue;const a=Rl(n,!1),l=await Xo(a);l.id=`clip_${Date.now()}_${Math.random().toString(36).substr(2,9)}`;const u=`track_${Date.now()}_${Math.random().toString(36).substr(2,9)}`,c=`${o.name} (Copy)`;this.addTrack({id:u,name:c,type:o.type}),await this.addClip(l,{trackId:u}),i.push(l.id)}i.length>0&&this.studio.selection.selectClipsByIds(i)}async splitSelected(e){const t=Array.from(this.studio.selection.selectedClips);if(t.length!==1){console.warn("[Studio] Split requires exactly one selected clip");return}const i=t[0];if(i.locked){console.warn("[Studio] Cannot split a locked clip");return}const n=e??this.studio.currentTime;if(n<=i.display.from||i.display.to>0&&n>=i.display.to){console.warn("[Studio] Split time is outside clip bounds");return}const s=Rl(i,!1),o=n-i.display.from,a=i.playbackRate||1,l=o*a,u={duration:o,display:{from:i.display.from,to:n}};i.trim&&(u.trim={from:i.trim.from,to:i.trim.from+l}),await this.updateClip(i.id,u);const c={...s};c.display={from:n,to:s.display.to},c.duration=s.duration-o,c.trim&&(c.trim={from:c.trim.from+l,to:c.trim.to});const h=await Xo(c);h.id=`clip_${Date.now()}_${Math.random().toString(36).substr(2,9)}`;const d=this.findTrackIdByClipId(i.id);d&&(await this.addClip(h,{trackId:d}),this.studio.selection.selectClipsByIds([h.id]))}async trimSelected(e){const t=Array.from(this.studio.selection.selectedClips);if(t.length!==1){console.warn("[Studio] Trim requires exactly one selected clip");return}const i=t[0];if(i.locked){console.warn("[Studio] Cannot trim a locked clip");return}const n=e*1e6,s=i.playbackRate||1,o=n*s;if(n>=i.duration){console.warn("[Studio] Trim amount exceeds clip duration");return}const a=i.duration-n,l=i.display.from+n,u=i.display.to,c={duration:a,display:{from:l,to:u}};if(i.trim)c.trim={from:i.trim.from+o,to:i.trim.to};else{const h=i.sourceDuration||i.duration;c.trim={from:o,to:h}}await this.updateClip(i.id,c)}async updateSelected(e){const t=Array.from(this.studio.selection.selectedClips);if(t.length!==0)for(const i of t)await this.updateClip(i.id,e)}async setTracks(e){this.tracks=JSON.parse(JSON.stringify(e)),await this.recalculateMaxDuration(),await this.studio.updateFrame(this.studio.currentTime)}async ensureFontsForClips(e){const t=new Map;for(const i of e){if(i.type==="Text"){const n=i.style?.fontUrl||i.fontUrl;n&&t.set(n,{name:i.style?.fontFamily||i.fontFamily||"CustomFont",url:n})}if(i.type==="Caption"){const n=i.style?.fontUrl||i.fontUrl;n&&t.set(n,{name:i.style?.fontFamily||i.fontFamily||"CustomFont",url:n})}}if(t.size>0)try{await L4.loadFonts(Array.from(t.values()))}catch(i){console.warn("Failed to load some fonts:",i)}}async recalculateMaxDuration(){let e=0;for(const t of this.clips){t.display.to===0&&t.duration!==1/0&&!isNaN(t.duration)&&t.duration>0;const i=t.duration>0?t.duration:0;if(i===1/0)continue;const n=t.display.to>0?t.display.to:t.display.from+i;n>e&&(e=n)}this.studio.maxDuration=e}async setupPlaybackForClip(e,t){if(this.studio.pixiApp!=null&&this.isPlaybackCapable(e))try{const i=e;if(e.type==="Audio"&&t&&typeof t!="string"){const o=URL.createObjectURL(t);e.src=o}const{element:n,objectUrl:s}=await i.createPlaybackElement();if(e.type==="Video"){const o=Q.from(n),a=new Je(o);a.visible=!1,this.studio.clipsNormalContainer&&this.studio.clipsNormalContainer.addChild(a),this.studio.videoSprites.set(e,a)}this.studio.transport.playbackElements.set(e,{element:n,objectUrl:s})}catch(i){console.warn(`Failed to setup playback for ${e.constructor.name}`,i)}}isPlaybackCapable(e){return"createPlaybackElement"in e&&"play"in e&&"pause"in e&&"seek"in e&&"syncPlayback"in e&&"cleanupPlayback"in e}async clear(){this.studio.selection.deselectClip(),this.studio.selection.interactiveClips.clear();for(const[e,t]of this.studio.clipListeners)e.off("propsChange",t);this.studio.clipListeners.clear(),this.studio.globalEffects.clear(),this.studio.effectFilters.clear(),this.studio.transitionRenderers.forEach(e=>e.destroy()),this.studio.transitionRenderers.clear(),this.studio.transitionSprites.forEach(e=>{e.parent&&e.parent.removeChild(e),e.destroy()}),this.studio.transitionSprites.clear(),this.studio.spriteRenderers.forEach(e=>e.destroy()),this.studio.spriteRenderers.clear();for(const[e,t]of this.studio.transport.playbackElements)this.isPlaybackCapable(e)&&e.cleanupPlayback(t.element,t.objectUrl);this.studio.transport.playbackElements.clear();for(const e of this.studio.videoSprites.values())e.destroy();this.studio.videoSprites.clear(),this.tracks=[],this.clips=[],this.studio.maxDuration=0,this.studio.currentTime=0,this.studio.emit("reset")}async rippleDelete(e,t){if(e>=t)return;const i=t-e,n=[...this.clips];for(const s of n){const o=s.display.from,a=s.display.to;if(!(a<=e)){if(o>=t){await this.updateClip(s.id,{display:{from:s.display.from-i,to:s.display.to-i}});continue}if(o>=e&&a<=t){await this.removeClip(s);continue}if(o<e&&a>t){const l=await s.clone();l.id=`clip_${Date.now()}_${Math.random().toString(36).substr(2,9)}`;const u=e,c=e+(a-t),h=s.trim.from+(t-o)*s.playbackRate,d=s.trim.to,f=this.tracks.find(p=>p.clipIds.includes(s.id));f&&(await this.addClip(l,{trackId:f.id}),await this.updateClip(l.id,{display:{from:u,to:c},trim:{from:h,to:d}})),await this.updateClip(s.id,{display:{from:s.display.from,to:e},trim:{from:s.trim.from,to:s.trim.from+(e-o)*s.playbackRate}});continue}if(o<e&&a<=t){await this.updateClip(s.id,{display:{from:s.display.from,to:e},trim:{from:s.trim.from,to:s.trim.from+(e-o)*s.playbackRate}});continue}if(o>=e&&a>t){await this.updateClip(s.id,{display:{from:e,to:e+(a-t)},trim:{from:s.trim.from+(t-o)*s.playbackRate,to:s.trim.to}});continue}}}await this.recalculateMaxDuration(),await this.studio.updateFrame(this.studio.currentTime)}}const Tte={Date:!0,RegExp:!0,String:!0,Number:!0};function N4(r,e,t={cyclesFix:!0},i=[]){let n=[];const s=Array.isArray(r);for(const a in r){const l=r[a],u=s?+a:a;if(!(a in e)){n.push({type:"REMOVE",path:[u],oldValue:r[a]});continue}const c=e[a],h=typeof l=="object"&&typeof c=="object"&&Array.isArray(l)===Array.isArray(c);l&&c&&h&&!Tte[Object.getPrototypeOf(l)?.constructor?.name]&&(!t.cyclesFix||!i.includes(l))?n.push.apply(n,N4(l,c,t,t.cyclesFix?i.concat([l]):[]).map(d=>(d.path.unshift(u),d))):l!==c&&!(Number.isNaN(l)&&Number.isNaN(c))&&!(h&&(isNaN(l)?l+""==c+"":+l==+c))&&n.push({path:[u],type:"CHANGE",value:c,oldValue:l})}const o=Array.isArray(e);for(const a in e)a in r||n.push({type:"CREATE",path:[o?+a:a],value:e[a]});return n}class Cte{past=[];future=[];lastState=null;maxSize;constructor(e={}){this.maxSize=e.maxSize||50}projectToHistoryState(e){const t={},i=JSON.parse(JSON.stringify(e.tracks||[]));return e.clips.forEach(n=>{n.id&&(t[n.id]=JSON.parse(JSON.stringify(n)))}),{clips:t,tracks:i,settings:JSON.parse(JSON.stringify(e.settings||{}))}}init(e){this.lastState=this.projectToHistoryState(JSON.parse(JSON.stringify(e))),this.past=[],this.future=[]}push(e){if(!this.lastState){this.init(e);return}const t=this.projectToHistoryState(JSON.parse(JSON.stringify(e))),i=N4(this.lastState,t);i.length!==0&&(this.past.push(i),this.past.length>this.maxSize&&this.past.shift(),this.future=[],this.lastState=t)}undo(e){const t=this.past.pop();if(!t)return null;const i=this.projectToHistoryState(JSON.parse(JSON.stringify(e))),n=this.applyPatches(i,t,!0);return this.future.push(t),this.lastState=n,{patches:t,state:n}}redo(e){const t=this.future.pop();if(!t)return null;const i=this.projectToHistoryState(JSON.parse(JSON.stringify(e))),n=this.applyPatches(i,t,!1);return this.past.push(t),this.lastState=n,{patches:t,state:n}}applyPatches(e,t,i){const n=JSON.parse(JSON.stringify(e)),s=i?[...t].reverse():t;for(const o of s){const{type:a,path:l}=o,u=o.value,c=o.oldValue;let h=n,d=!1;for(let p=0;p<l.length-1;p++){if(h[l[p]]===void 0||h[l[p]]===null){d=!0;break}h=h[l[p]]}if(d)continue;const f=l[l.length-1];if(i)switch(a){case"CREATE":Array.isArray(h)?h.splice(f,1):delete h[f];break;case"REMOVE":h[f]=c&&typeof c=="object"?JSON.parse(JSON.stringify(c)):c;break;case"CHANGE":h[f]=c&&typeof c=="object"?JSON.parse(JSON.stringify(c)):c;break}else switch(a){case"CREATE":h[f]=u&&typeof u=="object"?JSON.parse(JSON.stringify(u)):u;break;case"REMOVE":Array.isArray(h)?h.splice(f,1):delete h[f];break;case"CHANGE":h[f]=u&&typeof u=="object"?JSON.parse(JSON.stringify(u)):u;break}}return n}canUndo(){return this.past.length>0}canRedo(){return this.future.length>0}}class Ate extends X0{selection;transport;timeline;history;resourceManager;pixiApp=null;get tracks(){return this.timeline.tracks}get clips(){return this.timeline.clips}spriteRenderers=new Map;artboard=null;clipContainer=null;artboardMask=null;artboardBg=null;get activeTransformer(){return this.selection.activeTransformer}set activeTransformer(e){this.selection.activeTransformer=e}get selectedClips(){return this.selection.selectedClips}set selectedClips(e){this.selection.selectedClips=e}get interactiveClips(){return this.selection.interactiveClips}set interactiveClips(e){this.selection.interactiveClips=e}get playbackElements(){return this.transport.playbackElements}videoSprites=new Map;clipListeners=new Map;get isPlaying(){return this.transport.isPlaying}set isPlaying(e){this.transport.isPlaying=e}get currentTime(){return this.transport.currentTime}set currentTime(e){this.transport.currentTime=e}get maxDuration(){return this.transport.maxDuration}set maxDuration(e){this.transport.maxDuration=e}opts;destroyed=!1;renderingSuspended=!1;historyPaused=!1;processingHistory=!1;historyGroupDepth=0;clipCache=new Map;_isUpdatingLayout=!1;globalEffects=new Map;activeGlobalEffects=[];currentGlobalEffectSprite=null;effectFilters=new Map;transitionRenderers=new Map;transitionSprites=new Map;transFromTexture=null;transToTexture=null;transBgGraphics=null;clipsNormalContainer=null;clipsEffectContainer=null;videoTextureCache=new WeakMap;lastFromFrame=null;lastToFrame=null;hexToNumber(e){const t=e.startsWith("#")?e.slice(1):e;return parseInt(t,16)}ready;constructor(e){super(),this.opts={fps:30,bgColor:"#000000",interactivity:!0,spacing:0,...e},this.selection=new _te(this),this.transport=new wte(this),this.timeline=new Ste(this),this.history=new Cte,this.resourceManager=new Lo,this.ready=this.initPixiApp().then(()=>{this.history.init(this.exportToJSON())}),this.on("clip:added",t=>this.handleTimelineChange(t)),this.on("clips:added",t=>this.handleTimelineChange(t)),this.on("clip:replaced",t=>this.handleTimelineChange({clip:t.newClip})),this.on("studio:restored",t=>{t.clips.forEach(i=>this.attachClipEvents(i)),this.handleTimelineChange()}),this.on("clip:removed",this.handleClipRemoved),this.on("clips:removed",this.handleClipsRemoved),this.on("clip:updated",this.handleTimelineChange),this.on("track:removed",()=>this.handleTimelineChange()),this.on("track:added",()=>this.handleTimelineChange())}attachClipEvents(e){if(this.clipListeners.has(e))return;const t=()=>{this.updateFrame(this.currentTime)};e.on("request-render",t),this.clipListeners.set(e,t)}handleTimelineChange=e=>{e?.clip&&this.attachClipEvents(e.clip),e?.clips&&e.clips.forEach(t=>this.attachClipEvents(t)),this.updateFrame(this.currentTime),this.saveHistory()};saveHistory(){this.historyPaused||this.processingHistory||(this.history.push(this.exportToJSON()),this.emit("history:changed",{canUndo:this.history.canUndo(),canRedo:this.history.canRedo()}))}beginHistoryGroup(){this.historyGroupDepth++,this.historyPaused=!0}endHistoryGroup(){this.historyGroupDepth=Math.max(0,this.historyGroupDepth-1),this.historyGroupDepth===0&&(this.historyPaused=!1,this.saveHistory())}setPath(e,t,i){let n=e;for(let s=0;s<t.length-1;s++){const o=t[s];n[o]||(n[o]=typeof t[s+1]=="number"?[]:{}),n=n[o]}n[t[t.length-1]]=i}async applyHistoryPatches(e,t,i){const n=new Map,s=new Map,o=new Set;for(const a of e){const{type:l,path:u}=a,c=a.value,h=a.oldValue;if(u[0]==="clips"){const d=u[1];i?l==="CREATE"?o.add(d):l==="REMOVE"?s.set(d,h):l==="CHANGE"&&(n.has(d)||n.set(d,{}),this.setPath(n.get(d),u.slice(2),h)):l==="CREATE"?s.set(d,c):l==="REMOVE"?o.add(d):l==="CHANGE"&&(n.has(d)||n.set(d,{}),this.setPath(n.get(d),u.slice(2),c))}else u[0]==="settings"&&(i?this.setPath(this.opts,u.slice(1),h):this.setPath(this.opts,u.slice(1),c))}for(const a of o){const l=this.timeline.getClipById(a);l&&await this.removeClip(l)}for(const[a,l]of s){let u=this.clipCache.get(a);u||(u=await Xo(l),this.clipCache.set(a,u),this.attachClipEvents(u));let c;for(const h of t.tracks)if(h.clipIds.includes(a)){c=h.id;break}await this.addClip(u,{trackId:c})}for(const[a,l]of n)await this.updateClip(a,l);this.timeline.setTracks(t.tracks),this.emit("studio:restored",{clips:this.clips,tracks:this.tracks,settings:this.opts})}async undo(){if(!(!this.history.canUndo()||this.processingHistory)){this.processingHistory=!0,this.historyPaused=!0;try{const e=this.history.undo(this.exportToJSON());e&&await this.applyHistoryPatches(e.patches,e.state,!0),this.emit("history:changed",{canUndo:this.history.canUndo(),canRedo:this.history.canRedo()})}finally{this.historyPaused=!1,this.processingHistory=!1}}}async redo(){if(!(!this.history.canRedo()||this.processingHistory)){this.processingHistory=!0,this.historyPaused=!0;try{const e=this.history.redo(this.exportToJSON());e&&await this.applyHistoryPatches(e.patches,e.state,!1),this.emit("history:changed",{canUndo:this.history.canUndo(),canRedo:this.history.canRedo()})}finally{this.historyPaused=!1,this.processingHistory=!1}}}cleanupClipVisuals=e=>{for(const[s,o]of this.spriteRenderers)if(s.id===e){const a=o.getRoot();a&&a.parent&&a.parent.removeChild(a),o.destroy(),this.spriteRenderers.delete(s);break}const t=this.transitionSprites.get(e);t&&(t.parent&&t.parent.removeChild(t),t.destroy(),this.transitionSprites.delete(e)),this.transitionRenderers.get(e)&&this.transitionRenderers.delete(e);for(const[s,o]of this.videoSprites)if(s.id===e){o.parent&&o.parent.removeChild(o),o.destroy(),this.videoSprites.delete(s);break}const n=this.timeline.getClipById(e);if(n){const s=this.clipListeners.get(n);s&&(n.off("request-render",s),this.clipListeners.delete(n))}};handleClipRemoved=({clipId:e})=>{this.cleanupClipVisuals(e),this.updateFrame(this.currentTime),this.saveHistory()};handleClipsRemoved=({clipIds:e})=>{for(const t of e)this.cleanupClipVisuals(t);this.updateFrame(this.currentTime),this.saveHistory()};async initPixiApp(){if(this.destroyed)return;const e=this.opts.canvas||document.createElement("canvas");e.width=this.opts.width,e.height=this.opts.height;const t=new gc,i=e.parentElement||window;await t.init({canvas:e,resizeTo:i,backgroundColor:this.hexToNumber(this.opts.bgColor),antialias:!0,resolution:window.devicePixelRatio||1,autoDensity:!0,autoStart:!1}),this.pixiApp=t,t.render(),t.stage.eventMode="static",t.stage.hitArea=t.screen,this.artboard=new Pe,this.artboard.label="ArtboardRoot",t.stage.addChild(this.artboard),this.selection.init(t,this.artboard),this.artboardBg=new Ze,this.artboardBg.rect(0,0,this.opts.width,this.opts.height).fill({color:0}),this.artboard.addChild(this.artboardBg),this.clipContainer=new Pe,this.clipContainer.label="ClipContainer",this.artboard.addChild(this.clipContainer),this.artboardMask=new Ze,this.artboardMask.rect(0,0,this.opts.width,this.opts.height).fill({color:16777215}),this.clipContainer.addChild(this.artboardMask),this.clipContainer.mask=this.artboardMask,this.clipsEffectContainer=new Pe,this.clipsEffectContainer.label="ClipsEffect",this.clipsEffectContainer.visible=!1,this.clipsEffectContainer.zIndex=1,this.clipsEffectContainer.sortableChildren=!0,this.clipContainer.addChild(this.clipsEffectContainer),this.clipsNormalContainer=new Pe,this.clipsNormalContainer.label="ClipsNormal",this.clipsNormalContainer.zIndex=10,this.clipsNormalContainer.sortableChildren=!0,this.clipContainer.addChild(this.clipsNormalContainer),this.transFromTexture=Ot.create({width:this.opts.width,height:this.opts.height}),this.transToTexture=Ot.create({width:this.opts.width,height:this.opts.height}),this.transBgGraphics=new Ze,this.transBgGraphics.rect(0,0,this.opts.width,this.opts.height).fill({color:0,alpha:0}),this.clipContainer.sortableChildren=!0,this.updateArtboardLayout(),t.renderer.on("resize",()=>{this.handleResize()})}getOptions(){return this.opts}setSize(e,t){this.updateDimensions(e,t)}setBgColor(e){this.opts.bgColor=e;const t=this.hexToNumber(e);this.pixiApp&&(this.pixiApp.renderer.background.color=t,this.pixiApp.render()),this.updateFrame(this.currentTime)}updateDimensions(e,t){this.opts.width=e,this.opts.height=t,this.artboardBg&&this.artboardBg.clear().rect(0,0,e,t).fill({color:0}),this.artboardMask&&this.artboardMask.clear().rect(0,0,e,t).fill({color:16777215}),this.transFromTexture&&this.transFromTexture.resize(e,t),this.transToTexture&&this.transToTexture.resize(e,t),this.transBgGraphics&&this.transBgGraphics.clear().rect(0,0,e,t).fill({color:0,alpha:0}),this.updateArtboardLayout(),this.updateFrame(this.currentTime)}handleResize=()=>{this.destroyed||!this.pixiApp||this._isUpdatingLayout||this.updateArtboardLayout()};updateArtboardLayout(){if(!(!this.pixiApp||!this.artboard||this._isUpdatingLayout)){this._isUpdatingLayout=!0;try{this.pixiApp.resize();const t=this.pixiApp.canvas.parentElement,i=t?t.getBoundingClientRect().width:this.pixiApp.screen.width,n=t?t.getBoundingClientRect().height:this.pixiApp.screen.height,s=this.opts.width,o=this.opts.height,a=this.opts.spacing||0,l=Math.max(0,i-a*2),u=Math.max(0,n-a*2),c=l/s,h=u/o,d=Math.min(c,h);this.artboard.scale.set(d),this.artboard.x=(i-s*d)/2,this.artboard.y=(n-o*d)/2,this.pixiApp.render()}finally{this._isUpdatingLayout=!1}}}getCanvas(){if(this.opts.canvas)return this.opts.canvas;if(this.pixiApp?.canvas)return this.pixiApp.canvas;throw new Error("Canvas not initialized yet. Wait for initPixiApp to complete.")}async addTransition(e,t=2e6,i,n){return this.timeline.addTransition(e,t,i,n)}findTrackIdByClipId(e){return this.timeline.findTrackIdByClipId(e)}async addClip(e,t){const i=Array.isArray(e)?e:[e];i.forEach(n=>this.clipCache.set(n.id,n)),this.beginHistoryGroup();try{const n=await this.timeline.addClip(e,t);return i.forEach(s=>this.attachClipEvents(s)),n}finally{this.endHistoryGroup()}}addTrack(e,t){return this.timeline.addTrack(e,t)}async setTracks(e){return this.timeline.setTracks(e)}async moveTrack(e,t){return this.timeline.moveTrack(e,t)}async setTrackOrder(e){return this.timeline.setTrackOrder(e)}async removeTrack(e){return this.timeline.removeTrack(e)}getClipById(e){return this.timeline.getClipById(e)}async updateClip(e,t){return this.timeline.updateClip(e,t)}async centerClip(e){const t=typeof e=="string"?this.getClipById(e):e;if(!t)return;const i=(this.opts.width-t.width)/2,n=(this.opts.height-t.height)/2;if(this.getClipById(t.id))return this.updateClip(t.id,{left:i,top:n});t.left=i,t.top=n}async centerClipH(e){const t=typeof e=="string"?this.getClipById(e):e;if(!t)return;const i=(this.opts.width-t.width)/2;if(this.getClipById(t.id))return this.updateClip(t.id,{left:i});t.left=i}async centerClipV(e){const t=typeof e=="string"?this.getClipById(e):e;if(!t)return;const i=(this.opts.height-t.height)/2;if(this.getClipById(t.id))return this.updateClip(t.id,{top:i});t.top=i}async scaleToFit(e){const t=typeof e=="string"?this.getClipById(e):e;if(!t)return;const i=await t.ready,{width:n,height:s}=i;if(n===0||s===0)return;const o=Math.min(this.opts.width/n,this.opts.height/s),a=n*o,l=s*o;if(this.getClipById(t.id))return this.updateClip(t.id,{width:a,height:l});t.width=a,t.height=l}async scaleToCover(e){const t=typeof e=="string"?this.getClipById(e):e;if(!t)return;const i=await t.ready,{width:n,height:s}=i;if(n===0||s===0)return;const o=Math.max(this.opts.width/n,this.opts.height/s),a=n*o,l=s*o;if(this.getClipById(t.id))return this.updateClip(t.id,{width:a,height:l});t.width=a,t.height=l}async updateClips(e){this.suspendRendering(),await this.timeline.updateClips(e),this.resumeRendering(),this.updateFrame(this.currentTime)}suspendRendering(){this.renderingSuspended=!0}resumeRendering(){this.renderingSuspended=!1}getTracks(){return this.timeline.tracks}getClip(e){return this.timeline.getClipById(e)}findClip(e){return this.timeline.getClipById(e)}setupSpriteInteractivity(e){this.selection.setupSpriteInteractivity(e)}async removeClip(e){const t=typeof e=="string"?this.getClipById(e):e;if(!t){console.warn("[Studio] removeClip: Clip not found",e);return}this.beginHistoryGroup();try{return this.clipCache.set(t.id,t),this.timeline.removeClip(t,{permanent:!this.processingHistory})}finally{this.endHistoryGroup()}}async removeClips(e){this.beginHistoryGroup();try{return e.forEach(t=>this.clipCache.set(t.id,t)),this.timeline.removeClips(e,{permanent:!this.processingHistory})}finally{this.endHistoryGroup()}}async removeClipById(e){const t=this.timeline.getClipById(e);if(t)return this.removeClip(t)}async removeClipsById(e){const t=e.map(i=>this.timeline.getClipById(i)).filter(Boolean);return this.removeClips(t)}async deleteSelected(){const e=this.selection.selectedClips;if(e.size!==0){this.beginHistoryGroup();try{await this.removeClips(Array.from(e))}finally{this.endHistoryGroup()}}}async duplicateSelected(){this.beginHistoryGroup();try{return await this.timeline.duplicateSelected()}finally{this.endHistoryGroup()}}async splitSelected(e){this.beginHistoryGroup();try{return await this.timeline.splitSelected(e)}finally{this.endHistoryGroup()}}async trimSelected(e){return this.timeline.trimSelected(e)}async updateSelected(e){return this.timeline.updateSelected(e)}async clear(){await this.timeline.clear(),this.transFromTexture&&(this.transFromTexture.destroy(!0),this.transFromTexture=null),this.transToTexture&&(this.transToTexture.destroy(!0),this.transToTexture=null),this.transBgGraphics&&(this.transBgGraphics.destroy(!0),this.transBgGraphics=null),this.transitionRenderers.forEach(e=>e.destroy()),this.transitionRenderers.clear(),this.transitionSprites.forEach(e=>e.destroy()),this.transitionSprites.clear(),this.emit("reset")}async play(){return this.transport.play()}pause(){this.transport.pause()}async stop(){return this.transport.stop()}async seek(e){return this.transport.seek(e)}async frameNext(){return this.transport.frameNext()}async framePrev(){return this.transport.framePrev()}getCurrentTime(){return this.transport.currentTime}getMaxDuration(){return this.transport.maxDuration}getIsPlaying(){return this.transport.isPlaying}getSelectedClips(){return Array.from(this.selectedClips)}getVideoTexture(e){let t=this.videoTextureCache.get(e);return t||(t=Q.from(e),this.videoTextureCache.set(e,t)),t}isPlaybackCapable(e){return"createPlaybackElement"in e&&"play"in e&&"pause"in e&&"seek"in e&&"syncPlayback"in e&&"cleanupPlayback"in e}async updateFrame(e){if(this.destroyed||this.pixiApp==null||this.renderingSuspended)return;this.updateActiveGlobalEffect(e);const t=new Set,i=new Set,n=this.tracks.length;for(const o of this.clips){const a=this.getTrackIndex(o.id);if(a!==-1){const l=(n-a)*10;o.zIndex=l;const u=this.spriteRenderers.get(o);if(u){const h=u.getRoot();h&&(h.zIndex=l)}const c=this.videoSprites.get(o);c&&(c.zIndex=l)}}const s=[...this.clips].sort((o,a)=>o.zIndex-a.zIndex);for(const o of s){if(e<o.display.from){const v=this.spriteRenderers.get(o);v!=null&&await v.updateFrame(null);const x=this.playbackElements.get(o);x!=null&&this.isPlaybackCapable(o)&&o.pause(x.element);continue}if(o.display.to>0&&e>o.display.to){const v=this.spriteRenderers.get(o);v!=null&&await v.updateFrame(null);const x=this.playbackElements.get(o);x!=null&&this.isPlaybackCapable(o)&&o.pause(x.element);continue}const a=e-o.display.from,l=a*o.playbackRate;o.animate(l);const u=await o.ready,c=o.duration||u.duration;if(c>0&&a>c){const v=this.spriteRenderers.get(o);v!=null&&await v.updateFrame(null);const x=this.playbackElements.get(o);x!=null&&this.isPlaybackCapable(o)&&o.pause(x.element);continue}const h=this.playbackElements.get(o),d=o.type==="Video"||o.type==="Image",f=o.transition?o.transition.start:0,p=o.transition?o.transition.end:0,m=d&&o.transition&&e>=f&&e<p;if(h!=null&&this.isPlaybackCapable(o)){const v=a/1e6;if(o.syncPlayback(h.element,this.isPlaying,v),o.type==="Video"&&this.isPlaybackCapable(o)){const x=this.videoSprites.get(o);if(x!=null){const y=o.meta.duration/1e6;if(this.spriteRenderers.has(o))x.visible=!1;else if(x.visible=!m&&v>=0&&v<y,x.visible&&hee(o,x),!m)continue}}else continue}if(m){const v=o?.transition?.fromClipId,x=o?.transition?.toClipId,y=`${v}_${x}`;if(i.has(y)){const E=this.spriteRenderers.get(o);E?.getRoot()&&(E.getRoot().visible=!1);const _=this.videoSprites.get(o);_&&(_.visible=!1);continue}i.add(y),this.transFromTexture||(this.transFromTexture=Ot.create({width:this.opts.width,height:this.opts.height})),this.transToTexture||(this.transToTexture=Ot.create({width:this.opts.width,height:this.opts.height})),this.transBgGraphics||(this.transBgGraphics=new Ze,this.transBgGraphics.rect(0,0,this.opts.width,this.opts.height).fill({color:0,alpha:0}));const b=v?this.getClipById(v):null,T=x?this.getClipById(x):null;let P=null,A=null;if(b){const E=Math.max(0,e-b.display.from),{video:_}=await b.getFrame(E);_ instanceof HTMLVideoElement?P=this.getVideoTexture(_):P=_,P&&(this.lastFromFrame=P)}if(T){const E=Math.max(0,e-T.display.from),{video:_}=await T.getFrame(E);_ instanceof HTMLVideoElement?A=this.getVideoTexture(_):A=_,A&&(this.lastToFrame=A)}if(P||(P=this.lastFromFrame),A||(A=this.lastToFrame),!P||!A)continue;if(P&&A&&this.pixiApp&&this.transFromTexture&&this.transToTexture){const E=(e-f)/o?.transition?.duration;b&&P&&this.renderClipToTransitionTexture(b,P,this.transFromTexture),T&&A&&this.renderClipToTransitionTexture(T,A,this.transToTexture);let _=this.transitionRenderers.get(y);if(!_)try{_=c1({name:o?.transition?.name,renderer:this.pixiApp.renderer}),this.transitionRenderers.set(y,_)}catch(S){console.error("[Studio] Failed to create transition renderer:",S)}if(_){const S=_.render({width:this.opts.width,height:this.opts.height,from:this.transFromTexture,to:this.transToTexture,progress:E});let I=this.transitionSprites.get(o.id);I||(I=new Je,I.label=`TransitionSprite_${o.id}`,this.transitionSprites.set(o.id,I),this.clipsNormalContainer&&this.clipsNormalContainer.addChild(I)),I.texture=S,I.visible=!0,I.x=0,I.y=0,I.width=this.opts.width,I.height=this.opts.height,I.anchor.set(0,0),I.zIndex=o.zIndex,t.add(o.id);const M=this.spriteRenderers.get(o);M?.getRoot()&&(M.getRoot().visible=!1);const O=this.videoSprites.get(o);if(O&&(O.visible=!1),b){const U=this.spriteRenderers.get(b);U?.getRoot()&&(U.getRoot().visible=!1);const X=this.videoSprites.get(b);X&&(X.visible=!1)}if(T){const U=this.spriteRenderers.get(T);U?.getRoot()&&(U.getRoot().visible=!1);const X=this.videoSprites.get(T);X&&(X.visible=!1)}continue}}}const g=this.spriteRenderers.get(o);if(g!=null){const v=this.selectedClips.has(o);if(o.type!=="Text"&&o.type!=="Caption"&&typeof o.getTexture=="function"&&o.getTexture()!=null){const y=o.getTexture();if(y!=null){await g.updateFrame(y),v||g.updateTransforms(),this.opts.interactivity&&this.selection.setupSpriteInteractivity(o);continue}}if(o.type==="Text"){const y=o;this.pixiApp?.renderer&&typeof y.setRenderer=="function"&&y.setRenderer(this.pixiApp.renderer);const b=await y.getTexture();if(b!=null){await g.updateFrame(b),v||g.updateTransforms(),this.opts.interactivity&&this.selection.setupSpriteInteractivity(o);continue}}if(o.type==="Caption"){o.updateState(a);const y=o;this.pixiApp?.renderer&&typeof y.setRenderer=="function"&&y.setRenderer(this.pixiApp.renderer);const b=await y.getTexture();if(b!=null){await g.updateFrame(b),v||g.updateTransforms(),this.opts.interactivity&&this.selection.setupSpriteInteractivity(o);continue}}const{video:x}=await o.getFrame(a);await g.updateFrame(x),v||g.updateTransforms(),this.opts.interactivity&&this.selection.setupSpriteInteractivity(o)}}if(this.activeGlobalEffects.length>0&&this.clipsNormalContainer&&this.clipsEffectContainer){for(const o of this.clips)this.moveClipToEffectContainer(o,!1);this.clipsNormalContainer.visible=!0,await this.applyGlobalEffects(e)}else if(this.clipsNormalContainer){for(const o of this.clips)this.moveClipToEffectContainer(o,!1);this.clipsNormalContainer.visible=!0,this.currentGlobalEffectSprite&&(this.currentGlobalEffectSprite.parent&&this.currentGlobalEffectSprite.parent.removeChild(this.currentGlobalEffectSprite),this.currentGlobalEffectSprite.destroy(),this.currentGlobalEffectSprite=null)}for(const[o,a]of this.transitionSprites.entries())t.has(o)||(a.visible=!1);this.pixiApp!=null&&this.pixiApp.render()}moveClipToEffectContainer(e,t=!0){if(!this.clipsNormalContainer||!this.clipsEffectContainer)return;const i=t?this.clipsEffectContainer:this.clipsNormalContainer,n=this.spriteRenderers.get(e);if(n){const o=n.getRoot();if(o&&o.parent!==i){try{o.parent&&o.parent.removeChild&&o.parent.removeChild(o)}catch(a){console.warn("moveClipToEffectContainer: could not remove root from parent",a)}i.addChild(o)}}const s=this.transitionSprites.get(e.id);if(s&&s.parent!==i){try{s.parent&&s.parent.removeChild&&s.parent.removeChild(s)}catch(o){console.warn("moveClipToEffectContainer: could not remove transSprite from parent",o)}i.addChild(s)}}applyGlobalEffect(e,t,i){const n=t.id||`${e}_${Date.now()}_${Math.random().toString(36).substr(2,9)}`,s={id:n,key:e,startTime:t.startTime,duration:t.duration??1e6};for(const o of i)o instanceof Bl&&o.addEffect(s),o instanceof br&&o.addEffect(s),o instanceof Ki&&o.addEffect(s),o instanceof On&&o.addEffect(s);return this.globalEffects.set(n,s),n}getTrackIndex(e){return this.tracks.findIndex(t=>t.clipIds.includes(e))}async getTransitionFromFrame(e,t){let i=null;if(e.transition?.prevClipId&&(i=this.clips.find(a=>a.id===e.transition.prevClipId)||null),i||(i=this.getPreviousClipOnTrack(e)),!i)return null;const n=i.duration>0?i.duration:0,s=Math.max(0,Math.min(t-i.display.from,n)),{video:o}=await i.getFrame(s);return o}getPreviousClipOnTrack(e){const t=this.getTrackIndex(e.id);return t===-1?null:this.clips.filter(i=>i.id!==e.id&&this.getTrackIndex(i.id)===t&&i.display.from<e.display.from&&(i instanceof br||i instanceof Bl)).sort((i,n)=>n.display.to-i.display.to)[0]||null}renderClipToTransitionTexture(e,t,i){if(!this.pixiApp)return;const n=e.style||{},{renderTransform:s}=e,o=(s?.mirror??0)>.5,a=t instanceof Q?t:Q.from(t),l=s?.x??0,u=s?.y??0,c=s?.angle??0,h=s?.scale??1,d=s?.opacity??1,f=s?.blur??0,p=s?.brightness??1,m=a.width||1,g=a.height||1,v=e.type==="Caption",x=!v&&e.width&&e.width!==0?Math.abs(e.width)/m:1,y=!v&&e.height&&e.height!==0?Math.abs(e.height)/g:1,b=new Pe;b.x=e.center.x+l,b.y=e.center.y+u,b.rotation=(e.flip==null?1:-1)*((e.angle+c)*Math.PI)/180,b.alpha=e.opacity*d;const T=new Je(a);T.anchor.set(.5,.5);let P=[];if(o){const U=x*h,X=y*h,D=m*U,k=g*X;T.position.set(0,0),T.scale.set(U,X);const Y=[[D,0,-U,X],[-D,0,-U,X],[0,k,U,-X],[0,-k,U,-X],[D,k,-U,-X],[-D,k,-U,-X],[D,-k,-U,-X],[-D,-k,-U,-X]];for(const[H,$,K,we]of Y){const Ie=new Je(a);Ie.anchor.set(.5,.5),Ie.position.set(H,$),Ie.scale.set(K,we),P.push(Ie)}if(e.flip==="horizontal"){T.scale.x=-U;for(let H=0;H<8;H++)P[H].scale.x=-Y[H][2]}else if(e.flip==="vertical"){T.scale.y=-X;for(let H=0;H<8;H++)P[H].scale.y=-Y[H][3]}b.addChild(T);for(const H of P)b.addChild(H)}else e.flip==="horizontal"?(T.scale.x=-x*h,T.scale.y=y*h):e.flip==="vertical"?(T.scale.x=x*h,T.scale.y=-y*h):(T.scale.x=x*h,T.scale.y=y*h),b.addChild(T);const A=[];if(f>0){const U=new ys;U.strength=f,U.quality=4,U.repeatEdgePixels=!0,A.push(U)}if(p!==1){const U=new Ro;U.brightness(p,!1),A.push(U)}b.filters=A;const E=n.borderRadius||0;let _=null;E>0&&(_=new Ze,_.roundRect(-m/2,-g/2,m,g,Math.min(E,m/2,g/2)),_.fill({color:16777215,alpha:1}),T.addChild(_),T.mask=_);const S=n.stroke;let I=null;if(S&&S.width>0){I=new Ze;const U=yt(S.color)??16777215;if(I.setStrokeStyle({width:S.width,color:U,alignment:1}),E>0){const X=Math.min(E,m/2,g/2);I.roundRect(-m/2,-g/2,m,g,X)}else I.rect(-m/2,-g/2,m,g);I.stroke(),T.addChild(I)}const M=n.dropShadow;let O=null;if(M&&(M.blur>0||M.distance>0)){O=new Ze;const U=yt(M.color)??0,X=M.alpha??.5,D=M.distance??0,k=M.angle??0,Y=Math.cos(k)*D,H=Math.sin(k)*D;if(E>0){const $=Math.min(E,m/2,g/2);O.roundRect(-m/2+Y,-g/2+H,m,g,$)}else O.rect(-m/2+Y,-g/2+H,m,g);O.fill({color:U,alpha:X}),b.addChildAt(O,0)}this.pixiApp.renderer.render({container:b,target:i,clear:!0}),t instanceof Q||T.texture.destroy(!0),_&&_.destroy(),I&&I.destroy(),O&&O.destroy();for(const U of P)U.destroy();T.destroy(),b.destroy()}removeGlobalEffect(e){this.globalEffects.delete(e)}clearGlobalEffects(){this.globalEffects.clear()}updateActiveGlobalEffect(e){const t=[];for(const i of this.clips)i instanceof Qi&&e>=i.display.from&&(i.display.to===0||e<i.display.to)&&t.push({id:i.id,key:i.effect.key,startTime:i.display.from,duration:i.duration>0?i.duration:i.display.to-i.display.from,trackIndex:this.getTrackIndex(i.id),values:i.effect.values});for(const i of this.globalEffects.values()){const n=i.startTime+i.duration;e>=i.startTime&&e<n&&t.push({id:i.id,key:i.key,startTime:i.startTime,duration:i.duration,trackIndex:-1})}this.activeGlobalEffects=t.sort((i,n)=>(n.trackIndex??-1)-(i.trackIndex??-1))}async applyGlobalEffects(e){if(this.currentGlobalEffectSprite&&(this.currentGlobalEffectSprite.parent&&this.currentGlobalEffectSprite.parent.removeChild(this.currentGlobalEffectSprite),this.currentGlobalEffectSprite.destroy(),this.currentGlobalEffectSprite=null),this.activeGlobalEffects.length===0||!this.pixiApp||!this.clipContainer||!this.clipsNormalContainer||!this.clipsEffectContainer)return;const t=this.opts.width,i=this.opts.height;let n=null,s=new Set;const o=[];for(const a of this.activeGlobalEffects){const{key:l,startTime:u,duration:c,trackIndex:h,values:d}=a,f=e-u,p=Math.min(Math.max(f/c,0),1);if(p<0||p>=1)continue;if(this.clipsEffectContainer.visible=!0,this.clipsEffectContainer.removeChildren(),n){const y=new Je(n);y.label="PrevEffectResult",y.width=t,y.height=i,this.clipsEffectContainer.addChild(y)}const m=h??-1;for(const y of this.clips){if(s.has(y.id))continue;const b=this.getTrackIndex(y.id);!(y instanceof Qi)&&(m===-1||b>m)&&(this.moveClipToEffectContainer(y,!0),s.add(y.id))}let g=this.effectFilters.get(l);if(!g)try{if(g=await l1({name:l,renderer:this.pixiApp.renderer,values:d}),g)this.effectFilters.set(l,g);else continue}catch(y){console.error(y);continue}const v=Ot.create({width:t,height:i});o.push(v),this.pixiApp.renderer.render({container:this.clipsEffectContainer,target:v,clear:!0});const x=g.render({canvasTexture:v,progress:p,width:t,height:i,values:d});this.clipsEffectContainer.visible=!1,n=x}if(n){const a=new Je(n);a.x=0,a.y=0,a.width=t,a.height=i,a.scale.set(1),a.zIndex=5,this.clipContainer.addChild(a),this.currentGlobalEffectSprite=a}for(const a of o)a.destroy(!0)}destroy(){if(!this.destroyed){window.removeEventListener("resize",this.handleResize),this.destroyed=!0,this.stop(),this.clear(),this.transitionRenderers.clear(),this.transFromTexture&&(this.transFromTexture.destroy(!0),this.transFromTexture=null),this.transToTexture&&(this.transToTexture.destroy(!0),this.transToTexture=null),this.transBgGraphics&&(this.transBgGraphics.destroy(!0),this.transBgGraphics=null);for(const e of this.transitionSprites.values())e.destroy();this.transitionSprites.clear(),this.pixiApp&&(this.pixiApp.destroy(!0,{children:!0,texture:!0}),this.pixiApp=null)}}selectClip(e,t=!1){this.selection.selectClip(e,t)}setSelection(e){this.selection.setSelection(e)}selectClipsByIds(e){this.selection.selectClipsByIds(e)}deselectClip(){this.selection.deselectClip()}async lockClip(e,t){const i=this.timeline.getClipById(e);i&&(await this.timeline.updateClip(e,{locked:t}),this.emit("clip:lock-changed",{clip:i,locked:t}),this.selection.selectedClips.has(i)&&this.selection.recreateTransformer(),await this.updateFrame(this.currentTime))}exportToJSON(){return this.timeline.exportToJSON()}async loadFromJSON(e){return this.timeline.loadFromJSON(e)}}xe.add($T),xe.mixin(Pe,eC),xe.add(Ox),xe.add(Ux),xe.add(Ly),xe.mixin(Pe,pP),xe.add(Oy),xe.add(yb),xe.add(kc),xe.add(_b),xe.add(Cb),xe.add(Ab),xe.add(Nb),xe.add(Lb),xe.add(Mb),xe.add(Ub),xe.add(Db),xe.add(kb),xe.add(Pb),xe.add(Ky),xe.add(Yy);const Ete=Object.freeze(Object.defineProperty({__proto__:null},Symbol.toStringTag,{value:"Module"})),Pte=Object.freeze(Object.defineProperty({__proto__:null},Symbol.toStringTag,{value:"Module"}));_e.ANIMATABLE_PROPERTIES=FL,_e.Audio=Jr,_e.Caption=On,_e.Compositor=gte,_e.DEFAULT_AUDIO_CONF=rt,_e.Effect=Qi,_e.GL_EFFECT_OPTIONS=bQ,_e.GL_TRANSITION_OPTIONS=pte,_e.Image=Bl,_e.KeyframeAnimation=B,_e.Log=Ue,_e.MP4Clip=br,_e.Placeholder=kl,_e.Studio=Ate,_e.Text=Ki,_e.Transition=Bi,_e.VALUES_FILTER_SPECIAL=a1,_e.VALUES_FILTER_SPECIAL_LIMITS=lee,_e.Video=br,_e.animationRegistry=z,_e.clipToJSON=Rl,_e.createChromakey=TL,_e.createSlowMo=iS,_e.easings=Su,_e.fastConcatMP4=Hk,_e.fixFMP4Duration=Bq,_e.fontManager=L4,_e.getAllEffects=jb,_e.getAllTransitions=qo,_e.getEasing=Y0,_e.getEffectOptions=Yk,_e.getPresetTemplate=V,_e.getTransitionOptions=D4,_e.jsonToClip=Xo,_e.makeEffect=l1,_e.makeTransition=c1,_e.mixinMP4AndAudio=Mq,_e.registerCustomEffect=vQ,_e.registerCustomTransition=dte,_e.renderTxt2ImgBitmap=kL,_e.unregisterCustomEffect=xQ,_e.unregisterCustomTransition=fte,Object.defineProperty(_e,Symbol.toStringTag,{value:"Module"})}));
14345
+ `,hte={radialSwipe:{label:"Radial Swipe",fragment:vee}},Ah={};function dte(r,e){Ah[r]=e}function fte(r){delete Ah[r]}function qo(){return{...Yo.reduce((r,e)=>(r[e.name]={label:e.name,fragment:e.glsl,uniforms:e.defaultParams,previewDynamic:""},r),{}),...hte,...Ah}}qo();function D4(){const r=Object.keys(Ah);return Object.entries(qo()).map(([e,t])=>({key:e,label:t.label,isCustom:r.includes(e),previewStatic:t.previewStatic||`https://cdn.subgen.co/previews/static/transition_${e}_static.webp`,previewDynamic:t.previewDynamic||`https://cdn.subgen.co/previews/dynamic/transition_${e}_dynamic.webp`}))}const pte=D4();function c1({name:r,renderer:e}){let t=Yo.find(G=>G.name===r);if(!t){const G=qo(),ne=Object.keys(G).find(oe=>oe.toLowerCase()===r.toLowerCase());ne&&(t=G[ne])}if(t||(t=Yo.find(G=>G.name.toLowerCase()===r.toLowerCase())),!t){const G=[r,r.toLowerCase(),r.charAt(0).toUpperCase()+r.slice(1).toLowerCase(),r.replace(/([A-Z])/g,"_$1").toLowerCase().replace(/^_/,""),r.replace(/_/g,"")],ne=qo();for(const oe of G){if(t=Yo.find(be=>be.name.toLowerCase()===oe.toLowerCase()),t)break;const te=Object.keys(ne).find(be=>be.toLowerCase()===oe.toLowerCase());if(te){t=ne[te];break}}}if(!t){const G=Yo.length,ne=Yo.slice(0,5).map(be=>be.name).join(", "),oe=qo(),te=Object.keys(oe).slice(0,3).join(", ");throw console.error(`Transition not found: "${r}". Available in gl-transitions (${G} total):`,ne+"..."),console.error("Available locally:",te+"..."),new Error(`Transition "${r}" not found in gl-transitions library or local definitions`)}const i=new Je(Q.WHITE),n=Ot.create({width:e.width,height:e.height}),s=new jr({}),o=new jr({}),a=t.name==="displacement"||r.toLowerCase()==="displacement"||t.label==="displacement",l=a?new jr({}):void 0;let u=null;if(a){u=document.createElement("canvas"),u.width=256,u.height=256;const G=u.getContext("2d");if(G){const ne=G.createImageData(256,256);for(let oe=0;oe<ne.data.length;oe+=4){const te=Math.random();ne.data[oe]=te*255,ne.data[oe+1]=te*255,ne.data[oe+2]=te*255,ne.data[oe+3]=255}G.putImageData(ne,0,0)}}let c=t.glsl||t.fragment;if(!c)throw new Error(`Transition "${r}" has no glsl or fragment code`);let h={...st.basics,...st.custom(t)};Object.entries(h).forEach(([,G])=>{G.type==="int<f32>"&&(G.type="i32",typeof G.value=="number"&&(G.value=Math.trunc(G.value))),G.type==="ivec2<f32>"&&(G.type="vec2<f32>")});const d=t.name==="GridFlip"||r.toLowerCase()==="gridflip"||t.label==="gridflip",f=t.name==="circle"||r.toLowerCase()==="circle"||t.label==="circle",p=t.name==="directional"||r.toLowerCase()==="directional"||t.label==="directional",m=t.name==="UndulatingBurnOut"||r.toLowerCase()==="undulatingburnout"||t.label==="undulatingBurnOut",g=t.name==="SquaresWire"||r.toLowerCase()==="squareswire"||t.label==="squaresWire",v=t.name==="rotate_scale_fade"||r.toLowerCase()==="rotatescalefade"||t.label==="rotateScaleFade",x=t.name==="RandomSquares"||r.toLowerCase()==="randomsquares"||t.label==="randomSquares",y=t.name==="polar_function"||r.toLowerCase()==="polar_function"||t.label==="polar_function",b=t.name==="pixelate"||r.toLowerCase()==="pixelate"||t.label==="pixelate",T=t.name==="perlin"||r.toLowerCase()==="perlin"||t.label==="perlin",P=t.name==="luma"||r.toLowerCase()==="luma"||t.label==="luma",A=t.name==="luminance_melt"||r.toLowerCase()==="luminance_melt"||r.toLowerCase()==="luminancemelt"||t.label==="luminance_melt",E=t.name==="hexagonalize"||r.toLowerCase()==="hexagonalize"||t.label==="hexagonalize",_=t.name==="heart"||r.toLowerCase()==="heart"||t.label==="heart",S=t.name==="displacement"||r.toLowerCase()==="displacement"||t.label==="displacement",I=t.name==="directionalwipe"||r.toLowerCase()==="directionalwipe"||r.toLowerCase()==="directional_wipe"||t.label==="directionalwipe",M=t.name==="directionalwarp"||r.toLowerCase()==="directionalwarp"||r.toLowerCase()==="directional_warp"||t.label==="directionalwarp",O=t.name==="crosshatch"||r.toLowerCase()==="crosshatch"||t.label==="crosshatch",U=t.name==="circleopen"||r.toLowerCase()==="circleopen"||r.toLowerCase()==="circle_open"||t.label==="circleopen",X=t.name==="cannabisleaf"||r.toLowerCase()==="cannabisleaf"||r.toLowerCase()==="cannabis_leaf"||t.label==="cannabisleaf",D=t.name==="StereoViewer"||r.toLowerCase()==="stereoviewer"||r.toLowerCase()==="stereo_viewer"||t.label==="StereoViewer",k=t.name==="GlitchDisplace"||r.toLowerCase()==="glitchDisplace"||t.label==="GlitchDisplace",Y=t.name==="CrossZoom"||r.toLowerCase()==="crosszoom"||t.label==="CrossZoom",H=t.name==="CrazyParametricFun"||r.toLowerCase()==="crazyparametricfun"||t.label==="CrazyParametricFun",$=t.name==="BowTieHorizontal"||r.toLowerCase()==="bowtiehorizontal"||t.label==="BowTieHorizontal",K=t.name==="PolkaDotsCurtain"||r.toLowerCase()==="polkadotscurtain"||t.label==="PolkaDotsCurtain",we=t.name==="Pixelize"||r.toLowerCase()==="pixelize"||t.label==="Pixelize";d&&(c=xee,h={...st.basics,...yee}),f&&(c=bee,h={...st.basics,...M4}),p&&(c=_ee,h={...st.basics,...wee}),m&&(c=See,h={...st.basics,...Tee}),g&&(c=Cee,h={...st.basics,...Aee}),v&&(c=Eee,h={...st.basics,...Pee}),x&&(c=Iee,h={...st.basics,...Bee}),y&&(c=kee,h={...st.basics,...Ree}),b&&(c=Wk,h={...st.basics,...Vk}),T&&(c=Dee,h={...st.basics,...Oee}),P&&(c=Uee,h={...st.basics,...zee}),A&&(c=Lee,h={...st.basics,...Nee}),E&&(c=Gee,h={...st.basics,...Hee}),_&&(c=Wee,h={...st.basics,...Vee}),S&&(c=Xee,h={...st.basics,...Yee}),I&&(c=qee,h={...st.basics,...jee}),M&&(c=Kee,h={...st.basics,...Qee}),O&&(c=Zee,h={...st.basics,...Jee}),U&&(c=$ee,h={...st.basics,...M4}),X&&(c=ete,h={...st.basics,...tte}),D&&(c=rte,h={...st.basics,...ite}),k&&(c=nte),Y&&(c=ste,h={...st.basics,...ote}),H&&(c=ate,h={...st.basics,...lte}),$&&(c=ute),K&&(c=cte),we&&(c=Fee,h={...st.basics,...Mee});const Ie={from:s,to:o,uniforms:h};a&&l&&(Ie.displacementMap=l,u&&(l.resource=u,l.update()));const ve=new ge({glProgram:new ue({vertex:pee,fragment:gee(c)}),resources:Ie});return i.filters=[ve],{render({width:G,height:ne,from:oe,to:te,progress:be}){if((i.width!==G||i.height!==ne)&&(i.setSize({width:G,height:ne}),n.resize(G,ne)),oe instanceof Q?ve.resources.from=oe.source:(s.resource=oe,s.update(),ve.resources.from=s),te instanceof Q?ve.resources.to=te.source:(o.resource=te,o.update(),ve.resources.to=o),a&&l&&u){if(u.width!==G||u.height!==ne){u.width=G,u.height=ne;const Le=u.getContext("2d");if(Le){const ke=Le.createImageData(G,ne);for(let Ae=0;Ae<ke.data.length;Ae+=4){const je=Math.random();ke.data[Ae]=je*255,ke.data[Ae+1]=je*255,ke.data[Ae+2]=je*255,ke.data[Ae+3]=255}Le.putImageData(ke,0,0)}}l.resource=u,l.update()}return ve.resources.uniforms.uniforms.progress=be,e.render({container:i,target:n,clear:!0,width:G,height:ne}),n},destroy(){n.destroy(),i.destroy({children:!0})}}}let mte=0;async function O4(r){r()>50&&(await wu(15),await O4(r))}class gte extends X0{static async isSupported(e={}){return(self.OffscreenCanvas!=null&&self.VideoEncoder!=null&&self.VideoDecoder!=null&&self.VideoFrame!=null&&self.AudioEncoder!=null&&self.AudioDecoder!=null&&self.AudioData!=null&&((await self.VideoEncoder.isConfigSupported({codec:e.videoCodec??"avc1.42E032",width:e.width??1920,height:e.height??1080,bitrate:e.bitrate??7e6})).supported??!1)&&(await self.AudioEncoder.isConfigSupported({codec:(await kk()).codec,sampleRate:rt.sampleRate,numberOfChannels:rt.channelCount})).supported)??!1}logger=Ue.create(`id:${mte++},`);destroyed=!1;sprites=[];canvas;pixiApp=null;stopOutput=null;opts;hasVideoTrack;constructor(e={}){super(),console.log("Compositor constructor",e);const{width:t=0,height:i=0}=e;this.canvas=new OffscreenCanvas(t,i),this.opts=Object.assign({bgColor:"#000",width:0,height:0,format:"mp4",videoCodec:"avc1.42E032",audio:!0,audioCodec:"aac",audioSampleRate:48e3,bitrate:5e6,fps:30,metaDataTags:null},e),console.log("Compositor opts",this.opts),this.hasVideoTrack=t*i>0,kk().catch(n=>{this.logger.warn("Failed to detect audio codec:",n)})}async initPixiApp(){const{width:e,height:t}=this.opts;if(this.pixiApp=new gc,await this.pixiApp.init({canvas:this.canvas,width:e,height:t,backgroundColor:0,antialias:!1,autoDensity:!1,resolution:1,preference:"webgl"}),this.pixiApp.renderer==null||this.pixiApp.stage==null)throw new Error("Pixi.js Application failed to initialize properly");try{const i=this.pixiApp;i.ticker&&typeof i.ticker.stop=="function"&&i.ticker.stop()}catch{}}async addSprite(e,t={}){const i={rect:{x:e.left,y:e.top,w:e.width,h:e.height},display:{...e.display},duration:e.duration,playbackRate:e.playbackRate,zIndex:e.zIndex};this.logger.info("Compositor add clip",i);const n=await e.clone();this.pixiApp!=null&&this.pixiApp.renderer!=null&&typeof n.setRenderer=="function"&&n.setRenderer(this.pixiApp.renderer),this.logger.info("Compositor add clip ready"),this.sprites.push(Object.assign(n,{main:t.main??!1,expired:!1})),this.sprites.sort((s,o)=>s.zIndex-o.zIndex)}initMuxer(e){const{fps:t,width:i,height:n,videoCodec:s,bitrate:o,audio:a,metaDataTags:l,format:u,audioCodec:c,audioSampleRate:h}=this.opts,d=this.sprites.some(m=>m.width>0&&m.height>0),f=this.hasVideoTrack&&d;return UO({format:u||"mp4",video:f?{width:i,height:n,expectFPS:t,codec:s,bitrate:o,__unsafe_hardwareAcceleration__:this.opts.__unsafe_hardwareAcceleration__}:null,audio:a===!1?null:{codec:c||rt.codecType,sampleRate:h||rt.sampleRate,channelCount:rt.channelCount},duration:e,metaDataTags:l})}output(e={}){if(console.log("Compositor output",e),this.sprites.length===0)throw Error("No sprite added");const t=this.sprites.find(u=>u.main),n=this.sprites.map(u=>u.display.from+u.duration).filter(u=>u!==1/0),s=e.maxTime??(t!=null?t.display.from+t.duration:n.length>0?Math.max(...n):0);if(s===1/0||s<=0)throw Error("Unable to determine the end time, please specify a main sprite, or limit the duration of Image, Audio");s===-1&&this.logger.warn("Unable to determine the end time, process value don't update"),this.logger.info(`start combinate video, maxTime:${s}`);const o=this.initMuxer(s);let a=performance.now();const l=this.runEncoding(o,s,{onProgress:u=>{this.logger.debug("OutputProgress:",u),this.emit("OutputProgress",u)},onEnded:async()=>{await o.flush(),this.logger.info("===== output ended =====, cost:",performance.now()-a),this.emit("OutputProgress",1),this.destroy()},onError:u=>{this.emit("error",u),o.close(),this.destroy()}});return this.stopOutput=()=>{l(),o.close()},o.stream}destroy(){if(!this.destroyed&&(this.destroyed=!0,this.stopOutput?.(),this.off("OutputProgress"),this.off("error"),this.pixiApp!=null))try{const e=this.pixiApp;if(e.destroyed===!0){this.pixiApp=null;return}if(e.ticker&&typeof e.ticker.stop=="function")try{e.ticker.stop()}catch{}if(e.renderer!=null){const t=e.renderer.gl;if(t&&t.isContextLost()){this.pixiApp=null;return}this.pixiApp.destroy()}}catch(e){console.warn("Error while destroying Pixi application:",e)}finally{this.pixiApp=null}}runEncoding(e,t,{onProgress:i,onEnded:n,onError:s}){let o=0;const a={aborted:!1};let l=null,u=null;const c=async()=>{const{fps:f,bgColor:p,audio:m}=this.opts,g=Math.round(1e6/f),v=this.sprites.some(b=>b.width>0&&b.height>0);u=vte({pixiApp:this.pixiApp,sprites:this.sprites,aborter:a});const x=xte({muxer:e,canvas:this.canvas,outputAudio:m,hasVideoTrack:this.hasVideoTrack&&v,timeSlice:g,fps:f});let y=0;for(;;){if(l!=null)return;if(a.aborted||t!==-1&&y>t||this.sprites.length===0){h(),await n();return}o=y/t;const{audios:b,mainSprDone:T}=await u.render(y);if(T){h(),await n();return}if(a.aborted)return;this.hasVideoTrack&&await wu(0),x(y,b,!0),y+=g,await O4(e.getEncodeQueueSize)}},h=()=>{a.aborted||(a.aborted=!0,clearInterval(d),u?.cleanup(),this.sprites.forEach(f=>{f.destroy()}))};c().catch(f=>{l=f,this.logger.error(f),h(),s(f)});const d=setInterval(()=>{i(o)},500);return h}exportToJSON(){const e=this.sprites.map(i=>Rl(i,i.main)),t=[];return this.sprites.forEach(i=>{if(i.transition){const n=this.sprites.filter(s=>s.id!==i.id&&s.zIndex===i.zIndex&&s.display.from<i.display.from&&(s instanceof br||s instanceof Bl)).sort((s,o)=>o.display.to-s.display.to)[0];n&&t.push({key:i.transition.name,duration:i.transition.duration,clips:[n.id,i.id]})}}),{clips:e,settings:{width:this.opts.width,height:this.opts.height,fps:this.opts.fps,bgColor:this.opts.bgColor,format:this.opts.format,videoCodec:this.opts.videoCodec,bitrate:this.opts.bitrate,audio:this.opts.audio,audioCodec:this.opts.audioCodec,audioSampleRate:this.opts.audioSampleRate,metaDataTags:this.opts.metaDataTags}}}async loadFromJSON(e){this.sprites.forEach(t=>{t.destroy()}),this.sprites=[],e.settings&&(e.settings.width!==void 0&&(this.opts.width=e.settings.width),e.settings.height!==void 0&&(this.opts.height=e.settings.height),e.settings.fps!==void 0&&(this.opts.fps=e.settings.fps),e.settings.bgColor!==void 0&&(this.opts.bgColor=e.settings.bgColor),e.settings.format!==void 0&&(this.opts.format=e.settings.format),e.settings.videoCodec!==void 0&&(this.opts.videoCodec=e.settings.videoCodec),e.settings.bitrate!==void 0&&(this.opts.bitrate=e.settings.bitrate),e.settings.audio!==void 0&&(this.opts.audio=e.settings.audio===!1?!1:void 0),e.settings.audioCodec!==void 0&&(this.opts.audioCodec=e.settings.audioCodec),e.settings.audioSampleRate!==void 0&&(this.opts.audioSampleRate=e.settings.audioSampleRate),e.settings.metaDataTags!==void 0&&(this.opts.metaDataTags=e.settings.metaDataTags));for(const t of e.clips){const i=await Xo(t);await this.addSprite(i,{main:t.main||!1})}}}function vte(r){const{pixiApp:e,sprites:t,aborter:i}=r,n=e!=null,s=new Map,o=new Map,a=new Map,l=Ot.create({width:e?.renderer.width||0,height:e?.renderer.height||0}),u=Ot.create({width:e?.renderer.width||0,height:e?.renderer.height||0}),c=new Ze().rect(0,0,e?.renderer.width||0,e?.renderer.height||0).fill({color:0}),h=new Map,d=async(b,T,P)=>{const A=Math.max(0,Math.min(T-b.display.from,b.duration));b.animate(A*b.playbackRate);const{video:E}=await P(b,A);return E},f=(b,T,P)=>{if(!e)return;const A=b.style||{},{renderTransform:E}=b,_=(E?.mirror??0)>.5,S=T instanceof Q?T:Q.from(T),I=E?.x??0,M=E?.y??0,O=E?.angle??0,U=E?.scale??1,X=E?.scaleX??1,D=E?.scaleY??1,k=E?.opacity??1,Y=E?.blur??0,H=E?.brightness??1,$=S.width||1,K=S.height||1,we=b.type==="Caption",Ie=!we&&b.width&&b.width!==0?Math.abs(b.width)/$:1,ve=!we&&b.height&&b.height!==0?Math.abs(b.height)/K:1,G=Ie*U*X,ne=ve*U*D,oe=new Pe;oe.x=b.center.x+I,oe.y=b.center.y+M,oe.rotation=(b.flip==null?1:-1)*((b.angle+O)*Math.PI)/180,oe.alpha=b.opacity*k;const te=new Je(S);te.anchor.set(.5,.5);let be=[];if(_){const Re=G,nt=ne,Bt=$*Re,Vt=K*nt;te.position.set(0,0),te.scale.set(Re,nt);const Qe=[[Bt,0,-Re,nt],[-Bt,0,-Re,nt],[0,Vt,Re,-nt],[0,-Vt,Re,-nt],[Bt,Vt,-Re,-nt],[-Bt,Vt,-Re,-nt],[Bt,-Vt,-Re,-nt],[-Bt,-Vt,-Re,-nt]];for(const[Oe,Ri,As,Fl]of Qe){const Un=new Je(S);Un.anchor.set(.5,.5),Un.position.set(Oe,Ri),Un.scale.set(As,Fl),be.push(Un)}if(b.flip==="horizontal"){te.scale.x=-Re;for(let Oe=0;Oe<8;Oe++)be[Oe].scale.x=-Qe[Oe][2]}else if(b.flip==="vertical"){te.scale.y=-nt;for(let Oe=0;Oe<8;Oe++)be[Oe].scale.y=-Qe[Oe][3]}oe.addChild(te);for(const Oe of be)oe.addChild(Oe)}else b.flip==="horizontal"?(te.scale.x=-G,te.scale.y=ne):b.flip==="vertical"?(te.scale.x=G,te.scale.y=-ne):(te.scale.x=G,te.scale.y=ne),oe.addChild(te);const Le=[];if(Y>0){const Re=new ys;Re.strength=Y,Re.quality=4,Re.repeatEdgePixels=!0,Le.push(Re)}if(H!==1){const Re=new Ro;Re.brightness(H,!1),Le.push(Re)}if(b.chromaKey&&b.chromaKey.enabled){const Re=new ft({uKeyColor:{value:[0,1,0],type:"vec3<f32>"},uSimilarity:{value:.1,type:"f32"},uSpill:{value:0,type:"f32"}}),nt=Fk(b.chromaKey.color);nt&&(Re.uniforms.uKeyColor[0]=nt.r/255,Re.uniforms.uKeyColor[1]=nt.g/255,Re.uniforms.uKeyColor[2]=nt.b/255),Re.uniforms.uSimilarity=b.chromaKey.similarity,Re.uniforms.uSpill=b.chromaKey.spill;const Bt=new ge({glProgram:new ue({vertex:qb,fragment:Xk,name:"ChromaKeyShader"}),resources:{chromaUniforms:Re}});Le.push(Bt)}oe.filters=Le;const ke=A.borderRadius||0;let Ae=null;ke>0&&(Ae=new Ze,Ae.roundRect(-$/2,-K/2,$,K,Math.min(ke,$/2,K/2)),Ae.fill({color:16777215,alpha:1}),te.addChild(Ae),te.mask=Ae);const je=A.stroke;let Fe=null;if(je&&je.width>0){Fe=new Ze;const Re=yt(je.color)??16777215;if(Fe.setStrokeStyle({width:je.width,color:Re,alignment:1}),ke>0){const nt=Math.min(ke,$/2,K/2);Fe.roundRect(-$/2,-K/2,$,K,nt)}else Fe.rect(-$/2,-K/2,$,K);Fe.stroke(),te.addChild(Fe)}const at=A.dropShadow;let it=null;if(at&&(at.blur>0||at.distance>0)){it=new Ze;const Re=yt(at.color)??0,nt=at.alpha??.5,Bt=at.distance??0,Vt=at.angle??0,Qe=Math.cos(Vt)*Bt,Oe=Math.sin(Vt)*Bt;if(ke>0){const Ri=Math.min(ke,$/2,K/2);it.roundRect(-$/2+Qe,-K/2+Oe,$,K,Ri)}else it.rect(-$/2+Qe,-K/2+Oe,$,K);it.fill({color:Re,alpha:nt}),oe.addChildAt(it,0)}e.renderer.render({container:oe,target:P,clear:!0}),T instanceof Q||te.texture.destroy(!0),Fe&&Fe.destroy(),Ae&&Ae.destroy(),it&&it.destroy();for(const Re of be)Re.destroy();te.destroy(),oe.destroy()};let p=null,m=null,g=null;n&&e!=null&&(p=new Pe,m=new Pe,g=new Pe,m.sortableChildren=!0,g.sortableChildren=!0,e.stage.addChild(m),e.stage.addChild(g),p.visible=!1,e.stage.addChild(p));const v=[...t].sort((b,T)=>b.zIndex-T.zIndex);return{render:async b=>{const T=[];let P=!1,A=!1;const E=new Map,_=async(S,I)=>{if(E.has(S))return E.get(S);const M=await S.getFrame(I);return E.set(S,M),M};for(const S of a.values())S.visible=!1;for(const S of v){if(i.aborted)break;if(b<S.display.from||S.expired){if(n&&e!=null){const D=s.get(S);D&&await D.updateFrame(null)}continue}const I=b-S.display.from,M=I*S.playbackRate;S.animate(M);const{video:O,audio:U,done:X}=await _(S,I);if(T.push(U),n&&e!=null&&m!=null){if(S instanceof Bi){const k=t.find(H=>H.id===S.fromClipId),Y=t.find(H=>H.id===S.toClipId);if(k&&Y){const H=b-S.display.from;if(H>=S.duration){S.expired=!0;const $=a.get(S.id);$&&($.visible=!1)}else{const $=await d(k,b,_),K=await d(Y,b,_);if($&&K){const we=Math.min(Math.max(H/S.duration,0),1);f(k,$,l),f(Y,K,u);let Ie=o.get(S.id);Ie||(Ie=c1({name:S.transitionEffect.key,renderer:e.renderer}),o.set(S.id,Ie));const ve=Ie.render({width:e.renderer.width,height:e.renderer.height,from:l,to:u,progress:we});let G=a.get(S.id);G||(G=new Je,G.label=`TransitionSprite_${S.id}`,a.set(S.id,G),m.addChild(G)),G.texture=ve,G.visible=!0,G.x=0,G.y=0,G.width=e.renderer.width,G.height=e.renderer.height,G.anchor.set(0,0),G.zIndex=S.zIndex,A=!0;const ne=s.get(k);if(ne){const te=ne.getRoot();te&&(te.visible=!1)}const oe=s.get(Y);if(oe){const te=oe.getRoot();te&&(te.visible=!1)}continue}}}}let D=s.get(S);if(D==null&&O!=null&&(D=new R4(e,S,m),s.set(S,D)),D!=null){const k=D.getRoot();O!=null?(A=!0,k&&(k.visible=!0),await D.updateFrame(O)):(k&&(k.visible=!1),await D.updateFrame(null)),D.updateTransforms()}}if(S.duration>0&&I>S.duration||X){if(S.main&&(P=!0),S.expired=!0,n){const D=s.get(S);if(D!=null){const k=D.getRoot();k&&(k.visible=!1)}}}else if(n){const D=s.get(S);D?.updateTransforms()}}if(n&&e!=null&&p!=null&&m!=null&&g!=null){const S=[];for(const I of t)if(I instanceof Qi&&b>=I.display.from&&b<I.display.from+I.duration&&S.push({id:I.id,key:I.effect.key,startTime:I.display.from,duration:I.duration,zIndex:I.zIndex,values:I.effect.values}),I.effects&&I.effects.length>0)for(const M of I.effects)b>=M.startTime&&b<M.startTime+M.duration&&S.push({...M,zIndex:I.zIndex});S.sort((I,M)=>I.zIndex-M.zIndex),g.removeChildren();for(const I of s.values()){const M=I.getRoot();M&&M.parent!==m&&(M.parent&&M.parent.removeChild(M),m.addChild(M))}if(S.length>0){const I=e.renderer.width,M=e.renderer.height;let O=null;const U=new Set,X=[];for(const D of S){const{key:k,startTime:Y,duration:H,id:$,zIndex:K}=D,we=b-Y,Ie=H>0?Math.min(Math.max(we/H,0),1):0,ve=t.some(G=>G.id===$&&G instanceof Qi);if(p.removeChildren(),O){const G=new Je(O);G.width=I,G.height=M,p.addChild(G)}for(const G of t){if(U.has(G.id))continue;let ne=!1;if(ve?ne=G.id!==$&&G.zIndex<K:ne=!!G.effects&&G.effects.some(oe=>oe.id===$),ne){const oe=s.get(G);if(oe){const be=oe.getRoot();be&&(be.parent&&be.parent.removeChild(be),p.addChild(be),U.add(G.id))}const te=a.get(G.id);te&&(te.parent&&te.parent.removeChild(te),p.addChild(te),U.add(G.id))}}if(p.children.length>0){let G=h.get($);if(!G)try{const ne=await l1({name:k,renderer:e.renderer,values:D.values});ne&&ne.filter&&(G={filter:ne.filter,render:ne.render},h.set($,G))}catch(ne){console.warn("Failed to create effect",k,ne)}if(G){const{filter:ne,render:oe}=G;ne.resources&&ne.resources.effectUniforms&&(ne.resources.effectUniforms.uniforms.uTime=Ie);const te=Ot.create({width:I,height:M});X.push(te),p.visible=!0,e.renderer.render({container:p,target:te,clear:!0}),p.visible=!1,oe&&(O=oe({canvasTexture:te,progress:Ie,width:I,height:M}))}}}if(O){const D=new Je(O);D.width=I,D.height=M,g.addChild(D)}for(const D of X)D.destroy(!0)}}return n&&e!=null&&e.render(),{audios:T,mainSprDone:P,hasVideo:A}},cleanup:()=>{l&&l.destroy(!0),u&&u.destroy(!0),c&&c.destroy(!0);for(const b of a.values())b.destroy();a.clear(),o.clear(),p&&p.destroy({children:!0}),m&&m.destroy({children:!0}),g&&g.destroy({children:!0}),s.forEach(b=>{b.destroy()}),s.clear()}}}function xte(r){const{canvas:e,outputAudio:t,muxer:i,hasVideoTrack:n,timeSlice:s}=r;let o=0;const a=Math.floor(3*r.fps),l=yte(1024);return(u,c,h)=>{if(t!==!1)for(const d of l(u,c))i.encodeAudio(d);if(n&&h)try{const d=new VideoFrame(e,{duration:s,timestamp:u});i.encodeVideo(d,{keyFrame:o%a===0}),o+=1}catch(d){console.warn("Failed to create VideoFrame from canvas, skipping frame:",d)}}}function yte(r){const e=r*rt.channelCount,t=new Float32Array(e*3);let i=0,n=0;const s=r/rt.sampleRate*1e6,o=new Float32Array(e),a=l=>{let u=0;const c=Math.floor(i/e),h=[];for(let d=0;d<c;d++)h.push(new AudioData({timestamp:n,numberOfChannels:rt.channelCount,numberOfFrames:r,sampleRate:rt.sampleRate,format:"f32",data:t.subarray(u,u+e)})),u+=e,n+=s;for(t.set(t.subarray(u,i),0),i-=u;l-n>s;)h.push(new AudioData({timestamp:n,numberOfChannels:rt.channelCount,numberOfFrames:r,sampleRate:rt.sampleRate,format:"f32",data:o})),n+=s;return h};return(l,u)=>{const c=Math.max(...u.map(h=>h[0]?.length??0));for(let h=0;h<c;h++){let d=0,f=0;for(let p=0;p<u.length;p++){const m=u[p][0]?.[h]??0,g=u[p][1]?.[h]??m;d+=m,f+=g}t[i]=d,t[i+1]=f,i+=2}return a(l)}}class bte extends Ze{constructor(){super(),this.eventMode="static",this.cursor="move"}draw(e,t=1){const n=1.5*t;this.clear(),this.setStrokeStyle({width:n,color:165063}).rect(e.x,e.y,e.width,e.height).stroke(),this.hitArea=e}}class Ji extends Ze{#e=!1;handle;cursor;callbacks;constructor(e,t,i){super(),this.handle=e,this.cursor=t,this.callbacks=i,this.eventMode="static",this.#l(),this.on("pointerdown",this.#r),this.on("globalpointermove",this.#n),this.on("pointerup",this.#u),this.on("pointerupoutside",this.#u)}#l(){this.clear();const e=165063;if(this.handle==="rot")this.circle(0,0,8),this.fill({color:"#ffffff"}),this.stroke({width:1,color:13421772}),this.moveTo(0,-4),this.arc(0,0,4,-Math.PI/2,Math.PI,!1),this.stroke({width:1,color:0}),this.moveTo(0,-8),this.lineTo(-3,-5),this.lineTo(0,-2),this.stroke({width:1,color:0,cap:"round",join:"round"}),this.hitArea=new sl(0,0,24);else if(["ml","mr","mt","mb"].includes(this.handle)){const t=this.handle==="ml"||this.handle==="mr",i=t?6:24,n=t?24:6;this.roundRect(-i/2,-n/2,i,n,3),this.fill({color:"#ffffff"}),this.stroke({width:1,color:e}),this.hitArea=new he(-15,-15,30,30)}else this.rect(-4,-4,8,8),this.fill({color:"#ffffff"}),this.stroke({width:1,color:e}),this.hitArea=new he(-15,-15,30,30)}#r=e=>{this.#e=!0,this.cursor="grabbing",this.callbacks.beginDrag(this.handle,e.global)};#n=e=>{this.#e&&this.callbacks.updateDrag(this.handle,e.global)};#u=e=>{this.#e&&(this.#e=!1,this.cursor="pointer",this.callbacks.endDrag())}}class Eh{constructor(e,t,i=1){this.artboardWidth=e,this.artboardHeight=t,this.scale=i}static SNAP_THRESHOLD=5;updateContext(e,t,i){this.artboardWidth=e,this.artboardHeight=t,this.scale=i}snapMove(e){const t=[];let i=0,n=0;const s=Eh.SNAP_THRESHOLD/this.scale,o=[{value:this.artboardWidth/2,label:"center"},{value:0,label:"start"},{value:this.artboardWidth,label:"end"}],a=[{value:e.x,type:"start"},{value:e.x+e.width/2,type:"center"},{value:e.x+e.width,type:"end"}];let l=!1;for(const d of o){if(l)break;for(const f of a){const p=d.value-f.value;if(Math.abs(p)<s){i=p,l=!0,t.push({type:"vertical",position:d.value,start:Math.min(0,e.y),end:Math.max(this.artboardHeight,e.y+e.height)});break}}}const u=[{value:this.artboardHeight/2,label:"center"},{value:0,label:"start"},{value:this.artboardHeight,label:"end"}],c=[{value:e.y,type:"start"},{value:e.y+e.height/2,type:"center"},{value:e.y+e.height,type:"end"}];let h=!1;for(const d of u){if(h)break;for(const f of c){const p=d.value-f.value;if(Math.abs(p)<s){n=p,h=!0,t.push({type:"horizontal",position:d.value,start:Math.min(0,e.x),end:Math.max(this.artboardWidth,e.x+e.width)});break}}}return{dx:i,dy:n,guides:t}}snapResize(e){const t=e.clone(),{dx:i,dy:n,guides:s}=this.snapMove(t);return t.x+=i,t.y+=n,{corrected:t,guides:s}}snapPoint(e){const t=Eh.SNAP_THRESHOLD/this.scale,i=[],n=e.clone(),s=[0,this.artboardWidth/2,this.artboardWidth];for(const a of s)if(Math.abs(a-e.x)<t){n.x=a,i.push({type:"vertical",position:a,start:0,end:this.artboardHeight});break}const o=[0,this.artboardHeight/2,this.artboardHeight];for(const a of o)if(Math.abs(a-e.y)<t){n.y=a,i.push({type:"horizontal",position:a,start:0,end:this.artboardWidth});break}return{p:n,guides:i}}}const U4={delta:new ae};class z4 extends Pe{group;wireframe=new bte;selectionOutlines=new Ze;isDragging=!1;lastPointer=new me;activeHandle=null;#e;#l=new Map;#r=new me;#n=0;#u=0;#c=new he;#i=new me;#s=new he;#t=[new me,new me,new me,new me];#o=1;#a=1;#h;#d=new Ze;#m=new me;opts;constructor(e){super(),this.opts=e,this.group=e.group,this.eventMode="static",this.#h=new Eh(e.artboardWidth??1920,e.artboardHeight??1080),this.addChild(this.#d);const t={beginDrag:(i,n)=>this.#A(i,n),updateDrag:(i,n)=>this.#E(i,n),endDrag:()=>this.#v()};this.#e={tl:new Ji("tl","nwse-resize",t),tr:new Ji("tr","nesw-resize",t),bl:new Ji("bl","nesw-resize",t),br:new Ji("br","nwse-resize",t),ml:new Ji("ml","ew-resize",t),mr:new Ji("mr","ew-resize",t),mt:new Ji("mt","ns-resize",t),mb:new Ji("mb","ns-resize",t),rot:new Ji("rot","crosshair",{beginDrag:(i,n)=>this.#B(n),updateDrag:(i,n)=>this.#k(n),endDrag:()=>this.#v()})},this.addChild(this.selectionOutlines,this.wireframe,...Object.values(this.#e)),this.#w(),this.visible=!1,Ft.shared.addOnce(()=>{this.showImmediate()})}#x=!1;showImmediate(){this.#x||this.destroyed||!this.parent||(this.#f(),this.visible=!0,this.#x=!0)}#w(){this.on("pointerdown",this.#S),this.on("pointerup",this.#y),this.on("pointerupoutside",this.#y),this.on("globalpointermove",this.#T)}#f(){if(this.group.length===1){const e=this.group[0];this.#n=e.rotation;const t=this.#g(e);let i,n;this.opts.clip?(i=this.opts.clip.width,n=this.opts.clip.height):(i=t.width,n=t.height);const s=e.toGlobal(new me(0,0));this.#r.set(s.x,s.y),this.#s.copyFrom(new he(-i/2,-n/2,i,n))}else{let e=1/0,t=1/0,i=-1/0,n=-1/0;if(this.parent)for(const u of this.group){const c=this.#g(u);this.#t[0].set(c.x,c.y),this.#t[1].set(c.x+c.width,c.y),this.#t[2].set(c.x+c.width,c.y+c.height),this.#t[3].set(c.x,c.y+c.height);for(const h of this.#t)u.toGlobal(h,h),this.toLocal(h,void 0,h),e=Math.min(e,h.x),t=Math.min(t,h.y),i=Math.max(i,h.x),n=Math.max(n,h.y)}const s=i-e,o=n-t,a=e+s/2,l=t+o/2;if(this.#s.copyFrom(new he(-s/2,-o/2,s,o)),this.parent){const u=this.toGlobal(new me(a,l));this.#r.set(u.x,u.y)}}this.#p()}#g(e){let t=null;const i=u=>{if(u.label==="MainSprite"&&u instanceof Je)return u;for(const c of u.children)if(c instanceof Pe){const h=i(c);if(h)return h}return null};if(t=i(e),t){const u=t.getLocalBounds(),c=t.localTransform.clone(),h=c.apply(new me(u.x,u.y)),d=c.apply(new me(u.x+u.width,u.y)),f=c.apply(new me(u.x+u.width,u.y+u.height)),p=c.apply(new me(u.x,u.y+u.height)),m=Math.min(h.x,d.x,f.x,p.x),g=Math.max(h.x,d.x,f.x,p.x),v=Math.min(h.y,d.y,f.y,p.y),x=Math.max(h.y,d.y,f.y,p.y);return new he(m,v,g-m,x-v)}let n=1/0,s=1/0,o=-1/0,a=-1/0;const l=e.children.filter(u=>u.label!=="ShadowContainer"&&u.label!=="AnimationContainer");if(l.length===0&&e.children.length>0){const u=e.children.find(c=>c.label==="AnimationContainer");if(u){const c=u.getLocalBounds();return new he(c.minX,c.minY,c.maxX-c.minX,c.maxY-c.minY)}}for(const u of l){const c=u.getBounds(),h=e.toLocal(new me(c.minX,c.minY)),d=e.toLocal(new me(c.maxX,c.maxY));n=Math.min(n,h.x,d.x),s=Math.min(s,h.y,d.y),o=Math.max(o,h.x,d.x),a=Math.max(a,h.y,d.y)}if(n===1/0){const u=e.getLocalBounds();return new he(u.minX,u.minY,u.maxX-u.minX,u.maxY-u.minY)}return new he(n,s,o-n,a-s)}updateBounds(){this.#f()}#S=e=>{e.button===0&&(this.opts.locked||(this.#f(),this.#m.copyFrom(this.#r),this.isDragging=!0,this.lastPointer.copyFrom(e.global),this.cursor="grabbing"))};#y=()=>{this.isDragging&&this.#v(),this.cursor="default"};#T=e=>{if(!this.isDragging||this.activeHandle||!this.parent)return;const{moveDx:t,moveDy:i,newPivotWorld:n}=this.#C(e);for(const s of this.group)s.x+=t,s.y+=i;this.#r.copyFrom(n),this.lastPointer.copyFrom(e.global),this.#p(),this.emit("transforming")};#C(e){const t=Math.abs(this.parent.worldTransform.a);this.#h.updateContext(this.opts.artboardWidth??1920,this.opts.artboardHeight??1080,t);const i=e.global.x-this.lastPointer.x,n=e.global.y-this.lastPointer.y;this.#m.x+=i,this.#m.y+=n;const s=this.parent.toLocal(this.#m),o=new he(s.x+this.#s.x,s.y+this.#s.y,this.#s.width,this.#s.height),{dx:a,dy:l,guides:u}=this.#h.snapMove(o);this.#b(u,t);const c=s.x+a,h=s.y+l,d=this.parent.toLocal(this.#r),f=c-d.x,p=h-d.y,m=this.parent.toGlobal(new me(c,h));return{moveDx:f,moveDy:p,newPivotWorld:m}}#A(e,t){this.#f(),this.isDragging=!0,this.activeHandle=e,this.#l.clear();for(const i of this.group)this.#l.set(i,i.localTransform.clone());this.rotation=this.#n,this.#c.copyFrom(this.#s),this.#F(e)}#E(e,t){this.#P(e,t)}async#P(e,t){const{proposed:i,sx:n,sy:s,pivotWorld:o}=await this.#I(e,t),a=this.opts.clip&&this.opts.clip.type==="Text",l=this.opts.clip&&this.opts.clip.type==="Caption";a||l?this.emit("textClipResize",{handle:e,newWidth:i.width,newHeight:i.height,pivotWorld:o,proposed:i,sx:n,sy:s}):this.#_(this.#D(o,this.#n,n,s)),this.#s.copyFrom(i),this.#p(),this.emit("transforming")}async#I(e,t){const i=this.#i,n=this.#M(e,this.toLocal(t),i),s=this.parent?Math.abs(this.parent.worldTransform.a):1;this.#h.updateContext(this.opts.artboardWidth??1920,this.opts.artboardHeight??1080,s);const{dx:o,dy:a,guides:l}=this.#h.snapMove(n);n.x+=o,n.y+=a,this.#b(l,s);const u=n.width/this.#c.width,c=n.height/this.#c.height,h=this.toGlobal(i);return{proposed:n,sx:u,sy:c,pivotWorld:h}}#B(e){this.#f(),this.isDragging=!0,this.activeHandle="rot",this.#l.clear();for(const t of this.group)this.#l.set(t,t.localTransform.clone());this.#u=Math.atan2(e.y-this.#r.y,e.x-this.#r.x)}#k(e){const i=Math.atan2(e.y-this.#r.y,e.x-this.#r.x)-this.#u,n=this.#n+i;this.#_(this.#O(this.#r,i)),this.rotation=n,this.#p(n),this.emit("transforming")}#v(){this.isDragging=!1,this.#n=this.rotation,this.activeHandle=null,this.#d.clear(),this.#p(this.#n),this.emit("transformEnd")}#b(e,t){if(this.#d.clear(),!(!e.length||!this.parent)){this.#d.stroke({width:1/t,color:4774907});for(const i of e){let n,s;i.type==="vertical"?(n=new me(i.position,i.start),s=new me(i.position,i.end)):(n=new me(i.start,i.position),s=new me(i.end,i.position)),this.toLocal(n,this.parent,n),this.toLocal(s,this.parent,s),this.#d.moveTo(n.x,n.y).lineTo(s.x,s.y).stroke({width:1/t,color:4774907})}}}#p(e=this.#n){this.parent&&this.position.copyFrom(this.parent.toLocal(this.#r)),this.rotation=e;const i=1/((this.parent?Math.abs(this.parent.worldTransform.a):1)||1),n=this.#s;this.wireframe.draw(n,i);const s=n.x+n.width/2,o=n.y+n.height/2,l=this.opts.locked?[]:this.opts.clip?.getVisibleHandles?.()??["tl","tr","bl","br","ml","mr","mt","mb","rot"],u=[this.#e.tl,this.#e.tr,this.#e.bl,this.#e.br,this.#e.ml,this.#e.mr,this.#e.mt,this.#e.mb,this.#e.rot];for(const c of u)c.scale.set(i);this.#e.tl.visible=l.includes("tl"),this.#e.tr.visible=l.includes("tr"),this.#e.bl.visible=l.includes("bl"),this.#e.br.visible=l.includes("br"),this.#e.ml.visible=l.includes("ml"),this.#e.mr.visible=l.includes("mr"),this.#e.mt.visible=l.includes("mt"),this.#e.mb.visible=l.includes("mb"),this.#e.rot.visible=l.includes("rot"),this.#e.tl.position.set(n.x,n.y),this.#e.tr.position.set(n.x+n.width,n.y),this.#e.bl.position.set(n.x,n.y+n.height),this.#e.br.position.set(n.x+n.width,n.y+n.height),this.#e.ml.position.set(n.x,o),this.#e.mr.position.set(n.x+n.width,o),this.#e.mt.position.set(s,n.y),this.#e.mb.position.set(s,n.y+n.height),this.#e.rot.position.set(s,n.y-30*i),this.#R(i)}#R(e){if(this.selectionOutlines.clear(),this.group.length<=1||!this.parent)return;const t={width:1*e,color:43775,alpha:1};for(const i of this.group){const n=this.#g(i);this.#t[0].set(n.x,n.y),this.#t[1].set(n.x+n.width,n.y),this.#t[2].set(n.x+n.width,n.y+n.height),this.#t[3].set(n.x,n.y+n.height);for(const s of this.#t)i.toGlobal(s,s),this.toLocal(s,void 0,s);this.selectionOutlines.moveTo(this.#t[0].x,this.#t[0].y).lineTo(this.#t[1].x,this.#t[1].y).lineTo(this.#t[2].x,this.#t[2].y).lineTo(this.#t[3].x,this.#t[3].y).closePath().stroke(t)}}#F(e){const t=this.#c;if(this.opts.centeredScaling){this.#i.set(t.x+t.width/2,t.y+t.height/2);return}e==="tl"?this.#i.set(t.x+t.width,t.y+t.height):e==="tr"?this.#i.set(t.x,t.y+t.height):e==="bl"?this.#i.set(t.x+t.width,t.y):e==="br"?this.#i.set(t.x,t.y):e==="ml"?this.#i.set(t.x+t.width,t.y+t.height/2):e==="mr"?this.#i.set(t.x,t.y+t.height/2):e==="mt"?this.#i.set(t.x+t.width/2,t.y+t.height):e==="mb"&&this.#i.set(t.x+t.width/2,t.y)}#M(e,t,i){if(this.opts.centeredScaling){const s=Math.max(this.#o,Math.abs(t.x-i.x)*2),o=Math.max(this.#a,Math.abs(t.y-i.y)*2);return new he(i.x-s/2,i.y-o/2,s,o)}if(e==="tl"){const s=Math.min(t.x,i.x-this.#o),o=Math.min(t.y,i.y-this.#a);return new he(s,o,i.x-s,i.y-o)}if(e==="tr"){const s=Math.max(t.x,i.x+this.#o),o=Math.min(t.y,i.y-this.#a);return new he(i.x,o,s-i.x,i.y-o)}if(e==="bl"){const s=Math.min(t.x,i.x-this.#o),o=Math.max(t.y,i.y+this.#a);return new he(s,i.y,i.x-s,o-i.y)}if(e==="br"){const s=Math.max(t.x,i.x+this.#o),o=Math.max(t.y,i.y+this.#a);return new he(i.x,i.y,s-i.x,o-i.y)}const n=this.#c;if(e==="ml"){const s=Math.min(t.x,i.x-this.#o);return new he(s,n.y,i.x-s,n.height)}if(e==="mr"){const s=Math.max(t.x,i.x+this.#o);return new he(i.x,n.y,s-i.x,n.height)}if(e==="mt"){const s=Math.min(t.y,i.y-this.#a);return new he(n.x,s,n.width,i.y-s)}if(e==="mb"){const s=Math.max(t.y,i.y+this.#a);return new he(n.x,i.y,n.width,s-i.y)}return new he(i.x,i.y,this.#o,this.#a)}#D(e,t,i,n){return U4.delta.identity().translate(-e.x,-e.y).rotate(-t).scale(i,n).rotate(t).translate(e.x,e.y)}#O(e,t){return U4.delta.identity().translate(-e.x,-e.y).rotate(t).translate(e.x,e.y)}#_(e){for(const t of this.group){const i=this.#l.get(t),n=t.parent;if(!i||!n)continue;const s=n.worldTransform.clone().invert(),o=n.worldTransform.clone().append(i),a=e.clone().append(o),l=s.clone().append(a);t.setFromMatrix(l)}}}class _te{constructor(e){this.studio=e}selectedClips=new Set;activeTransformer=null;interactiveClips=new Set;selectionGraphics=null;isDragSelecting=!1;dragSelectionStart=new me;isUpdatingTextRealtime=!1;textClipResizedWidth=null;textClipResizeHandle=null;textClipResizedSx=null;textClipResizedSy=null;lastPointerDownTime=0;lastPointerDownClip=null;init(e,t){this.selectionGraphics=new Ze,this.selectionGraphics.visible=!1,this.selectionGraphics.zIndex=1e3,t.addChild(this.selectionGraphics),e.stage.eventMode="static",e.stage.hitArea=e.screen,e.stage.on("pointerdown",i=>this.onStagePointerDown(i)),e.stage.on("globalpointermove",i=>this.onStagePointerMove(i)),e.stage.on("pointerup",()=>this.onStagePointerUp()),e.stage.on("pointerupoutside",()=>this.onStagePointerUp())}onStagePointerDown(e){e.target===this.studio.pixiApp?.stage&&(e.shiftKey||this.deselectClip(),this.isDragSelecting=!0,this.studio.artboard?.toLocal(e.global,void 0,this.dragSelectionStart),this.selectionGraphics&&(this.selectionGraphics.clear(),this.selectionGraphics.visible=!0))}onStagePointerMove(e){if(this.isDragSelecting&&this.selectionGraphics&&this.studio.artboard){const t=this.studio.artboard.toLocal(e.global),i=Math.min(this.dragSelectionStart.x,t.x),n=Math.min(this.dragSelectionStart.y,t.y),s=Math.abs(t.x-this.dragSelectionStart.x),o=Math.abs(t.y-this.dragSelectionStart.y);this.selectionGraphics.clear(),this.selectionGraphics.rect(i,n,s,o).fill({color:703971,alpha:.3}),this.selectionGraphics.rect(i,n,s,o).stroke({width:2,color:703971});const a=this.selectionGraphics.getBounds(),l=new he(a.x,a.y,a.width,a.height);if(l.width>2||l.height>2){const u=this.getIntersectingClips(l);this.updatePreviewSelection(u)}else this.selectedClips.size===0&&this.destroyTransformer();this.studio.pixiApp?.render()}}onStagePointerUp(){if(this.isDragSelecting&&this.selectionGraphics&&this.studio.artboard){const e=this.selectionGraphics.getBounds(),t=new he(e.x,e.y,e.width,e.height);if(t.width>2||t.height>2){const i=this.getIntersectingClips(t);if(i.length>0){for(const n of i)this.selectedClips.add(n);this.recreateTransformer(),this.studio.emit("selection:created",{selected:Array.from(this.selectedClips)})}else this.selectedClips.size===0&&this.destroyTransformer()}else this.selectedClips.size===0&&this.destroyTransformer();this.selectionGraphics.clear(),this.selectionGraphics.visible=!1,this.isDragSelecting=!1,this.studio.pixiApp?.render()}}getIntersectingClips(e){const t=[];for(const i of this.studio.clips){const n=this.studio.spriteRenderers.get(i);if(!n)continue;const s=n.getRoot();if(!s||!s.visible)continue;const o=s.getBounds();e.x<o.x+o.width&&e.x+e.width>o.x&&e.y<o.y+o.height&&e.y+e.height>o.y&&t.push(i)}return t}updatePreviewSelection(e){if(e.length===0){this.selectedClips.size===0?this.destroyTransformer():this.recreateTransformer();return}const t=new Set(e),i=[];let n=null;for(const s of t){const o=this.studio.spriteRenderers.get(s);if(o==null)continue;const a=o.getRoot();a!=null&&(i.push(a),t.size===1&&(n=s))}if(i.length===0){this.selectedClips.size===0&&this.destroyTransformer();return}this.activeTransformer?(this.activeTransformer.group=i,this.activeTransformer.opts.group=i,this.activeTransformer.opts.clip=n,this.activeTransformer.updateBounds(),this.activeTransformer.showImmediate()):(this.activeTransformer=new z4({group:i,clip:n,artboardWidth:this.studio.opts.width,artboardHeight:this.studio.opts.height}),this.studio.artboard?.addChild(this.activeTransformer),this.activeTransformer.showImmediate()),this.studio.pixiApp?.render()}setupSpriteInteractivity(e){if(this.interactiveClips.has(e))return;const t=this.studio.spriteRenderers.get(e);if(t==null)return;const i=t.getRoot();i!=null&&(i.eventMode="static",i.cursor="pointer",i.on("pointerdown",n=>{const s=Date.now(),o=this.getTopmostClipAtPoint(n.global);o===e&&o===this.lastPointerDownClip&&s-this.lastPointerDownTime<350&&(o.type==="Text"||o.type==="Caption")&&this.studio.emit("clip:dblclick",{clip:o}),this.lastPointerDownTime=s,this.lastPointerDownClip=o,o&&this.selectClip(o,n.shiftKey)}),this.interactiveClips.add(e))}getTopmostClipAtPoint(e){if(!this.studio.pixiApp)return null;let t=null,i=-1/0;for(const n of this.interactiveClips){const s=this.studio.spriteRenderers.get(n);if(!s)continue;const o=s.getRoot();if(!o||!o.visible)continue;const a=o.toLocal(e),l=o.getLocalBounds();a.x>=l.minX&&a.x<=l.maxX&&a.y>=l.minY&&a.y<=l.maxY&&n.zIndex>i&&(i=n.zIndex,t=n)}return t}selectClip(e,t=!1){if(!(this.studio.destroyed||this.studio.pixiApp==null)){if(t||this.deselectClip(),t&&this.selectedClips.has(e)){this.selectedClips.delete(e),this.recreateTransformer(),this.studio.emit("selection:updated",{selected:Array.from(this.selectedClips)}),this.studio.pixiApp?.render();return}this.selectedClips.add(e),this.recreateTransformer(),t?this.studio.emit("selection:updated",{selected:Array.from(this.selectedClips)}):this.studio.emit("selection:created",{selected:Array.from(this.selectedClips)}),this.studio.pixiApp?.render()}}selectClipsByIds(e){const t=this.studio.clips.filter(i=>e.includes(i.id));this.setSelection(t)}setSelection(e){if(!(this.studio.destroyed||this.studio.pixiApp==null)&&!(this.selectedClips.size===e.length&&e.every(t=>this.selectedClips.has(t)))){for(const t of this.selectedClips)this.syncSpriteToClipProperties(t);this.destroyTransformer(),this.selectedClips.clear();for(const t of e)this.selectedClips.add(t);this.selectedClips.size>0?(this.createTransformer(),this.studio.emit("selection:updated",{selected:Array.from(this.selectedClips)})):this.studio.emit("selection:cleared",{deselected:[]}),this.studio.pixiApp?.render()}}deselectClip(){if(this.selectedClips.size>0)for(const t of this.selectedClips)this.syncSpriteToClipProperties(t);this.destroyTransformer();const e=Array.from(this.selectedClips);this.selectedClips.clear(),e.length>0&&this.studio.emit("selection:cleared",{deselected:e}),this.studio.pixiApp?.render()}async move(e,t){if(this.selectedClips.size===0)return;const i=[];for(const n of this.selectedClips)i.push({id:n.id,updates:{left:(n.left??0)+e,top:(n.top??0)+t}});await this.studio.updateClips(i),this.activeTransformer&&this.activeTransformer.updateBounds()}clear(){this.deselectClip(),this.interactiveClips.clear()}recreateTransformer(){this.destroyTransformer(),this.selectedClips.size>0&&this.createTransformer()}destroyTransformer(){this.activeTransformer!=null&&(this.activeTransformer.parent!=null&&this.activeTransformer.parent.removeChild(this.activeTransformer),this.activeTransformer.destroy(),this.activeTransformer=null)}createTransformer(){if(this.studio.destroyed||this.studio.artboard==null||this.selectedClips.size===0)return;const e=[];let t=null;for(const s of this.selectedClips){const o=this.studio.spriteRenderers.get(s);if(o==null)continue;const a=o.getRoot();a!=null&&(e.push(a),this.selectedClips.size===1&&(t=s))}if(e.length===0){console.warn("Cannot create transformer: no sprites found");return}const i=t?.locked??!1;this.activeTransformer=new z4({group:e,clip:t,artboardWidth:this.studio.opts.width,artboardHeight:this.studio.opts.height,locked:i});let n=null;this.activeTransformer.on("transforming",()=>{n===null&&(n=requestAnimationFrame(()=>{n=null,this.syncSelectedClipsTransformsRealtime(),this.studio.pixiApp?.render()}))}),this.activeTransformer.on("textClipResize",s=>{this.textClipResizedWidth=s.newWidth,this.textClipResizeHandle=s.handle,this.textClipResizedSx=s.sx,this.textClipResizedSy=s.sy}),this.activeTransformer.on("transformEnd",async()=>{n!==null&&(cancelAnimationFrame(n),n=null),await this.syncSelectedClipsTransforms();for(const s of this.selectedClips)this.studio.emit("clip:updated",{clip:s});this.studio.emit("transform:end",{transformer:this.activeTransformer})}),this.activeTransformer.on("pointerdown",s=>{if(s.button!==0)return;this.studio.emit("transform:start",{transformer:this.activeTransformer});const o=this.getTopmostClipAtPoint(s.global),a=Date.now();o&&o===this.lastPointerDownClip&&a-this.lastPointerDownTime<350&&(o.type==="Text"||o.type==="Caption")&&this.studio.emit("clip:dblclick",{clip:o}),this.lastPointerDownTime=a,this.lastPointerDownClip=o,o&&!this.selectedClips.has(o)&&(this.selectClip(o,s.shiftKey),s.stopPropagation())}),this.studio.artboard.addChild(this.activeTransformer),this.activeTransformer.showImmediate(),this.studio.pixiApp?.render()}async syncSelectedClipsTransformsRealtime(){if(this.selectedClips.size===0||this.activeTransformer==null)return;const e=this.activeTransformer.activeHandle;if(e===null){for(const t of this.selectedClips){const i=this.studio.spriteRenderers.get(t);if(i==null)continue;const n=i.getRoot(),s=i.getSprite();if(n==null||s==null||s.texture==null)continue;const o=Math.abs(n.scale.x*s.scale.x)*s.texture.width,a=Math.abs(n.scale.y*s.scale.y)*s.texture.height;t.left=n.x-o/2,t.top=n.y-a/2}return}if(e==="mr"||e==="ml"){if(this.isUpdatingTextRealtime)return;this.isUpdatingTextRealtime=!0;try{for(const t of this.selectedClips){if(!(t instanceof Ki))continue;const i=this.studio.spriteRenderers.get(t);if(i==null)continue;const n=i.getRoot(),s=i.getSprite();if(n==null||s==null||s.texture==null)continue;const o=Math.abs(n.scale.x*s.scale.x);if(o===1)continue;const a=t.left,l=t.top,u=t.width,c=s.texture.width,h=o*c;await t.updateStyle({wordWrap:!0,wordWrapWidth:h});const d=await t.getTexture();d&&(await i.updateFrame(d),s.scale.set(1,1),n.scale.set(1,1),e==="ml"?t.left=a+u-t.width:t.left=a,t.top=l,n.x=t.left+t.width/2,n.y=t.top+t.height/2,this.activeTransformer.updateBounds())}}finally{this.isUpdatingTextRealtime=!1}}}async syncSelectedClipsTransforms(){if(!(this.selectedClips.size===0||this.activeTransformer==null)){for(const e of this.selectedClips){const t=this.studio.spriteRenderers.get(e);if(t==null)continue;const i=t.getRoot(),n=t.getSprite();if(i==null||n==null||n.texture==null)continue;const s=n.texture.width,o=n.texture.height,a=Math.abs(i.scale.x*n.scale.x)*s,l=Math.abs(i.scale.y*n.scale.y)*o,u=(e instanceof Ki||e instanceof On)&&this.textClipResizedWidth!==null?this.textClipResizedWidth:a,c=e.width,d=(e.style?.fontSize??16)*Math.max(this.textClipResizedSx||1,this.textClipResizedSy||1);let f=i.x;if((e instanceof Ki||e instanceof On)&&this.textClipResizedWidth!==null){const m={wordWrap:!0,wordWrapWidth:u};this.textClipResizeHandle==="mr"?(f=e.left+u/2,i.x=f):this.textClipResizeHandle==="ml"?(f=e.left+u/2-(u-c),i.x=f):["br","tr"].includes(this.textClipResizeHandle)?(f=e.left+u/2,m.fontSize=d):["bl","tl"].includes(this.textClipResizeHandle)&&(f=e.left+u/2-(u-c),m.fontSize=d),await e.updateStyle(m);const g=await e.getTexture();g&&(await t.updateFrame(g),e.width=u,e.height=g.height,this.textClipResizedWidth=null,e.left=f-e.width/2,e.top=i.y-e.height/2,n.scale.set(1,1),i.scale.set(1,1))}else{let m=a,g=l;e.left=i.x-m/2,e.top=i.y-g/2,e.width=m,e.height=g;const v=e.flip==null?1:-1;e.angle=v*i.angle}}this.activeTransformer!=null&&this.activeTransformer.updateBounds();for(const e of this.selectedClips){const t=this.studio.spriteRenderers.get(e);t?.updateTransforms()}}}syncSpriteToClipProperties(e){const t=this.studio.spriteRenderers.get(e);if(t!=null){const i=t.getRoot(),n=t.getSprite();if(i!=null&&n!=null&&n.texture!=null){const s=n.texture.width,o=n.texture.height,a=Math.abs(i.scale.x*n.scale.x)*s,l=Math.abs(i.scale.y*n.scale.y)*o;let u=a,c=l;const h=i.x-u/2,d=i.y-c/2;e.left=h,e.top=d,e.width=u,e.height=c;const f=e.flip==null?1:-1;e.angle=f*i.angle,t.updateTransforms(),this.studio.emit("clip:updated",{clip:e})}}}async deleteSelected(){return this.studio.deleteSelected()}}class wte{constructor(e){this.studio=e}isPlaying=!1;currentTime=0;maxDuration=0;playStartTime=0;playStartTimestamp=0;rafId=null;playbackElements=new Map;setMaxDuration(e){this.maxDuration=e}async play(){if(!(this.isPlaying||this.studio.destroyed)){if(this.maxDuration<=0||this.maxDuration===1/0||isNaN(this.maxDuration)){console.warn("Cannot play: invalid duration",this.maxDuration);return}this.isPlaying||(this.isPlaying=!0),this.playStartTime=this.currentTime,this.playStartTimestamp=performance.now();for(const[e,{element:t}]of this.playbackElements.entries()){if(!(this.currentTime>=e.display.from&&(e.display.to===0||this.currentTime<=e.display.to))){this.isPlaybackCapable(e)&&e.pause(t);continue}const n=(this.currentTime-e.display.from)/1e6;this.isPlaybackCapable(e)&&await e.play(t,n)}this.renderLoop(),this.studio.emit("play",{isPlaying:!0})}}pause(){this.isPlaying=!1,this.rafId!=null&&(cancelAnimationFrame(this.rafId),this.rafId=null);for(const[e,{element:t}]of this.playbackElements.entries())this.isPlaybackCapable(e)&&e.pause(t);this.studio.emit("pause",{isPlaying:!1})}async stop(){this.pause(),await this.seek(0)}async seek(e){if(this.studio.destroyed)return;const t=this.isPlaying;this.playStartTime=Math.max(0,Math.min(e,this.maxDuration)),this.playStartTimestamp=performance.now(),this.currentTime=this.playStartTime;for(const[i,{element:n}]of this.playbackElements.entries()){if(!(this.currentTime>=i.display.from&&(i.display.to===0||this.currentTime<=i.display.to))){this.isPlaybackCapable(i)&&i.pause(n);continue}const o=(this.currentTime-i.display.from)/1e6;this.isPlaybackCapable(i)&&await i.seek(n,o)}if(await this.studio.updateFrame(this.currentTime),this.studio.emit("currentTime",{currentTime:this.currentTime}),t){this.isPlaying=!0;for(const[i,{element:n}]of this.playbackElements.entries()){if(!(this.currentTime>=i.display.from&&(i.display.to===0||this.currentTime<=i.display.to)))continue;const o=(this.currentTime-i.display.from)/1e6;this.isPlaybackCapable(i)&&await i.play(n,o)}}}async frameNext(){const t=1e6/(this.studio.opts.fps||30),i=Math.min(this.currentTime+t,this.maxDuration);await this.seek(i)}async framePrev(){const t=1e6/(this.studio.opts.fps||30),i=Math.max(0,this.currentTime-t);await this.seek(i)}async renderLoop(){if(!this.isPlaying||this.studio.destroyed||this.studio.pixiApp==null)return;if(this.maxDuration<=0||this.maxDuration===1/0||isNaN(this.maxDuration)){this.pause();return}const e=async()=>{if(!this.isPlaying||this.studio.destroyed||this.studio.pixiApp==null)return;if(this.currentTime>=this.maxDuration){this.currentTime=this.maxDuration,this.pause();return}const i=(performance.now()-this.playStartTimestamp)*1e3;this.currentTime=Math.min(this.playStartTime+i,this.maxDuration),this.studio.emit("currentTime",{currentTime:this.currentTime});try{await this.studio.updateFrame(this.currentTime)}catch(n){console.warn("Error updating frame:",n)}this.isPlaying&&(this.rafId=requestAnimationFrame(e))};e()}isPlaybackCapable(e){return"play"in e&&"pause"in e&&"seek"in e}}class jo{static instance;fonts=new Map;constructor(){}static getInstance(){return jo.instance||(jo.instance=new jo),jo.instance}async addFont(e){if(!this.fonts.has(e.name))try{const i=await new FontFace(e.name,`url(${e.url})`).load();document.fonts.add(i),this.fonts.set(e.name,i)}catch(t){console.error(`Failed to load font ${e.name}:`,t)}}async loadFonts(e){await Promise.all(e.map(t=>this.addFont(t)))}removeFont(e){const t=this.fonts.get(e);t&&(document.fonts.delete(t),this.fonts.delete(e))}clear(){this.fonts.forEach(e=>{document.fonts.delete(e)}),this.fonts.clear()}getLoadedFonts(){return Array.from(this.fonts.keys())}}const L4=jo.getInstance();class Ste{constructor(e){this.studio=e}tracks=[];clips=[];getTrackById(e){return this.tracks.find(t=>t.id===e)}getClipById(e){return this.clips.find(t=>t.id===e)}findTrackIdByClipId(e){for(const t of this.tracks)if(t.clipIds.includes(e))return t.id}getTrackIndex(e){return this.tracks.findIndex(t=>t.id===e)}addTrack(e,t){const i={id:e.id||`track_${Date.now()}_${Math.random().toString(36).substr(2,9)}`,name:e.name,type:e.type,clipIds:[]};return typeof t=="number"?this.tracks.splice(t,0,i):this.tracks.unshift(i),this.studio.emit("track:added",{track:i,index:t??0}),this.studio.emit("track:order-changed",{tracks:this.tracks}),i}async removeTrack(e){const t=this.tracks.findIndex(s=>s.id===e);if(t===-1)return;const n=[...this.tracks[t].clipIds];for(const s of n)await this.removeClipById(s);this.tracks.splice(t,1),this.studio.emit("track:removed",{trackId:e}),this.studio.emit("track:order-changed",{tracks:this.tracks})}async moveTrack(e,t){const i=this.tracks.findIndex(s=>s.id===e);if(i===-1)return;const n=this.tracks[i];this.tracks.splice(i,1),this.tracks.splice(t,0,n),this.studio.emit("track:order-changed",{tracks:this.tracks}),await this.studio.updateFrame(this.studio.currentTime)}async setTrackOrder(e){const t=[],i=new Map(this.tracks.map(n=>[n.id,n]));for(const n of e){const s=i.get(n);s&&t.push(s)}t.length!==this.tracks.length&&console.warn("[Studio] setTrackOrder: invalid track IDs provided, order not updated fully"),this.tracks=t,this.studio.emit("track:order-changed",{tracks:this.tracks}),await this.studio.updateFrame(this.studio.currentTime)}async addTransition(e,t=2e6,i,n){if(this.studio.destroyed)return;let s=null,o=null;if(i&&n&&(s=this.getClipById(i)??null,o=this.getClipById(n)??null),!s||!o){console.warn("[Studio] Invalid fromClipId or toClipId",{fromClipId:i,toClipId:n});return}await Promise.all([s.ready,o.ready]);const a=t,l=o.display.from-a/2,u=l+a,c={key:e,name:e,duration:a,fromClipId:s.id,toClipId:o.id,start:Math.max(0,l),end:u},h=this.findTrackIdByClipId(o.id);if(h){const p=this.tracks.find(m=>m.id===h);if(p){const m=p.clipIds.map(g=>this.getClipById(g)).filter(g=>{if(!g||g.type!=="Transition")return!1;const v=g;return v.fromClipId===s.id&&v.toClipId===o.id});for(const g of m)await this.removeClip(g)}}const d=`${s.id}_${o.id}`;this.studio.transitionRenderers.has(d)&&(this.studio.transitionRenderers.get(d)?.destroy(),this.studio.transitionRenderers.delete(d)),s.transition={...c},o.transition={...c};const f=new Bi(e);f.duration=a,f.fromClipId=Math.max(0,l)===0?null:s.id,f.toClipId=o.id,f.fromClipId===null&&s&&(f.fromClipId=s.id),f.display.from=Math.max(0,l),f.display.to=u,await this.addClip(f,{trackId:h}),this.studio.seek(this.studio.currentTime)}async addClip(e,t){const i=Array.isArray(e)?e:[e];if(i.length===0)return;const{trackId:n,audioSource:s}=this.normalizeAddClipOptions(t);if(this.studio.destroyed)return;if(this.studio.pixiApp==null)throw new Error("Failed to initialize Pixi.js Application");const o=[];for(const a of i)await this.prepareClipForTimeline(a,n),o.push(a);await this.recalculateMaxDuration();for(const a of o)await this.setupClipVisuals(a,s);await this.studio.updateFrame(this.studio.currentTime),this.emitAddClipEvents(o,n)}normalizeAddClipOptions(e){let t,i;if(e&&(typeof e=="string"||e instanceof File||e instanceof Blob))t=e;else if(typeof e=="object"&&e!==null&&!("size"in e)){const n=e;t=n.audioSource,i=n.trackId}return{trackId:i,audioSource:t}}async prepareClipForTimeline(e,t){e.id||(e.id=`clip_${Date.now()}_${Math.random().toString(36).substr(2,9)}`),this.clips.includes(e)||this.clips.push(e),this.addClipToTrack(e,t);const i=async()=>{await this.studio.updateFrame(this.studio.currentTime);const n=this.studio.selection;n.activeTransformer!=null&&n.selectedClips.has(e)&&typeof n.activeTransformer.updateBounds=="function"&&n.activeTransformer.updateBounds()};e.on("propsChange",i),this.studio.clipListeners.set(e,i),this.studio.pixiApp!=null&&typeof e.setRenderer=="function"&&e.setRenderer(this.studio.pixiApp.renderer),await e.ready}addClipToTrack(e,t){if(t){const i=this.tracks.find(n=>n.id===t);if(i)i.clipIds.includes(e.id)||i.clipIds.push(e.id);else{const n={id:t,name:`Track ${this.tracks.length+1}`,type:e.type,clipIds:[e.id]};this.tracks.unshift(n),this.studio.emit("track:added",{track:n,index:0}),this.studio.emit("track:order-changed",{tracks:this.tracks})}}else{const n={id:`track_${Date.now()}_${Math.random().toString(36).substr(2,9)}`,name:`Track ${this.tracks.length+1}`,type:e.type,clipIds:[e.id]};this.tracks.unshift(n),this.studio.emit("track:added",{track:n,index:0}),this.studio.emit("track:order-changed",{tracks:this.tracks})}}async setupClipVisuals(e,t){const i=this.studio.spriteRenderers.get(e);if(i){const n=this.studio.clipsNormalContainer,s=i.getRoot();s&&!s.parent&&n.addChild(s)}else{const n=await e.ready;if(n.width>0&&n.height>0){const s=this.studio.clipsNormalContainer,o=e.type==="Video"&&this.isPlaybackCapable(e);if(!o||o&&e.tickInterceptor!=null){const a=new R4(this.studio.pixiApp,e,s);this.studio.spriteRenderers.set(e,a)}}}await this.setupPlaybackForClip(e,t),this.studio.opts.interactivity&&this.studio.selection.setupSpriteInteractivity(e)}emitAddClipEvents(e,t){if(e.length!==0)if(e.length===1){const i=e[0],n=t||this.tracks.find(s=>s.clipIds.includes(i.id))?.id||"";this.studio.emit("clip:added",{clip:i,trackId:n})}else this.studio.emit("clips:added",{clips:e,trackId:t})}async removeClip(e,t={permanent:!0}){const{permanent:i}=t;if(e.locked)return;const n=this.clips.findIndex(c=>c===e);if(n===-1)return;if(e instanceof Bi){if(e.fromClipId){const c=this.getClipById(e.fromClipId);c&&"transition"in c&&delete c.transition}if(e.toClipId){const c=this.getClipById(e.toClipId);c&&"transition"in c&&delete c.transition}}this.studio.selection.selectedClips.has(e)&&this.studio.selection.deselectClip(),this.clips.splice(n,1);const s=[];for(const c of this.tracks){const h=c.clipIds.indexOf(e.id);h!==-1&&(c.clipIds.splice(h,1),s.push(c.id))}this.reconcileTracks(),this.studio.selection.interactiveClips.delete(e);const o=this.studio.clipListeners.get(e);o&&(e.off("propsChange",o),this.studio.clipListeners.delete(e));const a=this.studio.spriteRenderers.get(e);if(a!=null)if(i)a.destroy(),this.studio.spriteRenderers.delete(e);else{const c=a.getRoot();c&&c.parent&&c.parent.removeChild(c)}const l=this.studio.transport.playbackElements.get(e);l!=null&&(this.isPlaybackCapable(e)&&e.pause(l.element),this.studio.transport.playbackElements.delete(e),i&&this.isPlaybackCapable(e)&&e.cleanupPlayback(l.element,l.objectUrl));const u=this.studio.videoSprites.get(e);u!=null&&this.studio.pixiApp!=null&&(u.parent&&u.parent.removeChild(u),i&&(u.destroy(),this.studio.videoSprites.delete(e))),await this.recalculateMaxDuration(),this.studio.emit("clip:removed",{clipId:e.id})}async removeClips(e,t={permanent:!0}){if(e.length!==0){for(const i of e){if(i.locked)continue;const n=this.clips.findIndex(u=>u===i);if(n===-1)continue;if(i instanceof Bi){if(i.fromClipId){const u=this.getClipById(i.fromClipId);u&&"transition"in u&&delete u.transition}if(i.toClipId){const u=this.getClipById(i.toClipId);u&&"transition"in u&&delete u.transition}}this.studio.selection.selectedClips.has(i)&&this.studio.selection.deselectClip(),this.clips.splice(n,1);for(const u of this.tracks){const c=u.clipIds.indexOf(i.id);c!==-1&&u.clipIds.splice(c,1)}this.studio.selection.interactiveClips.delete(i);const s=this.studio.clipListeners.get(i);s&&(i.off("propsChange",s),this.studio.clipListeners.delete(i));const o=this.studio.spriteRenderers.get(i);if(o!=null)if(t.permanent)o.destroy(),this.studio.spriteRenderers.delete(i);else{const u=o.getRoot();u&&u.parent&&u.parent.removeChild(u)}const a=this.studio.transport.playbackElements.get(i);a!=null&&(this.isPlaybackCapable(i)&&i.pause(a.element),this.studio.transport.playbackElements.delete(i),t.permanent&&this.isPlaybackCapable(i)&&i.cleanupPlayback(a.element,a.objectUrl));const l=this.studio.videoSprites.get(i);l!=null&&this.studio.pixiApp!=null&&(l.parent&&l.parent.removeChild(l),t.permanent&&(l.destroy(),this.studio.videoSprites.delete(i)))}for(let i=this.tracks.length-1;i>=0;i--)if(this.tracks[i].clipIds.length===0){const n=this.tracks[i].id;this.tracks.splice(i,1),this.studio.emit("track:removed",{trackId:n})}await this.recalculateMaxDuration(),this.studio.emit("clips:removed",{clipIds:e.map(i=>i.id)})}}async removeClipById(e){const t=this.clips.find(i=>i.id===e);t&&await this.removeClip(t)}async updateClip(e,t){const i=this.clips.find(n=>n.id===e);i&&(i.locked&&!("locked"in t)||(i.locked&&"locked"in t&&(Object.keys(t).length===1||(t={locked:t.locked})),await this.applyClipUpdate(i,t),await this.recalculateMaxDuration(),await this.studio.updateFrame(this.studio.currentTime),this.updateTransformer(i),this.studio.emit("clip:updated",{clip:i})))}async updateClips(e){const t=[];for(const{id:i,updates:n}of e){const s=this.clips.find(o=>o.id===i);s&&(await this.applyClipUpdate(s,n),t.push(s))}if(t.length!==0){await this.recalculateMaxDuration(),await this.studio.updateFrame(this.studio.currentTime);for(const i of t)this.updateTransformer(i),this.studio.emit("clip:updated",{clip:i})}}async replaceClipsBySource(e,t){const i=this.clips.filter(n=>n.src===e);if(i.length!==0){this.studio.suspendRendering();for(const n of i){if(!this.clips.includes(n))continue;const s=this.findTrackIdByClipId(n.id);if(!s)continue;const o=this.getTrackById(s);if(!o)continue;const a=await t(n),l=async()=>{await this.studio.updateFrame(this.studio.currentTime),this.updateTransformer(a)};a.on("propsChange",l),this.studio.clipListeners.set(a,l),this.studio.pixiApp!=null&&typeof a.setRenderer=="function"&&a.setRenderer(this.studio.pixiApp.renderer),await a.ready;const u=this.clips.indexOf(n);u!==-1&&(this.clips[u]=a);const c=o.clipIds.indexOf(n.id);c!==-1&&(o.clipIds[c]=a.id),await this.setupClipVisuals(a);const h=this.studio.spriteRenderers.get(n);h&&(h.destroy(),this.studio.spriteRenderers.delete(n));const d=this.studio.videoSprites.get(n);d&&(d.parent&&d.parent.removeChild(d),d.destroy(),this.studio.videoSprites.delete(n));const f=this.studio.clipListeners.get(n);f&&(n.off("propsChange",f),this.studio.clipListeners.delete(n)),this.studio.selection.selectedClips.has(n)&&(this.studio.selection.selectedClips.delete(n),this.studio.selection.selectedClips.add(a)),this.studio.emit("clip:replaced",{oldClip:n,newClip:a,trackId:s})}await this.recalculateMaxDuration(),this.studio.resumeRendering(),await this.studio.updateFrame(this.studio.currentTime)}}async applyClipUpdate(e,t){if(e.type==="Text"||e.type==="Caption"){const i=e;typeof i.updateStyle=="function"&&await i.updateStyle(t),"style"in t&&delete t.style}if(Object.assign(e,t),t.display&&!t.duration?e.duration=t.display.to-t.display.from:t.duration&&(!t.display||!t.display.to)&&(e.display||(e.display={from:0,to:t.duration}),e.display.to=e.display.from+t.duration),t.display&&t.duration){const i=t.display.to-t.display.from;i!==t.duration&&(e.duration=i)}else e.display&&(e.display.to=e.display.from+e.duration)}updateTransformer(e){const t=this.studio.selection;t.selectedClips.has(e)&&t.activeTransformer&&t.activeTransformer.updateBounds()}exportToJSON(){this.reconcileTracks();const e=this.clips.map(n=>Rl(n,!1)),t=this.tracks.map(n=>({id:n.id,name:n.name,type:n.type,clipIds:[...n.clipIds]})),i=[];return this.clips.forEach(n=>{if(n.transition){const s=this.tracks.find(o=>o.clipIds.includes(n.id));if(s){const o=s.clipIds.indexOf(n.id);if(o>0){const a=s.clipIds[o-1];i.push({key:n.transition.name,duration:n.transition.duration,clips:[a,n.id]})}}}}),{tracks:t,clips:e,settings:{width:this.studio.opts.width,height:this.studio.opts.height,fps:this.studio.opts.fps,bgColor:this.studio.opts.bgColor}}}async loadFromJSON(e){if(await this.clear(),e.settings){const i=e.settings.width&&e.settings.width!==this.studio.opts.width||e.settings.height&&e.settings.height!==this.studio.opts.height;if(e.settings.width&&(this.studio.opts.width=e.settings.width),e.settings.height&&(this.studio.opts.height=e.settings.height),e.settings.fps&&(this.studio.opts.fps=e.settings.fps),e.settings.bgColor&&(this.studio.opts.bgColor=e.settings.bgColor),i&&this.studio.pixiApp!=null){const n=this.studio.opts.width,s=this.studio.opts.height;this.studio.pixiApp.renderer.resize(n,s),this.studio.opts.canvas&&(this.studio.opts.canvas.width=n,this.studio.opts.canvas.height=s)}}const t=[];if(e.clips){await this.ensureFontsForClips(e.clips);const i=e.clips.map(o=>o.src).filter(o=>o&&o.trim()!=="");this.studio.resourceManager.preload(i);const n=new Map;if(e.tracks){for(const o of e.tracks)if(o.clipIds)for(const a of o.clipIds)n.set(a,o.id)}if(e.tracks)for(const o of e.tracks)this.tracks.push({id:o.id,name:o.name,type:o.type,clipIds:[]});for(const o of e.clips)t.push((async()=>{try{let a=o.id?n.get(o.id):void 0;if(o.type==="Transition"){const u=o,c=u.toClipId||u.fromClipId;c&&(a=n.get(c))}if(o.type!=="Text"&&o.type!=="Caption"&&o.type!=="Effect"&&o.type!=="Transition"&&(!o.src||o.src.trim()===""))return console.warn(`Skipping clip ${o.type} with empty source`,o),{clip:null};const l=await Xo(o);return(l.type==="Video"||l.type==="Image")&&(!o.width||!o.height)&&this.studio.opts.width&&this.studio.opts.height&&(typeof l.scaleToFit=="function"&&await l.scaleToFit(this.studio.opts.width,this.studio.opts.height),typeof l.centerInScene=="function"&&l.centerInScene(this.studio.opts.width,this.studio.opts.height)),{clip:l,intendedTrackId:a}}catch(a){return console.error(`Failed to load clip ${o.id||"unknown"}:`,a),{clip:null}}})());const s=await Promise.all(t);for(const{clip:o,intendedTrackId:a}of s)o&&(o.id||(o.id=`clip_${Date.now()}_${Math.random().toString(36).substr(2,9)}`),this.clips.push(o),this.addClipToTrack(o,a))}this.studio.pixiApp&&this.clips.forEach(i=>{const n=async()=>{await this.studio.updateFrame(this.studio.currentTime);const s=this.studio.selection;s.activeTransformer!=null&&s.selectedClips.has(i)&&typeof s.activeTransformer.updateBounds=="function"&&s.activeTransformer.updateBounds()};i.on("propsChange",n),this.studio.clipListeners.set(i,n),typeof i.setRenderer=="function"&&i.setRenderer(this.studio.pixiApp.renderer),(async()=>{try{await i.ready,await this.setupClipVisuals(i),await this.studio.updateFrame(this.studio.currentTime)}catch(s){console.warn(`[Studio] Failed to setup visuals for clip ${i.id}:`,s)}})()});for(const i of this.clips){const n=i.effects;if(Array.isArray(n))for(const s of n)this.studio.globalEffects.has(s.id)||this.studio.globalEffects.set(s.id,{id:s.id,key:s.key,startTime:s.startTime,duration:s.duration})}for(const i of this.clips)if(i instanceof Bi){const n={name:i.transitionEffect.key,key:i.transitionEffect.key,duration:i.duration,fromClipId:i.fromClipId,toClipId:i.toClipId,start:i.display.from,end:i.display.to};if(i.fromClipId){const s=this.getClipById(i.fromClipId);s&&(s.transition={...n})}if(i.toClipId){const s=this.getClipById(i.toClipId);s&&(s.transition={...n})}}await this.recalculateMaxDuration();try{await this.studio.updateFrame(this.studio.currentTime)}catch(i){console.error("[Studio] Failed to update initial frame:",i)}this.studio.emit("studio:restored",{clips:this.clips,tracks:this.tracks,settings:this.studio.opts})}async deleteSelected(){const e=this.studio.selection.selectedClips,t=Array.from(e);if(t.length!==0)for(const i of t)await this.removeClip(i)}async duplicateSelected(){const e=this.studio.selection.selectedClips,t=Array.from(e).filter(n=>!n.locked);if(t.length===0)return;const i=[];for(const n of t){const s=this.findTrackIdByClipId(n.id);if(!s)continue;const o=this.tracks.find(h=>h.id===s);if(!o)continue;const a=Rl(n,!1),l=await Xo(a);l.id=`clip_${Date.now()}_${Math.random().toString(36).substr(2,9)}`;const u=`track_${Date.now()}_${Math.random().toString(36).substr(2,9)}`,c=`${o.name} (Copy)`;this.addTrack({id:u,name:c,type:o.type}),await this.addClip(l,{trackId:u}),i.push(l.id)}i.length>0&&this.studio.selection.selectClipsByIds(i)}async splitSelected(e){const t=Array.from(this.studio.selection.selectedClips);if(t.length!==1){console.warn("[Studio] Split requires exactly one selected clip");return}const i=t[0];if(i.locked){console.warn("[Studio] Cannot split a locked clip");return}const n=e??this.studio.currentTime;if(n<=i.display.from||i.display.to>0&&n>=i.display.to){console.warn("[Studio] Split time is outside clip bounds");return}const s=Rl(i,!1),o=n-i.display.from,a=i.playbackRate||1,l=o*a,u={duration:o,display:{from:i.display.from,to:n}};i.trim&&(u.trim={from:i.trim.from,to:i.trim.from+l}),await this.updateClip(i.id,u);const c={...s};c.display={from:n,to:s.display.to},c.duration=s.duration-o,c.trim&&(c.trim={from:c.trim.from+l,to:c.trim.to});const h=await Xo(c);h.id=`clip_${Date.now()}_${Math.random().toString(36).substr(2,9)}`;const d=this.findTrackIdByClipId(i.id);d&&(await this.addClip(h,{trackId:d}),this.studio.selection.selectClipsByIds([h.id]))}async trimSelected(e){const t=Array.from(this.studio.selection.selectedClips);if(t.length!==1){console.warn("[Studio] Trim requires exactly one selected clip");return}const i=t[0];if(i.locked){console.warn("[Studio] Cannot trim a locked clip");return}const n=e*1e6,s=i.playbackRate||1,o=n*s;if(n>=i.duration){console.warn("[Studio] Trim amount exceeds clip duration");return}const a=i.duration-n,l=i.display.from+n,u=i.display.to,c={duration:a,display:{from:l,to:u}};if(i.trim)c.trim={from:i.trim.from+o,to:i.trim.to};else{const h=i.sourceDuration||i.duration;c.trim={from:o,to:h}}await this.updateClip(i.id,c)}async updateSelected(e){const t=Array.from(this.studio.selection.selectedClips);if(t.length!==0)for(const i of t)await this.updateClip(i.id,e)}async setTracks(e){const t=JSON.parse(JSON.stringify(this.tracks));this.tracks=JSON.parse(JSON.stringify(e)),this.reconcileTracks(),this.tracks.length===0&&this.clips.length>0&&(this.tracks=t,this.reconcileTracks()),await this.recalculateMaxDuration(),this.studio.isRestoring||this.studio.emit("track:order-changed",{tracks:this.tracks}),await this.studio.updateFrame(this.studio.currentTime)}reconcileTracks(){const e=new Set(this.clips.map(t=>t.id));for(let t=this.tracks.length-1;t>=0;t--){const i=this.tracks[t],n=i.clipIds.filter(s=>e.has(s));n.length!==i.clipIds.length&&(i.clipIds=n),i.clipIds.length===0&&(this.tracks.splice(t,1),this.studio.isRestoring||this.studio.emit("track:removed",{trackId:i.id}))}this.tracks.length===0&&!this.studio.isRestoring&&this.studio.emit("track:order-changed",{tracks:this.tracks})}async ensureFontsForClips(e){const t=new Map;for(const i of e){if(i.type==="Text"){const n=i.style?.fontUrl||i.fontUrl;n&&t.set(n,{name:i.style?.fontFamily||i.fontFamily||"CustomFont",url:n})}if(i.type==="Caption"){const n=i.style?.fontUrl||i.fontUrl;n&&t.set(n,{name:i.style?.fontFamily||i.fontFamily||"CustomFont",url:n})}}if(t.size>0)try{await L4.loadFonts(Array.from(t.values()))}catch(i){console.warn("Failed to load some fonts:",i)}}async recalculateMaxDuration(){let e=0;for(const t of this.clips){t.display.to===0&&t.duration!==1/0&&!isNaN(t.duration)&&t.duration>0;const i=t.duration>0?t.duration:0;if(i===1/0)continue;const n=t.display.to>0?t.display.to:t.display.from+i;n>e&&(e=n)}this.studio.maxDuration=e}async setupPlaybackForClip(e,t){if(this.studio.pixiApp!=null&&this.isPlaybackCapable(e))try{const i=e;if(e.type==="Audio"&&t&&typeof t!="string"){const o=URL.createObjectURL(t);e.src=o}const{element:n,objectUrl:s}=await i.createPlaybackElement();if(e.type==="Video"){const o=Q.from(n),a=new Je(o);a.visible=!1,this.studio.clipsNormalContainer&&this.studio.clipsNormalContainer.addChild(a),this.studio.videoSprites.set(e,a)}this.studio.transport.playbackElements.set(e,{element:n,objectUrl:s})}catch(i){console.warn(`Failed to setup playback for ${e.constructor.name}`,i)}}isPlaybackCapable(e){return"createPlaybackElement"in e&&"play"in e&&"pause"in e&&"seek"in e&&"syncPlayback"in e&&"cleanupPlayback"in e}async clear(){this.studio.selection.deselectClip(),this.studio.selection.interactiveClips.clear();for(const[e,t]of this.studio.clipListeners)e.off("propsChange",t);this.studio.clipListeners.clear(),this.studio.globalEffects.clear(),this.studio.effectFilters.clear(),this.studio.transitionRenderers.forEach(e=>e.destroy()),this.studio.transitionRenderers.clear(),this.studio.transitionSprites.forEach(e=>{e.parent&&e.parent.removeChild(e),e.destroy()}),this.studio.transitionSprites.clear(),this.studio.spriteRenderers.forEach(e=>e.destroy()),this.studio.spriteRenderers.clear();for(const[e,t]of this.studio.transport.playbackElements)this.isPlaybackCapable(e)&&e.cleanupPlayback(t.element,t.objectUrl);this.studio.transport.playbackElements.clear();for(const e of this.studio.videoSprites.values())e.destroy();this.studio.videoSprites.clear(),this.tracks=[],this.clips=[],this.studio.maxDuration=0,this.studio.currentTime=0,this.studio.emit("reset")}async rippleDelete(e,t){if(e>=t)return;const i=t-e,n=[...this.clips];for(const s of n){const o=s.display.from,a=s.display.to;if(!(a<=e)){if(o>=t){await this.updateClip(s.id,{display:{from:s.display.from-i,to:s.display.to-i}});continue}if(o>=e&&a<=t){await this.removeClip(s);continue}if(o<e&&a>t){const l=await s.clone();l.id=`clip_${Date.now()}_${Math.random().toString(36).substr(2,9)}`;const u=e,c=e+(a-t),h=s.trim.from+(t-o)*s.playbackRate,d=s.trim.to,f=this.tracks.find(p=>p.clipIds.includes(s.id));f&&(await this.addClip(l,{trackId:f.id}),await this.updateClip(l.id,{display:{from:u,to:c},trim:{from:h,to:d}})),await this.updateClip(s.id,{display:{from:s.display.from,to:e},trim:{from:s.trim.from,to:s.trim.from+(e-o)*s.playbackRate}});continue}if(o<e&&a<=t){await this.updateClip(s.id,{display:{from:s.display.from,to:e},trim:{from:s.trim.from,to:s.trim.from+(e-o)*s.playbackRate}});continue}if(o>=e&&a>t){await this.updateClip(s.id,{display:{from:e,to:e+(a-t)},trim:{from:s.trim.from+(t-o)*s.playbackRate,to:s.trim.to}});continue}}}await this.recalculateMaxDuration(),await this.studio.updateFrame(this.studio.currentTime)}}const Tte={Date:!0,RegExp:!0,String:!0,Number:!0};function N4(r,e,t={cyclesFix:!0},i=[]){let n=[];const s=Array.isArray(r);for(const a in r){const l=r[a],u=s?+a:a;if(!(a in e)){n.push({type:"REMOVE",path:[u],oldValue:r[a]});continue}const c=e[a],h=typeof l=="object"&&typeof c=="object"&&Array.isArray(l)===Array.isArray(c);l&&c&&h&&!Tte[Object.getPrototypeOf(l)?.constructor?.name]&&(!t.cyclesFix||!i.includes(l))?n.push.apply(n,N4(l,c,t,t.cyclesFix?i.concat([l]):[]).map(d=>(d.path.unshift(u),d))):l!==c&&!(Number.isNaN(l)&&Number.isNaN(c))&&!(h&&(isNaN(l)?l+""==c+"":+l==+c))&&n.push({path:[u],type:"CHANGE",value:c,oldValue:l})}const o=Array.isArray(e);for(const a in e)a in r||n.push({type:"CREATE",path:[o?+a:a],value:e[a]});return n}class Cte{past=[];future=[];lastState=null;maxSize;constructor(e={}){this.maxSize=e.maxSize||50}projectToHistoryState(e){const t={},i=JSON.parse(JSON.stringify(e.tracks||[]));return e.clips.forEach(n=>{n.id&&(t[n.id]=JSON.parse(JSON.stringify(n)))}),{clips:t,tracks:i,settings:JSON.parse(JSON.stringify(e.settings||{}))}}init(e){this.lastState=this.projectToHistoryState(JSON.parse(JSON.stringify(e))),this.past=[],this.future=[]}push(e){if(!this.lastState){this.init(e);return}const t=this.projectToHistoryState(JSON.parse(JSON.stringify(e))),i=N4(this.lastState,t);i.length!==0&&(this.past.push(i),this.past.length>this.maxSize&&this.past.shift(),this.future=[],this.lastState=t)}undo(e){const t=this.past.pop();if(!t)return null;const i=this.projectToHistoryState(JSON.parse(JSON.stringify(e))),n=this.applyPatches(i,t,!0);return this.future.push(t),this.lastState=n,{patches:t,state:n}}redo(e){const t=this.future.pop();if(!t)return null;const i=this.projectToHistoryState(JSON.parse(JSON.stringify(e))),n=this.applyPatches(i,t,!1);return this.past.push(t),this.lastState=n,{patches:t,state:n}}applyPatches(e,t,i){const n=JSON.parse(JSON.stringify(e)),s=i?[...t].reverse():t;for(const o of s){const{type:a,path:l}=o,u=o.value,c=o.oldValue;let h=n,d=!1;for(let p=0;p<l.length-1;p++){if(h[l[p]]===void 0||h[l[p]]===null){d=!0;break}h=h[l[p]]}if(d)continue;const f=l[l.length-1];if(i)switch(a){case"CREATE":Array.isArray(h)?h.splice(f,1):delete h[f];break;case"REMOVE":h[f]=c&&typeof c=="object"?JSON.parse(JSON.stringify(c)):c;break;case"CHANGE":h[f]=c&&typeof c=="object"?JSON.parse(JSON.stringify(c)):c;break}else switch(a){case"CREATE":h[f]=u&&typeof u=="object"?JSON.parse(JSON.stringify(u)):u;break;case"REMOVE":Array.isArray(h)?h.splice(f,1):delete h[f];break;case"CHANGE":h[f]=u&&typeof u=="object"?JSON.parse(JSON.stringify(u)):u;break}}return n}canUndo(){return this.past.length>0}canRedo(){return this.future.length>0}}class Ate extends X0{selection;transport;timeline;history;resourceManager;pixiApp=null;get tracks(){return this.timeline.tracks}get clips(){return this.timeline.clips}spriteRenderers=new Map;artboard=null;clipContainer=null;artboardMask=null;artboardBg=null;get activeTransformer(){return this.selection.activeTransformer}set activeTransformer(e){this.selection.activeTransformer=e}get selectedClips(){return this.selection.selectedClips}set selectedClips(e){this.selection.selectedClips=e}get interactiveClips(){return this.selection.interactiveClips}set interactiveClips(e){this.selection.interactiveClips=e}get playbackElements(){return this.transport.playbackElements}videoSprites=new Map;clipListeners=new Map;get isPlaying(){return this.transport.isPlaying}set isPlaying(e){this.transport.isPlaying=e}get currentTime(){return this.transport.currentTime}set currentTime(e){this.transport.currentTime=e}get maxDuration(){return this.transport.maxDuration}set maxDuration(e){this.transport.maxDuration=e}opts;destroyed=!1;renderingSuspended=!1;historyPaused=!1;processingHistory=!1;isRestoring=!1;historyGroupDepth=0;clipCache=new Map;_isUpdatingLayout=!1;globalEffects=new Map;activeGlobalEffects=[];currentGlobalEffectSprite=null;effectFilters=new Map;transitionRenderers=new Map;transitionSprites=new Map;transFromTexture=null;transToTexture=null;transBgGraphics=null;clipsNormalContainer=null;clipsEffectContainer=null;videoTextureCache=new WeakMap;lastFromFrame=null;lastToFrame=null;hexToNumber(e){const t=e.startsWith("#")?e.slice(1):e;return parseInt(t,16)}ready;constructor(e){super(),this.opts={fps:30,bgColor:"#000000",interactivity:!0,spacing:0,...e},this.selection=new _te(this),this.transport=new wte(this),this.timeline=new Ste(this),this.history=new Cte,this.resourceManager=new Lo,this.ready=this.initPixiApp().then(()=>{this.history.init(this.exportToJSON())}),this.on("clip:added",t=>this.handleTimelineChange(t)),this.on("clips:added",t=>this.handleTimelineChange(t)),this.on("clip:replaced",t=>this.handleTimelineChange({clip:t.newClip})),this.on("studio:restored",t=>{t.clips.forEach(i=>this.attachClipEvents(i)),this.handleTimelineChange()}),this.on("clip:removed",this.handleClipRemoved),this.on("clips:removed",this.handleClipsRemoved),this.on("clip:updated",this.handleTimelineChange),this.on("track:removed",()=>this.handleTimelineChange()),this.on("track:added",()=>this.handleTimelineChange())}attachClipEvents(e){if(this.clipListeners.has(e))return;const t=()=>{this.updateFrame(this.currentTime)};e.on("request-render",t),this.clipListeners.set(e,t)}handleTimelineChange=e=>{e?.clip&&this.attachClipEvents(e.clip),e?.clips&&e.clips.forEach(t=>this.attachClipEvents(t)),this.updateFrame(this.currentTime),this.saveHistory()};saveHistory(){this.historyPaused||this.processingHistory||(this.history.push(this.exportToJSON()),this.emit("history:changed",{canUndo:this.history.canUndo(),canRedo:this.history.canRedo()}))}beginHistoryGroup(){this.processingHistory||this.isRestoring||(this.historyGroupDepth++,this.historyPaused=!0)}endHistoryGroup(){this.processingHistory||this.isRestoring||(this.historyGroupDepth=Math.max(0,this.historyGroupDepth-1),this.historyGroupDepth===0&&(this.historyPaused=!1,this.saveHistory()))}setPath(e,t,i){let n=e;for(let s=0;s<t.length-1;s++){const o=t[s];n[o]||(n[o]=typeof t[s+1]=="number"?[]:{}),n=n[o]}n[t[t.length-1]]=i}async applyHistoryPatches(e,t,i){const n=new Map,s=new Map,o=new Set;for(const a of e){const{type:l,path:u}=a,c=a.value,h=a.oldValue;if(u[0]==="clips"){const d=u[1];i?l==="CREATE"?o.add(d):l==="REMOVE"?s.set(d,h):l==="CHANGE"&&(n.has(d)||n.set(d,{}),this.setPath(n.get(d),u.slice(2),h)):l==="CREATE"?s.set(d,c):l==="REMOVE"?o.add(d):l==="CHANGE"&&(n.has(d)||n.set(d,{}),this.setPath(n.get(d),u.slice(2),c))}else u[0]==="settings"&&(i?this.setPath(this.opts,u.slice(1),h):this.setPath(this.opts,u.slice(1),c))}for(const a of o){const l=this.timeline.getClipById(a);l&&await this.removeClip(l)}for(const[a,l]of s){let u=this.clipCache.get(a);u||(u=await Xo(l),this.clipCache.set(a,u),this.attachClipEvents(u));let c;for(const h of t.tracks)if(h.clipIds.includes(a)){c=h.id;break}await this.addClip(u,{trackId:c})}for(const[a,l]of n)await this.updateClip(a,l);this.timeline.setTracks(t.tracks),this.emit("studio:restored",{clips:this.clips,tracks:this.tracks,settings:this.opts})}async undo(){if(!(!this.history.canUndo()||this.processingHistory)){this.processingHistory=!0,this.isRestoring=!0,this.historyPaused=!0;try{const e=this.history.undo(this.exportToJSON());e&&await this.applyHistoryPatches(e.patches,e.state,!0),this.emit("history:changed",{canUndo:this.history.canUndo(),canRedo:this.history.canRedo()})}finally{this.historyPaused=!1,this.isRestoring=!1,this.processingHistory=!1}}}async redo(){if(!(!this.history.canRedo()||this.processingHistory)){this.processingHistory=!0,this.isRestoring=!0,this.historyPaused=!0;try{const e=this.history.redo(this.exportToJSON());e&&await this.applyHistoryPatches(e.patches,e.state,!1),this.emit("history:changed",{canUndo:this.history.canUndo(),canRedo:this.history.canRedo()})}finally{this.historyPaused=!1,this.isRestoring=!1,this.processingHistory=!1}}}cleanupClipVisuals=e=>{for(const[s,o]of this.spriteRenderers)if(s.id===e){const a=o.getRoot();a&&a.parent&&a.parent.removeChild(a),o.destroy(),this.spriteRenderers.delete(s);break}const t=this.transitionSprites.get(e);t&&(t.parent&&t.parent.removeChild(t),t.destroy(),this.transitionSprites.delete(e)),this.transitionRenderers.get(e)&&this.transitionRenderers.delete(e);for(const[s,o]of this.videoSprites)if(s.id===e){o.parent&&o.parent.removeChild(o),o.destroy(),this.videoSprites.delete(s);break}const n=this.timeline.getClipById(e);if(n){const s=this.clipListeners.get(n);s&&(n.off("request-render",s),this.clipListeners.delete(n))}};handleClipRemoved=({clipId:e})=>{this.cleanupClipVisuals(e),this.updateFrame(this.currentTime),this.saveHistory()};handleClipsRemoved=({clipIds:e})=>{for(const t of e)this.cleanupClipVisuals(t);this.updateFrame(this.currentTime),this.saveHistory()};async initPixiApp(){if(this.destroyed)return;const e=this.opts.canvas||document.createElement("canvas");e.width=this.opts.width,e.height=this.opts.height;const t=new gc,i=e.parentElement||window;await t.init({canvas:e,resizeTo:i,backgroundColor:this.hexToNumber(this.opts.bgColor),antialias:!0,resolution:window.devicePixelRatio||1,autoDensity:!0,autoStart:!1}),this.pixiApp=t,t.render(),t.stage.eventMode="static",t.stage.hitArea=t.screen,this.artboard=new Pe,this.artboard.label="ArtboardRoot",t.stage.addChild(this.artboard),this.selection.init(t,this.artboard),this.artboardBg=new Ze,this.artboardBg.rect(0,0,this.opts.width,this.opts.height).fill({color:0}),this.artboard.addChild(this.artboardBg),this.clipContainer=new Pe,this.clipContainer.label="ClipContainer",this.artboard.addChild(this.clipContainer),this.artboardMask=new Ze,this.artboardMask.rect(0,0,this.opts.width,this.opts.height).fill({color:16777215}),this.clipContainer.addChild(this.artboardMask),this.clipContainer.mask=this.artboardMask,this.clipsEffectContainer=new Pe,this.clipsEffectContainer.label="ClipsEffect",this.clipsEffectContainer.visible=!1,this.clipsEffectContainer.zIndex=1,this.clipsEffectContainer.sortableChildren=!0,this.clipContainer.addChild(this.clipsEffectContainer),this.clipsNormalContainer=new Pe,this.clipsNormalContainer.label="ClipsNormal",this.clipsNormalContainer.zIndex=10,this.clipsNormalContainer.sortableChildren=!0,this.clipContainer.addChild(this.clipsNormalContainer),this.transFromTexture=Ot.create({width:this.opts.width,height:this.opts.height}),this.transToTexture=Ot.create({width:this.opts.width,height:this.opts.height}),this.transBgGraphics=new Ze,this.transBgGraphics.rect(0,0,this.opts.width,this.opts.height).fill({color:0,alpha:0}),this.clipContainer.sortableChildren=!0,this.updateArtboardLayout(),t.renderer.on("resize",()=>{this.handleResize()})}getOptions(){return this.opts}setSize(e,t){this.updateDimensions(e,t)}setBgColor(e){this.opts.bgColor=e;const t=this.hexToNumber(e);this.pixiApp&&(this.pixiApp.renderer.background.color=t,this.pixiApp.render()),this.updateFrame(this.currentTime)}updateDimensions(e,t){this.opts.width=e,this.opts.height=t,this.artboardBg&&this.artboardBg.clear().rect(0,0,e,t).fill({color:0}),this.artboardMask&&this.artboardMask.clear().rect(0,0,e,t).fill({color:16777215}),this.transFromTexture&&this.transFromTexture.resize(e,t),this.transToTexture&&this.transToTexture.resize(e,t),this.transBgGraphics&&this.transBgGraphics.clear().rect(0,0,e,t).fill({color:0,alpha:0}),this.updateArtboardLayout(),this.updateFrame(this.currentTime)}handleResize=()=>{this.destroyed||!this.pixiApp||this._isUpdatingLayout||this.updateArtboardLayout()};updateArtboardLayout(){if(!(!this.pixiApp||!this.artboard||this._isUpdatingLayout)){this._isUpdatingLayout=!0;try{this.pixiApp.resize();const t=this.pixiApp.canvas.parentElement,i=t?t.getBoundingClientRect().width:this.pixiApp.screen.width,n=t?t.getBoundingClientRect().height:this.pixiApp.screen.height,s=this.opts.width,o=this.opts.height,a=this.opts.spacing||0,l=Math.max(0,i-a*2),u=Math.max(0,n-a*2),c=l/s,h=u/o,d=Math.min(c,h);this.artboard.scale.set(d),this.artboard.x=(i-s*d)/2,this.artboard.y=(n-o*d)/2,this.pixiApp.render()}finally{this._isUpdatingLayout=!1}}}getCanvas(){if(this.opts.canvas)return this.opts.canvas;if(this.pixiApp?.canvas)return this.pixiApp.canvas;throw new Error("Canvas not initialized yet. Wait for initPixiApp to complete.")}async addTransition(e,t=2e6,i,n){return this.timeline.addTransition(e,t,i,n)}findTrackIdByClipId(e){return this.timeline.findTrackIdByClipId(e)}async addClip(e,t){const i=Array.isArray(e)?e:[e];i.forEach(n=>this.clipCache.set(n.id,n)),this.beginHistoryGroup();try{const n=await this.timeline.addClip(e,t);return i.forEach(s=>this.attachClipEvents(s)),n}finally{this.endHistoryGroup()}}addTrack(e,t){return this.timeline.addTrack(e,t)}async setTracks(e){if(this.isRestoring)return;const t=new Set(this.timeline.clips.map(i=>i.id));if(!(e.length===0&&t.size>0)&&!(e.length>0&&t.size>0&&!e.some(n=>n.clipIds.some(s=>t.has(s)))))return this.timeline.setTracks(e)}async moveTrack(e,t){return this.timeline.moveTrack(e,t)}async setTrackOrder(e){return this.timeline.setTrackOrder(e)}async removeTrack(e){return this.timeline.removeTrack(e)}getClipById(e){return this.timeline.getClipById(e)}async updateClip(e,t){return this.timeline.updateClip(e,t)}async centerClip(e){const t=typeof e=="string"?this.getClipById(e):e;if(!t)return;const i=(this.opts.width-t.width)/2,n=(this.opts.height-t.height)/2;if(this.getClipById(t.id))return this.updateClip(t.id,{left:i,top:n});t.left=i,t.top=n}async centerClipH(e){const t=typeof e=="string"?this.getClipById(e):e;if(!t)return;const i=(this.opts.width-t.width)/2;if(this.getClipById(t.id))return this.updateClip(t.id,{left:i});t.left=i}async centerClipV(e){const t=typeof e=="string"?this.getClipById(e):e;if(!t)return;const i=(this.opts.height-t.height)/2;if(this.getClipById(t.id))return this.updateClip(t.id,{top:i});t.top=i}async scaleToFit(e){const t=typeof e=="string"?this.getClipById(e):e;if(!t)return;const i=await t.ready,{width:n,height:s}=i;if(n===0||s===0)return;const o=Math.min(this.opts.width/n,this.opts.height/s),a=n*o,l=s*o;if(this.getClipById(t.id))return this.updateClip(t.id,{width:a,height:l});t.width=a,t.height=l}async scaleToCover(e){const t=typeof e=="string"?this.getClipById(e):e;if(!t)return;const i=await t.ready,{width:n,height:s}=i;if(n===0||s===0)return;const o=Math.max(this.opts.width/n,this.opts.height/s),a=n*o,l=s*o;if(this.getClipById(t.id))return this.updateClip(t.id,{width:a,height:l});t.width=a,t.height=l}async updateClips(e){this.suspendRendering(),await this.timeline.updateClips(e),this.resumeRendering(),this.updateFrame(this.currentTime)}suspendRendering(){this.renderingSuspended=!0}resumeRendering(){this.renderingSuspended=!1}getTracks(){return this.timeline.tracks}getClip(e){return this.timeline.getClipById(e)}findClip(e){return this.timeline.getClipById(e)}setupSpriteInteractivity(e){this.selection.setupSpriteInteractivity(e)}async removeClip(e){const t=typeof e=="string"?this.getClipById(e):e;if(!t){console.warn("[Studio] removeClip: Clip not found",e);return}this.beginHistoryGroup();try{return this.clipCache.set(t.id,t),this.timeline.removeClip(t,{permanent:!this.processingHistory})}finally{this.endHistoryGroup()}}async removeClips(e){this.beginHistoryGroup();try{return e.forEach(t=>this.clipCache.set(t.id,t)),this.timeline.removeClips(e,{permanent:!this.processingHistory})}finally{this.endHistoryGroup()}}async removeClipById(e){const t=this.timeline.getClipById(e);if(t)return this.removeClip(t)}async removeClipsById(e){const t=e.map(i=>this.timeline.getClipById(i)).filter(Boolean);return this.removeClips(t)}async deleteSelected(){const e=this.selection.selectedClips;if(e.size!==0){this.beginHistoryGroup();try{await this.removeClips(Array.from(e))}finally{this.endHistoryGroup()}}}async duplicateSelected(){this.beginHistoryGroup();try{return await this.timeline.duplicateSelected()}finally{this.endHistoryGroup()}}async splitSelected(e){this.beginHistoryGroup();try{return await this.timeline.splitSelected(e)}finally{this.endHistoryGroup()}}async trimSelected(e){return this.timeline.trimSelected(e)}async updateSelected(e){return this.timeline.updateSelected(e)}async clear(){await this.timeline.clear(),this.transFromTexture&&(this.transFromTexture.destroy(!0),this.transFromTexture=null),this.transToTexture&&(this.transToTexture.destroy(!0),this.transToTexture=null),this.transBgGraphics&&(this.transBgGraphics.destroy(!0),this.transBgGraphics=null),this.transitionRenderers.forEach(e=>e.destroy()),this.transitionRenderers.clear(),this.transitionSprites.forEach(e=>e.destroy()),this.transitionSprites.clear(),this.emit("reset")}async play(){return this.transport.play()}pause(){this.transport.pause()}async stop(){return this.transport.stop()}async seek(e){return this.transport.seek(e)}async frameNext(){return this.transport.frameNext()}async framePrev(){return this.transport.framePrev()}getCurrentTime(){return this.transport.currentTime}getMaxDuration(){return this.transport.maxDuration}getIsPlaying(){return this.transport.isPlaying}getSelectedClips(){return Array.from(this.selectedClips)}getVideoTexture(e){let t=this.videoTextureCache.get(e);return t||(t=Q.from(e),this.videoTextureCache.set(e,t)),t}isPlaybackCapable(e){return"createPlaybackElement"in e&&"play"in e&&"pause"in e&&"seek"in e&&"syncPlayback"in e&&"cleanupPlayback"in e}async updateFrame(e){if(this.destroyed||this.pixiApp==null||this.renderingSuspended)return;this.updateActiveGlobalEffect(e);const t=new Set,i=new Set,n=this.tracks.length;for(const o of this.clips){const a=this.getTrackIndex(o.id);if(a!==-1){const l=(n-a)*10;o.zIndex=l;const u=this.spriteRenderers.get(o);if(u){const h=u.getRoot();h&&(h.zIndex=l)}const c=this.videoSprites.get(o);c&&(c.zIndex=l)}}const s=[...this.clips].sort((o,a)=>o.zIndex-a.zIndex);for(const o of s){if(e<o.display.from){const v=this.spriteRenderers.get(o);v!=null&&await v.updateFrame(null);const x=this.playbackElements.get(o);x!=null&&this.isPlaybackCapable(o)&&o.pause(x.element);continue}if(o.display.to>0&&e>o.display.to){const v=this.spriteRenderers.get(o);v!=null&&await v.updateFrame(null);const x=this.playbackElements.get(o);x!=null&&this.isPlaybackCapable(o)&&o.pause(x.element);continue}const a=e-o.display.from,l=a*o.playbackRate;o.animate(l);const u=await o.ready,c=o.duration||u.duration;if(c>0&&a>c){const v=this.spriteRenderers.get(o);v!=null&&await v.updateFrame(null);const x=this.playbackElements.get(o);x!=null&&this.isPlaybackCapable(o)&&o.pause(x.element);continue}const h=this.playbackElements.get(o),d=o.type==="Video"||o.type==="Image",f=o.transition?o.transition.start:0,p=o.transition?o.transition.end:0,m=d&&o.transition&&e>=f&&e<p;if(h!=null&&this.isPlaybackCapable(o)){const v=a/1e6;if(o.syncPlayback(h.element,this.isPlaying,v),o.type==="Video"&&this.isPlaybackCapable(o)){const x=this.videoSprites.get(o);if(x!=null){const y=o.meta.duration/1e6;if(this.spriteRenderers.has(o))x.visible=!1;else if(x.visible=!m&&v>=0&&v<y,x.visible&&hee(o,x),!m)continue}}else continue}if(m){const v=o?.transition?.fromClipId,x=o?.transition?.toClipId,y=`${v}_${x}`;if(i.has(y)){const E=this.spriteRenderers.get(o);E?.getRoot()&&(E.getRoot().visible=!1);const _=this.videoSprites.get(o);_&&(_.visible=!1);continue}i.add(y),this.transFromTexture||(this.transFromTexture=Ot.create({width:this.opts.width,height:this.opts.height})),this.transToTexture||(this.transToTexture=Ot.create({width:this.opts.width,height:this.opts.height})),this.transBgGraphics||(this.transBgGraphics=new Ze,this.transBgGraphics.rect(0,0,this.opts.width,this.opts.height).fill({color:0,alpha:0}));const b=v?this.getClipById(v):null,T=x?this.getClipById(x):null;let P=null,A=null;if(b){const E=Math.max(0,e-b.display.from),{video:_}=await b.getFrame(E);_ instanceof HTMLVideoElement?P=this.getVideoTexture(_):P=_,P&&(this.lastFromFrame=P)}if(T){const E=Math.max(0,e-T.display.from),{video:_}=await T.getFrame(E);_ instanceof HTMLVideoElement?A=this.getVideoTexture(_):A=_,A&&(this.lastToFrame=A)}if(P||(P=this.lastFromFrame),A||(A=this.lastToFrame),!P||!A)continue;if(P&&A&&this.pixiApp&&this.transFromTexture&&this.transToTexture){const E=(e-f)/o?.transition?.duration;b&&P&&this.renderClipToTransitionTexture(b,P,this.transFromTexture),T&&A&&this.renderClipToTransitionTexture(T,A,this.transToTexture);let _=this.transitionRenderers.get(y);if(!_)try{_=c1({name:o?.transition?.name,renderer:this.pixiApp.renderer}),this.transitionRenderers.set(y,_)}catch(S){console.error("[Studio] Failed to create transition renderer:",S)}if(_){const S=_.render({width:this.opts.width,height:this.opts.height,from:this.transFromTexture,to:this.transToTexture,progress:E});let I=this.transitionSprites.get(o.id);I||(I=new Je,I.label=`TransitionSprite_${o.id}`,this.transitionSprites.set(o.id,I),this.clipsNormalContainer&&this.clipsNormalContainer.addChild(I)),I.texture=S,I.visible=!0,I.x=0,I.y=0,I.width=this.opts.width,I.height=this.opts.height,I.anchor.set(0,0),I.zIndex=o.zIndex,t.add(o.id);const M=this.spriteRenderers.get(o);M?.getRoot()&&(M.getRoot().visible=!1);const O=this.videoSprites.get(o);if(O&&(O.visible=!1),b){const U=this.spriteRenderers.get(b);U?.getRoot()&&(U.getRoot().visible=!1);const X=this.videoSprites.get(b);X&&(X.visible=!1)}if(T){const U=this.spriteRenderers.get(T);U?.getRoot()&&(U.getRoot().visible=!1);const X=this.videoSprites.get(T);X&&(X.visible=!1)}continue}}}const g=this.spriteRenderers.get(o);if(g!=null){const v=this.selectedClips.has(o);if(o.type!=="Text"&&o.type!=="Caption"&&typeof o.getTexture=="function"&&o.getTexture()!=null){const y=o.getTexture();if(y!=null){await g.updateFrame(y),v||g.updateTransforms(),this.opts.interactivity&&this.selection.setupSpriteInteractivity(o);continue}}if(o.type==="Text"){const y=o;this.pixiApp?.renderer&&typeof y.setRenderer=="function"&&y.setRenderer(this.pixiApp.renderer);const b=await y.getTexture();if(b!=null){await g.updateFrame(b),v||g.updateTransforms(),this.opts.interactivity&&this.selection.setupSpriteInteractivity(o);continue}}if(o.type==="Caption"){o.updateState(a);const y=o;this.pixiApp?.renderer&&typeof y.setRenderer=="function"&&y.setRenderer(this.pixiApp.renderer);const b=await y.getTexture();if(b!=null){await g.updateFrame(b),v||g.updateTransforms(),this.opts.interactivity&&this.selection.setupSpriteInteractivity(o);continue}}const{video:x}=await o.getFrame(a);await g.updateFrame(x),v||g.updateTransforms(),this.opts.interactivity&&this.selection.setupSpriteInteractivity(o)}}if(this.activeGlobalEffects.length>0&&this.clipsNormalContainer&&this.clipsEffectContainer){for(const o of this.clips)this.moveClipToEffectContainer(o,!1);this.clipsNormalContainer.visible=!0,await this.applyGlobalEffects(e)}else if(this.clipsNormalContainer){for(const o of this.clips)this.moveClipToEffectContainer(o,!1);this.clipsNormalContainer.visible=!0,this.currentGlobalEffectSprite&&(this.currentGlobalEffectSprite.parent&&this.currentGlobalEffectSprite.parent.removeChild(this.currentGlobalEffectSprite),this.currentGlobalEffectSprite.destroy(),this.currentGlobalEffectSprite=null)}for(const[o,a]of this.transitionSprites.entries())t.has(o)||(a.visible=!1);this.pixiApp!=null&&this.pixiApp.render()}moveClipToEffectContainer(e,t=!0){if(!this.clipsNormalContainer||!this.clipsEffectContainer)return;const i=t?this.clipsEffectContainer:this.clipsNormalContainer,n=this.spriteRenderers.get(e);if(n){const o=n.getRoot();if(o&&o.parent!==i){try{o.parent&&o.parent.removeChild&&o.parent.removeChild(o)}catch(a){console.warn("moveClipToEffectContainer: could not remove root from parent",a)}i.addChild(o)}}const s=this.transitionSprites.get(e.id);if(s&&s.parent!==i){try{s.parent&&s.parent.removeChild&&s.parent.removeChild(s)}catch(o){console.warn("moveClipToEffectContainer: could not remove transSprite from parent",o)}i.addChild(s)}}applyGlobalEffect(e,t,i){const n=t.id||`${e}_${Date.now()}_${Math.random().toString(36).substr(2,9)}`,s={id:n,key:e,startTime:t.startTime,duration:t.duration??1e6};for(const o of i)o instanceof Bl&&o.addEffect(s),o instanceof br&&o.addEffect(s),o instanceof Ki&&o.addEffect(s),o instanceof On&&o.addEffect(s);return this.globalEffects.set(n,s),n}getTrackIndex(e){return this.tracks.findIndex(t=>t.clipIds.includes(e))}async getTransitionFromFrame(e,t){let i=null;if(e.transition?.prevClipId&&(i=this.clips.find(a=>a.id===e.transition.prevClipId)||null),i||(i=this.getPreviousClipOnTrack(e)),!i)return null;const n=i.duration>0?i.duration:0,s=Math.max(0,Math.min(t-i.display.from,n)),{video:o}=await i.getFrame(s);return o}getPreviousClipOnTrack(e){const t=this.getTrackIndex(e.id);return t===-1?null:this.clips.filter(i=>i.id!==e.id&&this.getTrackIndex(i.id)===t&&i.display.from<e.display.from&&(i instanceof br||i instanceof Bl)).sort((i,n)=>n.display.to-i.display.to)[0]||null}renderClipToTransitionTexture(e,t,i){if(!this.pixiApp)return;const n=e.style||{},{renderTransform:s}=e,o=(s?.mirror??0)>.5,a=t instanceof Q?t:Q.from(t),l=s?.x??0,u=s?.y??0,c=s?.angle??0,h=s?.scale??1,d=s?.opacity??1,f=s?.blur??0,p=s?.brightness??1,m=a.width||1,g=a.height||1,v=e.type==="Caption",x=!v&&e.width&&e.width!==0?Math.abs(e.width)/m:1,y=!v&&e.height&&e.height!==0?Math.abs(e.height)/g:1,b=new Pe;b.x=e.center.x+l,b.y=e.center.y+u,b.rotation=(e.flip==null?1:-1)*((e.angle+c)*Math.PI)/180,b.alpha=e.opacity*d;const T=new Je(a);T.anchor.set(.5,.5);let P=[];if(o){const U=x*h,X=y*h,D=m*U,k=g*X;T.position.set(0,0),T.scale.set(U,X);const Y=[[D,0,-U,X],[-D,0,-U,X],[0,k,U,-X],[0,-k,U,-X],[D,k,-U,-X],[-D,k,-U,-X],[D,-k,-U,-X],[-D,-k,-U,-X]];for(const[H,$,K,we]of Y){const Ie=new Je(a);Ie.anchor.set(.5,.5),Ie.position.set(H,$),Ie.scale.set(K,we),P.push(Ie)}if(e.flip==="horizontal"){T.scale.x=-U;for(let H=0;H<8;H++)P[H].scale.x=-Y[H][2]}else if(e.flip==="vertical"){T.scale.y=-X;for(let H=0;H<8;H++)P[H].scale.y=-Y[H][3]}b.addChild(T);for(const H of P)b.addChild(H)}else e.flip==="horizontal"?(T.scale.x=-x*h,T.scale.y=y*h):e.flip==="vertical"?(T.scale.x=x*h,T.scale.y=-y*h):(T.scale.x=x*h,T.scale.y=y*h),b.addChild(T);const A=[];if(f>0){const U=new ys;U.strength=f,U.quality=4,U.repeatEdgePixels=!0,A.push(U)}if(p!==1){const U=new Ro;U.brightness(p,!1),A.push(U)}b.filters=A;const E=n.borderRadius||0;let _=null;E>0&&(_=new Ze,_.roundRect(-m/2,-g/2,m,g,Math.min(E,m/2,g/2)),_.fill({color:16777215,alpha:1}),T.addChild(_),T.mask=_);const S=n.stroke;let I=null;if(S&&S.width>0){I=new Ze;const U=yt(S.color)??16777215;if(I.setStrokeStyle({width:S.width,color:U,alignment:1}),E>0){const X=Math.min(E,m/2,g/2);I.roundRect(-m/2,-g/2,m,g,X)}else I.rect(-m/2,-g/2,m,g);I.stroke(),T.addChild(I)}const M=n.dropShadow;let O=null;if(M&&(M.blur>0||M.distance>0)){O=new Ze;const U=yt(M.color)??0,X=M.alpha??.5,D=M.distance??0,k=M.angle??0,Y=Math.cos(k)*D,H=Math.sin(k)*D;if(E>0){const $=Math.min(E,m/2,g/2);O.roundRect(-m/2+Y,-g/2+H,m,g,$)}else O.rect(-m/2+Y,-g/2+H,m,g);O.fill({color:U,alpha:X}),b.addChildAt(O,0)}this.pixiApp.renderer.render({container:b,target:i,clear:!0}),t instanceof Q||T.texture.destroy(!0),_&&_.destroy(),I&&I.destroy(),O&&O.destroy();for(const U of P)U.destroy();T.destroy(),b.destroy()}removeGlobalEffect(e){this.globalEffects.delete(e)}clearGlobalEffects(){this.globalEffects.clear()}updateActiveGlobalEffect(e){const t=[];for(const i of this.clips)i instanceof Qi&&e>=i.display.from&&(i.display.to===0||e<i.display.to)&&t.push({id:i.id,key:i.effect.key,startTime:i.display.from,duration:i.duration>0?i.duration:i.display.to-i.display.from,trackIndex:this.getTrackIndex(i.id),values:i.effect.values});for(const i of this.globalEffects.values()){const n=i.startTime+i.duration;e>=i.startTime&&e<n&&t.push({id:i.id,key:i.key,startTime:i.startTime,duration:i.duration,trackIndex:-1})}this.activeGlobalEffects=t.sort((i,n)=>(n.trackIndex??-1)-(i.trackIndex??-1))}async applyGlobalEffects(e){if(this.currentGlobalEffectSprite&&(this.currentGlobalEffectSprite.parent&&this.currentGlobalEffectSprite.parent.removeChild(this.currentGlobalEffectSprite),this.currentGlobalEffectSprite.destroy(),this.currentGlobalEffectSprite=null),this.activeGlobalEffects.length===0||!this.pixiApp||!this.clipContainer||!this.clipsNormalContainer||!this.clipsEffectContainer)return;const t=this.opts.width,i=this.opts.height;let n=null,s=new Set;const o=[];for(const a of this.activeGlobalEffects){const{key:l,startTime:u,duration:c,trackIndex:h,values:d}=a,f=e-u,p=Math.min(Math.max(f/c,0),1);if(p<0||p>=1)continue;if(this.clipsEffectContainer.visible=!0,this.clipsEffectContainer.removeChildren(),n){const y=new Je(n);y.label="PrevEffectResult",y.width=t,y.height=i,this.clipsEffectContainer.addChild(y)}const m=h??-1;for(const y of this.clips){if(s.has(y.id))continue;const b=this.getTrackIndex(y.id);!(y instanceof Qi)&&(m===-1||b>m)&&(this.moveClipToEffectContainer(y,!0),s.add(y.id))}let g=this.effectFilters.get(l);if(!g)try{if(g=await l1({name:l,renderer:this.pixiApp.renderer,values:d}),g)this.effectFilters.set(l,g);else continue}catch(y){console.error(y);continue}const v=Ot.create({width:t,height:i});o.push(v),this.pixiApp.renderer.render({container:this.clipsEffectContainer,target:v,clear:!0});const x=g.render({canvasTexture:v,progress:p,width:t,height:i,values:d});this.clipsEffectContainer.visible=!1,n=x}if(n){const a=new Je(n);a.x=0,a.y=0,a.width=t,a.height=i,a.scale.set(1),a.zIndex=5,this.clipContainer.addChild(a),this.currentGlobalEffectSprite=a}for(const a of o)a.destroy(!0)}destroy(){if(!this.destroyed){window.removeEventListener("resize",this.handleResize),this.destroyed=!0,this.stop(),this.clear(),this.transitionRenderers.clear(),this.transFromTexture&&(this.transFromTexture.destroy(!0),this.transFromTexture=null),this.transToTexture&&(this.transToTexture.destroy(!0),this.transToTexture=null),this.transBgGraphics&&(this.transBgGraphics.destroy(!0),this.transBgGraphics=null);for(const e of this.transitionSprites.values())e.destroy();this.transitionSprites.clear(),this.pixiApp&&(this.pixiApp.destroy(!0,{children:!0,texture:!0}),this.pixiApp=null)}}selectClip(e,t=!1){this.selection.selectClip(e,t)}setSelection(e){this.selection.setSelection(e)}selectClipsByIds(e){this.selection.selectClipsByIds(e)}deselectClip(){this.selection.deselectClip()}async lockClip(e,t){const i=this.timeline.getClipById(e);i&&(await this.timeline.updateClip(e,{locked:t}),this.emit("clip:lock-changed",{clip:i,locked:t}),this.selection.selectedClips.has(i)&&this.selection.recreateTransformer(),await this.updateFrame(this.currentTime))}exportToJSON(){return this.timeline.exportToJSON()}async loadFromJSON(e){return this.timeline.loadFromJSON(e)}}xe.add($T),xe.mixin(Pe,eC),xe.add(Ox),xe.add(Ux),xe.add(Ly),xe.mixin(Pe,pP),xe.add(Oy),xe.add(yb),xe.add(kc),xe.add(_b),xe.add(Cb),xe.add(Ab),xe.add(Nb),xe.add(Lb),xe.add(Mb),xe.add(Ub),xe.add(Db),xe.add(kb),xe.add(Pb),xe.add(Ky),xe.add(Yy);const Ete=Object.freeze(Object.defineProperty({__proto__:null},Symbol.toStringTag,{value:"Module"})),Pte=Object.freeze(Object.defineProperty({__proto__:null},Symbol.toStringTag,{value:"Module"}));_e.ANIMATABLE_PROPERTIES=FL,_e.Audio=Jr,_e.Caption=On,_e.Compositor=gte,_e.DEFAULT_AUDIO_CONF=rt,_e.Effect=Qi,_e.GL_EFFECT_OPTIONS=bQ,_e.GL_TRANSITION_OPTIONS=pte,_e.Image=Bl,_e.KeyframeAnimation=B,_e.Log=Ue,_e.MP4Clip=br,_e.Placeholder=kl,_e.Studio=Ate,_e.Text=Ki,_e.Transition=Bi,_e.VALUES_FILTER_SPECIAL=a1,_e.VALUES_FILTER_SPECIAL_LIMITS=lee,_e.Video=br,_e.animationRegistry=z,_e.clipToJSON=Rl,_e.createChromakey=TL,_e.createSlowMo=iS,_e.easings=Su,_e.fastConcatMP4=Hk,_e.fixFMP4Duration=Bq,_e.fontManager=L4,_e.getAllEffects=jb,_e.getAllTransitions=qo,_e.getEasing=Y0,_e.getEffectOptions=Yk,_e.getPresetTemplate=V,_e.getTransitionOptions=D4,_e.jsonToClip=Xo,_e.makeEffect=l1,_e.makeTransition=c1,_e.mixinMP4AndAudio=Mq,_e.registerCustomEffect=vQ,_e.registerCustomTransition=dte,_e.renderTxt2ImgBitmap=kL,_e.unregisterCustomEffect=xQ,_e.unregisterCustomTransition=fte,Object.defineProperty(_e,Symbol.toStringTag,{value:"Module"})}));
@@ -95,6 +95,13 @@ export declare class TimelineModel {
95
95
  trimSelected(trimFromSeconds: number): Promise<void>;
96
96
  updateSelected(updates: Partial<IClip>): Promise<void>;
97
97
  setTracks(tracks: StudioTrack[]): Promise<void>;
98
+ /**
99
+ * Reconciles the tracks list with the available clips.
100
+ * 1. Filters each track's clipIds to only include IDs present in this.clips.
101
+ * 2. Removes any tracks that are then empty.
102
+ * This is used as a safety net to ensure no orphaned empty tracks or dangling references remain.
103
+ */
104
+ reconcileTracks(): void;
98
105
  private ensureFontsForClips;
99
106
  recalculateMaxDuration(): Promise<void>;
100
107
  private setupPlaybackForClip;
package/dist/studio.d.ts CHANGED
@@ -148,6 +148,10 @@ export declare class Studio extends EventEmitter<StudioEvents> {
148
148
  private renderingSuspended;
149
149
  private historyPaused;
150
150
  private processingHistory;
151
+ /**
152
+ * Indicates if the studio is currently restoring state from history (undo/redo)
153
+ */
154
+ isRestoring: boolean;
151
155
  private historyGroupDepth;
152
156
  private clipCache;
153
157
  private _isUpdatingLayout;
@@ -1,4 +1,4 @@
1
- import { e as a, R as e, T as d, G as i, b as s, M as t, c as p, d as P, f as n, g as r, B as T, H as l, h as c, i as m, N as x, j as S, k as o } from "./index-xULbfbWy.js";
1
+ import { e as a, R as e, T as d, G as i, b as s, M as t, c as p, d as P, f as n, g as r, B as T, H as l, h as c, i as m, N as x, j as S, k as o } from "./index-CqBdAdbt.js";
2
2
  a.add(e);
3
3
  a.add(d);
4
4
  a.add(i);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "openvideo",
3
- "version": "0.2.14",
3
+ "version": "0.2.15",
4
4
  "description": "Video rendering and processing library",
5
5
  "type": "module",
6
6
  "publishConfig": {