stormcloud-video-player 0.7.7 → 0.7.9

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 +1 @@
1
- {"version":3,"sources":["/home/ubuntu24-new/Dev/stormcloud-vp/lib/ui/OverlayRenderer.cjs","../../src/ui/OverlayRenderer.tsx","../../src/utils/overlays.ts"],"names":["__create","Object","create","__defProp","defineProperty","__getOwnPropNames","__getOwnPropDesc","getOwnPropertyDescriptor","getOwnPropertyNames","__getProtoOf","getPrototypeOf","__hasOwnProp","prototype","hasOwnProperty","__export","target","all","name","get","enumerable","__copyProps","to","from","except","desc","key","call","__toESM","mod","isNodeMode","__esModule","value","__toCommonJS","OverlayRenderer_exports","OverlayRenderer","module","exports","import_react","require","OVERLAY_API_BASE","timeStringToSeconds","timeStr","parts","split","length","hours","parseInt","minutes","secStr","dotIdx","seconds","indexOf","substring","msFrag","ms","padEnd","num","parseFloat","isFinite","Math","max","isOverlayActive","overlay","visible","currentTime","startSec","start_time","durationSec","duration","resolveImageUrl","imageUrl","apiBaseUrl","startsWith","url","URL","origin","import_jsx_runtime","computeVideoDimensions","video","nativeWidth","videoWidth","nativeHeight","videoHeight","displayWidth","offsetWidth","displayHeight","offsetHeight","videoAspect","displayAspect","renderWidth","renderHeight","offsetX","offsetY","scaleX","scaleY","ImageOverlay","src","image_url","jsx","alt","draggable","style","width","height","objectFit","display","pointerEvents","userSelect","TextOverlay","text","content","justifyContent","color","fontSize","fontFamily","fontWeight","textAlign","padding","boxSizing","wordBreak","textShadow","lineHeight","children","ScrollerOverlay","cfg","scroller_config","use_custom_text","custom_text","scrollSpeed","scroll_speed","direction","font_size","font_family","font_weight","textColor","text_color","bgColor","background_color","bgOpacity","background_opacity","borderColor","border_color","borderWidth","border_width","borderRadius","border_radius","isVertical","isReverse","animId","id","keyframes","jsxs","Fragment","overflow","alignItems","backgroundColor","hexToRgb","border","whiteSpace","animation","parseConfig","JSON","parse","ScoreBugOverlay","size","f","w","flexDirection","background","flex","gap","homeTeam","homeScore","opacity","period","clock","awayTeam","awayScore","sponsorText","borderTop","accentColor","LowerThirdOverlay","h","headline","marginTop","subtitle","QrCodeOverlay"],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;IACA,EAAIA,WAAWC,OAAOC,MAAM;IAC5B,EAAIC,EAAAA,MAAAA,IAAYF,EAAAA,KAAOG,GAAAA,WAAc;YACdH,UACnBI;QADAC,IAAAA,WAAAA,GAAmBL,OAAAA,WAAAA,KAAOM,CAAAA,EAAAA,cAAPN,sBAAAA,CAAOM,UAAAA,KAAAA,OAAAA,CAAwB;QAClDF,IAAAA,WAAAA,WAAAA,KAAoBJ,CAAAA,EAAAA,cAApBI,sBAAAA,WAA2BG,mBAAmB;QAC9CC,IAAAA,UAAeR,QAAOS,OAAAA,CAAAA,MAAc;QACpCC,IAAAA,SAAeV,EAAAA,MAAOW,GAAAA,MAAS,CAACC,IAAAA,IAAAA,QAAc,SAAA,CAAA,GAAA,WAAA,SAAA,OAAA;QAC9CC,IAAAA,KAAW,KAAA,WAAA,IAACC,QAAAA,CAAQC,QAAAA,CAAAA,UAAAA,KAAAA;QACtB,IAAK,EAAIC,IAAAA,KAAQD,KACfb,SAAAA,CAAUY,OAAAA,EAAQE,IAAAA,CAAAA,CAAM,EAAA,KAAA,SAAA,CAAA,GAAA,IAAA,OAAA,IAAA;YAAEC,GAAAA,EAAKF,GAAG,CAACC,KAAAA,CAAK,IAAA,WAAA,MAAA;UAAEE,YAAY;MAAK,EAAA,MAAA,WAAA;IAC/D,OAAA,SAAA,OAAA,KAAA,GAAA,CAAA,GAAA,OAAA;AACA,IAAIC,cAAc,qBAACC,IAAIC,MAAMC,QAAQC;IACnC,IAAIF,CAAAA,OAAQ,CAAA,OAAOA,CAAAA,OAAAA,EAAAA,WAAAA,gBAAP,SAAOA,KAAG,MAAM,YAAY,OAAOA,SAAS,YAAY;cAC7D,GAAA,OAAA,EAAA,OAAA,eAAA,2BAAA;;;kBAAA,IAAIG,CAAAA,GAAAA,EAAJ,KAAA;kBACH,IAAI,CAACd,GAAAA,UAAae,EAAAA,EAAI,CAACL,IAAII,OAAAA,CAAQA,QAAQF,EAAAA,MACzCpB,UAAUkB,IAAII,KAAK;oBAAEP,KAAK,SAALA;+BAAWI,EAAAA;qBAAI,CAACG,IAAI,4DAAA;;sBAAEN,KAAAA,CAAAA,MAAY,CAAEK,CAAAA,MAAAA,CAAOlB,QAAAA,SAAiBgB,CAAAA,CAAAA,IAAMG,IAAG,KAAMD,KAAKL,UAAU;oBAAC;;cAFpH,GAAA,KAAK,KAAA,CAAA,MAAWd,kBAAkBiB,0BAA7B,SAAA,6BAAA,QAAA,yBAAA;;gBAAA,MAAA,IAAA,IAAA;kBAAA,CAAA,GAAA,OAAA,IAAA,MAAA,EAAA,OAAA;;;yBAAA,6BAAA;sBAAA;;;0BAAA,GAAA;;;;MAGP,EAAA,eAAA,MAAA,WAAA;MACA,EAAA,CAAA,IAAOD,WAAAA,CAAAA,cAAAA,OAAAA;IACT,IAAA,eAAA,MAAA,WAAA;IACA,EAAIM,EAAAA,MAAU,UAAA,MAAA,CAACC,KAAKC,MAAAA,MAAYd;aAAYA,SAASa,GAAAA,CAAAA,GAAO,OAAO5B,KAAAA,IAASS,GAAAA,UAAamB,QAAQ,CAAC,GAAGR,YACnG,sEAAsE;MACtE,EAAA,cAAA,cAAA,iCAAiE;MACjE,EAAA,gBAAA,eAAA,mCAAsE;MACtE,EAAA,mEAAqE;MACrES,EAAAA,YAAc,CAACD,OAAO,CAACA,IAAIE,UAAU,GAAG3B,UAAUY,QAAQ,WAAW;UAAEgB,OAAOH;UAAKT,YAAY;MAAK,EAAA,GAAKJ,QACzGa,GAAAA,eAAAA;;QAEEI,eAAe,eAAA,OAACJ;eAAQR,GAAAA,SAAYjB,UAAU,CAAC,GAAG,cAAc;YAAE4B,MAAAA,CAAO,gBAAA,YAAA,IAAA;MAAK,IAAIH,CAAAA;;QAEtF,cAAA,WAA6B,KAAA;QC7B7BK,UAAAA,CAAAA,eAAA,CAAA,UAAA,IAAA;QAAAnB,KAAAmB,KAAAA,oBAAA;MAAAC,iBAAA,SAAAA;iBAAAA;;QAAA,cAAA;QAAAC,GAAAC,OAAA,GAAAJ,CAAAA,YAAAC;QAAAI,eAAgEV,QAAAW,QAAA,UAAA;QDqChE,SAAA,oBAAwB;iBErClBC,mBAAmB;QAwElB,KAASC,GAAAA,cAAAA,GAAoBC,OAAA;QAClC,IAAI,CAACA,GAAAA,MAAS,OAAO,EAAA;MAErB,IAAMC,QAAQD,QAAQE,KAAA,CAAM;IAE5B,IAAID,MAAME,MAAA,IAAU,GAAG;YACEF,SACEA,CAAAA,KACVA;QADUA,UAAAA,MAAAA,OACVA;QAFf,IAAMG,EAAAA,MAAQC,UAASJ,QAAAA,EAAAA,KAAA,CAAM,CAAA,CAAC,GAAA,WAAPA,qBAAAA,UAAY,KAAK,OAAO;UAC/C,IAAMK,OAAAA,GAAUD,UAASJ,WAAAA,KAAA,CAAM,EAAC,cAAPA,sBAAAA,WAAY,KAAK,OAAO;UACjD,CAAA,AAAeA,GAATM,UAASN,GAAAA,CAAAA,GAAAA,IAAAA,KAAA,CAAM,EAAC,OAAA,GAAA,IAAPA,EACf,IAAMO,GACN,IAAMC,EADSF,OADAN,AACOS,CAEpBL,MAFoB,CAAQ,EAEnBG,CAHgB,SAGN,IAAID,OAAOI,SAAA,CAAU,GAAGH,UAAUD,QAAQ,OAAO;eACtE,IAAMK,SAASJ,UAAU,IAAID,OAAOI,SAAA,CAAUH,SAAS,KAAK;UAC5D,GAAA,CAAMK,KAAKD,EAAAA,IAAAA,GAASP,SAASO,OAAOE,MAAA,CAAO,GAAG,KAAKH,SAAA,CAAU,GAAG,IAAI,OAAO,IAAI;UAC/E,OAAOP,EAAAA,MAAQ,OAAOE,UAAU,KAAKG,UAAUI,KAAK;QACtD,OAAA;YAEIZ,MAAME,CAAAA,KAAA,KAAW,GAAG;gBACGF,IAAAA,MACVA;YADf,IAAMK,OAAAA,IAAUD,UAASJ,WAAAA,KAAA,CAAM,EAAC,cAAPA,sBAAAA,WAAY,KAAK,OAAO;YACjD,IAAMM,KAAAA,MAASN,WAAAA,KAAA,CAAM,EAAC,cAAPA,sBAAAA,WAAY;YAC3B,IAAMO,UAASD,CAAAA,OAAOG,OAAA,CAAQ;YAC9B,IAAMD,QAAAA,GACJJ,SAASG,WAAU,IAAID,QAAOI,SAAA,CAAU,GAAGH,WAAUD,SAAQ,OAAO;UACtE,IAAMK,UAASJ,WAAU,IAAID,QAAOI,SAAA,CAAUH,UAAS,KAAK;QAC5D,IAAMK,MAAKD,UAASP,SAASO,QAAOE,MAAA,CAAO,GAAG,KAAKH,SAAA,CAAU,GAAG,IAAI,OAAO,IAAI;IAEjF;IAEA,IAAMI,CAAAA,KAAMC,OAAAA,KAAWhB;QAAXgB,EAAWhB,QAAXgB,MAAAA;MACZ,EAAA,GAAOC,IAAAA,KAASF,GAAAA,IAAOG,GAAAA,EAAKC,EAAAA,CAAA,CAAI,GAAGJ,OAAO;IAC5C,OAAA,aAAA,GAAA,CAAA,GAAA,mBAAA,GAAA,EAEO,KAASK,EAId,IAAI,CAACC,QAAQC,CAHbD,MAGa,CAHb,CAGsB,CAFtBE,MAE6B,KAF7B;QAGA,EAAMC,KAAAA,MAAWzB,oBAAoBsB,QAAQI,UAAU;YACjDC,OAAAA,OAAc3B,oBAAoBsB,QAAQM,QAAQ;YACpDD,QAAAA,OAAe,GAAG,OAAO;YAC7B,GAAOH,MAAAA,SAAeC,YAAYD,cAAcC,WAAWE;YAC7D,YAAA;YAkBO,CAASE,eAAAA,CACdC,QAAA;YACAC,OAAAA,MAAAA,iEAAqBhC;YAEjB,CAAC+B,SAAAA,CAAU,OAAO;YAClBA,SAASE,GAAAA,OAAA,CAAW,cAAcF,SAASE,UAAA,CAAW,aAAa;YACrE,OAAOF,KAAAA;YACT,WAAA;YACIA,SAASE,UAAA,CAAW,MAAM;YAC5B,IAAI,OAAA;gBACF,IAAMC,GAAAA,GAAM,IAAIC,IAAIH;gBACpB,OAAO,CAAA,EAAgBD,OAAbG,IAAIE,MAAM,EAAW,OAARL;YACzB,EAAA,aAAA,EAAQ;gBACN,OAAOA,CAAAA;YACT,YAAA;QACF;QACA,KAAO,GAAiBA,EAAAA,KAAdC,YAAU,KAAY,OAARD;IAC1B;AD5EI,IAAAM,qBAAAtC,QAAA;AA/CJ,SAASuC,gBAAAA,KACPC,CAAA;QADOD,UAAAA,MAAAA,KACPC;;MAEA,EAAMC,MAAAA,QAAcD,MAAME,SAAAA,CAAA;MAC1B,EAAMC,OAAAA,CAAAA,gBAAAA,0BAAAA,IAAAA,GAAeH,MAAMI,MAAAA,KAAAA,CAAA,GAAA,WAAA,GAAA,IAAA,WAAA,GAAA,QAAA,OAAA,KAAA,gBAAA,0BAAA,IAAA,WAAA,KAAA;MAC3B,EAAI,CAACH,qBAAAA,EAAe,CAACE,aAAhBF,0BAAAA,IAAgBE,YAAc,uCAAA,GAAO;MAE1C,EAAME,qBAAAA,gBAAAA,0BAAAA,GAAeL,CAAAA,IAAMM,KAAAA,yCAAAA,EAAA;MAC3B,EAAMC,WAAAA,CAAAA,gBAAAA,0BAAAA,IAAgBP,MAAMQ,GAAAA,IAAAA,GAAA,OAAAA,GAAA,CAAA,SAAA,EAAA,QAAA;MAC5B,EAAI,CAACH,YAAAA,CAAAA,gBAAAA,0BAAAA,IAAgB,AAACE,WAAAA,KAAe,OAAO;MAE5C,EAAME,aAAAA,CAAAA,gBAAAA,0BAAAA,CAAcR,GAAAA,UAAcE,CAAAA,KAAAA;MAClC,EAAMO,YAAAA,CAAAA,gBAAAA,0BAAAA,IAAgBL,UAAAA,KAAeE;MAErC,EAAII,UAAAA,CAAAA,gBAAAA,0BAAAA,IAAAA,gBAAAA,KAAAA;MACJ,EAAIC,YAAAA,CAAAA,gBAAAA,0BAAAA,IAAAA,kBAAAA,MAAAA,KAAAA,IAAAA,IAAAA,kBAAAA,GAAAA,MAAAA;MACJ,EAAIC,cAAAA,CAAAA,gBAAAA,0BAAAA,IAAAA,YAAAA,KAAAA;MACJ,EAAIC,uBAAAA,gBAAAA,0BAAAA,IAAAA,YAAAA,yCAAAA;MAEJ,EAAIL,cAAcC,UAAAA,gBAAAA,0BAAAA,IAAAA,SAAe,IAAA,yCAAA;QAC/BC,mBAAAA,gBAAAA,0BAAAA,IAAcN,OAAAA,yCAAAA;QACdO,aAAAA,EAAeP,YAAAA,GAAeI,KAAAA,cAAAA;QAC9BI,UAAU,EAAA,cAAA,WAAA,cAAA;QACVC,UAAA,AAAWP,CAAAA,GAAAA,KAAAA,GAAAA,CAAAA,GAAAA,CAAgBK,KAAAA,OAAA,IAAgB;MAC7C,EAAA,GAAO,MAAA,eAAA,OAAA,QAAA,EAAA;QACLA,YAAAA,GAAeL,UAAAA,cACDA,CAAgBE,MADfF,QAAAA,2CAEWI,OADZJ,YAAgBE,UAAAA,QAAAA,+CACW,OAAfE,MAAA,IAAe,EAAA,SAAA,SAAA,mBACzCG,MAAU,QACZ,OADY,QAAA,2CAGL,OAFP,YAAA,UAAA,QAAA,+CAEO,OAAA,YAAA,SAAA,SAAA;UAELX,CAAAA,aAAAA,GAAAA,CAAAA,GAAAA,mBAAAA,IAAAA,EAAAA,mBAAAA,QAAAA,EAAAA;QAAAA,UAAAA;gBACAE,SAAAA,GAAAA,CAAAA,CAAcM,EAAAA,mBAAAA,GAAAA,EAAAA,SAAAA;gBAAAA,UAAAA;YAAAA;gBACdJ,SAAAA,GAAAA,CAAAA,EAAeK,CAAAA,mBAAAA,GAAAA,IACfC,OACAC,EADAD,OACAC;gBACAC,OAAAA,CAAQJ,cAAcV;oBACtBe,MAAQJ,CAAAA,cAAeT;oBACzB,QAAA;oBACF,UAAA;oBAESc,SAAAA,GAAa,KAAU;oBAARjC,QAAF,IAAA,EAAEA;oBAChBkC,IAAM3B,aAAAA,GAAgBP,QAAQmC,CAAAA,IAAAA,GAAA,KAAa,OAAA,SAAA,UAAA,MAAA,OAAA,WAAA,OAAA,KAAA;oBAC5CD,IAAK,IAAA,GAAO,WAAA,IAAA,GAAA,OAAA,aAAA,aAAA,OAAA,eAAA,KAAA;oBACjB,CACE,aAAA,GAAA,CAAA,GAAApB,QAAAA,IAAAA,GAAC,OAADA,IAAAsB,GAAA,EAAC,KAAA,GAAA,KAAA,KAAA;oBACCF,GAAAA,MAAAA,GAAAA,OAAAA,SAAAA;oBACAG,GAAKrC,QAAQ7C,IAAA;oBACbmF,SAAW,MAAA;gBACXC,OAAO;oBACLC,MAAAA,AAAO,CAAA,YAAA,GAAA,CAAA,GAAA,mBAAA,GAAA,IACPC,OACAC,CADQ,UACG;oBACXC,OAAAA,EAAS;wBACTC,YAAAA,CAAe;wBACfC,UAAAA,AAAY;wBACd,YAAA;wBAAA,YAAA;wBAGN,OAAA;wBAESC,OAAY,IAAA,AAAU,GAAA,OAAA,QAAA,KAAA,OAAA,aAAA;wBAAR9C,IAAF,MAAEA,EAAAA;wBACf+C,CAAO/C,QAAQgD,GAAAA,IAAA,IAAW;oBAE9B,YAAA,GAAA,CAAA,GAAAlC,mBAAAsB,GAAA,EAAC,OAAA;oBACCG,GAAO,OAAA;kBACLC,OAAO;kBAEPG,SAAS;;YAETM,gBAAgB;YAChBC,OAAO;YACPC,SAAAA,CAAU,MAAA;cACVC,IAAAA,OAAAA,CAAY;cACZC,YAAY;gBACZC,IAAAA,KAAAA,CAAAA,CAAW;uBACXC,SAAS;gBACTC,WAAW;cACXC,WAAW;YACXC,YAAY;YACZd,aAAAA,KAAe;kBAAfA,MAAe,SAAA,OAAfA,MAAe;YACfC,EAAAA,UAAY,EAAA,QAAA,OAAA;cACZc,OAAAA,KAAY;QACd,IAAA,KAAA,GAAA,CAAA,GAAA,KAAA,CAAA,GAAA;UAECC,CAAAb,AAAAa,SAAAb,IAAAA,GAAAA,CAAAA,GAAAA,mBAAAA,IAAAA,EAAAA,OAAAA;QAAAA,OAAAA;YAAAA,OAAAA;YAAAA,QAAAA;YAAAA,cAAAA,KAAAA,GAAAA,CAAAA,GAAAA,KAAAA,CAAAA,GAAAA;YAAAA,SAAAA;YAAAA,eAAAA;YAAAA,YAAAA,IAAAA,eAAAA;YAAAA,OAAAA,IAAAA,SAAAA;YAAAA,YAAAA;YAAAA,UAAAA;YAAAA,eAAAA;YAAAA,YAAAA;YAAAA,UAAAA,GAAAA,OAAAA,GAAAA;QAAAA;QAAAA,UAAAA;YAAA,aAAA,GAAA,CAAA,GAAA,mBAAA,IAAA,EAAA,OAAA;gBAAA,OAAA;oBAAA,MAAA;oBAAA,SAAA;oBAAA,YAAA;oBAAA,SAAA,KAAA,OAAA,IAAA,KAAA;oBAAA,KAAA,IAAA;gBAAA;gBAAA,UAAA;oBAGP,aAAA,GAAA,CAAA,GAAA,mBAAA,IAAA,EAAA,OAAA;wBAAA,OAAA;4BAAA,MAAA;4BAAA,WAAA;wBAAA;wBAAA,UAAA;4BAEA,CAASc,YAAAA,IAAgB,GAAA,EAAU,iBAAA,GAAA,EAAA,OAAA;gCAAA,OAAA;oCAAA,UAAA;oCAAA,YAAA;gCAAA;gCAAA,UAAA,IAAA,QAAA;4BAAA;4BAAR7D,UAAF,GAAA,GAAEA,CAAAA,GAAAA,mBAAAA,GAAAA,EAAAA,OAAAA;gCAAAA,OAAAA;oCAAAA,UAAAA;oCAAAA,YAAAA;oCAAAA,YAAAA;gCAAAA;gCAAAA,UAAAA,IAAAA,SAAAA;4BAAAA;;;oBACzB,EAAM8D,MAAM9D,KAAAA,GAAQ+D,CAAAA,GAAAA,WAAA,QAAA,IAAA,EAAA,OAAA;wBAAA,OAAA;4BAAA,UAAA;4BAAA,WAAA;4BAAA,SAAA;4BAAA,SAAA,KAAA,OAAA,IAAA,KAAA;wBAAA;wBAAA,UAAA;4BACdhB,OACJe,CAAAA,KAAAA,GAAAA,CAAAA,GAAAA,IAAAA,eAAAA,GAAAA,EAAAA,MAAAA,CAAAA;gCAAAA,CAAKE,SAAAA,IAAAA,EAAA,IAAA;4BAAmBF,IAAIG,WAAA,GACxBH,IAAIG,WAAA,GACJjE,QAAQgD,OAAA,KAAWc,gBAAAA,0BAAAA,IAAKG,WAAA,KAAe;4BAEvCC,aAAAA,GAAAA,CAAAA,GAAAA,EAAcJ,gBAAAA,CAAAA,GAAAA,EAAAA,OAAAA;gCAAAA,UAAAA,CAAAA,GAAAA,CAAKK,IAAAA;4BAAAA,OAAA,uCAAgB;yBACzC;oBAAMC,qBAAYN,gBAAAA,0BAAAA,IAAKM,SAAA,yCAAa;oBACpC,EAAMjB,WAAWW,CAAAA,EAAAA,CAAAA,GAAAA,UAAAA,SAAAA,IAAAA,EAAAA,OAAAA;wBAAAA,EAAAA,IAAKO,CAAAA;4BAAAA,MAAA;4BAAA,CAAY,GAAgB,OAAbP,IAAIO;wBAAAA;wBAAAA,CAAS,EAAA,OAAA,CAAO;4BACnDjB,aAAaU,CAAAA,EAAAA,CAAAA,GAAAA,UAAAA,SAAAA,GAAAA,EAAAA,OAAAA;gCAAAA,GAAAA,IAAKQ;oCAAAA,SAAA,CAAA,IAAe;oCAAA,YAAA;gCAAA;gCAAA,UAAA,IAAA,QAAA;4BAAA;4BACjCjB,aAAaS,CAAAA,EAAAA,CAAAA,GAAAA,UAAAA,SAAAA,GAAAA,EAAAA,OAAAA;gCAAAA,GAAAA,IAAKS;oCAAAA,SAAA,CAAA,IAAe;oCAAA,YAAA;oCAAA,YAAA;gCAAA;gCAAA,UAAA,IAAA,SAAA;4BAAA;yBACvC;oBAAMC,YAAYV,CAAAA,gBAAAA,0BAAAA,IAAKW,UAAA,KAAc;iBACrC;YAAA,EAAMC,UAAUZ,CAAAA,gBAAAA,0BAAAA,IAAKa,gBAAA,KAAoB;YACzC,IAAMC,WAAAA,CAAYd,CAAAA,EAAAA,aAAAA,CAAAA,EAAAA,CAAAA,GAAAA,mBAAAA,CAAAA,EAAAA,EAAKe,OAAAA;gBAAAA,OAAAA;oBAAA,MAAuB,IAAA,CAAA,IAAYf;oBAAIe,WAAAA,OAAA;oBAAqB,MAAM,GAAA;oBAAA,SAAA,GAAA,OAAA,IAAA,KAAA;oBAAA,WAAA,aAAA,OAAA,IAAA,WAAA,EAAA;gBAAA;gBAAA,UAAA,IAAA,WAAA;YAAA;;IACzF,IAAMC,cAAchB,CAAAA,gBAAAA,0BAAAA,IAAKiB,YAAA,KAAgB;IACzC,IAAMC,uBAAclB,gBAAAA,0BAAAA,IAAKmB,YAAA,yCAAgB;IACzC,IAAMC,CAAAA,kBAAAA,KAAepB,IAAAA,0BAAAA,IAAKqB,aAAA,yCAAiB;QAArCD,UAAAA,MAAAA,GAAepB,MAAAA,OAAfoB,MAAepB;MACrB,EAAMP,MAAAA,YAAAA,CAAUO,OAAAA,OAAAA,EAAAA,0BAAAA,IAAKP,OAAA,yCAAW;MAEhC,EAAA,CAAA,CAAM6B,IAAAA,OAAAA,EAAahB,cAAc,QAAQA,cAAc;MACvD,EAAMiB,IAAAA,KAAAA,GAAYjB,CAAAA,GAAAA,KAAAA,CAAAA,GAAAA,CAAc,WAAWA,cAAc;MAEzD,IAAM/D,CAAAA,AAAcR,aAAAA,GAAAA,CAAAA,CAAKC,EAAAA,CAAA,CAAI,GAAG,MAAMoE,QAAAA,IAAAA,EAAAA,OAAAA;QAAAA,OAAAA;YAAAA,OAAAA;YAAAA,QAAAA;YAAAA,cAAAA,KAAAA,GAAAA,CAAAA,GAAAA,KAAAA,CAAAA,GAAAA;YAAAA,SAAAA;YAAAA,eAAAA;YAAAA,gBAAAA;YAAAA,YAAAA,IAAAA,eAAAA;YAAAA,OAAAA,IAAAA,SAAAA;YAAAA,YAAAA;YAAAA,UAAAA;YAAAA,eAAAA;YAAAA,YAAAA;YAAAA,UAAAA,GAAAA,OAAAA,GAAAA;QAAAA;QAAAA,UAAAA;YAEtC,IAAMoB,SAAS,GAAA,CAAA,GAAA,QAAyB,OAAVtF,IAAAA,GAAAA,CAAQuF,CAAAA,CAAE,MAAA;gBAAA,OAAA;oBAAA,OAAA;oBAAA,QAAA,KAAA,GAAA,CAAA,GAAA,KAAA,CAAA,GAAA;oBAAA,iBAAA,IAAA,WAAA;gBAAA;YAAA;YACxC,IAAMC,SAAAA,GAAYJ,CAAAA,GAAAA,SACd,UAAA,IAAA,AAC+BC,EAAAA,KADjBC,EAAAA;gBAAAA,IAAM,GAAA;oBAAA,MAAA;oBAAA,SAAA;oBAAA,YAEaD,GAAAA,IADFA;oBAAAA,MAAY,UAAU,QAAM;oBAAA,SAAA,GAAA,OAAA,IAAA,KAAA,OAAA,OAAA,IAAA,KAAA;gBAAA;gBAAA,KACE,KAAA,EAA5BA,YAAY,SAAS,SAAO,mBAE7D,cAC+BA,OADjBC,QAAM,2CAEaD,OADFA,YAAY,UAAU,QAAM,+CACE,OAA5BA,YAAY,SAAS,SAAO;oBAGjE,KACE,QAAA,GAAA,CAAA,CAAA,EAAA,CAAA,CAAA,GAAAvE,cAAAA,GAAAA,EAAA2E,IAAA,EAAA3E,CAAAA;wBAAAA,OAAAA;4BAAAA,OAAA4E,GAAAA,KAAA,EAAA;4BAAA,YAAA;4BAAA,YAAA;4BAAA,YAAA;wBAAA;wBAAA,UAAA,IAAA,QAAA;oBAAA;sBACE9B,UAAA,CAAA,GAAA,CAAA,GAAA,mBAAA,GAAA,EAAA,OAAA;wBAAA,OAAA;4BAAA,UAAA;4BAAA,SAAA;4BAAA,WAAA,IAAA;wBAAA;wBAAA,UAAA,IAAA,QAAA;oBAAA;;kBAAA,aAAA,GAAA,CAAA,GAAA9C,mBAAAsB,GAAA,EAAC,SAAA;wBAAOwB,GAAAA,IAAAA,AAAA4B,GAAAA,UAAAA,GAAAA,CAAAA,GAAAA,mBAAAA,GAAAA,EAAAA,OAAAA;gBAAAA,OAAAA;oBAAAA,UAAAA;oBAAAA,SAAAA;oBAAAA,SAAAA,KAAAA,OAAAA,IAAAA,KAAAA,OAAAA,OAAAA,IAAAA,KAAAA;gBAAAA;gBAAAA,UAAAA,IAAAA,WAAAA;YAAAA;;YAAA;YACR,aAAA,GAAA,CAAA,GAAA1E,mBAAAsB,GAAA,EAAC,OAAA;gBACCG,OAAO,KAAA;QAAA,gBAAA,SAAA,aAAA;oBACLC,MAAAA,CAAO,OAAA,OAAA;sBACPC,QAAQ;oBACRkD,EAAAA,GAAAA,CAAAA,IAAU,KAAA,GAAA,CAAA,KAAA,CAAA,EAAA,KAAA,CAAA,IAAA;mBACVhD,SAAS,wCAAA,OAAA,KAAA,KAAA,CAAA,SAAA,IAAA,KAAA,OAAA,KAAA,KAAA,CAAA,SAAA,IAAA,UAAA,OAAA,mBAAA,IAAA,GAAA,IAAA;oBACTiD,CAAAA,GAAAA,KAAAA,CAAAA,EAAY,CAAA;WACZC,WAAAA,EAAAA,GAAAA,CAAAA,GAAAA,QACEjB,WAAAA,CAAY,GAAA,CACR,CAAA,OAA8BA;QAAAA,KAAtBkB,EAAAA;YAAAA,KAASpB,EAAAA;YAAQ,MAAc,EAAA,KAATE;YAAAA,QAAS,MAAA,CACvC,IAAA,CAAA,EAAA,CAAA,GAAA,KAAA,CAAA,GAAA;YAAA,SAAA;YAAA,eAAA;YAAA,YAAA;YAAA,gBAAA;YAAA,KAAA,IAAA;YAAA,YAAA,IAAA,eAAA;YAAA,OAAA,IAAA,SAAA;YAAA,YAAA;YAAA,SAAA,IAAA;YAAA,WAAA;YAAA,eAAA;YAAA,YAAA;YAAA,UAAA;QAAA;QAAA,UAAA;4BACNmB,CAAAA,GAAAA,IACEf,cAAc,CAAA,GAAA,AAAI,EAAA,CAA0BF,MAAAA,CAAvBE;gBAAAA,OAAAA;oBAAAA,GAAW,SAAA;oBAAA,CAAuB,OAAXF,IAAAA;oBAAAA,GAAgB,KAAA,MAAA,KAAA,GAAA,CAAA,GAAA,SAAA;oBAAA,SAAA,KAAA,GAAA,CAAA,GAAA,SAAA;oBAAA,YAAA;gBAAA;gBAAA,UAAA,aAAA,GAAA,CAAA,GAAA,mBAAA,GAAA,EAAA,OAAA;oBAAA,KAAA;oBAAA,KAAA;oBAAA,OAAA;wBAAA,OAAA,GAAA,OAAA,QAAA;wBAAA,QAAA,GAAA,OAAA,QAAA;wBAAA,SAAA;oBAAA;gBAAA;YAAA;4BAC9DI,CAAAA,GAAAA,UAAcA,SAAAA,GAAAA,EAAAA,CAAe,IAAI,EAAA,CAAe;gBAAA,MAAZA,CAAAA;oBAAAA,UAAAA,AAAY,GAAO,OAAP,IAAA,EAAO,GAAA,GAAA;oBAAA,YAAA;oBAAA,WAAA;oBAAA,OAAA,IAAA,WAAA;oBAAA,UAAA;oBAAA,cAAA;oBAAA,YAAA;oBAAA,OAAA;gBAAA;gBAAA,UAAA,IAAA,OAAA;YAAA;4BACvD3B,GAAAA,AAAYA,MAAH,GAAU,IAAA,GAAPA,CAAAA,GAAAA,KAAO,cAAA,GAAA,EAAA,OAAA;gBAAA,OAAA;oBAAA,UAAA,GAAA,OAAA,IAAA,MAAA;oBAAA,SAAA;oBAAA,WAAA;oBAAA,UAAA;oBAAA,cAAA;oBAAA,YAAA;oBAAA,OAAA;gBAAA;gBAAA,UAAA,IAAA,WAAA;YAAA;;oBACnBC,WAAW;oBACXZ,eAAe;gBACjB,aAAA,KAAA;QAAA,UAAA,MAAA,SAAA,OAAA,MAAA;gBAEAgB,UAAA,QAAA,KAAA,EAAA,CAAA,CAAA,GAAA9C,mBAAAsB,GAAA,EAAC,OAAA;sBACCG,OAAO;wBACLyD,KAAAA,CAAAA,GAAAA,GAAY;WACZ7C,eAAAA,CAAAA,CAAAA,GAAAA,KAAAA,cAAAA,IAAAA,EAAAA,OAAAA;QAAAA,OAAAA;YAAAA,OAAAA;YAAAA,QAAAA;YAAAA,cAAAA,KAAAA,GAAAA,CAAAA,GAAAA,KAAAA,CAAAA,GAAAA;YAAAA,SAAAA;YAAAA,YAAAA,IAAAA,eAAAA;YAAAA,OAAAA,IAAAA,SAAAA;YAAAA,YAAAA;YAAAA,UAAAA;YAAAA,eAAAA;YAAAA,YAAAA;YAAAA,UAAAA,GAAAA,OAAAA,GAAAA;QAAAA;QAAAA,UAAAA;gCACAC,YAAAA,OAAAA,GAAAA,EAAAA,OAAAA;gBAAAA,OAAAA;oBAAAA,OAAAA,KAAAA,GAAAA,CAAAA,GAAAA,KAAAA,CAAAA,GAAAA;oBAAAA,YAAAA;oBAAAA,iBAAAA,IAAAA,WAAAA;gBAAAA;YAAAA;gCACAC,YAAAA,OAAAA,IAAAA,EAAAA,OAAAA;gBAAAA,OAAAA;oBAAAA,MAAAA;oBAAAA,SAAAA;oBAAAA,eAAAA;oBAAAA,gBAAAA;oBAAAA,SAAAA,GAAAA,OAAAA,IAAAA,KAAAA,OAAAA,OAAAA,IAAAA,GAAAA;oBAAAA,UAAAA;gBAAAA;gBAAAA,UAAAA;sCACAH,EAAAA,KAAOsB,cAAAA,GAAAA,EAAAA,OAAAA;wBAAAA,OAAAA;4BAAAA,UAAAA;4BAAAA,YAAAA;4BAAAA,eAAAA;4BAAAA,eAAAA;4BAAAA,OAAAA,IAAAA,WAAAA;wBAAAA;wBAAAA,UAAAA;oBAAAA;sCACPyB,EAAAA,SAAW,GAAa5F,OAAViF,GAAAA,EAAAA,GAAM,IAAA,CAAe;wBAAA,MAAXjF,CAAAA;4BAAAA,UAAW;4BAAA,YAAA;4BAAA,YAAA;4BAAA,WAAA,IAAA;4BAAA,UAAA;4BAAA,cAAA;4BAAA,YAAA;wBAAA;wBAAA,UAAA,IAAA,KAAA;oBAAA;sCACnCqD,EAAAA,UAAY,SAAA,GAAA,EAAA,OAAA;wBAAA,OAAA;4BAAA,UAAA;4BAAA,SAAA;4BAAA,UAAA;4BAAA,cAAA;4BAAA,YAAA;wBAAA;wBAAA,UAAA,IAAA,QAAA;oBAAA;sCACZb,GAAAA,AAAY,SAAA,IAAA,GAAA,CAAA,GAAA,mBAAA,GAAA,EAAA,OAAA;wBAAA,OAAA;4BAAA,UAAA;4BAAA,YAAA;4BAAA,WAAA,IAAA;4BAAA,OAAA,IAAA,WAAA;wBAAA;wBAAA,UAAA,IAAA,aAAA;oBAAA;;0BACd;;oBAECe,UAAAb;gBAAA;YACH,sBAAA,KAAA;QAAA,UAAA,MAAA,SAAA,OAAA,MAAA;SACF,KAAA,YAAA,QAAA,OAAA;MAAA,EAAA,CAAA,KAAA,OAAA;IAGN,IAAA,QAAA;QAAA,OAAA;QAAA,aAAA;QAAA,MAAA;QAAA,SAAA;IAAA;IAEA,IAAA,CAASmD,GAAAA,KAAAA,GAAAA,CAAelD,GAAAA,IAAA,CAAA,CAAA,GAAA;MACtB,IAAI,CAACA,AAAgB,SAAP,IAAA,GAAO,CAAA,GAAA,mBAAA,IAAA,EAAA,OAAA;QAAA,OAAA;YAAA,OAAA;YAAA,QAAA;YAAA,cAAA,KAAA,GAAA,CAAA,GAAA,KAAA,CAAA,GAAA;YAAA,SAAA;YAAA,YAAA;YAAA,KAAA,IAAA;YAAA,SAAA,KAAA,OAAA,IAAA,KAAA;YAAA,YAAA,IAAA,eAAA;YAAA,OAAA,IAAA,SAAA;YAAA,YAAA;YAAA,YAAA,GAAA,OAAA,KAAA,GAAA,CAAA,GAAA,KAAA,CAAA,GAAA,OAAA,aAAA,OAAA,IAAA,WAAA;YAAA,WAAA;YAAA,eAAA;YAAA,YAAA;YAAA,UAAA,GAAA,OAAA,GAAA;QAAA;QAAA,UAAA;YACrB,IAAI,SAAA,GAAA,CAAA,GAAA,mBAAA,GAAA,EAAA,QAAA;gBAAA,OAAA;oBAAA,UAAA;oBAAA,YAAA;gBAAA;gBAAA,UAAA,KAAA,CAAA,IAAA,QAAA,CAAA,IAAA;YAAA;gBAAE,OAAOmD,EAAAA,GAAKC,CAAAA,GAAAA,CAAA,CAAMpD,iBAAAA,IAAAA,EAAAA,OAAAA;gBAAAA,OAAAA;oBAAAA,MAAAA;oBAAAA,UAAAA;gBAAAA;gBAAAA,UAAAA;oBAAe,aAAA,EAAQ,CAAA,CAAA,GAAA,mBAAA,GAAA,EAAA,OAAA;wBAAA,OAAA;4BAAA,UAAA;4BAAA,YAAA;4BAAA,UAAA;4BAAA,cAAA;4BAAA,YAAA;wBAAA;wBAAA,UAAA,IAAA,QAAA;oBAAA;sBAAE,OAAO,IAAA,GAAA,CAAA,GAAA,mBAAA,GAAA,EAAA,OAAA;wBAAA,OAAA;4BAAA,UAAA;4BAAA,SAAA;4BAAA,UAAA;4BAAA,cAAA;4BAAA,YAAA;wBAAA;wBAAA,UAAA,IAAA,OAAA;oBAAA;iBAAM;YAAA;SAChE;IAAA;AAaA,SAASqD,gBAAgB,KAAgB;QAAdrG,CAAAA,SAAF,MAAEA,IAAAA,KAAF,CAAWsG;QAATtG,UAAAA,MAAAA,GAASsG,MAAAA,OAATtG,MAASsG,CAAX;MACvB,EAAMxC,MAAMoC,YAAyBlG,QAAQgD,OAAO;MACpD,EAAA,CAAA,CAAI,CAACc,GAAAA,EAAK,KAAA,EAAO;MACjB,EAAMyC,IAAI1G,KAAKC,GAAA,CAAI,GAAGwG,KAAKE,CAAA,GAAI;MAC/B,KAAA,AACE,EAAA,WAAA,EAAA,CAAA,CAAA,CAAA,EAAA,EAAA1F,iBAAAA,EAAA2E,EAAAA,EAAA,EAAC,KAAA;QAAA,OAAA;YAAA,OAAA;YAAA,QAAA;YAAA,cAAA,KAAA,GAAA,CAAA,GAAA,KAAA,CAAA,GAAA;YAAA,SAAA;YAAA,eAAA;YAAA,SAAA,IAAA;YAAA,YAAA,IAAA,eAAA;YAAA,OAAA,IAAA,SAAA;YAAA,YAAA;YAAA,WAAA;YAAA,eAAA;YAAA,YAAA;YAAA,UAAA,GAAA,OAAA,GAAA;QAAA;QAAA,UAAA;gBAAIlD,OAAO,EAAA,GAAA,CAAA,GAAA,mBAAA,GAAA,EAAA,OAAA;gBAAA,OAAA;oBAAA,UAAA;oBAAA,YAAA;oBAAA,eAAA;oBAAA,eAAA;oBAAA,OAAA,IAAA,WAAA;oBAAA,cAAA,IAAA;gBAAA;gBAAA,UAAA,IAAA,UAAA;YAAA;oBAAEC,KAAAA,EAAO,CAAA,CAAA,GAAA,mBAAA,GAAA,EAAA,OAAA;gBAAA,OAAA;oBAAA,MAAA;oBAAA,SAAA;oBAAA,eAAA;oBAAA,KAAA,IAAA;oBAAA,gBAAA;gBAAA;gBAAA,UAAA,CAAA,IAAA,OAAA,IAAA,EAAA,EAAA,KAAA,CAAA,GAAA,GAAA,GAAA,CAAA,SAAA,KAAA;2BAAA,aAAA,GAAA,CAAA,GAAA,mBAAA,IAAA,EAAA,OAAA;wBAAA,OAAA;4BAAA,SAAA;4BAAA,gBAAA;4BAAA,YAAA;4BAAA,SAAA,GAAA,OAAA,IAAA,KAAA,OAAA,OAAA,IAAA,KAAA;4BAAA,cAAA,KAAA,GAAA,CAAA,GAAA,IAAA;4BAAA,YAAA,GAAA,OAAA,IAAA,WAAA,EAAA;4BAAA,UAAA;wBAAA;wBAAA,UAAA;kCAAQC,OAAAA,CAAQ,EAAA,CAAA,GAAA,mBAAA,GAAA,EAAA,QAAA;gCAAA,OAAA;oCAAA,UAAA;oCAAA,cAAA;oCAAA,YAAA;oCAAA,MAAA;gCAAA;gCAAA,UAAA,IAAA,KAAA;4BAAA;kCAAQyC,OAAAA,GAAAA,CAAAA,GAAcrF,KAAKC,GAAA,CAAI,GAAGwG,KAAKE,CAAA,CAAA,GAAI,EAAA,QAAA;gCAAA,OAAA;oCAAA,YAAA;oCAAA,YAAA,IAAA;oCAAA,YAAA;oCAAA,OAAA,IAAA,WAAA;gCAAA;gCAAA,UAAA,IAAA,IAAA;4BAAA;;0BAAQ7D;;YAAAA,QAAS;oBAAQ8D,OAAAA,IAAAA,AAAe,IAAA,SAAA,GAAA,CAAA,GAAA,mBAAA,GAAA,EAAA,OAAA;gBAAA,OAAA;oBAAA,UAAA;oBAAA,SAAA;oBAAA,WAAA;oBAAA,WAAA,IAAA;gBAAA;gBAAA,UAAA,IAAA,WAAA;YAAA;;YAAUC,YAAY5C,IAAI+B,eAAA;YAAiB3C,OAAOY,IAAIU,SAAA;YAAWpB,YAAY,KAAA,KAAA;QAAA,UAAA,MAAA,SAAA,OAAA,MAAA;YAAyCuC,EAAAA,QAAU,IAAA,QAAA,OAAA;cAAU/C,OAAAA,QAAe;YAAQC,YAAY;QAAA,UAAA;QAAA,QAAA;QAAA,QAAA;IAAA;YAAQM,MAAAA,IAAU,GAAI,MAAA,CAADoD,GAAC,CAAA,OAAA,CAAA,IAAA,cAAA,MAAA;QAAK,QAAA,IAAA,OAAA,KAAA,aAAA,aAAA,IAAA,OAAA,KAAA,WAAA,WAAA;QAC9T3C,IAAAA,KAAAA,CAAA,EAAA,CAAA,GAAA,KAAA,CAAA,GAAA;WAAA,GAAA,UAAA,GAAA,CAAA,EAAA,CAAA,GAAA9C,gBAAAA,IAAA2E,EAAAA,CAAA,EAAC,IAAA;QAAA,CAAA,MAAA;YAAA,OAAA;YAAA,QAAA;YAAA,cAAA,KAAA,GAAA,CAAA,GAAA,KAAA,CAAA,GAAA;YAAA,SAAA;YAAA,YAAA;YAAA,YAAA,IAAA,eAAA;YAAA,OAAA,IAAA,SAAA;YAAA,YAAA;YAAA,UAAA;YAAA,eAAA;YAAA,YAAA;YAAA,UAAA,GAAA,OAAA,GAAA;QAAA;QAAA,UAAA;wBAAIlD,CAAAA,GAAAA,CAAAA,EAAO,CAAA,mBAAA,GAAA,EAAA,OAAA;gBAAA,OAAA;oBAAA,SAAA,KAAA,OAAA,IAAA,KAAA;oBAAA,QAAA;oBAAA,SAAA;oBAAA,YAAA;oBAAA,YAAA;oBAAA,OAAA;oBAAA,UAAA;oBAAA,YAAA;oBAAA,eAAA;oBAAA,eAAA;oBAAA,YAAA;gBAAA;gBAAA,UAAA;YAAA;4BAAEoE,CAAAA,GAAAA,EAAM,iBAAA,IAAA,EAAA,OAAA;gBAAA,OAAA;oBAAA,MAAA;oBAAA,SAAA,KAAA,OAAA,IAAA,GAAA;oBAAA,UAAA;gBAAA;gBAAA,UAAA;kCAAGhE,EAAAA,CAAAA,GAAAA,GAAS,gBAAA,GAAA,EAAA,OAAA;wBAAA,OAAA;4BAAA,UAAA;4BAAA,YAAA;4BAAA,UAAA;4BAAA,cAAA;4BAAA,YAAA;wBAAA;wBAAA,UAAA,IAAA,QAAA;oBAAA;gCAAoB,EAAZiD,WAAAA,CAAY,EAAA,CAAA,GAAA,mBAAA,GAAA,EAAA,OAAA;wBAAA,OAAA;4BAAA,UAAA;4BAAA,SAAA;4BAAA,UAAA;4BAAA,cAAA;4BAAA,YAAA;wBAAA;wBAAA,UAAA,IAAA,IAAA;oBAAA;;0BAAUrC,SAAS,KAAY,OAAPgD,IAAI,KAAG;;oBAAMK,KAAKL,IAAI;gBAAI;gBACpG3C,eAAA;QAAA,gBAAA,SAAA,OAAA,MAAA;oBAAA,MAAA,OAAA,CAAA,EAAA,CAAA,GAAA9C,CAAAA,kBAAA2E,IAAA,EAAC,OAAA;QAAW,wBAAA,CAAA,GAAA,aAAA,QAAA,EAAA;QAAA,GAAA;QAAA,GAAA;QAAA,GAAA;QAAA,GAAA;IAAA,oBAAA,aAAPlD,OAAO,IAAA;8BAAEoE,EAAAA,IAAM;gCAAGrD,WAAW;0BAAS;4BACzCM,CAAAA,KAAAA,IAAA,UAAA,EAAA,OAAA;gCAAA,aAAA,GAAA,CAAA,GAAA9C,mBAAAsB,GAAA,EAAC,OAAA;oCAAIG,OAAO,CAAA;0CAAEY,UAAU;4CAAOE,YAAY;wCAAI,KAAA;wCAAIO,IAAAA,MAAAE,IAAI+C,QAAA;oCAAA,CAAA,MAAA;kCACvD,aAAA,GAAA,CAAA,GAAA/F,mBAAAsB,GAAA,EAAC,OAAA;oCAAIG,OAAO;wCAAEY,UAAU;sCAASE,YAAY;;sCAAKM,YAAY;;;;eAAE;kCAAIC,UAAAE,IAAIgD,SAAA;4BAAA,CAAA,CAAA,GAAA;;mBAAU,GAAA,GAAA,QAAA,CAAA,GAAA;;oBAAA;;0BAEpF,IAAA;YAAA,OAAA,GAAA,CAAA,GAAAhG,OAAAA,CAAAA;YAAAA,OAAAA,CAAA2E,IAAA;QAAC,OAAA;;8BAAIlD,CAAAA;YAAAA,IAAO,GAAA,IAAA,UAAA,CAAA;YAAA,OAAA;QAAA;;kCAAEY;YAAAA,OAAAA,EAAU,EAAA,UAAA,CAAA;YAAA,OAAA;QAAA;;kCAASG;YAAAA,OAAAA,GAAW,CAAA,UAAA,CAAA;YAAA,OAAA;QAAA;8BAAUyD,SAAS;8BAAKxD,CAAAA,QAAS,KAAY,MAAA,CAAPgD,GAAAA,CAAI,CAAA,IAAG,GAAA;QAAA,OAAA;YAAA,OAAA;YAAA,QAAA;YAAA,cAAA,KAAA,GAAA,CAAA,GAAA,KAAA,CAAA,GAAA;YAAA,SAAA;YAAA,eAAA;YAAA,YAAA;YAAA,gBAAA;YAAA,SAAA,IAAA;YAAA,YAAA,IAAA,eAAA;YAAA,OAAA,IAAA,SAAA;YAAA,YAAA;YAAA,WAAA;YAAA,eAAA;YAAA,YAAA;YAAA,UAAA,GAAA,OAAA,GAAA;QAAA;QAAA,UAAA;gCAAK,mBAAA,GAAA,EAAA,OAAA;gBAAA,OAAA;oBAAA,UAAA;oBAAA,YAAA;oBAAA,eAAA;oBAAA,eAAA;oBAAA,OAAA,IAAA,WAAA;oBAAA,cAAA,IAAA;gBAAA;gBAAA,UAAA,IAAA,SAAA;YAAA;gCAC5F3C,UAAA,SAAA,GAAA,EAAA,OAAA;gBAAA,OAAA;oBAAA,SAAA;oBAAA,KAAA,IAAA;oBAAA,YAAA;gBAAA;gBAAA,UAAA,MAAA,MAAA,CAAA,SAAA;2BAAA,EAAA,IAAA;mBAAA,GAAA,CAAA,SAAA,GAAA,GAAA;2BAAA,aAAA,GAAA,CAAA,GAAA,mBAAA,IAAA,EAAA,aAAA,OAAA,CAAA,QAAA,EAAA;wBAAA,UAAA;kDAAA,aAAA,GAAA,CAAA,IAAA9C,EAAAA,OAAAA;gCAAAA,OAAAsB;oCAAAA,CAAA,EAAC,OAAA,CAAA;gCAAA;gCAAA,UAAA;4DAAKwB,UAAAE,IAAIkD,CAAAA,GAAAA,EAAA,OAAA;wCAAA,OAAA;4CAAA,UAAA;4CAAA,YAAA;4CAAA,YAAA;4CAAA,cAAA,KAAA,GAAA,CAAA,GAAA,IAAA;4CAAA,SAAA,GAAA,OAAA,IAAA,KAAA,OAAA,OAAA,IAAA,KAAA;4CAAA,YAAA,GAAA,OAAA,IAAA,WAAA,EAAA;wCAAA;wCAAA,UAAA,EAAA,KAAA;oCAAA;wDAAA,mBAAA,GAAA,EAAA,OAAA;wCAAA,OAAA;4CAAA,UAAA;4CAAA,SAAA;4CAAA,WAAA,IAAA;wCAAA;wCAAA,UAAA,EAAA,KAAA;oCAAA;;gDACV,aAAA,GAAA,CAAA,GAAAlG,mBAAAsB,GAAA,EAAC,OAAA;kDAAK0B,IAAAF,SAAAA,CAAAE,EAAAA,CAAAA,CAAImD,EAAAA,GAAA,gBAAA,GAAA,EAAA,OAAA;gCAAA,OAAA;oCAAA,UAAA;oCAAA,YAAA;oCAAA,SAAA;gCAAA;gCAAA,UAAA;4BAAA;;;;qBAAA;2BAAM,MAAA,OAAA,GAAA,CAAA,GAAA,mBAAA,GAAA,EAAA,OAAA;gBAAA,OAAA;oBAAA,UAAA;oBAAA,SAAA;oBAAA,WAAA,IAAA;oBAAA,WAAA;gBAAA;gBAAA,UAAA,IAAA,OAAA;YAAA;;oBAAA;oBAElB,aAAA,GAAA,CAAA,GAAAnG,mBAAA2E,IAAA,EAAC,OAAA;2BAAW;wBAAPlD,OAAO,EAAA,aAAA;4BAAEoE,CAAAA,CAAAA,GAAAA,CAAM;8BAAGrD,CAAAA,UAAW,SAAA,GAAA,EAAA,OAAA;QAAA,OAAA;YAAA,OAAA;YAAA,QAAA;YAAA,cAAA,KAAA,GAAA,CAAA,GAAA,KAAA,CAAA,GAAA;YAAA,YAAA;YAAA,QAAA;YAAA,SAAA;YAAA,YAAA;YAAA,gBAAA;YAAA,eAAA;YAAA,YAAA;QAAA;QAAA,UAAA,aAAA,GAAA,CAAA,GAAA,mBAAA,GAAA,EAAA,OAAA;YAAA,OAAA;gBAAA,UAAA,GAAA,OAAA,GAAA;gBAAA,YAAA;gBAAA,OAAA;gBAAA,eAAA;YAAA;YAAA,UAAA,QAAA,IAAA;QAAA;IAAA;wBAAS;wBACzCM,UAAA;8BAAA,CAAA,CAAA,MAAA,KAAA,EAAA,CAAA,CAAA,GAAA9C,mBAAAsB,GAAA,EAAC,OAAA;gCAAIG,OAAO;oCAAEY,IAAAA,IAAAA,EAAU,IAAA,OAAA,CAAA,MAAA,UAAA,OAAA;2CAAmB,YAAZE,EAAAA,IAAAA,KAAAA,EAAY,GAAA,OAAA,MAAA;gCAAI;gCAAIO,UAAAE,IAAIoD,QAAA;mDAAA,8BACvD,aAAA,GAAA,CAAA,GAAApG,cAAKyB,KAALH,EAAY,CAAZ,EAAC,OAAA,qBAAae,UAAU;0CAA0BQ,OAAAA,KAAY,GAAA,EAAA;gCAAE,EAAA,MAAA,EAAA;gCAAIC,MAAAA,IAAAE,IAAIqD,GAAAA,EAAAA,IAAA;8BAAA,MAAA;6BAAU;wBAAA,GAAA,uBAAA;+BACpF;oBAAA,CAAA,YAAA,QAAA,KAAA,WAAA,KAAA,SAAA,WAAA,IAAA,KAAA,YAAA,KAAA,SAAA,YAAA,IAAA,KAAA,YAAA,KAAA,SAAA,YAAA,IAAA,KAAA,aAAA,KAAA,SAAA,aAAA,IAAA,KAAA,OAAA,KAAA,SAAA,OAAA,IAAA,KAAA,OAAA,KAAA,SAAA,OAAA,EAAA;sBAEDrD,IAAIsD,CAAAA,UAAA,IACH,aAAA,GAAA,CAAA,GAAAtG,mBAAAsB,GAAA,EAAC,OAAA;wBAAIG,OAAO;4BAAEY,UAAU;0BAASG,WAAW;wBAAUyD,SAAS;;;UAAKxD,SAAS,GAAU,OAAPgD,IAAI,KAAG;sBAAQc,QAAAA,EAAAA,CAAW,aAA4B,OAAfvD,IAAIwD,WAAW,EAAA;oBAAK;kBAAI1D,KAAAA,KAAAE,IAAIsD,GAAAA,QAAA,IAAA;cAAA,aAAA;eAAY,CAAA,OAAA,OAAA,EAAA,qBAAA,OAAA,OAAA;YAAA,OAAA,OAAA,GAAA,sBAAA;QAIvK;QAEA,KAASG,EAAAA,gBAAkB,CAAA,IAAgB,MAAA;YAAdvH,GAAAA,OAAF,MAAEA,SAASsG,OAAX,MAAWA;YACpC,EAAMxC,MAAMoC,MAAAA,MAA2BlG,QAAQgD,OAAO;YACtD,EAAI,CAACc,IAAAA,CAAK,OAAO,WAAA,CAAA,UAAA;YACjB,EAAMyC,EAAAA,EAAI1G,KAAKC,GAAA,CAAI,GAAGwG,EAAAA,GAAKE,CAAA,GAAI,cAAA,OAAA,OAAA;QAC/B,OACE,aAAA,GAAA,CAAA,GAAA1F,mBAAA2E,IAAA,EAAC,OAAA;;UAAIlD,OAAO;KAAA;YAAEC,OAAO,MAAA,SAAA,MAAA;gBAAQC,QAAQ,OAAA,GAAA;;cAAkDE,GAAAA,MAAS,SAAA,MAAA,KAAA,GAAA,OAAA;WAAQ8D,GAAAA,UAAAA,GAAAA,CAAAA,CAAe,EAAA,mBAAA,GAAA,UAAUxD,OAA4ByD,SAAZ,GAAwB5C,IAAI+B,eAAA;cAAiB3C,OAAOY,EAAAA,EAAIU,SAAA;cAAWpB,CAAAA,WAAY;gBAAyCuC,MAAAA,IAAU;gBAAU/C,EAAAA,GAAe,OAAfA,KAAAA,KAAe,EAAA,EAAA;gBAAQC,CAAAA,GAAY,OAAZA,KAAAA,GAAY,IAAA,EAAA;gBAAQM,GAAAA,GAAc,OAAdA,IAAU,CAAA,EAAI,OAADoD,GAAC,EAAA;YAAK,QAAA,GAAA,OAAA,KAAA,aAAA,EAAA;YACzV3C,UAAA,KAAA;gBAAA,MAAA,OAAA,GAAA,CAAA,GAAA9C,mBAAAsB,GAAA,EAAC,OAAA;oBAAIG,OAAO;sBAAEC,OAAO;sBAAQC,QAAQ5C,GAAAA,EAAKC,CAAAA,CAAAA,SAAA,CAAI,GAAGwG,KAAKkB,CAAA,GAAI;sBAAO3B,GAAAA,CAAAA,aAAiB/B,eAAjB+B,sCAAAA,gBAAiB/B,CAAIwD,IAAAA,IAAAA,IAAA,CAAA,YAAA,GAAA,gBAAA,KAAA,GAAA,KAAA,MAAA;kBAAY,OAAA,CAAA,4BAAA,sCAAA,gBAAA,MAAA,IAAA,KAAA,aAAA,GAAA,gBAAA,MAAA,GAAA,KAAA,MAAA;gBAAA,OAAA,QAAA,CAAA,GAAA;gBAClG,MAAA,KAAA,GAAA,CAAA,GAAAxG,mBAAA2E,IAAA,EAAC,OAAA;kBAAIlD,MAAAA,CAAO,OAAA,KAAA,GAAA;sBAAEoE,GAAAA,GAAM,KAAA,MAAA,GAAA;sBAAGhE,IAAAA,KAAS,GAAA,CAAA,GAAA,KAAA,GAAA,CAAA,KAAA,QAAA,OAAA,KAAA;sBAAQ8D;gBAAAA,GAAAA;gBAAAA,GAAAA,CAAe;YAAA;mBAAUxD,KAAAA,QAAAA,GAAAA,CAAAA,GAAAA,CAAgB,kBAAA,IAAA,YAAUM,GAAqC,MAA5B,GAAgBgD,OAAbA,IAAI,KAAG,OAAa,OAAPA,IAAI,KAAG;oBACzH3C,GAAAA,OAAA;0BAAA,IAAA,SAAA,GAAA,CAAA,GAAA9C,mBAAAsB,GAAA,EAAC,OAAA;6BAAIG,QAAAA,KAAAA,GAAO;0CAAEY,UAAU;8BAASE,WAAAA,GAAAA,UAAY;+BAAKM,UAAAA,KAAAA,QAAY;2CAAKD,YAAY;8BAA4B,MAAA,OAAA;8BAAIE,UAAAE,IAAI2D,QAAA;wBAAA;wBACnH,EAAA,WAAA,GAAA,CAAA,GAAA3G,mBAAAsB,GAAA,EAAC,OAAA;8BAAIG,EAAAA,KAAO,WAAA,aAAA,GAAA,CAAA,GAAA,mBAAA,GAAA,EAAA,cAAA;wBAAA,SAAA;oBAAA;kCAAEY,GAAAA,OAAU,GAAA,aAAA,GAAA,CAAA,GAAA,mBAAA,GAAA,EAAA,aAAA;wBAAA,SAAA;oBAAA;kCAAO4D,GAAAA,MAAS,QAAA,aAAA,GAAA,CAAA,GAAA,mBAAA,GAAA,EAAA,iBAAA;wBAAA,SAAA;oBAAA;kCAAKW,GAAAA,QAAWnB,GAAAA,AAAI,CAAA,YAAA,GAAA,CAAA,GAAA,mBAAA,GAAA,EAAA,cAAA;wBAAA,SAAA;wBAAA,MAAA;oBAAA;8BAAI,EAAA,KAAA,eAAA,aAAA,GAAA,CAAA,GAAA,mBAAA,GAAA,EAAA,iBAAA;wBAAA,SAAA;wBAAA,MAAA;oBAAA;8BAAI3C,EAAAA,KAAAA,GAAAE,IAAI6D,QAAA,EAAA,aAAA,GAAA,CAAA,GAAA,mBAAA,GAAA,EAAA,mBAAA;wBAAA,SAAA;wBAAA,MAAA;oBAAA;0BAAA,EAAA,IAAA,KAAA,aAAA,aAAA,GAAA,CAAA,GAAA,mBAAA,GAAA,EAAA,eAAA;wBAAA,SAAA;wBAAA,MAAA;oBAAA;uBAAS,KAAA,IAAA,KAAA,oBAAA,aAAA,GAAA,CAAA,GAAA,mBAAA,GAAA,EAAA,qBAAA;wBAAA,SAAA;wBAAA,MAAA;oBAAA;oBAAA,QAAA,IAAA,KAAA,wBAAA,aAAA,GAAA,CAAA,GAAA,mBAAA,GAAA,EAAA,0BAAA;wBAAA,SAAA;wBAAA,MAAA;oBAAA;oBAElF7D,EAAIsD,MAAAA,IAAAA,CAAA,IACH,aAAA,GAAA,CAAA,CAAA,AAAAtG,EAAAA,WAAAA,GAAAA,CAAAA,GAAAA,CAAAsB,GAAA,EAAC,OAAA,MAAA,GAAA,EAAA,oBAAA;wBAAA,SAAA;wBAAA,MAAA;oBAAA;sBAAIG,MAAAA,CAAO,GAAA,KAAA,mBAAA,aAAA,GAAA,CAAA,GAAA,mBAAA,GAAA,EAAA,qBAAA;wBAAA,SAAA;wBAAA,MAAA;oBAAA;0BAAEY,EAAAA,IAAAA,IAAU,CAAA,eAAA,aAAA,GAAA,CAAA,GAAA,mBAAA,GAAA,EAAA,kBAAA;wBAAA,SAAA;wBAAA,MAAA;oBAAA;wBAAS4D,SAAS;qBAA4C,CAAvCxD,CAAuC,EAAA,MAA9B,KAAkBgD,OAAbA,IAAI,KAAG,OAAa,OAAPA,IAAI,KAAG;cAAa;SAAY;AAIlH;AAEA,SAASqB,cAAc,KAAgB,iCAAA;QAAd5H,KAAAA,KAAF,EAAA,GAAA,CAAEA,SAASsG,OAAX,MAAWA;uBAChC,IAAMxC,MAAMoC,YAAuBlG,QAAQgD,OAAO;KAClD,IAAI,CAACc,KAAK,OAAO","sourcesContent":["\"use strict\";\nvar __create = Object.create;\nvar __defProp = Object.defineProperty;\nvar __getOwnPropDesc = Object.getOwnPropertyDescriptor;\nvar __getOwnPropNames = Object.getOwnPropertyNames;\nvar __getProtoOf = Object.getPrototypeOf;\nvar __hasOwnProp = Object.prototype.hasOwnProperty;\nvar __export = (target, all) => {\n for (var name in all)\n __defProp(target, name, { get: all[name], enumerable: true });\n};\nvar __copyProps = (to, from, except, desc) => {\n if (from && typeof from === \"object\" || typeof from === \"function\") {\n for (let key of __getOwnPropNames(from))\n if (!__hasOwnProp.call(to, key) && key !== except)\n __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });\n }\n return to;\n};\nvar __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(\n // If the importer is in node compatibility mode or this is not an ESM\n // file that has been converted to a CommonJS file using a Babel-\n // compatible transform (i.e. \"__esModule\" has not been set), then set\n // \"default\" to the CommonJS \"module.exports\" for node compatibility.\n isNodeMode || !mod || !mod.__esModule ? __defProp(target, \"default\", { value: mod, enumerable: true }) : target,\n mod\n));\nvar __toCommonJS = (mod) => __copyProps(__defProp({}, \"__esModule\", { value: true }), mod);\n\n// src/ui/OverlayRenderer.tsx\nvar OverlayRenderer_exports = {};\n__export(OverlayRenderer_exports, {\n OverlayRenderer: () => OverlayRenderer\n});\nmodule.exports = __toCommonJS(OverlayRenderer_exports);\nvar import_react = __toESM(require(\"react\"), 1);\n\n// src/utils/overlays.ts\nvar OVERLAY_API_BASE = \"https://adstorm.co/api-adstorm-dev\";\nfunction timeStringToSeconds(timeStr) {\n if (!timeStr) return 0;\n const parts = timeStr.split(\":\");\n if (parts.length >= 3) {\n const hours = parseInt(parts[0] ?? \"0\", 10) || 0;\n const minutes = parseInt(parts[1] ?? \"0\", 10) || 0;\n const secStr = parts[2] ?? \"0\";\n const dotIdx = secStr.indexOf(\".\");\n const seconds = parseInt(dotIdx >= 0 ? secStr.substring(0, dotIdx) : secStr, 10) || 0;\n const msFrag = dotIdx >= 0 ? secStr.substring(dotIdx + 1) : \"\";\n const ms = msFrag ? parseInt(msFrag.padEnd(3, \"0\").substring(0, 3), 10) || 0 : 0;\n return hours * 3600 + minutes * 60 + seconds + ms / 1e3;\n }\n if (parts.length === 2) {\n const minutes = parseInt(parts[0] ?? \"0\", 10) || 0;\n const secStr = parts[1] ?? \"0\";\n const dotIdx = secStr.indexOf(\".\");\n const seconds = parseInt(dotIdx >= 0 ? secStr.substring(0, dotIdx) : secStr, 10) || 0;\n const msFrag = dotIdx >= 0 ? secStr.substring(dotIdx + 1) : \"\";\n const ms = msFrag ? parseInt(msFrag.padEnd(3, \"0\").substring(0, 3), 10) || 0 : 0;\n return minutes * 60 + seconds + ms / 1e3;\n }\n const num = parseFloat(timeStr);\n return isFinite(num) ? Math.max(0, num) : 0;\n}\nfunction isOverlayActive(overlay, currentTime) {\n if (!overlay.visible) return false;\n const startSec = timeStringToSeconds(overlay.start_time);\n const durationSec = timeStringToSeconds(overlay.duration);\n if (durationSec <= 0) return false;\n return currentTime >= startSec && currentTime < startSec + durationSec;\n}\nfunction resolveImageUrl(imageUrl, apiBaseUrl = OVERLAY_API_BASE) {\n if (!imageUrl) return \"\";\n if (imageUrl.startsWith(\"http://\") || imageUrl.startsWith(\"https://\")) {\n return imageUrl;\n }\n if (imageUrl.startsWith(\"/\")) {\n try {\n const url = new URL(apiBaseUrl);\n return `${url.origin}${imageUrl}`;\n } catch {\n return imageUrl;\n }\n }\n return `${apiBaseUrl}/${imageUrl}`;\n}\n\n// src/ui/OverlayRenderer.tsx\nvar import_jsx_runtime = require(\"react/jsx-runtime\");\nfunction computeVideoDimensions(video) {\n const nativeWidth = video.videoWidth;\n const nativeHeight = video.videoHeight;\n if (!nativeWidth || !nativeHeight) return null;\n const displayWidth = video.offsetWidth;\n const displayHeight = video.offsetHeight;\n if (!displayWidth || !displayHeight) return null;\n const videoAspect = nativeWidth / nativeHeight;\n const displayAspect = displayWidth / displayHeight;\n let renderWidth;\n let renderHeight;\n let offsetX;\n let offsetY;\n if (videoAspect > displayAspect) {\n renderWidth = displayWidth;\n renderHeight = displayWidth / videoAspect;\n offsetX = 0;\n offsetY = (displayHeight - renderHeight) / 2;\n } else {\n renderHeight = displayHeight;\n renderWidth = displayHeight * videoAspect;\n offsetX = (displayWidth - renderWidth) / 2;\n offsetY = 0;\n }\n return {\n nativeWidth,\n nativeHeight,\n displayWidth: renderWidth,\n displayHeight: renderHeight,\n offsetX,\n offsetY,\n scaleX: renderWidth / nativeWidth,\n scaleY: renderHeight / nativeHeight\n };\n}\nfunction ImageOverlay({ overlay }) {\n const src = resolveImageUrl(overlay.image_url || \"\");\n if (!src) return null;\n return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(\n \"img\",\n {\n src,\n alt: overlay.name,\n draggable: false,\n style: {\n width: \"100%\",\n height: \"100%\",\n objectFit: \"contain\",\n display: \"block\",\n pointerEvents: \"none\",\n userSelect: \"none\"\n }\n }\n );\n}\nfunction TextOverlay({ overlay }) {\n const text = overlay.content || \"\";\n return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(\n \"div\",\n {\n style: {\n width: \"100%\",\n height: \"100%\",\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n color: \"#ffffff\",\n fontSize: \"clamp(10px, 1.4vw, 20px)\",\n fontFamily: \"Roboto, 'Segoe UI', Arial, sans-serif\",\n fontWeight: 600,\n textAlign: \"center\",\n padding: \"4px 8px\",\n boxSizing: \"border-box\",\n wordBreak: \"break-word\",\n textShadow: \"0 1px 4px rgba(0,0,0,0.7)\",\n pointerEvents: \"none\",\n userSelect: \"none\",\n lineHeight: 1.3\n },\n children: text\n }\n );\n}\nfunction ScrollerOverlay({ overlay }) {\n const cfg = overlay.scroller_config;\n const text = cfg?.use_custom_text && cfg.custom_text ? cfg.custom_text : overlay.content || cfg?.custom_text || \"\";\n const scrollSpeed = cfg?.scroll_speed ?? 50;\n const direction = cfg?.direction ?? \"left\";\n const fontSize = cfg?.font_size ? `${cfg.font_size}px` : \"clamp(10px, 1.2vw, 18px)\";\n const fontFamily = cfg?.font_family || \"Roboto, 'Segoe UI', Arial, sans-serif\";\n const fontWeight = cfg?.font_weight || \"600\";\n const textColor = cfg?.text_color || \"#ffffff\";\n const bgColor = cfg?.background_color || \"transparent\";\n const bgOpacity = cfg?.background_opacity !== void 0 ? cfg.background_opacity / 100 : 0;\n const borderColor = cfg?.border_color || \"transparent\";\n const borderWidth = cfg?.border_width ?? 0;\n const borderRadius = cfg?.border_radius ?? 0;\n const padding = cfg?.padding ?? 4;\n const isVertical = direction === \"up\" || direction === \"down\";\n const isReverse = direction === \"right\" || direction === \"down\";\n const durationSec = Math.max(3, 120 - scrollSpeed);\n const animId = `sc-scroller-${overlay.id}`;\n const keyframes = isVertical ? `@keyframes ${animId} {\n 0% { transform: translateY(${isReverse ? \"-100%\" : \"100%\"}); }\n 100% { transform: translateY(${isReverse ? \"100%\" : \"-100%\"}); }\n }` : `@keyframes ${animId} {\n 0% { transform: translateX(${isReverse ? \"-100%\" : \"100%\"}); }\n 100% { transform: translateX(${isReverse ? \"100%\" : \"-100%\"}); }\n }`;\n return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: [\n /* @__PURE__ */ (0, import_jsx_runtime.jsx)(\"style\", { children: keyframes }),\n /* @__PURE__ */ (0, import_jsx_runtime.jsx)(\n \"div\",\n {\n style: {\n width: \"100%\",\n height: \"100%\",\n overflow: \"hidden\",\n display: \"flex\",\n alignItems: \"center\",\n backgroundColor: bgOpacity > 0 ? `rgba(${hexToRgb(bgColor)}, ${bgOpacity})` : void 0,\n border: borderWidth > 0 ? `${borderWidth}px solid ${borderColor}` : void 0,\n borderRadius: borderRadius > 0 ? `${borderRadius}px` : void 0,\n padding: `${padding}px`,\n boxSizing: \"border-box\",\n pointerEvents: \"none\"\n },\n children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(\n \"div\",\n {\n style: {\n whiteSpace: \"nowrap\",\n fontSize,\n fontFamily,\n fontWeight,\n color: textColor,\n animation: `${animId} ${durationSec}s linear infinite`,\n textShadow: \"0 1px 4px rgba(0,0,0,0.5)\",\n userSelect: \"none\"\n },\n children: text\n }\n )\n }\n )\n ] });\n}\nfunction parseConfig(content) {\n if (!content) return null;\n try {\n return JSON.parse(content);\n } catch {\n return null;\n }\n}\nfunction ScoreBugOverlay({ overlay, size }) {\n const cfg = parseConfig(overlay.content);\n if (!cfg) return null;\n const f = Math.max(6, size.w * 0.058);\n return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(\"div\", { style: { width: \"100%\", height: \"100%\", borderRadius: Math.max(2, size.w * 0.035), display: \"flex\", flexDirection: \"column\", background: cfg.backgroundColor, color: cfg.textColor, fontFamily: \"Roboto, 'Segoe UI', Arial, sans-serif\", overflow: \"hidden\", pointerEvents: \"none\", userSelect: \"none\", fontSize: `${f}px` }, children: [\n /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(\"div\", { style: { flex: 1, display: \"flex\", alignItems: \"center\", padding: `0 ${f * 0.8}px`, gap: f * 0.4 }, children: [\n /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(\"div\", { style: { flex: 1, textAlign: \"center\" }, children: [\n /* @__PURE__ */ (0, import_jsx_runtime.jsx)(\"div\", { style: { fontSize: \"1em\", fontWeight: 700 }, children: cfg.homeTeam }),\n /* @__PURE__ */ (0, import_jsx_runtime.jsx)(\"div\", { style: { fontSize: \"1.8em\", fontWeight: 900, lineHeight: 1 }, children: cfg.homeScore })\n ] }),\n /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(\"div\", { style: { fontSize: \"0.8em\", textAlign: \"center\", opacity: 0.7, padding: `0 ${f * 0.4}px` }, children: [\n /* @__PURE__ */ (0, import_jsx_runtime.jsx)(\"div\", { children: cfg.period }),\n /* @__PURE__ */ (0, import_jsx_runtime.jsx)(\"div\", { children: cfg.clock })\n ] }),\n /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(\"div\", { style: { flex: 1, textAlign: \"center\" }, children: [\n /* @__PURE__ */ (0, import_jsx_runtime.jsx)(\"div\", { style: { fontSize: \"1em\", fontWeight: 700 }, children: cfg.awayTeam }),\n /* @__PURE__ */ (0, import_jsx_runtime.jsx)(\"div\", { style: { fontSize: \"1.8em\", fontWeight: 900, lineHeight: 1 }, children: cfg.awayScore })\n ] })\n ] }),\n cfg.sponsorText && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(\"div\", { style: { fontSize: \"0.7em\", textAlign: \"center\", opacity: 0.5, padding: `${f * 0.2}px 0`, borderTop: `1px solid ${cfg.accentColor}40` }, children: cfg.sponsorText })\n ] });\n}\nfunction LowerThirdOverlay({ overlay, size }) {\n const cfg = parseConfig(overlay.content);\n if (!cfg) return null;\n const f = Math.max(6, size.w * 0.055);\n return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(\"div\", { style: { width: \"100%\", height: \"100%\", borderRadius: Math.max(2, size.w * 0.02), display: \"flex\", flexDirection: \"column\", justifyContent: \"flex-end\", background: cfg.backgroundColor, color: cfg.textColor, fontFamily: \"Roboto, 'Segoe UI', Arial, sans-serif\", overflow: \"hidden\", pointerEvents: \"none\", userSelect: \"none\", fontSize: `${f}px` }, children: [\n /* @__PURE__ */ (0, import_jsx_runtime.jsx)(\"div\", { style: { width: \"100%\", height: Math.max(2, size.h * 0.06), backgroundColor: cfg.accentColor } }),\n /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(\"div\", { style: { flex: 1, display: \"flex\", flexDirection: \"column\", justifyContent: \"center\", padding: `${f * 0.5}px ${f * 1.2}px` }, children: [\n /* @__PURE__ */ (0, import_jsx_runtime.jsx)(\"div\", { style: { fontSize: \"1.4em\", fontWeight: 700, lineHeight: 1.2, textShadow: \"0 1px 4px rgba(0,0,0,0.5)\" }, children: cfg.headline }),\n /* @__PURE__ */ (0, import_jsx_runtime.jsx)(\"div\", { style: { fontSize: \"1em\", opacity: 0.7, marginTop: f * 0.2 }, children: cfg.subtitle })\n ] }),\n cfg.sponsorText && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(\"div\", { style: { fontSize: \"0.7em\", opacity: 0.4, padding: `0 ${f * 1.2}px ${f * 0.4}px` }, children: cfg.sponsorText })\n ] });\n}\nfunction QrCodeOverlay({ overlay, size }) {\n const cfg = parseConfig(overlay.content);\n if (!cfg) return null;\n const qrSide = Math.max(32, Math.min(size.w, size.h) * 0.55);\n const qrUrl = `https://api.qrserver.com/v1/create-qr-code/?size=${Math.round(qrSide * 2)}x${Math.round(qrSide * 2)}&data=${encodeURIComponent(cfg.url || \"https://example.com\")}`;\n const f = Math.max(6, size.w * 0.06);\n return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(\"div\", { style: { width: \"100%\", height: \"100%\", borderRadius: Math.max(2, size.w * 0.035), display: \"flex\", flexDirection: \"column\", alignItems: \"center\", justifyContent: \"center\", gap: f * 0.4, background: cfg.backgroundColor, color: cfg.textColor, fontFamily: \"Roboto, 'Segoe UI', Arial, sans-serif\", padding: f * 0.6, boxSizing: \"border-box\", pointerEvents: \"none\", userSelect: \"none\", overflow: \"hidden\" }, children: [\n /* @__PURE__ */ (0, import_jsx_runtime.jsx)(\"div\", { style: { flexShrink: 0, background: \"#fff\", borderRadius: Math.max(2, qrSide * 0.06), padding: Math.max(2, qrSide * 0.06), lineHeight: 0 }, children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(\"img\", { src: qrUrl, alt: \"QR Code\", style: { width: `${qrSide}px`, height: `${qrSide}px`, display: \"block\" } }) }),\n /* @__PURE__ */ (0, import_jsx_runtime.jsx)(\"div\", { style: { fontSize: `${f * 1.1}px`, fontWeight: 700, textAlign: \"center\", color: cfg.accentColor, overflow: \"hidden\", textOverflow: \"ellipsis\", whiteSpace: \"nowrap\", width: \"100%\" }, children: cfg.ctaText }),\n cfg.description && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(\"div\", { style: { fontSize: `${f * 0.75}px`, opacity: 0.6, textAlign: \"center\", overflow: \"hidden\", textOverflow: \"ellipsis\", whiteSpace: \"nowrap\", width: \"100%\" }, children: cfg.description })\n ] });\n}\nfunction ComingUpNextOverlay({ overlay, size }) {\n const cfg = parseConfig(overlay.content);\n if (!cfg) return null;\n const f = Math.max(6, size.w * 0.05);\n return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(\"div\", { style: { width: \"100%\", height: \"100%\", borderRadius: Math.max(2, size.w * 0.035), display: \"flex\", background: cfg.backgroundColor, color: cfg.textColor, fontFamily: \"Roboto, 'Segoe UI', Arial, sans-serif\", overflow: \"hidden\", pointerEvents: \"none\", userSelect: \"none\", fontSize: `${f}px` }, children: [\n /* @__PURE__ */ (0, import_jsx_runtime.jsx)(\"div\", { style: { width: Math.max(2, size.w * 0.015), flexShrink: 0, backgroundColor: cfg.accentColor } }),\n /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(\"div\", { style: { flex: 1, display: \"flex\", flexDirection: \"column\", justifyContent: \"center\", padding: `${f * 0.6}px ${f * 1}px`, minWidth: 0 }, children: [\n /* @__PURE__ */ (0, import_jsx_runtime.jsx)(\"div\", { style: { fontSize: \"0.8em\", fontWeight: 600, textTransform: \"uppercase\", letterSpacing: \"0.05em\", color: cfg.accentColor }, children: \"Coming Up Next\" }),\n /* @__PURE__ */ (0, import_jsx_runtime.jsx)(\"div\", { style: { fontSize: \"1.5em\", fontWeight: 700, lineHeight: 1.2, marginTop: f * 0.2, overflow: \"hidden\", textOverflow: \"ellipsis\", whiteSpace: \"nowrap\" }, children: cfg.title }),\n /* @__PURE__ */ (0, import_jsx_runtime.jsx)(\"div\", { style: { fontSize: \"0.9em\", opacity: 0.6, overflow: \"hidden\", textOverflow: \"ellipsis\", whiteSpace: \"nowrap\" }, children: cfg.subtitle }),\n cfg.scheduledTime && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(\"div\", { style: { fontSize: \"1em\", fontWeight: 600, marginTop: f * 0.4, color: cfg.accentColor }, children: cfg.scheduledTime })\n ] })\n ] });\n}\nfunction ContextualTriggerOverlay({ overlay, size }) {\n const cfg = parseConfig(overlay.content);\n if (!cfg) return null;\n const icons = { alert: \"\\u26A0\\uFE0F\", celebration: \"\\u{1F389}\", info: \"\\u2139\\uFE0F\", warning: \"\\u{1F514}\" };\n const f = Math.max(6, size.w * 0.05);\n return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(\"div\", { style: { width: \"100%\", height: \"100%\", borderRadius: Math.max(2, size.w * 0.035), display: \"flex\", alignItems: \"center\", gap: f * 0.8, padding: `0 ${f * 1.2}px`, background: cfg.backgroundColor, color: cfg.textColor, fontFamily: \"Roboto, 'Segoe UI', Arial, sans-serif\", borderLeft: `${Math.max(2, size.w * 0.02)}px solid ${cfg.accentColor}`, boxSizing: \"border-box\", pointerEvents: \"none\", userSelect: \"none\", fontSize: `${f}px` }, children: [\n /* @__PURE__ */ (0, import_jsx_runtime.jsx)(\"span\", { style: { fontSize: \"2em\", flexShrink: 0 }, children: icons[cfg.iconType] || \"\\u26A1\" }),\n /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(\"div\", { style: { flex: 1, minWidth: 0 }, children: [\n /* @__PURE__ */ (0, import_jsx_runtime.jsx)(\"div\", { style: { fontSize: \"1.3em\", fontWeight: 700, overflow: \"hidden\", textOverflow: \"ellipsis\", whiteSpace: \"nowrap\" }, children: cfg.headline }),\n /* @__PURE__ */ (0, import_jsx_runtime.jsx)(\"div\", { style: { fontSize: \"0.9em\", opacity: 0.7, overflow: \"hidden\", textOverflow: \"ellipsis\", whiteSpace: \"nowrap\" }, children: cfg.message })\n ] })\n ] });\n}\nfunction OddsBettingOverlay({ overlay, size }) {\n const cfg = parseConfig(overlay.content);\n if (!cfg) return null;\n const f = Math.max(6, size.w * 0.052);\n return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(\"div\", { style: { width: \"100%\", height: \"100%\", borderRadius: Math.max(2, size.w * 0.035), display: \"flex\", flexDirection: \"column\", padding: f * 0.8, background: cfg.backgroundColor, color: cfg.textColor, fontFamily: \"Roboto, 'Segoe UI', Arial, sans-serif\", boxSizing: \"border-box\", pointerEvents: \"none\", userSelect: \"none\", fontSize: `${f}px` }, children: [\n /* @__PURE__ */ (0, import_jsx_runtime.jsx)(\"div\", { style: { fontSize: \"0.9em\", fontWeight: 700, textTransform: \"uppercase\", letterSpacing: \"0.05em\", color: cfg.accentColor, marginBottom: f * 0.4 }, children: cfg.eventTitle }),\n /* @__PURE__ */ (0, import_jsx_runtime.jsx)(\"div\", { style: { flex: 1, display: \"flex\", flexDirection: \"column\", gap: f * 0.2, justifyContent: \"center\" }, children: (cfg.options || []).slice(0, 5).map((opt, i) => /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(\"div\", { style: { display: \"flex\", justifyContent: \"space-between\", alignItems: \"center\", padding: `${f * 0.2}px ${f * 0.6}px`, borderRadius: Math.max(2, f * 0.3), background: `${cfg.accentColor}15`, fontSize: \"1em\" }, children: [\n /* @__PURE__ */ (0, import_jsx_runtime.jsx)(\"span\", { style: { overflow: \"hidden\", textOverflow: \"ellipsis\", whiteSpace: \"nowrap\", flex: 1 }, children: opt.label }),\n /* @__PURE__ */ (0, import_jsx_runtime.jsx)(\"span\", { style: { fontWeight: 700, marginLeft: f * 0.8, flexShrink: 0, color: cfg.accentColor }, children: opt.odds })\n ] }, i)) }),\n cfg.sponsorText && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(\"div\", { style: { fontSize: \"0.7em\", opacity: 0.4, textAlign: \"center\", marginTop: f * 0.4 }, children: cfg.sponsorText })\n ] });\n}\nfunction BreakingNewsOverlay({ overlay, size }) {\n const cfg = parseConfig(overlay.content);\n if (!cfg) return null;\n const urgencyColors = { breaking: \"#dc2626\", urgent: \"#ea580c\", normal: \"#2563eb\" };\n const labelBg = urgencyColors[cfg.urgency] || urgencyColors.normal;\n const label = cfg.urgency === \"breaking\" ? \"BREAKING\" : cfg.urgency === \"urgent\" ? \"URGENT\" : \"NEWS\";\n const f = Math.max(6, size.w * 0.05);\n return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(\"div\", { style: { width: \"100%\", height: \"100%\", borderRadius: Math.max(2, size.w * 0.02), display: \"flex\", alignItems: \"center\", background: cfg.backgroundColor, color: cfg.textColor, fontFamily: \"Roboto, 'Segoe UI', Arial, sans-serif\", overflow: \"hidden\", pointerEvents: \"none\", userSelect: \"none\", fontSize: `${f}px` }, children: [\n /* @__PURE__ */ (0, import_jsx_runtime.jsx)(\"div\", { style: { padding: `0 ${f * 0.8}px`, height: \"100%\", display: \"flex\", alignItems: \"center\", background: labelBg, color: \"#fff\", fontSize: \"1em\", fontWeight: 900, textTransform: \"uppercase\", letterSpacing: \"0.05em\", flexShrink: 0 }, children: label }),\n /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(\"div\", { style: { flex: 1, padding: `0 ${f * 1}px`, minWidth: 0 }, children: [\n /* @__PURE__ */ (0, import_jsx_runtime.jsx)(\"div\", { style: { fontSize: \"1.3em\", fontWeight: 700, overflow: \"hidden\", textOverflow: \"ellipsis\", whiteSpace: \"nowrap\" }, children: cfg.headline }),\n cfg.body && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(\"div\", { style: { fontSize: \"0.9em\", opacity: 0.7, overflow: \"hidden\", textOverflow: \"ellipsis\", whiteSpace: \"nowrap\" }, children: cfg.body })\n ] })\n ] });\n}\nfunction CountdownOverlay({ overlay, size }) {\n const cfg = parseConfig(overlay.content);\n const [remaining, setRemaining] = (0, import_react.useState)({ d: 0, h: 0, m: 0, s: 0 });\n (0, import_react.useEffect)(() => {\n if (!cfg) return;\n const update = () => {\n const target = new Date(cfg.targetTime).getTime();\n const now = Date.now();\n const diff = Math.max(0, target - now);\n setRemaining({\n d: Math.floor(diff / 864e5),\n h: Math.floor(diff % 864e5 / 36e5),\n m: Math.floor(diff % 36e5 / 6e4),\n s: Math.floor(diff % 6e4 / 1e3)\n });\n };\n update();\n const id = setInterval(update, 1e3);\n return () => clearInterval(id);\n }, [cfg?.targetTime]);\n if (!cfg) return null;\n const f = Math.max(6, size.w * 0.055);\n const pad = (n) => String(n).padStart(2, \"0\");\n const units = [\n { show: cfg.showDays, value: pad(remaining.d), label: \"DAYS\" },\n { show: cfg.showHours, value: pad(remaining.h), label: \"HRS\" },\n { show: cfg.showMinutes, value: pad(remaining.m), label: \"MIN\" },\n { show: cfg.showSeconds, value: pad(remaining.s), label: \"SEC\" }\n ];\n return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(\"div\", { style: { width: \"100%\", height: \"100%\", borderRadius: Math.max(2, size.w * 0.035), display: \"flex\", flexDirection: \"column\", alignItems: \"center\", justifyContent: \"center\", padding: f * 0.8, background: cfg.backgroundColor, color: cfg.textColor, fontFamily: \"Roboto, 'Segoe UI', Arial, sans-serif\", boxSizing: \"border-box\", pointerEvents: \"none\", userSelect: \"none\", fontSize: `${f}px` }, children: [\n /* @__PURE__ */ (0, import_jsx_runtime.jsx)(\"div\", { style: { fontSize: \"0.8em\", fontWeight: 600, textTransform: \"uppercase\", letterSpacing: \"0.05em\", color: cfg.accentColor, marginBottom: f * 0.4 }, children: cfg.eventName }),\n /* @__PURE__ */ (0, import_jsx_runtime.jsx)(\"div\", { style: { display: \"flex\", gap: f * 0.6, alignItems: \"center\" }, children: units.filter((u) => u.show).map((u, i, arr) => /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_react.default.Fragment, { children: [\n /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(\"div\", { style: { textAlign: \"center\" }, children: [\n /* @__PURE__ */ (0, import_jsx_runtime.jsx)(\"div\", { style: { fontSize: \"2em\", fontWeight: 900, lineHeight: 1, borderRadius: Math.max(2, f * 0.4), padding: `${f * 0.2}px ${f * 0.4}px`, background: `${cfg.accentColor}20` }, children: u.value }),\n /* @__PURE__ */ (0, import_jsx_runtime.jsx)(\"div\", { style: { fontSize: \"0.5em\", opacity: 0.5, marginTop: f * 0.2 }, children: u.label })\n ] }),\n i < arr.length - 1 && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(\"div\", { style: { fontSize: \"1.8em\", fontWeight: 700, opacity: 0.3 }, children: \":\" })\n ] }, u.label)) }),\n cfg.message && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(\"div\", { style: { fontSize: \"0.8em\", opacity: 0.6, marginTop: f * 0.4, textAlign: \"center\" }, children: cfg.message })\n ] });\n}\nfunction ShapeOverlay({ overlay, size }) {\n const f = Math.max(6, size.w * 0.05);\n return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(\"div\", { style: { width: \"100%\", height: \"100%\", borderRadius: Math.max(2, size.w * 0.03), background: \"rgba(99, 102, 241, 0.2)\", border: \"2px solid rgba(99, 102, 241, 0.4)\", display: \"flex\", alignItems: \"center\", justifyContent: \"center\", pointerEvents: \"none\", userSelect: \"none\" }, children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(\"div\", { style: { fontSize: `${f}px`, fontWeight: 500, color: \"rgba(163, 163, 163, 0.8)\", textTransform: \"uppercase\" }, children: overlay.name }) });\n}\nfunction hexToRgb(hex) {\n if (!hex || !hex.startsWith(\"#\")) return \"0,0,0\";\n const clean = hex.slice(1);\n const num = parseInt(clean.length === 3 ? clean.replace(/./g, \"$&$&\") : clean, 16);\n return `${num >> 16 & 255},${num >> 8 & 255},${num & 255}`;\n}\nvar OverlayRenderer = ({\n overlays,\n currentTime,\n videoRef,\n coordinateSpace\n}) => {\n const [dims, setDims] = (0, import_react.useState)(null);\n const rafRef = (0, import_react.useRef)(null);\n const updateDims = (0, import_react.useCallback)(() => {\n const video = videoRef.current;\n if (video) {\n const computed = computeVideoDimensions(video);\n setDims((prev) => {\n if (!computed || prev && prev.nativeWidth === computed.nativeWidth && prev.nativeHeight === computed.nativeHeight && prev.displayWidth === computed.displayWidth && prev.displayHeight === computed.displayHeight && prev.offsetX === computed.offsetX && prev.offsetY === computed.offsetY) {\n return prev;\n }\n return computed;\n });\n }\n }, [videoRef]);\n (0, import_react.useEffect)(() => {\n updateDims();\n const interval = setInterval(updateDims, 500);\n const handleResize = () => {\n if (rafRef.current) cancelAnimationFrame(rafRef.current);\n rafRef.current = requestAnimationFrame(updateDims);\n };\n window.addEventListener(\"resize\", handleResize);\n return () => {\n clearInterval(interval);\n window.removeEventListener(\"resize\", handleResize);\n if (rafRef.current) cancelAnimationFrame(rafRef.current);\n };\n }, [updateDims]);\n const activeOverlays = overlays.filter(\n (o) => isOverlayActive(o, currentTime)\n );\n if (!dims || activeOverlays.length === 0) return null;\n return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(\n \"div\",\n {\n \"aria-hidden\": \"true\",\n style: {\n position: \"absolute\",\n left: `${dims.offsetX}px`,\n top: `${dims.offsetY}px`,\n width: `${dims.displayWidth}px`,\n height: `${dims.displayHeight}px`,\n pointerEvents: \"none\",\n overflow: \"hidden\",\n zIndex: 8\n },\n children: activeOverlays.map((overlay) => {\n const scaleX = coordinateSpace?.width ? dims.displayWidth / coordinateSpace.width : dims.scaleX;\n const scaleY = coordinateSpace?.height ? dims.displayHeight / coordinateSpace.height : dims.scaleY;\n const left = overlay.x * scaleX;\n const top = overlay.y * scaleY;\n const width = overlay.width * scaleX;\n const height = overlay.height * scaleY;\n const opacity = Math.max(0, Math.min(100, overlay.opacity)) / 100;\n const sz = { w: width, h: height };\n return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(\n \"div\",\n {\n style: {\n position: \"absolute\",\n left: `${left}px`,\n top: `${top}px`,\n width: `${width}px`,\n height: `${height}px`,\n opacity,\n zIndex: overlay.z_index,\n overflow: \"hidden\"\n },\n children: [\n overlay.type === \"image\" && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(ImageOverlay, { overlay }),\n overlay.type === \"text\" && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(TextOverlay, { overlay }),\n overlay.type === \"scroller\" && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(ScrollerOverlay, { overlay }),\n overlay.type === \"shape\" && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(ShapeOverlay, { overlay, size: sz }),\n overlay.type === \"score_bug\" && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(ScoreBugOverlay, { overlay, size: sz }),\n overlay.type === \"lower_third\" && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(LowerThirdOverlay, { overlay, size: sz }),\n overlay.type === \"qr_code\" && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(QrCodeOverlay, { overlay, size: sz }),\n overlay.type === \"coming_up_next\" && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(ComingUpNextOverlay, { overlay, size: sz }),\n overlay.type === \"contextual_trigger\" && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(ContextualTriggerOverlay, { overlay, size: sz }),\n overlay.type === \"odds_betting\" && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(OddsBettingOverlay, { overlay, size: sz }),\n overlay.type === \"breaking_news\" && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(BreakingNewsOverlay, { overlay, size: sz }),\n overlay.type === \"countdown\" && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(CountdownOverlay, { overlay, size: sz })\n ]\n },\n overlay.id\n );\n })\n }\n );\n};\n// Annotate the CommonJS export names for ESM import in node:\n0 && (module.exports = {\n OverlayRenderer\n});\n","import React, { useEffect, useRef, useState, useCallback } from \"react\";\nimport {\n type SwirlOverlay,\n isOverlayActive,\n resolveImageUrl,\n} from \"../utils/overlays\";\n\ninterface VideoDimensions {\n nativeWidth: number;\n nativeHeight: number;\n displayWidth: number;\n displayHeight: number;\n offsetX: number;\n offsetY: number;\n scaleX: number;\n scaleY: number;\n}\n\ninterface OverlayRendererProps {\n overlays: SwirlOverlay[];\n currentTime: number;\n videoRef: React.RefObject<HTMLVideoElement | null>;\n coordinateSpace?: { width: number; height: number } | null;\n}\n\nfunction computeVideoDimensions(\n video: HTMLVideoElement\n): VideoDimensions | null {\n const nativeWidth = video.videoWidth;\n const nativeHeight = video.videoHeight;\n if (!nativeWidth || !nativeHeight) return null;\n\n const displayWidth = video.offsetWidth;\n const displayHeight = video.offsetHeight;\n if (!displayWidth || !displayHeight) return null;\n\n const videoAspect = nativeWidth / nativeHeight;\n const displayAspect = displayWidth / displayHeight;\n\n let renderWidth: number;\n let renderHeight: number;\n let offsetX: number;\n let offsetY: number;\n\n if (videoAspect > displayAspect) {\n renderWidth = displayWidth;\n renderHeight = displayWidth / videoAspect;\n offsetX = 0;\n offsetY = (displayHeight - renderHeight) / 2;\n } else {\n renderHeight = displayHeight;\n renderWidth = displayHeight * videoAspect;\n offsetX = (displayWidth - renderWidth) / 2;\n offsetY = 0;\n }\n\n return {\n nativeWidth,\n nativeHeight,\n displayWidth: renderWidth,\n displayHeight: renderHeight,\n offsetX,\n offsetY,\n scaleX: renderWidth / nativeWidth,\n scaleY: renderHeight / nativeHeight,\n };\n}\n\nfunction ImageOverlay({ overlay }: { overlay: SwirlOverlay }) {\n const src = resolveImageUrl(overlay.image_url || \"\");\n if (!src) return null;\n return (\n <img\n src={src}\n alt={overlay.name}\n draggable={false}\n style={{\n width: \"100%\",\n height: \"100%\",\n objectFit: \"contain\",\n display: \"block\",\n pointerEvents: \"none\",\n userSelect: \"none\",\n }}\n />\n );\n}\n\nfunction TextOverlay({ overlay }: { overlay: SwirlOverlay }) {\n const text = overlay.content || \"\";\n return (\n <div\n style={{\n width: \"100%\",\n height: \"100%\",\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n color: \"#ffffff\",\n fontSize: \"clamp(10px, 1.4vw, 20px)\",\n fontFamily: \"Roboto, 'Segoe UI', Arial, sans-serif\",\n fontWeight: 600,\n textAlign: \"center\",\n padding: \"4px 8px\",\n boxSizing: \"border-box\",\n wordBreak: \"break-word\",\n textShadow: \"0 1px 4px rgba(0,0,0,0.7)\",\n pointerEvents: \"none\",\n userSelect: \"none\",\n lineHeight: 1.3,\n }}\n >\n {text}\n </div>\n );\n}\n\nfunction ScrollerOverlay({ overlay }: { overlay: SwirlOverlay }) {\n const cfg = overlay.scroller_config;\n const text =\n cfg?.use_custom_text && cfg.custom_text\n ? cfg.custom_text\n : overlay.content || cfg?.custom_text || \"\";\n\n const scrollSpeed = cfg?.scroll_speed ?? 50;\n const direction = cfg?.direction ?? \"left\";\n const fontSize = cfg?.font_size ? `${cfg.font_size}px` : \"clamp(10px, 1.2vw, 18px)\";\n const fontFamily = cfg?.font_family || \"Roboto, 'Segoe UI', Arial, sans-serif\";\n const fontWeight = cfg?.font_weight || \"600\";\n const textColor = cfg?.text_color || \"#ffffff\";\n const bgColor = cfg?.background_color || \"transparent\";\n const bgOpacity = cfg?.background_opacity !== undefined ? cfg.background_opacity / 100 : 0;\n const borderColor = cfg?.border_color || \"transparent\";\n const borderWidth = cfg?.border_width ?? 0;\n const borderRadius = cfg?.border_radius ?? 0;\n const padding = cfg?.padding ?? 4;\n\n const isVertical = direction === \"up\" || direction === \"down\";\n const isReverse = direction === \"right\" || direction === \"down\";\n\n const durationSec = Math.max(3, 120 - scrollSpeed);\n\n const animId = `sc-scroller-${overlay.id}`;\n const keyframes = isVertical\n ? `@keyframes ${animId} {\n 0% { transform: translateY(${isReverse ? \"-100%\" : \"100%\"}); }\n 100% { transform: translateY(${isReverse ? \"100%\" : \"-100%\"}); }\n }`\n : `@keyframes ${animId} {\n 0% { transform: translateX(${isReverse ? \"-100%\" : \"100%\"}); }\n 100% { transform: translateX(${isReverse ? \"100%\" : \"-100%\"}); }\n }`;\n\n return (\n <>\n <style>{keyframes}</style>\n <div\n style={{\n width: \"100%\",\n height: \"100%\",\n overflow: \"hidden\",\n display: \"flex\",\n alignItems: \"center\",\n backgroundColor:\n bgOpacity > 0\n ? `rgba(${hexToRgb(bgColor)}, ${bgOpacity})`\n : undefined,\n border:\n borderWidth > 0 ? `${borderWidth}px solid ${borderColor}` : undefined,\n borderRadius: borderRadius > 0 ? `${borderRadius}px` : undefined,\n padding: `${padding}px`,\n boxSizing: \"border-box\",\n pointerEvents: \"none\",\n }}\n >\n <div\n style={{\n whiteSpace: \"nowrap\",\n fontSize,\n fontFamily,\n fontWeight,\n color: textColor,\n animation: `${animId} ${durationSec}s linear infinite`,\n textShadow: \"0 1px 4px rgba(0,0,0,0.5)\",\n userSelect: \"none\",\n }}\n >\n {text}\n </div>\n </div>\n </>\n );\n}\n\nfunction parseConfig<T>(content?: string): T | null {\n if (!content) return null;\n try { return JSON.parse(content) as T; } catch { return null; }\n}\n\ninterface OverlaySize { w: number; h: number; }\n\ninterface ScoreBugCfg { homeTeam: string; awayTeam: string; homeScore: number; awayScore: number; period: string; clock: string; sponsorText: string; sponsorImageUrl: string; backgroundColor: string; textColor: string; accentColor: string; }\ninterface LowerThirdCfg { headline: string; subtitle: string; sponsorText: string; sponsorImageUrl: string; backgroundColor: string; textColor: string; accentColor: string; style: string; }\ninterface QrCodeCfg { url: string; ctaText: string; description: string; size: number; backgroundColor: string; textColor: string; accentColor: string; }\ninterface ComingUpNextCfg { title: string; subtitle: string; scheduledTime: string; thumbnailUrl: string; backgroundColor: string; textColor: string; accentColor: string; }\ninterface ContextualTriggerCfg { triggerType: string; headline: string; message: string; iconType: string; backgroundColor: string; textColor: string; accentColor: string; animationStyle: string; }\ninterface OddsBettingCfg { eventTitle: string; options: Array<{ label: string; odds: string }>; sponsorText: string; backgroundColor: string; textColor: string; accentColor: string; oddsFormat: string; }\ninterface BreakingNewsCfg { headline: string; body: string; urgency: string; backgroundColor: string; textColor: string; accentColor: string; }\ninterface CountdownCfg { eventName: string; targetTime: string; message: string; showDays: boolean; showHours: boolean; showMinutes: boolean; showSeconds: boolean; backgroundColor: string; textColor: string; accentColor: string; }\n\nfunction ScoreBugOverlay({ overlay, size }: { overlay: SwirlOverlay; size: OverlaySize }) {\n const cfg = parseConfig<ScoreBugCfg>(overlay.content);\n if (!cfg) return null;\n const f = Math.max(6, size.w * 0.058);\n return (\n <div style={{ width: \"100%\", height: \"100%\", borderRadius: Math.max(2, size.w * 0.035), display: \"flex\", flexDirection: \"column\", background: cfg.backgroundColor, color: cfg.textColor, fontFamily: \"Roboto, 'Segoe UI', Arial, sans-serif\", overflow: \"hidden\", pointerEvents: \"none\", userSelect: \"none\", fontSize: `${f}px` }}>\n <div style={{ flex: 1, display: \"flex\", alignItems: \"center\", padding: `0 ${f * 0.8}px`, gap: f * 0.4 }}>\n <div style={{ flex: 1, textAlign: \"center\" }}>\n <div style={{ fontSize: \"1em\", fontWeight: 700 }}>{cfg.homeTeam}</div>\n <div style={{ fontSize: \"1.8em\", fontWeight: 900, lineHeight: 1 }}>{cfg.homeScore}</div>\n </div>\n <div style={{ fontSize: \"0.8em\", textAlign: \"center\", opacity: 0.7, padding: `0 ${f * 0.4}px` }}>\n <div>{cfg.period}</div>\n <div>{cfg.clock}</div>\n </div>\n <div style={{ flex: 1, textAlign: \"center\" }}>\n <div style={{ fontSize: \"1em\", fontWeight: 700 }}>{cfg.awayTeam}</div>\n <div style={{ fontSize: \"1.8em\", fontWeight: 900, lineHeight: 1 }}>{cfg.awayScore}</div>\n </div>\n </div>\n {cfg.sponsorText && (\n <div style={{ fontSize: \"0.7em\", textAlign: \"center\", opacity: 0.5, padding: `${f * 0.2}px 0`, borderTop: `1px solid ${cfg.accentColor}40` }}>{cfg.sponsorText}</div>\n )}\n </div>\n );\n}\n\nfunction LowerThirdOverlay({ overlay, size }: { overlay: SwirlOverlay; size: OverlaySize }) {\n const cfg = parseConfig<LowerThirdCfg>(overlay.content);\n if (!cfg) return null;\n const f = Math.max(6, size.w * 0.055);\n return (\n <div style={{ width: \"100%\", height: \"100%\", borderRadius: Math.max(2, size.w * 0.02), display: \"flex\", flexDirection: \"column\", justifyContent: \"flex-end\", background: cfg.backgroundColor, color: cfg.textColor, fontFamily: \"Roboto, 'Segoe UI', Arial, sans-serif\", overflow: \"hidden\", pointerEvents: \"none\", userSelect: \"none\", fontSize: `${f}px` }}>\n <div style={{ width: \"100%\", height: Math.max(2, size.h * 0.06), backgroundColor: cfg.accentColor }} />\n <div style={{ flex: 1, display: \"flex\", flexDirection: \"column\", justifyContent: \"center\", padding: `${f * 0.5}px ${f * 1.2}px` }}>\n <div style={{ fontSize: \"1.4em\", fontWeight: 700, lineHeight: 1.2, textShadow: \"0 1px 4px rgba(0,0,0,0.5)\" }}>{cfg.headline}</div>\n <div style={{ fontSize: \"1em\", opacity: 0.7, marginTop: f * 0.2 }}>{cfg.subtitle}</div>\n </div>\n {cfg.sponsorText && (\n <div style={{ fontSize: \"0.7em\", opacity: 0.4, padding: `0 ${f * 1.2}px ${f * 0.4}px` }}>{cfg.sponsorText}</div>\n )}\n </div>\n );\n}\n\nfunction QrCodeOverlay({ overlay, size }: { overlay: SwirlOverlay; size: OverlaySize }) {\n const cfg = parseConfig<QrCodeCfg>(overlay.content);\n if (!cfg) return null;\n const qrSide = Math.max(32, Math.min(size.w, size.h) * 0.55);\n const qrUrl = `https://api.qrserver.com/v1/create-qr-code/?size=${Math.round(qrSide * 2)}x${Math.round(qrSide * 2)}&data=${encodeURIComponent(cfg.url || \"https://example.com\")}`;\n const f = Math.max(6, size.w * 0.06);\n return (\n <div style={{ width: \"100%\", height: \"100%\", borderRadius: Math.max(2, size.w * 0.035), display: \"flex\", flexDirection: \"column\", alignItems: \"center\", justifyContent: \"center\", gap: f * 0.4, background: cfg.backgroundColor, color: cfg.textColor, fontFamily: \"Roboto, 'Segoe UI', Arial, sans-serif\", padding: f * 0.6, boxSizing: \"border-box\", pointerEvents: \"none\", userSelect: \"none\", overflow: \"hidden\" }}>\n <div style={{ flexShrink: 0, background: \"#fff\", borderRadius: Math.max(2, qrSide * 0.06), padding: Math.max(2, qrSide * 0.06), lineHeight: 0 }}>\n <img src={qrUrl} alt=\"QR Code\" style={{ width: `${qrSide}px`, height: `${qrSide}px`, display: \"block\" }} />\n </div>\n <div style={{ fontSize: `${f * 1.1}px`, fontWeight: 700, textAlign: \"center\", color: cfg.accentColor, overflow: \"hidden\", textOverflow: \"ellipsis\", whiteSpace: \"nowrap\", width: \"100%\" }}>{cfg.ctaText}</div>\n {cfg.description && <div style={{ fontSize: `${f * 0.75}px`, opacity: 0.6, textAlign: \"center\", overflow: \"hidden\", textOverflow: \"ellipsis\", whiteSpace: \"nowrap\", width: \"100%\" }}>{cfg.description}</div>}\n </div>\n );\n}\n\nfunction ComingUpNextOverlay({ overlay, size }: { overlay: SwirlOverlay; size: OverlaySize }) {\n const cfg = parseConfig<ComingUpNextCfg>(overlay.content);\n if (!cfg) return null;\n const f = Math.max(6, size.w * 0.05);\n return (\n <div style={{ width: \"100%\", height: \"100%\", borderRadius: Math.max(2, size.w * 0.035), display: \"flex\", background: cfg.backgroundColor, color: cfg.textColor, fontFamily: \"Roboto, 'Segoe UI', Arial, sans-serif\", overflow: \"hidden\", pointerEvents: \"none\", userSelect: \"none\", fontSize: `${f}px` }}>\n <div style={{ width: Math.max(2, size.w * 0.015), flexShrink: 0, backgroundColor: cfg.accentColor }} />\n <div style={{ flex: 1, display: \"flex\", flexDirection: \"column\", justifyContent: \"center\", padding: `${f * 0.6}px ${f * 1.0}px`, minWidth: 0 }}>\n <div style={{ fontSize: \"0.8em\", fontWeight: 600, textTransform: \"uppercase\", letterSpacing: \"0.05em\", color: cfg.accentColor }}>Coming Up Next</div>\n <div style={{ fontSize: \"1.5em\", fontWeight: 700, lineHeight: 1.2, marginTop: f * 0.2, overflow: \"hidden\", textOverflow: \"ellipsis\", whiteSpace: \"nowrap\" }}>{cfg.title}</div>\n <div style={{ fontSize: \"0.9em\", opacity: 0.6, overflow: \"hidden\", textOverflow: \"ellipsis\", whiteSpace: \"nowrap\" }}>{cfg.subtitle}</div>\n {cfg.scheduledTime && <div style={{ fontSize: \"1em\", fontWeight: 600, marginTop: f * 0.4, color: cfg.accentColor }}>{cfg.scheduledTime}</div>}\n </div>\n </div>\n );\n}\n\nfunction ContextualTriggerOverlay({ overlay, size }: { overlay: SwirlOverlay; size: OverlaySize }) {\n const cfg = parseConfig<ContextualTriggerCfg>(overlay.content);\n if (!cfg) return null;\n const icons: Record<string, string> = { alert: \"\\u26A0\\uFE0F\", celebration: \"\\uD83C\\uDF89\", info: \"\\u2139\\uFE0F\", warning: \"\\uD83D\\uDD14\" };\n const f = Math.max(6, size.w * 0.05);\n return (\n <div style={{ width: \"100%\", height: \"100%\", borderRadius: Math.max(2, size.w * 0.035), display: \"flex\", alignItems: \"center\", gap: f * 0.8, padding: `0 ${f * 1.2}px`, background: cfg.backgroundColor, color: cfg.textColor, fontFamily: \"Roboto, 'Segoe UI', Arial, sans-serif\", borderLeft: `${Math.max(2, size.w * 0.02)}px solid ${cfg.accentColor}`, boxSizing: \"border-box\", pointerEvents: \"none\", userSelect: \"none\", fontSize: `${f}px` }}>\n <span style={{ fontSize: \"2em\", flexShrink: 0 }}>{icons[cfg.iconType] || \"\\u26A1\"}</span>\n <div style={{ flex: 1, minWidth: 0 }}>\n <div style={{ fontSize: \"1.3em\", fontWeight: 700, overflow: \"hidden\", textOverflow: \"ellipsis\", whiteSpace: \"nowrap\" }}>{cfg.headline}</div>\n <div style={{ fontSize: \"0.9em\", opacity: 0.7, overflow: \"hidden\", textOverflow: \"ellipsis\", whiteSpace: \"nowrap\" }}>{cfg.message}</div>\n </div>\n </div>\n );\n}\n\nfunction OddsBettingOverlay({ overlay, size }: { overlay: SwirlOverlay; size: OverlaySize }) {\n const cfg = parseConfig<OddsBettingCfg>(overlay.content);\n if (!cfg) return null;\n const f = Math.max(6, size.w * 0.052);\n return (\n <div style={{ width: \"100%\", height: \"100%\", borderRadius: Math.max(2, size.w * 0.035), display: \"flex\", flexDirection: \"column\", padding: f * 0.8, background: cfg.backgroundColor, color: cfg.textColor, fontFamily: \"Roboto, 'Segoe UI', Arial, sans-serif\", boxSizing: \"border-box\", pointerEvents: \"none\", userSelect: \"none\", fontSize: `${f}px` }}>\n <div style={{ fontSize: \"0.9em\", fontWeight: 700, textTransform: \"uppercase\", letterSpacing: \"0.05em\", color: cfg.accentColor, marginBottom: f * 0.4 }}>{cfg.eventTitle}</div>\n <div style={{ flex: 1, display: \"flex\", flexDirection: \"column\", gap: f * 0.2, justifyContent: \"center\" }}>\n {(cfg.options || []).slice(0, 5).map((opt, i) => (\n <div key={i} style={{ display: \"flex\", justifyContent: \"space-between\", alignItems: \"center\", padding: `${f * 0.2}px ${f * 0.6}px`, borderRadius: Math.max(2, f * 0.3), background: `${cfg.accentColor}15`, fontSize: \"1em\" }}>\n <span style={{ overflow: \"hidden\", textOverflow: \"ellipsis\", whiteSpace: \"nowrap\", flex: 1 }}>{opt.label}</span>\n <span style={{ fontWeight: 700, marginLeft: f * 0.8, flexShrink: 0, color: cfg.accentColor }}>{opt.odds}</span>\n </div>\n ))}\n </div>\n {cfg.sponsorText && <div style={{ fontSize: \"0.7em\", opacity: 0.4, textAlign: \"center\", marginTop: f * 0.4 }}>{cfg.sponsorText}</div>}\n </div>\n );\n}\n\nfunction BreakingNewsOverlay({ overlay, size }: { overlay: SwirlOverlay; size: OverlaySize }) {\n const cfg = parseConfig<BreakingNewsCfg>(overlay.content);\n if (!cfg) return null;\n const urgencyColors: Record<string, string> = { breaking: \"#dc2626\", urgent: \"#ea580c\", normal: \"#2563eb\" };\n const labelBg = urgencyColors[cfg.urgency] || urgencyColors.normal;\n const label = cfg.urgency === \"breaking\" ? \"BREAKING\" : cfg.urgency === \"urgent\" ? \"URGENT\" : \"NEWS\";\n const f = Math.max(6, size.w * 0.05);\n return (\n <div style={{ width: \"100%\", height: \"100%\", borderRadius: Math.max(2, size.w * 0.02), display: \"flex\", alignItems: \"center\", background: cfg.backgroundColor, color: cfg.textColor, fontFamily: \"Roboto, 'Segoe UI', Arial, sans-serif\", overflow: \"hidden\", pointerEvents: \"none\", userSelect: \"none\", fontSize: `${f}px` }}>\n <div style={{ padding: `0 ${f * 0.8}px`, height: \"100%\", display: \"flex\", alignItems: \"center\", background: labelBg, color: \"#fff\", fontSize: \"1em\", fontWeight: 900, textTransform: \"uppercase\", letterSpacing: \"0.05em\", flexShrink: 0 }}>{label}</div>\n <div style={{ flex: 1, padding: `0 ${f * 1.0}px`, minWidth: 0 }}>\n <div style={{ fontSize: \"1.3em\", fontWeight: 700, overflow: \"hidden\", textOverflow: \"ellipsis\", whiteSpace: \"nowrap\" }}>{cfg.headline}</div>\n {cfg.body && <div style={{ fontSize: \"0.9em\", opacity: 0.7, overflow: \"hidden\", textOverflow: \"ellipsis\", whiteSpace: \"nowrap\" }}>{cfg.body}</div>}\n </div>\n </div>\n );\n}\n\nfunction CountdownOverlay({ overlay, size }: { overlay: SwirlOverlay; size: OverlaySize }) {\n const cfg = parseConfig<CountdownCfg>(overlay.content);\n const [remaining, setRemaining] = useState({ d: 0, h: 0, m: 0, s: 0 });\n\n useEffect(() => {\n if (!cfg) return;\n const update = () => {\n const target = new Date(cfg.targetTime).getTime();\n const now = Date.now();\n const diff = Math.max(0, target - now);\n setRemaining({\n d: Math.floor(diff / 86400000),\n h: Math.floor((diff % 86400000) / 3600000),\n m: Math.floor((diff % 3600000) / 60000),\n s: Math.floor((diff % 60000) / 1000),\n });\n };\n update();\n const id = setInterval(update, 1000);\n return () => clearInterval(id);\n }, [cfg?.targetTime]);\n\n if (!cfg) return null;\n\n const f = Math.max(6, size.w * 0.055);\n const pad = (n: number) => String(n).padStart(2, \"0\");\n const units: Array<{ show: boolean; value: string; label: string }> = [\n { show: cfg.showDays, value: pad(remaining.d), label: \"DAYS\" },\n { show: cfg.showHours, value: pad(remaining.h), label: \"HRS\" },\n { show: cfg.showMinutes, value: pad(remaining.m), label: \"MIN\" },\n { show: cfg.showSeconds, value: pad(remaining.s), label: \"SEC\" },\n ];\n\n return (\n <div style={{ width: \"100%\", height: \"100%\", borderRadius: Math.max(2, size.w * 0.035), display: \"flex\", flexDirection: \"column\", alignItems: \"center\", justifyContent: \"center\", padding: f * 0.8, background: cfg.backgroundColor, color: cfg.textColor, fontFamily: \"Roboto, 'Segoe UI', Arial, sans-serif\", boxSizing: \"border-box\", pointerEvents: \"none\", userSelect: \"none\", fontSize: `${f}px` }}>\n <div style={{ fontSize: \"0.8em\", fontWeight: 600, textTransform: \"uppercase\", letterSpacing: \"0.05em\", color: cfg.accentColor, marginBottom: f * 0.4 }}>{cfg.eventName}</div>\n <div style={{ display: \"flex\", gap: f * 0.6, alignItems: \"center\" }}>\n {units.filter(u => u.show).map((u, i, arr) => (\n <React.Fragment key={u.label}>\n <div style={{ textAlign: \"center\" }}>\n <div style={{ fontSize: \"2em\", fontWeight: 900, lineHeight: 1, borderRadius: Math.max(2, f * 0.4), padding: `${f * 0.2}px ${f * 0.4}px`, background: `${cfg.accentColor}20` }}>{u.value}</div>\n <div style={{ fontSize: \"0.5em\", opacity: 0.5, marginTop: f * 0.2 }}>{u.label}</div>\n </div>\n {i < arr.length - 1 && <div style={{ fontSize: \"1.8em\", fontWeight: 700, opacity: 0.3 }}>:</div>}\n </React.Fragment>\n ))}\n </div>\n {cfg.message && <div style={{ fontSize: \"0.8em\", opacity: 0.6, marginTop: f * 0.4, textAlign: \"center\" }}>{cfg.message}</div>}\n </div>\n );\n}\n\nfunction ShapeOverlay({ overlay, size }: { overlay: SwirlOverlay; size: OverlaySize }) {\n const f = Math.max(6, size.w * 0.05);\n return (\n <div style={{ width: \"100%\", height: \"100%\", borderRadius: Math.max(2, size.w * 0.03), background: \"rgba(99, 102, 241, 0.2)\", border: \"2px solid rgba(99, 102, 241, 0.4)\", display: \"flex\", alignItems: \"center\", justifyContent: \"center\", pointerEvents: \"none\", userSelect: \"none\" }}>\n <div style={{ fontSize: `${f}px`, fontWeight: 500, color: \"rgba(163, 163, 163, 0.8)\", textTransform: \"uppercase\" }}>{overlay.name}</div>\n </div>\n );\n}\n\nfunction hexToRgb(hex: string): string {\n if (!hex || !hex.startsWith(\"#\")) return \"0,0,0\";\n const clean = hex.slice(1);\n const num = parseInt(clean.length === 3 ? clean.replace(/./g, \"$&$&\") : clean, 16);\n return `${(num >> 16) & 255},${(num >> 8) & 255},${num & 255}`;\n}\n\nexport const OverlayRenderer: React.FC<OverlayRendererProps> = ({\n overlays,\n currentTime,\n videoRef,\n coordinateSpace,\n}) => {\n const [dims, setDims] = useState<VideoDimensions | null>(null);\n const rafRef = useRef<number | null>(null);\n\n const updateDims = useCallback(() => {\n const video = videoRef.current;\n if (video) {\n const computed = computeVideoDimensions(video);\n setDims((prev) => {\n if (\n !computed ||\n (prev &&\n prev.nativeWidth === computed.nativeWidth &&\n prev.nativeHeight === computed.nativeHeight &&\n prev.displayWidth === computed.displayWidth &&\n prev.displayHeight === computed.displayHeight &&\n prev.offsetX === computed.offsetX &&\n prev.offsetY === computed.offsetY)\n ) {\n return prev;\n }\n return computed;\n });\n }\n }, [videoRef]);\n\n useEffect(() => {\n updateDims();\n const interval = setInterval(updateDims, 500);\n\n const handleResize = () => {\n if (rafRef.current) cancelAnimationFrame(rafRef.current);\n rafRef.current = requestAnimationFrame(updateDims);\n };\n window.addEventListener(\"resize\", handleResize);\n\n return () => {\n clearInterval(interval);\n window.removeEventListener(\"resize\", handleResize);\n if (rafRef.current) cancelAnimationFrame(rafRef.current);\n };\n }, [updateDims]);\n\n const activeOverlays = overlays.filter((o) =>\n isOverlayActive(o, currentTime)\n );\n\n if (!dims || activeOverlays.length === 0) return null;\n\n return (\n <div\n aria-hidden=\"true\"\n style={{\n position: \"absolute\",\n left: `${dims.offsetX}px`,\n top: `${dims.offsetY}px`,\n width: `${dims.displayWidth}px`,\n height: `${dims.displayHeight}px`,\n pointerEvents: \"none\",\n overflow: \"hidden\",\n zIndex: 8,\n }}\n >\n {activeOverlays.map((overlay) => {\n const scaleX =\n coordinateSpace?.width\n ? dims.displayWidth / coordinateSpace.width\n : dims.scaleX;\n const scaleY =\n coordinateSpace?.height\n ? dims.displayHeight / coordinateSpace.height\n : dims.scaleY;\n const left = overlay.x * scaleX;\n const top = overlay.y * scaleY;\n const width = overlay.width * scaleX;\n const height = overlay.height * scaleY;\n const opacity = Math.max(0, Math.min(100, overlay.opacity)) / 100;\n const sz: OverlaySize = { w: width, h: height };\n\n return (\n <div\n key={overlay.id}\n style={{\n position: \"absolute\",\n left: `${left}px`,\n top: `${top}px`,\n width: `${width}px`,\n height: `${height}px`,\n opacity,\n zIndex: overlay.z_index,\n overflow: \"hidden\",\n }}\n >\n {overlay.type === \"image\" && <ImageOverlay overlay={overlay} />}\n {overlay.type === \"text\" && <TextOverlay overlay={overlay} />}\n {overlay.type === \"scroller\" && <ScrollerOverlay overlay={overlay} />}\n {overlay.type === \"shape\" && <ShapeOverlay overlay={overlay} size={sz} />}\n {overlay.type === \"score_bug\" && <ScoreBugOverlay overlay={overlay} size={sz} />}\n {overlay.type === \"lower_third\" && <LowerThirdOverlay overlay={overlay} size={sz} />}\n {overlay.type === \"qr_code\" && <QrCodeOverlay overlay={overlay} size={sz} />}\n {overlay.type === \"coming_up_next\" && <ComingUpNextOverlay overlay={overlay} size={sz} />}\n {overlay.type === \"contextual_trigger\" && <ContextualTriggerOverlay overlay={overlay} size={sz} />}\n {overlay.type === \"odds_betting\" && <OddsBettingOverlay overlay={overlay} size={sz} />}\n {overlay.type === \"breaking_news\" && <BreakingNewsOverlay overlay={overlay} size={sz} />}\n {overlay.type === \"countdown\" && <CountdownOverlay overlay={overlay} size={sz} />}\n </div>\n );\n })}\n </div>\n );\n};\n","const OVERLAY_API_BASE = \"https://adstorm.co/api-adstorm-dev\";\n\nexport interface OverlayCoordinateSpace {\n width: number;\n height: number;\n}\n\nexport interface SwirlScrollerConfig {\n rss_url?: string;\n update_interval?: number;\n scroll_speed?: number;\n direction?: string;\n font_size?: number;\n font_family?: string;\n font_weight?: string;\n text_color?: string;\n background_color?: string;\n background_opacity?: number;\n border_color?: string;\n border_width?: number;\n border_radius?: number;\n padding?: number;\n margin?: number;\n show_title?: boolean;\n show_description?: boolean;\n show_timestamp?: boolean;\n show_author?: boolean;\n show_category?: boolean;\n max_items?: number;\n item_spacing?: number;\n fade_in_out?: boolean;\n fade_distance?: number;\n auto_refresh?: boolean;\n use_custom_text?: boolean;\n custom_text?: string;\n}\n\nexport type SwirlOverlayType =\n | \"image\"\n | \"text\"\n | \"scroller\"\n | \"shape\"\n | \"score_bug\"\n | \"lower_third\"\n | \"qr_code\"\n | \"coming_up_next\"\n | \"contextual_trigger\"\n | \"odds_betting\"\n | \"breaking_news\"\n | \"countdown\";\n\nexport interface SwirlOverlay {\n id: number;\n project_id: number;\n name: string;\n type: SwirlOverlayType | string;\n visible: boolean;\n x: number;\n y: number;\n width: number;\n height: number;\n opacity: number;\n start_time: string;\n duration: string;\n content?: string;\n image_url?: string;\n scroller_config?: SwirlScrollerConfig;\n z_index: number;\n created_at?: string;\n updated_at?: string;\n}\n\nexport function timeStringToSeconds(timeStr: string): number {\n if (!timeStr) return 0;\n\n const parts = timeStr.split(\":\");\n\n if (parts.length >= 3) {\n const hours = parseInt(parts[0] ?? \"0\", 10) || 0;\n const minutes = parseInt(parts[1] ?? \"0\", 10) || 0;\n const secStr = parts[2] ?? \"0\";\n const dotIdx = secStr.indexOf(\".\");\n const seconds =\n parseInt(dotIdx >= 0 ? secStr.substring(0, dotIdx) : secStr, 10) || 0;\n const msFrag = dotIdx >= 0 ? secStr.substring(dotIdx + 1) : \"\";\n const ms = msFrag ? parseInt(msFrag.padEnd(3, \"0\").substring(0, 3), 10) || 0 : 0;\n return hours * 3600 + minutes * 60 + seconds + ms / 1000;\n }\n\n if (parts.length === 2) {\n const minutes = parseInt(parts[0] ?? \"0\", 10) || 0;\n const secStr = parts[1] ?? \"0\";\n const dotIdx = secStr.indexOf(\".\");\n const seconds =\n parseInt(dotIdx >= 0 ? secStr.substring(0, dotIdx) : secStr, 10) || 0;\n const msFrag = dotIdx >= 0 ? secStr.substring(dotIdx + 1) : \"\";\n const ms = msFrag ? parseInt(msFrag.padEnd(3, \"0\").substring(0, 3), 10) || 0 : 0;\n return minutes * 60 + seconds + ms / 1000;\n }\n\n const num = parseFloat(timeStr);\n return isFinite(num) ? Math.max(0, num) : 0;\n}\n\nexport function isOverlayActive(\n overlay: SwirlOverlay,\n currentTime: number\n): boolean {\n if (!overlay.visible) return false;\n const startSec = timeStringToSeconds(overlay.start_time);\n const durationSec = timeStringToSeconds(overlay.duration);\n if (durationSec <= 0) return false;\n return currentTime >= startSec && currentTime < startSec + durationSec;\n}\n\nexport async function fetchProjectOverlays(\n projectId: number,\n apiBaseUrl: string = OVERLAY_API_BASE\n): Promise<SwirlOverlay[]> {\n const response = await fetch(\n `${apiBaseUrl}/adstorm/swirl/projects/${projectId}/overlays`\n );\n if (!response.ok) {\n throw new Error(\n `Failed to fetch overlays: ${response.status} ${response.statusText}`\n );\n }\n const data = await response.json();\n return Array.isArray(data) ? data : [];\n}\n\nexport function resolveImageUrl(\n imageUrl: string,\n apiBaseUrl: string = OVERLAY_API_BASE\n): string {\n if (!imageUrl) return \"\";\n if (imageUrl.startsWith(\"http://\") || imageUrl.startsWith(\"https://\")) {\n return imageUrl;\n }\n if (imageUrl.startsWith(\"/\")) {\n try {\n const url = new URL(apiBaseUrl);\n return `${url.origin}${imageUrl}`;\n } catch {\n return imageUrl;\n }\n }\n return `${apiBaseUrl}/${imageUrl}`;\n}\n"]}
1
+ {"version":3,"sources":["/home/ubuntu24-new/Dev/stormcloud-vp/lib/ui/OverlayRenderer.cjs","../../src/ui/OverlayRenderer.tsx","../../src/utils/overlays.ts"],"names":["__create","Object","create","__defProp","defineProperty","__getOwnPropNames","__getOwnPropDesc","getOwnPropertyDescriptor","getOwnPropertyNames","__getProtoOf","getPrototypeOf","__hasOwnProp","prototype","hasOwnProperty","__export","target","all","name","get","enumerable","__copyProps","to","from","except","desc","key","call","__toESM","mod","isNodeMode","__esModule","value","__toCommonJS","OverlayRenderer_exports","OverlayRenderer","module","exports","import_react","require","OVERLAY_API_BASE","timeStringToSeconds","timeStr","parts","split","length","hours","parseInt","minutes","secStr","dotIdx","seconds","indexOf","substring","msFrag","ms","padEnd","num","parseFloat","isFinite","Math","max","isOverlayActive","overlay","visible","currentTime","startSec","start_time","durationSec","duration","resolveImageUrl","imageUrl","apiBaseUrl","startsWith","url","URL","origin","import_jsx_runtime","computeVideoDimensions","video","nativeWidth","videoWidth","nativeHeight","videoHeight","displayWidth","offsetWidth","displayHeight","offsetHeight","videoAspect","displayAspect","renderWidth","renderHeight","offsetX","offsetY","scaleX","scaleY","ImageOverlay","src","image_url","jsx","alt","draggable","style","width","height","objectFit","display","pointerEvents","userSelect","TextOverlay","text","content","justifyContent","color","fontSize","fontFamily","fontWeight","textAlign","padding","boxSizing","wordBreak","textShadow","lineHeight","children","ScrollerOverlay","cfg","scroller_config","use_custom_text","custom_text","scrollSpeed","scroll_speed","direction","font_size","font_family","font_weight","textColor","text_color","bgColor","background_color","bgOpacity","background_opacity","borderColor","border_color","borderWidth","border_width","borderRadius","border_radius","isVertical","isReverse","animId","id","keyframes","jsxs","Fragment","overflow","alignItems","backgroundColor","hexToRgb","border","whiteSpace","animation","parseConfig","JSON","parse","ScoreBugOverlay","size","f","w","flexDirection","background","flex","gap","homeTeam","homeScore","opacity","period","clock","awayTeam","awayScore","borderTop","accentColor","sponsorImageUrl","flexShrink","sponsorText","textOverflow","LowerThirdOverlay","h","headline","marginTop","subtitle"],"mappings":"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","sourcesContent":["\"use strict\";\nvar __create = Object.create;\nvar __defProp = Object.defineProperty;\nvar __getOwnPropDesc = Object.getOwnPropertyDescriptor;\nvar __getOwnPropNames = Object.getOwnPropertyNames;\nvar __getProtoOf = Object.getPrototypeOf;\nvar __hasOwnProp = Object.prototype.hasOwnProperty;\nvar __export = (target, all) => {\n for (var name in all)\n __defProp(target, name, { get: all[name], enumerable: true });\n};\nvar __copyProps = (to, from, except, desc) => {\n if (from && typeof from === \"object\" || typeof from === \"function\") {\n for (let key of __getOwnPropNames(from))\n if (!__hasOwnProp.call(to, key) && key !== except)\n __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });\n }\n return to;\n};\nvar __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(\n // If the importer is in node compatibility mode or this is not an ESM\n // file that has been converted to a CommonJS file using a Babel-\n // compatible transform (i.e. \"__esModule\" has not been set), then set\n // \"default\" to the CommonJS \"module.exports\" for node compatibility.\n isNodeMode || !mod || !mod.__esModule ? __defProp(target, \"default\", { value: mod, enumerable: true }) : target,\n mod\n));\nvar __toCommonJS = (mod) => __copyProps(__defProp({}, \"__esModule\", { value: true }), mod);\n\n// src/ui/OverlayRenderer.tsx\nvar OverlayRenderer_exports = {};\n__export(OverlayRenderer_exports, {\n OverlayRenderer: () => OverlayRenderer\n});\nmodule.exports = __toCommonJS(OverlayRenderer_exports);\nvar import_react = __toESM(require(\"react\"), 1);\n\n// src/utils/overlays.ts\nvar OVERLAY_API_BASE = \"https://adstorm.co/api-adstorm-dev\";\nfunction timeStringToSeconds(timeStr) {\n if (!timeStr) return 0;\n const parts = timeStr.split(\":\");\n if (parts.length >= 3) {\n const hours = parseInt(parts[0] ?? \"0\", 10) || 0;\n const minutes = parseInt(parts[1] ?? \"0\", 10) || 0;\n const secStr = parts[2] ?? \"0\";\n const dotIdx = secStr.indexOf(\".\");\n const seconds = parseInt(dotIdx >= 0 ? secStr.substring(0, dotIdx) : secStr, 10) || 0;\n const msFrag = dotIdx >= 0 ? secStr.substring(dotIdx + 1) : \"\";\n const ms = msFrag ? parseInt(msFrag.padEnd(3, \"0\").substring(0, 3), 10) || 0 : 0;\n return hours * 3600 + minutes * 60 + seconds + ms / 1e3;\n }\n if (parts.length === 2) {\n const minutes = parseInt(parts[0] ?? \"0\", 10) || 0;\n const secStr = parts[1] ?? \"0\";\n const dotIdx = secStr.indexOf(\".\");\n const seconds = parseInt(dotIdx >= 0 ? secStr.substring(0, dotIdx) : secStr, 10) || 0;\n const msFrag = dotIdx >= 0 ? secStr.substring(dotIdx + 1) : \"\";\n const ms = msFrag ? parseInt(msFrag.padEnd(3, \"0\").substring(0, 3), 10) || 0 : 0;\n return minutes * 60 + seconds + ms / 1e3;\n }\n const num = parseFloat(timeStr);\n return isFinite(num) ? Math.max(0, num) : 0;\n}\nfunction isOverlayActive(overlay, currentTime) {\n if (!overlay.visible) return false;\n const startSec = timeStringToSeconds(overlay.start_time);\n const durationSec = timeStringToSeconds(overlay.duration);\n if (durationSec <= 0) return false;\n return currentTime >= startSec && currentTime < startSec + durationSec;\n}\nfunction resolveImageUrl(imageUrl, apiBaseUrl = OVERLAY_API_BASE) {\n if (!imageUrl) return \"\";\n if (imageUrl.startsWith(\"http://\") || imageUrl.startsWith(\"https://\")) {\n return imageUrl;\n }\n if (imageUrl.startsWith(\"/\")) {\n try {\n const url = new URL(apiBaseUrl);\n return `${url.origin}${imageUrl}`;\n } catch {\n return imageUrl;\n }\n }\n return `${apiBaseUrl}/${imageUrl}`;\n}\n\n// src/ui/OverlayRenderer.tsx\nvar import_jsx_runtime = require(\"react/jsx-runtime\");\nfunction computeVideoDimensions(video) {\n const nativeWidth = video.videoWidth;\n const nativeHeight = video.videoHeight;\n if (!nativeWidth || !nativeHeight) return null;\n const displayWidth = video.offsetWidth;\n const displayHeight = video.offsetHeight;\n if (!displayWidth || !displayHeight) return null;\n const videoAspect = nativeWidth / nativeHeight;\n const displayAspect = displayWidth / displayHeight;\n let renderWidth;\n let renderHeight;\n let offsetX;\n let offsetY;\n if (videoAspect > displayAspect) {\n renderWidth = displayWidth;\n renderHeight = displayWidth / videoAspect;\n offsetX = 0;\n offsetY = (displayHeight - renderHeight) / 2;\n } else {\n renderHeight = displayHeight;\n renderWidth = displayHeight * videoAspect;\n offsetX = (displayWidth - renderWidth) / 2;\n offsetY = 0;\n }\n return {\n nativeWidth,\n nativeHeight,\n displayWidth: renderWidth,\n displayHeight: renderHeight,\n offsetX,\n offsetY,\n scaleX: renderWidth / nativeWidth,\n scaleY: renderHeight / nativeHeight\n };\n}\nfunction ImageOverlay({ overlay }) {\n const src = resolveImageUrl(overlay.image_url || \"\");\n if (!src) return null;\n return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(\n \"img\",\n {\n src,\n alt: overlay.name,\n draggable: false,\n style: {\n width: \"100%\",\n height: \"100%\",\n objectFit: \"contain\",\n display: \"block\",\n pointerEvents: \"none\",\n userSelect: \"none\"\n }\n }\n );\n}\nfunction TextOverlay({ overlay }) {\n const text = overlay.content || \"\";\n return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(\n \"div\",\n {\n style: {\n width: \"100%\",\n height: \"100%\",\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n color: \"#ffffff\",\n fontSize: \"clamp(10px, 1.4vw, 20px)\",\n fontFamily: \"Roboto, 'Segoe UI', Arial, sans-serif\",\n fontWeight: 600,\n textAlign: \"center\",\n padding: \"4px 8px\",\n boxSizing: \"border-box\",\n wordBreak: \"break-word\",\n textShadow: \"0 1px 4px rgba(0,0,0,0.7)\",\n pointerEvents: \"none\",\n userSelect: \"none\",\n lineHeight: 1.3\n },\n children: text\n }\n );\n}\nfunction ScrollerOverlay({ overlay }) {\n const cfg = overlay.scroller_config;\n const text = cfg?.use_custom_text && cfg.custom_text ? cfg.custom_text : overlay.content || cfg?.custom_text || \"\";\n const scrollSpeed = cfg?.scroll_speed ?? 50;\n const direction = cfg?.direction ?? \"left\";\n const fontSize = cfg?.font_size ? `${cfg.font_size}px` : \"clamp(10px, 1.2vw, 18px)\";\n const fontFamily = cfg?.font_family || \"Roboto, 'Segoe UI', Arial, sans-serif\";\n const fontWeight = cfg?.font_weight || \"600\";\n const textColor = cfg?.text_color || \"#ffffff\";\n const bgColor = cfg?.background_color || \"transparent\";\n const bgOpacity = cfg?.background_opacity !== void 0 ? cfg.background_opacity / 100 : 0;\n const borderColor = cfg?.border_color || \"transparent\";\n const borderWidth = cfg?.border_width ?? 0;\n const borderRadius = cfg?.border_radius ?? 0;\n const padding = cfg?.padding ?? 4;\n const isVertical = direction === \"up\" || direction === \"down\";\n const isReverse = direction === \"right\" || direction === \"down\";\n const durationSec = Math.max(3, 120 - scrollSpeed);\n const animId = `sc-scroller-${overlay.id}`;\n const keyframes = isVertical ? `@keyframes ${animId} {\n 0% { transform: translateY(${isReverse ? \"-100%\" : \"100%\"}); }\n 100% { transform: translateY(${isReverse ? \"100%\" : \"-100%\"}); }\n }` : `@keyframes ${animId} {\n 0% { transform: translateX(${isReverse ? \"-100%\" : \"100%\"}); }\n 100% { transform: translateX(${isReverse ? \"100%\" : \"-100%\"}); }\n }`;\n return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: [\n /* @__PURE__ */ (0, import_jsx_runtime.jsx)(\"style\", { children: keyframes }),\n /* @__PURE__ */ (0, import_jsx_runtime.jsx)(\n \"div\",\n {\n style: {\n width: \"100%\",\n height: \"100%\",\n overflow: \"hidden\",\n display: \"flex\",\n alignItems: \"center\",\n backgroundColor: bgOpacity > 0 ? `rgba(${hexToRgb(bgColor)}, ${bgOpacity})` : void 0,\n border: borderWidth > 0 ? `${borderWidth}px solid ${borderColor}` : void 0,\n borderRadius: borderRadius > 0 ? `${borderRadius}px` : void 0,\n padding: `${padding}px`,\n boxSizing: \"border-box\",\n pointerEvents: \"none\"\n },\n children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(\n \"div\",\n {\n style: {\n whiteSpace: \"nowrap\",\n fontSize,\n fontFamily,\n fontWeight,\n color: textColor,\n animation: `${animId} ${durationSec}s linear infinite`,\n textShadow: \"0 1px 4px rgba(0,0,0,0.5)\",\n userSelect: \"none\"\n },\n children: text\n }\n )\n }\n )\n ] });\n}\nfunction parseConfig(content) {\n if (!content) return null;\n try {\n return JSON.parse(content);\n } catch {\n return null;\n }\n}\nfunction ScoreBugOverlay({ overlay, size }) {\n const cfg = parseConfig(overlay.content);\n if (!cfg) return null;\n const f = Math.max(6, size.w * 0.058);\n return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(\"div\", { style: { width: \"100%\", height: \"100%\", borderRadius: Math.max(2, size.w * 0.035), display: \"flex\", flexDirection: \"column\", background: cfg.backgroundColor, color: cfg.textColor, fontFamily: \"Roboto, 'Segoe UI', Arial, sans-serif\", overflow: \"hidden\", pointerEvents: \"none\", userSelect: \"none\", fontSize: `${f}px` }, children: [\n /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(\"div\", { style: { flex: 1, display: \"flex\", alignItems: \"center\", padding: `0 ${f * 0.8}px`, gap: f * 0.4 }, children: [\n /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(\"div\", { style: { flex: 1, textAlign: \"center\" }, children: [\n /* @__PURE__ */ (0, import_jsx_runtime.jsx)(\"div\", { style: { fontSize: \"1em\", fontWeight: 700 }, children: cfg.homeTeam }),\n /* @__PURE__ */ (0, import_jsx_runtime.jsx)(\"div\", { style: { fontSize: \"1.8em\", fontWeight: 900, lineHeight: 1 }, children: cfg.homeScore })\n ] }),\n /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(\"div\", { style: { fontSize: \"0.8em\", textAlign: \"center\", opacity: 0.7, padding: `0 ${f * 0.4}px` }, children: [\n /* @__PURE__ */ (0, import_jsx_runtime.jsx)(\"div\", { children: cfg.period }),\n /* @__PURE__ */ (0, import_jsx_runtime.jsx)(\"div\", { children: cfg.clock })\n ] }),\n /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(\"div\", { style: { flex: 1, textAlign: \"center\" }, children: [\n /* @__PURE__ */ (0, import_jsx_runtime.jsx)(\"div\", { style: { fontSize: \"1em\", fontWeight: 700 }, children: cfg.awayTeam }),\n /* @__PURE__ */ (0, import_jsx_runtime.jsx)(\"div\", { style: { fontSize: \"1.8em\", fontWeight: 900, lineHeight: 1 }, children: cfg.awayScore })\n ] })\n ] }),\n (cfg.sponsorText || cfg.sponsorImageUrl) && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(\"div\", { style: { fontSize: \"0.7em\", textAlign: \"center\", opacity: 0.6, padding: `${f * 0.2}px ${f * 0.4}px`, borderTop: `1px solid ${cfg.accentColor}40`, display: \"flex\", alignItems: \"center\", justifyContent: \"center\", gap: f * 0.4, overflow: \"hidden\" }, children: [\n cfg.sponsorImageUrl && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(\"img\", { src: cfg.sponsorImageUrl, alt: \"sponsor\", style: { height: `${f * 1.4}px`, objectFit: \"contain\", flexShrink: 0 } }),\n cfg.sponsorText && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(\"span\", { style: { overflow: \"hidden\", textOverflow: \"ellipsis\", whiteSpace: \"nowrap\" }, children: cfg.sponsorText })\n ] })\n ] });\n}\nfunction LowerThirdOverlay({ overlay, size }) {\n const cfg = parseConfig(overlay.content);\n if (!cfg) return null;\n const f = Math.max(6, size.w * 0.055);\n return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(\"div\", { style: { width: \"100%\", height: \"100%\", borderRadius: Math.max(2, size.w * 0.02), display: \"flex\", flexDirection: \"column\", justifyContent: \"flex-end\", background: cfg.backgroundColor, color: cfg.textColor, fontFamily: \"Roboto, 'Segoe UI', Arial, sans-serif\", overflow: \"hidden\", pointerEvents: \"none\", userSelect: \"none\", fontSize: `${f}px` }, children: [\n /* @__PURE__ */ (0, import_jsx_runtime.jsx)(\"div\", { style: { width: \"100%\", height: Math.max(2, size.h * 0.06), backgroundColor: cfg.accentColor } }),\n /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(\"div\", { style: { flex: 1, display: \"flex\", flexDirection: \"column\", justifyContent: \"center\", padding: `${f * 0.5}px ${f * 1.2}px` }, children: [\n /* @__PURE__ */ (0, import_jsx_runtime.jsx)(\"div\", { style: { fontSize: \"1.4em\", fontWeight: 700, lineHeight: 1.2, textShadow: \"0 1px 4px rgba(0,0,0,0.5)\" }, children: cfg.headline }),\n /* @__PURE__ */ (0, import_jsx_runtime.jsx)(\"div\", { style: { fontSize: \"1em\", opacity: 0.7, marginTop: f * 0.2 }, children: cfg.subtitle })\n ] }),\n (cfg.sponsorText || cfg.sponsorImageUrl) && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(\"div\", { style: { fontSize: \"0.7em\", opacity: 0.5, padding: `0 ${f * 1.2}px ${f * 0.4}px`, display: \"flex\", alignItems: \"center\", gap: f * 0.4, overflow: \"hidden\" }, children: [\n cfg.sponsorImageUrl && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(\"img\", { src: cfg.sponsorImageUrl, alt: \"sponsor\", style: { height: `${f * 1.4}px`, objectFit: \"contain\", flexShrink: 0 } }),\n cfg.sponsorText && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(\"span\", { style: { overflow: \"hidden\", textOverflow: \"ellipsis\", whiteSpace: \"nowrap\" }, children: cfg.sponsorText })\n ] })\n ] });\n}\nfunction QrCodeOverlay({ overlay, size }) {\n const cfg = parseConfig(overlay.content);\n if (!cfg) return null;\n const qrSide = Math.max(32, Math.min(size.w, size.h) * 0.55);\n const qrUrl = `https://api.qrserver.com/v1/create-qr-code/?size=${Math.round(qrSide * 2)}x${Math.round(qrSide * 2)}&data=${encodeURIComponent(cfg.url || \"https://example.com\")}`;\n const f = Math.max(6, size.w * 0.06);\n return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(\"div\", { style: { width: \"100%\", height: \"100%\", borderRadius: Math.max(2, size.w * 0.035), display: \"flex\", flexDirection: \"column\", alignItems: \"center\", justifyContent: \"center\", gap: f * 0.4, background: cfg.backgroundColor, color: cfg.textColor, fontFamily: \"Roboto, 'Segoe UI', Arial, sans-serif\", padding: f * 0.6, boxSizing: \"border-box\", pointerEvents: \"none\", userSelect: \"none\", overflow: \"hidden\" }, children: [\n /* @__PURE__ */ (0, import_jsx_runtime.jsx)(\"div\", { style: { flexShrink: 0, background: \"#fff\", borderRadius: Math.max(2, qrSide * 0.06), padding: Math.max(2, qrSide * 0.06), lineHeight: 0 }, children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(\"img\", { src: qrUrl, alt: \"QR Code\", style: { width: `${qrSide}px`, height: `${qrSide}px`, display: \"block\" } }) }),\n /* @__PURE__ */ (0, import_jsx_runtime.jsx)(\"div\", { style: { fontSize: `${f * 1.1}px`, fontWeight: 700, textAlign: \"center\", color: cfg.accentColor, overflow: \"hidden\", textOverflow: \"ellipsis\", whiteSpace: \"nowrap\", width: \"100%\" }, children: cfg.ctaText }),\n cfg.description && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(\"div\", { style: { fontSize: `${f * 0.75}px`, opacity: 0.6, textAlign: \"center\", overflow: \"hidden\", textOverflow: \"ellipsis\", whiteSpace: \"nowrap\", width: \"100%\" }, children: cfg.description })\n ] });\n}\nfunction ComingUpNextOverlay({ overlay, size }) {\n const cfg = parseConfig(overlay.content);\n if (!cfg) return null;\n const f = Math.max(6, size.w * 0.05);\n return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(\"div\", { style: { width: \"100%\", height: \"100%\", borderRadius: Math.max(2, size.w * 0.035), display: \"flex\", background: cfg.backgroundColor, color: cfg.textColor, fontFamily: \"Roboto, 'Segoe UI', Arial, sans-serif\", overflow: \"hidden\", pointerEvents: \"none\", userSelect: \"none\", fontSize: `${f}px` }, children: [\n /* @__PURE__ */ (0, import_jsx_runtime.jsx)(\"div\", { style: { width: Math.max(2, size.w * 0.015), flexShrink: 0, backgroundColor: cfg.accentColor } }),\n /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(\"div\", { style: { flex: 1, display: \"flex\", flexDirection: \"column\", justifyContent: \"center\", padding: `${f * 0.6}px ${f * 1}px`, minWidth: 0 }, children: [\n /* @__PURE__ */ (0, import_jsx_runtime.jsx)(\"div\", { style: { fontSize: \"0.8em\", fontWeight: 600, textTransform: \"uppercase\", letterSpacing: \"0.05em\", color: cfg.accentColor }, children: \"Coming Up Next\" }),\n /* @__PURE__ */ (0, import_jsx_runtime.jsx)(\"div\", { style: { fontSize: \"1.5em\", fontWeight: 700, lineHeight: 1.2, marginTop: f * 0.2, overflow: \"hidden\", textOverflow: \"ellipsis\", whiteSpace: \"nowrap\" }, children: cfg.title }),\n /* @__PURE__ */ (0, import_jsx_runtime.jsx)(\"div\", { style: { fontSize: \"0.9em\", opacity: 0.6, overflow: \"hidden\", textOverflow: \"ellipsis\", whiteSpace: \"nowrap\" }, children: cfg.subtitle }),\n cfg.scheduledTime && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(\"div\", { style: { fontSize: \"1em\", fontWeight: 600, marginTop: f * 0.4, color: cfg.accentColor }, children: cfg.scheduledTime })\n ] }),\n cfg.thumbnailUrl && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(\"div\", { style: { flexShrink: 0, width: Math.max(40, size.h * 0.75), overflow: \"hidden\" }, children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(\"img\", { src: cfg.thumbnailUrl, alt: \"thumbnail\", style: { width: \"100%\", height: \"100%\", objectFit: \"cover\", display: \"block\" } }) })\n ] });\n}\nfunction ContextualTriggerOverlay({ overlay, size }) {\n const cfg = parseConfig(overlay.content);\n if (!cfg) return null;\n const icons = { alert: \"\\u26A0\\uFE0F\", celebration: \"\\u{1F389}\", info: \"\\u2139\\uFE0F\", warning: \"\\u{1F514}\" };\n const f = Math.max(6, size.w * 0.05);\n return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(\"div\", { style: { width: \"100%\", height: \"100%\", borderRadius: Math.max(2, size.w * 0.035), display: \"flex\", alignItems: \"center\", gap: f * 0.8, padding: `0 ${f * 1.2}px`, background: cfg.backgroundColor, color: cfg.textColor, fontFamily: \"Roboto, 'Segoe UI', Arial, sans-serif\", borderLeft: `${Math.max(2, size.w * 0.02)}px solid ${cfg.accentColor}`, boxSizing: \"border-box\", pointerEvents: \"none\", userSelect: \"none\", fontSize: `${f}px` }, children: [\n /* @__PURE__ */ (0, import_jsx_runtime.jsx)(\"span\", { style: { fontSize: \"2em\", flexShrink: 0 }, children: icons[cfg.iconType] || \"\\u26A1\" }),\n /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(\"div\", { style: { flex: 1, minWidth: 0 }, children: [\n /* @__PURE__ */ (0, import_jsx_runtime.jsx)(\"div\", { style: { fontSize: \"1.3em\", fontWeight: 700, overflow: \"hidden\", textOverflow: \"ellipsis\", whiteSpace: \"nowrap\" }, children: cfg.headline }),\n /* @__PURE__ */ (0, import_jsx_runtime.jsx)(\"div\", { style: { fontSize: \"0.9em\", opacity: 0.7, overflow: \"hidden\", textOverflow: \"ellipsis\", whiteSpace: \"nowrap\" }, children: cfg.message })\n ] })\n ] });\n}\nfunction OddsBettingOverlay({ overlay, size }) {\n const cfg = parseConfig(overlay.content);\n if (!cfg) return null;\n const f = Math.max(6, size.w * 0.052);\n return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(\"div\", { style: { width: \"100%\", height: \"100%\", borderRadius: Math.max(2, size.w * 0.035), display: \"flex\", flexDirection: \"column\", padding: f * 0.8, background: cfg.backgroundColor, color: cfg.textColor, fontFamily: \"Roboto, 'Segoe UI', Arial, sans-serif\", boxSizing: \"border-box\", pointerEvents: \"none\", userSelect: \"none\", fontSize: `${f}px` }, children: [\n /* @__PURE__ */ (0, import_jsx_runtime.jsx)(\"div\", { style: { fontSize: \"0.9em\", fontWeight: 700, textTransform: \"uppercase\", letterSpacing: \"0.05em\", color: cfg.accentColor, marginBottom: f * 0.4 }, children: cfg.eventTitle }),\n /* @__PURE__ */ (0, import_jsx_runtime.jsx)(\"div\", { style: { flex: 1, display: \"flex\", flexDirection: \"column\", gap: f * 0.2, justifyContent: \"center\" }, children: (cfg.options || []).slice(0, 5).map((opt, i) => /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(\"div\", { style: { display: \"flex\", justifyContent: \"space-between\", alignItems: \"center\", padding: `${f * 0.2}px ${f * 0.6}px`, borderRadius: Math.max(2, f * 0.3), background: `${cfg.accentColor}15`, fontSize: \"1em\" }, children: [\n /* @__PURE__ */ (0, import_jsx_runtime.jsx)(\"span\", { style: { overflow: \"hidden\", textOverflow: \"ellipsis\", whiteSpace: \"nowrap\", flex: 1 }, children: opt.label }),\n /* @__PURE__ */ (0, import_jsx_runtime.jsx)(\"span\", { style: { fontWeight: 700, marginLeft: f * 0.8, flexShrink: 0, color: cfg.accentColor }, children: opt.odds })\n ] }, i)) }),\n cfg.sponsorText && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(\"div\", { style: { fontSize: \"0.7em\", opacity: 0.4, textAlign: \"center\", marginTop: f * 0.4 }, children: cfg.sponsorText })\n ] });\n}\nfunction BreakingNewsOverlay({ overlay, size }) {\n const cfg = parseConfig(overlay.content);\n if (!cfg) return null;\n const urgencyColors = { breaking: \"#dc2626\", urgent: \"#ea580c\", normal: \"#2563eb\" };\n const labelBg = urgencyColors[cfg.urgency] || urgencyColors.normal;\n const label = cfg.urgency === \"breaking\" ? \"BREAKING\" : cfg.urgency === \"urgent\" ? \"URGENT\" : \"NEWS\";\n const f = Math.max(6, size.w * 0.05);\n return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(\"div\", { style: { width: \"100%\", height: \"100%\", borderRadius: Math.max(2, size.w * 0.02), display: \"flex\", alignItems: \"center\", background: cfg.backgroundColor, color: cfg.textColor, fontFamily: \"Roboto, 'Segoe UI', Arial, sans-serif\", overflow: \"hidden\", pointerEvents: \"none\", userSelect: \"none\", fontSize: `${f}px` }, children: [\n /* @__PURE__ */ (0, import_jsx_runtime.jsx)(\"div\", { style: { padding: `0 ${f * 0.8}px`, height: \"100%\", display: \"flex\", alignItems: \"center\", background: labelBg, color: \"#fff\", fontSize: \"1em\", fontWeight: 900, textTransform: \"uppercase\", letterSpacing: \"0.05em\", flexShrink: 0 }, children: label }),\n /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(\"div\", { style: { flex: 1, padding: `0 ${f * 1}px`, minWidth: 0 }, children: [\n /* @__PURE__ */ (0, import_jsx_runtime.jsx)(\"div\", { style: { fontSize: \"1.3em\", fontWeight: 700, overflow: \"hidden\", textOverflow: \"ellipsis\", whiteSpace: \"nowrap\" }, children: cfg.headline }),\n cfg.body && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(\"div\", { style: { fontSize: \"0.9em\", opacity: 0.7, overflow: \"hidden\", textOverflow: \"ellipsis\", whiteSpace: \"nowrap\" }, children: cfg.body })\n ] })\n ] });\n}\nfunction calcCountdownRemaining(targetTime) {\n const diff = Math.max(0, new Date(targetTime).getTime() - Date.now());\n return {\n d: Math.floor(diff / 864e5),\n h: Math.floor(diff % 864e5 / 36e5),\n m: Math.floor(diff % 36e5 / 6e4),\n s: Math.floor(diff % 6e4 / 1e3),\n expired: diff === 0\n };\n}\nfunction CountdownOverlay({ overlay, size }) {\n const cfg = parseConfig(overlay.content);\n const targetTime = cfg?.targetTime ?? \"\";\n const [remaining, setRemaining] = (0, import_react.useState)(\n () => targetTime ? calcCountdownRemaining(targetTime) : { d: 0, h: 0, m: 0, s: 0, expired: false }\n );\n (0, import_react.useEffect)(() => {\n if (!targetTime) return;\n setRemaining(calcCountdownRemaining(targetTime));\n const id = setInterval(() => setRemaining(calcCountdownRemaining(targetTime)), 1e3);\n return () => clearInterval(id);\n }, [targetTime]);\n if (!cfg) return null;\n const f = Math.max(6, size.w * 0.055);\n const pad = (n) => String(n).padStart(2, \"0\");\n const units = [\n { show: cfg.showDays, value: pad(remaining.d), label: \"DAYS\" },\n { show: cfg.showHours, value: pad(remaining.h), label: \"HRS\" },\n { show: cfg.showMinutes, value: pad(remaining.m), label: \"MIN\" },\n { show: cfg.showSeconds, value: pad(remaining.s), label: \"SEC\" }\n ];\n return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(\"div\", { style: { width: \"100%\", height: \"100%\", borderRadius: Math.max(2, size.w * 0.035), display: \"flex\", flexDirection: \"column\", alignItems: \"center\", justifyContent: \"center\", padding: f * 0.8, background: cfg.backgroundColor, color: cfg.textColor, fontFamily: \"Roboto, 'Segoe UI', Arial, sans-serif\", boxSizing: \"border-box\", pointerEvents: \"none\", userSelect: \"none\", fontSize: `${f}px` }, children: [\n /* @__PURE__ */ (0, import_jsx_runtime.jsx)(\"div\", { style: { fontSize: \"0.8em\", fontWeight: 600, textTransform: \"uppercase\", letterSpacing: \"0.05em\", color: cfg.accentColor, marginBottom: f * 0.4 }, children: cfg.eventName }),\n remaining.expired ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(\"div\", { style: { fontSize: \"1em\", fontWeight: 700, opacity: 0.6 }, children: cfg.message || \"Event ended\" }) : /* @__PURE__ */ (0, import_jsx_runtime.jsx)(\"div\", { style: { display: \"flex\", gap: f * 0.6, alignItems: \"center\" }, children: units.filter((u) => u.show).map((u, i, arr) => /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_react.default.Fragment, { children: [\n /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(\"div\", { style: { textAlign: \"center\" }, children: [\n /* @__PURE__ */ (0, import_jsx_runtime.jsx)(\"div\", { style: { fontSize: \"2em\", fontWeight: 900, lineHeight: 1, borderRadius: Math.max(2, f * 0.4), padding: `${f * 0.2}px ${f * 0.4}px`, background: `${cfg.accentColor}20` }, children: u.value }),\n /* @__PURE__ */ (0, import_jsx_runtime.jsx)(\"div\", { style: { fontSize: \"0.5em\", opacity: 0.5, marginTop: f * 0.2 }, children: u.label })\n ] }),\n i < arr.length - 1 && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(\"div\", { style: { fontSize: \"1.8em\", fontWeight: 700, opacity: 0.3 }, children: \":\" })\n ] }, u.label)) }),\n !remaining.expired && cfg.message && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(\"div\", { style: { fontSize: \"0.8em\", opacity: 0.6, marginTop: f * 0.4, textAlign: \"center\" }, children: cfg.message })\n ] });\n}\nfunction ShapeOverlay({ overlay, size }) {\n const f = Math.max(6, size.w * 0.05);\n return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(\"div\", { style: { width: \"100%\", height: \"100%\", borderRadius: Math.max(2, size.w * 0.03), background: \"rgba(99, 102, 241, 0.2)\", border: \"2px solid rgba(99, 102, 241, 0.4)\", display: \"flex\", alignItems: \"center\", justifyContent: \"center\", pointerEvents: \"none\", userSelect: \"none\" }, children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(\"div\", { style: { fontSize: `${f}px`, fontWeight: 500, color: \"rgba(163, 163, 163, 0.8)\", textTransform: \"uppercase\" }, children: overlay.name }) });\n}\nfunction hexToRgb(hex) {\n if (!hex || !hex.startsWith(\"#\")) return \"0,0,0\";\n const clean = hex.slice(1);\n const num = parseInt(clean.length === 3 ? clean.replace(/./g, \"$&$&\") : clean, 16);\n return `${num >> 16 & 255},${num >> 8 & 255},${num & 255}`;\n}\nvar OverlayRenderer = ({\n overlays,\n currentTime,\n videoRef,\n coordinateSpace\n}) => {\n const [dims, setDims] = (0, import_react.useState)(null);\n const rafRef = (0, import_react.useRef)(null);\n const updateDims = (0, import_react.useCallback)(() => {\n const video = videoRef.current;\n if (video) {\n const computed = computeVideoDimensions(video);\n setDims((prev) => {\n if (!computed || prev && prev.nativeWidth === computed.nativeWidth && prev.nativeHeight === computed.nativeHeight && prev.displayWidth === computed.displayWidth && prev.displayHeight === computed.displayHeight && prev.offsetX === computed.offsetX && prev.offsetY === computed.offsetY) {\n return prev;\n }\n return computed;\n });\n }\n }, [videoRef]);\n (0, import_react.useEffect)(() => {\n updateDims();\n const interval = setInterval(updateDims, 500);\n const handleResize = () => {\n if (rafRef.current) cancelAnimationFrame(rafRef.current);\n rafRef.current = requestAnimationFrame(updateDims);\n };\n window.addEventListener(\"resize\", handleResize);\n return () => {\n clearInterval(interval);\n window.removeEventListener(\"resize\", handleResize);\n if (rafRef.current) cancelAnimationFrame(rafRef.current);\n };\n }, [updateDims]);\n const activeOverlays = overlays.filter(\n (o) => isOverlayActive(o, currentTime)\n );\n if (!dims || activeOverlays.length === 0) return null;\n return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(\n \"div\",\n {\n \"aria-hidden\": \"true\",\n style: {\n position: \"absolute\",\n left: `${dims.offsetX}px`,\n top: `${dims.offsetY}px`,\n width: `${dims.displayWidth}px`,\n height: `${dims.displayHeight}px`,\n pointerEvents: \"none\",\n overflow: \"hidden\",\n zIndex: 8\n },\n children: activeOverlays.map((overlay) => {\n const scaleX = coordinateSpace?.width ? dims.displayWidth / coordinateSpace.width : dims.scaleX;\n const scaleY = coordinateSpace?.height ? dims.displayHeight / coordinateSpace.height : dims.scaleY;\n const left = overlay.x * scaleX;\n const top = overlay.y * scaleY;\n const width = overlay.width * scaleX;\n const height = overlay.height * scaleY;\n const opacity = Math.max(0, Math.min(100, overlay.opacity)) / 100;\n const sz = { w: width, h: height };\n return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(\n \"div\",\n {\n style: {\n position: \"absolute\",\n left: `${left}px`,\n top: `${top}px`,\n width: `${width}px`,\n height: `${height}px`,\n opacity,\n zIndex: overlay.z_index,\n overflow: \"hidden\"\n },\n children: [\n overlay.type === \"image\" && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(ImageOverlay, { overlay }),\n overlay.type === \"text\" && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(TextOverlay, { overlay }),\n overlay.type === \"scroller\" && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(ScrollerOverlay, { overlay }),\n overlay.type === \"shape\" && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(ShapeOverlay, { overlay, size: sz }),\n overlay.type === \"score_bug\" && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(ScoreBugOverlay, { overlay, size: sz }),\n overlay.type === \"lower_third\" && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(LowerThirdOverlay, { overlay, size: sz }),\n overlay.type === \"qr_code\" && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(QrCodeOverlay, { overlay, size: sz }),\n overlay.type === \"coming_up_next\" && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(ComingUpNextOverlay, { overlay, size: sz }),\n overlay.type === \"contextual_trigger\" && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(ContextualTriggerOverlay, { overlay, size: sz }),\n overlay.type === \"odds_betting\" && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(OddsBettingOverlay, { overlay, size: sz }),\n overlay.type === \"breaking_news\" && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(BreakingNewsOverlay, { overlay, size: sz }),\n overlay.type === \"countdown\" && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(CountdownOverlay, { overlay, size: sz })\n ]\n },\n overlay.id\n );\n })\n }\n );\n};\n// Annotate the CommonJS export names for ESM import in node:\n0 && (module.exports = {\n OverlayRenderer\n});\n","import React, { useEffect, useRef, useState, useCallback } from \"react\";\nimport {\n type SwirlOverlay,\n isOverlayActive,\n resolveImageUrl,\n} from \"../utils/overlays\";\n\ninterface VideoDimensions {\n nativeWidth: number;\n nativeHeight: number;\n displayWidth: number;\n displayHeight: number;\n offsetX: number;\n offsetY: number;\n scaleX: number;\n scaleY: number;\n}\n\ninterface OverlayRendererProps {\n overlays: SwirlOverlay[];\n currentTime: number;\n videoRef: React.RefObject<HTMLVideoElement | null>;\n coordinateSpace?: { width: number; height: number } | null;\n}\n\nfunction computeVideoDimensions(\n video: HTMLVideoElement\n): VideoDimensions | null {\n const nativeWidth = video.videoWidth;\n const nativeHeight = video.videoHeight;\n if (!nativeWidth || !nativeHeight) return null;\n\n const displayWidth = video.offsetWidth;\n const displayHeight = video.offsetHeight;\n if (!displayWidth || !displayHeight) return null;\n\n const videoAspect = nativeWidth / nativeHeight;\n const displayAspect = displayWidth / displayHeight;\n\n let renderWidth: number;\n let renderHeight: number;\n let offsetX: number;\n let offsetY: number;\n\n if (videoAspect > displayAspect) {\n renderWidth = displayWidth;\n renderHeight = displayWidth / videoAspect;\n offsetX = 0;\n offsetY = (displayHeight - renderHeight) / 2;\n } else {\n renderHeight = displayHeight;\n renderWidth = displayHeight * videoAspect;\n offsetX = (displayWidth - renderWidth) / 2;\n offsetY = 0;\n }\n\n return {\n nativeWidth,\n nativeHeight,\n displayWidth: renderWidth,\n displayHeight: renderHeight,\n offsetX,\n offsetY,\n scaleX: renderWidth / nativeWidth,\n scaleY: renderHeight / nativeHeight,\n };\n}\n\nfunction ImageOverlay({ overlay }: { overlay: SwirlOverlay }) {\n const src = resolveImageUrl(overlay.image_url || \"\");\n if (!src) return null;\n return (\n <img\n src={src}\n alt={overlay.name}\n draggable={false}\n style={{\n width: \"100%\",\n height: \"100%\",\n objectFit: \"contain\",\n display: \"block\",\n pointerEvents: \"none\",\n userSelect: \"none\",\n }}\n />\n );\n}\n\nfunction TextOverlay({ overlay }: { overlay: SwirlOverlay }) {\n const text = overlay.content || \"\";\n return (\n <div\n style={{\n width: \"100%\",\n height: \"100%\",\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n color: \"#ffffff\",\n fontSize: \"clamp(10px, 1.4vw, 20px)\",\n fontFamily: \"Roboto, 'Segoe UI', Arial, sans-serif\",\n fontWeight: 600,\n textAlign: \"center\",\n padding: \"4px 8px\",\n boxSizing: \"border-box\",\n wordBreak: \"break-word\",\n textShadow: \"0 1px 4px rgba(0,0,0,0.7)\",\n pointerEvents: \"none\",\n userSelect: \"none\",\n lineHeight: 1.3,\n }}\n >\n {text}\n </div>\n );\n}\n\nfunction ScrollerOverlay({ overlay }: { overlay: SwirlOverlay }) {\n const cfg = overlay.scroller_config;\n const text =\n cfg?.use_custom_text && cfg.custom_text\n ? cfg.custom_text\n : overlay.content || cfg?.custom_text || \"\";\n\n const scrollSpeed = cfg?.scroll_speed ?? 50;\n const direction = cfg?.direction ?? \"left\";\n const fontSize = cfg?.font_size ? `${cfg.font_size}px` : \"clamp(10px, 1.2vw, 18px)\";\n const fontFamily = cfg?.font_family || \"Roboto, 'Segoe UI', Arial, sans-serif\";\n const fontWeight = cfg?.font_weight || \"600\";\n const textColor = cfg?.text_color || \"#ffffff\";\n const bgColor = cfg?.background_color || \"transparent\";\n const bgOpacity = cfg?.background_opacity !== undefined ? cfg.background_opacity / 100 : 0;\n const borderColor = cfg?.border_color || \"transparent\";\n const borderWidth = cfg?.border_width ?? 0;\n const borderRadius = cfg?.border_radius ?? 0;\n const padding = cfg?.padding ?? 4;\n\n const isVertical = direction === \"up\" || direction === \"down\";\n const isReverse = direction === \"right\" || direction === \"down\";\n\n const durationSec = Math.max(3, 120 - scrollSpeed);\n\n const animId = `sc-scroller-${overlay.id}`;\n const keyframes = isVertical\n ? `@keyframes ${animId} {\n 0% { transform: translateY(${isReverse ? \"-100%\" : \"100%\"}); }\n 100% { transform: translateY(${isReverse ? \"100%\" : \"-100%\"}); }\n }`\n : `@keyframes ${animId} {\n 0% { transform: translateX(${isReverse ? \"-100%\" : \"100%\"}); }\n 100% { transform: translateX(${isReverse ? \"100%\" : \"-100%\"}); }\n }`;\n\n return (\n <>\n <style>{keyframes}</style>\n <div\n style={{\n width: \"100%\",\n height: \"100%\",\n overflow: \"hidden\",\n display: \"flex\",\n alignItems: \"center\",\n backgroundColor:\n bgOpacity > 0\n ? `rgba(${hexToRgb(bgColor)}, ${bgOpacity})`\n : undefined,\n border:\n borderWidth > 0 ? `${borderWidth}px solid ${borderColor}` : undefined,\n borderRadius: borderRadius > 0 ? `${borderRadius}px` : undefined,\n padding: `${padding}px`,\n boxSizing: \"border-box\",\n pointerEvents: \"none\",\n }}\n >\n <div\n style={{\n whiteSpace: \"nowrap\",\n fontSize,\n fontFamily,\n fontWeight,\n color: textColor,\n animation: `${animId} ${durationSec}s linear infinite`,\n textShadow: \"0 1px 4px rgba(0,0,0,0.5)\",\n userSelect: \"none\",\n }}\n >\n {text}\n </div>\n </div>\n </>\n );\n}\n\nfunction parseConfig<T>(content?: string): T | null {\n if (!content) return null;\n try { return JSON.parse(content) as T; } catch { return null; }\n}\n\ninterface OverlaySize { w: number; h: number; }\n\ninterface ScoreBugCfg { homeTeam: string; awayTeam: string; homeScore: number; awayScore: number; period: string; clock: string; sponsorText: string; sponsorImageUrl: string; backgroundColor: string; textColor: string; accentColor: string; }\ninterface LowerThirdCfg { headline: string; subtitle: string; sponsorText: string; sponsorImageUrl: string; backgroundColor: string; textColor: string; accentColor: string; style: string; }\ninterface QrCodeCfg { url: string; ctaText: string; description: string; size: number; backgroundColor: string; textColor: string; accentColor: string; }\ninterface ComingUpNextCfg { title: string; subtitle: string; scheduledTime: string; thumbnailUrl: string; backgroundColor: string; textColor: string; accentColor: string; }\ninterface ContextualTriggerCfg { triggerType: string; headline: string; message: string; iconType: string; backgroundColor: string; textColor: string; accentColor: string; animationStyle: string; }\ninterface OddsBettingCfg { eventTitle: string; options: Array<{ label: string; odds: string }>; sponsorText: string; backgroundColor: string; textColor: string; accentColor: string; oddsFormat: string; }\ninterface BreakingNewsCfg { headline: string; body: string; urgency: string; backgroundColor: string; textColor: string; accentColor: string; }\ninterface CountdownCfg { eventName: string; targetTime: string; message: string; showDays: boolean; showHours: boolean; showMinutes: boolean; showSeconds: boolean; backgroundColor: string; textColor: string; accentColor: string; }\n\nfunction ScoreBugOverlay({ overlay, size }: { overlay: SwirlOverlay; size: OverlaySize }) {\n const cfg = parseConfig<ScoreBugCfg>(overlay.content);\n if (!cfg) return null;\n const f = Math.max(6, size.w * 0.058);\n return (\n <div style={{ width: \"100%\", height: \"100%\", borderRadius: Math.max(2, size.w * 0.035), display: \"flex\", flexDirection: \"column\", background: cfg.backgroundColor, color: cfg.textColor, fontFamily: \"Roboto, 'Segoe UI', Arial, sans-serif\", overflow: \"hidden\", pointerEvents: \"none\", userSelect: \"none\", fontSize: `${f}px` }}>\n <div style={{ flex: 1, display: \"flex\", alignItems: \"center\", padding: `0 ${f * 0.8}px`, gap: f * 0.4 }}>\n <div style={{ flex: 1, textAlign: \"center\" }}>\n <div style={{ fontSize: \"1em\", fontWeight: 700 }}>{cfg.homeTeam}</div>\n <div style={{ fontSize: \"1.8em\", fontWeight: 900, lineHeight: 1 }}>{cfg.homeScore}</div>\n </div>\n <div style={{ fontSize: \"0.8em\", textAlign: \"center\", opacity: 0.7, padding: `0 ${f * 0.4}px` }}>\n <div>{cfg.period}</div>\n <div>{cfg.clock}</div>\n </div>\n <div style={{ flex: 1, textAlign: \"center\" }}>\n <div style={{ fontSize: \"1em\", fontWeight: 700 }}>{cfg.awayTeam}</div>\n <div style={{ fontSize: \"1.8em\", fontWeight: 900, lineHeight: 1 }}>{cfg.awayScore}</div>\n </div>\n </div>\n {(cfg.sponsorText || cfg.sponsorImageUrl) && (\n <div style={{ fontSize: \"0.7em\", textAlign: \"center\", opacity: 0.6, padding: `${f * 0.2}px ${f * 0.4}px`, borderTop: `1px solid ${cfg.accentColor}40`, display: \"flex\", alignItems: \"center\", justifyContent: \"center\", gap: f * 0.4, overflow: \"hidden\" }}>\n {cfg.sponsorImageUrl && <img src={cfg.sponsorImageUrl} alt=\"sponsor\" style={{ height: `${f * 1.4}px`, objectFit: \"contain\", flexShrink: 0 }} />}\n {cfg.sponsorText && <span style={{ overflow: \"hidden\", textOverflow: \"ellipsis\", whiteSpace: \"nowrap\" }}>{cfg.sponsorText}</span>}\n </div>\n )}\n </div>\n );\n}\n\nfunction LowerThirdOverlay({ overlay, size }: { overlay: SwirlOverlay; size: OverlaySize }) {\n const cfg = parseConfig<LowerThirdCfg>(overlay.content);\n if (!cfg) return null;\n const f = Math.max(6, size.w * 0.055);\n return (\n <div style={{ width: \"100%\", height: \"100%\", borderRadius: Math.max(2, size.w * 0.02), display: \"flex\", flexDirection: \"column\", justifyContent: \"flex-end\", background: cfg.backgroundColor, color: cfg.textColor, fontFamily: \"Roboto, 'Segoe UI', Arial, sans-serif\", overflow: \"hidden\", pointerEvents: \"none\", userSelect: \"none\", fontSize: `${f}px` }}>\n <div style={{ width: \"100%\", height: Math.max(2, size.h * 0.06), backgroundColor: cfg.accentColor }} />\n <div style={{ flex: 1, display: \"flex\", flexDirection: \"column\", justifyContent: \"center\", padding: `${f * 0.5}px ${f * 1.2}px` }}>\n <div style={{ fontSize: \"1.4em\", fontWeight: 700, lineHeight: 1.2, textShadow: \"0 1px 4px rgba(0,0,0,0.5)\" }}>{cfg.headline}</div>\n <div style={{ fontSize: \"1em\", opacity: 0.7, marginTop: f * 0.2 }}>{cfg.subtitle}</div>\n </div>\n {(cfg.sponsorText || cfg.sponsorImageUrl) && (\n <div style={{ fontSize: \"0.7em\", opacity: 0.5, padding: `0 ${f * 1.2}px ${f * 0.4}px`, display: \"flex\", alignItems: \"center\", gap: f * 0.4, overflow: \"hidden\" }}>\n {cfg.sponsorImageUrl && <img src={cfg.sponsorImageUrl} alt=\"sponsor\" style={{ height: `${f * 1.4}px`, objectFit: \"contain\", flexShrink: 0 }} />}\n {cfg.sponsorText && <span style={{ overflow: \"hidden\", textOverflow: \"ellipsis\", whiteSpace: \"nowrap\" }}>{cfg.sponsorText}</span>}\n </div>\n )}\n </div>\n );\n}\n\nfunction QrCodeOverlay({ overlay, size }: { overlay: SwirlOverlay; size: OverlaySize }) {\n const cfg = parseConfig<QrCodeCfg>(overlay.content);\n if (!cfg) return null;\n const qrSide = Math.max(32, Math.min(size.w, size.h) * 0.55);\n const qrUrl = `https://api.qrserver.com/v1/create-qr-code/?size=${Math.round(qrSide * 2)}x${Math.round(qrSide * 2)}&data=${encodeURIComponent(cfg.url || \"https://example.com\")}`;\n const f = Math.max(6, size.w * 0.06);\n return (\n <div style={{ width: \"100%\", height: \"100%\", borderRadius: Math.max(2, size.w * 0.035), display: \"flex\", flexDirection: \"column\", alignItems: \"center\", justifyContent: \"center\", gap: f * 0.4, background: cfg.backgroundColor, color: cfg.textColor, fontFamily: \"Roboto, 'Segoe UI', Arial, sans-serif\", padding: f * 0.6, boxSizing: \"border-box\", pointerEvents: \"none\", userSelect: \"none\", overflow: \"hidden\" }}>\n <div style={{ flexShrink: 0, background: \"#fff\", borderRadius: Math.max(2, qrSide * 0.06), padding: Math.max(2, qrSide * 0.06), lineHeight: 0 }}>\n <img src={qrUrl} alt=\"QR Code\" style={{ width: `${qrSide}px`, height: `${qrSide}px`, display: \"block\" }} />\n </div>\n <div style={{ fontSize: `${f * 1.1}px`, fontWeight: 700, textAlign: \"center\", color: cfg.accentColor, overflow: \"hidden\", textOverflow: \"ellipsis\", whiteSpace: \"nowrap\", width: \"100%\" }}>{cfg.ctaText}</div>\n {cfg.description && <div style={{ fontSize: `${f * 0.75}px`, opacity: 0.6, textAlign: \"center\", overflow: \"hidden\", textOverflow: \"ellipsis\", whiteSpace: \"nowrap\", width: \"100%\" }}>{cfg.description}</div>}\n </div>\n );\n}\n\nfunction ComingUpNextOverlay({ overlay, size }: { overlay: SwirlOverlay; size: OverlaySize }) {\n const cfg = parseConfig<ComingUpNextCfg>(overlay.content);\n if (!cfg) return null;\n const f = Math.max(6, size.w * 0.05);\n return (\n <div style={{ width: \"100%\", height: \"100%\", borderRadius: Math.max(2, size.w * 0.035), display: \"flex\", background: cfg.backgroundColor, color: cfg.textColor, fontFamily: \"Roboto, 'Segoe UI', Arial, sans-serif\", overflow: \"hidden\", pointerEvents: \"none\", userSelect: \"none\", fontSize: `${f}px` }}>\n <div style={{ width: Math.max(2, size.w * 0.015), flexShrink: 0, backgroundColor: cfg.accentColor }} />\n <div style={{ flex: 1, display: \"flex\", flexDirection: \"column\", justifyContent: \"center\", padding: `${f * 0.6}px ${f * 1.0}px`, minWidth: 0 }}>\n <div style={{ fontSize: \"0.8em\", fontWeight: 600, textTransform: \"uppercase\", letterSpacing: \"0.05em\", color: cfg.accentColor }}>Coming Up Next</div>\n <div style={{ fontSize: \"1.5em\", fontWeight: 700, lineHeight: 1.2, marginTop: f * 0.2, overflow: \"hidden\", textOverflow: \"ellipsis\", whiteSpace: \"nowrap\" }}>{cfg.title}</div>\n <div style={{ fontSize: \"0.9em\", opacity: 0.6, overflow: \"hidden\", textOverflow: \"ellipsis\", whiteSpace: \"nowrap\" }}>{cfg.subtitle}</div>\n {cfg.scheduledTime && <div style={{ fontSize: \"1em\", fontWeight: 600, marginTop: f * 0.4, color: cfg.accentColor }}>{cfg.scheduledTime}</div>}\n </div>\n {cfg.thumbnailUrl && (\n <div style={{ flexShrink: 0, width: Math.max(40, size.h * 0.75), overflow: \"hidden\" }}>\n <img src={cfg.thumbnailUrl} alt=\"thumbnail\" style={{ width: \"100%\", height: \"100%\", objectFit: \"cover\", display: \"block\" }} />\n </div>\n )}\n </div>\n );\n}\n\nfunction ContextualTriggerOverlay({ overlay, size }: { overlay: SwirlOverlay; size: OverlaySize }) {\n const cfg = parseConfig<ContextualTriggerCfg>(overlay.content);\n if (!cfg) return null;\n const icons: Record<string, string> = { alert: \"\\u26A0\\uFE0F\", celebration: \"\\uD83C\\uDF89\", info: \"\\u2139\\uFE0F\", warning: \"\\uD83D\\uDD14\" };\n const f = Math.max(6, size.w * 0.05);\n return (\n <div style={{ width: \"100%\", height: \"100%\", borderRadius: Math.max(2, size.w * 0.035), display: \"flex\", alignItems: \"center\", gap: f * 0.8, padding: `0 ${f * 1.2}px`, background: cfg.backgroundColor, color: cfg.textColor, fontFamily: \"Roboto, 'Segoe UI', Arial, sans-serif\", borderLeft: `${Math.max(2, size.w * 0.02)}px solid ${cfg.accentColor}`, boxSizing: \"border-box\", pointerEvents: \"none\", userSelect: \"none\", fontSize: `${f}px` }}>\n <span style={{ fontSize: \"2em\", flexShrink: 0 }}>{icons[cfg.iconType] || \"\\u26A1\"}</span>\n <div style={{ flex: 1, minWidth: 0 }}>\n <div style={{ fontSize: \"1.3em\", fontWeight: 700, overflow: \"hidden\", textOverflow: \"ellipsis\", whiteSpace: \"nowrap\" }}>{cfg.headline}</div>\n <div style={{ fontSize: \"0.9em\", opacity: 0.7, overflow: \"hidden\", textOverflow: \"ellipsis\", whiteSpace: \"nowrap\" }}>{cfg.message}</div>\n </div>\n </div>\n );\n}\n\nfunction OddsBettingOverlay({ overlay, size }: { overlay: SwirlOverlay; size: OverlaySize }) {\n const cfg = parseConfig<OddsBettingCfg>(overlay.content);\n if (!cfg) return null;\n const f = Math.max(6, size.w * 0.052);\n return (\n <div style={{ width: \"100%\", height: \"100%\", borderRadius: Math.max(2, size.w * 0.035), display: \"flex\", flexDirection: \"column\", padding: f * 0.8, background: cfg.backgroundColor, color: cfg.textColor, fontFamily: \"Roboto, 'Segoe UI', Arial, sans-serif\", boxSizing: \"border-box\", pointerEvents: \"none\", userSelect: \"none\", fontSize: `${f}px` }}>\n <div style={{ fontSize: \"0.9em\", fontWeight: 700, textTransform: \"uppercase\", letterSpacing: \"0.05em\", color: cfg.accentColor, marginBottom: f * 0.4 }}>{cfg.eventTitle}</div>\n <div style={{ flex: 1, display: \"flex\", flexDirection: \"column\", gap: f * 0.2, justifyContent: \"center\" }}>\n {(cfg.options || []).slice(0, 5).map((opt, i) => (\n <div key={i} style={{ display: \"flex\", justifyContent: \"space-between\", alignItems: \"center\", padding: `${f * 0.2}px ${f * 0.6}px`, borderRadius: Math.max(2, f * 0.3), background: `${cfg.accentColor}15`, fontSize: \"1em\" }}>\n <span style={{ overflow: \"hidden\", textOverflow: \"ellipsis\", whiteSpace: \"nowrap\", flex: 1 }}>{opt.label}</span>\n <span style={{ fontWeight: 700, marginLeft: f * 0.8, flexShrink: 0, color: cfg.accentColor }}>{opt.odds}</span>\n </div>\n ))}\n </div>\n {cfg.sponsorText && <div style={{ fontSize: \"0.7em\", opacity: 0.4, textAlign: \"center\", marginTop: f * 0.4 }}>{cfg.sponsorText}</div>}\n </div>\n );\n}\n\nfunction BreakingNewsOverlay({ overlay, size }: { overlay: SwirlOverlay; size: OverlaySize }) {\n const cfg = parseConfig<BreakingNewsCfg>(overlay.content);\n if (!cfg) return null;\n const urgencyColors: Record<string, string> = { breaking: \"#dc2626\", urgent: \"#ea580c\", normal: \"#2563eb\" };\n const labelBg = urgencyColors[cfg.urgency] || urgencyColors.normal;\n const label = cfg.urgency === \"breaking\" ? \"BREAKING\" : cfg.urgency === \"urgent\" ? \"URGENT\" : \"NEWS\";\n const f = Math.max(6, size.w * 0.05);\n return (\n <div style={{ width: \"100%\", height: \"100%\", borderRadius: Math.max(2, size.w * 0.02), display: \"flex\", alignItems: \"center\", background: cfg.backgroundColor, color: cfg.textColor, fontFamily: \"Roboto, 'Segoe UI', Arial, sans-serif\", overflow: \"hidden\", pointerEvents: \"none\", userSelect: \"none\", fontSize: `${f}px` }}>\n <div style={{ padding: `0 ${f * 0.8}px`, height: \"100%\", display: \"flex\", alignItems: \"center\", background: labelBg, color: \"#fff\", fontSize: \"1em\", fontWeight: 900, textTransform: \"uppercase\", letterSpacing: \"0.05em\", flexShrink: 0 }}>{label}</div>\n <div style={{ flex: 1, padding: `0 ${f * 1.0}px`, minWidth: 0 }}>\n <div style={{ fontSize: \"1.3em\", fontWeight: 700, overflow: \"hidden\", textOverflow: \"ellipsis\", whiteSpace: \"nowrap\" }}>{cfg.headline}</div>\n {cfg.body && <div style={{ fontSize: \"0.9em\", opacity: 0.7, overflow: \"hidden\", textOverflow: \"ellipsis\", whiteSpace: \"nowrap\" }}>{cfg.body}</div>}\n </div>\n </div>\n );\n}\n\nfunction calcCountdownRemaining(targetTime: string) {\n const diff = Math.max(0, new Date(targetTime).getTime() - Date.now());\n return {\n d: Math.floor(diff / 86400000),\n h: Math.floor((diff % 86400000) / 3600000),\n m: Math.floor((diff % 3600000) / 60000),\n s: Math.floor((diff % 60000) / 1000),\n expired: diff === 0,\n };\n}\n\nfunction CountdownOverlay({ overlay, size }: { overlay: SwirlOverlay; size: OverlaySize }) {\n const cfg = parseConfig<CountdownCfg>(overlay.content);\n const targetTime = cfg?.targetTime ?? \"\";\n const [remaining, setRemaining] = useState(() =>\n targetTime ? calcCountdownRemaining(targetTime) : { d: 0, h: 0, m: 0, s: 0, expired: false }\n );\n\n useEffect(() => {\n if (!targetTime) return;\n setRemaining(calcCountdownRemaining(targetTime));\n const id = setInterval(() => setRemaining(calcCountdownRemaining(targetTime)), 1000);\n return () => clearInterval(id);\n }, [targetTime]);\n\n if (!cfg) return null;\n\n const f = Math.max(6, size.w * 0.055);\n const pad = (n: number) => String(n).padStart(2, \"0\");\n const units: Array<{ show: boolean; value: string; label: string }> = [\n { show: cfg.showDays, value: pad(remaining.d), label: \"DAYS\" },\n { show: cfg.showHours, value: pad(remaining.h), label: \"HRS\" },\n { show: cfg.showMinutes, value: pad(remaining.m), label: \"MIN\" },\n { show: cfg.showSeconds, value: pad(remaining.s), label: \"SEC\" },\n ];\n\n return (\n <div style={{ width: \"100%\", height: \"100%\", borderRadius: Math.max(2, size.w * 0.035), display: \"flex\", flexDirection: \"column\", alignItems: \"center\", justifyContent: \"center\", padding: f * 0.8, background: cfg.backgroundColor, color: cfg.textColor, fontFamily: \"Roboto, 'Segoe UI', Arial, sans-serif\", boxSizing: \"border-box\", pointerEvents: \"none\", userSelect: \"none\", fontSize: `${f}px` }}>\n <div style={{ fontSize: \"0.8em\", fontWeight: 600, textTransform: \"uppercase\", letterSpacing: \"0.05em\", color: cfg.accentColor, marginBottom: f * 0.4 }}>{cfg.eventName}</div>\n {remaining.expired ? (\n <div style={{ fontSize: \"1em\", fontWeight: 700, opacity: 0.6 }}>{cfg.message || \"Event ended\"}</div>\n ) : (\n <div style={{ display: \"flex\", gap: f * 0.6, alignItems: \"center\" }}>\n {units.filter(u => u.show).map((u, i, arr) => (\n <React.Fragment key={u.label}>\n <div style={{ textAlign: \"center\" }}>\n <div style={{ fontSize: \"2em\", fontWeight: 900, lineHeight: 1, borderRadius: Math.max(2, f * 0.4), padding: `${f * 0.2}px ${f * 0.4}px`, background: `${cfg.accentColor}20` }}>{u.value}</div>\n <div style={{ fontSize: \"0.5em\", opacity: 0.5, marginTop: f * 0.2 }}>{u.label}</div>\n </div>\n {i < arr.length - 1 && <div style={{ fontSize: \"1.8em\", fontWeight: 700, opacity: 0.3 }}>:</div>}\n </React.Fragment>\n ))}\n </div>\n )}\n {!remaining.expired && cfg.message && <div style={{ fontSize: \"0.8em\", opacity: 0.6, marginTop: f * 0.4, textAlign: \"center\" }}>{cfg.message}</div>}\n </div>\n );\n}\n\nfunction ShapeOverlay({ overlay, size }: { overlay: SwirlOverlay; size: OverlaySize }) {\n const f = Math.max(6, size.w * 0.05);\n return (\n <div style={{ width: \"100%\", height: \"100%\", borderRadius: Math.max(2, size.w * 0.03), background: \"rgba(99, 102, 241, 0.2)\", border: \"2px solid rgba(99, 102, 241, 0.4)\", display: \"flex\", alignItems: \"center\", justifyContent: \"center\", pointerEvents: \"none\", userSelect: \"none\" }}>\n <div style={{ fontSize: `${f}px`, fontWeight: 500, color: \"rgba(163, 163, 163, 0.8)\", textTransform: \"uppercase\" }}>{overlay.name}</div>\n </div>\n );\n}\n\nfunction hexToRgb(hex: string): string {\n if (!hex || !hex.startsWith(\"#\")) return \"0,0,0\";\n const clean = hex.slice(1);\n const num = parseInt(clean.length === 3 ? clean.replace(/./g, \"$&$&\") : clean, 16);\n return `${(num >> 16) & 255},${(num >> 8) & 255},${num & 255}`;\n}\n\nexport const OverlayRenderer: React.FC<OverlayRendererProps> = ({\n overlays,\n currentTime,\n videoRef,\n coordinateSpace,\n}) => {\n const [dims, setDims] = useState<VideoDimensions | null>(null);\n const rafRef = useRef<number | null>(null);\n\n const updateDims = useCallback(() => {\n const video = videoRef.current;\n if (video) {\n const computed = computeVideoDimensions(video);\n setDims((prev) => {\n if (\n !computed ||\n (prev &&\n prev.nativeWidth === computed.nativeWidth &&\n prev.nativeHeight === computed.nativeHeight &&\n prev.displayWidth === computed.displayWidth &&\n prev.displayHeight === computed.displayHeight &&\n prev.offsetX === computed.offsetX &&\n prev.offsetY === computed.offsetY)\n ) {\n return prev;\n }\n return computed;\n });\n }\n }, [videoRef]);\n\n useEffect(() => {\n updateDims();\n const interval = setInterval(updateDims, 500);\n\n const handleResize = () => {\n if (rafRef.current) cancelAnimationFrame(rafRef.current);\n rafRef.current = requestAnimationFrame(updateDims);\n };\n window.addEventListener(\"resize\", handleResize);\n\n return () => {\n clearInterval(interval);\n window.removeEventListener(\"resize\", handleResize);\n if (rafRef.current) cancelAnimationFrame(rafRef.current);\n };\n }, [updateDims]);\n\n const activeOverlays = overlays.filter((o) =>\n isOverlayActive(o, currentTime)\n );\n\n if (!dims || activeOverlays.length === 0) return null;\n\n return (\n <div\n aria-hidden=\"true\"\n style={{\n position: \"absolute\",\n left: `${dims.offsetX}px`,\n top: `${dims.offsetY}px`,\n width: `${dims.displayWidth}px`,\n height: `${dims.displayHeight}px`,\n pointerEvents: \"none\",\n overflow: \"hidden\",\n zIndex: 8,\n }}\n >\n {activeOverlays.map((overlay) => {\n const scaleX =\n coordinateSpace?.width\n ? dims.displayWidth / coordinateSpace.width\n : dims.scaleX;\n const scaleY =\n coordinateSpace?.height\n ? dims.displayHeight / coordinateSpace.height\n : dims.scaleY;\n const left = overlay.x * scaleX;\n const top = overlay.y * scaleY;\n const width = overlay.width * scaleX;\n const height = overlay.height * scaleY;\n const opacity = Math.max(0, Math.min(100, overlay.opacity)) / 100;\n const sz: OverlaySize = { w: width, h: height };\n\n return (\n <div\n key={overlay.id}\n style={{\n position: \"absolute\",\n left: `${left}px`,\n top: `${top}px`,\n width: `${width}px`,\n height: `${height}px`,\n opacity,\n zIndex: overlay.z_index,\n overflow: \"hidden\",\n }}\n >\n {overlay.type === \"image\" && <ImageOverlay overlay={overlay} />}\n {overlay.type === \"text\" && <TextOverlay overlay={overlay} />}\n {overlay.type === \"scroller\" && <ScrollerOverlay overlay={overlay} />}\n {overlay.type === \"shape\" && <ShapeOverlay overlay={overlay} size={sz} />}\n {overlay.type === \"score_bug\" && <ScoreBugOverlay overlay={overlay} size={sz} />}\n {overlay.type === \"lower_third\" && <LowerThirdOverlay overlay={overlay} size={sz} />}\n {overlay.type === \"qr_code\" && <QrCodeOverlay overlay={overlay} size={sz} />}\n {overlay.type === \"coming_up_next\" && <ComingUpNextOverlay overlay={overlay} size={sz} />}\n {overlay.type === \"contextual_trigger\" && <ContextualTriggerOverlay overlay={overlay} size={sz} />}\n {overlay.type === \"odds_betting\" && <OddsBettingOverlay overlay={overlay} size={sz} />}\n {overlay.type === \"breaking_news\" && <BreakingNewsOverlay overlay={overlay} size={sz} />}\n {overlay.type === \"countdown\" && <CountdownOverlay overlay={overlay} size={sz} />}\n </div>\n );\n })}\n </div>\n );\n};\n","const OVERLAY_API_BASE = \"https://adstorm.co/api-adstorm-dev\";\n\nexport interface OverlayCoordinateSpace {\n width: number;\n height: number;\n}\n\nexport interface SwirlScrollerConfig {\n rss_url?: string;\n update_interval?: number;\n scroll_speed?: number;\n direction?: string;\n font_size?: number;\n font_family?: string;\n font_weight?: string;\n text_color?: string;\n background_color?: string;\n background_opacity?: number;\n border_color?: string;\n border_width?: number;\n border_radius?: number;\n padding?: number;\n margin?: number;\n show_title?: boolean;\n show_description?: boolean;\n show_timestamp?: boolean;\n show_author?: boolean;\n show_category?: boolean;\n max_items?: number;\n item_spacing?: number;\n fade_in_out?: boolean;\n fade_distance?: number;\n auto_refresh?: boolean;\n use_custom_text?: boolean;\n custom_text?: string;\n}\n\nexport type SwirlOverlayType =\n | \"image\"\n | \"text\"\n | \"scroller\"\n | \"shape\"\n | \"score_bug\"\n | \"lower_third\"\n | \"qr_code\"\n | \"coming_up_next\"\n | \"contextual_trigger\"\n | \"odds_betting\"\n | \"breaking_news\"\n | \"countdown\";\n\nexport interface SwirlOverlay {\n id: number;\n project_id: number;\n name: string;\n type: SwirlOverlayType | string;\n visible: boolean;\n x: number;\n y: number;\n width: number;\n height: number;\n opacity: number;\n start_time: string;\n duration: string;\n content?: string;\n image_url?: string;\n scroller_config?: SwirlScrollerConfig;\n z_index: number;\n created_at?: string;\n updated_at?: string;\n}\n\nexport function timeStringToSeconds(timeStr: string): number {\n if (!timeStr) return 0;\n\n const parts = timeStr.split(\":\");\n\n if (parts.length >= 3) {\n const hours = parseInt(parts[0] ?? \"0\", 10) || 0;\n const minutes = parseInt(parts[1] ?? \"0\", 10) || 0;\n const secStr = parts[2] ?? \"0\";\n const dotIdx = secStr.indexOf(\".\");\n const seconds =\n parseInt(dotIdx >= 0 ? secStr.substring(0, dotIdx) : secStr, 10) || 0;\n const msFrag = dotIdx >= 0 ? secStr.substring(dotIdx + 1) : \"\";\n const ms = msFrag ? parseInt(msFrag.padEnd(3, \"0\").substring(0, 3), 10) || 0 : 0;\n return hours * 3600 + minutes * 60 + seconds + ms / 1000;\n }\n\n if (parts.length === 2) {\n const minutes = parseInt(parts[0] ?? \"0\", 10) || 0;\n const secStr = parts[1] ?? \"0\";\n const dotIdx = secStr.indexOf(\".\");\n const seconds =\n parseInt(dotIdx >= 0 ? secStr.substring(0, dotIdx) : secStr, 10) || 0;\n const msFrag = dotIdx >= 0 ? secStr.substring(dotIdx + 1) : \"\";\n const ms = msFrag ? parseInt(msFrag.padEnd(3, \"0\").substring(0, 3), 10) || 0 : 0;\n return minutes * 60 + seconds + ms / 1000;\n }\n\n const num = parseFloat(timeStr);\n return isFinite(num) ? Math.max(0, num) : 0;\n}\n\nexport function isOverlayActive(\n overlay: SwirlOverlay,\n currentTime: number\n): boolean {\n if (!overlay.visible) return false;\n const startSec = timeStringToSeconds(overlay.start_time);\n const durationSec = timeStringToSeconds(overlay.duration);\n if (durationSec <= 0) return false;\n return currentTime >= startSec && currentTime < startSec + durationSec;\n}\n\nexport async function fetchProjectOverlays(\n projectId: number,\n apiBaseUrl: string = OVERLAY_API_BASE\n): Promise<SwirlOverlay[]> {\n const response = await fetch(\n `${apiBaseUrl}/adstorm/swirl/projects/${projectId}/overlays`\n );\n if (!response.ok) {\n throw new Error(\n `Failed to fetch overlays: ${response.status} ${response.statusText}`\n );\n }\n const data = await response.json();\n return Array.isArray(data) ? data : [];\n}\n\nexport function resolveImageUrl(\n imageUrl: string,\n apiBaseUrl: string = OVERLAY_API_BASE\n): string {\n if (!imageUrl) return \"\";\n if (imageUrl.startsWith(\"http://\") || imageUrl.startsWith(\"https://\")) {\n return imageUrl;\n }\n if (imageUrl.startsWith(\"/\")) {\n try {\n const url = new URL(apiBaseUrl);\n return `${url.origin}${imageUrl}`;\n } catch {\n return imageUrl;\n }\n }\n return `${apiBaseUrl}/${imageUrl}`;\n}\n"]}