{"version":3,"file":"static/chunks/52774a7f-be1ede5df6bad878.js","mappings":"sbAmUA,EACA,EA67DA,EAoxCA,EACA,EAwqBA,wBAvoI0mB,EAm/I1mB,+TAjiJA,MAAe,GAAU,CAEzB,wBAEA,0BA0CA,uBAA0C,QAAmB,EAAqB,IAAmB,CAA1B,OAAO,CAAmB,OAAiC,IAA+B,WAAoB,IAAW,kBAAyB,WAAmB,SAA+B,GAAR,KAAQ,oDAA2E,MAAoB,qCAAkD,IAAuB,QAAqB,mCAAmD,4BAA6D,UAA+B,SAAe,SAa1mB,KACA,wCACA,kDACA,CACA,cACA,+DACA,CA2BA,cACA,QA3BA,EA4BA,0BACA,UA5BA,CADA,EA8BA,0BA7BA,iCAAiD,IACjD,4CAA0D,IAC1D,wCAA6D,oCAAqC,sBAAsB,IAExH,GA0BA,IACA,CACA,SACA,WACA,CACA,CACA,cACA,MACA,GAmBA,eAnBA,EACA,IACA,EACA,iBACA,SApCA,GACA,YAAY,GAAU,EACtB,yBACA,SACA,wBAAyC,uBAA0B,IAanE,MAZA,iBACA,gBAEA,aACA,gBAAgC,YAAe,IAE/C,gBACA,mBAAmC,eAAkB,IAErD,gBACA,0BAEA,cAAmC,CACnC,EAkBA,EACA,CACA,SACA,MAEA,oDACA,iBAMA,QADA,uCACA,UAJA,qBAtEA,YACA,2BACA,mCACA,yBACA,mBACA,qBACA,wBACA,CAAC,WA2ED,SACA,cACA,uBACA,4BACA,CACA,gBACA,EAGA,EADA,wEACA,QAFA,EAGA,CACA,WACA,kCACA,CACA,SACA,wCACA,CACA,WACA,oCACA,CACA,qBACA,oBACA,yBACA,cACA,kDAEA,CACA,OACA,4BACA,CACA,WACA,8BACA,CACA,SACA,WACA,wBACA,yBACA,CACA,aACA,sBACA,MACA,8BACA,GACA,yBACA,CACA,uBACA,CACA,QACA,uBACA,4BACA,CACA,CAIA,6BAA2B,mBAAkC,EAI7D,MAHA,cACA,aAEA,uBACA,SACA,gBACA,wBACA,CACA,qBAA0B,kCAAwC,EAClE,mBACA,GAGA,GACA,WAEA,sBALA,CAMA,CACA,cACA,sBACA,CACA,cACA,sBACA,CACA,2BAmBA,cACA,aACA,6CACA,WACA,EAEA,KACA,IACA,CACA,yBACA,2CACA,4BAEA,QAEA,iBACA,MACA,IACA,0CACA,CACA,SACA,WACA,CAGA,YADA,iBADA,uBAEA,oCACA,CACA,UACA,eACA,YACA,KACA,SAEA,sBACA,YACA,yCACA,IACA,+BACA,aACA,sBACA,sBACA,SACA,GACA,MAEA,qBACA,CACA,SACA,CAEA,2BACA,CACA,kBACA,6BACA,CACA,kBACA,+BACA,CAEA,SACA,0BAEA,cACA,WACA,CAwBA,oDACA,yBACA,eACA,2BACA,iBACA,yCACA,cACA,WACA,MACA,SAEA,2BAGA,WAFA,aAA0B,EAAW,EAAE,EAAS,EAAE,EAAW,GAK7D,cACA,aAA0B,EAAW,EAAE,GA7BvC,iBA6BuC,EA5BvC,gCA4BuC,EAzBvC,eAEA,cAuBuC,EAA+B,EAAE,EAAW,GAEnF,mBACA,eAEA,aADA,QACA,GACA,UAGA,SACA,QAGA,WAGA,aAAsB,EAAW,EAAE,YAAgB,EAAE,EAAW,GAC3D,CACL,CACA,4BACA,wBA2DA,eACA,wBACA,iBAGA,QAFA,CAGA,CAIA,iBACA,gBAKA,GAJA,IACA,uBACA,aAEA,EAGA,iDACA,QACA,MAJA,KAMA,OADA,yBACA,MACA,CACA,gCACA,EAGA,WACA,qCAGA,gCAGA,mBACA,iCAGA,aACA,SAnGA,KACA,iBACA,SAEA,QACA,kBACA,EACA,oCACA,GACA,OACA,YACA,GAEA,EACA,CACA,SACA,KACA,OACA,eAFA,CAKA,YACA,qBACA,kCACA,cAEA,CACA,SACA,UACA,SACA,QACA,kBACA,WACA,qBACA,KACA,CACA,KAWA,SACA,WAZA,CACA,YACA,KACA,qBACA,KACA,CACA,SACA,MAEA,CAMA,KACA,IACA,CACA,CACA,CACA,mBACA,EA0CA,KAEA,YACA,YAEA,yBACA,QAEA,qBACA,SAEA,EArBA,QAJA,CA0BA,CACA,mBACA,gDACA,CAoCA,iCACA,IAEA,6BAEA,IAHA,GAKA,KACA,EACA,wBACA,CACA,iBACA,WAEA,UADA,EAEA,SACA,IACA,MACA,sBACA,IANA,EAMA,YAAuC,EAAU,GACjD,cAEA,YA/BA,KACA,6BAA2C,KAAS,CACpD,GADoD,CACpD,iBACA,aACA,QAEA,CACA,QACA,EAcA,EASA,GACA,SAGA,MAbA,EAaA,WACA,SACA,QACA,CACA,SACA,QACA,CACA,CACA,CACA,yBACA,IACA,kCACA,EACA,gBACA,YACA,SACA,wBACA,qCAUA,IARA,mBACA,eACA,YACA,SACA,eACA,cACA,SACA,CACA,YACA,QAEA,CACA,SACA,KACA,MAEA,IADA,iBACA,EACA,SAEA,0BACA,KACA,CAEA,GADA,kBACA,EACA,SAEA,0BACA,CACA,YACA,SACA,KAEA,SAEA,GACA,CACA,SACA,CACA,SACA,CA+WA,sBACA,QACA,GAGA,eAEA,CAyEA,qBA6BA,EA5BA,QAAY,4MAA6M,kFAA+E,0LAA+M,EACvf,oBAAU,MAA4B,EACtC,EAtYA,cACA,QAAY,4MAAoM,+CAA8C,yEAA4E,EAC1U,EA2EA,cACA,iBACA,OACA,iBACA,qBACA,EAhFA,KACA,mBACA,qBACA,+BACA,OACA,gBACA,cACA,yBAIA,OACA,gBACA,cAGA,2BACA,OACA,oBACA,YACA,oBACA,oBACA,QACA,CACA,qBACA,gBA8GA,SAwJA,EAvJA,IAAY,6FAAwF,oDAAmD,0KAAuK,EAC9T,WA9TA,SACA,IACA,mBACA,SAEA,sBACA,4BACA,QACA,MAGA,6BAAwD,KAAS,CACjE,GADiE,CACjE,iBACA,aACA,QAEA,CAEA,KACA,mBAEA,CACA,SACA,CACA,QACA,EAqSA,SACA,EAhfA,YACA,gCACA,aAEA,0BACA,WACA,MAEA,CACA,EAueA,GACA,KACA,sBACA,YAAoB,IAAS,KAC7B,sBACA,+BACA,yCAEA,CACA,kBACA,wCACA,iBAEA,OACA,GACA,SAEA,IACA,aACA,cACA,wBAEA,CACA,gBACA,SACA,iDACA,iBACA,GACA,wBAEA,CACA,gBACA,gBACA,cACA,cAEA,QADA,GAEA,KAFA,EAEA,QACA,YACA,kCACA,SALA,EAKA,WACA,OACA,aACA,kBACA,CAAa,EACb,YACA,WACA,QAZA,EAaA,QACA,aACA,CAAa,CACb,CACA,GACA,aAEA,CASA,GARA,eACA,sBACA,cAGA,mBAGA,iBACA,sBACA,CAroBA,YACA,yBACA,MACA,SAEA,YAAoB,UAAkB,GADtC,GAEA,YAAwB,WAAmB,GAF3C,GAE2C,CAC3C,qBAKA,GADA,gBAHA,QACA,KACA,GACA,oBAPA,GAOA,oBAPA,GAOA,0BACA,eACA,QACA,CAEA,QACA,EAonBA,IACA,kDAGA,uBACA,oCACA,2BACA,iBACA,kBAEA,IADA,+BAEA,gBAEA,EAEA,iBACA,GAEA,GADA,8BACA,kBAGA,MADA,EACA,YADA,EACA,qCACA,EAFA,EAEA,YACA,OAHA,EAIA,8BACA,IACA,uBACA,SAPA,EAOA,cACA,YARA,EAQA,KACA,0CACA,CACA,SACA,iBAZA,EAYA,aAZA,EAaA,wBAbA,EAcA,cAdA,EAcA,aACA,IAfA,EAiBA,2BACA,MACA,CAEA,sCAA0D,EAAS,WAAW,EAAI,EAElF,CACA,cAxBA,EAwBA,aACA,GACA,gBA1BA,EA2BA,+BAEA,CACA,CA9BA,EA8BA,cA9BA,EA8BA,aACA,IA/BA,EAiCA,0BACA,CAeA,GAdA,6BACA,yBACA,SACA,SACA,qCAEA,KACA,cACA,+BAEA,aACA,8BAGA,GACA,UAAgB,YAAgB,0BAChC,GACA,cACA,YAAyB,EAAM,IAC/B,aAA0B,EAAO,IAEjC,CACA,yBACA,sBACA,iBAEA,cAGA,IACA,uBACA,MACA,CACA,SACA,CACA,OACA,eACA,UACA,aACA,cACA,MAjhBA,sBAihBA,EAjhBA,kBAihBA,OACA,YACA,SACA,UACA,CACA,EAvRA,GACA,MACA,aACA,gBACA,kBACA,mBACA,kBACA,mBACA,cACA,iBACA,eACA,eACA,kBACA,oBACA,SACA,cACA,gBACA,kBACA,mBACA,oBACA,CAAa,CACb,kBACA,gBAkCA,KACA,gBAAY,oIAAwI,EACpJ,qCACA,gBACA,sBACA,uBACA,yBACA,SACA,IACA,kCAEA,oFACA,yBAEA,CACA,SACA,qEAAiF,EAAI,IACrF,CACA,iBACA,CACA,GACA,yBAEA,sBAwBA,OAvBA,iBACA,KACA,qBACA,wBAEA,uBACA,KACA,kBACA,wBAEA,iBAMA,MACA,sBANA,GACA,UACA,UACA,kBACA,CAAS,GAGT,UACA,QACA,aACA,EAAS,EAET,CACA,YACA,kBACA,UACA,QACA,CACA,EAvFA,GACA,MACA,cACA,gBACA,kBACA,mBACA,qBACA,aACA,mBACA,cACA,QACA,CAAa,CACb,2BACA,OACA,aACA,eACA,QACA,CACA,qBACA,OACA,eACA,8BACA,QACA,CACA,SACA,QACA,CACA,EA0TA,GACA,MACA,SACA,aACA,gBACA,cACA,kBACA,gBACA,kBACA,mBACA,qBACA,mBACA,mBACA,kBACA,aACA,cACA,iBACA,eACA,eACA,kBACA,mBACA,CAAK,EACL,MAEA,OADA,iCACA,KAIA,EADA,aACA,WAEA,UAzGA,KACA,iCACA,SAEA,uBACA,aACA,uBACA,oBACA,+BACA,qCACA,4BACA,oBACA,+BACA,oCACA,+BAGA,eACA,yDACA,oBACA,mEACA,4CACA,+BACA,2CACA,yCATA,SAYA,uBACA,2BACA,uDAGA,kBACA,uDACA,+CACA,qCALA,SAQA,qBACA,mCACA,qCACA,mCACA,SAEA,wBACA,oCACA,cAEA,yBACA,mCACA,qCACA,qCACA,qCACA,kCACA,8CACA,8CACA,cAEA,2BACA,qDACA,+CACA,sCACA,2CACA,qCACA,wCACA,sDACA,QAEA,CACA,CACA,QACA,EAkCA,MACA,IACA,iBACA,WACA,gDAIA,KApxBA,GAsxBA,0BAA4D,EAAI,EAEhE,GADA,WAvxBA,KAwxBA,EACA,YAEA,GACA,KAEA,SACA,uBACA,kBACA,mBACA,mBACA,SACA,mBACA,CACA,yBACA,qBACA,GACA,kBACA,oBACA,oBACA,OAEA,OACA,MACA,SACA,aACA,gBACA,cACA,kBACA,gBACA,kBACA,mBACA,qBACA,YACA,mBACA,mBACA,kBACA,aACA,cACA,iBACA,iBACA,eACA,eACA,qBACA,cACA,eACA,oBACA,mBACA,wBACA,iBACA,EACA,uCACA,cACA,GACA,oBAEA,CACA,KAzjCA,WAyjCA,EAzjCA,cAyjCA,aACA,kDACA,cACA,IACA,iBACA,gBACA,qBAEA,CAEA,CA0FA,OAzFA,cACA,iBACA,iBACA,gBAEA,oBACA,sBACA,SAtjBA,WAMA,EALA,sBACA,MACA,OAEA,SAEA,IACA,wBAEA,SACA,MACA,CACA,mBACA,cACA,IACA,IACA,KAEA,CAAS,IACT,+BACA,MACA,KACA,GACA,CAAS,EACT,MACA,CACA,oBACA,wBACA,WACA,WAEA,OADA,QACA,6BAEA,4BACA,EAmhBA,OACA,wBACA,SACA,YACA,MACA,SACA,aACA,gBACA,kBACA,cACA,gBACA,kBACA,mBACA,qBACA,aACA,mBACA,mBACA,kBACA,aACA,cACA,iBACA,iBACA,eACA,eACA,qBACA,cACA,eACA,oBACA,mBACA,wBACA,iBACA,CAAiB,EACjB,GACA,MAEA,CACA,CAAS,IAET,oBACA,oBACA,mCACA,kCACA,8BACA,oCACA,gCA9jBA,gBACA,IACA,EADA,KAEA,IACA,UAEA,SACA,MACA,CACA,KACA,OACA,cACA,IACA,IACA,KAEA,CAAK,IACL,+BACA,MACA,KACA,GACA,CAAK,CACL,EAyiBA,OACA,MACA,YACA,MACA,SACA,aACA,gBACA,kBACA,cACA,gBACA,kBACA,mBACA,qBACA,aACA,mBACA,mBACA,kBACA,aACA,cACA,iBACA,iBACA,eACA,eACA,qBACA,cACA,eACA,oBACA,mBACA,wBACA,iBACA,CAAiB,EACjB,GACA,MAEA,CACA,CAAS,IAET,CACA,CAyEA,iBAAiC,IAA+B,WAAoB,IAAW,kBAAyB,WAAmB,SAA+B,GAAR,KAAQ,oDAA2E,MAAoB,qCAAkD,IAAuB,QAAqB,mCAAmD,4BAA6D,UAA+B,SACtf,4BACA,OAAsB,uBAEtB,OADA,0BACA,gCACA,CACA,mOAKA,IACA,MAAW,CACX,WACA,kBACA,IAEA,aACA,kBACA,MAEA,oBACA,iBACA,CAAK,CACL,SACA,kBACA,IAEA,QACA,iBACA,CAAK,EAYL,oBAA4C,EAC5C,WACA,IACA,sBACA,iBACA,mBACA,MAEA,cACA,OACA,WACA,IACA,SA8RA,MACA,wBACA,EAhSA,GACA,QAEA,IACA,cAEA,oBACA,WACA,8BACA,OACA,YACA,CAAa,IAEb,CACA,CAiBA,mBACA,IACA,aACA,WACA,EAEA,WACA,OAWA,MAVA,uBACA,4BACA,2BACA,oBACA,cACA,OACA,CAAiB,CACJ,GAEb,OACA,KACA,MACA,CACA,CACA,SACA,WACA,CACA,CACA,CA/EA,0DACA,kBACA,cACA,WACA,kBAEA,mBAEA,EAAK,EAwEL,gBAIA,eACA,iBACA,OACA,wBACA,8BACA,uBACA,cACA,wEACA,yGACA,qEACA,EACA,uBACA,6BACA,uBACA,cACA,uEACA,wGACA,oEACA,CACA,CACA,CACA,cACA,2BACA,iEACA,0CAEA,cACA,0BACA,gEACA,yCAEA,sBACA,EAGA,4BACA,EACA,gBAJA,IAMA,CACA,uBACA,MACA,SAEA,YACA,MACA,SAEA,cACA,OACA,sBACA,eACA,CACA,cACA,WACA,SAGA,GACA,qBAEA,WAGA,IACA,CAIA,iBACA,sBACA,CAkBA,eACA,yBA0BA,iBACA,6CACA,CACA,iBACA,8BACA,6BACA,gBACA,sCACA,aACA,CACA,eACA,gDACA,CAnIA,YAAkB,GAAG,+BACrB,6BAmIA,UACA,cACA,UACA,4BACA,uBACA,CACA,SACA,MAAe,OAAgB,+BAC/B,CACA,OACA,6BACA,CACA,aAGA,SAFA,YACA,eAGA,EADA,WACA,UAGA,EACA,yBACA,yBACA,EACA,CACA,YACA,mCACA,CACA,QACA,4BACA,wBACA,SACA,CACA,aACA,gBACA,CACA,CACA,eACA,WAIA,OAHA,sHACA,sBACA,yBACA,CACA,CAeA,eACA,4BACA,KAEA,yBAXA,GACA,sBACA,MACA,SACA,eAXA,GACA,IACA,EADA,IAEA,cACA,IACA,QACA,EAKA,GACA,oBACA,EAKA,GACA,CACA,UACA,eACA,YACA,KACA,SAEA,sBACA,YACA,yCACA,IACA,+BACA,aACA,sBACA,sBACA,SACA,GACA,MAEA,qBACA,CACA,SACA,CAEA,2BACA,CAIA,kBACA,6BACA,CAKA,YACA,2CACA,mBACA,mCACA,iDACA,mBACA,uBACA,uBACA,EACA,CAAC,OAAiB,EAClB,QACA,2BACA,6BACA,2CACA,uBACA,uCACA,qBACA,6BACA,2CACA,uCACA,uCACA,oBACA,kBACA,oBACA,4CACA,8BACA,8CACA,sCACA,EACA,CAAC,OAAyB,EAC1B,QACA,yBACA,6BACA,qBACA,iCACA,2BACA,qBACA,mBACA,+BACA,+CACA,2BACA,kCACA,EACA,CAAC,OAAyB,EAC1B,QACA,qBACA,iBACA,qBACA,EACA,CAAC,OAAoB,CAMrB,UACA,cACA,cACA,eACA,cACA,CACA,OACA,kBACA,8CAEA,gBACA,YAA4B,IAAkB,IAC9C,WAhBA,KAAiC,IAA+B,WAAoB,IAAW,kBAAyB,WAAmB,SAA+B,GAAR,KAAQ,oDAA2E,MAAoB,qCAAkD,IAAuB,QAAqB,mCAAmD,4BAA6D,UAA+B,UAgBtf,sCAEA,QACA,CACA,WACA,OACA,QACA,cACA,SACA,EAEA,GADA,SACA,mBAzBA,SAyBA,mBACA,kCACA,SACA,kCACA,8BACA,GACA,cAEA,MACA,kBAlCA,SAmCA,eACA,6BACA,kCACA,aACA,0BACA,8BACA,GACA,UAEA,MAEA,WACA,uBAEA,iBACA,WAEA,gBACA,cAEA,aACA,CACA,cACA,aACA,YAGA,YAUA,uBACA,OACA,2BAGA,uBAdA,iBACA,UACA,wBAGA,gBAYA,QACA,cAEA,cACA,CACA,CACA,iBAAqC,EAAG,GAAG,EAAS,CACpD,UACA,cACA,eACA,eACA,cACA,mBACA,8BACA,gBACA,mBACA,iBACA,sBACA,sBACA,wBACA,0BACA,gCACA,WACA,EACA,eACA,4BACA,OAEA,SACA,UACA,SACA,MACA,QACA,EA7/CA,GA8/CA,aAEA,EADA,sBACA,qBAEA,QACA,EACA,MACA,yBACA,OAEA,sBACA,yBACA,gCACA,OACA,kBACA,oBAEA,YACA,aACA,mBACA,2BACA,iCACA,6BACA,qCACA,iCACA,qCACA,uCACA,2CACA,aACA,qBACA,uCACA,uCACA,qCACA,2BACA,6BACA,mCACA,mCACA,+BACA,+BACA,gBACA,mBACA,mEACA,gCAEA,mBACA,2CAEA,OACA,0DAEA,CAAqB,CACrB,qBACA,mEAGA,qCACA,iBACA,8CAEA,6CACA,CAAqB,CACrB,yBACA,6CACA,CAAqB,CACJ,EACjB,IACA,QACA,WACA,SACA,MACA,CAAqB,EACrB,YAEA,EACA,6BACA,uDAEA,2BACA,kCACA,kCAGA,KAEA,2BACA,uBACA,+BAGA,oBACA,KAGA,uBANA,KASA,WACA,gBACA,WACA,MACA,4CACA,YACA,iBACA,KAEA,CACA,OACA,aACA,SACA,QAEA,GADA,aACA,GACA,4CAEA,QADA,WAEA,SACA,WACA,IACA,KACA,CACA,CACA,cACA,iBACA,wBACA,6BACA,mBACA,KAEA,QADA,qBACA,CACA,IACA,KACA,CACA,CACA,CACA,CACA,CACA,CACA,OACA,aACA,2BAEA,KACA,CACA,aACA,sBACA,UACA,CACA,OACA,iBACA,SACA,6BACA,cACA,CAAiB,EACjB,wBACA,iCACA,2BACA,QACA,eAA4B,GAAa,EACzC,6BACA,kCACA,oCACA,0BACA,6BACA,8BACA,qBAGA,CACA,OACA,6BACA,YACA,CACA,CAAiB,EACjB,wBACA,iCACA,qBACA,MACA,EACA,iBACA,qBACA,kBACA,iBAGA,cACA,mBACA,8BACA,gBACA,sBACA,sBACA,wBACA,iBACA,mBACA,EACA,yBACA,6BAGA,eACA,qBACA,2BACA,yEACA,gBACA,iBACA,6HACA,gBACA,gCACA,uBACA,EACA,aACA,CAAyB,EAEzB,KACA,CACA,kBACA,eACA,kBACA,2BACA,gBACA,WACA,YACA,YACA,SACA,uCACA,UACA,MACA,CAAyB,EAEzB,KACA,SAFA,qGAGA,UACA,QACA,6BACyB,CACzB,CACA,4EACA,eACA,OAEA,sCACA,yBACA,WACA,0BACA,qBAIA,OAHA,UAKA,CAgBA,GAfA,IACA,GACA,cACA,aAA0C,CAC1C,YAAyC,CACzC,mBAAgD,EAEhD,wBACA,mCAEA,YACA,qBACA,6CACA,6CAEA,mBACA,wEACA,cACA,uBACA,IACA,mBACA,4CACA,CACA,SACA,4BAGA,+CAIA,aAHA,YACA,mCAEA,sBACA,kCACA,gCACA,kCACA,mCACA,OACA,iBAGA,qBAIA,4BAGA,iCACA,kCACA,mBAGA,CAEA,KACA,CACA,gBACA,2EACA,OAEA,kDACA,2BACA,2BACA,cACA,iCACA,4BACA,yEACA,mBAroBA,SAsoBA,QAtoBA,MAsoBA,KAGA,sBACA,oBACA,wBAEA,qCACA,SAzoBA,OACA,QACA,SAEA,uBACA,WAGA,gBACA,4CAGA,cAGA,kBACA,EAynBA,wBACA,sBACA,uBACA,oBAGA,mBACA,WACA,KACA,uCAEA,MACA,CAA6B,GAE7B,wBACA,CAAqB,CAGrB,CACA,EACA,qBACA,sDAEA,8CAEA,2BACA,qBACA,OAEA,qBACA,WACA,2BACA,yBAEA,WACA,8CAEA,MAEA,qBACA,yBAEA,qEACA,yCACA,OACA,oCACA,sCACA,iBACA,CAAqB,GAGrB,CACA,CACA,QACA,CACA,aACA,aACA,gBACA,kBACA,cACA,gBACA,kBACA,mBACA,qBACA,mBACA,mBACA,kBACA,aACA,cACA,kBACA,eACA,eACA,iBACA,iBACA,MACA,SACA,gBACA,oBACA,mBACA,gBACA,uBACA,aACA,aACS,CACT,CACA,SACA,eACA,2BACA,CACA,WACA,eACA,8BACA,WACA,CACA,WACA,mBAEA,OACA,eACA,yBACA,CACA,SACA,eACA,4BACA,WACA,CACA,QACA,8BACA,0BACA,CACA,CACA,iBACA,YACA,gCACA,CACA,0BACA,cAEA,SAEA,OACA,mBACA,SACA,iBACA,uBACA,SAEA,eAEA,QACA,EAZA,MACA,CAYA,wBACA,YAEA,SAEA,OACA,eAAY,GAAa,QACzB,QAGA,UAGA,OACA,EAXA,IACA,CAmBA,UACA,EAGA,SACA,IACA,cACA,CACA,SACA,gBACA,WACA,CAEA,QACA,CACA,CAAK,CAbL,EAiBA,iBAAiC,IAA+B,WAAoB,IAAW,kBAAyB,WAAmB,SAA+B,GAAR,KAAQ,oDAA2E,MAAoB,qCAAkD,IAAuB,QAAqB,mCAAmD,4BAA6D,UAA+B,SACtf,UACA,eACA,IACA,uBACA,uBACA,YACA,iBAGA,6BACA,iBAGA,SACA,CACA,mBAEA,iBACA,aACA,WACA,UACA,+BACA,4BACA,mHACA,GACA,WACA,cAEA,mBACA,oCAGA,6BACA,CAAK,GASL,OARA,aACA,cACA,qBACA,iBACA,yBACA,aACA,UACA,CAAK,EACL,CACA,CAoJA,sBAA8B,2EAA8E,EAwB5G,mBAvBA,aACA,YACA,OACA,eACA,OAEA,iBACA,yBACA,wBACA,GACA,KACA,SACA,QACa,CACb,MAEA,GACA,KACA,eACA,cACa,CAEb,CAAK,kBACL,EACA,CAkBA,qCACA,eAuGA,mBAEA,EAoBA,OApBA,EADA,GAEA,uBACA,yCACA,oBAiBA,EAhBA,oCACA,uBACA,yCACA,wBAaA,EAZA,uCAGA,UADA,MADA,KAWA,EAXA,qBACA,QAUA,IAPA,oBAGA,UADA,MADA,kCACA,QAKA,IAFA,CAGA,CACA,mBACA,eACA,GAEA,YACA,uBAEA,aACA,CACA,UACA,IACA,GARA,EASA,CA+IA,oBAAyC,sBAA4B,IACrE,WAEA,EADA,yBACA,WAEA,gBACA,+BACA,iEACA,uGACA,0CACA,8FACA,cACA,UACA,QACA,GACA,GAGA,8CACA,4BACA,wBACA,MACA,6EACA,CAAS,CACT,OACA,+EACA,oBACA,IACA,uBACA,CACA,SACA,CAEA,QACA,CAAS,CACJ,EACL,QACA,8CACA,4BACA,wBACA,UACA,UACS,CACT,CAAK,GA3BL,KACA,CA2BA,CAyKA,kBAAqC,MAMrC,EALA,wBACA,MACA,WACA,CAGA,cACA,gBAEA,eAxrBA,aAA4B,4BAAqC,MAUjE,EATA,oBACA,WACA,EAEA,kDACA,uCACA,oBACA,IACA,KAEA,YACA,mBACA,YACA,gBACA,IACS,GACT,KACA,MACA,CAAK,KACL,eACA,YACA,CAAgB,qBAAmB,MACnC,oBACA,EACA,GACA,SAEA,QACA,IACA,IACA,cACA,iBACA,CAAS,EACT,wDACA,QACA,wBACA,aACA,aACA,CAAK,KACL,WACA,CAAK,GACL,GACA,oBACA,oBACA,eACA,CACA,eACA,iBACA,CAAK,CACL,EAsoBA,GACA,WAtoBA,oBAAwC,2EAAwF,EAChI,2BACA,WACA,EAEA,+BACA,4BACA,GACA,mBACA,KACA,OACA,KACA,IACA,YACA,kBACA,OAEA,WACA,IACA,sBACA,sBACA,YACA,WACA,KACA,aACA,WACA,KACA,WACA,QAEA,CACA,aACA,qBACA,eAEA,oBACA,eAGA,YAEA,OACA,YAEA,WACA,IACA,wBACA,cACA,uBACA,eACA,UAGA,mBACA,IACA,QAEA,kCACA,MACA,OAEA,iBACA,SAAoB,aAAmB,EACvC,OACA,WACA,KACA,IACA,IACA,0BAA8C,EAC9C,CAAa,CACb,EAsBA,OApBA,gBACA,mCACA,0BACA,WACA,YACA,WACA,OACA,uBACA,cACA,kBACA,gBACA,+BACA,KACA,oBACA,iBACA,MACA,CAEA,iBACA,CAAK,EACL,QACA,iBACA,CAAK,CACL,EAuiBA,GACA,QACA,EA9gBA,2BAAsC,EAAkB,MAAI,EAAK,EACjE,SACA,KAaA,mBAZA,cACA,WACA,OACA,iBACA,GACA,gBACA,gBACA,CAAa,EACb,IACA,IAEA,CAAK,QACL,EACA,EA8fA,GACA,KACA,CAAK,EACL,EA9fA,kBAA6B,4OAAqO,EAClQ,cACA,YACA,cACA,kBAGA,GAFA,cACA,oBACA,IACA,IACA,iBACA,eACA,OAEA,QACA,4BACA,gBACA,OAEA,WACA,YACA,KACA,KACA,mBACA,UACA,MACA,CAAS,EACT,kBACA,+BACA,cAEA,KACA,WACA,UACA,QACA,aACA,CAAS,EACT,MACA,MAAgB,+BAChB,MAAgB,cAAiB,EACjC,aACA,mBACA,EACA,8CAA+D,EAAK,KACpE,YACA,UACA,SACA,WACA,UACA,gBACA,aACA,CAAqB,EACrB,MACA,MAA4B,iCAC5B,MAA4B,eAA6B,CACzD,CACA,CAAa,CAEb,CACA,gBACA,gBACA,OACA,iBACA,2BACA,YACA,iBACA,OACA,KACA,IACA,CAAa,CACb,CACA,CAEA,OADA,gDACA,sBACA,gBACA,MACA,WACA,iBACA,EAEA,8EACA,GACA,uCACA,yCACA,wCACA,0CACA,gDACA,2CACA,CAWA,OAVA,UACA,6BAnvCA,oBACA,6CAaA,OAZA,8BACA,EACA,CACA,OACA,QACA,kBACA,CAAiB,IACjB,UACA,kBAEA,CAAa,CACJ,EACT,eAAuD,IACvD,GAouCA,WACA,MACA,OACA,YACA,YACA,CAAiB,CACjB,CACA,CAAS,SAET,QACA,iBACA,CAAK,CACL,EAyZA,GACA,EAvIA,6BAAwC,2EAAwF,EAChI,sBACA,YACA,OACA,eACA,OAEA,gBAAgB,mCAA2C,EAC3D,GACA,OACA,cACA,cACA,SACA,QACA,cACA,CAAS,CACT,CAAK,iBACL,GACA,kBACA,mBACA,oBACA,0BACA,wBACA,CACA,eACA,iBACA,CAAK,CACL,EA4GA,GACA,SACA,SACA,SACA,QACA,eACA,WA1XA,kBAAkC,+BAA6C,MAAI,EAAK,MAmCxF,EAkBA,EApDA,gDACA,WACA,EAEA,2CACA,kDACA,mBACA,WACA,IAAoB,aAAc,sBAQlC,MAPA,wBACA,GACA,KACA,UACA,YAA6B,UAAa,EACzB,EAEjB,YACA,CAAS,CACT,CAAK,EACL,2CACA,kDACA,mBACA,SACA,IAAoB,aAAc,sBAQlC,MAPA,wBACA,GACA,KACA,UACA,gBAAgC,EAAO,EACtB,EAEjB,YACA,CAAS,CACT,CAAK,EAEL,oCACA,oCACA,+CACA,mBACA,SACA,CAAwB,gBAAc,sBAQtC,MAPA,wBACA,GACA,KACA,UACA,SACA,CAAqB,EAErB,YACA,CAAa,CACb,CAAS,GAGT,wCACA,wCACA,mDACA,mBACA,SACA,IAAwB,aAAc,sBAQtC,MAPA,wBACA,GACA,KACA,UACA,aACA,CAAqB,EAErB,YACA,CAAa,CACb,CAAS,GAET,SACA,sBACA,qCAGA,oBACA,gCAEA,wBACA,wCAEA,uBACA,uCAGA,SA6CA,OA5CA,oCACA,MACA,kCACA,mCAEA,kDACA,mBACA,WACA,IAAwB,aAAc,uCAgBtC,MAfA,wBACA,GACA,KACA,UACA,MACA,CACA,OACA,UACA,MACA,KACA,CAC6B,CAC7B,CACqB,EAErB,YACA,CAAa,CACb,CAAS,EACT,kDACA,mBACA,SACA,IAAwB,aAAc,uCAUtC,MATA,wBACA,GACA,KACA,UACA,SACA,CAA8B,mBAAuD,CACrF,CACqB,EAErB,YACA,CAAa,CACb,CAAS,CACT,CAAK,EACL,QACA,uCACA,uCACA,yCACA,6CACA,oCACA,uCACA,uCACS,CACT,CAAK,CACL,EA6OA,GAAyD,MAAoB,EAC7E,cACA,EAjMA,6BAAwC,qDAAqE,MAAI,EAAK,EACtH,kDACA,yDACA,mBACA,aACA,YACA,0BAEA,OAAoB,aAAc,4FAalC,MAZA,wBACA,GACA,KACA,UACA,KACA,WACA,QACA,UACA,CAAqB,CACrB,sBACA,CAAiB,EAEjB,YACA,CAAS,CACT,CAAK,EACL,qDAqBA,OApBA,4DACA,mBACA,SACA,YACA,sBAEA,OAAoB,aAAc,4FAWlC,MAVA,wBACA,GACA,KACA,UACA,QACA,UACA,CAAqB,CACrB,sBACA,CAAiB,EAEjB,YACA,CAAS,CACT,CAAK,EACL,QACA,8CACA,gDACA,CAAK,CACL,EAgJA,GACA,KACA,CAAS,EACT,gBACA,GAvHA,iBAA4B,QAAa,EACzC,oBACA,MACA,WACA,EAEA,SACA,cACA,aACA,2BACA,mBASA,OARA,SACA,SACA,0BACA,cACA,8BACA,EACA,6CACA,CAAS,EACT,CACA,EACA,mCACA,mBAQA,OAPA,WACA,eACA,IACA,KACA,YAEA,CAAa,KACb,iBACA,CACA,CAAK,EAKL,OAJA,YACA,YACA,CAAK,EACL,UACA,QACA,iBACA,CAAK,CACL,EA+EA,KAGA,eAjFA,GACA,QAAY,yEAAwE,EACpF,KACA,UACA,uBACA,oDACA,OACA,oBACA,SACA,kBACA,YAAwB,IAAW,KAEnC,mBAAoB,4CAAuD,EAD3E,cAEA,gBACA,gBAGA,QACA,iBACA,cACA,eACA,WACA,CAAa,CACb,CACA,UAAsB,EAAQ,CAC9B,CAAK,EAEL,OADA,IACA,uBACA,EAqDA,GACA,WArDA,KAAqC,oBAAuB,EAC5D,2BACA,oBAEA,yCACA,uBACA,IACA,GACA,QACA,MACA,CAAqB,CACJ,CACjB,CACA,SACA,CACA,4BACA,CACA,CAAK,EAdL,MAgBA,EAkCA,GACA,KACA,uBACA,2CAEA,eACA,yBACA,uDACA,IACA,IACA,IACA,IACA,IACA,IACA,IACA,IACA,IACA,IACA,IACA,IACA,iBACA,CAAK,CACL,CACA,eACA,0BAEA,eACA,6BACA,qBACA,oCACA,mCACA,CAEA,SACA,eACA,oBACA,uCACA,sCACA,CACA,eACA,oCACA,gCACA,WAMA,OALA,IACA,sBACA,WACA,YAEA,CACA,CACA,YACA,iCACA,6BACA,oCACA,CACA,mBACA,0CACA,mBACA,EACA,UAEA,EAEA,CACA,kBACA,iCACA,wCACA,CACA,SACA,OACA,uCACA,uCACA,MACA,CACA,qCACA,oCACA,CACA,sBACA,wCAKA,OAJA,IACA,UACA,qCAEA,CACA,CACA,sBACA,wCAKA,OAJA,IACA,UACA,qCAEA,CACA,CACA,CAEA,iBAAiC,IAA+B,WAAoB,IAAW,kBAAyB,WAAmB,SAA+B,GAAR,KAAQ,oDAA2E,MAAoB,qCAAkD,IAAuB,QAAqB,mCAAmD,4BAA6D,UAA+B,SACtf,SACA,cACA,wCACA,2CACA,CACA,YACA,CACA,kBACA,CACA,eACA,CACA,CACA,SACA,eACA,yBACA,sCACA,wCACA,4CACA,6BACA,+BACA,2CACA,yDACA,iIACA,qBACA,+BACA,gEAEA,CACA,aACA,uBACA,iBACA,gDACA,CACA,mBACA,mBACA,CACA,kBACA,iBACA,MACA,CACA,8BACA,YACA,MACA,CAAiB,CACjB,CACA,WACA,SACA,cACA,iBACA,CAAS,EACT,6DACA,mBACA,sCACA,+CACA,kHACA,CACA,iBAEA,aADA,EACA,WADA,EAEA,wBAGA,CADA,SADA,OAIA,8CACA,MACA,OACA,qDACA,GACA,qCACA,CACA,+BACA,eACA,sBACA,sCACA,2CACA,oCACA,qBAGA,OAFA,yCACA,sCACA,CACA,sBACA,4BACA,MACA,mBACA,MACA,CACA,8BACA,YACA,iBAC6B,CAC7B,CACA,WACA,SACA,cACA,iBACA,CAAqB,CAErB,CACA,aACA,aACA,yBACA,KAEA,gBACA,QAEA,gBAEA,OADA,0EACA,CAEA,6BACA,sBACA,iBAoBA,OAnBA,wBACA,qBACA,WACA,SACA,aACA,EACA,+BACA,4CACA,oCACA,CAAyB,EACzB,2BACA,sCACA,CAAyB,EACzB,8BACA,2BACA,CAAyB,EACzB,yBACA,2BACA,CAAyB,EACzB,CAEA,cACA,kBACA,kBAIA,OAHA,6BACA,2BACA,CAAyB,EACzB,CAEA,wBACA,QAEA,0BACA,yBACA,eACA,uBACA,cAEA,OADA,iCACA,CAEA,wBACA,yBAGA,OAFA,iCACA,2CACA,CAEA,cACA,QAEA,mBAIA,OAHA,0BACA,oCACA,CAAyB,EACzB,CAEA,2BAMA,OALA,iCACA,4CACA,4FACA,qCACA,CAAyB,IACzB,CAEA,CAEA,CACA,QACA,CACA,iBACA,eACA,+CAEA,oBACA,sBAGA,sBAGA,QACA,CACA,kBACA,uDACA,CACA,uBACA,4DACA,CACA,qBACA,qCACA,kBACA,yBACA,yBACA,CAAa,CAEb,CACA,uBACA,+BACA,aACA,kBACA,yBACA,2BACA,CAAa,CAEb,CACA,CAEA,SACA,OACA,CACA,gBACA,CACA,sBACA,CACA,QACA,CACA,CACA,SACA,eACA,4BACA,wBACA,6BACA,yBACA,mCACA,qBACA,WACA,CACA,OACA,aACA,wCACA,CACA,mBACA,UAEA,uBADA,OAGA,uBACA,kDACA,UACA,sBACA,MACA,2BACA,mBACA,sBACS,IACT,8CACA,8BACA,sBACA,uBACA,MACA,mBACS,GACT,QACA,sBACA,+BACA,sGACA,8BACA,mBACA,uDACa,IACb,CAAS,GACT,CACA,uBACA,oCAEA,iEACA,CACA,uBACA,WACA,oEACA,mBACA,qBAGA,OAFA,2BACA,mCACA,CACA,CACA,CAAS,EACT,CACA,QACA,iCACA,IACA,GACA,CACA,SACA,CACA,CAAS,EACT,wBACA,4BACA,mDACA,CACA,CAEA,SACA,QACA,CACA,SACA,CACA,WACA,CACA,OACA,CACA,SACA,CACA,WACA,CACA,YACA,CACA,gBACA,CACA,mBACA,CACA,CAEA,SACA,eACA,qCACA,wBACA,6BACA,+CAEA,uBACA,2BACA,iBACA,QACA,WACA,SACA,YACA,CACA,QACA,aACA,WACqB,CACrB,CACa,EACb,wBACA,CACA,oBACA,kCAEA,gCACA,qCACA,CACA,sBACA,gBACA,OACA,OACA,KACA,aAEA,KACA,gBACA,MACA,wBAWA,6BAVA,0BACA,QACA,UACA,2CACA,UACA,OACA,EAAqB,CACrB,CAAiB,GAIjB,kBACA,CACA,YACA,aACA,2BACA,CACA,QACA,yBACA,oCACA,CACA,gCACA,CACA,CAEA,SACA,cACA,yBACA,cACA,CACA,mBACA,0BACA,sCACA,CACA,SACA,cACA,eAl5DA,eACA,iCACA,EAi5DA,KACA,yBACA,cACA,CAAa,GAEb,yDACA,CACA,UACA,CACA,CAIA,IACA,kCACA,uCACA,6BACA,WAAqB,OAAc,6FACnC,4BACA,CACA,CACA,SACA,gDACA,CACA,OAn2GA,MAo2GA,gBAA4B,MAsE5B,EArEA,SAAY,kbAAke,oBAAqB,iIACngB,cACA,0LAAqN,EAnyCrN,EAoyCA,EACA,UACA,uBAEA,KACA,MACA,IACA,wBACA,MAEA,CACA,SACA,IACA,CAEA,SACA,yCAEA,UACA,WACA,CAEA,mCACA,gBAEA,WACA,aACA,CACA,SACA,QACA,oBACA,SACA,SACA,UACA,SACA,UACA,OACA,QACA,QACA,OACA,QACA,YACA,UACA,SACA,WACA,EACA,WACA,EACA,GACA,oBACA,CACA,UACA,WACA,eACA,kBACA,kBACA,kBACA,qBACA,wBACA,6BACA,8BACA,EACA,GAEA,IA9mEA,mBACA,+CACA,8CACA,SAEA,uDACA,kDACA,SAEA,yBACA,kCACA,WACA,aACA,0CAEA,GACA,YACA,eAEc,mBACd,QACA,EAEA,IA0lEA,QACA,MACA,mBACA,kBACA,wBAOA,OAJA,GACA,IACA,SAEA,CACA,EACA,UASA,GARA,EACA,eACY,OAAc,sEAF1B,EAGA,wBACA,EAJA,EAIA,+BACA,8BACA,4BAEA,EACY,OAAc,0BAT1B,GAS0B,UAE1B,MACA,OACA,aACA,QAdA,GAeA,8BACA,YACA,EACA,gCACA,CACA,GApBA,EAoBA,uBACA,EArBA,EAsBA,SAEA,GAxBA,EAwBA,+BACA,gCAzBA,EA0BA,oBACA,MAEA,KACA,cACA,KACA,GACA,0BACA,QACA,MAEA,CACA,EACA,UACA,GACA,4BACA,MACA,mBACA,IACA,CAAa,CACJ,CACT,EACA,QACA,4BACA,MACA,iBACA,KACS,CACJ,EACL,QACA,4BACA,MACA,yBACA,KACS,CACJ,EAQL,WACA,aACA,oBATA,MACA,4BACA,MACA,4BACA,KACS,CACJ,CAIL,CAAK,EACL,wEACA,OACA,QACA,UACA,aACA,qBACA,2BACA,aACA,CAAS,EACT,mBACA,aACA,aACA,cACA,mDACA,6DACa,EAEb,cACA,YAmTA,KACA,IACA,SACA,KACA,MACA,CACA,SAEA,OADA,mDACA,MACA,CACA,EA7TA,GACA,UACA,WACA,iBACA,4BACA,MACA,yBACA,KACa,CACJ,EACT,eACA,aACA,gBACA,kBACA,gBACA,kBACA,iBACA,cACA,CAAK,EACL,mDACA,6BACA,OACA,QACA,aACA,WACA,eACA,aACA,aACA,gBACA,kBACA,cACA,gBACA,kBACA,mBACA,qBACA,mBACA,mBACA,iBACA,kBACA,aACA,cACA,eACA,eACA,WACA,iBACA,iBACA,qBACA,iBACA,kBACA,uBACA,CAAa,CACb,SACA,CAAS,EACT,YACA,MACA,OAEA,GACA,aACA,MACA,0BACA,WACA,WACA,CAAa,CACJ,IACT,WACA,UACA,wBACA,eAtjFA,KACA,WAAY,meAA6gB,MAuCzhB,aACA,MACA,SACA,aACA,gBACA,kBACA,cACA,gBACA,kBACA,mBACA,qBACA,aACA,mBACA,iBAnDA,OACA,CACA,SACA,QACA,oBACA,SACA,SACA,UACA,SACA,UACA,OACA,QACA,QACA,OACA,QACA,YACA,SACA,EACA,OACA,GACA,EAgCA,kBACA,aACA,cACA,eAlCA,kBAEA,CACA,UACA,WACA,eACA,kBACA,+BACA,kBACA,kBACA,qBACA,sBACA,uBACA,EACA,OACA,GACA,EAmBA,iBACA,eACA,eACA,qBACA,cACA,eACA,oBACA,mBACA,wBACA,kBACA,oBACA,CAAK,CACL,EAg/EA,UACA,UACA,aACA,gBACA,kBACA,cACA,gBACA,kBACA,mBACA,qBACA,mBACA,gBACA,kBACA,cACA,aACA,UACA,iBACA,eACA,eACA,gBACA,UACA,gBAEA,UACA,uBAEA,OACA,uCAEA,CAAa,CACb,qBACA,qBACA,iBACA,8BAEA,yBACA,CAAa,CACb,yBACA,yBACA,CAAa,CACb,iBACA,CAAS,EACT,MACA,uDAEA,GACA,qBACA,MACA,OACA,wBACA,CACA,CAAS,EACT,0BACA,mEACA,mEACA,EACA,KACA,IACA,SACA,KACA,QACA,aACA,aACA,sBACA,4BACA,MACA,SACA,WACA,CAAqB,CACJ,EACjB,yBACA,4BACA,MACA,2BACA,KAEA,CAAiB,EACjB,WACA,uBACA,4BACA,MACA,yBACA,KACqB,CACJ,EACjB,cACA,4BACA,MACA,gBACA,KACqB,CACJ,EACjB,yBACA,4BACA,MACA,2BACA,KACqB,CACJ,EACjB,uBACA,4BACA,MACA,yBACA,KAEA,CAAiB,EACjB,yBACA,4BACA,MACA,2BACA,KACqB,CACJ,EACjB,mBACA,aACA,4BACA,MACA,eACA,KACqB,CACJ,EACjB,gBACA,GACA,4BACA,MACA,oBACA,IACA,CACA,CAAqB,CACrB,CAAiB,CACjB,oBACA,GACA,4BACA,MACA,wBACA,KACyB,CACJ,CACrB,CAAiB,CACjB,aACA,cACA,iBACA,cACA,gBACA,kBACA,mBACA,qBACA,mBACA,mBACA,WACA,YACA,eACA,eACA,uBACA,eACA,MACA,kBACA,cACA,aACA,kBACA,gBACA,kBACA,iBACA,iBACA,UACA,iBACA,qBACA,oBACA,wBACA,iBACA,sBACA,QAAyB,OAAc,IACvC,wDACA,2CACA,oBACA,kBACA,eACA,eACA,MACA,cACA,SACA,CAAyB,CACJ,CACrB,EAAiB,QACJ,GAAI,EAEjB,uBACA,IACA,4BACA,CACA,SACA,eACA,CACA,CAAS,EACT,WACA,KACA,mBACA,EAuBA,MAtBA,qCACA,iCACA,KAGA,kCACA,GACA,yBACA,OAA4B,CACX,EACjB,wBACA,GACA,CAAa,GACb,sBACA,GACA,aACA,OAA4B,CACX,EACjB,YACA,GACA,CAAa,WAEb,KACA,kBACA,aACA,SAhvDA,QAkvDA,CACA,CACA,SACA,eACA,CACA,CAOA,aACA,oBAPA,YACA,MACA,+DAEA,IACA,EAsBA,qCAiFA,eAEA,OADA,cACA,OACA,CAKA,eAEA,OADA,cACA,OACA,CAKA,iBACA,oCAIA,6CACA,wBAEA,iCAGA,iBAGA,qBACA,eAGA,+BACA,MACA,iBAEA,QAAiB,QAAS,UAC1B,CAAO,CACF,EAGL,yBAEA,CAKA,eAEA,OADA,UAJA,aAKA,CACA,CAQA,eACA,mBAEA,wBAIA,MAHA,CAIA,CAGA,qBASA,iBARA,MAQA,WARA,EACA,SAGA,CACA,EAtFA,WApDA,OACA,qBACA,oBACA,cACA,oBACA,iBACK,EAsCL,eACA,eACA,CAAK,CAIL,IAsIA,gBACA,YACA,kBACA,oBACA,qBACA,kBACA,aACA,oBACA,CAQA,UAGA,YACA,EACA,EAEA,KACA,CACA,qBACA,mBACA,gBAGA,4BACA,gCACA,uCACA,eACA,sCACA,0BACA,CAGA,mBAzEA,EA0EA,OA1EA,EA0EA,KAEA,uBACA,CAAK,CA3EL,IACA,KAeE,QAAI,sBACN,sBACA,KACA,IACA,iBACA,CAAU,SAEV,CAGA,mBACA,CACA,CAAG,GAvBH,UAEA,KACA,wBACA,MACA,aAEA,EAiEA,qBACA,IAEA,gBACA,qBACA,kBACA,CACA,CAGA,kBACA,gBACA,iBAGA,yBACA,qCAEA,CAGA,qBAkKA,EAjKA,0BAkKA,aAlKA,EAkKA,UAKA,gFAQA,MA/KA,EA+KA,SACA,CAhLA,EAgLA,8DAhLA,EAgLA,yBAKA,GArLA,EAqLA,YAQA,EA7LA,EA6LA,uBA7LA,EA6LA,aA7LA,EA6LA,WA5LA,OAGA,OACA,0BACA,kBAEA,aACA,MACA,EAIA,6EAKA,qBAGA,yBACA,4BAEA,CAGA,+BACA,wBACA,CAGA,6BACA,sBACA,CAGA,iBACA,YACA,yBACA,CAGA,qBACA,+BACA,cACA,CAAK,CACL,CAGA,cACA,yCACA,CAGA,eACA,SAEA,OAiBA,aAfA,yBACA,sCACA,wFAEA,kCACA,kFAIA,8BACA,SAEA,CAAK,EAGL,IACA,8BAEA,OACA,6BACA,yBAEA,CAGA,qBACA,2BAEA,CAGA,wBACA,mBACA,mDACA,oDAGA,YAAY,qBAA8B,EAG1C,GAJA,OAIA,CAGA,iEACA,2CAEA,GACA,eACA,kBACA,sBACA,gCACA,MACA,UACA,oBACA,0BACA,mBACA,YAGA,eACA,CACA,EAEA,8BACA,MACA,CAGA,QACA,OACA,eACA,kBACA,sBACA,yBACA,MACA,UACA,oBACA,0BACA,aACA,SACA,CAAS,EAGT,6BACA,CACA,CAGA,uBACA,yBACA,sCAGA,wBAA8B,QAAY,6BAC1C,CACA,CAEA,8BAmCA,cACA,qBACA,CAoDA,YACA,GAEA,OACA,yBACA,eACA,KAEA,EAGA,YACA,2BACA,mCACA,yBACA,mBACA,qBACA,wBACA,CAAC,UAA4B,EAI7B,gBACA,KACA,QACA,aACA,OACA,OACA,MACA,QACA,eACA,cACA,WACA,gBACA,wBACA,EAyBA,MAGA,IACA,kBACA,OAGA,eA6DA,GACA,WAAU,aAAkB,SAQ5B,OAGA,EAFA,uBAGA,OAGA,IACA,4BACA,EAAc,QAAgB,IAAW,oBAAsB,cAC/D,CAAI,SACJ,aACA,CAEA,cAAW,YACX,EAvB4B,GAE5B,WACA,eAAoB,OAAiB,EACrC,WACG,CACH,EApEA,GAEA,MACA,OAGA,uBACA,mBAGA,GACA,iBACA,GACA,UACA,WACA,YACA,YACA,aAEA,SAtYA,OACA,kBACA,EAqYA,gBACA,EACA,aAIA,OACA,EAIA,iBACA,yBACA,0BACA,0BACA,OAqDA,iBArDA,OAEA,OACA,UACA,OACA,CACA,SACA,MACA,KACA,kBACA,qCACA,uCACA,gBACA,iBACA,SACA,oBA9EA,GACA,SAIA,YAHA,uDACA,sDAEA,EACA,cACA,QAEA,yCACA,aAGA,UAIA,QACA,EA4DA,aACA,CAAW,EAEX,EAAU,CAEV,CAiGA,OAEA,CAEA,SAkGA,SACA,GAEA,IACA,YACA,gBACA,OACA,cACA,YACA,kBACA,kBACA,iBACA,eACA,CAAI,QAGJ,uCACA,KAGA,CACA,QAAa,EAAU,GAAG,EAAc,EACxC,YACA,UACA,OACA,MACA,OACA,aACA,kBACA,iBACA,CAAK,CAEL,EAjIA,MAuCA,YACA,aAAU,kCAAuC,EAEjD,QACA,OACA,OACA,OACA,QACA,QACA,WACA,CACA,EAhDA,WAkDA,YACA,IACA,YACA,OACA,kBACA,WACA,cACA,kBACA,6BACA,2BACA,iBACA,iBACA,eACA,gBACA,YACA,eACA,OACA,CAAI,SAGJ,MACA,KAGA,CACA,QAAa,EAAU,GAAG,EAAK,EAC/B,YACA,UACA,OACA,MACA,OACA,kBACA,kBACA,WACA,iBACA,6BACA,2BACA,iBACA,eACA,cACA,eACA,CAAK,CAEL,CA5FA,EAKA,YACA,EACA,GAEA,eAAY,EAAQ,6CACpB,CAWA,eACA,6BACA,EAIA,KAHA,IAIA,CAEA,eAGA,QAAW,IAA4B,kCACvC,CAiGA,eACA,oCAEA,uCADA,gCAEA,CASA,eACA,SACA,KACA,uBACA,GAVA,mBAUA,CACA,SACA,uBACA,WACA,eACA,8BACA,GACA,SAEA,CAEA,QAA0B,wCAAmE,CAC7F,CAGA,0CACA,CAKA,eACA,oCAEA,gCADA,8BAEA,CAKA,eACA,oCAEA,wCADA,8BAEA,CAKA,YACA,EACA,EACA,EACA,GAEA,cACA,WAEA,QAEA,OACA,iBACA,OACA,QACA,MACA,MACA,QACA,OACA,SACA,8CACA,cACA,CAAK,CAEL,CA0CA,uBACA,cACA,+CAAmD,SACnD,CA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CM,SACN,uBACA,EAAM,OACN,uBAEA,GAMA,sBAEA,CACA,EAGA,oBACA,2CACA,gBAEA,CAGA,UAAc,4BACd,eAEA,8BACA,wCACA,SAIA,WACA,UACA,4BACA,MACA,QACA,OACA,CAAS,CACF,EACP,+BACA,OAGA,KAGA,WAAkB,iEAAuE,EACzF,GAKA,EACA,CAEA,iBACA,UACA,KAEA,EACA,UACA,CAyDA,OACA,mGAEA,8CAEA,MAgBA,MACA,SASA,UAIA,sBAA0B,iBAkB1B,aACA,gBA3iSA,GA2iSA,CACA,gBAziSA,IAyiSA,CACA,oBAnhSA,IAmhSA,CACA,oBA/gSA,IA+gSA,CACA,IAhhSqC,UAghSrC,KACA,oBACA,YACA,iBAAqB,CACrB,iBACA,mBACA,mBAEA,8BACA,oBAEA,uBACA,8BAEA,4BACA,2BACA,0BACA,2BACA,4BAEA,UACA,yCACA,YACA,WACA,aACA,YACA,SAEA,0BACA,sBACA,CAAI,EAAI,EACR,gBAEA,MA/IA,eAA6B,sCAAsC,EAgBnE,MAVA,CAEA,iBALA,4CAMA,mBALA,SAOA,0DAVA,iBAUA,EACA,yBACA,mFACA,CAGA,EA8HA,CACA,OACA,SACA,QACA,UACA,QACA,CAAK,EAwEL,GAtEA,wBACA,gBACA,cACA,kBAA0B,YAAgB,CAC1C,aACA,cACA,yBACA,CAxIA,UACA,KACA,MACA,iBACA,cACA,iBACA,QACC,QAED,IAKA,sDAJA,EASA,eAGA,2FAEA,uBAGA,CACA,GA4GA,CACA,iBACA,cACA,iBACA,MACA,QACA,IACA,CAAS,EAET,KAGA,qBACA,oBAEA,gBAGA,gBACA,iBACA,IACA,cACA,CAAU,SAGV,CACA,CAAO,EAGP,sBACA,gBACA,gBACA,6BAnmSA,MAomSA,6BAjmSA,MAkmSA,gBACA,iBACA,YACA,gBACA,gBACA,cACA,0BACA,gBACA,mBACA,2BACA,yBACA,wBACA,uBACA,4BACA,6BACA,0BACA,sBAEA,cACA,EAEA,oCAGA,2EAEA,GAAa,qCAAqC,GAAG,IAAgB,CADrE,EACqE,EAGrE,qBAA+B,OAAS,GACxC,yEAGA,uBACA,CAGA,qBACA,SACA,CAGA,sBACA,IACA,CAKA,iBACS,OAAS,oBAIlB,eACA,oBACA,CASA,QACA,cAGA,oBACA,CAMA,iBACA,cAIA,6BACA,CAMA,cACA,aAIA,mBAA+B,kDAAsD,EAHrF,iBAIA,CAUA,gBACA,aAKA,yBAKA,2CAJA,qBACA,mBANA,iBAUA,CAKA,cACA,0CAIA,kCACA,CAKA,eACA,eAIA,8CACA,kCACA,CAGA,UAEA,eA8BA,KACA,qBAEA,GACA,oBACA,kBACA,GAAO,QAAiB,KAGxB,EAAmC,OAAe,6BAClD,EAAmC,OAAe,6BAmBlD,OAjBA,kBACI,QAAc,MAElB,aACA,wGAEA,CAAK,EAGL,SACA,wBAGA,SACA,sBAGA,CACA,EA5DA,uBAEA,sBACA,UACA,wCACK,CACL,CAGA,yCAIA,IACA,6CAGA,MACA,MAGA,oCACA,CAAM,SAEN,CAEA,CACA,CAmCA,eACA,2CApCC","sources":["webpack://_N_E/./node_modules/@sentry-internal/replay/build/npm/esm/index.js?16c8"],"sourcesContent":["import { _nullishCoalesce, _optionalChain } from '@sentry/utils';\nimport { captureException, addBreadcrumb, getClient, isSentryRequestUrl, addEventProcessor, getCurrentScope, getActiveSpan, getDynamicSamplingContextFromSpan, prepareEvent, getIsolationScope, setContext, getRootSpan, spanToJSON, SEMANTIC_ATTRIBUTE_SENTRY_SOURCE, parseSampleRate } from '@sentry/core';\nimport { GLOBAL_OBJ, logger as logger$1, severityLevelFromString, normalize, fill, htmlTreeAsString, browserPerformanceTimeOrigin, uuid4, getLocationHref, dropUndefinedKeys, stringMatchesSomePattern, createEnvelope, createEventEnvelopeHeaders, getSdkMetadataForEnvelopeHeader, resolvedSyncPromise, updateRateLimits, isRateLimited, isBrowser, consoleSandbox } from '@sentry/utils';\nimport { setTimeout as setTimeout$3, addPerformanceInstrumentationHandler, addLcpInstrumentationHandler, addClsInstrumentationHandler, addFidInstrumentationHandler, addInpInstrumentationHandler, SENTRY_XHR_DATA_KEY, addClickKeypressInstrumentationHandler, addHistoryInstrumentationHandler } from '@sentry-internal/browser-utils';\n\n// exporting a separate copy of `WINDOW` rather than exporting the one from `@sentry/browser`\n// prevents the browser package from being bundled in the CDN bundle, and avoids a\n// circular dependency between the browser and replay packages should `@sentry/browser` import\n// from `@sentry/replay` in the future\nconst WINDOW = GLOBAL_OBJ ;\n\nconst REPLAY_SESSION_KEY = 'sentryReplaySession';\nconst REPLAY_EVENT_NAME = 'replay_event';\nconst UNABLE_TO_SEND_REPLAY = 'Unable to send Replay';\n\n// The idle limit for a session after which recording is paused.\nconst SESSION_IDLE_PAUSE_DURATION = 300000; // 5 minutes in ms\n\n// The idle limit for a session after which the session expires.\nconst SESSION_IDLE_EXPIRE_DURATION = 900000; // 15 minutes in ms\n\n/** Default flush delays */\nconst DEFAULT_FLUSH_MIN_DELAY = 5000;\n// XXX: Temp fix for our debounce logic where `maxWait` would never occur if it\n// was the same as `wait`\nconst DEFAULT_FLUSH_MAX_DELAY = 5500;\n\n/* How long to wait for error checkouts */\nconst BUFFER_CHECKOUT_TIME = 60000;\n\nconst RETRY_BASE_INTERVAL = 5000;\nconst RETRY_MAX_COUNT = 3;\n\n/* The max (uncompressed) size in bytes of a network body. Any body larger than this will be truncated. */\nconst NETWORK_BODY_MAX_SIZE = 150000;\n\n/* The max size of a single console arg that is captured. Any arg larger than this will be truncated. */\nconst CONSOLE_ARG_MAX_SIZE = 5000;\n\n/* Min. time to wait before we consider something a slow click. */\nconst SLOW_CLICK_THRESHOLD = 3000;\n/* For scroll actions after a click, we only look for a very short time period to detect programmatic scrolling. */\nconst SLOW_CLICK_SCROLL_TIMEOUT = 300;\n\n/** When encountering a total segment size exceeding this size, stop the replay (as we cannot properly ingest it). */\nconst REPLAY_MAX_EVENT_BUFFER_SIZE = 20000000; // ~20MB\n\n/** Replays must be min. 5s long before we send them. */\nconst MIN_REPLAY_DURATION = 4999;\n/* The max. allowed value that the minReplayDuration can be set to. */\nconst MIN_REPLAY_DURATION_LIMIT = 15000;\n\n/** The max. length of a replay. */\nconst MAX_REPLAY_DURATION = 3600000; // 60 minutes in ms;\n\nfunction _nullishCoalesce$1(lhs, rhsFn) { if (lhs != null) { return lhs; } else { return rhsFn(); } }function _optionalChain$5(ops) { let lastAccessLHS = undefined; let value = ops[0]; let i = 1; while (i < ops.length) { const op = ops[i]; const fn = ops[i + 1]; i += 2; if ((op === 'optionalAccess' || op === 'optionalCall') && value == null) { return undefined; } if (op === 'access' || op === 'optionalAccess') { lastAccessLHS = value; value = fn(value); } else if (op === 'call' || op === 'optionalCall') { value = fn((...args) => value.call(lastAccessLHS, ...args)); lastAccessLHS = undefined; } } return value; }var NodeType$1;\n(function (NodeType) {\n    NodeType[NodeType[\"Document\"] = 0] = \"Document\";\n    NodeType[NodeType[\"DocumentType\"] = 1] = \"DocumentType\";\n    NodeType[NodeType[\"Element\"] = 2] = \"Element\";\n    NodeType[NodeType[\"Text\"] = 3] = \"Text\";\n    NodeType[NodeType[\"CDATA\"] = 4] = \"CDATA\";\n    NodeType[NodeType[\"Comment\"] = 5] = \"Comment\";\n})(NodeType$1 || (NodeType$1 = {}));\n\nfunction isElement$1(n) {\n    return n.nodeType === n.ELEMENT_NODE;\n}\nfunction isShadowRoot(n) {\n    const host = _optionalChain$5([n, 'optionalAccess', _ => _.host]);\n    return Boolean(_optionalChain$5([host, 'optionalAccess', _2 => _2.shadowRoot]) === n);\n}\nfunction isNativeShadowDom(shadowRoot) {\n    return Object.prototype.toString.call(shadowRoot) === '[object ShadowRoot]';\n}\nfunction fixBrowserCompatibilityIssuesInCSS(cssText) {\n    if (cssText.includes(' background-clip: text;') &&\n        !cssText.includes(' -webkit-background-clip: text;')) {\n        cssText = cssText.replace(/\\sbackground-clip:\\s*text;/g, ' -webkit-background-clip: text; background-clip: text;');\n    }\n    return cssText;\n}\nfunction escapeImportStatement(rule) {\n    const { cssText } = rule;\n    if (cssText.split('\"').length < 3)\n        return cssText;\n    const statement = ['@import', `url(${JSON.stringify(rule.href)})`];\n    if (rule.layerName === '') {\n        statement.push(`layer`);\n    }\n    else if (rule.layerName) {\n        statement.push(`layer(${rule.layerName})`);\n    }\n    if (rule.supportsText) {\n        statement.push(`supports(${rule.supportsText})`);\n    }\n    if (rule.media.length) {\n        statement.push(rule.media.mediaText);\n    }\n    return statement.join(' ') + ';';\n}\nfunction stringifyStylesheet(s) {\n    try {\n        const rules = s.rules || s.cssRules;\n        return rules\n            ? fixBrowserCompatibilityIssuesInCSS(Array.from(rules, stringifyRule).join(''))\n            : null;\n    }\n    catch (error) {\n        return null;\n    }\n}\nfunction stringifyRule(rule) {\n    let importStringified;\n    if (isCSSImportRule(rule)) {\n        try {\n            importStringified =\n                stringifyStylesheet(rule.styleSheet) ||\n                    escapeImportStatement(rule);\n        }\n        catch (error) {\n        }\n    }\n    else if (isCSSStyleRule(rule) && rule.selectorText.includes(':')) {\n        return fixSafariColons(rule.cssText);\n    }\n    return importStringified || rule.cssText;\n}\nfunction fixSafariColons(cssStringified) {\n    const regex = /(\\[(?:[\\w-]+)[^\\\\])(:(?:[\\w-]+)\\])/gm;\n    return cssStringified.replace(regex, '$1\\\\$2');\n}\nfunction isCSSImportRule(rule) {\n    return 'styleSheet' in rule;\n}\nfunction isCSSStyleRule(rule) {\n    return 'selectorText' in rule;\n}\nclass Mirror {\n    constructor() {\n        this.idNodeMap = new Map();\n        this.nodeMetaMap = new WeakMap();\n    }\n    getId(n) {\n        if (!n)\n            return -1;\n        const id = _optionalChain$5([this, 'access', _3 => _3.getMeta, 'call', _4 => _4(n), 'optionalAccess', _5 => _5.id]);\n        return _nullishCoalesce$1(id, () => ( -1));\n    }\n    getNode(id) {\n        return this.idNodeMap.get(id) || null;\n    }\n    getIds() {\n        return Array.from(this.idNodeMap.keys());\n    }\n    getMeta(n) {\n        return this.nodeMetaMap.get(n) || null;\n    }\n    removeNodeFromMap(n) {\n        const id = this.getId(n);\n        this.idNodeMap.delete(id);\n        if (n.childNodes) {\n            n.childNodes.forEach((childNode) => this.removeNodeFromMap(childNode));\n        }\n    }\n    has(id) {\n        return this.idNodeMap.has(id);\n    }\n    hasNode(node) {\n        return this.nodeMetaMap.has(node);\n    }\n    add(n, meta) {\n        const id = meta.id;\n        this.idNodeMap.set(id, n);\n        this.nodeMetaMap.set(n, meta);\n    }\n    replace(id, n) {\n        const oldNode = this.getNode(id);\n        if (oldNode) {\n            const meta = this.nodeMetaMap.get(oldNode);\n            if (meta)\n                this.nodeMetaMap.set(n, meta);\n        }\n        this.idNodeMap.set(id, n);\n    }\n    reset() {\n        this.idNodeMap = new Map();\n        this.nodeMetaMap = new WeakMap();\n    }\n}\nfunction createMirror() {\n    return new Mirror();\n}\nfunction shouldMaskInput({ maskInputOptions, tagName, type, }) {\n    if (tagName === 'OPTION') {\n        tagName = 'SELECT';\n    }\n    return Boolean(maskInputOptions[tagName.toLowerCase()] ||\n        (type && maskInputOptions[type]) ||\n        type === 'password' ||\n        (tagName === 'INPUT' && !type && maskInputOptions['text']));\n}\nfunction maskInputValue({ isMasked, element, value, maskInputFn, }) {\n    let text = value || '';\n    if (!isMasked) {\n        return text;\n    }\n    if (maskInputFn) {\n        text = maskInputFn(text, element);\n    }\n    return '*'.repeat(text.length);\n}\nfunction toLowerCase(str) {\n    return str.toLowerCase();\n}\nfunction toUpperCase(str) {\n    return str.toUpperCase();\n}\nconst ORIGINAL_ATTRIBUTE_NAME = '__rrweb_original__';\nfunction is2DCanvasBlank(canvas) {\n    const ctx = canvas.getContext('2d');\n    if (!ctx)\n        return true;\n    const chunkSize = 50;\n    for (let x = 0; x < canvas.width; x += chunkSize) {\n        for (let y = 0; y < canvas.height; y += chunkSize) {\n            const getImageData = ctx.getImageData;\n            const originalGetImageData = ORIGINAL_ATTRIBUTE_NAME in getImageData\n                ? getImageData[ORIGINAL_ATTRIBUTE_NAME]\n                : getImageData;\n            const pixelBuffer = new Uint32Array(originalGetImageData.call(ctx, x, y, Math.min(chunkSize, canvas.width - x), Math.min(chunkSize, canvas.height - y)).data.buffer);\n            if (pixelBuffer.some((pixel) => pixel !== 0))\n                return false;\n        }\n    }\n    return true;\n}\nfunction getInputType(element) {\n    const type = element.type;\n    return element.hasAttribute('data-rr-is-password')\n        ? 'password'\n        : type\n            ?\n                toLowerCase(type)\n            : null;\n}\nfunction getInputValue(el, tagName, type) {\n    if (tagName === 'INPUT' && (type === 'radio' || type === 'checkbox')) {\n        return el.getAttribute('value') || '';\n    }\n    return el.value;\n}\nfunction extractFileExtension(path, baseURL) {\n    let url;\n    try {\n        url = new URL(path, _nullishCoalesce$1(baseURL, () => ( window.location.href)));\n    }\n    catch (err) {\n        return null;\n    }\n    const regex = /\\.([0-9a-z]+)(?:$)/i;\n    const match = url.pathname.match(regex);\n    return _nullishCoalesce$1(_optionalChain$5([match, 'optionalAccess', _6 => _6[1]]), () => ( null));\n}\nconst cachedImplementations$1 = {};\nfunction getImplementation$1(name) {\n    const cached = cachedImplementations$1[name];\n    if (cached) {\n        return cached;\n    }\n    const document = window.document;\n    let impl = window[name];\n    if (document && typeof document.createElement === 'function') {\n        try {\n            const sandbox = document.createElement('iframe');\n            sandbox.hidden = true;\n            document.head.appendChild(sandbox);\n            const contentWindow = sandbox.contentWindow;\n            if (contentWindow && contentWindow[name]) {\n                impl =\n                    contentWindow[name];\n            }\n            document.head.removeChild(sandbox);\n        }\n        catch (e) {\n        }\n    }\n    return (cachedImplementations$1[name] = impl.bind(window));\n}\nfunction setTimeout$2(...rest) {\n    return getImplementation$1('setTimeout')(...rest);\n}\nfunction clearTimeout$2(...rest) {\n    return getImplementation$1('clearTimeout')(...rest);\n}\n\nlet _id = 1;\nconst tagNameRegex = new RegExp('[^a-z0-9-_:]');\nconst IGNORED_NODE = -2;\nfunction genId() {\n    return _id++;\n}\nfunction getValidTagName(element) {\n    if (element instanceof HTMLFormElement) {\n        return 'form';\n    }\n    const processedTagName = toLowerCase(element.tagName);\n    if (tagNameRegex.test(processedTagName)) {\n        return 'div';\n    }\n    return processedTagName;\n}\nfunction extractOrigin(url) {\n    let origin = '';\n    if (url.indexOf('//') > -1) {\n        origin = url.split('/').slice(0, 3).join('/');\n    }\n    else {\n        origin = url.split('/')[0];\n    }\n    origin = origin.split('?')[0];\n    return origin;\n}\nlet canvasService;\nlet canvasCtx;\nconst URL_IN_CSS_REF = /url\\((?:(')([^']*)'|(\")(.*?)\"|([^)]*))\\)/gm;\nconst URL_PROTOCOL_MATCH = /^(?:[a-z+]+:)?\\/\\//i;\nconst URL_WWW_MATCH = /^www\\..*/i;\nconst DATA_URI = /^(data:)([^,]*),(.*)/i;\nfunction absoluteToStylesheet(cssText, href) {\n    return (cssText || '').replace(URL_IN_CSS_REF, (origin, quote1, path1, quote2, path2, path3) => {\n        const filePath = path1 || path2 || path3;\n        const maybeQuote = quote1 || quote2 || '';\n        if (!filePath) {\n            return origin;\n        }\n        if (URL_PROTOCOL_MATCH.test(filePath) || URL_WWW_MATCH.test(filePath)) {\n            return `url(${maybeQuote}${filePath}${maybeQuote})`;\n        }\n        if (DATA_URI.test(filePath)) {\n            return `url(${maybeQuote}${filePath}${maybeQuote})`;\n        }\n        if (filePath[0] === '/') {\n            return `url(${maybeQuote}${extractOrigin(href) + filePath}${maybeQuote})`;\n        }\n        const stack = href.split('/');\n        const parts = filePath.split('/');\n        stack.pop();\n        for (const part of parts) {\n            if (part === '.') {\n                continue;\n            }\n            else if (part === '..') {\n                stack.pop();\n            }\n            else {\n                stack.push(part);\n            }\n        }\n        return `url(${maybeQuote}${stack.join('/')}${maybeQuote})`;\n    });\n}\nconst SRCSET_NOT_SPACES = /^[^ \\t\\n\\r\\u000c]+/;\nconst SRCSET_COMMAS_OR_SPACES = /^[, \\t\\n\\r\\u000c]+/;\nfunction getAbsoluteSrcsetString(doc, attributeValue) {\n    if (attributeValue.trim() === '') {\n        return attributeValue;\n    }\n    let pos = 0;\n    function collectCharacters(regEx) {\n        let chars;\n        const match = regEx.exec(attributeValue.substring(pos));\n        if (match) {\n            chars = match[0];\n            pos += chars.length;\n            return chars;\n        }\n        return '';\n    }\n    const output = [];\n    while (true) {\n        collectCharacters(SRCSET_COMMAS_OR_SPACES);\n        if (pos >= attributeValue.length) {\n            break;\n        }\n        let url = collectCharacters(SRCSET_NOT_SPACES);\n        if (url.slice(-1) === ',') {\n            url = absoluteToDoc(doc, url.substring(0, url.length - 1));\n            output.push(url);\n        }\n        else {\n            let descriptorsStr = '';\n            url = absoluteToDoc(doc, url);\n            let inParens = false;\n            while (true) {\n                const c = attributeValue.charAt(pos);\n                if (c === '') {\n                    output.push((url + descriptorsStr).trim());\n                    break;\n                }\n                else if (!inParens) {\n                    if (c === ',') {\n                        pos += 1;\n                        output.push((url + descriptorsStr).trim());\n                        break;\n                    }\n                    else if (c === '(') {\n                        inParens = true;\n                    }\n                }\n                else {\n                    if (c === ')') {\n                        inParens = false;\n                    }\n                }\n                descriptorsStr += c;\n                pos += 1;\n            }\n        }\n    }\n    return output.join(', ');\n}\nconst cachedDocument = new WeakMap();\nfunction absoluteToDoc(doc, attributeValue) {\n    if (!attributeValue || attributeValue.trim() === '') {\n        return attributeValue;\n    }\n    return getHref(doc, attributeValue);\n}\nfunction isSVGElement(el) {\n    return Boolean(el.tagName === 'svg' || el.ownerSVGElement);\n}\nfunction getHref(doc, customHref) {\n    let a = cachedDocument.get(doc);\n    if (!a) {\n        a = doc.createElement('a');\n        cachedDocument.set(doc, a);\n    }\n    if (!customHref) {\n        customHref = '';\n    }\n    else if (customHref.startsWith('blob:') || customHref.startsWith('data:')) {\n        return customHref;\n    }\n    a.setAttribute('href', customHref);\n    return a.href;\n}\nfunction transformAttribute(doc, tagName, name, value, element, maskAttributeFn) {\n    if (!value) {\n        return value;\n    }\n    if (name === 'src' ||\n        (name === 'href' && !(tagName === 'use' && value[0] === '#'))) {\n        return absoluteToDoc(doc, value);\n    }\n    else if (name === 'xlink:href' && value[0] !== '#') {\n        return absoluteToDoc(doc, value);\n    }\n    else if (name === 'background' &&\n        (tagName === 'table' || tagName === 'td' || tagName === 'th')) {\n        return absoluteToDoc(doc, value);\n    }\n    else if (name === 'srcset') {\n        return getAbsoluteSrcsetString(doc, value);\n    }\n    else if (name === 'style') {\n        return absoluteToStylesheet(value, getHref(doc));\n    }\n    else if (tagName === 'object' && name === 'data') {\n        return absoluteToDoc(doc, value);\n    }\n    if (typeof maskAttributeFn === 'function') {\n        return maskAttributeFn(name, value, element);\n    }\n    return value;\n}\nfunction ignoreAttribute(tagName, name, _value) {\n    return (tagName === 'video' || tagName === 'audio') && name === 'autoplay';\n}\nfunction _isBlockedElement(element, blockClass, blockSelector, unblockSelector) {\n    try {\n        if (unblockSelector && element.matches(unblockSelector)) {\n            return false;\n        }\n        if (typeof blockClass === 'string') {\n            if (element.classList.contains(blockClass)) {\n                return true;\n            }\n        }\n        else {\n            for (let eIndex = element.classList.length; eIndex--;) {\n                const className = element.classList[eIndex];\n                if (blockClass.test(className)) {\n                    return true;\n                }\n            }\n        }\n        if (blockSelector) {\n            return element.matches(blockSelector);\n        }\n    }\n    catch (e) {\n    }\n    return false;\n}\nfunction elementClassMatchesRegex(el, regex) {\n    for (let eIndex = el.classList.length; eIndex--;) {\n        const className = el.classList[eIndex];\n        if (regex.test(className)) {\n            return true;\n        }\n    }\n    return false;\n}\nfunction distanceToMatch(node, matchPredicate, limit = Infinity, distance = 0) {\n    if (!node)\n        return -1;\n    if (node.nodeType !== node.ELEMENT_NODE)\n        return -1;\n    if (distance > limit)\n        return -1;\n    if (matchPredicate(node))\n        return distance;\n    return distanceToMatch(node.parentNode, matchPredicate, limit, distance + 1);\n}\nfunction createMatchPredicate(className, selector) {\n    return (node) => {\n        const el = node;\n        if (el === null)\n            return false;\n        try {\n            if (className) {\n                if (typeof className === 'string') {\n                    if (el.matches(`.${className}`))\n                        return true;\n                }\n                else if (elementClassMatchesRegex(el, className)) {\n                    return true;\n                }\n            }\n            if (selector && el.matches(selector))\n                return true;\n            return false;\n        }\n        catch (e2) {\n            return false;\n        }\n    };\n}\nfunction needMaskingText(node, maskTextClass, maskTextSelector, unmaskTextClass, unmaskTextSelector, maskAllText) {\n    try {\n        const el = node.nodeType === node.ELEMENT_NODE\n            ? node\n            : node.parentElement;\n        if (el === null)\n            return false;\n        if (el.tagName === 'INPUT') {\n            const autocomplete = el.getAttribute('autocomplete');\n            const disallowedAutocompleteValues = [\n                'current-password',\n                'new-password',\n                'cc-number',\n                'cc-exp',\n                'cc-exp-month',\n                'cc-exp-year',\n                'cc-csc',\n            ];\n            if (disallowedAutocompleteValues.includes(autocomplete)) {\n                return true;\n            }\n        }\n        let maskDistance = -1;\n        let unmaskDistance = -1;\n        if (maskAllText) {\n            unmaskDistance = distanceToMatch(el, createMatchPredicate(unmaskTextClass, unmaskTextSelector));\n            if (unmaskDistance < 0) {\n                return true;\n            }\n            maskDistance = distanceToMatch(el, createMatchPredicate(maskTextClass, maskTextSelector), unmaskDistance >= 0 ? unmaskDistance : Infinity);\n        }\n        else {\n            maskDistance = distanceToMatch(el, createMatchPredicate(maskTextClass, maskTextSelector));\n            if (maskDistance < 0) {\n                return false;\n            }\n            unmaskDistance = distanceToMatch(el, createMatchPredicate(unmaskTextClass, unmaskTextSelector), maskDistance >= 0 ? maskDistance : Infinity);\n        }\n        return maskDistance >= 0\n            ? unmaskDistance >= 0\n                ? maskDistance <= unmaskDistance\n                : true\n            : unmaskDistance >= 0\n                ? false\n                : !!maskAllText;\n    }\n    catch (e) {\n    }\n    return !!maskAllText;\n}\nfunction onceIframeLoaded(iframeEl, listener, iframeLoadTimeout) {\n    const win = iframeEl.contentWindow;\n    if (!win) {\n        return;\n    }\n    let fired = false;\n    let readyState;\n    try {\n        readyState = win.document.readyState;\n    }\n    catch (error) {\n        return;\n    }\n    if (readyState !== 'complete') {\n        const timer = setTimeout$2(() => {\n            if (!fired) {\n                listener();\n                fired = true;\n            }\n        }, iframeLoadTimeout);\n        iframeEl.addEventListener('load', () => {\n            clearTimeout$2(timer);\n            fired = true;\n            listener();\n        });\n        return;\n    }\n    const blankUrl = 'about:blank';\n    if (win.location.href !== blankUrl ||\n        iframeEl.src === blankUrl ||\n        iframeEl.src === '') {\n        setTimeout$2(listener, 0);\n        return iframeEl.addEventListener('load', listener);\n    }\n    iframeEl.addEventListener('load', listener);\n}\nfunction onceStylesheetLoaded(link, listener, styleSheetLoadTimeout) {\n    let fired = false;\n    let styleSheetLoaded;\n    try {\n        styleSheetLoaded = link.sheet;\n    }\n    catch (error) {\n        return;\n    }\n    if (styleSheetLoaded)\n        return;\n    const timer = setTimeout$2(() => {\n        if (!fired) {\n            listener();\n            fired = true;\n        }\n    }, styleSheetLoadTimeout);\n    link.addEventListener('load', () => {\n        clearTimeout$2(timer);\n        fired = true;\n        listener();\n    });\n}\nfunction serializeNode(n, options) {\n    const { doc, mirror, blockClass, blockSelector, unblockSelector, maskAllText, maskAttributeFn, maskTextClass, unmaskTextClass, maskTextSelector, unmaskTextSelector, inlineStylesheet, maskInputOptions = {}, maskTextFn, maskInputFn, dataURLOptions = {}, inlineImages, recordCanvas, keepIframeSrcFn, newlyAddedElement = false, } = options;\n    const rootId = getRootId(doc, mirror);\n    switch (n.nodeType) {\n        case n.DOCUMENT_NODE:\n            if (n.compatMode !== 'CSS1Compat') {\n                return {\n                    type: NodeType$1.Document,\n                    childNodes: [],\n                    compatMode: n.compatMode,\n                };\n            }\n            else {\n                return {\n                    type: NodeType$1.Document,\n                    childNodes: [],\n                };\n            }\n        case n.DOCUMENT_TYPE_NODE:\n            return {\n                type: NodeType$1.DocumentType,\n                name: n.name,\n                publicId: n.publicId,\n                systemId: n.systemId,\n                rootId,\n            };\n        case n.ELEMENT_NODE:\n            return serializeElementNode(n, {\n                doc,\n                blockClass,\n                blockSelector,\n                unblockSelector,\n                inlineStylesheet,\n                maskAttributeFn,\n                maskInputOptions,\n                maskInputFn,\n                dataURLOptions,\n                inlineImages,\n                recordCanvas,\n                keepIframeSrcFn,\n                newlyAddedElement,\n                rootId,\n                maskAllText,\n                maskTextClass,\n                unmaskTextClass,\n                maskTextSelector,\n                unmaskTextSelector,\n            });\n        case n.TEXT_NODE:\n            return serializeTextNode(n, {\n                doc,\n                maskAllText,\n                maskTextClass,\n                unmaskTextClass,\n                maskTextSelector,\n                unmaskTextSelector,\n                maskTextFn,\n                maskInputOptions,\n                maskInputFn,\n                rootId,\n            });\n        case n.CDATA_SECTION_NODE:\n            return {\n                type: NodeType$1.CDATA,\n                textContent: '',\n                rootId,\n            };\n        case n.COMMENT_NODE:\n            return {\n                type: NodeType$1.Comment,\n                textContent: n.textContent || '',\n                rootId,\n            };\n        default:\n            return false;\n    }\n}\nfunction getRootId(doc, mirror) {\n    if (!mirror.hasNode(doc))\n        return undefined;\n    const docId = mirror.getId(doc);\n    return docId === 1 ? undefined : docId;\n}\nfunction serializeTextNode(n, options) {\n    const { maskAllText, maskTextClass, unmaskTextClass, maskTextSelector, unmaskTextSelector, maskTextFn, maskInputOptions, maskInputFn, rootId, } = options;\n    const parentTagName = n.parentNode && n.parentNode.tagName;\n    let textContent = n.textContent;\n    const isStyle = parentTagName === 'STYLE' ? true : undefined;\n    const isScript = parentTagName === 'SCRIPT' ? true : undefined;\n    const isTextarea = parentTagName === 'TEXTAREA' ? true : undefined;\n    if (isStyle && textContent) {\n        try {\n            if (n.nextSibling || n.previousSibling) {\n            }\n            else if (_optionalChain$5([n, 'access', _7 => _7.parentNode, 'access', _8 => _8.sheet, 'optionalAccess', _9 => _9.cssRules])) {\n                textContent = stringifyStylesheet(n.parentNode.sheet);\n            }\n        }\n        catch (err) {\n            console.warn(`Cannot get CSS styles from text's parentNode. Error: ${err}`, n);\n        }\n        textContent = absoluteToStylesheet(textContent, getHref(options.doc));\n    }\n    if (isScript) {\n        textContent = 'SCRIPT_PLACEHOLDER';\n    }\n    const forceMask = needMaskingText(n, maskTextClass, maskTextSelector, unmaskTextClass, unmaskTextSelector, maskAllText);\n    if (!isStyle && !isScript && !isTextarea && textContent && forceMask) {\n        textContent = maskTextFn\n            ? maskTextFn(textContent, n.parentElement)\n            : textContent.replace(/[\\S]/g, '*');\n    }\n    if (isTextarea && textContent && (maskInputOptions.textarea || forceMask)) {\n        textContent = maskInputFn\n            ? maskInputFn(textContent, n.parentNode)\n            : textContent.replace(/[\\S]/g, '*');\n    }\n    if (parentTagName === 'OPTION' && textContent) {\n        const isInputMasked = shouldMaskInput({\n            type: null,\n            tagName: parentTagName,\n            maskInputOptions,\n        });\n        textContent = maskInputValue({\n            isMasked: needMaskingText(n, maskTextClass, maskTextSelector, unmaskTextClass, unmaskTextSelector, isInputMasked),\n            element: n,\n            value: textContent,\n            maskInputFn,\n        });\n    }\n    return {\n        type: NodeType$1.Text,\n        textContent: textContent || '',\n        isStyle,\n        rootId,\n    };\n}\nfunction serializeElementNode(n, options) {\n    const { doc, blockClass, blockSelector, unblockSelector, inlineStylesheet, maskInputOptions = {}, maskAttributeFn, maskInputFn, dataURLOptions = {}, inlineImages, recordCanvas, keepIframeSrcFn, newlyAddedElement = false, rootId, maskAllText, maskTextClass, unmaskTextClass, maskTextSelector, unmaskTextSelector, } = options;\n    const needBlock = _isBlockedElement(n, blockClass, blockSelector, unblockSelector);\n    const tagName = getValidTagName(n);\n    let attributes = {};\n    const len = n.attributes.length;\n    for (let i = 0; i < len; i++) {\n        const attr = n.attributes[i];\n        if (attr.name && !ignoreAttribute(tagName, attr.name, attr.value)) {\n            attributes[attr.name] = transformAttribute(doc, tagName, toLowerCase(attr.name), attr.value, n, maskAttributeFn);\n        }\n    }\n    if (tagName === 'link' && inlineStylesheet) {\n        const stylesheet = Array.from(doc.styleSheets).find((s) => {\n            return s.href === n.href;\n        });\n        let cssText = null;\n        if (stylesheet) {\n            cssText = stringifyStylesheet(stylesheet);\n        }\n        if (cssText) {\n            delete attributes.rel;\n            delete attributes.href;\n            attributes._cssText = absoluteToStylesheet(cssText, stylesheet.href);\n        }\n    }\n    if (tagName === 'style' &&\n        n.sheet &&\n        !(n.innerText || n.textContent || '').trim().length) {\n        const cssText = stringifyStylesheet(n.sheet);\n        if (cssText) {\n            attributes._cssText = absoluteToStylesheet(cssText, getHref(doc));\n        }\n    }\n    if (tagName === 'input' ||\n        tagName === 'textarea' ||\n        tagName === 'select' ||\n        tagName === 'option') {\n        const el = n;\n        const type = getInputType(el);\n        const value = getInputValue(el, toUpperCase(tagName), type);\n        const checked = el.checked;\n        if (type !== 'submit' && type !== 'button' && value) {\n            const forceMask = needMaskingText(el, maskTextClass, maskTextSelector, unmaskTextClass, unmaskTextSelector, shouldMaskInput({\n                type,\n                tagName: toUpperCase(tagName),\n                maskInputOptions,\n            }));\n            attributes.value = maskInputValue({\n                isMasked: forceMask,\n                element: el,\n                value,\n                maskInputFn,\n            });\n        }\n        if (checked) {\n            attributes.checked = checked;\n        }\n    }\n    if (tagName === 'option') {\n        if (n.selected && !maskInputOptions['select']) {\n            attributes.selected = true;\n        }\n        else {\n            delete attributes.selected;\n        }\n    }\n    if (tagName === 'canvas' && recordCanvas) {\n        if (n.__context === '2d') {\n            if (!is2DCanvasBlank(n)) {\n                attributes.rr_dataURL = n.toDataURL(dataURLOptions.type, dataURLOptions.quality);\n            }\n        }\n        else if (!('__context' in n)) {\n            const canvasDataURL = n.toDataURL(dataURLOptions.type, dataURLOptions.quality);\n            const blankCanvas = doc.createElement('canvas');\n            blankCanvas.width = n.width;\n            blankCanvas.height = n.height;\n            const blankCanvasDataURL = blankCanvas.toDataURL(dataURLOptions.type, dataURLOptions.quality);\n            if (canvasDataURL !== blankCanvasDataURL) {\n                attributes.rr_dataURL = canvasDataURL;\n            }\n        }\n    }\n    if (tagName === 'img' && inlineImages) {\n        if (!canvasService) {\n            canvasService = doc.createElement('canvas');\n            canvasCtx = canvasService.getContext('2d');\n        }\n        const image = n;\n        const imageSrc = image.currentSrc || image.getAttribute('src') || '<unknown-src>';\n        const priorCrossOrigin = image.crossOrigin;\n        const recordInlineImage = () => {\n            image.removeEventListener('load', recordInlineImage);\n            try {\n                canvasService.width = image.naturalWidth;\n                canvasService.height = image.naturalHeight;\n                canvasCtx.drawImage(image, 0, 0);\n                attributes.rr_dataURL = canvasService.toDataURL(dataURLOptions.type, dataURLOptions.quality);\n            }\n            catch (err) {\n                if (image.crossOrigin !== 'anonymous') {\n                    image.crossOrigin = 'anonymous';\n                    if (image.complete && image.naturalWidth !== 0)\n                        recordInlineImage();\n                    else\n                        image.addEventListener('load', recordInlineImage);\n                    return;\n                }\n                else {\n                    console.warn(`Cannot inline img src=${imageSrc}! Error: ${err}`);\n                }\n            }\n            if (image.crossOrigin === 'anonymous') {\n                priorCrossOrigin\n                    ? (attributes.crossOrigin = priorCrossOrigin)\n                    : image.removeAttribute('crossorigin');\n            }\n        };\n        if (image.complete && image.naturalWidth !== 0)\n            recordInlineImage();\n        else\n            image.addEventListener('load', recordInlineImage);\n    }\n    if (tagName === 'audio' || tagName === 'video') {\n        attributes.rr_mediaState = n.paused\n            ? 'paused'\n            : 'played';\n        attributes.rr_mediaCurrentTime = n.currentTime;\n    }\n    if (!newlyAddedElement) {\n        if (n.scrollLeft) {\n            attributes.rr_scrollLeft = n.scrollLeft;\n        }\n        if (n.scrollTop) {\n            attributes.rr_scrollTop = n.scrollTop;\n        }\n    }\n    if (needBlock) {\n        const { width, height } = n.getBoundingClientRect();\n        attributes = {\n            class: attributes.class,\n            rr_width: `${width}px`,\n            rr_height: `${height}px`,\n        };\n    }\n    if (tagName === 'iframe' && !keepIframeSrcFn(attributes.src)) {\n        if (!needBlock && !n.contentDocument) {\n            attributes.rr_src = attributes.src;\n        }\n        delete attributes.src;\n    }\n    let isCustomElement;\n    try {\n        if (customElements.get(tagName))\n            isCustomElement = true;\n    }\n    catch (e) {\n    }\n    return {\n        type: NodeType$1.Element,\n        tagName,\n        attributes,\n        childNodes: [],\n        isSVG: isSVGElement(n) || undefined,\n        needBlock,\n        rootId,\n        isCustom: isCustomElement,\n    };\n}\nfunction lowerIfExists(maybeAttr) {\n    if (maybeAttr === undefined || maybeAttr === null) {\n        return '';\n    }\n    else {\n        return maybeAttr.toLowerCase();\n    }\n}\nfunction slimDOMExcluded(sn, slimDOMOptions) {\n    if (slimDOMOptions.comment && sn.type === NodeType$1.Comment) {\n        return true;\n    }\n    else if (sn.type === NodeType$1.Element) {\n        if (slimDOMOptions.script &&\n            (sn.tagName === 'script' ||\n                (sn.tagName === 'link' &&\n                    (sn.attributes.rel === 'preload' ||\n                        sn.attributes.rel === 'modulepreload') &&\n                    sn.attributes.as === 'script') ||\n                (sn.tagName === 'link' &&\n                    sn.attributes.rel === 'prefetch' &&\n                    typeof sn.attributes.href === 'string' &&\n                    extractFileExtension(sn.attributes.href) === 'js'))) {\n            return true;\n        }\n        else if (slimDOMOptions.headFavicon &&\n            ((sn.tagName === 'link' && sn.attributes.rel === 'shortcut icon') ||\n                (sn.tagName === 'meta' &&\n                    (lowerIfExists(sn.attributes.name).match(/^msapplication-tile(image|color)$/) ||\n                        lowerIfExists(sn.attributes.name) === 'application-name' ||\n                        lowerIfExists(sn.attributes.rel) === 'icon' ||\n                        lowerIfExists(sn.attributes.rel) === 'apple-touch-icon' ||\n                        lowerIfExists(sn.attributes.rel) === 'shortcut icon')))) {\n            return true;\n        }\n        else if (sn.tagName === 'meta') {\n            if (slimDOMOptions.headMetaDescKeywords &&\n                lowerIfExists(sn.attributes.name).match(/^description|keywords$/)) {\n                return true;\n            }\n            else if (slimDOMOptions.headMetaSocial &&\n                (lowerIfExists(sn.attributes.property).match(/^(og|twitter|fb):/) ||\n                    lowerIfExists(sn.attributes.name).match(/^(og|twitter):/) ||\n                    lowerIfExists(sn.attributes.name) === 'pinterest')) {\n                return true;\n            }\n            else if (slimDOMOptions.headMetaRobots &&\n                (lowerIfExists(sn.attributes.name) === 'robots' ||\n                    lowerIfExists(sn.attributes.name) === 'googlebot' ||\n                    lowerIfExists(sn.attributes.name) === 'bingbot')) {\n                return true;\n            }\n            else if (slimDOMOptions.headMetaHttpEquiv &&\n                sn.attributes['http-equiv'] !== undefined) {\n                return true;\n            }\n            else if (slimDOMOptions.headMetaAuthorship &&\n                (lowerIfExists(sn.attributes.name) === 'author' ||\n                    lowerIfExists(sn.attributes.name) === 'generator' ||\n                    lowerIfExists(sn.attributes.name) === 'framework' ||\n                    lowerIfExists(sn.attributes.name) === 'publisher' ||\n                    lowerIfExists(sn.attributes.name) === 'progid' ||\n                    lowerIfExists(sn.attributes.property).match(/^article:/) ||\n                    lowerIfExists(sn.attributes.property).match(/^product:/))) {\n                return true;\n            }\n            else if (slimDOMOptions.headMetaVerification &&\n                (lowerIfExists(sn.attributes.name) === 'google-site-verification' ||\n                    lowerIfExists(sn.attributes.name) === 'yandex-verification' ||\n                    lowerIfExists(sn.attributes.name) === 'csrf-token' ||\n                    lowerIfExists(sn.attributes.name) === 'p:domain_verify' ||\n                    lowerIfExists(sn.attributes.name) === 'verify-v1' ||\n                    lowerIfExists(sn.attributes.name) === 'verification' ||\n                    lowerIfExists(sn.attributes.name) === 'shopify-checkout-api-token')) {\n                return true;\n            }\n        }\n    }\n    return false;\n}\nfunction serializeNodeWithId(n, options) {\n    const { doc, mirror, blockClass, blockSelector, unblockSelector, maskAllText, maskTextClass, unmaskTextClass, maskTextSelector, unmaskTextSelector, skipChild = false, inlineStylesheet = true, maskInputOptions = {}, maskAttributeFn, maskTextFn, maskInputFn, slimDOMOptions, dataURLOptions = {}, inlineImages = false, recordCanvas = false, onSerialize, onIframeLoad, iframeLoadTimeout = 5000, onStylesheetLoad, stylesheetLoadTimeout = 5000, keepIframeSrcFn = () => false, newlyAddedElement = false, } = options;\n    let { preserveWhiteSpace = true } = options;\n    const _serializedNode = serializeNode(n, {\n        doc,\n        mirror,\n        blockClass,\n        blockSelector,\n        maskAllText,\n        unblockSelector,\n        maskTextClass,\n        unmaskTextClass,\n        maskTextSelector,\n        unmaskTextSelector,\n        inlineStylesheet,\n        maskInputOptions,\n        maskAttributeFn,\n        maskTextFn,\n        maskInputFn,\n        dataURLOptions,\n        inlineImages,\n        recordCanvas,\n        keepIframeSrcFn,\n        newlyAddedElement,\n    });\n    if (!_serializedNode) {\n        console.warn(n, 'not serialized');\n        return null;\n    }\n    let id;\n    if (mirror.hasNode(n)) {\n        id = mirror.getId(n);\n    }\n    else if (slimDOMExcluded(_serializedNode, slimDOMOptions) ||\n        (!preserveWhiteSpace &&\n            _serializedNode.type === NodeType$1.Text &&\n            !_serializedNode.isStyle &&\n            !_serializedNode.textContent.replace(/^\\s+|\\s+$/gm, '').length)) {\n        id = IGNORED_NODE;\n    }\n    else {\n        id = genId();\n    }\n    const serializedNode = Object.assign(_serializedNode, { id });\n    mirror.add(n, serializedNode);\n    if (id === IGNORED_NODE) {\n        return null;\n    }\n    if (onSerialize) {\n        onSerialize(n);\n    }\n    let recordChild = !skipChild;\n    if (serializedNode.type === NodeType$1.Element) {\n        recordChild = recordChild && !serializedNode.needBlock;\n        delete serializedNode.needBlock;\n        const shadowRoot = n.shadowRoot;\n        if (shadowRoot && isNativeShadowDom(shadowRoot))\n            serializedNode.isShadowHost = true;\n    }\n    if ((serializedNode.type === NodeType$1.Document ||\n        serializedNode.type === NodeType$1.Element) &&\n        recordChild) {\n        if (slimDOMOptions.headWhitespace &&\n            serializedNode.type === NodeType$1.Element &&\n            serializedNode.tagName === 'head') {\n            preserveWhiteSpace = false;\n        }\n        const bypassOptions = {\n            doc,\n            mirror,\n            blockClass,\n            blockSelector,\n            maskAllText,\n            unblockSelector,\n            maskTextClass,\n            unmaskTextClass,\n            maskTextSelector,\n            unmaskTextSelector,\n            skipChild,\n            inlineStylesheet,\n            maskInputOptions,\n            maskAttributeFn,\n            maskTextFn,\n            maskInputFn,\n            slimDOMOptions,\n            dataURLOptions,\n            inlineImages,\n            recordCanvas,\n            preserveWhiteSpace,\n            onSerialize,\n            onIframeLoad,\n            iframeLoadTimeout,\n            onStylesheetLoad,\n            stylesheetLoadTimeout,\n            keepIframeSrcFn,\n        };\n        for (const childN of Array.from(n.childNodes)) {\n            const serializedChildNode = serializeNodeWithId(childN, bypassOptions);\n            if (serializedChildNode) {\n                serializedNode.childNodes.push(serializedChildNode);\n            }\n        }\n        if (isElement$1(n) && n.shadowRoot) {\n            for (const childN of Array.from(n.shadowRoot.childNodes)) {\n                const serializedChildNode = serializeNodeWithId(childN, bypassOptions);\n                if (serializedChildNode) {\n                    isNativeShadowDom(n.shadowRoot) &&\n                        (serializedChildNode.isShadow = true);\n                    serializedNode.childNodes.push(serializedChildNode);\n                }\n            }\n        }\n    }\n    if (n.parentNode &&\n        isShadowRoot(n.parentNode) &&\n        isNativeShadowDom(n.parentNode)) {\n        serializedNode.isShadow = true;\n    }\n    if (serializedNode.type === NodeType$1.Element &&\n        serializedNode.tagName === 'iframe') {\n        onceIframeLoaded(n, () => {\n            const iframeDoc = n.contentDocument;\n            if (iframeDoc && onIframeLoad) {\n                const serializedIframeNode = serializeNodeWithId(iframeDoc, {\n                    doc: iframeDoc,\n                    mirror,\n                    blockClass,\n                    blockSelector,\n                    unblockSelector,\n                    maskAllText,\n                    maskTextClass,\n                    unmaskTextClass,\n                    maskTextSelector,\n                    unmaskTextSelector,\n                    skipChild: false,\n                    inlineStylesheet,\n                    maskInputOptions,\n                    maskAttributeFn,\n                    maskTextFn,\n                    maskInputFn,\n                    slimDOMOptions,\n                    dataURLOptions,\n                    inlineImages,\n                    recordCanvas,\n                    preserveWhiteSpace,\n                    onSerialize,\n                    onIframeLoad,\n                    iframeLoadTimeout,\n                    onStylesheetLoad,\n                    stylesheetLoadTimeout,\n                    keepIframeSrcFn,\n                });\n                if (serializedIframeNode) {\n                    onIframeLoad(n, serializedIframeNode);\n                }\n            }\n        }, iframeLoadTimeout);\n    }\n    if (serializedNode.type === NodeType$1.Element &&\n        serializedNode.tagName === 'link' &&\n        typeof serializedNode.attributes.rel === 'string' &&\n        (serializedNode.attributes.rel === 'stylesheet' ||\n            (serializedNode.attributes.rel === 'preload' &&\n                typeof serializedNode.attributes.href === 'string' &&\n                extractFileExtension(serializedNode.attributes.href) === 'css'))) {\n        onceStylesheetLoaded(n, () => {\n            if (onStylesheetLoad) {\n                const serializedLinkNode = serializeNodeWithId(n, {\n                    doc,\n                    mirror,\n                    blockClass,\n                    blockSelector,\n                    unblockSelector,\n                    maskAllText,\n                    maskTextClass,\n                    unmaskTextClass,\n                    maskTextSelector,\n                    unmaskTextSelector,\n                    skipChild: false,\n                    inlineStylesheet,\n                    maskInputOptions,\n                    maskAttributeFn,\n                    maskTextFn,\n                    maskInputFn,\n                    slimDOMOptions,\n                    dataURLOptions,\n                    inlineImages,\n                    recordCanvas,\n                    preserveWhiteSpace,\n                    onSerialize,\n                    onIframeLoad,\n                    iframeLoadTimeout,\n                    onStylesheetLoad,\n                    stylesheetLoadTimeout,\n                    keepIframeSrcFn,\n                });\n                if (serializedLinkNode) {\n                    onStylesheetLoad(n, serializedLinkNode);\n                }\n            }\n        }, stylesheetLoadTimeout);\n    }\n    return serializedNode;\n}\nfunction snapshot(n, options) {\n    const { mirror = new Mirror(), blockClass = 'rr-block', blockSelector = null, unblockSelector = null, maskAllText = false, maskTextClass = 'rr-mask', unmaskTextClass = null, maskTextSelector = null, unmaskTextSelector = null, inlineStylesheet = true, inlineImages = false, recordCanvas = false, maskAllInputs = false, maskAttributeFn, maskTextFn, maskInputFn, slimDOM = false, dataURLOptions, preserveWhiteSpace, onSerialize, onIframeLoad, iframeLoadTimeout, onStylesheetLoad, stylesheetLoadTimeout, keepIframeSrcFn = () => false, } = options || {};\n    const maskInputOptions = maskAllInputs === true\n        ? {\n            color: true,\n            date: true,\n            'datetime-local': true,\n            email: true,\n            month: true,\n            number: true,\n            range: true,\n            search: true,\n            tel: true,\n            text: true,\n            time: true,\n            url: true,\n            week: true,\n            textarea: true,\n            select: true,\n        }\n        : maskAllInputs === false\n            ? {}\n            : maskAllInputs;\n    const slimDOMOptions = slimDOM === true || slimDOM === 'all'\n        ?\n            {\n                script: true,\n                comment: true,\n                headFavicon: true,\n                headWhitespace: true,\n                headMetaDescKeywords: slimDOM === 'all',\n                headMetaSocial: true,\n                headMetaRobots: true,\n                headMetaHttpEquiv: true,\n                headMetaAuthorship: true,\n                headMetaVerification: true,\n            }\n        : slimDOM === false\n            ? {}\n            : slimDOM;\n    return serializeNodeWithId(n, {\n        doc: n,\n        mirror,\n        blockClass,\n        blockSelector,\n        unblockSelector,\n        maskAllText,\n        maskTextClass,\n        unmaskTextClass,\n        maskTextSelector,\n        unmaskTextSelector,\n        skipChild: false,\n        inlineStylesheet,\n        maskInputOptions,\n        maskAttributeFn,\n        maskTextFn,\n        maskInputFn,\n        slimDOMOptions,\n        dataURLOptions,\n        inlineImages,\n        recordCanvas,\n        preserveWhiteSpace,\n        onSerialize,\n        onIframeLoad,\n        iframeLoadTimeout,\n        onStylesheetLoad,\n        stylesheetLoadTimeout,\n        keepIframeSrcFn,\n        newlyAddedElement: false,\n    });\n}\n\nfunction _optionalChain$4(ops) { let lastAccessLHS = undefined; let value = ops[0]; let i = 1; while (i < ops.length) { const op = ops[i]; const fn = ops[i + 1]; i += 2; if ((op === 'optionalAccess' || op === 'optionalCall') && value == null) { return undefined; } if (op === 'access' || op === 'optionalAccess') { lastAccessLHS = value; value = fn(value); } else if (op === 'call' || op === 'optionalCall') { value = fn((...args) => value.call(lastAccessLHS, ...args)); lastAccessLHS = undefined; } } return value; }\nfunction on(type, fn, target = document) {\n    const options = { capture: true, passive: true };\n    target.addEventListener(type, fn, options);\n    return () => target.removeEventListener(type, fn, options);\n}\nconst DEPARTED_MIRROR_ACCESS_WARNING = 'Please stop import mirror directly. Instead of that,' +\n    '\\r\\n' +\n    'now you can use replayer.getMirror() to access the mirror instance of a replayer,' +\n    '\\r\\n' +\n    'or you can use record.mirror to access the mirror instance during recording.';\nlet _mirror = {\n    map: {},\n    getId() {\n        console.error(DEPARTED_MIRROR_ACCESS_WARNING);\n        return -1;\n    },\n    getNode() {\n        console.error(DEPARTED_MIRROR_ACCESS_WARNING);\n        return null;\n    },\n    removeNodeFromMap() {\n        console.error(DEPARTED_MIRROR_ACCESS_WARNING);\n    },\n    has() {\n        console.error(DEPARTED_MIRROR_ACCESS_WARNING);\n        return false;\n    },\n    reset() {\n        console.error(DEPARTED_MIRROR_ACCESS_WARNING);\n    },\n};\nif (typeof window !== 'undefined' && window.Proxy && window.Reflect) {\n    _mirror = new Proxy(_mirror, {\n        get(target, prop, receiver) {\n            if (prop === 'map') {\n                console.error(DEPARTED_MIRROR_ACCESS_WARNING);\n            }\n            return Reflect.get(target, prop, receiver);\n        },\n    });\n}\nfunction throttle$1(func, wait, options = {}) {\n    let timeout = null;\n    let previous = 0;\n    return function (...args) {\n        const now = Date.now();\n        if (!previous && options.leading === false) {\n            previous = now;\n        }\n        const remaining = wait - (now - previous);\n        const context = this;\n        if (remaining <= 0 || remaining > wait) {\n            if (timeout) {\n                clearTimeout$1(timeout);\n                timeout = null;\n            }\n            previous = now;\n            func.apply(context, args);\n        }\n        else if (!timeout && options.trailing !== false) {\n            timeout = setTimeout$1(() => {\n                previous = options.leading === false ? 0 : Date.now();\n                timeout = null;\n                func.apply(context, args);\n            }, remaining);\n        }\n    };\n}\nfunction hookSetter(target, key, d, isRevoked, win = window) {\n    const original = win.Object.getOwnPropertyDescriptor(target, key);\n    win.Object.defineProperty(target, key, isRevoked\n        ? d\n        : {\n            set(value) {\n                setTimeout$1(() => {\n                    d.set.call(this, value);\n                }, 0);\n                if (original && original.set) {\n                    original.set.call(this, value);\n                }\n            },\n        });\n    return () => hookSetter(target, key, original || {}, true);\n}\nfunction patch(source, name, replacement) {\n    try {\n        if (!(name in source)) {\n            return () => {\n            };\n        }\n        const original = source[name];\n        const wrapped = replacement(original);\n        if (typeof wrapped === 'function') {\n            wrapped.prototype = wrapped.prototype || {};\n            Object.defineProperties(wrapped, {\n                __rrweb_original__: {\n                    enumerable: false,\n                    value: original,\n                },\n            });\n        }\n        source[name] = wrapped;\n        return () => {\n            source[name] = original;\n        };\n    }\n    catch (e2) {\n        return () => {\n        };\n    }\n}\nlet nowTimestamp = Date.now;\nif (!(/[1-9][0-9]{12}/.test(Date.now().toString()))) {\n    nowTimestamp = () => new Date().getTime();\n}\nfunction getWindowScroll(win) {\n    const doc = win.document;\n    return {\n        left: doc.scrollingElement\n            ? doc.scrollingElement.scrollLeft\n            : win.pageXOffset !== undefined\n                ? win.pageXOffset\n                : _optionalChain$4([doc, 'optionalAccess', _ => _.documentElement, 'access', _2 => _2.scrollLeft]) ||\n                    _optionalChain$4([doc, 'optionalAccess', _3 => _3.body, 'optionalAccess', _4 => _4.parentElement, 'optionalAccess', _5 => _5.scrollLeft]) ||\n                    _optionalChain$4([doc, 'optionalAccess', _6 => _6.body, 'optionalAccess', _7 => _7.scrollLeft]) ||\n                    0,\n        top: doc.scrollingElement\n            ? doc.scrollingElement.scrollTop\n            : win.pageYOffset !== undefined\n                ? win.pageYOffset\n                : _optionalChain$4([doc, 'optionalAccess', _8 => _8.documentElement, 'access', _9 => _9.scrollTop]) ||\n                    _optionalChain$4([doc, 'optionalAccess', _10 => _10.body, 'optionalAccess', _11 => _11.parentElement, 'optionalAccess', _12 => _12.scrollTop]) ||\n                    _optionalChain$4([doc, 'optionalAccess', _13 => _13.body, 'optionalAccess', _14 => _14.scrollTop]) ||\n                    0,\n    };\n}\nfunction getWindowHeight() {\n    return (window.innerHeight ||\n        (document.documentElement && document.documentElement.clientHeight) ||\n        (document.body && document.body.clientHeight));\n}\nfunction getWindowWidth() {\n    return (window.innerWidth ||\n        (document.documentElement && document.documentElement.clientWidth) ||\n        (document.body && document.body.clientWidth));\n}\nfunction closestElementOfNode(node) {\n    if (!node) {\n        return null;\n    }\n    const el = node.nodeType === node.ELEMENT_NODE\n        ? node\n        : node.parentElement;\n    return el;\n}\nfunction isBlocked(node, blockClass, blockSelector, unblockSelector, checkAncestors) {\n    if (!node) {\n        return false;\n    }\n    const el = closestElementOfNode(node);\n    if (!el) {\n        return false;\n    }\n    const blockedPredicate = createMatchPredicate(blockClass, blockSelector);\n    if (!checkAncestors) {\n        const isUnblocked = unblockSelector && el.matches(unblockSelector);\n        return blockedPredicate(el) && !isUnblocked;\n    }\n    const blockDistance = distanceToMatch(el, blockedPredicate);\n    let unblockDistance = -1;\n    if (blockDistance < 0) {\n        return false;\n    }\n    if (unblockSelector) {\n        unblockDistance = distanceToMatch(el, createMatchPredicate(null, unblockSelector));\n    }\n    if (blockDistance > -1 && unblockDistance < 0) {\n        return true;\n    }\n    return blockDistance < unblockDistance;\n}\nfunction isSerialized(n, mirror) {\n    return mirror.getId(n) !== -1;\n}\nfunction isIgnored(n, mirror) {\n    return mirror.getId(n) === IGNORED_NODE;\n}\nfunction isAncestorRemoved(target, mirror) {\n    if (isShadowRoot(target)) {\n        return false;\n    }\n    const id = mirror.getId(target);\n    if (!mirror.has(id)) {\n        return true;\n    }\n    if (target.parentNode &&\n        target.parentNode.nodeType === target.DOCUMENT_NODE) {\n        return false;\n    }\n    if (!target.parentNode) {\n        return true;\n    }\n    return isAncestorRemoved(target.parentNode, mirror);\n}\nfunction legacy_isTouchEvent(event) {\n    return Boolean(event.changedTouches);\n}\nfunction polyfill(win = window) {\n    if ('NodeList' in win && !win.NodeList.prototype.forEach) {\n        win.NodeList.prototype.forEach = Array.prototype\n            .forEach;\n    }\n    if ('DOMTokenList' in win && !win.DOMTokenList.prototype.forEach) {\n        win.DOMTokenList.prototype.forEach = Array.prototype\n            .forEach;\n    }\n    if (!Node.prototype.contains) {\n        Node.prototype.contains = (...args) => {\n            let node = args[0];\n            if (!(0 in args)) {\n                throw new TypeError('1 argument is required');\n            }\n            do {\n                if (this === node) {\n                    return true;\n                }\n            } while ((node = node && node.parentNode));\n            return false;\n        };\n    }\n}\nfunction isSerializedIframe(n, mirror) {\n    return Boolean(n.nodeName === 'IFRAME' && mirror.getMeta(n));\n}\nfunction isSerializedStylesheet(n, mirror) {\n    return Boolean(n.nodeName === 'LINK' &&\n        n.nodeType === n.ELEMENT_NODE &&\n        n.getAttribute &&\n        n.getAttribute('rel') === 'stylesheet' &&\n        mirror.getMeta(n));\n}\nfunction hasShadowRoot(n) {\n    return Boolean(_optionalChain$4([n, 'optionalAccess', _18 => _18.shadowRoot]));\n}\nclass StyleSheetMirror {\n    constructor() {\n        this.id = 1;\n        this.styleIDMap = new WeakMap();\n        this.idStyleMap = new Map();\n    }\n    getId(stylesheet) {\n        return _nullishCoalesce(this.styleIDMap.get(stylesheet), () => ( -1));\n    }\n    has(stylesheet) {\n        return this.styleIDMap.has(stylesheet);\n    }\n    add(stylesheet, id) {\n        if (this.has(stylesheet))\n            return this.getId(stylesheet);\n        let newId;\n        if (id === undefined) {\n            newId = this.id++;\n        }\n        else\n            newId = id;\n        this.styleIDMap.set(stylesheet, newId);\n        this.idStyleMap.set(newId, stylesheet);\n        return newId;\n    }\n    getStyle(id) {\n        return this.idStyleMap.get(id) || null;\n    }\n    reset() {\n        this.styleIDMap = new WeakMap();\n        this.idStyleMap = new Map();\n        this.id = 1;\n    }\n    generateId() {\n        return this.id++;\n    }\n}\nfunction getShadowHost(n) {\n    let shadowHost = null;\n    if (_optionalChain$4([n, 'access', _19 => _19.getRootNode, 'optionalCall', _20 => _20(), 'optionalAccess', _21 => _21.nodeType]) === Node.DOCUMENT_FRAGMENT_NODE &&\n        n.getRootNode().host)\n        shadowHost = n.getRootNode().host;\n    return shadowHost;\n}\nfunction getRootShadowHost(n) {\n    let rootShadowHost = n;\n    let shadowHost;\n    while ((shadowHost = getShadowHost(rootShadowHost)))\n        rootShadowHost = shadowHost;\n    return rootShadowHost;\n}\nfunction shadowHostInDom(n) {\n    const doc = n.ownerDocument;\n    if (!doc)\n        return false;\n    const shadowHost = getRootShadowHost(n);\n    return doc.contains(shadowHost);\n}\nfunction inDom(n) {\n    const doc = n.ownerDocument;\n    if (!doc)\n        return false;\n    return doc.contains(n) || shadowHostInDom(n);\n}\nconst cachedImplementations = {};\nfunction getImplementation(name) {\n    const cached = cachedImplementations[name];\n    if (cached) {\n        return cached;\n    }\n    const document = window.document;\n    let impl = window[name];\n    if (document && typeof document.createElement === 'function') {\n        try {\n            const sandbox = document.createElement('iframe');\n            sandbox.hidden = true;\n            document.head.appendChild(sandbox);\n            const contentWindow = sandbox.contentWindow;\n            if (contentWindow && contentWindow[name]) {\n                impl =\n                    contentWindow[name];\n            }\n            document.head.removeChild(sandbox);\n        }\n        catch (e) {\n        }\n    }\n    return (cachedImplementations[name] = impl.bind(window));\n}\nfunction onRequestAnimationFrame(...rest) {\n    return getImplementation('requestAnimationFrame')(...rest);\n}\nfunction setTimeout$1(...rest) {\n    return getImplementation('setTimeout')(...rest);\n}\nfunction clearTimeout$1(...rest) {\n    return getImplementation('clearTimeout')(...rest);\n}\n\nvar EventType = /* @__PURE__ */ ((EventType2) => {\n  EventType2[EventType2[\"DomContentLoaded\"] = 0] = \"DomContentLoaded\";\n  EventType2[EventType2[\"Load\"] = 1] = \"Load\";\n  EventType2[EventType2[\"FullSnapshot\"] = 2] = \"FullSnapshot\";\n  EventType2[EventType2[\"IncrementalSnapshot\"] = 3] = \"IncrementalSnapshot\";\n  EventType2[EventType2[\"Meta\"] = 4] = \"Meta\";\n  EventType2[EventType2[\"Custom\"] = 5] = \"Custom\";\n  EventType2[EventType2[\"Plugin\"] = 6] = \"Plugin\";\n  return EventType2;\n})(EventType || {});\nvar IncrementalSource = /* @__PURE__ */ ((IncrementalSource2) => {\n  IncrementalSource2[IncrementalSource2[\"Mutation\"] = 0] = \"Mutation\";\n  IncrementalSource2[IncrementalSource2[\"MouseMove\"] = 1] = \"MouseMove\";\n  IncrementalSource2[IncrementalSource2[\"MouseInteraction\"] = 2] = \"MouseInteraction\";\n  IncrementalSource2[IncrementalSource2[\"Scroll\"] = 3] = \"Scroll\";\n  IncrementalSource2[IncrementalSource2[\"ViewportResize\"] = 4] = \"ViewportResize\";\n  IncrementalSource2[IncrementalSource2[\"Input\"] = 5] = \"Input\";\n  IncrementalSource2[IncrementalSource2[\"TouchMove\"] = 6] = \"TouchMove\";\n  IncrementalSource2[IncrementalSource2[\"MediaInteraction\"] = 7] = \"MediaInteraction\";\n  IncrementalSource2[IncrementalSource2[\"StyleSheetRule\"] = 8] = \"StyleSheetRule\";\n  IncrementalSource2[IncrementalSource2[\"CanvasMutation\"] = 9] = \"CanvasMutation\";\n  IncrementalSource2[IncrementalSource2[\"Font\"] = 10] = \"Font\";\n  IncrementalSource2[IncrementalSource2[\"Log\"] = 11] = \"Log\";\n  IncrementalSource2[IncrementalSource2[\"Drag\"] = 12] = \"Drag\";\n  IncrementalSource2[IncrementalSource2[\"StyleDeclaration\"] = 13] = \"StyleDeclaration\";\n  IncrementalSource2[IncrementalSource2[\"Selection\"] = 14] = \"Selection\";\n  IncrementalSource2[IncrementalSource2[\"AdoptedStyleSheet\"] = 15] = \"AdoptedStyleSheet\";\n  IncrementalSource2[IncrementalSource2[\"CustomElement\"] = 16] = \"CustomElement\";\n  return IncrementalSource2;\n})(IncrementalSource || {});\nvar MouseInteractions = /* @__PURE__ */ ((MouseInteractions2) => {\n  MouseInteractions2[MouseInteractions2[\"MouseUp\"] = 0] = \"MouseUp\";\n  MouseInteractions2[MouseInteractions2[\"MouseDown\"] = 1] = \"MouseDown\";\n  MouseInteractions2[MouseInteractions2[\"Click\"] = 2] = \"Click\";\n  MouseInteractions2[MouseInteractions2[\"ContextMenu\"] = 3] = \"ContextMenu\";\n  MouseInteractions2[MouseInteractions2[\"DblClick\"] = 4] = \"DblClick\";\n  MouseInteractions2[MouseInteractions2[\"Focus\"] = 5] = \"Focus\";\n  MouseInteractions2[MouseInteractions2[\"Blur\"] = 6] = \"Blur\";\n  MouseInteractions2[MouseInteractions2[\"TouchStart\"] = 7] = \"TouchStart\";\n  MouseInteractions2[MouseInteractions2[\"TouchMove_Departed\"] = 8] = \"TouchMove_Departed\";\n  MouseInteractions2[MouseInteractions2[\"TouchEnd\"] = 9] = \"TouchEnd\";\n  MouseInteractions2[MouseInteractions2[\"TouchCancel\"] = 10] = \"TouchCancel\";\n  return MouseInteractions2;\n})(MouseInteractions || {});\nvar PointerTypes = /* @__PURE__ */ ((PointerTypes2) => {\n  PointerTypes2[PointerTypes2[\"Mouse\"] = 0] = \"Mouse\";\n  PointerTypes2[PointerTypes2[\"Pen\"] = 1] = \"Pen\";\n  PointerTypes2[PointerTypes2[\"Touch\"] = 2] = \"Touch\";\n  return PointerTypes2;\n})(PointerTypes || {});\n\nfunction _optionalChain$3(ops) { let lastAccessLHS = undefined; let value = ops[0]; let i = 1; while (i < ops.length) { const op = ops[i]; const fn = ops[i + 1]; i += 2; if ((op === 'optionalAccess' || op === 'optionalCall') && value == null) { return undefined; } if (op === 'access' || op === 'optionalAccess') { lastAccessLHS = value; value = fn(value); } else if (op === 'call' || op === 'optionalCall') { value = fn((...args) => value.call(lastAccessLHS, ...args)); lastAccessLHS = undefined; } } return value; }\nfunction isNodeInLinkedList(n) {\n    return '__ln' in n;\n}\nclass DoubleLinkedList {\n    constructor() {\n        this.length = 0;\n        this.head = null;\n        this.tail = null;\n    }\n    get(position) {\n        if (position >= this.length) {\n            throw new Error('Position outside of list range');\n        }\n        let current = this.head;\n        for (let index = 0; index < position; index++) {\n            current = _optionalChain$3([current, 'optionalAccess', _ => _.next]) || null;\n        }\n        return current;\n    }\n    addNode(n) {\n        const node = {\n            value: n,\n            previous: null,\n            next: null,\n        };\n        n.__ln = node;\n        if (n.previousSibling && isNodeInLinkedList(n.previousSibling)) {\n            const current = n.previousSibling.__ln.next;\n            node.next = current;\n            node.previous = n.previousSibling.__ln;\n            n.previousSibling.__ln.next = node;\n            if (current) {\n                current.previous = node;\n            }\n        }\n        else if (n.nextSibling &&\n            isNodeInLinkedList(n.nextSibling) &&\n            n.nextSibling.__ln.previous) {\n            const current = n.nextSibling.__ln.previous;\n            node.previous = current;\n            node.next = n.nextSibling.__ln;\n            n.nextSibling.__ln.previous = node;\n            if (current) {\n                current.next = node;\n            }\n        }\n        else {\n            if (this.head) {\n                this.head.previous = node;\n            }\n            node.next = this.head;\n            this.head = node;\n        }\n        if (node.next === null) {\n            this.tail = node;\n        }\n        this.length++;\n    }\n    removeNode(n) {\n        const current = n.__ln;\n        if (!this.head) {\n            return;\n        }\n        if (!current.previous) {\n            this.head = current.next;\n            if (this.head) {\n                this.head.previous = null;\n            }\n            else {\n                this.tail = null;\n            }\n        }\n        else {\n            current.previous.next = current.next;\n            if (current.next) {\n                current.next.previous = current.previous;\n            }\n            else {\n                this.tail = current.previous;\n            }\n        }\n        if (n.__ln) {\n            delete n.__ln;\n        }\n        this.length--;\n    }\n}\nconst moveKey = (id, parentId) => `${id}@${parentId}`;\nclass MutationBuffer {\n    constructor() {\n        this.frozen = false;\n        this.locked = false;\n        this.texts = [];\n        this.attributes = [];\n        this.attributeMap = new WeakMap();\n        this.removes = [];\n        this.mapRemoves = [];\n        this.movedMap = {};\n        this.addedSet = new Set();\n        this.movedSet = new Set();\n        this.droppedSet = new Set();\n        this.processMutations = (mutations) => {\n            mutations.forEach(this.processMutation);\n            this.emit();\n        };\n        this.emit = () => {\n            if (this.frozen || this.locked) {\n                return;\n            }\n            const adds = [];\n            const addedIds = new Set();\n            const addList = new DoubleLinkedList();\n            const getNextId = (n) => {\n                let ns = n;\n                let nextId = IGNORED_NODE;\n                while (nextId === IGNORED_NODE) {\n                    ns = ns && ns.nextSibling;\n                    nextId = ns && this.mirror.getId(ns);\n                }\n                return nextId;\n            };\n            const pushAdd = (n) => {\n                if (!n.parentNode || !inDom(n)) {\n                    return;\n                }\n                const parentId = isShadowRoot(n.parentNode)\n                    ? this.mirror.getId(getShadowHost(n))\n                    : this.mirror.getId(n.parentNode);\n                const nextId = getNextId(n);\n                if (parentId === -1 || nextId === -1) {\n                    return addList.addNode(n);\n                }\n                const sn = serializeNodeWithId(n, {\n                    doc: this.doc,\n                    mirror: this.mirror,\n                    blockClass: this.blockClass,\n                    blockSelector: this.blockSelector,\n                    maskAllText: this.maskAllText,\n                    unblockSelector: this.unblockSelector,\n                    maskTextClass: this.maskTextClass,\n                    unmaskTextClass: this.unmaskTextClass,\n                    maskTextSelector: this.maskTextSelector,\n                    unmaskTextSelector: this.unmaskTextSelector,\n                    skipChild: true,\n                    newlyAddedElement: true,\n                    inlineStylesheet: this.inlineStylesheet,\n                    maskInputOptions: this.maskInputOptions,\n                    maskAttributeFn: this.maskAttributeFn,\n                    maskTextFn: this.maskTextFn,\n                    maskInputFn: this.maskInputFn,\n                    slimDOMOptions: this.slimDOMOptions,\n                    dataURLOptions: this.dataURLOptions,\n                    recordCanvas: this.recordCanvas,\n                    inlineImages: this.inlineImages,\n                    onSerialize: (currentN) => {\n                        if (isSerializedIframe(currentN, this.mirror) &&\n                            !isBlocked(currentN, this.blockClass, this.blockSelector, this.unblockSelector, false)) {\n                            this.iframeManager.addIframe(currentN);\n                        }\n                        if (isSerializedStylesheet(currentN, this.mirror)) {\n                            this.stylesheetManager.trackLinkElement(currentN);\n                        }\n                        if (hasShadowRoot(n)) {\n                            this.shadowDomManager.addShadowRoot(n.shadowRoot, this.doc);\n                        }\n                    },\n                    onIframeLoad: (iframe, childSn) => {\n                        if (isBlocked(iframe, this.blockClass, this.blockSelector, this.unblockSelector, false)) {\n                            return;\n                        }\n                        this.iframeManager.attachIframe(iframe, childSn);\n                        if (iframe.contentWindow) {\n                            this.canvasManager.addWindow(iframe.contentWindow);\n                        }\n                        this.shadowDomManager.observeAttachShadow(iframe);\n                    },\n                    onStylesheetLoad: (link, childSn) => {\n                        this.stylesheetManager.attachLinkElement(link, childSn);\n                    },\n                });\n                if (sn) {\n                    adds.push({\n                        parentId,\n                        nextId,\n                        node: sn,\n                    });\n                    addedIds.add(sn.id);\n                }\n            };\n            while (this.mapRemoves.length) {\n                this.mirror.removeNodeFromMap(this.mapRemoves.shift());\n            }\n            for (const n of this.movedSet) {\n                if (isParentRemoved(this.removes, n, this.mirror) &&\n                    !this.movedSet.has(n.parentNode)) {\n                    continue;\n                }\n                pushAdd(n);\n            }\n            for (const n of this.addedSet) {\n                if (!isAncestorInSet(this.droppedSet, n) &&\n                    !isParentRemoved(this.removes, n, this.mirror)) {\n                    pushAdd(n);\n                }\n                else if (isAncestorInSet(this.movedSet, n)) {\n                    pushAdd(n);\n                }\n                else {\n                    this.droppedSet.add(n);\n                }\n            }\n            let candidate = null;\n            while (addList.length) {\n                let node = null;\n                if (candidate) {\n                    const parentId = this.mirror.getId(candidate.value.parentNode);\n                    const nextId = getNextId(candidate.value);\n                    if (parentId !== -1 && nextId !== -1) {\n                        node = candidate;\n                    }\n                }\n                if (!node) {\n                    let tailNode = addList.tail;\n                    while (tailNode) {\n                        const _node = tailNode;\n                        tailNode = tailNode.previous;\n                        if (_node) {\n                            const parentId = this.mirror.getId(_node.value.parentNode);\n                            const nextId = getNextId(_node.value);\n                            if (nextId === -1)\n                                continue;\n                            else if (parentId !== -1) {\n                                node = _node;\n                                break;\n                            }\n                            else {\n                                const unhandledNode = _node.value;\n                                if (unhandledNode.parentNode &&\n                                    unhandledNode.parentNode.nodeType ===\n                                        Node.DOCUMENT_FRAGMENT_NODE) {\n                                    const shadowHost = unhandledNode.parentNode\n                                        .host;\n                                    const parentId = this.mirror.getId(shadowHost);\n                                    if (parentId !== -1) {\n                                        node = _node;\n                                        break;\n                                    }\n                                }\n                            }\n                        }\n                    }\n                }\n                if (!node) {\n                    while (addList.head) {\n                        addList.removeNode(addList.head.value);\n                    }\n                    break;\n                }\n                candidate = node.previous;\n                addList.removeNode(node.value);\n                pushAdd(node.value);\n            }\n            const payload = {\n                texts: this.texts\n                    .map((text) => ({\n                    id: this.mirror.getId(text.node),\n                    value: text.value,\n                }))\n                    .filter((text) => !addedIds.has(text.id))\n                    .filter((text) => this.mirror.has(text.id)),\n                attributes: this.attributes\n                    .map((attribute) => {\n                    const { attributes } = attribute;\n                    if (typeof attributes.style === 'string') {\n                        const diffAsStr = JSON.stringify(attribute.styleDiff);\n                        const unchangedAsStr = JSON.stringify(attribute._unchangedStyles);\n                        if (diffAsStr.length < attributes.style.length) {\n                            if ((diffAsStr + unchangedAsStr).split('var(').length ===\n                                attributes.style.split('var(').length) {\n                                attributes.style = attribute.styleDiff;\n                            }\n                        }\n                    }\n                    return {\n                        id: this.mirror.getId(attribute.node),\n                        attributes: attributes,\n                    };\n                })\n                    .filter((attribute) => !addedIds.has(attribute.id))\n                    .filter((attribute) => this.mirror.has(attribute.id)),\n                removes: this.removes,\n                adds,\n            };\n            if (!payload.texts.length &&\n                !payload.attributes.length &&\n                !payload.removes.length &&\n                !payload.adds.length) {\n                return;\n            }\n            this.texts = [];\n            this.attributes = [];\n            this.attributeMap = new WeakMap();\n            this.removes = [];\n            this.addedSet = new Set();\n            this.movedSet = new Set();\n            this.droppedSet = new Set();\n            this.movedMap = {};\n            this.mutationCb(payload);\n        };\n        this.processMutation = (m) => {\n            if (isIgnored(m.target, this.mirror)) {\n                return;\n            }\n            switch (m.type) {\n                case 'characterData': {\n                    const value = m.target.textContent;\n                    if (!isBlocked(m.target, this.blockClass, this.blockSelector, this.unblockSelector, false) &&\n                        value !== m.oldValue) {\n                        this.texts.push({\n                            value: needMaskingText(m.target, this.maskTextClass, this.maskTextSelector, this.unmaskTextClass, this.unmaskTextSelector, this.maskAllText) && value\n                                ? this.maskTextFn\n                                    ? this.maskTextFn(value, closestElementOfNode(m.target))\n                                    : value.replace(/[\\S]/g, '*')\n                                : value,\n                            node: m.target,\n                        });\n                    }\n                    break;\n                }\n                case 'attributes': {\n                    const target = m.target;\n                    let attributeName = m.attributeName;\n                    let value = m.target.getAttribute(attributeName);\n                    if (attributeName === 'value') {\n                        const type = getInputType(target);\n                        const tagName = target.tagName;\n                        value = getInputValue(target, tagName, type);\n                        const isInputMasked = shouldMaskInput({\n                            maskInputOptions: this.maskInputOptions,\n                            tagName,\n                            type,\n                        });\n                        const forceMask = needMaskingText(m.target, this.maskTextClass, this.maskTextSelector, this.unmaskTextClass, this.unmaskTextSelector, isInputMasked);\n                        value = maskInputValue({\n                            isMasked: forceMask,\n                            element: target,\n                            value,\n                            maskInputFn: this.maskInputFn,\n                        });\n                    }\n                    if (isBlocked(m.target, this.blockClass, this.blockSelector, this.unblockSelector, false) ||\n                        value === m.oldValue) {\n                        return;\n                    }\n                    let item = this.attributeMap.get(m.target);\n                    if (target.tagName === 'IFRAME' &&\n                        attributeName === 'src' &&\n                        !this.keepIframeSrcFn(value)) {\n                        if (!target.contentDocument) {\n                            attributeName = 'rr_src';\n                        }\n                        else {\n                            return;\n                        }\n                    }\n                    if (!item) {\n                        item = {\n                            node: m.target,\n                            attributes: {},\n                            styleDiff: {},\n                            _unchangedStyles: {},\n                        };\n                        this.attributes.push(item);\n                        this.attributeMap.set(m.target, item);\n                    }\n                    if (attributeName === 'type' &&\n                        target.tagName === 'INPUT' &&\n                        (m.oldValue || '').toLowerCase() === 'password') {\n                        target.setAttribute('data-rr-is-password', 'true');\n                    }\n                    if (!ignoreAttribute(target.tagName, attributeName)) {\n                        item.attributes[attributeName] = transformAttribute(this.doc, toLowerCase(target.tagName), toLowerCase(attributeName), value, target, this.maskAttributeFn);\n                        if (attributeName === 'style') {\n                            if (!this.unattachedDoc) {\n                                try {\n                                    this.unattachedDoc =\n                                        document.implementation.createHTMLDocument();\n                                }\n                                catch (e) {\n                                    this.unattachedDoc = this.doc;\n                                }\n                            }\n                            const old = this.unattachedDoc.createElement('span');\n                            if (m.oldValue) {\n                                old.setAttribute('style', m.oldValue);\n                            }\n                            for (const pname of Array.from(target.style)) {\n                                const newValue = target.style.getPropertyValue(pname);\n                                const newPriority = target.style.getPropertyPriority(pname);\n                                if (newValue !== old.style.getPropertyValue(pname) ||\n                                    newPriority !== old.style.getPropertyPriority(pname)) {\n                                    if (newPriority === '') {\n                                        item.styleDiff[pname] = newValue;\n                                    }\n                                    else {\n                                        item.styleDiff[pname] = [newValue, newPriority];\n                                    }\n                                }\n                                else {\n                                    item._unchangedStyles[pname] = [newValue, newPriority];\n                                }\n                            }\n                            for (const pname of Array.from(old.style)) {\n                                if (target.style.getPropertyValue(pname) === '') {\n                                    item.styleDiff[pname] = false;\n                                }\n                            }\n                        }\n                    }\n                    break;\n                }\n                case 'childList': {\n                    if (isBlocked(m.target, this.blockClass, this.blockSelector, this.unblockSelector, true)) {\n                        return;\n                    }\n                    m.addedNodes.forEach((n) => this.genAdds(n, m.target));\n                    m.removedNodes.forEach((n) => {\n                        const nodeId = this.mirror.getId(n);\n                        const parentId = isShadowRoot(m.target)\n                            ? this.mirror.getId(m.target.host)\n                            : this.mirror.getId(m.target);\n                        if (isBlocked(m.target, this.blockClass, this.blockSelector, this.unblockSelector, false) ||\n                            isIgnored(n, this.mirror) ||\n                            !isSerialized(n, this.mirror)) {\n                            return;\n                        }\n                        if (this.addedSet.has(n)) {\n                            deepDelete(this.addedSet, n);\n                            this.droppedSet.add(n);\n                        }\n                        else if (this.addedSet.has(m.target) && nodeId === -1) ;\n                        else if (isAncestorRemoved(m.target, this.mirror)) ;\n                        else if (this.movedSet.has(n) &&\n                            this.movedMap[moveKey(nodeId, parentId)]) {\n                            deepDelete(this.movedSet, n);\n                        }\n                        else {\n                            this.removes.push({\n                                parentId,\n                                id: nodeId,\n                                isShadow: isShadowRoot(m.target) && isNativeShadowDom(m.target)\n                                    ? true\n                                    : undefined,\n                            });\n                        }\n                        this.mapRemoves.push(n);\n                    });\n                    break;\n                }\n            }\n        };\n        this.genAdds = (n, target) => {\n            if (this.processedNodeManager.inOtherBuffer(n, this))\n                return;\n            if (this.addedSet.has(n) || this.movedSet.has(n))\n                return;\n            if (this.mirror.hasNode(n)) {\n                if (isIgnored(n, this.mirror)) {\n                    return;\n                }\n                this.movedSet.add(n);\n                let targetId = null;\n                if (target && this.mirror.hasNode(target)) {\n                    targetId = this.mirror.getId(target);\n                }\n                if (targetId && targetId !== -1) {\n                    this.movedMap[moveKey(this.mirror.getId(n), targetId)] = true;\n                }\n            }\n            else {\n                this.addedSet.add(n);\n                this.droppedSet.delete(n);\n            }\n            if (!isBlocked(n, this.blockClass, this.blockSelector, this.unblockSelector, false)) {\n                n.childNodes.forEach((childN) => this.genAdds(childN));\n                if (hasShadowRoot(n)) {\n                    n.shadowRoot.childNodes.forEach((childN) => {\n                        this.processedNodeManager.add(childN, this);\n                        this.genAdds(childN, n);\n                    });\n                }\n            }\n        };\n    }\n    init(options) {\n        [\n            'mutationCb',\n            'blockClass',\n            'blockSelector',\n            'unblockSelector',\n            'maskAllText',\n            'maskTextClass',\n            'unmaskTextClass',\n            'maskTextSelector',\n            'unmaskTextSelector',\n            'inlineStylesheet',\n            'maskInputOptions',\n            'maskAttributeFn',\n            'maskTextFn',\n            'maskInputFn',\n            'keepIframeSrcFn',\n            'recordCanvas',\n            'inlineImages',\n            'slimDOMOptions',\n            'dataURLOptions',\n            'doc',\n            'mirror',\n            'iframeManager',\n            'stylesheetManager',\n            'shadowDomManager',\n            'canvasManager',\n            'processedNodeManager',\n        ].forEach((key) => {\n            this[key] = options[key];\n        });\n    }\n    freeze() {\n        this.frozen = true;\n        this.canvasManager.freeze();\n    }\n    unfreeze() {\n        this.frozen = false;\n        this.canvasManager.unfreeze();\n        this.emit();\n    }\n    isFrozen() {\n        return this.frozen;\n    }\n    lock() {\n        this.locked = true;\n        this.canvasManager.lock();\n    }\n    unlock() {\n        this.locked = false;\n        this.canvasManager.unlock();\n        this.emit();\n    }\n    reset() {\n        this.shadowDomManager.reset();\n        this.canvasManager.reset();\n    }\n}\nfunction deepDelete(addsSet, n) {\n    addsSet.delete(n);\n    n.childNodes.forEach((childN) => deepDelete(addsSet, childN));\n}\nfunction isParentRemoved(removes, n, mirror) {\n    if (removes.length === 0)\n        return false;\n    return _isParentRemoved(removes, n, mirror);\n}\nfunction _isParentRemoved(removes, n, mirror) {\n    let node = n.parentNode;\n    while (node) {\n        const parentId = mirror.getId(node);\n        if (removes.some((r) => r.id === parentId)) {\n            return true;\n        }\n        node = node.parentNode;\n    }\n    return false;\n}\nfunction isAncestorInSet(set, n) {\n    if (set.size === 0)\n        return false;\n    return _isAncestorInSet(set, n);\n}\nfunction _isAncestorInSet(set, n) {\n    const { parentNode } = n;\n    if (!parentNode) {\n        return false;\n    }\n    if (set.has(parentNode)) {\n        return true;\n    }\n    return _isAncestorInSet(set, parentNode);\n}\n\nlet errorHandler;\nfunction registerErrorHandler(handler) {\n    errorHandler = handler;\n}\nfunction unregisterErrorHandler() {\n    errorHandler = undefined;\n}\nconst callbackWrapper = (cb) => {\n    if (!errorHandler) {\n        return cb;\n    }\n    const rrwebWrapped = ((...rest) => {\n        try {\n            return cb(...rest);\n        }\n        catch (error) {\n            if (errorHandler && errorHandler(error) === true) {\n                return () => {\n                };\n            }\n            throw error;\n        }\n    });\n    return rrwebWrapped;\n};\n\nfunction _optionalChain$2(ops) { let lastAccessLHS = undefined; let value = ops[0]; let i = 1; while (i < ops.length) { const op = ops[i]; const fn = ops[i + 1]; i += 2; if ((op === 'optionalAccess' || op === 'optionalCall') && value == null) { return undefined; } if (op === 'access' || op === 'optionalAccess') { lastAccessLHS = value; value = fn(value); } else if (op === 'call' || op === 'optionalCall') { value = fn((...args) => value.call(lastAccessLHS, ...args)); lastAccessLHS = undefined; } } return value; }\nconst mutationBuffers = [];\nfunction getEventTarget(event) {\n    try {\n        if ('composedPath' in event) {\n            const path = event.composedPath();\n            if (path.length) {\n                return path[0];\n            }\n        }\n        else if ('path' in event && event.path.length) {\n            return event.path[0];\n        }\n    }\n    catch (e2) {\n    }\n    return event && event.target;\n}\nfunction initMutationObserver(options, rootEl) {\n    const mutationBuffer = new MutationBuffer();\n    mutationBuffers.push(mutationBuffer);\n    mutationBuffer.init(options);\n    let mutationObserverCtor = window.MutationObserver ||\n        window.__rrMutationObserver;\n    const angularZoneSymbol = _optionalChain$2([window, 'optionalAccess', _ => _.Zone, 'optionalAccess', _2 => _2.__symbol__, 'optionalCall', _3 => _3('MutationObserver')]);\n    if (angularZoneSymbol &&\n        window[angularZoneSymbol]) {\n        mutationObserverCtor = window[angularZoneSymbol];\n    }\n    const observer = new mutationObserverCtor(callbackWrapper((mutations) => {\n        if (options.onMutation && options.onMutation(mutations) === false) {\n            return;\n        }\n        mutationBuffer.processMutations.bind(mutationBuffer)(mutations);\n    }));\n    observer.observe(rootEl, {\n        attributes: true,\n        attributeOldValue: true,\n        characterData: true,\n        characterDataOldValue: true,\n        childList: true,\n        subtree: true,\n    });\n    return observer;\n}\nfunction initMoveObserver({ mousemoveCb, sampling, doc, mirror, }) {\n    if (sampling.mousemove === false) {\n        return () => {\n        };\n    }\n    const threshold = typeof sampling.mousemove === 'number' ? sampling.mousemove : 50;\n    const callbackThreshold = typeof sampling.mousemoveCallback === 'number'\n        ? sampling.mousemoveCallback\n        : 500;\n    let positions = [];\n    let timeBaseline;\n    const wrappedCb = throttle$1(callbackWrapper((source) => {\n        const totalOffset = Date.now() - timeBaseline;\n        mousemoveCb(positions.map((p) => {\n            p.timeOffset -= totalOffset;\n            return p;\n        }), source);\n        positions = [];\n        timeBaseline = null;\n    }), callbackThreshold);\n    const updatePosition = callbackWrapper(throttle$1(callbackWrapper((evt) => {\n        const target = getEventTarget(evt);\n        const { clientX, clientY } = legacy_isTouchEvent(evt)\n            ? evt.changedTouches[0]\n            : evt;\n        if (!timeBaseline) {\n            timeBaseline = nowTimestamp();\n        }\n        positions.push({\n            x: clientX,\n            y: clientY,\n            id: mirror.getId(target),\n            timeOffset: nowTimestamp() - timeBaseline,\n        });\n        wrappedCb(typeof DragEvent !== 'undefined' && evt instanceof DragEvent\n            ? IncrementalSource.Drag\n            : evt instanceof MouseEvent\n                ? IncrementalSource.MouseMove\n                : IncrementalSource.TouchMove);\n    }), threshold, {\n        trailing: false,\n    }));\n    const handlers = [\n        on('mousemove', updatePosition, doc),\n        on('touchmove', updatePosition, doc),\n        on('drag', updatePosition, doc),\n    ];\n    return callbackWrapper(() => {\n        handlers.forEach((h) => h());\n    });\n}\nfunction initMouseInteractionObserver({ mouseInteractionCb, doc, mirror, blockClass, blockSelector, unblockSelector, sampling, }) {\n    if (sampling.mouseInteraction === false) {\n        return () => {\n        };\n    }\n    const disableMap = sampling.mouseInteraction === true ||\n        sampling.mouseInteraction === undefined\n        ? {}\n        : sampling.mouseInteraction;\n    const handlers = [];\n    let currentPointerType = null;\n    const getHandler = (eventKey) => {\n        return (event) => {\n            const target = getEventTarget(event);\n            if (isBlocked(target, blockClass, blockSelector, unblockSelector, true)) {\n                return;\n            }\n            let pointerType = null;\n            let thisEventKey = eventKey;\n            if ('pointerType' in event) {\n                switch (event.pointerType) {\n                    case 'mouse':\n                        pointerType = PointerTypes.Mouse;\n                        break;\n                    case 'touch':\n                        pointerType = PointerTypes.Touch;\n                        break;\n                    case 'pen':\n                        pointerType = PointerTypes.Pen;\n                        break;\n                }\n                if (pointerType === PointerTypes.Touch) {\n                    if (MouseInteractions[eventKey] === MouseInteractions.MouseDown) {\n                        thisEventKey = 'TouchStart';\n                    }\n                    else if (MouseInteractions[eventKey] === MouseInteractions.MouseUp) {\n                        thisEventKey = 'TouchEnd';\n                    }\n                }\n                else if (pointerType === PointerTypes.Pen) ;\n            }\n            else if (legacy_isTouchEvent(event)) {\n                pointerType = PointerTypes.Touch;\n            }\n            if (pointerType !== null) {\n                currentPointerType = pointerType;\n                if ((thisEventKey.startsWith('Touch') &&\n                    pointerType === PointerTypes.Touch) ||\n                    (thisEventKey.startsWith('Mouse') &&\n                        pointerType === PointerTypes.Mouse)) {\n                    pointerType = null;\n                }\n            }\n            else if (MouseInteractions[eventKey] === MouseInteractions.Click) {\n                pointerType = currentPointerType;\n                currentPointerType = null;\n            }\n            const e = legacy_isTouchEvent(event) ? event.changedTouches[0] : event;\n            if (!e) {\n                return;\n            }\n            const id = mirror.getId(target);\n            const { clientX, clientY } = e;\n            callbackWrapper(mouseInteractionCb)({\n                type: MouseInteractions[thisEventKey],\n                id,\n                x: clientX,\n                y: clientY,\n                ...(pointerType !== null && { pointerType }),\n            });\n        };\n    };\n    Object.keys(MouseInteractions)\n        .filter((key) => Number.isNaN(Number(key)) &&\n        !key.endsWith('_Departed') &&\n        disableMap[key] !== false)\n        .forEach((eventKey) => {\n        let eventName = toLowerCase(eventKey);\n        const handler = getHandler(eventKey);\n        if (window.PointerEvent) {\n            switch (MouseInteractions[eventKey]) {\n                case MouseInteractions.MouseDown:\n                case MouseInteractions.MouseUp:\n                    eventName = eventName.replace('mouse', 'pointer');\n                    break;\n                case MouseInteractions.TouchStart:\n                case MouseInteractions.TouchEnd:\n                    return;\n            }\n        }\n        handlers.push(on(eventName, handler, doc));\n    });\n    return callbackWrapper(() => {\n        handlers.forEach((h) => h());\n    });\n}\nfunction initScrollObserver({ scrollCb, doc, mirror, blockClass, blockSelector, unblockSelector, sampling, }) {\n    const updatePosition = callbackWrapper(throttle$1(callbackWrapper((evt) => {\n        const target = getEventTarget(evt);\n        if (!target ||\n            isBlocked(target, blockClass, blockSelector, unblockSelector, true)) {\n            return;\n        }\n        const id = mirror.getId(target);\n        if (target === doc && doc.defaultView) {\n            const scrollLeftTop = getWindowScroll(doc.defaultView);\n            scrollCb({\n                id,\n                x: scrollLeftTop.left,\n                y: scrollLeftTop.top,\n            });\n        }\n        else {\n            scrollCb({\n                id,\n                x: target.scrollLeft,\n                y: target.scrollTop,\n            });\n        }\n    }), sampling.scroll || 100));\n    return on('scroll', updatePosition, doc);\n}\nfunction initViewportResizeObserver({ viewportResizeCb }, { win }) {\n    let lastH = -1;\n    let lastW = -1;\n    const updateDimension = callbackWrapper(throttle$1(callbackWrapper(() => {\n        const height = getWindowHeight();\n        const width = getWindowWidth();\n        if (lastH !== height || lastW !== width) {\n            viewportResizeCb({\n                width: Number(width),\n                height: Number(height),\n            });\n            lastH = height;\n            lastW = width;\n        }\n    }), 200));\n    return on('resize', updateDimension, win);\n}\nconst INPUT_TAGS = ['INPUT', 'TEXTAREA', 'SELECT'];\nconst lastInputValueMap = new WeakMap();\nfunction initInputObserver({ inputCb, doc, mirror, blockClass, blockSelector, unblockSelector, ignoreClass, ignoreSelector, maskInputOptions, maskInputFn, sampling, userTriggeredOnInput, maskTextClass, unmaskTextClass, maskTextSelector, unmaskTextSelector, }) {\n    function eventHandler(event) {\n        let target = getEventTarget(event);\n        const userTriggered = event.isTrusted;\n        const tagName = target && toUpperCase(target.tagName);\n        if (tagName === 'OPTION')\n            target = target.parentElement;\n        if (!target ||\n            !tagName ||\n            INPUT_TAGS.indexOf(tagName) < 0 ||\n            isBlocked(target, blockClass, blockSelector, unblockSelector, true)) {\n            return;\n        }\n        const el = target;\n        if (el.classList.contains(ignoreClass) ||\n            (ignoreSelector && el.matches(ignoreSelector))) {\n            return;\n        }\n        const type = getInputType(target);\n        let text = getInputValue(el, tagName, type);\n        let isChecked = false;\n        const isInputMasked = shouldMaskInput({\n            maskInputOptions,\n            tagName,\n            type,\n        });\n        const forceMask = needMaskingText(target, maskTextClass, maskTextSelector, unmaskTextClass, unmaskTextSelector, isInputMasked);\n        if (type === 'radio' || type === 'checkbox') {\n            isChecked = target.checked;\n        }\n        text = maskInputValue({\n            isMasked: forceMask,\n            element: target,\n            value: text,\n            maskInputFn,\n        });\n        cbWithDedup(target, userTriggeredOnInput\n            ? { text, isChecked, userTriggered }\n            : { text, isChecked });\n        const name = target.name;\n        if (type === 'radio' && name && isChecked) {\n            doc\n                .querySelectorAll(`input[type=\"radio\"][name=\"${name}\"]`)\n                .forEach((el) => {\n                if (el !== target) {\n                    const text = maskInputValue({\n                        isMasked: forceMask,\n                        element: el,\n                        value: getInputValue(el, tagName, type),\n                        maskInputFn,\n                    });\n                    cbWithDedup(el, userTriggeredOnInput\n                        ? { text, isChecked: !isChecked, userTriggered: false }\n                        : { text, isChecked: !isChecked });\n                }\n            });\n        }\n    }\n    function cbWithDedup(target, v) {\n        const lastInputValue = lastInputValueMap.get(target);\n        if (!lastInputValue ||\n            lastInputValue.text !== v.text ||\n            lastInputValue.isChecked !== v.isChecked) {\n            lastInputValueMap.set(target, v);\n            const id = mirror.getId(target);\n            callbackWrapper(inputCb)({\n                ...v,\n                id,\n            });\n        }\n    }\n    const events = sampling.input === 'last' ? ['change'] : ['input', 'change'];\n    const handlers = events.map((eventName) => on(eventName, callbackWrapper(eventHandler), doc));\n    const currentWindow = doc.defaultView;\n    if (!currentWindow) {\n        return () => {\n            handlers.forEach((h) => h());\n        };\n    }\n    const propertyDescriptor = currentWindow.Object.getOwnPropertyDescriptor(currentWindow.HTMLInputElement.prototype, 'value');\n    const hookProperties = [\n        [currentWindow.HTMLInputElement.prototype, 'value'],\n        [currentWindow.HTMLInputElement.prototype, 'checked'],\n        [currentWindow.HTMLSelectElement.prototype, 'value'],\n        [currentWindow.HTMLTextAreaElement.prototype, 'value'],\n        [currentWindow.HTMLSelectElement.prototype, 'selectedIndex'],\n        [currentWindow.HTMLOptionElement.prototype, 'selected'],\n    ];\n    if (propertyDescriptor && propertyDescriptor.set) {\n        handlers.push(...hookProperties.map((p) => hookSetter(p[0], p[1], {\n            set() {\n                callbackWrapper(eventHandler)({\n                    target: this,\n                    isTrusted: false,\n                });\n            },\n        }, false, currentWindow)));\n    }\n    return callbackWrapper(() => {\n        handlers.forEach((h) => h());\n    });\n}\nfunction getNestedCSSRulePositions(rule) {\n    const positions = [];\n    function recurse(childRule, pos) {\n        if ((hasNestedCSSRule('CSSGroupingRule') &&\n            childRule.parentRule instanceof CSSGroupingRule) ||\n            (hasNestedCSSRule('CSSMediaRule') &&\n                childRule.parentRule instanceof CSSMediaRule) ||\n            (hasNestedCSSRule('CSSSupportsRule') &&\n                childRule.parentRule instanceof CSSSupportsRule) ||\n            (hasNestedCSSRule('CSSConditionRule') &&\n                childRule.parentRule instanceof CSSConditionRule)) {\n            const rules = Array.from(childRule.parentRule.cssRules);\n            const index = rules.indexOf(childRule);\n            pos.unshift(index);\n        }\n        else if (childRule.parentStyleSheet) {\n            const rules = Array.from(childRule.parentStyleSheet.cssRules);\n            const index = rules.indexOf(childRule);\n            pos.unshift(index);\n        }\n        return pos;\n    }\n    return recurse(rule, positions);\n}\nfunction getIdAndStyleId(sheet, mirror, styleMirror) {\n    let id, styleId;\n    if (!sheet)\n        return {};\n    if (sheet.ownerNode)\n        id = mirror.getId(sheet.ownerNode);\n    else\n        styleId = styleMirror.getId(sheet);\n    return {\n        styleId,\n        id,\n    };\n}\nfunction initStyleSheetObserver({ styleSheetRuleCb, mirror, stylesheetManager }, { win }) {\n    if (!win.CSSStyleSheet || !win.CSSStyleSheet.prototype) {\n        return () => {\n        };\n    }\n    const insertRule = win.CSSStyleSheet.prototype.insertRule;\n    win.CSSStyleSheet.prototype.insertRule = new Proxy(insertRule, {\n        apply: callbackWrapper((target, thisArg, argumentsList) => {\n            const [rule, index] = argumentsList;\n            const { id, styleId } = getIdAndStyleId(thisArg, mirror, stylesheetManager.styleMirror);\n            if ((id && id !== -1) || (styleId && styleId !== -1)) {\n                styleSheetRuleCb({\n                    id,\n                    styleId,\n                    adds: [{ rule, index }],\n                });\n            }\n            return target.apply(thisArg, argumentsList);\n        }),\n    });\n    const deleteRule = win.CSSStyleSheet.prototype.deleteRule;\n    win.CSSStyleSheet.prototype.deleteRule = new Proxy(deleteRule, {\n        apply: callbackWrapper((target, thisArg, argumentsList) => {\n            const [index] = argumentsList;\n            const { id, styleId } = getIdAndStyleId(thisArg, mirror, stylesheetManager.styleMirror);\n            if ((id && id !== -1) || (styleId && styleId !== -1)) {\n                styleSheetRuleCb({\n                    id,\n                    styleId,\n                    removes: [{ index }],\n                });\n            }\n            return target.apply(thisArg, argumentsList);\n        }),\n    });\n    let replace;\n    if (win.CSSStyleSheet.prototype.replace) {\n        replace = win.CSSStyleSheet.prototype.replace;\n        win.CSSStyleSheet.prototype.replace = new Proxy(replace, {\n            apply: callbackWrapper((target, thisArg, argumentsList) => {\n                const [text] = argumentsList;\n                const { id, styleId } = getIdAndStyleId(thisArg, mirror, stylesheetManager.styleMirror);\n                if ((id && id !== -1) || (styleId && styleId !== -1)) {\n                    styleSheetRuleCb({\n                        id,\n                        styleId,\n                        replace: text,\n                    });\n                }\n                return target.apply(thisArg, argumentsList);\n            }),\n        });\n    }\n    let replaceSync;\n    if (win.CSSStyleSheet.prototype.replaceSync) {\n        replaceSync = win.CSSStyleSheet.prototype.replaceSync;\n        win.CSSStyleSheet.prototype.replaceSync = new Proxy(replaceSync, {\n            apply: callbackWrapper((target, thisArg, argumentsList) => {\n                const [text] = argumentsList;\n                const { id, styleId } = getIdAndStyleId(thisArg, mirror, stylesheetManager.styleMirror);\n                if ((id && id !== -1) || (styleId && styleId !== -1)) {\n                    styleSheetRuleCb({\n                        id,\n                        styleId,\n                        replaceSync: text,\n                    });\n                }\n                return target.apply(thisArg, argumentsList);\n            }),\n        });\n    }\n    const supportedNestedCSSRuleTypes = {};\n    if (canMonkeyPatchNestedCSSRule('CSSGroupingRule')) {\n        supportedNestedCSSRuleTypes.CSSGroupingRule = win.CSSGroupingRule;\n    }\n    else {\n        if (canMonkeyPatchNestedCSSRule('CSSMediaRule')) {\n            supportedNestedCSSRuleTypes.CSSMediaRule = win.CSSMediaRule;\n        }\n        if (canMonkeyPatchNestedCSSRule('CSSConditionRule')) {\n            supportedNestedCSSRuleTypes.CSSConditionRule = win.CSSConditionRule;\n        }\n        if (canMonkeyPatchNestedCSSRule('CSSSupportsRule')) {\n            supportedNestedCSSRuleTypes.CSSSupportsRule = win.CSSSupportsRule;\n        }\n    }\n    const unmodifiedFunctions = {};\n    Object.entries(supportedNestedCSSRuleTypes).forEach(([typeKey, type]) => {\n        unmodifiedFunctions[typeKey] = {\n            insertRule: type.prototype.insertRule,\n            deleteRule: type.prototype.deleteRule,\n        };\n        type.prototype.insertRule = new Proxy(unmodifiedFunctions[typeKey].insertRule, {\n            apply: callbackWrapper((target, thisArg, argumentsList) => {\n                const [rule, index] = argumentsList;\n                const { id, styleId } = getIdAndStyleId(thisArg.parentStyleSheet, mirror, stylesheetManager.styleMirror);\n                if ((id && id !== -1) || (styleId && styleId !== -1)) {\n                    styleSheetRuleCb({\n                        id,\n                        styleId,\n                        adds: [\n                            {\n                                rule,\n                                index: [\n                                    ...getNestedCSSRulePositions(thisArg),\n                                    index || 0,\n                                ],\n                            },\n                        ],\n                    });\n                }\n                return target.apply(thisArg, argumentsList);\n            }),\n        });\n        type.prototype.deleteRule = new Proxy(unmodifiedFunctions[typeKey].deleteRule, {\n            apply: callbackWrapper((target, thisArg, argumentsList) => {\n                const [index] = argumentsList;\n                const { id, styleId } = getIdAndStyleId(thisArg.parentStyleSheet, mirror, stylesheetManager.styleMirror);\n                if ((id && id !== -1) || (styleId && styleId !== -1)) {\n                    styleSheetRuleCb({\n                        id,\n                        styleId,\n                        removes: [\n                            { index: [...getNestedCSSRulePositions(thisArg), index] },\n                        ],\n                    });\n                }\n                return target.apply(thisArg, argumentsList);\n            }),\n        });\n    });\n    return callbackWrapper(() => {\n        win.CSSStyleSheet.prototype.insertRule = insertRule;\n        win.CSSStyleSheet.prototype.deleteRule = deleteRule;\n        replace && (win.CSSStyleSheet.prototype.replace = replace);\n        replaceSync && (win.CSSStyleSheet.prototype.replaceSync = replaceSync);\n        Object.entries(supportedNestedCSSRuleTypes).forEach(([typeKey, type]) => {\n            type.prototype.insertRule = unmodifiedFunctions[typeKey].insertRule;\n            type.prototype.deleteRule = unmodifiedFunctions[typeKey].deleteRule;\n        });\n    });\n}\nfunction initAdoptedStyleSheetObserver({ mirror, stylesheetManager, }, host) {\n    let hostId = null;\n    if (host.nodeName === '#document')\n        hostId = mirror.getId(host);\n    else\n        hostId = mirror.getId(host.host);\n    const patchTarget = host.nodeName === '#document'\n        ? _optionalChain$2([host, 'access', _4 => _4.defaultView, 'optionalAccess', _5 => _5.Document])\n        : _optionalChain$2([host, 'access', _6 => _6.ownerDocument, 'optionalAccess', _7 => _7.defaultView, 'optionalAccess', _8 => _8.ShadowRoot]);\n    const originalPropertyDescriptor = _optionalChain$2([patchTarget, 'optionalAccess', _9 => _9.prototype])\n        ? Object.getOwnPropertyDescriptor(_optionalChain$2([patchTarget, 'optionalAccess', _10 => _10.prototype]), 'adoptedStyleSheets')\n        : undefined;\n    if (hostId === null ||\n        hostId === -1 ||\n        !patchTarget ||\n        !originalPropertyDescriptor)\n        return () => {\n        };\n    Object.defineProperty(host, 'adoptedStyleSheets', {\n        configurable: originalPropertyDescriptor.configurable,\n        enumerable: originalPropertyDescriptor.enumerable,\n        get() {\n            return _optionalChain$2([originalPropertyDescriptor, 'access', _11 => _11.get, 'optionalAccess', _12 => _12.call, 'call', _13 => _13(this)]);\n        },\n        set(sheets) {\n            const result = _optionalChain$2([originalPropertyDescriptor, 'access', _14 => _14.set, 'optionalAccess', _15 => _15.call, 'call', _16 => _16(this, sheets)]);\n            if (hostId !== null && hostId !== -1) {\n                try {\n                    stylesheetManager.adoptStyleSheets(sheets, hostId);\n                }\n                catch (e) {\n                }\n            }\n            return result;\n        },\n    });\n    return callbackWrapper(() => {\n        Object.defineProperty(host, 'adoptedStyleSheets', {\n            configurable: originalPropertyDescriptor.configurable,\n            enumerable: originalPropertyDescriptor.enumerable,\n            get: originalPropertyDescriptor.get,\n            set: originalPropertyDescriptor.set,\n        });\n    });\n}\nfunction initStyleDeclarationObserver({ styleDeclarationCb, mirror, ignoreCSSAttributes, stylesheetManager, }, { win }) {\n    const setProperty = win.CSSStyleDeclaration.prototype.setProperty;\n    win.CSSStyleDeclaration.prototype.setProperty = new Proxy(setProperty, {\n        apply: callbackWrapper((target, thisArg, argumentsList) => {\n            const [property, value, priority] = argumentsList;\n            if (ignoreCSSAttributes.has(property)) {\n                return setProperty.apply(thisArg, [property, value, priority]);\n            }\n            const { id, styleId } = getIdAndStyleId(_optionalChain$2([thisArg, 'access', _17 => _17.parentRule, 'optionalAccess', _18 => _18.parentStyleSheet]), mirror, stylesheetManager.styleMirror);\n            if ((id && id !== -1) || (styleId && styleId !== -1)) {\n                styleDeclarationCb({\n                    id,\n                    styleId,\n                    set: {\n                        property,\n                        value,\n                        priority,\n                    },\n                    index: getNestedCSSRulePositions(thisArg.parentRule),\n                });\n            }\n            return target.apply(thisArg, argumentsList);\n        }),\n    });\n    const removeProperty = win.CSSStyleDeclaration.prototype.removeProperty;\n    win.CSSStyleDeclaration.prototype.removeProperty = new Proxy(removeProperty, {\n        apply: callbackWrapper((target, thisArg, argumentsList) => {\n            const [property] = argumentsList;\n            if (ignoreCSSAttributes.has(property)) {\n                return removeProperty.apply(thisArg, [property]);\n            }\n            const { id, styleId } = getIdAndStyleId(_optionalChain$2([thisArg, 'access', _19 => _19.parentRule, 'optionalAccess', _20 => _20.parentStyleSheet]), mirror, stylesheetManager.styleMirror);\n            if ((id && id !== -1) || (styleId && styleId !== -1)) {\n                styleDeclarationCb({\n                    id,\n                    styleId,\n                    remove: {\n                        property,\n                    },\n                    index: getNestedCSSRulePositions(thisArg.parentRule),\n                });\n            }\n            return target.apply(thisArg, argumentsList);\n        }),\n    });\n    return callbackWrapper(() => {\n        win.CSSStyleDeclaration.prototype.setProperty = setProperty;\n        win.CSSStyleDeclaration.prototype.removeProperty = removeProperty;\n    });\n}\nfunction initMediaInteractionObserver({ mediaInteractionCb, blockClass, blockSelector, unblockSelector, mirror, sampling, doc, }) {\n    const handler = callbackWrapper((type) => throttle$1(callbackWrapper((event) => {\n        const target = getEventTarget(event);\n        if (!target ||\n            isBlocked(target, blockClass, blockSelector, unblockSelector, true)) {\n            return;\n        }\n        const { currentTime, volume, muted, playbackRate } = target;\n        mediaInteractionCb({\n            type,\n            id: mirror.getId(target),\n            currentTime,\n            volume,\n            muted,\n            playbackRate,\n        });\n    }), sampling.media || 500));\n    const handlers = [\n        on('play', handler(0), doc),\n        on('pause', handler(1), doc),\n        on('seeked', handler(2), doc),\n        on('volumechange', handler(3), doc),\n        on('ratechange', handler(4), doc),\n    ];\n    return callbackWrapper(() => {\n        handlers.forEach((h) => h());\n    });\n}\nfunction initFontObserver({ fontCb, doc }) {\n    const win = doc.defaultView;\n    if (!win) {\n        return () => {\n        };\n    }\n    const handlers = [];\n    const fontMap = new WeakMap();\n    const originalFontFace = win.FontFace;\n    win.FontFace = function FontFace(family, source, descriptors) {\n        const fontFace = new originalFontFace(family, source, descriptors);\n        fontMap.set(fontFace, {\n            family,\n            buffer: typeof source !== 'string',\n            descriptors,\n            fontSource: typeof source === 'string'\n                ? source\n                : JSON.stringify(Array.from(new Uint8Array(source))),\n        });\n        return fontFace;\n    };\n    const restoreHandler = patch(doc.fonts, 'add', function (original) {\n        return function (fontFace) {\n            setTimeout$1(callbackWrapper(() => {\n                const p = fontMap.get(fontFace);\n                if (p) {\n                    fontCb(p);\n                    fontMap.delete(fontFace);\n                }\n            }), 0);\n            return original.apply(this, [fontFace]);\n        };\n    });\n    handlers.push(() => {\n        win.FontFace = originalFontFace;\n    });\n    handlers.push(restoreHandler);\n    return callbackWrapper(() => {\n        handlers.forEach((h) => h());\n    });\n}\nfunction initSelectionObserver(param) {\n    const { doc, mirror, blockClass, blockSelector, unblockSelector, selectionCb, } = param;\n    let collapsed = true;\n    const updateSelection = callbackWrapper(() => {\n        const selection = doc.getSelection();\n        if (!selection || (collapsed && _optionalChain$2([selection, 'optionalAccess', _21 => _21.isCollapsed])))\n            return;\n        collapsed = selection.isCollapsed || false;\n        const ranges = [];\n        const count = selection.rangeCount || 0;\n        for (let i = 0; i < count; i++) {\n            const range = selection.getRangeAt(i);\n            const { startContainer, startOffset, endContainer, endOffset } = range;\n            const blocked = isBlocked(startContainer, blockClass, blockSelector, unblockSelector, true) ||\n                isBlocked(endContainer, blockClass, blockSelector, unblockSelector, true);\n            if (blocked)\n                continue;\n            ranges.push({\n                start: mirror.getId(startContainer),\n                startOffset,\n                end: mirror.getId(endContainer),\n                endOffset,\n            });\n        }\n        selectionCb({ ranges });\n    });\n    updateSelection();\n    return on('selectionchange', updateSelection);\n}\nfunction initCustomElementObserver({ doc, customElementCb, }) {\n    const win = doc.defaultView;\n    if (!win || !win.customElements)\n        return () => { };\n    const restoreHandler = patch(win.customElements, 'define', function (original) {\n        return function (name, constructor, options) {\n            try {\n                customElementCb({\n                    define: {\n                        name,\n                    },\n                });\n            }\n            catch (e) {\n            }\n            return original.apply(this, [name, constructor, options]);\n        };\n    });\n    return restoreHandler;\n}\nfunction initObservers(o, _hooks = {}) {\n    const currentWindow = o.doc.defaultView;\n    if (!currentWindow) {\n        return () => {\n        };\n    }\n    let mutationObserver;\n    if (o.recordDOM) {\n        mutationObserver = initMutationObserver(o, o.doc);\n    }\n    const mousemoveHandler = initMoveObserver(o);\n    const mouseInteractionHandler = initMouseInteractionObserver(o);\n    const scrollHandler = initScrollObserver(o);\n    const viewportResizeHandler = initViewportResizeObserver(o, {\n        win: currentWindow,\n    });\n    const inputHandler = initInputObserver(o);\n    const mediaInteractionHandler = initMediaInteractionObserver(o);\n    let styleSheetObserver = () => { };\n    let adoptedStyleSheetObserver = () => { };\n    let styleDeclarationObserver = () => { };\n    let fontObserver = () => { };\n    if (o.recordDOM) {\n        styleSheetObserver = initStyleSheetObserver(o, { win: currentWindow });\n        adoptedStyleSheetObserver = initAdoptedStyleSheetObserver(o, o.doc);\n        styleDeclarationObserver = initStyleDeclarationObserver(o, {\n            win: currentWindow,\n        });\n        if (o.collectFonts) {\n            fontObserver = initFontObserver(o);\n        }\n    }\n    const selectionObserver = initSelectionObserver(o);\n    const customElementObserver = initCustomElementObserver(o);\n    const pluginHandlers = [];\n    for (const plugin of o.plugins) {\n        pluginHandlers.push(plugin.observer(plugin.callback, currentWindow, plugin.options));\n    }\n    return callbackWrapper(() => {\n        mutationBuffers.forEach((b) => b.reset());\n        _optionalChain$2([mutationObserver, 'optionalAccess', _22 => _22.disconnect, 'call', _23 => _23()]);\n        mousemoveHandler();\n        mouseInteractionHandler();\n        scrollHandler();\n        viewportResizeHandler();\n        inputHandler();\n        mediaInteractionHandler();\n        styleSheetObserver();\n        adoptedStyleSheetObserver();\n        styleDeclarationObserver();\n        fontObserver();\n        selectionObserver();\n        customElementObserver();\n        pluginHandlers.forEach((h) => h());\n    });\n}\nfunction hasNestedCSSRule(prop) {\n    return typeof window[prop] !== 'undefined';\n}\nfunction canMonkeyPatchNestedCSSRule(prop) {\n    return Boolean(typeof window[prop] !== 'undefined' &&\n        window[prop].prototype &&\n        'insertRule' in window[prop].prototype &&\n        'deleteRule' in window[prop].prototype);\n}\n\nclass CrossOriginIframeMirror {\n    constructor(generateIdFn) {\n        this.generateIdFn = generateIdFn;\n        this.iframeIdToRemoteIdMap = new WeakMap();\n        this.iframeRemoteIdToIdMap = new WeakMap();\n    }\n    getId(iframe, remoteId, idToRemoteMap, remoteToIdMap) {\n        const idToRemoteIdMap = idToRemoteMap || this.getIdToRemoteIdMap(iframe);\n        const remoteIdToIdMap = remoteToIdMap || this.getRemoteIdToIdMap(iframe);\n        let id = idToRemoteIdMap.get(remoteId);\n        if (!id) {\n            id = this.generateIdFn();\n            idToRemoteIdMap.set(remoteId, id);\n            remoteIdToIdMap.set(id, remoteId);\n        }\n        return id;\n    }\n    getIds(iframe, remoteId) {\n        const idToRemoteIdMap = this.getIdToRemoteIdMap(iframe);\n        const remoteIdToIdMap = this.getRemoteIdToIdMap(iframe);\n        return remoteId.map((id) => this.getId(iframe, id, idToRemoteIdMap, remoteIdToIdMap));\n    }\n    getRemoteId(iframe, id, map) {\n        const remoteIdToIdMap = map || this.getRemoteIdToIdMap(iframe);\n        if (typeof id !== 'number')\n            return id;\n        const remoteId = remoteIdToIdMap.get(id);\n        if (!remoteId)\n            return -1;\n        return remoteId;\n    }\n    getRemoteIds(iframe, ids) {\n        const remoteIdToIdMap = this.getRemoteIdToIdMap(iframe);\n        return ids.map((id) => this.getRemoteId(iframe, id, remoteIdToIdMap));\n    }\n    reset(iframe) {\n        if (!iframe) {\n            this.iframeIdToRemoteIdMap = new WeakMap();\n            this.iframeRemoteIdToIdMap = new WeakMap();\n            return;\n        }\n        this.iframeIdToRemoteIdMap.delete(iframe);\n        this.iframeRemoteIdToIdMap.delete(iframe);\n    }\n    getIdToRemoteIdMap(iframe) {\n        let idToRemoteIdMap = this.iframeIdToRemoteIdMap.get(iframe);\n        if (!idToRemoteIdMap) {\n            idToRemoteIdMap = new Map();\n            this.iframeIdToRemoteIdMap.set(iframe, idToRemoteIdMap);\n        }\n        return idToRemoteIdMap;\n    }\n    getRemoteIdToIdMap(iframe) {\n        let remoteIdToIdMap = this.iframeRemoteIdToIdMap.get(iframe);\n        if (!remoteIdToIdMap) {\n            remoteIdToIdMap = new Map();\n            this.iframeRemoteIdToIdMap.set(iframe, remoteIdToIdMap);\n        }\n        return remoteIdToIdMap;\n    }\n}\n\nfunction _optionalChain$1(ops) { let lastAccessLHS = undefined; let value = ops[0]; let i = 1; while (i < ops.length) { const op = ops[i]; const fn = ops[i + 1]; i += 2; if ((op === 'optionalAccess' || op === 'optionalCall') && value == null) { return undefined; } if (op === 'access' || op === 'optionalAccess') { lastAccessLHS = value; value = fn(value); } else if (op === 'call' || op === 'optionalCall') { value = fn((...args) => value.call(lastAccessLHS, ...args)); lastAccessLHS = undefined; } } return value; }\nclass IframeManagerNoop {\n    constructor() {\n        this.crossOriginIframeMirror = new CrossOriginIframeMirror(genId);\n        this.crossOriginIframeRootIdMap = new WeakMap();\n    }\n    addIframe() {\n    }\n    addLoadListener() {\n    }\n    attachIframe() {\n    }\n}\nclass IframeManager {\n    constructor(options) {\n        this.iframes = new WeakMap();\n        this.crossOriginIframeMap = new WeakMap();\n        this.crossOriginIframeMirror = new CrossOriginIframeMirror(genId);\n        this.crossOriginIframeRootIdMap = new WeakMap();\n        this.mutationCb = options.mutationCb;\n        this.wrappedEmit = options.wrappedEmit;\n        this.stylesheetManager = options.stylesheetManager;\n        this.recordCrossOriginIframes = options.recordCrossOriginIframes;\n        this.crossOriginIframeStyleMirror = new CrossOriginIframeMirror(this.stylesheetManager.styleMirror.generateId.bind(this.stylesheetManager.styleMirror));\n        this.mirror = options.mirror;\n        if (this.recordCrossOriginIframes) {\n            window.addEventListener('message', this.handleMessage.bind(this));\n        }\n    }\n    addIframe(iframeEl) {\n        this.iframes.set(iframeEl, true);\n        if (iframeEl.contentWindow)\n            this.crossOriginIframeMap.set(iframeEl.contentWindow, iframeEl);\n    }\n    addLoadListener(cb) {\n        this.loadListener = cb;\n    }\n    attachIframe(iframeEl, childSn) {\n        this.mutationCb({\n            adds: [\n                {\n                    parentId: this.mirror.getId(iframeEl),\n                    nextId: null,\n                    node: childSn,\n                },\n            ],\n            removes: [],\n            texts: [],\n            attributes: [],\n            isAttachIframe: true,\n        });\n        _optionalChain$1([this, 'access', _ => _.loadListener, 'optionalCall', _2 => _2(iframeEl)]);\n        if (iframeEl.contentDocument &&\n            iframeEl.contentDocument.adoptedStyleSheets &&\n            iframeEl.contentDocument.adoptedStyleSheets.length > 0)\n            this.stylesheetManager.adoptStyleSheets(iframeEl.contentDocument.adoptedStyleSheets, this.mirror.getId(iframeEl.contentDocument));\n    }\n    handleMessage(message) {\n        const crossOriginMessageEvent = message;\n        if (crossOriginMessageEvent.data.type !== 'rrweb' ||\n            crossOriginMessageEvent.origin !== crossOriginMessageEvent.data.origin)\n            return;\n        const iframeSourceWindow = message.source;\n        if (!iframeSourceWindow)\n            return;\n        const iframeEl = this.crossOriginIframeMap.get(message.source);\n        if (!iframeEl)\n            return;\n        const transformedEvent = this.transformCrossOriginEvent(iframeEl, crossOriginMessageEvent.data.event);\n        if (transformedEvent)\n            this.wrappedEmit(transformedEvent, crossOriginMessageEvent.data.isCheckout);\n    }\n    transformCrossOriginEvent(iframeEl, e) {\n        switch (e.type) {\n            case EventType.FullSnapshot: {\n                this.crossOriginIframeMirror.reset(iframeEl);\n                this.crossOriginIframeStyleMirror.reset(iframeEl);\n                this.replaceIdOnNode(e.data.node, iframeEl);\n                const rootId = e.data.node.id;\n                this.crossOriginIframeRootIdMap.set(iframeEl, rootId);\n                this.patchRootIdOnNode(e.data.node, rootId);\n                return {\n                    timestamp: e.timestamp,\n                    type: EventType.IncrementalSnapshot,\n                    data: {\n                        source: IncrementalSource.Mutation,\n                        adds: [\n                            {\n                                parentId: this.mirror.getId(iframeEl),\n                                nextId: null,\n                                node: e.data.node,\n                            },\n                        ],\n                        removes: [],\n                        texts: [],\n                        attributes: [],\n                        isAttachIframe: true,\n                    },\n                };\n            }\n            case EventType.Meta:\n            case EventType.Load:\n            case EventType.DomContentLoaded: {\n                return false;\n            }\n            case EventType.Plugin: {\n                return e;\n            }\n            case EventType.Custom: {\n                this.replaceIds(e.data.payload, iframeEl, ['id', 'parentId', 'previousId', 'nextId']);\n                return e;\n            }\n            case EventType.IncrementalSnapshot: {\n                switch (e.data.source) {\n                    case IncrementalSource.Mutation: {\n                        e.data.adds.forEach((n) => {\n                            this.replaceIds(n, iframeEl, [\n                                'parentId',\n                                'nextId',\n                                'previousId',\n                            ]);\n                            this.replaceIdOnNode(n.node, iframeEl);\n                            const rootId = this.crossOriginIframeRootIdMap.get(iframeEl);\n                            rootId && this.patchRootIdOnNode(n.node, rootId);\n                        });\n                        e.data.removes.forEach((n) => {\n                            this.replaceIds(n, iframeEl, ['parentId', 'id']);\n                        });\n                        e.data.attributes.forEach((n) => {\n                            this.replaceIds(n, iframeEl, ['id']);\n                        });\n                        e.data.texts.forEach((n) => {\n                            this.replaceIds(n, iframeEl, ['id']);\n                        });\n                        return e;\n                    }\n                    case IncrementalSource.Drag:\n                    case IncrementalSource.TouchMove:\n                    case IncrementalSource.MouseMove: {\n                        e.data.positions.forEach((p) => {\n                            this.replaceIds(p, iframeEl, ['id']);\n                        });\n                        return e;\n                    }\n                    case IncrementalSource.ViewportResize: {\n                        return false;\n                    }\n                    case IncrementalSource.MediaInteraction:\n                    case IncrementalSource.MouseInteraction:\n                    case IncrementalSource.Scroll:\n                    case IncrementalSource.CanvasMutation:\n                    case IncrementalSource.Input: {\n                        this.replaceIds(e.data, iframeEl, ['id']);\n                        return e;\n                    }\n                    case IncrementalSource.StyleSheetRule:\n                    case IncrementalSource.StyleDeclaration: {\n                        this.replaceIds(e.data, iframeEl, ['id']);\n                        this.replaceStyleIds(e.data, iframeEl, ['styleId']);\n                        return e;\n                    }\n                    case IncrementalSource.Font: {\n                        return e;\n                    }\n                    case IncrementalSource.Selection: {\n                        e.data.ranges.forEach((range) => {\n                            this.replaceIds(range, iframeEl, ['start', 'end']);\n                        });\n                        return e;\n                    }\n                    case IncrementalSource.AdoptedStyleSheet: {\n                        this.replaceIds(e.data, iframeEl, ['id']);\n                        this.replaceStyleIds(e.data, iframeEl, ['styleIds']);\n                        _optionalChain$1([e, 'access', _3 => _3.data, 'access', _4 => _4.styles, 'optionalAccess', _5 => _5.forEach, 'call', _6 => _6((style) => {\n                            this.replaceStyleIds(style, iframeEl, ['styleId']);\n                        })]);\n                        return e;\n                    }\n                }\n            }\n        }\n        return false;\n    }\n    replace(iframeMirror, obj, iframeEl, keys) {\n        for (const key of keys) {\n            if (!Array.isArray(obj[key]) && typeof obj[key] !== 'number')\n                continue;\n            if (Array.isArray(obj[key])) {\n                obj[key] = iframeMirror.getIds(iframeEl, obj[key]);\n            }\n            else {\n                obj[key] = iframeMirror.getId(iframeEl, obj[key]);\n            }\n        }\n        return obj;\n    }\n    replaceIds(obj, iframeEl, keys) {\n        return this.replace(this.crossOriginIframeMirror, obj, iframeEl, keys);\n    }\n    replaceStyleIds(obj, iframeEl, keys) {\n        return this.replace(this.crossOriginIframeStyleMirror, obj, iframeEl, keys);\n    }\n    replaceIdOnNode(node, iframeEl) {\n        this.replaceIds(node, iframeEl, ['id', 'rootId']);\n        if ('childNodes' in node) {\n            node.childNodes.forEach((child) => {\n                this.replaceIdOnNode(child, iframeEl);\n            });\n        }\n    }\n    patchRootIdOnNode(node, rootId) {\n        if (node.type !== NodeType$1.Document && !node.rootId)\n            node.rootId = rootId;\n        if ('childNodes' in node) {\n            node.childNodes.forEach((child) => {\n                this.patchRootIdOnNode(child, rootId);\n            });\n        }\n    }\n}\n\nclass ShadowDomManagerNoop {\n    init() {\n    }\n    addShadowRoot() {\n    }\n    observeAttachShadow() {\n    }\n    reset() {\n    }\n}\nclass ShadowDomManager {\n    constructor(options) {\n        this.shadowDoms = new WeakSet();\n        this.restoreHandlers = [];\n        this.mutationCb = options.mutationCb;\n        this.scrollCb = options.scrollCb;\n        this.bypassOptions = options.bypassOptions;\n        this.mirror = options.mirror;\n        this.init();\n    }\n    init() {\n        this.reset();\n        this.patchAttachShadow(Element, document);\n    }\n    addShadowRoot(shadowRoot, doc) {\n        if (!isNativeShadowDom(shadowRoot))\n            return;\n        if (this.shadowDoms.has(shadowRoot))\n            return;\n        this.shadowDoms.add(shadowRoot);\n        this.bypassOptions.canvasManager.addShadowRoot(shadowRoot);\n        const observer = initMutationObserver({\n            ...this.bypassOptions,\n            doc,\n            mutationCb: this.mutationCb,\n            mirror: this.mirror,\n            shadowDomManager: this,\n        }, shadowRoot);\n        this.restoreHandlers.push(() => observer.disconnect());\n        this.restoreHandlers.push(initScrollObserver({\n            ...this.bypassOptions,\n            scrollCb: this.scrollCb,\n            doc: shadowRoot,\n            mirror: this.mirror,\n        }));\n        setTimeout$1(() => {\n            if (shadowRoot.adoptedStyleSheets &&\n                shadowRoot.adoptedStyleSheets.length > 0)\n                this.bypassOptions.stylesheetManager.adoptStyleSheets(shadowRoot.adoptedStyleSheets, this.mirror.getId(shadowRoot.host));\n            this.restoreHandlers.push(initAdoptedStyleSheetObserver({\n                mirror: this.mirror,\n                stylesheetManager: this.bypassOptions.stylesheetManager,\n            }, shadowRoot));\n        }, 0);\n    }\n    observeAttachShadow(iframeElement) {\n        if (!iframeElement.contentWindow || !iframeElement.contentDocument)\n            return;\n        this.patchAttachShadow(iframeElement.contentWindow.Element, iframeElement.contentDocument);\n    }\n    patchAttachShadow(element, doc) {\n        const manager = this;\n        this.restoreHandlers.push(patch(element.prototype, 'attachShadow', function (original) {\n            return function (option) {\n                const shadowRoot = original.call(this, option);\n                if (this.shadowRoot && inDom(this))\n                    manager.addShadowRoot(this.shadowRoot, doc);\n                return shadowRoot;\n            };\n        }));\n    }\n    reset() {\n        this.restoreHandlers.forEach((handler) => {\n            try {\n                handler();\n            }\n            catch (e) {\n            }\n        });\n        this.restoreHandlers = [];\n        this.shadowDoms = new WeakSet();\n        this.bypassOptions.canvasManager.resetShadowRoots();\n    }\n}\n\nclass CanvasManagerNoop {\n    reset() {\n    }\n    freeze() {\n    }\n    unfreeze() {\n    }\n    lock() {\n    }\n    unlock() {\n    }\n    snapshot() {\n    }\n    addWindow() {\n    }\n    addShadowRoot() {\n    }\n    resetShadowRoots() {\n    }\n}\n\nclass StylesheetManager {\n    constructor(options) {\n        this.trackedLinkElements = new WeakSet();\n        this.styleMirror = new StyleSheetMirror();\n        this.mutationCb = options.mutationCb;\n        this.adoptedStyleSheetCb = options.adoptedStyleSheetCb;\n    }\n    attachLinkElement(linkEl, childSn) {\n        if ('_cssText' in childSn.attributes)\n            this.mutationCb({\n                adds: [],\n                removes: [],\n                texts: [],\n                attributes: [\n                    {\n                        id: childSn.id,\n                        attributes: childSn\n                            .attributes,\n                    },\n                ],\n            });\n        this.trackLinkElement(linkEl);\n    }\n    trackLinkElement(linkEl) {\n        if (this.trackedLinkElements.has(linkEl))\n            return;\n        this.trackedLinkElements.add(linkEl);\n        this.trackStylesheetInLinkElement(linkEl);\n    }\n    adoptStyleSheets(sheets, hostId) {\n        if (sheets.length === 0)\n            return;\n        const adoptedStyleSheetData = {\n            id: hostId,\n            styleIds: [],\n        };\n        const styles = [];\n        for (const sheet of sheets) {\n            let styleId;\n            if (!this.styleMirror.has(sheet)) {\n                styleId = this.styleMirror.add(sheet);\n                styles.push({\n                    styleId,\n                    rules: Array.from(sheet.rules || CSSRule, (r, index) => ({\n                        rule: stringifyRule(r),\n                        index,\n                    })),\n                });\n            }\n            else\n                styleId = this.styleMirror.getId(sheet);\n            adoptedStyleSheetData.styleIds.push(styleId);\n        }\n        if (styles.length > 0)\n            adoptedStyleSheetData.styles = styles;\n        this.adoptedStyleSheetCb(adoptedStyleSheetData);\n    }\n    reset() {\n        this.styleMirror.reset();\n        this.trackedLinkElements = new WeakSet();\n    }\n    trackStylesheetInLinkElement(linkEl) {\n    }\n}\n\nclass ProcessedNodeManager {\n    constructor() {\n        this.nodeMap = new WeakMap();\n        this.active = false;\n    }\n    inOtherBuffer(node, thisBuffer) {\n        const buffers = this.nodeMap.get(node);\n        return (buffers && Array.from(buffers).some((buffer) => buffer !== thisBuffer));\n    }\n    add(node, buffer) {\n        if (!this.active) {\n            this.active = true;\n            onRequestAnimationFrame(() => {\n                this.nodeMap = new WeakMap();\n                this.active = false;\n            });\n        }\n        this.nodeMap.set(node, (this.nodeMap.get(node) || new Set()).add(buffer));\n    }\n    destroy() {\n    }\n}\n\nlet wrappedEmit;\nlet _takeFullSnapshot;\ntry {\n    if (Array.from([1], (x) => x * 2)[0] !== 2) {\n        const cleanFrame = document.createElement('iframe');\n        document.body.appendChild(cleanFrame);\n        Array.from = _optionalChain([cleanFrame, 'access', _ => _.contentWindow, 'optionalAccess', _2 => _2.Array, 'access', _3 => _3.from]) || Array.from;\n        document.body.removeChild(cleanFrame);\n    }\n}\ncatch (err) {\n    console.debug('Unable to override Array.from', err);\n}\nconst mirror = createMirror();\nfunction record(options = {}) {\n    const { emit, checkoutEveryNms, checkoutEveryNth, blockClass = 'rr-block', blockSelector = null, unblockSelector = null, ignoreClass = 'rr-ignore', ignoreSelector = null, maskAllText = false, maskTextClass = 'rr-mask', unmaskTextClass = null, maskTextSelector = null, unmaskTextSelector = null, inlineStylesheet = true, maskAllInputs, maskInputOptions: _maskInputOptions, slimDOMOptions: _slimDOMOptions, maskAttributeFn, maskInputFn, maskTextFn, maxCanvasSize = null, packFn, sampling = {}, dataURLOptions = {}, mousemoveWait, recordDOM = true, recordCanvas = false, recordCrossOriginIframes = false, recordAfter = options.recordAfter === 'DOMContentLoaded'\n        ? options.recordAfter\n        : 'load', userTriggeredOnInput = false, collectFonts = false, inlineImages = false, plugins, keepIframeSrcFn = () => false, ignoreCSSAttributes = new Set([]), errorHandler, onMutation, getCanvasManager, } = options;\n    registerErrorHandler(errorHandler);\n    const inEmittingFrame = recordCrossOriginIframes\n        ? window.parent === window\n        : true;\n    let passEmitsToParent = false;\n    if (!inEmittingFrame) {\n        try {\n            if (window.parent.document) {\n                passEmitsToParent = false;\n            }\n        }\n        catch (e) {\n            passEmitsToParent = true;\n        }\n    }\n    if (inEmittingFrame && !emit) {\n        throw new Error('emit function is required');\n    }\n    if (!inEmittingFrame && !passEmitsToParent) {\n        return () => {\n        };\n    }\n    if (mousemoveWait !== undefined && sampling.mousemove === undefined) {\n        sampling.mousemove = mousemoveWait;\n    }\n    mirror.reset();\n    const maskInputOptions = maskAllInputs === true\n        ? {\n            color: true,\n            date: true,\n            'datetime-local': true,\n            email: true,\n            month: true,\n            number: true,\n            range: true,\n            search: true,\n            tel: true,\n            text: true,\n            time: true,\n            url: true,\n            week: true,\n            textarea: true,\n            select: true,\n            radio: true,\n            checkbox: true,\n        }\n        : _maskInputOptions !== undefined\n            ? _maskInputOptions\n            : {};\n    const slimDOMOptions = _slimDOMOptions === true || _slimDOMOptions === 'all'\n        ? {\n            script: true,\n            comment: true,\n            headFavicon: true,\n            headWhitespace: true,\n            headMetaSocial: true,\n            headMetaRobots: true,\n            headMetaHttpEquiv: true,\n            headMetaVerification: true,\n            headMetaAuthorship: _slimDOMOptions === 'all',\n            headMetaDescKeywords: _slimDOMOptions === 'all',\n        }\n        : _slimDOMOptions\n            ? _slimDOMOptions\n            : {};\n    polyfill();\n    let lastFullSnapshotEvent;\n    let incrementalSnapshotCount = 0;\n    const eventProcessor = (e) => {\n        for (const plugin of plugins || []) {\n            if (plugin.eventProcessor) {\n                e = plugin.eventProcessor(e);\n            }\n        }\n        if (packFn &&\n            !passEmitsToParent) {\n            e = packFn(e);\n        }\n        return e;\n    };\n    wrappedEmit = (r, isCheckout) => {\n        const e = r;\n        e.timestamp = nowTimestamp();\n        if (_optionalChain([mutationBuffers, 'access', _4 => _4[0], 'optionalAccess', _5 => _5.isFrozen, 'call', _6 => _6()]) &&\n            e.type !== EventType.FullSnapshot &&\n            !(e.type === EventType.IncrementalSnapshot &&\n                e.data.source === IncrementalSource.Mutation)) {\n            mutationBuffers.forEach((buf) => buf.unfreeze());\n        }\n        if (inEmittingFrame) {\n            _optionalChain([emit, 'optionalCall', _7 => _7(eventProcessor(e), isCheckout)]);\n        }\n        else if (passEmitsToParent) {\n            const message = {\n                type: 'rrweb',\n                event: eventProcessor(e),\n                origin: window.location.origin,\n                isCheckout,\n            };\n            window.parent.postMessage(message, '*');\n        }\n        if (e.type === EventType.FullSnapshot) {\n            lastFullSnapshotEvent = e;\n            incrementalSnapshotCount = 0;\n        }\n        else if (e.type === EventType.IncrementalSnapshot) {\n            if (e.data.source === IncrementalSource.Mutation &&\n                e.data.isAttachIframe) {\n                return;\n            }\n            incrementalSnapshotCount++;\n            const exceedCount = checkoutEveryNth && incrementalSnapshotCount >= checkoutEveryNth;\n            const exceedTime = checkoutEveryNms &&\n                lastFullSnapshotEvent &&\n                e.timestamp - lastFullSnapshotEvent.timestamp > checkoutEveryNms;\n            if (exceedCount || exceedTime) {\n                takeFullSnapshot(true);\n            }\n        }\n    };\n    const wrappedMutationEmit = (m) => {\n        wrappedEmit({\n            type: EventType.IncrementalSnapshot,\n            data: {\n                source: IncrementalSource.Mutation,\n                ...m,\n            },\n        });\n    };\n    const wrappedScrollEmit = (p) => wrappedEmit({\n        type: EventType.IncrementalSnapshot,\n        data: {\n            source: IncrementalSource.Scroll,\n            ...p,\n        },\n    });\n    const wrappedCanvasMutationEmit = (p) => wrappedEmit({\n        type: EventType.IncrementalSnapshot,\n        data: {\n            source: IncrementalSource.CanvasMutation,\n            ...p,\n        },\n    });\n    const wrappedAdoptedStyleSheetEmit = (a) => wrappedEmit({\n        type: EventType.IncrementalSnapshot,\n        data: {\n            source: IncrementalSource.AdoptedStyleSheet,\n            ...a,\n        },\n    });\n    const stylesheetManager = new StylesheetManager({\n        mutationCb: wrappedMutationEmit,\n        adoptedStyleSheetCb: wrappedAdoptedStyleSheetEmit,\n    });\n    const iframeManager = typeof __RRWEB_EXCLUDE_IFRAME__ === 'boolean' && __RRWEB_EXCLUDE_IFRAME__\n        ? new IframeManagerNoop()\n        : new IframeManager({\n            mirror,\n            mutationCb: wrappedMutationEmit,\n            stylesheetManager: stylesheetManager,\n            recordCrossOriginIframes,\n            wrappedEmit,\n        });\n    for (const plugin of plugins || []) {\n        if (plugin.getMirror)\n            plugin.getMirror({\n                nodeMirror: mirror,\n                crossOriginIframeMirror: iframeManager.crossOriginIframeMirror,\n                crossOriginIframeStyleMirror: iframeManager.crossOriginIframeStyleMirror,\n            });\n    }\n    const processedNodeManager = new ProcessedNodeManager();\n    const canvasManager = _getCanvasManager(getCanvasManager, {\n        mirror,\n        win: window,\n        mutationCb: (p) => wrappedEmit({\n            type: EventType.IncrementalSnapshot,\n            data: {\n                source: IncrementalSource.CanvasMutation,\n                ...p,\n            },\n        }),\n        recordCanvas,\n        blockClass,\n        blockSelector,\n        unblockSelector,\n        maxCanvasSize,\n        sampling: sampling['canvas'],\n        dataURLOptions,\n        errorHandler,\n    });\n    const shadowDomManager = typeof __RRWEB_EXCLUDE_SHADOW_DOM__ === 'boolean' &&\n        __RRWEB_EXCLUDE_SHADOW_DOM__\n        ? new ShadowDomManagerNoop()\n        : new ShadowDomManager({\n            mutationCb: wrappedMutationEmit,\n            scrollCb: wrappedScrollEmit,\n            bypassOptions: {\n                onMutation,\n                blockClass,\n                blockSelector,\n                unblockSelector,\n                maskAllText,\n                maskTextClass,\n                unmaskTextClass,\n                maskTextSelector,\n                unmaskTextSelector,\n                inlineStylesheet,\n                maskInputOptions,\n                dataURLOptions,\n                maskAttributeFn,\n                maskTextFn,\n                maskInputFn,\n                recordCanvas,\n                inlineImages,\n                sampling,\n                slimDOMOptions,\n                iframeManager,\n                stylesheetManager,\n                canvasManager,\n                keepIframeSrcFn,\n                processedNodeManager,\n            },\n            mirror,\n        });\n    const takeFullSnapshot = (isCheckout = false) => {\n        if (!recordDOM) {\n            return;\n        }\n        wrappedEmit({\n            type: EventType.Meta,\n            data: {\n                href: window.location.href,\n                width: getWindowWidth(),\n                height: getWindowHeight(),\n            },\n        }, isCheckout);\n        stylesheetManager.reset();\n        shadowDomManager.init();\n        mutationBuffers.forEach((buf) => buf.lock());\n        const node = snapshot(document, {\n            mirror,\n            blockClass,\n            blockSelector,\n            unblockSelector,\n            maskAllText,\n            maskTextClass,\n            unmaskTextClass,\n            maskTextSelector,\n            unmaskTextSelector,\n            inlineStylesheet,\n            maskAllInputs: maskInputOptions,\n            maskAttributeFn,\n            maskInputFn,\n            maskTextFn,\n            slimDOM: slimDOMOptions,\n            dataURLOptions,\n            recordCanvas,\n            inlineImages,\n            onSerialize: (n) => {\n                if (isSerializedIframe(n, mirror)) {\n                    iframeManager.addIframe(n);\n                }\n                if (isSerializedStylesheet(n, mirror)) {\n                    stylesheetManager.trackLinkElement(n);\n                }\n                if (hasShadowRoot(n)) {\n                    shadowDomManager.addShadowRoot(n.shadowRoot, document);\n                }\n            },\n            onIframeLoad: (iframe, childSn) => {\n                iframeManager.attachIframe(iframe, childSn);\n                if (iframe.contentWindow) {\n                    canvasManager.addWindow(iframe.contentWindow);\n                }\n                shadowDomManager.observeAttachShadow(iframe);\n            },\n            onStylesheetLoad: (linkEl, childSn) => {\n                stylesheetManager.attachLinkElement(linkEl, childSn);\n            },\n            keepIframeSrcFn,\n        });\n        if (!node) {\n            return console.warn('Failed to snapshot the document');\n        }\n        wrappedEmit({\n            type: EventType.FullSnapshot,\n            data: {\n                node,\n                initialOffset: getWindowScroll(window),\n            },\n        });\n        mutationBuffers.forEach((buf) => buf.unlock());\n        if (document.adoptedStyleSheets && document.adoptedStyleSheets.length > 0)\n            stylesheetManager.adoptStyleSheets(document.adoptedStyleSheets, mirror.getId(document));\n    };\n    _takeFullSnapshot = takeFullSnapshot;\n    try {\n        const handlers = [];\n        const observe = (doc) => {\n            return callbackWrapper(initObservers)({\n                onMutation,\n                mutationCb: wrappedMutationEmit,\n                mousemoveCb: (positions, source) => wrappedEmit({\n                    type: EventType.IncrementalSnapshot,\n                    data: {\n                        source,\n                        positions,\n                    },\n                }),\n                mouseInteractionCb: (d) => wrappedEmit({\n                    type: EventType.IncrementalSnapshot,\n                    data: {\n                        source: IncrementalSource.MouseInteraction,\n                        ...d,\n                    },\n                }),\n                scrollCb: wrappedScrollEmit,\n                viewportResizeCb: (d) => wrappedEmit({\n                    type: EventType.IncrementalSnapshot,\n                    data: {\n                        source: IncrementalSource.ViewportResize,\n                        ...d,\n                    },\n                }),\n                inputCb: (v) => wrappedEmit({\n                    type: EventType.IncrementalSnapshot,\n                    data: {\n                        source: IncrementalSource.Input,\n                        ...v,\n                    },\n                }),\n                mediaInteractionCb: (p) => wrappedEmit({\n                    type: EventType.IncrementalSnapshot,\n                    data: {\n                        source: IncrementalSource.MediaInteraction,\n                        ...p,\n                    },\n                }),\n                styleSheetRuleCb: (r) => wrappedEmit({\n                    type: EventType.IncrementalSnapshot,\n                    data: {\n                        source: IncrementalSource.StyleSheetRule,\n                        ...r,\n                    },\n                }),\n                styleDeclarationCb: (r) => wrappedEmit({\n                    type: EventType.IncrementalSnapshot,\n                    data: {\n                        source: IncrementalSource.StyleDeclaration,\n                        ...r,\n                    },\n                }),\n                canvasMutationCb: wrappedCanvasMutationEmit,\n                fontCb: (p) => wrappedEmit({\n                    type: EventType.IncrementalSnapshot,\n                    data: {\n                        source: IncrementalSource.Font,\n                        ...p,\n                    },\n                }),\n                selectionCb: (p) => {\n                    wrappedEmit({\n                        type: EventType.IncrementalSnapshot,\n                        data: {\n                            source: IncrementalSource.Selection,\n                            ...p,\n                        },\n                    });\n                },\n                customElementCb: (c) => {\n                    wrappedEmit({\n                        type: EventType.IncrementalSnapshot,\n                        data: {\n                            source: IncrementalSource.CustomElement,\n                            ...c,\n                        },\n                    });\n                },\n                blockClass,\n                ignoreClass,\n                ignoreSelector,\n                maskAllText,\n                maskTextClass,\n                unmaskTextClass,\n                maskTextSelector,\n                unmaskTextSelector,\n                maskInputOptions,\n                inlineStylesheet,\n                sampling,\n                recordDOM,\n                recordCanvas,\n                inlineImages,\n                userTriggeredOnInput,\n                collectFonts,\n                doc,\n                maskAttributeFn,\n                maskInputFn,\n                maskTextFn,\n                keepIframeSrcFn,\n                blockSelector,\n                unblockSelector,\n                slimDOMOptions,\n                dataURLOptions,\n                mirror,\n                iframeManager,\n                stylesheetManager,\n                shadowDomManager,\n                processedNodeManager,\n                canvasManager,\n                ignoreCSSAttributes,\n                plugins: _optionalChain([plugins\n, 'optionalAccess', _8 => _8.filter, 'call', _9 => _9((p) => p.observer)\n, 'optionalAccess', _10 => _10.map, 'call', _11 => _11((p) => ({\n                    observer: p.observer,\n                    options: p.options,\n                    callback: (payload) => wrappedEmit({\n                        type: EventType.Plugin,\n                        data: {\n                            plugin: p.name,\n                            payload,\n                        },\n                    }),\n                }))]) || [],\n            }, {});\n        };\n        iframeManager.addLoadListener((iframeEl) => {\n            try {\n                handlers.push(observe(iframeEl.contentDocument));\n            }\n            catch (error) {\n                console.warn(error);\n            }\n        });\n        const init = () => {\n            takeFullSnapshot();\n            handlers.push(observe(document));\n        };\n        if (document.readyState === 'interactive' ||\n            document.readyState === 'complete') {\n            init();\n        }\n        else {\n            handlers.push(on('DOMContentLoaded', () => {\n                wrappedEmit({\n                    type: EventType.DomContentLoaded,\n                    data: {},\n                });\n                if (recordAfter === 'DOMContentLoaded')\n                    init();\n            }));\n            handlers.push(on('load', () => {\n                wrappedEmit({\n                    type: EventType.Load,\n                    data: {},\n                });\n                if (recordAfter === 'load')\n                    init();\n            }, window));\n        }\n        return () => {\n            handlers.forEach((h) => h());\n            processedNodeManager.destroy();\n            _takeFullSnapshot = undefined;\n            unregisterErrorHandler();\n        };\n    }\n    catch (error) {\n        console.warn(error);\n    }\n}\nfunction takeFullSnapshot(isCheckout) {\n    if (!_takeFullSnapshot) {\n        throw new Error('please take full snapshot after start recording');\n    }\n    _takeFullSnapshot(isCheckout);\n}\nrecord.mirror = mirror;\nrecord.takeFullSnapshot = takeFullSnapshot;\nfunction _getCanvasManager(getCanvasManagerFn, options) {\n    try {\n        return getCanvasManagerFn\n            ? getCanvasManagerFn(options)\n            : new CanvasManagerNoop();\n    }\n    catch (e2) {\n        console.warn('Unable to initialize CanvasManager');\n        return new CanvasManagerNoop();\n    }\n}\n\n/**\n * This serves as a build time flag that will be true by default, but false in non-debug builds or if users replace `__SENTRY_DEBUG__` in their generated code.\n *\n * ATTENTION: This constant must never cross package boundaries (i.e. be exported) to guarantee that it can be used for tree shaking.\n */\nconst DEBUG_BUILD = (typeof __SENTRY_DEBUG__ === 'undefined' || __SENTRY_DEBUG__);\n\nconst CONSOLE_LEVELS = ['info', 'warn', 'error', 'log'] ;\nconst PREFIX = '[Replay] ';\n\nfunction _addBreadcrumb(message, level = 'info') {\n  addBreadcrumb(\n    {\n      category: 'console',\n      data: {\n        logger: 'replay',\n      },\n      level,\n      message: `${PREFIX}${message}`,\n    },\n    { level },\n  );\n}\n\nfunction makeReplayLogger() {\n  let _capture = false;\n  let _trace = false;\n\n  const _logger = {\n    exception: () => undefined,\n    infoTick: () => undefined,\n    setConfig: (opts) => {\n      _capture = opts.captureExceptions;\n      _trace = opts.traceInternals;\n    },\n  };\n\n  if (DEBUG_BUILD) {\n    CONSOLE_LEVELS.forEach(name => {\n      _logger[name] = (...args) => {\n        logger$1[name](PREFIX, ...args);\n        if (_trace) {\n          _addBreadcrumb(args.join(''), severityLevelFromString(name));\n        }\n      };\n    });\n\n    _logger.exception = (error, ...message) => {\n      if (message.length && _logger.error) {\n        _logger.error(...message);\n      }\n\n      logger$1.error(PREFIX, error);\n\n      if (_capture) {\n        captureException(error);\n      } else if (_trace) {\n        // No need for a breadcrumb if `_capture` is enabled since it should be\n        // captured as an exception\n        _addBreadcrumb(error, 'error');\n      }\n    };\n\n    _logger.infoTick = (...args) => {\n      logger$1.info(PREFIX, ...args);\n      if (_trace) {\n        // Wait a tick here to avoid race conditions for some initial logs\n        // which may be added before replay is initialized\n        setTimeout(() => _addBreadcrumb(args[0]), 0);\n      }\n    };\n  } else {\n    CONSOLE_LEVELS.forEach(name => {\n      _logger[name] = () => undefined;\n    });\n  }\n\n  return _logger ;\n}\n\nconst logger = makeReplayLogger();\n\nconst ReplayEventTypeIncrementalSnapshot = 3;\nconst ReplayEventTypeCustom = 5;\n\n/**\n * Converts a timestamp to ms, if it was in s, or keeps it as ms.\n */\nfunction timestampToMs(timestamp) {\n  const isMs = timestamp > 9999999999;\n  return isMs ? timestamp : timestamp * 1000;\n}\n\n/**\n * Converts a timestamp to s, if it was in ms, or keeps it as s.\n */\nfunction timestampToS(timestamp) {\n  const isMs = timestamp > 9999999999;\n  return isMs ? timestamp / 1000 : timestamp;\n}\n\n/**\n * Add a breadcrumb event to replay.\n */\nfunction addBreadcrumbEvent(replay, breadcrumb) {\n  if (breadcrumb.category === 'sentry.transaction') {\n    return;\n  }\n\n  if (['ui.click', 'ui.input'].includes(breadcrumb.category )) {\n    replay.triggerUserActivity();\n  } else {\n    replay.checkAndHandleExpiredSession();\n  }\n\n  replay.addUpdate(() => {\n    // This should never reject\n    // eslint-disable-next-line @typescript-eslint/no-floating-promises\n    replay.throttledAddEvent({\n      type: EventType.Custom,\n      // TODO: We were converting from ms to seconds for breadcrumbs, spans,\n      // but maybe we should just keep them as milliseconds\n      timestamp: (breadcrumb.timestamp || 0) * 1000,\n      data: {\n        tag: 'breadcrumb',\n        // normalize to max. 10 depth and 1_000 properties per object\n        payload: normalize(breadcrumb, 10, 1000),\n      },\n    });\n\n    // Do not flush after console log messages\n    return breadcrumb.category === 'console';\n  });\n}\n\nconst INTERACTIVE_SELECTOR = 'button,a';\n\n/** Get the closest interactive parent element, or else return the given element. */\nfunction getClosestInteractive(element) {\n  const closestInteractive = element.closest(INTERACTIVE_SELECTOR);\n  return closestInteractive || element;\n}\n\n/**\n * For clicks, we check if the target is inside of a button or link\n * If so, we use this as the target instead\n * This is useful because if you click on the image in <button><img></button>,\n * The target will be the image, not the button, which we don't want here\n */\nfunction getClickTargetNode(event) {\n  const target = getTargetNode(event);\n\n  if (!target || !(target instanceof Element)) {\n    return target;\n  }\n\n  return getClosestInteractive(target);\n}\n\n/** Get the event target node. */\nfunction getTargetNode(event) {\n  if (isEventWithTarget(event)) {\n    return event.target ;\n  }\n\n  return event;\n}\n\nfunction isEventWithTarget(event) {\n  return typeof event === 'object' && !!event && 'target' in event;\n}\n\nlet handlers;\n\n/**\n * Register a handler to be called when `window.open()` is called.\n * Returns a cleanup function.\n */\nfunction onWindowOpen(cb) {\n  // Ensure to only register this once\n  if (!handlers) {\n    handlers = [];\n    monkeyPatchWindowOpen();\n  }\n\n  handlers.push(cb);\n\n  return () => {\n    const pos = handlers ? handlers.indexOf(cb) : -1;\n    if (pos > -1) {\n      (handlers ).splice(pos, 1);\n    }\n  };\n}\n\nfunction monkeyPatchWindowOpen() {\n  fill(WINDOW, 'open', function (originalWindowOpen) {\n    return function (...args) {\n      if (handlers) {\n        try {\n          handlers.forEach(handler => handler());\n        } catch (e) {\n          // ignore errors in here\n        }\n      }\n\n      return originalWindowOpen.apply(WINDOW, args);\n    };\n  });\n}\n\n/** Any IncrementalSource for rrweb that we interpret as a kind of mutation. */\nconst IncrementalMutationSources = new Set([\n  IncrementalSource.Mutation,\n  IncrementalSource.StyleSheetRule,\n  IncrementalSource.StyleDeclaration,\n  IncrementalSource.AdoptedStyleSheet,\n  IncrementalSource.CanvasMutation,\n  IncrementalSource.Selection,\n  IncrementalSource.MediaInteraction,\n]);\n\n/** Handle a click. */\nfunction handleClick(clickDetector, clickBreadcrumb, node) {\n  clickDetector.handleClick(clickBreadcrumb, node);\n}\n\n/** A click detector class that can be used to detect slow or rage clicks on elements. */\nclass ClickDetector  {\n  // protected for testing\n\n   constructor(\n    replay,\n    slowClickConfig,\n    // Just for easier testing\n    _addBreadcrumbEvent = addBreadcrumbEvent,\n  ) {\n    this._lastMutation = 0;\n    this._lastScroll = 0;\n    this._clicks = [];\n\n    // We want everything in s, but options are in ms\n    this._timeout = slowClickConfig.timeout / 1000;\n    this._threshold = slowClickConfig.threshold / 1000;\n    this._scollTimeout = slowClickConfig.scrollTimeout / 1000;\n    this._replay = replay;\n    this._ignoreSelector = slowClickConfig.ignoreSelector;\n    this._addBreadcrumbEvent = _addBreadcrumbEvent;\n  }\n\n  /** Register click detection handlers on mutation or scroll. */\n   addListeners() {\n    const cleanupWindowOpen = onWindowOpen(() => {\n      // Treat window.open as mutation\n      this._lastMutation = nowInSeconds();\n    });\n\n    this._teardown = () => {\n      cleanupWindowOpen();\n\n      this._clicks = [];\n      this._lastMutation = 0;\n      this._lastScroll = 0;\n    };\n  }\n\n  /** Clean up listeners. */\n   removeListeners() {\n    if (this._teardown) {\n      this._teardown();\n    }\n\n    if (this._checkClickTimeout) {\n      clearTimeout(this._checkClickTimeout);\n    }\n  }\n\n  /** @inheritDoc */\n   handleClick(breadcrumb, node) {\n    if (ignoreElement(node, this._ignoreSelector) || !isClickBreadcrumb(breadcrumb)) {\n      return;\n    }\n\n    const newClick = {\n      timestamp: timestampToS(breadcrumb.timestamp),\n      clickBreadcrumb: breadcrumb,\n      // Set this to 0 so we know it originates from the click breadcrumb\n      clickCount: 0,\n      node,\n    };\n\n    // If there was a click in the last 1s on the same element, ignore it - only keep a single reference per second\n    if (\n      this._clicks.some(click => click.node === newClick.node && Math.abs(click.timestamp - newClick.timestamp) < 1)\n    ) {\n      return;\n    }\n\n    this._clicks.push(newClick);\n\n    // If this is the first new click, set a timeout to check for multi clicks\n    if (this._clicks.length === 1) {\n      this._scheduleCheckClicks();\n    }\n  }\n\n  /** @inheritDoc */\n   registerMutation(timestamp = Date.now()) {\n    this._lastMutation = timestampToS(timestamp);\n  }\n\n  /** @inheritDoc */\n   registerScroll(timestamp = Date.now()) {\n    this._lastScroll = timestampToS(timestamp);\n  }\n\n  /** @inheritDoc */\n   registerClick(element) {\n    const node = getClosestInteractive(element);\n    this._handleMultiClick(node );\n  }\n\n  /** Count multiple clicks on elements. */\n   _handleMultiClick(node) {\n    this._getClicks(node).forEach(click => {\n      click.clickCount++;\n    });\n  }\n\n  /** Get all pending clicks for a given node. */\n   _getClicks(node) {\n    return this._clicks.filter(click => click.node === node);\n  }\n\n  /** Check the clicks that happened. */\n   _checkClicks() {\n    const timedOutClicks = [];\n\n    const now = nowInSeconds();\n\n    this._clicks.forEach(click => {\n      if (!click.mutationAfter && this._lastMutation) {\n        click.mutationAfter = click.timestamp <= this._lastMutation ? this._lastMutation - click.timestamp : undefined;\n      }\n      if (!click.scrollAfter && this._lastScroll) {\n        click.scrollAfter = click.timestamp <= this._lastScroll ? this._lastScroll - click.timestamp : undefined;\n      }\n\n      // All of these are in seconds!\n      if (click.timestamp + this._timeout <= now) {\n        timedOutClicks.push(click);\n      }\n    });\n\n    // Remove \"old\" clicks\n    for (const click of timedOutClicks) {\n      const pos = this._clicks.indexOf(click);\n\n      if (pos > -1) {\n        this._generateBreadcrumbs(click);\n        this._clicks.splice(pos, 1);\n      }\n    }\n\n    // Trigger new check, unless no clicks left\n    if (this._clicks.length) {\n      this._scheduleCheckClicks();\n    }\n  }\n\n  /** Generate matching breadcrumb(s) for the click. */\n   _generateBreadcrumbs(click) {\n    const replay = this._replay;\n    const hadScroll = click.scrollAfter && click.scrollAfter <= this._scollTimeout;\n    const hadMutation = click.mutationAfter && click.mutationAfter <= this._threshold;\n\n    const isSlowClick = !hadScroll && !hadMutation;\n    const { clickCount, clickBreadcrumb } = click;\n\n    // Slow click\n    if (isSlowClick) {\n      // If `mutationAfter` is set, it means a mutation happened after the threshold, but before the timeout\n      // If not, it means we just timed out without scroll & mutation\n      const timeAfterClickMs = Math.min(click.mutationAfter || this._timeout, this._timeout) * 1000;\n      const endReason = timeAfterClickMs < this._timeout * 1000 ? 'mutation' : 'timeout';\n\n      const breadcrumb = {\n        type: 'default',\n        message: clickBreadcrumb.message,\n        timestamp: clickBreadcrumb.timestamp,\n        category: 'ui.slowClickDetected',\n        data: {\n          ...clickBreadcrumb.data,\n          url: WINDOW.location.href,\n          route: replay.getCurrentRoute(),\n          timeAfterClickMs,\n          endReason,\n          // If clickCount === 0, it means multiClick was not correctly captured here\n          // - we still want to send 1 in this case\n          clickCount: clickCount || 1,\n        },\n      };\n\n      this._addBreadcrumbEvent(replay, breadcrumb);\n      return;\n    }\n\n    // Multi click\n    if (clickCount > 1) {\n      const breadcrumb = {\n        type: 'default',\n        message: clickBreadcrumb.message,\n        timestamp: clickBreadcrumb.timestamp,\n        category: 'ui.multiClick',\n        data: {\n          ...clickBreadcrumb.data,\n          url: WINDOW.location.href,\n          route: replay.getCurrentRoute(),\n          clickCount,\n          metric: true,\n        },\n      };\n\n      this._addBreadcrumbEvent(replay, breadcrumb);\n    }\n  }\n\n  /** Schedule to check current clicks. */\n   _scheduleCheckClicks() {\n    if (this._checkClickTimeout) {\n      clearTimeout(this._checkClickTimeout);\n    }\n\n    this._checkClickTimeout = setTimeout$3(() => this._checkClicks(), 1000);\n  }\n}\n\nconst SLOW_CLICK_TAGS = ['A', 'BUTTON', 'INPUT'];\n\n/** exported for tests only */\nfunction ignoreElement(node, ignoreSelector) {\n  if (!SLOW_CLICK_TAGS.includes(node.tagName)) {\n    return true;\n  }\n\n  // If <input> tag, we only want to consider input[type='submit'] & input[type='button']\n  if (node.tagName === 'INPUT' && !['submit', 'button'].includes(node.getAttribute('type') || '')) {\n    return true;\n  }\n\n  // If <a> tag, detect special variants that may not lead to an action\n  // If target !== _self, we may open the link somewhere else, which would lead to no action\n  // Also, when downloading a file, we may not leave the page, but still not trigger an action\n  if (\n    node.tagName === 'A' &&\n    (node.hasAttribute('download') || (node.hasAttribute('target') && node.getAttribute('target') !== '_self'))\n  ) {\n    return true;\n  }\n\n  if (ignoreSelector && node.matches(ignoreSelector)) {\n    return true;\n  }\n\n  return false;\n}\n\nfunction isClickBreadcrumb(breadcrumb) {\n  return !!(breadcrumb.data && typeof breadcrumb.data.nodeId === 'number' && breadcrumb.timestamp);\n}\n\n// This is good enough for us, and is easier to test/mock than `timestampInSeconds`\nfunction nowInSeconds() {\n  return Date.now() / 1000;\n}\n\n/** Update the click detector based on a recording event of rrweb. */\nfunction updateClickDetectorForRecordingEvent(clickDetector, event) {\n  try {\n    // note: We only consider incremental snapshots here\n    // This means that any full snapshot is ignored for mutation detection - the reason is that we simply cannot know if a mutation happened here.\n    // E.g. think that we are buffering, an error happens and we take a full snapshot because we switched to session mode -\n    // in this scenario, we would not know if a dead click happened because of the error, which is a key dead click scenario.\n    // Instead, by ignoring full snapshots, we have the risk that we generate a false positive\n    // (if a mutation _did_ happen but was \"swallowed\" by the full snapshot)\n    // But this should be more unlikely as we'd generally capture the incremental snapshot right away\n\n    if (!isIncrementalEvent(event)) {\n      return;\n    }\n\n    const { source } = event.data;\n    if (IncrementalMutationSources.has(source)) {\n      clickDetector.registerMutation(event.timestamp);\n    }\n\n    if (source === IncrementalSource.Scroll) {\n      clickDetector.registerScroll(event.timestamp);\n    }\n\n    if (isIncrementalMouseInteraction(event)) {\n      const { type, id } = event.data;\n      const node = record.mirror.getNode(id);\n\n      if (node instanceof HTMLElement && type === MouseInteractions.Click) {\n        clickDetector.registerClick(node);\n      }\n    }\n  } catch (e) {\n    // ignore errors here, e.g. if accessing something that does not exist\n  }\n}\n\nfunction isIncrementalEvent(event) {\n  return event.type === ReplayEventTypeIncrementalSnapshot;\n}\n\nfunction isIncrementalMouseInteraction(\n  event,\n) {\n  return event.data.source === IncrementalSource.MouseInteraction;\n}\n\n/**\n * Create a breadcrumb for a replay.\n */\nfunction createBreadcrumb(\n  breadcrumb,\n) {\n  return {\n    timestamp: Date.now() / 1000,\n    type: 'default',\n    ...breadcrumb,\n  };\n}\n\nvar NodeType;\n(function (NodeType) {\n    NodeType[NodeType[\"Document\"] = 0] = \"Document\";\n    NodeType[NodeType[\"DocumentType\"] = 1] = \"DocumentType\";\n    NodeType[NodeType[\"Element\"] = 2] = \"Element\";\n    NodeType[NodeType[\"Text\"] = 3] = \"Text\";\n    NodeType[NodeType[\"CDATA\"] = 4] = \"CDATA\";\n    NodeType[NodeType[\"Comment\"] = 5] = \"Comment\";\n})(NodeType || (NodeType = {}));\n\n// Note that these are the serialized attributes and not attributes directly on\n// the DOM Node. Attributes we are interested in:\nconst ATTRIBUTES_TO_RECORD = new Set([\n  'id',\n  'class',\n  'aria-label',\n  'role',\n  'name',\n  'alt',\n  'title',\n  'data-test-id',\n  'data-testid',\n  'disabled',\n  'aria-disabled',\n  'data-sentry-component',\n]);\n\n/**\n * Inclusion list of attributes that we want to record from the DOM element\n */\nfunction getAttributesToRecord(attributes) {\n  const obj = {};\n  if (!attributes['data-sentry-component'] && attributes['data-sentry-element']) {\n    attributes['data-sentry-component'] = attributes['data-sentry-element'];\n  }\n  for (const key in attributes) {\n    if (ATTRIBUTES_TO_RECORD.has(key)) {\n      let normalizedKey = key;\n\n      if (key === 'data-testid' || key === 'data-test-id') {\n        normalizedKey = 'testId';\n      }\n\n      obj[normalizedKey] = attributes[key];\n    }\n  }\n\n  return obj;\n}\n\nconst handleDomListener = (\n  replay,\n) => {\n  return (handlerData) => {\n    if (!replay.isEnabled()) {\n      return;\n    }\n\n    const result = handleDom(handlerData);\n\n    if (!result) {\n      return;\n    }\n\n    const isClick = handlerData.name === 'click';\n    const event = isClick ? (handlerData.event ) : undefined;\n    // Ignore clicks if ctrl/alt/meta/shift keys are held down as they alter behavior of clicks (e.g. open in new tab)\n    if (\n      isClick &&\n      replay.clickDetector &&\n      event &&\n      event.target &&\n      !event.altKey &&\n      !event.metaKey &&\n      !event.ctrlKey &&\n      !event.shiftKey\n    ) {\n      handleClick(\n        replay.clickDetector,\n        result ,\n        getClickTargetNode(handlerData.event ) ,\n      );\n    }\n\n    addBreadcrumbEvent(replay, result);\n  };\n};\n\n/** Get the base DOM breadcrumb. */\nfunction getBaseDomBreadcrumb(target, message) {\n  const nodeId = record.mirror.getId(target);\n  const node = nodeId && record.mirror.getNode(nodeId);\n  const meta = node && record.mirror.getMeta(node);\n  const element = meta && isElement(meta) ? meta : null;\n\n  return {\n    message,\n    data: element\n      ? {\n          nodeId,\n          node: {\n            id: nodeId,\n            tagName: element.tagName,\n            textContent: Array.from(element.childNodes)\n              .map((node) => node.type === NodeType.Text && node.textContent)\n              .filter(Boolean) // filter out empty values\n              .map(text => (text ).trim())\n              .join(''),\n            attributes: getAttributesToRecord(element.attributes),\n          },\n        }\n      : {},\n  };\n}\n\n/**\n * An event handler to react to DOM events.\n * Exported for tests.\n */\nfunction handleDom(handlerData) {\n  const { target, message } = getDomTarget(handlerData);\n\n  return createBreadcrumb({\n    category: `ui.${handlerData.name}`,\n    ...getBaseDomBreadcrumb(target, message),\n  });\n}\n\nfunction getDomTarget(handlerData) {\n  const isClick = handlerData.name === 'click';\n\n  let message;\n  let target = null;\n\n  // Accessing event.target can throw (see getsentry/raven-js#838, #768)\n  try {\n    target = isClick ? getClickTargetNode(handlerData.event ) : getTargetNode(handlerData.event );\n    message = htmlTreeAsString(target, { maxStringLength: 200 }) || '<unknown>';\n  } catch (e) {\n    message = '<unknown>';\n  }\n\n  return { target, message };\n}\n\nfunction isElement(node) {\n  return node.type === NodeType.Element;\n}\n\n/** Handle keyboard events & create breadcrumbs. */\nfunction handleKeyboardEvent(replay, event) {\n  if (!replay.isEnabled()) {\n    return;\n  }\n\n  // Update user activity, but do not restart recording as it can create\n  // noisy/low-value replays (e.g. user comes back from idle, hits alt-tab, new\n  // session with a single \"keydown\" breadcrumb is created)\n  replay.updateUserActivity();\n\n  const breadcrumb = getKeyboardBreadcrumb(event);\n\n  if (!breadcrumb) {\n    return;\n  }\n\n  addBreadcrumbEvent(replay, breadcrumb);\n}\n\n/** exported only for tests */\nfunction getKeyboardBreadcrumb(event) {\n  const { metaKey, shiftKey, ctrlKey, altKey, key, target } = event;\n\n  // never capture for input fields\n  if (!target || isInputElement(target ) || !key) {\n    return null;\n  }\n\n  // Note: We do not consider shift here, as that means \"uppercase\"\n  const hasModifierKey = metaKey || ctrlKey || altKey;\n  const isCharacterKey = key.length === 1; // other keys like Escape, Tab, etc have a longer length\n\n  // Do not capture breadcrumb if only a word key is pressed\n  // This could leak e.g. user input\n  if (!hasModifierKey && isCharacterKey) {\n    return null;\n  }\n\n  const message = htmlTreeAsString(target, { maxStringLength: 200 }) || '<unknown>';\n  const baseBreadcrumb = getBaseDomBreadcrumb(target , message);\n\n  return createBreadcrumb({\n    category: 'ui.keyDown',\n    message,\n    data: {\n      ...baseBreadcrumb.data,\n      metaKey,\n      shiftKey,\n      ctrlKey,\n      altKey,\n      key,\n    },\n  });\n}\n\nfunction isInputElement(target) {\n  return target.tagName === 'INPUT' || target.tagName === 'TEXTAREA' || target.isContentEditable;\n}\n\n// Map entryType -> function to normalize data for event\nconst ENTRY_TYPES\n\n = {\n  // @ts-expect-error TODO: entry type does not fit the create* functions entry type\n  resource: createResourceEntry,\n  paint: createPaintEntry,\n  // @ts-expect-error TODO: entry type does not fit the create* functions entry type\n  navigation: createNavigationEntry,\n};\n\n/**\n * Handler creater for web vitals\n */\nfunction webVitalHandler(\n  getter,\n  replay,\n) {\n  return ({ metric }) => void replay.replayPerformanceEntries.push(getter(metric));\n}\n\n/**\n * Create replay performance entries from the browser performance entries.\n */\nfunction createPerformanceEntries(\n  entries,\n) {\n  return entries.map(createPerformanceEntry).filter(Boolean) ;\n}\n\nfunction createPerformanceEntry(entry) {\n  const entryType = ENTRY_TYPES[entry.entryType];\n  if (!entryType) {\n    return null;\n  }\n\n  return entryType(entry);\n}\n\nfunction getAbsoluteTime(time) {\n  // browserPerformanceTimeOrigin can be undefined if `performance` or\n  // `performance.now` doesn't exist, but this is already checked by this integration\n  return ((browserPerformanceTimeOrigin || WINDOW.performance.timeOrigin) + time) / 1000;\n}\n\nfunction createPaintEntry(entry) {\n  const { duration, entryType, name, startTime } = entry;\n\n  const start = getAbsoluteTime(startTime);\n  return {\n    type: entryType,\n    name,\n    start,\n    end: start + duration,\n    data: undefined,\n  };\n}\n\nfunction createNavigationEntry(entry) {\n  const {\n    entryType,\n    name,\n    decodedBodySize,\n    duration,\n    domComplete,\n    encodedBodySize,\n    domContentLoadedEventStart,\n    domContentLoadedEventEnd,\n    domInteractive,\n    loadEventStart,\n    loadEventEnd,\n    redirectCount,\n    startTime,\n    transferSize,\n    type,\n  } = entry;\n\n  // Ignore entries with no duration, they do not seem to be useful and cause dupes\n  if (duration === 0) {\n    return null;\n  }\n\n  return {\n    type: `${entryType}.${type}`,\n    start: getAbsoluteTime(startTime),\n    end: getAbsoluteTime(domComplete),\n    name,\n    data: {\n      size: transferSize,\n      decodedBodySize,\n      encodedBodySize,\n      duration,\n      domInteractive,\n      domContentLoadedEventStart,\n      domContentLoadedEventEnd,\n      loadEventStart,\n      loadEventEnd,\n      domComplete,\n      redirectCount,\n    },\n  };\n}\n\nfunction createResourceEntry(\n  entry,\n) {\n  const {\n    entryType,\n    initiatorType,\n    name,\n    responseEnd,\n    startTime,\n    decodedBodySize,\n    encodedBodySize,\n    responseStatus,\n    transferSize,\n  } = entry;\n\n  // Core SDK handles these\n  if (['fetch', 'xmlhttprequest'].includes(initiatorType)) {\n    return null;\n  }\n\n  return {\n    type: `${entryType}.${initiatorType}`,\n    start: getAbsoluteTime(startTime),\n    end: getAbsoluteTime(responseEnd),\n    name,\n    data: {\n      size: transferSize,\n      statusCode: responseStatus,\n      decodedBodySize,\n      encodedBodySize,\n    },\n  };\n}\n\n/**\n * Add a LCP event to the replay based on a LCP metric.\n */\nfunction getLargestContentfulPaint(metric) {\n  const lastEntry = metric.entries[metric.entries.length - 1] ;\n  const node = lastEntry && lastEntry.element ? [lastEntry.element] : undefined;\n  return getWebVital(metric, 'largest-contentful-paint', node);\n}\n\nfunction isLayoutShift(entry) {\n  return (entry ).sources !== undefined;\n}\n\n/**\n * Add a CLS event to the replay based on a CLS metric.\n */\nfunction getCumulativeLayoutShift(metric) {\n  const layoutShifts = [];\n  const nodes = [];\n  for (const entry of metric.entries) {\n    if (isLayoutShift(entry)) {\n      const nodeIds = [];\n      for (const source of entry.sources) {\n        if (source.node) {\n          nodes.push(source.node);\n          const nodeId = record.mirror.getId(source.node);\n          if (nodeId) {\n            nodeIds.push(nodeId);\n          }\n        }\n      }\n      layoutShifts.push({ value: entry.value, nodeIds: nodeIds.length ? nodeIds : undefined });\n    }\n  }\n\n  return getWebVital(metric, 'cumulative-layout-shift', nodes, layoutShifts);\n}\n\n/**\n * Add a FID event to the replay based on a FID metric.\n */\nfunction getFirstInputDelay(metric) {\n  const lastEntry = metric.entries[metric.entries.length - 1] ;\n  const node = lastEntry && lastEntry.target ? [lastEntry.target] : undefined;\n  return getWebVital(metric, 'first-input-delay', node);\n}\n\n/**\n * Add an INP event to the replay based on an INP metric.\n */\nfunction getInteractionToNextPaint(metric) {\n  const lastEntry = metric.entries[metric.entries.length - 1] ;\n  const node = lastEntry && lastEntry.target ? [lastEntry.target] : undefined;\n  return getWebVital(metric, 'interaction-to-next-paint', node);\n}\n\n/**\n * Add an web vital event to the replay based on the web vital metric.\n */\nfunction getWebVital(\n  metric,\n  name,\n  nodes,\n  attributions,\n) {\n  const value = metric.value;\n  const rating = metric.rating;\n\n  const end = getAbsoluteTime(value);\n\n  return {\n    type: 'web-vital',\n    name,\n    start: end,\n    end,\n    data: {\n      value,\n      size: value,\n      rating,\n      nodeIds: nodes ? nodes.map(node => record.mirror.getId(node)) : undefined,\n      attributions,\n    },\n  };\n}\n\n/**\n * Sets up a PerformanceObserver to listen to all performance entry types.\n * Returns a callback to stop observing.\n */\nfunction setupPerformanceObserver(replay) {\n  function addPerformanceEntry(entry) {\n    // It is possible for entries to come up multiple times\n    if (!replay.performanceEntries.includes(entry)) {\n      replay.performanceEntries.push(entry);\n    }\n  }\n\n  function onEntries({ entries }) {\n    entries.forEach(addPerformanceEntry);\n  }\n\n  const clearCallbacks = [];\n\n  (['navigation', 'paint', 'resource'] ).forEach(type => {\n    clearCallbacks.push(addPerformanceInstrumentationHandler(type, onEntries));\n  });\n\n  clearCallbacks.push(\n    addLcpInstrumentationHandler(webVitalHandler(getLargestContentfulPaint, replay)),\n    addClsInstrumentationHandler(webVitalHandler(getCumulativeLayoutShift, replay)),\n    addFidInstrumentationHandler(webVitalHandler(getFirstInputDelay, replay)),\n    addInpInstrumentationHandler(webVitalHandler(getInteractionToNextPaint, replay)),\n  );\n\n  // A callback to cleanup all handlers\n  return () => {\n    clearCallbacks.forEach(clearCallback => clearCallback());\n  };\n}\n\nconst r = `var t=Uint8Array,n=Uint16Array,r=Int32Array,e=new t([0,0,0,0,0,0,0,0,1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,4,5,5,5,5,0,0,0,0]),i=new t([0,0,0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,10,10,11,11,12,12,13,13,0,0]),a=new t([16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15]),s=function(t,e){for(var i=new n(31),a=0;a<31;++a)i[a]=e+=1<<t[a-1];var s=new r(i[30]);for(a=1;a<30;++a)for(var o=i[a];o<i[a+1];++o)s[o]=o-i[a]<<5|a;return{b:i,r:s}},o=s(e,2),f=o.b,h=o.r;f[28]=258,h[258]=28;for(var l=s(i,0).r,u=new n(32768),c=0;c<32768;++c){var v=(43690&c)>>1|(21845&c)<<1;v=(61680&(v=(52428&v)>>2|(13107&v)<<2))>>4|(3855&v)<<4,u[c]=((65280&v)>>8|(255&v)<<8)>>1}var d=function(t,r,e){for(var i=t.length,a=0,s=new n(r);a<i;++a)t[a]&&++s[t[a]-1];var o,f=new n(r);for(a=1;a<r;++a)f[a]=f[a-1]+s[a-1]<<1;if(e){o=new n(1<<r);var h=15-r;for(a=0;a<i;++a)if(t[a])for(var l=a<<4|t[a],c=r-t[a],v=f[t[a]-1]++<<c,d=v|(1<<c)-1;v<=d;++v)o[u[v]>>h]=l}else for(o=new n(i),a=0;a<i;++a)t[a]&&(o[a]=u[f[t[a]-1]++]>>15-t[a]);return o},g=new t(288);for(c=0;c<144;++c)g[c]=8;for(c=144;c<256;++c)g[c]=9;for(c=256;c<280;++c)g[c]=7;for(c=280;c<288;++c)g[c]=8;var w=new t(32);for(c=0;c<32;++c)w[c]=5;var p=d(g,9,0),y=d(w,5,0),m=function(t){return(t+7)/8|0},b=function(n,r,e){return(null==r||r<0)&&(r=0),(null==e||e>n.length)&&(e=n.length),new t(n.subarray(r,e))},M=[\"unexpected EOF\",\"invalid block type\",\"invalid length/literal\",\"invalid distance\",\"stream finished\",\"no stream handler\",,\"no callback\",\"invalid UTF-8 data\",\"extra field too long\",\"date not in range 1980-2099\",\"filename too long\",\"stream finishing\",\"invalid zip data\"],E=function(t,n,r){var e=new Error(n||M[t]);if(e.code=t,Error.captureStackTrace&&Error.captureStackTrace(e,E),!r)throw e;return e},z=function(t,n,r){r<<=7&n;var e=n/8|0;t[e]|=r,t[e+1]|=r>>8},A=function(t,n,r){r<<=7&n;var e=n/8|0;t[e]|=r,t[e+1]|=r>>8,t[e+2]|=r>>16},_=function(r,e){for(var i=[],a=0;a<r.length;++a)r[a]&&i.push({s:a,f:r[a]});var s=i.length,o=i.slice();if(!s)return{t:F,l:0};if(1==s){var f=new t(i[0].s+1);return f[i[0].s]=1,{t:f,l:1}}i.sort((function(t,n){return t.f-n.f})),i.push({s:-1,f:25001});var h=i[0],l=i[1],u=0,c=1,v=2;for(i[0]={s:-1,f:h.f+l.f,l:h,r:l};c!=s-1;)h=i[i[u].f<i[v].f?u++:v++],l=i[u!=c&&i[u].f<i[v].f?u++:v++],i[c++]={s:-1,f:h.f+l.f,l:h,r:l};var d=o[0].s;for(a=1;a<s;++a)o[a].s>d&&(d=o[a].s);var g=new n(d+1),w=x(i[c-1],g,0);if(w>e){a=0;var p=0,y=w-e,m=1<<y;for(o.sort((function(t,n){return g[n.s]-g[t.s]||t.f-n.f}));a<s;++a){var b=o[a].s;if(!(g[b]>e))break;p+=m-(1<<w-g[b]),g[b]=e}for(p>>=y;p>0;){var M=o[a].s;g[M]<e?p-=1<<e-g[M]++-1:++a}for(;a>=0&&p;--a){var E=o[a].s;g[E]==e&&(--g[E],++p)}w=e}return{t:new t(g),l:w}},x=function(t,n,r){return-1==t.s?Math.max(x(t.l,n,r+1),x(t.r,n,r+1)):n[t.s]=r},D=function(t){for(var r=t.length;r&&!t[--r];);for(var e=new n(++r),i=0,a=t[0],s=1,o=function(t){e[i++]=t},f=1;f<=r;++f)if(t[f]==a&&f!=r)++s;else{if(!a&&s>2){for(;s>138;s-=138)o(32754);s>2&&(o(s>10?s-11<<5|28690:s-3<<5|12305),s=0)}else if(s>3){for(o(a),--s;s>6;s-=6)o(8304);s>2&&(o(s-3<<5|8208),s=0)}for(;s--;)o(a);s=1,a=t[f]}return{c:e.subarray(0,i),n:r}},T=function(t,n){for(var r=0,e=0;e<n.length;++e)r+=t[e]*n[e];return r},k=function(t,n,r){var e=r.length,i=m(n+2);t[i]=255&e,t[i+1]=e>>8,t[i+2]=255^t[i],t[i+3]=255^t[i+1];for(var a=0;a<e;++a)t[i+a+4]=r[a];return 8*(i+4+e)},C=function(t,r,s,o,f,h,l,u,c,v,m){z(r,m++,s),++f[256];for(var b=_(f,15),M=b.t,E=b.l,x=_(h,15),C=x.t,U=x.l,F=D(M),I=F.c,S=F.n,L=D(C),O=L.c,j=L.n,q=new n(19),B=0;B<I.length;++B)++q[31&I[B]];for(B=0;B<O.length;++B)++q[31&O[B]];for(var G=_(q,7),H=G.t,J=G.l,K=19;K>4&&!H[a[K-1]];--K);var N,P,Q,R,V=v+5<<3,W=T(f,g)+T(h,w)+l,X=T(f,M)+T(h,C)+l+14+3*K+T(q,H)+2*q[16]+3*q[17]+7*q[18];if(c>=0&&V<=W&&V<=X)return k(r,m,t.subarray(c,c+v));if(z(r,m,1+(X<W)),m+=2,X<W){N=d(M,E,0),P=M,Q=d(C,U,0),R=C;var Y=d(H,J,0);z(r,m,S-257),z(r,m+5,j-1),z(r,m+10,K-4),m+=14;for(B=0;B<K;++B)z(r,m+3*B,H[a[B]]);m+=3*K;for(var Z=[I,O],$=0;$<2;++$){var tt=Z[$];for(B=0;B<tt.length;++B){var nt=31&tt[B];z(r,m,Y[nt]),m+=H[nt],nt>15&&(z(r,m,tt[B]>>5&127),m+=tt[B]>>12)}}}else N=p,P=g,Q=y,R=w;for(B=0;B<u;++B){var rt=o[B];if(rt>255){A(r,m,N[(nt=rt>>18&31)+257]),m+=P[nt+257],nt>7&&(z(r,m,rt>>23&31),m+=e[nt]);var et=31&rt;A(r,m,Q[et]),m+=R[et],et>3&&(A(r,m,rt>>5&8191),m+=i[et])}else A(r,m,N[rt]),m+=P[rt]}return A(r,m,N[256]),m+P[256]},U=new r([65540,131080,131088,131104,262176,1048704,1048832,2114560,2117632]),F=new t(0),I=function(){for(var t=new Int32Array(256),n=0;n<256;++n){for(var r=n,e=9;--e;)r=(1&r&&-306674912)^r>>>1;t[n]=r}return t}(),S=function(){var t=-1;return{p:function(n){for(var r=t,e=0;e<n.length;++e)r=I[255&r^n[e]]^r>>>8;t=r},d:function(){return~t}}},L=function(){var t=1,n=0;return{p:function(r){for(var e=t,i=n,a=0|r.length,s=0;s!=a;){for(var o=Math.min(s+2655,a);s<o;++s)i+=e+=r[s];e=(65535&e)+15*(e>>16),i=(65535&i)+15*(i>>16)}t=e,n=i},d:function(){return(255&(t%=65521))<<24|(65280&t)<<8|(255&(n%=65521))<<8|n>>8}}},O=function(a,s,o,f,u){if(!u&&(u={l:1},s.dictionary)){var c=s.dictionary.subarray(-32768),v=new t(c.length+a.length);v.set(c),v.set(a,c.length),a=v,u.w=c.length}return function(a,s,o,f,u,c){var v=c.z||a.length,d=new t(f+v+5*(1+Math.ceil(v/7e3))+u),g=d.subarray(f,d.length-u),w=c.l,p=7&(c.r||0);if(s){p&&(g[0]=c.r>>3);for(var y=U[s-1],M=y>>13,E=8191&y,z=(1<<o)-1,A=c.p||new n(32768),_=c.h||new n(z+1),x=Math.ceil(o/3),D=2*x,T=function(t){return(a[t]^a[t+1]<<x^a[t+2]<<D)&z},F=new r(25e3),I=new n(288),S=new n(32),L=0,O=0,j=c.i||0,q=0,B=c.w||0,G=0;j+2<v;++j){var H=T(j),J=32767&j,K=_[H];if(A[J]=K,_[H]=J,B<=j){var N=v-j;if((L>7e3||q>24576)&&(N>423||!w)){p=C(a,g,0,F,I,S,O,q,G,j-G,p),q=L=O=0,G=j;for(var P=0;P<286;++P)I[P]=0;for(P=0;P<30;++P)S[P]=0}var Q=2,R=0,V=E,W=J-K&32767;if(N>2&&H==T(j-W))for(var X=Math.min(M,N)-1,Y=Math.min(32767,j),Z=Math.min(258,N);W<=Y&&--V&&J!=K;){if(a[j+Q]==a[j+Q-W]){for(var $=0;$<Z&&a[j+$]==a[j+$-W];++$);if($>Q){if(Q=$,R=W,$>X)break;var tt=Math.min(W,$-2),nt=0;for(P=0;P<tt;++P){var rt=j-W+P&32767,et=rt-A[rt]&32767;et>nt&&(nt=et,K=rt)}}}W+=(J=K)-(K=A[J])&32767}if(R){F[q++]=268435456|h[Q]<<18|l[R];var it=31&h[Q],at=31&l[R];O+=e[it]+i[at],++I[257+it],++S[at],B=j+Q,++L}else F[q++]=a[j],++I[a[j]]}}for(j=Math.max(j,B);j<v;++j)F[q++]=a[j],++I[a[j]];p=C(a,g,w,F,I,S,O,q,G,j-G,p),w||(c.r=7&p|g[p/8|0]<<3,p-=7,c.h=_,c.p=A,c.i=j,c.w=B)}else{for(j=c.w||0;j<v+w;j+=65535){var st=j+65535;st>=v&&(g[p/8|0]=w,st=v),p=k(g,p+1,a.subarray(j,st))}c.i=v}return b(d,0,f+m(p)+u)}(a,null==s.level?6:s.level,null==s.mem?Math.ceil(1.5*Math.max(8,Math.min(13,Math.log(a.length)))):12+s.mem,o,f,u)},j=function(t,n,r){for(;r;++n)t[n]=r,r>>>=8},q=function(t,n){var r=n.filename;if(t[0]=31,t[1]=139,t[2]=8,t[8]=n.level<2?4:9==n.level?2:0,t[9]=3,0!=n.mtime&&j(t,4,Math.floor(new Date(n.mtime||Date.now())/1e3)),r){t[3]=8;for(var e=0;e<=r.length;++e)t[e+10]=r.charCodeAt(e)}},B=function(t){return 10+(t.filename?t.filename.length+1:0)},G=function(){function n(n,r){if(\"function\"==typeof n&&(r=n,n={}),this.ondata=r,this.o=n||{},this.s={l:0,i:32768,w:32768,z:32768},this.b=new t(98304),this.o.dictionary){var e=this.o.dictionary.subarray(-32768);this.b.set(e,32768-e.length),this.s.i=32768-e.length}}return n.prototype.p=function(t,n){this.ondata(O(t,this.o,0,0,this.s),n)},n.prototype.push=function(n,r){this.ondata||E(5),this.s.l&&E(4);var e=n.length+this.s.z;if(e>this.b.length){if(e>2*this.b.length-32768){var i=new t(-32768&e);i.set(this.b.subarray(0,this.s.z)),this.b=i}var a=this.b.length-this.s.z;a&&(this.b.set(n.subarray(0,a),this.s.z),this.s.z=this.b.length,this.p(this.b,!1)),this.b.set(this.b.subarray(-32768)),this.b.set(n.subarray(a),32768),this.s.z=n.length-a+32768,this.s.i=32766,this.s.w=32768}else this.b.set(n,this.s.z),this.s.z+=n.length;this.s.l=1&r,(this.s.z>this.s.w+8191||r)&&(this.p(this.b,r||!1),this.s.w=this.s.i,this.s.i-=2)},n}();var H=function(){function t(t,n){this.c=L(),this.v=1,G.call(this,t,n)}return t.prototype.push=function(t,n){this.c.p(t),G.prototype.push.call(this,t,n)},t.prototype.p=function(t,n){var r=O(t,this.o,this.v&&(this.o.dictionary?6:2),n&&4,this.s);this.v&&(function(t,n){var r=n.level,e=0==r?0:r<6?1:9==r?3:2;if(t[0]=120,t[1]=e<<6|(n.dictionary&&32),t[1]|=31-(t[0]<<8|t[1])%31,n.dictionary){var i=L();i.p(n.dictionary),j(t,2,i.d())}}(r,this.o),this.v=0),n&&j(r,r.length-4,this.c.d()),this.ondata(r,n)},t}(),J=\"undefined\"!=typeof TextEncoder&&new TextEncoder,K=\"undefined\"!=typeof TextDecoder&&new TextDecoder;try{K.decode(F,{stream:!0})}catch(t){}var N=function(){function t(t){this.ondata=t}return t.prototype.push=function(t,n){this.ondata||E(5),this.d&&E(4),this.ondata(P(t),this.d=n||!1)},t}();function P(n,r){if(r){for(var e=new t(n.length),i=0;i<n.length;++i)e[i]=n.charCodeAt(i);return e}if(J)return J.encode(n);var a=n.length,s=new t(n.length+(n.length>>1)),o=0,f=function(t){s[o++]=t};for(i=0;i<a;++i){if(o+5>s.length){var h=new t(o+8+(a-i<<1));h.set(s),s=h}var l=n.charCodeAt(i);l<128||r?f(l):l<2048?(f(192|l>>6),f(128|63&l)):l>55295&&l<57344?(f(240|(l=65536+(1047552&l)|1023&n.charCodeAt(++i))>>18),f(128|l>>12&63),f(128|l>>6&63),f(128|63&l)):(f(224|l>>12),f(128|l>>6&63),f(128|63&l))}return b(s,0,o)}function Q(t){return function(t,n){n||(n={});var r=S(),e=t.length;r.p(t);var i=O(t,n,B(n),8),a=i.length;return q(i,n),j(i,a-8,r.d()),j(i,a-4,e),i}(P(t))}const R=new class{constructor(){this._init()}clear(){this._init()}addEvent(t){if(!t)throw new Error(\"Adding invalid event\");const n=this._hasEvents?\",\":\"\";this.stream.push(n+t),this._hasEvents=!0}finish(){this.stream.push(\"]\",!0);const t=function(t){let n=0;for(const r of t)n+=r.length;const r=new Uint8Array(n);for(let n=0,e=0,i=t.length;n<i;n++){const i=t[n];r.set(i,e),e+=i.length}return r}(this._deflatedData);return this._init(),t}_init(){this._hasEvents=!1,this._deflatedData=[],this.deflate=new H,this.deflate.ondata=(t,n)=>{this._deflatedData.push(t)},this.stream=new N(((t,n)=>{this.deflate.push(t,n)})),this.stream.push(\"[\")}},V={clear:()=>{R.clear()},addEvent:t=>R.addEvent(t),finish:()=>R.finish(),compress:t=>Q(t)};addEventListener(\"message\",(function(t){const n=t.data.method,r=t.data.id,e=t.data.arg;if(n in V&&\"function\"==typeof V[n])try{const t=V[n](e);postMessage({id:r,method:n,success:!0,response:t})}catch(t){postMessage({id:r,method:n,success:!1,response:t.message}),console.error(t)}})),postMessage({id:void 0,method:\"init\",success:!0,response:void 0});`;\n\nfunction e(){const e=new Blob([r]);return URL.createObjectURL(e)}\n\n/** This error indicates that the event buffer size exceeded the limit.. */\nclass EventBufferSizeExceededError extends Error {\n   constructor() {\n    super(`Event buffer exceeded maximum size of ${REPLAY_MAX_EVENT_BUFFER_SIZE}.`);\n  }\n}\n\n/**\n * A basic event buffer that does not do any compression.\n * Used as fallback if the compression worker cannot be loaded or is disabled.\n */\nclass EventBufferArray  {\n  /** All the events that are buffered to be sent. */\n\n  /** @inheritdoc */\n\n   constructor() {\n    this.events = [];\n    this._totalSize = 0;\n    this.hasCheckout = false;\n  }\n\n  /** @inheritdoc */\n   get hasEvents() {\n    return this.events.length > 0;\n  }\n\n  /** @inheritdoc */\n   get type() {\n    return 'sync';\n  }\n\n  /** @inheritdoc */\n   destroy() {\n    this.events = [];\n  }\n\n  /** @inheritdoc */\n   async addEvent(event) {\n    const eventSize = JSON.stringify(event).length;\n    this._totalSize += eventSize;\n    if (this._totalSize > REPLAY_MAX_EVENT_BUFFER_SIZE) {\n      throw new EventBufferSizeExceededError();\n    }\n\n    this.events.push(event);\n  }\n\n  /** @inheritdoc */\n   finish() {\n    return new Promise(resolve => {\n      // Make a copy of the events array reference and immediately clear the\n      // events member so that we do not lose new events while uploading\n      // attachment.\n      const eventsRet = this.events;\n      this.clear();\n      resolve(JSON.stringify(eventsRet));\n    });\n  }\n\n  /** @inheritdoc */\n   clear() {\n    this.events = [];\n    this._totalSize = 0;\n    this.hasCheckout = false;\n  }\n\n  /** @inheritdoc */\n   getEarliestTimestamp() {\n    const timestamp = this.events.map(event => event.timestamp).sort()[0];\n\n    if (!timestamp) {\n      return null;\n    }\n\n    return timestampToMs(timestamp);\n  }\n}\n\n/**\n * Event buffer that uses a web worker to compress events.\n * Exported only for testing.\n */\nclass WorkerHandler {\n\n   constructor(worker) {\n    this._worker = worker;\n    this._id = 0;\n  }\n\n  /**\n   * Ensure the worker is ready (or not).\n   * This will either resolve when the worker is ready, or reject if an error occured.\n   */\n   ensureReady() {\n    // Ensure we only check once\n    if (this._ensureReadyPromise) {\n      return this._ensureReadyPromise;\n    }\n\n    this._ensureReadyPromise = new Promise((resolve, reject) => {\n      this._worker.addEventListener(\n        'message',\n        ({ data }) => {\n          if ((data ).success) {\n            resolve();\n          } else {\n            reject();\n          }\n        },\n        { once: true },\n      );\n\n      this._worker.addEventListener(\n        'error',\n        error => {\n          reject(error);\n        },\n        { once: true },\n      );\n    });\n\n    return this._ensureReadyPromise;\n  }\n\n  /**\n   * Destroy the worker.\n   */\n   destroy() {\n    DEBUG_BUILD && logger.info('Destroying compression worker');\n    this._worker.terminate();\n  }\n\n  /**\n   * Post message to worker and wait for response before resolving promise.\n   */\n   postMessage(method, arg) {\n    const id = this._getAndIncrementId();\n\n    return new Promise((resolve, reject) => {\n      const listener = ({ data }) => {\n        const response = data ;\n        if (response.method !== method) {\n          return;\n        }\n\n        // There can be multiple listeners for a single method, the id ensures\n        // that the response matches the caller.\n        if (response.id !== id) {\n          return;\n        }\n\n        // At this point, we'll always want to remove listener regardless of result status\n        this._worker.removeEventListener('message', listener);\n\n        if (!response.success) {\n          // TODO: Do some error handling, not sure what\n          DEBUG_BUILD && logger.error('Error in compression worker: ', response.response);\n\n          reject(new Error('Error in compression worker'));\n          return;\n        }\n\n        resolve(response.response );\n      };\n\n      // Note: we can't use `once` option because it's possible it needs to\n      // listen to multiple messages\n      this._worker.addEventListener('message', listener);\n      this._worker.postMessage({ id, method, arg });\n    });\n  }\n\n  /** Get the current ID and increment it for the next call. */\n   _getAndIncrementId() {\n    return this._id++;\n  }\n}\n\n/**\n * Event buffer that uses a web worker to compress events.\n * Exported only for testing.\n */\nclass EventBufferCompressionWorker  {\n  /** @inheritdoc */\n\n   constructor(worker) {\n    this._worker = new WorkerHandler(worker);\n    this._earliestTimestamp = null;\n    this._totalSize = 0;\n    this.hasCheckout = false;\n  }\n\n  /** @inheritdoc */\n   get hasEvents() {\n    return !!this._earliestTimestamp;\n  }\n\n  /** @inheritdoc */\n   get type() {\n    return 'worker';\n  }\n\n  /**\n   * Ensure the worker is ready (or not).\n   * This will either resolve when the worker is ready, or reject if an error occured.\n   */\n   ensureReady() {\n    return this._worker.ensureReady();\n  }\n\n  /**\n   * Destroy the event buffer.\n   */\n   destroy() {\n    this._worker.destroy();\n  }\n\n  /**\n   * Add an event to the event buffer.\n   *\n   * Returns true if event was successfuly received and processed by worker.\n   */\n   addEvent(event) {\n    const timestamp = timestampToMs(event.timestamp);\n    if (!this._earliestTimestamp || timestamp < this._earliestTimestamp) {\n      this._earliestTimestamp = timestamp;\n    }\n\n    const data = JSON.stringify(event);\n    this._totalSize += data.length;\n\n    if (this._totalSize > REPLAY_MAX_EVENT_BUFFER_SIZE) {\n      return Promise.reject(new EventBufferSizeExceededError());\n    }\n\n    return this._sendEventToWorker(data);\n  }\n\n  /**\n   * Finish the event buffer and return the compressed data.\n   */\n   finish() {\n    return this._finishRequest();\n  }\n\n  /** @inheritdoc */\n   clear() {\n    this._earliestTimestamp = null;\n    this._totalSize = 0;\n    this.hasCheckout = false;\n\n    // We do not wait on this, as we assume the order of messages is consistent for the worker\n    this._worker.postMessage('clear').then(null, e => {\n      DEBUG_BUILD && logger.exception(e, 'Sending \"clear\" message to worker failed', e);\n    });\n  }\n\n  /** @inheritdoc */\n   getEarliestTimestamp() {\n    return this._earliestTimestamp;\n  }\n\n  /**\n   * Send the event to the worker.\n   */\n   _sendEventToWorker(data) {\n    return this._worker.postMessage('addEvent', data);\n  }\n\n  /**\n   * Finish the request and return the compressed data from the worker.\n   */\n   async _finishRequest() {\n    const response = await this._worker.postMessage('finish');\n\n    this._earliestTimestamp = null;\n    this._totalSize = 0;\n\n    return response;\n  }\n}\n\n/**\n * This proxy will try to use the compression worker, and fall back to use the simple buffer if an error occurs there.\n * This can happen e.g. if the worker cannot be loaded.\n * Exported only for testing.\n */\nclass EventBufferProxy  {\n\n   constructor(worker) {\n    this._fallback = new EventBufferArray();\n    this._compression = new EventBufferCompressionWorker(worker);\n    this._used = this._fallback;\n\n    this._ensureWorkerIsLoadedPromise = this._ensureWorkerIsLoaded();\n  }\n\n  /** @inheritdoc */\n   get type() {\n    return this._used.type;\n  }\n\n  /** @inheritDoc */\n   get hasEvents() {\n    return this._used.hasEvents;\n  }\n\n  /** @inheritdoc */\n   get hasCheckout() {\n    return this._used.hasCheckout;\n  }\n  /** @inheritdoc */\n   set hasCheckout(value) {\n    this._used.hasCheckout = value;\n  }\n\n  /** @inheritDoc */\n   destroy() {\n    this._fallback.destroy();\n    this._compression.destroy();\n  }\n\n  /** @inheritdoc */\n   clear() {\n    return this._used.clear();\n  }\n\n  /** @inheritdoc */\n   getEarliestTimestamp() {\n    return this._used.getEarliestTimestamp();\n  }\n\n  /**\n   * Add an event to the event buffer.\n   *\n   * Returns true if event was successfully added.\n   */\n   addEvent(event) {\n    return this._used.addEvent(event);\n  }\n\n  /** @inheritDoc */\n   async finish() {\n    // Ensure the worker is loaded, so the sent event is compressed\n    await this.ensureWorkerIsLoaded();\n\n    return this._used.finish();\n  }\n\n  /** Ensure the worker has loaded. */\n   ensureWorkerIsLoaded() {\n    return this._ensureWorkerIsLoadedPromise;\n  }\n\n  /** Actually check if the worker has been loaded. */\n   async _ensureWorkerIsLoaded() {\n    try {\n      await this._compression.ensureReady();\n    } catch (error) {\n      // If the worker fails to load, we fall back to the simple buffer.\n      // Nothing more to do from our side here\n      DEBUG_BUILD && logger.exception(error, 'Failed to load the compression worker, falling back to simple buffer');\n      return;\n    }\n\n    // Now we need to switch over the array buffer to the compression worker\n    await this._switchToCompressionWorker();\n  }\n\n  /** Switch the used buffer to the compression worker. */\n   async _switchToCompressionWorker() {\n    const { events, hasCheckout } = this._fallback;\n\n    const addEventPromises = [];\n    for (const event of events) {\n      addEventPromises.push(this._compression.addEvent(event));\n    }\n\n    this._compression.hasCheckout = hasCheckout;\n\n    // We switch over to the new buffer immediately - any further events will be added\n    // after the previously buffered ones\n    this._used = this._compression;\n\n    // Wait for original events to be re-added before resolving\n    try {\n      await Promise.all(addEventPromises);\n\n      // Can now clear fallback buffer as it's no longer necessary\n      this._fallback.clear();\n    } catch (error) {\n      DEBUG_BUILD && logger.exception(error, 'Failed to add events when switching buffers.');\n    }\n  }\n}\n\n/**\n * Create an event buffer for replays.\n */\nfunction createEventBuffer({\n  useCompression,\n  workerUrl: customWorkerUrl,\n}) {\n  if (\n    useCompression &&\n    // eslint-disable-next-line no-restricted-globals\n    window.Worker\n  ) {\n    const worker = _loadWorker(customWorkerUrl);\n\n    if (worker) {\n      return worker;\n    }\n  }\n\n  DEBUG_BUILD && logger.info('Using simple buffer');\n  return new EventBufferArray();\n}\n\nfunction _loadWorker(customWorkerUrl) {\n  try {\n    const workerUrl = customWorkerUrl || _getWorkerUrl();\n\n    if (!workerUrl) {\n      return;\n    }\n\n    DEBUG_BUILD && logger.info(`Using compression worker${customWorkerUrl ? ` from ${customWorkerUrl}` : ''}`);\n    const worker = new Worker(workerUrl);\n    return new EventBufferProxy(worker);\n  } catch (error) {\n    DEBUG_BUILD && logger.exception(error, 'Failed to create compression worker');\n    // Fall back to use simple event buffer array\n  }\n}\n\nfunction _getWorkerUrl() {\n  if (typeof __SENTRY_EXCLUDE_REPLAY_WORKER__ === 'undefined' || !__SENTRY_EXCLUDE_REPLAY_WORKER__) {\n    return e();\n  }\n\n  return '';\n}\n\n/** If sessionStorage is available. */\nfunction hasSessionStorage() {\n  try {\n    // This can throw, e.g. when being accessed in a sandboxed iframe\n    return 'sessionStorage' in WINDOW && !!WINDOW.sessionStorage;\n  } catch (e) {\n    return false;\n  }\n}\n\n/**\n * Removes the session from Session Storage and unsets session in replay instance\n */\nfunction clearSession(replay) {\n  deleteSession();\n  replay.session = undefined;\n}\n\n/**\n * Deletes a session from storage\n */\nfunction deleteSession() {\n  if (!hasSessionStorage()) {\n    return;\n  }\n\n  try {\n    WINDOW.sessionStorage.removeItem(REPLAY_SESSION_KEY);\n  } catch (e) {\n    // Ignore potential SecurityError exceptions\n  }\n}\n\n/**\n * Given a sample rate, returns true if replay should be sampled.\n *\n * 1.0 = 100% sampling\n * 0.0 = 0% sampling\n */\nfunction isSampled(sampleRate) {\n  if (sampleRate === undefined) {\n    return false;\n  }\n\n  // Math.random() returns a number in range of 0 to 1 (inclusive of 0, but not 1)\n  return Math.random() < sampleRate;\n}\n\n/**\n * Get a session with defaults & applied sampling.\n */\nfunction makeSession(session) {\n  const now = Date.now();\n  const id = session.id || uuid4();\n  // Note that this means we cannot set a started/lastActivity of `0`, but this should not be relevant outside of tests.\n  const started = session.started || now;\n  const lastActivity = session.lastActivity || now;\n  const segmentId = session.segmentId || 0;\n  const sampled = session.sampled;\n  const previousSessionId = session.previousSessionId;\n\n  return {\n    id,\n    started,\n    lastActivity,\n    segmentId,\n    sampled,\n    previousSessionId,\n  };\n}\n\n/**\n * Save a session to session storage.\n */\nfunction saveSession(session) {\n  if (!hasSessionStorage()) {\n    return;\n  }\n\n  try {\n    WINDOW.sessionStorage.setItem(REPLAY_SESSION_KEY, JSON.stringify(session));\n  } catch (e) {\n    // Ignore potential SecurityError exceptions\n  }\n}\n\n/**\n * Get the sampled status for a session based on sample rates & current sampled status.\n */\nfunction getSessionSampleType(sessionSampleRate, allowBuffering) {\n  return isSampled(sessionSampleRate) ? 'session' : allowBuffering ? 'buffer' : false;\n}\n\n/**\n * Create a new session, which in its current implementation is a Sentry event\n * that all replays will be saved to as attachments. Currently, we only expect\n * one of these Sentry events per \"replay session\".\n */\nfunction createSession(\n  { sessionSampleRate, allowBuffering, stickySession = false },\n  { previousSessionId } = {},\n) {\n  const sampled = getSessionSampleType(sessionSampleRate, allowBuffering);\n  const session = makeSession({\n    sampled,\n    previousSessionId,\n  });\n\n  if (stickySession) {\n    saveSession(session);\n  }\n\n  return session;\n}\n\n/**\n * Fetches a session from storage\n */\nfunction fetchSession() {\n  if (!hasSessionStorage()) {\n    return null;\n  }\n\n  try {\n    // This can throw if cookies are disabled\n    const sessionStringFromStorage = WINDOW.sessionStorage.getItem(REPLAY_SESSION_KEY);\n\n    if (!sessionStringFromStorage) {\n      return null;\n    }\n\n    const sessionObj = JSON.parse(sessionStringFromStorage) ;\n\n    DEBUG_BUILD && logger.infoTick('Loading existing session');\n\n    return makeSession(sessionObj);\n  } catch (e) {\n    return null;\n  }\n}\n\n/**\n * Given an initial timestamp and an expiry duration, checks to see if current\n * time should be considered as expired.\n */\nfunction isExpired(\n  initialTime,\n  expiry,\n  targetTime = +new Date(),\n) {\n  // Always expired if < 0\n  if (initialTime === null || expiry === undefined || expiry < 0) {\n    return true;\n  }\n\n  // Never expires if == 0\n  if (expiry === 0) {\n    return false;\n  }\n\n  return initialTime + expiry <= targetTime;\n}\n\n/**\n * Checks to see if session is expired\n */\nfunction isSessionExpired(\n  session,\n  {\n    maxReplayDuration,\n    sessionIdleExpire,\n    targetTime = Date.now(),\n  },\n) {\n  return (\n    // First, check that maximum session length has not been exceeded\n    isExpired(session.started, maxReplayDuration, targetTime) ||\n    // check that the idle timeout has not been exceeded (i.e. user has\n    // performed an action within the last `sessionIdleExpire` ms)\n    isExpired(session.lastActivity, sessionIdleExpire, targetTime)\n  );\n}\n\n/** If the session should be refreshed or not. */\nfunction shouldRefreshSession(\n  session,\n  { sessionIdleExpire, maxReplayDuration },\n) {\n  // If not expired, all good, just keep the session\n  if (!isSessionExpired(session, { sessionIdleExpire, maxReplayDuration })) {\n    return false;\n  }\n\n  // If we are buffering & haven't ever flushed yet, always continue\n  if (session.sampled === 'buffer' && session.segmentId === 0) {\n    return false;\n  }\n\n  return true;\n}\n\n/**\n * Get or create a session, when initializing the replay.\n * Returns a session that may be unsampled.\n */\nfunction loadOrCreateSession(\n  {\n    sessionIdleExpire,\n    maxReplayDuration,\n    previousSessionId,\n  }\n\n,\n  sessionOptions,\n) {\n  const existingSession = sessionOptions.stickySession && fetchSession();\n\n  // No session exists yet, just create a new one\n  if (!existingSession) {\n    DEBUG_BUILD && logger.infoTick('Creating new session');\n    return createSession(sessionOptions, { previousSessionId });\n  }\n\n  if (!shouldRefreshSession(existingSession, { sessionIdleExpire, maxReplayDuration })) {\n    return existingSession;\n  }\n\n  DEBUG_BUILD && logger.infoTick('Session in sessionStorage is expired, creating new one...');\n  return createSession(sessionOptions, { previousSessionId: existingSession.id });\n}\n\nfunction isCustomEvent(event) {\n  return event.type === EventType.Custom;\n}\n\n/**\n * Add an event to the event buffer.\n * In contrast to `addEvent`, this does not return a promise & does not wait for the adding of the event to succeed/fail.\n * Instead this returns `true` if we tried to add the event, else false.\n * It returns `false` e.g. if we are paused, disabled, or out of the max replay duration.\n *\n * `isCheckout` is true if this is either the very first event, or an event triggered by `checkoutEveryNms`.\n */\nfunction addEventSync(replay, event, isCheckout) {\n  if (!shouldAddEvent(replay, event)) {\n    return false;\n  }\n\n  // This should never reject\n  // eslint-disable-next-line @typescript-eslint/no-floating-promises\n  _addEvent(replay, event, isCheckout);\n\n  return true;\n}\n\n/**\n * Add an event to the event buffer.\n * Resolves to `null` if no event was added, else to `void`.\n *\n * `isCheckout` is true if this is either the very first event, or an event triggered by `checkoutEveryNms`.\n */\nfunction addEvent(\n  replay,\n  event,\n  isCheckout,\n) {\n  if (!shouldAddEvent(replay, event)) {\n    return Promise.resolve(null);\n  }\n\n  return _addEvent(replay, event, isCheckout);\n}\n\nasync function _addEvent(\n  replay,\n  event,\n  isCheckout,\n) {\n  if (!replay.eventBuffer) {\n    return null;\n  }\n\n  try {\n    if (isCheckout && replay.recordingMode === 'buffer') {\n      replay.eventBuffer.clear();\n    }\n\n    if (isCheckout) {\n      replay.eventBuffer.hasCheckout = true;\n    }\n\n    const replayOptions = replay.getOptions();\n\n    const eventAfterPossibleCallback = maybeApplyCallback(event, replayOptions.beforeAddRecordingEvent);\n\n    if (!eventAfterPossibleCallback) {\n      return;\n    }\n\n    return await replay.eventBuffer.addEvent(eventAfterPossibleCallback);\n  } catch (error) {\n    const reason = error && error instanceof EventBufferSizeExceededError ? 'addEventSizeExceeded' : 'addEvent';\n    replay.handleException(error);\n\n    await replay.stop({ reason });\n\n    const client = getClient();\n\n    if (client) {\n      client.recordDroppedEvent('internal_sdk_error', 'replay');\n    }\n  }\n}\n\n/** Exported only for tests. */\nfunction shouldAddEvent(replay, event) {\n  if (!replay.eventBuffer || replay.isPaused() || !replay.isEnabled()) {\n    return false;\n  }\n\n  const timestampInMs = timestampToMs(event.timestamp);\n\n  // Throw out events that happen more than 5 minutes ago. This can happen if\n  // page has been left open and idle for a long period of time and user\n  // comes back to trigger a new session. The performance entries rely on\n  // `performance.timeOrigin`, which is when the page first opened.\n  if (timestampInMs + replay.timeouts.sessionIdlePause < Date.now()) {\n    return false;\n  }\n\n  // Throw out events that are +60min from the initial timestamp\n  if (timestampInMs > replay.getContext().initialTimestamp + replay.getOptions().maxReplayDuration) {\n    DEBUG_BUILD &&\n      logger.infoTick(`Skipping event with timestamp ${timestampInMs} because it is after maxReplayDuration`);\n    return false;\n  }\n\n  return true;\n}\n\nfunction maybeApplyCallback(\n  event,\n  callback,\n) {\n  try {\n    if (typeof callback === 'function' && isCustomEvent(event)) {\n      return callback(event);\n    }\n  } catch (error) {\n    DEBUG_BUILD &&\n      logger.exception(error, 'An error occured in the `beforeAddRecordingEvent` callback, skipping the event...');\n    return null;\n  }\n\n  return event;\n}\n\n/** If the event is an error event */\nfunction isErrorEvent(event) {\n  return !event.type;\n}\n\n/** If the event is a transaction event */\nfunction isTransactionEvent(event) {\n  return event.type === 'transaction';\n}\n\n/** If the event is an replay event */\nfunction isReplayEvent(event) {\n  return event.type === 'replay_event';\n}\n\n/** If the event is a feedback event */\nfunction isFeedbackEvent(event) {\n  return event.type === 'feedback';\n}\n\n/**\n * Returns a listener to be added to `client.on('afterSendErrorEvent, listener)`.\n */\nfunction handleAfterSendEvent(replay) {\n  return (event, sendResponse) => {\n    if (!replay.isEnabled() || (!isErrorEvent(event) && !isTransactionEvent(event))) {\n      return;\n    }\n\n    const statusCode = sendResponse && sendResponse.statusCode;\n\n    // We only want to do stuff on successful error sending, otherwise you get error replays without errors attached\n    // If not using the base transport, we allow `undefined` response (as a custom transport may not implement this correctly yet)\n    // If we do use the base transport, we skip if we encountered an non-OK status code\n    if (!statusCode || statusCode < 200 || statusCode >= 300) {\n      return;\n    }\n\n    if (isTransactionEvent(event)) {\n      handleTransactionEvent(replay, event);\n      return;\n    }\n\n    handleErrorEvent(replay, event);\n  };\n}\n\nfunction handleTransactionEvent(replay, event) {\n  const replayContext = replay.getContext();\n\n  // Collect traceIds in _context regardless of `recordingMode`\n  // In error mode, _context gets cleared on every checkout\n  // We limit to max. 100 transactions linked\n  if (event.contexts && event.contexts.trace && event.contexts.trace.trace_id && replayContext.traceIds.size < 100) {\n    replayContext.traceIds.add(event.contexts.trace.trace_id );\n  }\n}\n\nfunction handleErrorEvent(replay, event) {\n  const replayContext = replay.getContext();\n\n  // Add error to list of errorIds of replay. This is ok to do even if not\n  // sampled because context will get reset at next checkout.\n  // XXX: There is also a race condition where it's possible to capture an\n  // error to Sentry before Replay SDK has loaded, but response returns after\n  // it was loaded, and this gets called.\n  // We limit to max. 100 errors linked\n  if (event.event_id && replayContext.errorIds.size < 100) {\n    replayContext.errorIds.add(event.event_id);\n  }\n\n  // If error event is tagged with replay id it means it was sampled (when in buffer mode)\n  // Need to be very careful that this does not cause an infinite loop\n  if (replay.recordingMode !== 'buffer' || !event.tags || !event.tags.replayId) {\n    return;\n  }\n\n  const { beforeErrorSampling } = replay.getOptions();\n  if (typeof beforeErrorSampling === 'function' && !beforeErrorSampling(event)) {\n    return;\n  }\n\n  setTimeout$3(async () => {\n    try {\n      // Capture current event buffer as new replay\n      await replay.sendBufferedReplayOrFlush();\n    } catch (err) {\n      replay.handleException(err);\n    }\n  });\n}\n\n/**\n * Returns a listener to be added to `client.on('afterSendErrorEvent, listener)`.\n */\nfunction handleBeforeSendEvent(replay) {\n  return (event) => {\n    if (!replay.isEnabled() || !isErrorEvent(event)) {\n      return;\n    }\n\n    handleHydrationError(replay, event);\n  };\n}\n\nfunction handleHydrationError(replay, event) {\n  const exceptionValue =\n    event.exception && event.exception.values && event.exception.values[0] && event.exception.values[0].value;\n  if (typeof exceptionValue !== 'string') {\n    return;\n  }\n\n  if (\n    // Only matches errors in production builds of react-dom\n    // Example https://reactjs.org/docs/error-decoder.html?invariant=423\n    // With newer React versions, the messages changed to a different website https://react.dev/errors/418\n    exceptionValue.match(\n      /(reactjs\\.org\\/docs\\/error-decoder\\.html\\?invariant=|react\\.dev\\/errors\\/)(418|419|422|423|425)/,\n    ) ||\n    // Development builds of react-dom\n    // Error 1: Hydration failed because the initial UI does not match what was rendered on the server.\n    // Error 2: Text content does not match server-rendered HTML. Warning: Text content did not match.\n    exceptionValue.match(/(does not match server-rendered HTML|Hydration failed because)/i)\n  ) {\n    const breadcrumb = createBreadcrumb({\n      category: 'replay.hydrate-error',\n      data: {\n        url: getLocationHref(),\n      },\n    });\n    addBreadcrumbEvent(replay, breadcrumb);\n  }\n}\n\n/**\n * Handle breadcrumbs that Sentry captures, and make sure to capture relevant breadcrumbs to Replay as well.\n */\nfunction handleBreadcrumbs(replay) {\n  const client = getClient();\n\n  if (!client) {\n    return;\n  }\n\n  client.on('beforeAddBreadcrumb', breadcrumb => beforeAddBreadcrumb(replay, breadcrumb));\n}\n\nfunction beforeAddBreadcrumb(replay, breadcrumb) {\n  if (!replay.isEnabled() || !isBreadcrumbWithCategory(breadcrumb)) {\n    return;\n  }\n\n  const result = normalizeBreadcrumb(breadcrumb);\n  if (result) {\n    addBreadcrumbEvent(replay, result);\n  }\n}\n\n/** Exported only for tests. */\nfunction normalizeBreadcrumb(breadcrumb) {\n  if (\n    !isBreadcrumbWithCategory(breadcrumb) ||\n    [\n      // fetch & xhr are handled separately,in handleNetworkBreadcrumbs\n      'fetch',\n      'xhr',\n      // These two are breadcrumbs for emitted sentry events, we don't care about them\n      'sentry.event',\n      'sentry.transaction',\n    ].includes(breadcrumb.category) ||\n    // We capture UI breadcrumbs separately\n    breadcrumb.category.startsWith('ui.')\n  ) {\n    return null;\n  }\n\n  if (breadcrumb.category === 'console') {\n    return normalizeConsoleBreadcrumb(breadcrumb);\n  }\n\n  return createBreadcrumb(breadcrumb);\n}\n\n/** exported for tests only */\nfunction normalizeConsoleBreadcrumb(\n  breadcrumb,\n) {\n  const args = breadcrumb.data && breadcrumb.data.arguments;\n\n  if (!Array.isArray(args) || args.length === 0) {\n    return createBreadcrumb(breadcrumb);\n  }\n\n  let isTruncated = false;\n\n  // Avoid giant args captures\n  const normalizedArgs = args.map(arg => {\n    if (!arg) {\n      return arg;\n    }\n    if (typeof arg === 'string') {\n      if (arg.length > CONSOLE_ARG_MAX_SIZE) {\n        isTruncated = true;\n        return `${arg.slice(0, CONSOLE_ARG_MAX_SIZE)}…`;\n      }\n\n      return arg;\n    }\n    if (typeof arg === 'object') {\n      try {\n        const normalizedArg = normalize(arg, 7);\n        const stringified = JSON.stringify(normalizedArg);\n        if (stringified.length > CONSOLE_ARG_MAX_SIZE) {\n          isTruncated = true;\n          // We use the pretty printed JSON string here as a base\n          return `${JSON.stringify(normalizedArg, null, 2).slice(0, CONSOLE_ARG_MAX_SIZE)}…`;\n        }\n        return normalizedArg;\n      } catch (e) {\n        // fall back to default\n      }\n    }\n\n    return arg;\n  });\n\n  return createBreadcrumb({\n    ...breadcrumb,\n    data: {\n      ...breadcrumb.data,\n      arguments: normalizedArgs,\n      ...(isTruncated ? { _meta: { warnings: ['CONSOLE_ARG_TRUNCATED'] } } : {}),\n    },\n  });\n}\n\nfunction isBreadcrumbWithCategory(breadcrumb) {\n  return !!breadcrumb.category;\n}\n\n/**\n * Returns true if we think the given event is an error originating inside of rrweb.\n */\nfunction isRrwebError(event, hint) {\n  if (event.type || !event.exception || !event.exception.values || !event.exception.values.length) {\n    return false;\n  }\n\n  // @ts-expect-error this may be set by rrweb when it finds errors\n  if (hint.originalException && hint.originalException.__rrweb__) {\n    return true;\n  }\n\n  return false;\n}\n\n/**\n * Add a feedback breadcrumb event to replay.\n */\nfunction addFeedbackBreadcrumb(replay, event) {\n  replay.triggerUserActivity();\n  replay.addUpdate(() => {\n    if (!event.timestamp) {\n      // Ignore events that don't have timestamps (this shouldn't happen, more of a typing issue)\n      // Return true here so that we don't flush\n      return true;\n    }\n\n    // This should never reject\n    // eslint-disable-next-line @typescript-eslint/no-floating-promises\n    replay.throttledAddEvent({\n      type: EventType.Custom,\n      timestamp: event.timestamp * 1000,\n      data: {\n        tag: 'breadcrumb',\n        payload: {\n          timestamp: event.timestamp,\n          type: 'default',\n          category: 'sentry.feedback',\n          data: {\n            feedbackId: event.event_id,\n          },\n        },\n      },\n    } );\n\n    return false;\n  });\n}\n\n/**\n * Determine if event should be sampled (only applies in buffer mode).\n * When an event is captured by `hanldleGlobalEvent`, when in buffer mode\n * we determine if we want to sample the error or not.\n */\nfunction shouldSampleForBufferEvent(replay, event) {\n  if (replay.recordingMode !== 'buffer') {\n    return false;\n  }\n\n  // ignore this error because otherwise we could loop indefinitely with\n  // trying to capture replay and failing\n  if (event.message === UNABLE_TO_SEND_REPLAY) {\n    return false;\n  }\n\n  // Require the event to be an error event & to have an exception\n  if (!event.exception || event.type) {\n    return false;\n  }\n\n  return isSampled(replay.getOptions().errorSampleRate);\n}\n\n/**\n * Returns a listener to be added to `addEventProcessor(listener)`.\n */\nfunction handleGlobalEventListener(replay) {\n  return Object.assign(\n    (event, hint) => {\n      // Do nothing if replay has been disabled or paused\n      if (!replay.isEnabled() || replay.isPaused()) {\n        return event;\n      }\n\n      if (isReplayEvent(event)) {\n        // Replays have separate set of breadcrumbs, do not include breadcrumbs\n        // from core SDK\n        delete event.breadcrumbs;\n        return event;\n      }\n\n      // We only want to handle errors, transactions, and feedbacks, nothing else\n      if (!isErrorEvent(event) && !isTransactionEvent(event) && !isFeedbackEvent(event)) {\n        return event;\n      }\n\n      // Ensure we do not add replay_id if the session is expired\n      const isSessionActive = replay.checkAndHandleExpiredSession();\n      if (!isSessionActive) {\n        return event;\n      }\n\n      if (isFeedbackEvent(event)) {\n        // This should never reject\n        // eslint-disable-next-line @typescript-eslint/no-floating-promises\n        replay.flush();\n        event.contexts.feedback.replay_id = replay.getSessionId();\n        // Add a replay breadcrumb for this piece of feedback\n        addFeedbackBreadcrumb(replay, event);\n        return event;\n      }\n\n      // Unless `captureExceptions` is enabled, we want to ignore errors coming from rrweb\n      // As there can be a bunch of stuff going wrong in internals there, that we don't want to bubble up to users\n      if (isRrwebError(event, hint) && !replay.getOptions()._experiments.captureExceptions) {\n        DEBUG_BUILD && logger.log('Ignoring error from rrweb internals', event);\n        return null;\n      }\n\n      // When in buffer mode, we decide to sample here.\n      // Later, in `handleAfterSendEvent`, if the replayId is set, we know that we sampled\n      // And convert the buffer session to a full session\n      const isErrorEventSampled = shouldSampleForBufferEvent(replay, event);\n\n      // Tag errors if it has been sampled in buffer mode, or if it is session mode\n      // Only tag transactions if in session mode\n      const shouldTagReplayId = isErrorEventSampled || replay.recordingMode === 'session';\n\n      if (shouldTagReplayId) {\n        event.tags = { ...event.tags, replayId: replay.getSessionId() };\n      }\n\n      return event;\n    },\n    { id: 'Replay' },\n  );\n}\n\n/**\n * Create a \"span\" for each performance entry.\n */\nfunction createPerformanceSpans(\n  replay,\n  entries,\n) {\n  return entries.map(({ type, start, end, name, data }) => {\n    const response = replay.throttledAddEvent({\n      type: EventType.Custom,\n      timestamp: start,\n      data: {\n        tag: 'performanceSpan',\n        payload: {\n          op: type,\n          description: name,\n          startTimestamp: start,\n          endTimestamp: end,\n          data,\n        },\n      },\n    });\n\n    // If response is a string, it means its either THROTTLED or SKIPPED\n    return typeof response === 'string' ? Promise.resolve(null) : response;\n  });\n}\n\nfunction handleHistory(handlerData) {\n  const { from, to } = handlerData;\n\n  const now = Date.now() / 1000;\n\n  return {\n    type: 'navigation.push',\n    start: now,\n    end: now,\n    name: to,\n    data: {\n      previous: from,\n    },\n  };\n}\n\n/**\n * Returns a listener to be added to `addHistoryInstrumentationHandler(listener)`.\n */\nfunction handleHistorySpanListener(replay) {\n  return (handlerData) => {\n    if (!replay.isEnabled()) {\n      return;\n    }\n\n    const result = handleHistory(handlerData);\n\n    if (result === null) {\n      return;\n    }\n\n    // Need to collect visited URLs\n    replay.getContext().urls.push(result.name);\n    replay.triggerUserActivity();\n\n    replay.addUpdate(() => {\n      createPerformanceSpans(replay, [result]);\n      // Returning false to flush\n      return false;\n    });\n  };\n}\n\n/**\n * Check whether a given request URL should be filtered out. This is so we\n * don't log Sentry ingest requests.\n */\nfunction shouldFilterRequest(replay, url) {\n  // If we enabled the `traceInternals` experiment, we want to trace everything\n  if (DEBUG_BUILD && replay.getOptions()._experiments.traceInternals) {\n    return false;\n  }\n\n  return isSentryRequestUrl(url, getClient());\n}\n\n/** Add a performance entry breadcrumb */\nfunction addNetworkBreadcrumb(\n  replay,\n  result,\n) {\n  if (!replay.isEnabled()) {\n    return;\n  }\n\n  if (result === null) {\n    return;\n  }\n\n  if (shouldFilterRequest(replay, result.name)) {\n    return;\n  }\n\n  replay.addUpdate(() => {\n    createPerformanceSpans(replay, [result]);\n    // Returning true will cause `addUpdate` to not flush\n    // We do not want network requests to cause a flush. This will prevent\n    // recurring/polling requests from keeping the replay session alive.\n    return true;\n  });\n}\n\n/** Get the size of a body. */\nfunction getBodySize(body) {\n  if (!body) {\n    return undefined;\n  }\n\n  const textEncoder = new TextEncoder();\n\n  try {\n    if (typeof body === 'string') {\n      return textEncoder.encode(body).length;\n    }\n\n    if (body instanceof URLSearchParams) {\n      return textEncoder.encode(body.toString()).length;\n    }\n\n    if (body instanceof FormData) {\n      const formDataStr = _serializeFormData(body);\n      return textEncoder.encode(formDataStr).length;\n    }\n\n    if (body instanceof Blob) {\n      return body.size;\n    }\n\n    if (body instanceof ArrayBuffer) {\n      return body.byteLength;\n    }\n\n    // Currently unhandled types: ArrayBufferView, ReadableStream\n  } catch (e) {\n    // just return undefined\n  }\n\n  return undefined;\n}\n\n/** Convert a Content-Length header to number/undefined.  */\nfunction parseContentLengthHeader(header) {\n  if (!header) {\n    return undefined;\n  }\n\n  const size = parseInt(header, 10);\n  return isNaN(size) ? undefined : size;\n}\n\n/** Get the string representation of a body. */\nfunction getBodyString(body) {\n  try {\n    if (typeof body === 'string') {\n      return [body];\n    }\n\n    if (body instanceof URLSearchParams) {\n      return [body.toString()];\n    }\n\n    if (body instanceof FormData) {\n      return [_serializeFormData(body)];\n    }\n\n    if (!body) {\n      return [undefined];\n    }\n  } catch (error) {\n    DEBUG_BUILD && logger.exception(error, 'Failed to serialize body', body);\n    return [undefined, 'BODY_PARSE_ERROR'];\n  }\n\n  DEBUG_BUILD && logger.info('Skipping network body because of body type', body);\n\n  return [undefined, 'UNPARSEABLE_BODY_TYPE'];\n}\n\n/** Merge a warning into an existing network request/response. */\nfunction mergeWarning(\n  info,\n  warning,\n) {\n  if (!info) {\n    return {\n      headers: {},\n      size: undefined,\n      _meta: {\n        warnings: [warning],\n      },\n    };\n  }\n\n  const newMeta = { ...info._meta };\n  const existingWarnings = newMeta.warnings || [];\n  newMeta.warnings = [...existingWarnings, warning];\n\n  info._meta = newMeta;\n  return info;\n}\n\n/** Convert ReplayNetworkRequestData to a PerformanceEntry. */\nfunction makeNetworkReplayBreadcrumb(\n  type,\n  data,\n) {\n  if (!data) {\n    return null;\n  }\n\n  const { startTimestamp, endTimestamp, url, method, statusCode, request, response } = data;\n\n  const result = {\n    type,\n    start: startTimestamp / 1000,\n    end: endTimestamp / 1000,\n    name: url,\n    data: dropUndefinedKeys({\n      method,\n      statusCode,\n      request,\n      response,\n    }),\n  };\n\n  return result;\n}\n\n/** Build the request or response part of a replay network breadcrumb that was skipped. */\nfunction buildSkippedNetworkRequestOrResponse(bodySize) {\n  return {\n    headers: {},\n    size: bodySize,\n    _meta: {\n      warnings: ['URL_SKIPPED'],\n    },\n  };\n}\n\n/** Build the request or response part of a replay network breadcrumb. */\nfunction buildNetworkRequestOrResponse(\n  headers,\n  bodySize,\n  body,\n) {\n  if (!bodySize && Object.keys(headers).length === 0) {\n    return undefined;\n  }\n\n  if (!bodySize) {\n    return {\n      headers,\n    };\n  }\n\n  if (!body) {\n    return {\n      headers,\n      size: bodySize,\n    };\n  }\n\n  const info = {\n    headers,\n    size: bodySize,\n  };\n\n  const { body: normalizedBody, warnings } = normalizeNetworkBody(body);\n  info.body = normalizedBody;\n  if (warnings && warnings.length > 0) {\n    info._meta = {\n      warnings,\n    };\n  }\n\n  return info;\n}\n\n/** Filter a set of headers */\nfunction getAllowedHeaders(headers, allowedHeaders) {\n  return Object.entries(headers).reduce((filteredHeaders, [key, value]) => {\n    const normalizedKey = key.toLowerCase();\n    // Avoid putting empty strings into the headers\n    if (allowedHeaders.includes(normalizedKey) && headers[key]) {\n      filteredHeaders[normalizedKey] = value;\n    }\n    return filteredHeaders;\n  }, {});\n}\n\nfunction _serializeFormData(formData) {\n  // This is a bit simplified, but gives us a decent estimate\n  // This converts e.g. { name: 'Anne Smith', age: 13 } to 'name=Anne+Smith&age=13'\n  // @ts-expect-error passing FormData to URLSearchParams actually works\n  return new URLSearchParams(formData).toString();\n}\n\nfunction normalizeNetworkBody(body)\n\n {\n  if (!body || typeof body !== 'string') {\n    return {\n      body,\n    };\n  }\n\n  const exceedsSizeLimit = body.length > NETWORK_BODY_MAX_SIZE;\n  const isProbablyJson = _strIsProbablyJson(body);\n\n  if (exceedsSizeLimit) {\n    const truncatedBody = body.slice(0, NETWORK_BODY_MAX_SIZE);\n\n    if (isProbablyJson) {\n      return {\n        body: truncatedBody,\n        warnings: ['MAYBE_JSON_TRUNCATED'],\n      };\n    }\n\n    return {\n      body: `${truncatedBody}…`,\n      warnings: ['TEXT_TRUNCATED'],\n    };\n  }\n\n  if (isProbablyJson) {\n    try {\n      const jsonBody = JSON.parse(body);\n      return {\n        body: jsonBody,\n      };\n    } catch (e2) {\n      // fall back to just send the body as string\n    }\n  }\n\n  return {\n    body,\n  };\n}\n\nfunction _strIsProbablyJson(str) {\n  const first = str[0];\n  const last = str[str.length - 1];\n\n  // Simple check: If this does not start & end with {} or [], it's not JSON\n  return (first === '[' && last === ']') || (first === '{' && last === '}');\n}\n\n/** Match an URL against a list of strings/Regex. */\nfunction urlMatches(url, urls) {\n  const fullUrl = getFullUrl(url);\n\n  return stringMatchesSomePattern(fullUrl, urls);\n}\n\n/** exported for tests */\nfunction getFullUrl(url, baseURI = WINDOW.document.baseURI) {\n  // Short circuit for common cases:\n  if (url.startsWith('http://') || url.startsWith('https://') || url.startsWith(WINDOW.location.origin)) {\n    return url;\n  }\n  const fixedUrl = new URL(url, baseURI);\n\n  // If these do not match, we are not dealing with a relative URL, so just return it\n  if (fixedUrl.origin !== new URL(baseURI).origin) {\n    return url;\n  }\n\n  const fullUrl = fixedUrl.href;\n\n  // Remove trailing slashes, if they don't match the original URL\n  if (!url.endsWith('/') && fullUrl.endsWith('/')) {\n    return fullUrl.slice(0, -1);\n  }\n\n  return fullUrl;\n}\n\n/**\n * Capture a fetch breadcrumb to a replay.\n * This adds additional data (where approriate).\n */\nasync function captureFetchBreadcrumbToReplay(\n  breadcrumb,\n  hint,\n  options\n\n,\n) {\n  try {\n    const data = await _prepareFetchData(breadcrumb, hint, options);\n\n    // Create a replay performance entry from this breadcrumb\n    const result = makeNetworkReplayBreadcrumb('resource.fetch', data);\n    addNetworkBreadcrumb(options.replay, result);\n  } catch (error) {\n    DEBUG_BUILD && logger.exception(error, 'Failed to capture fetch breadcrumb');\n  }\n}\n\n/**\n * Enrich a breadcrumb with additional data.\n * This has to be sync & mutate the given breadcrumb,\n * as the breadcrumb is afterwards consumed by other handlers.\n */\nfunction enrichFetchBreadcrumb(\n  breadcrumb,\n  hint,\n) {\n  const { input, response } = hint;\n\n  const body = input ? _getFetchRequestArgBody(input) : undefined;\n  const reqSize = getBodySize(body);\n\n  const resSize = response ? parseContentLengthHeader(response.headers.get('content-length')) : undefined;\n\n  if (reqSize !== undefined) {\n    breadcrumb.data.request_body_size = reqSize;\n  }\n  if (resSize !== undefined) {\n    breadcrumb.data.response_body_size = resSize;\n  }\n}\n\nasync function _prepareFetchData(\n  breadcrumb,\n  hint,\n  options,\n) {\n  const now = Date.now();\n  const { startTimestamp = now, endTimestamp = now } = hint;\n\n  const {\n    url,\n    method,\n    status_code: statusCode = 0,\n    request_body_size: requestBodySize,\n    response_body_size: responseBodySize,\n  } = breadcrumb.data;\n\n  const captureDetails =\n    urlMatches(url, options.networkDetailAllowUrls) && !urlMatches(url, options.networkDetailDenyUrls);\n\n  const request = captureDetails\n    ? _getRequestInfo(options, hint.input, requestBodySize)\n    : buildSkippedNetworkRequestOrResponse(requestBodySize);\n  const response = await _getResponseInfo(captureDetails, options, hint.response, responseBodySize);\n\n  return {\n    startTimestamp,\n    endTimestamp,\n    url,\n    method,\n    statusCode,\n    request,\n    response,\n  };\n}\n\nfunction _getRequestInfo(\n  { networkCaptureBodies, networkRequestHeaders },\n  input,\n  requestBodySize,\n) {\n  const headers = input ? getRequestHeaders(input, networkRequestHeaders) : {};\n\n  if (!networkCaptureBodies) {\n    return buildNetworkRequestOrResponse(headers, requestBodySize, undefined);\n  }\n\n  // We only want to transmit string or string-like bodies\n  const requestBody = _getFetchRequestArgBody(input);\n  const [bodyStr, warning] = getBodyString(requestBody);\n  const data = buildNetworkRequestOrResponse(headers, requestBodySize, bodyStr);\n\n  if (warning) {\n    return mergeWarning(data, warning);\n  }\n\n  return data;\n}\n\n/** Exported only for tests. */\nasync function _getResponseInfo(\n  captureDetails,\n  {\n    networkCaptureBodies,\n    networkResponseHeaders,\n  },\n  response,\n  responseBodySize,\n) {\n  if (!captureDetails && responseBodySize !== undefined) {\n    return buildSkippedNetworkRequestOrResponse(responseBodySize);\n  }\n\n  const headers = response ? getAllHeaders(response.headers, networkResponseHeaders) : {};\n\n  if (!response || (!networkCaptureBodies && responseBodySize !== undefined)) {\n    return buildNetworkRequestOrResponse(headers, responseBodySize, undefined);\n  }\n\n  const [bodyText, warning] = await _parseFetchResponseBody(response);\n  const result = getResponseData(bodyText, {\n    networkCaptureBodies,\n\n    responseBodySize,\n    captureDetails,\n    headers,\n  });\n\n  if (warning) {\n    return mergeWarning(result, warning);\n  }\n\n  return result;\n}\n\nfunction getResponseData(\n  bodyText,\n  {\n    networkCaptureBodies,\n    responseBodySize,\n    captureDetails,\n    headers,\n  }\n\n,\n) {\n  try {\n    const size =\n      bodyText && bodyText.length && responseBodySize === undefined ? getBodySize(bodyText) : responseBodySize;\n\n    if (!captureDetails) {\n      return buildSkippedNetworkRequestOrResponse(size);\n    }\n\n    if (networkCaptureBodies) {\n      return buildNetworkRequestOrResponse(headers, size, bodyText);\n    }\n\n    return buildNetworkRequestOrResponse(headers, size, undefined);\n  } catch (error) {\n    DEBUG_BUILD && logger.exception(error, 'Failed to serialize response body');\n    // fallback\n    return buildNetworkRequestOrResponse(headers, responseBodySize, undefined);\n  }\n}\n\nasync function _parseFetchResponseBody(response) {\n  const res = _tryCloneResponse(response);\n\n  if (!res) {\n    return [undefined, 'BODY_PARSE_ERROR'];\n  }\n\n  try {\n    const text = await _tryGetResponseText(res);\n    return [text];\n  } catch (error) {\n    DEBUG_BUILD && logger.exception(error, 'Failed to get text body from response');\n    return [undefined, 'BODY_PARSE_ERROR'];\n  }\n}\n\nfunction _getFetchRequestArgBody(fetchArgs = []) {\n  // We only support getting the body from the fetch options\n  if (fetchArgs.length !== 2 || typeof fetchArgs[1] !== 'object') {\n    return undefined;\n  }\n\n  return (fetchArgs[1] ).body;\n}\n\nfunction getAllHeaders(headers, allowedHeaders) {\n  const allHeaders = {};\n\n  allowedHeaders.forEach(header => {\n    if (headers.get(header)) {\n      allHeaders[header] = headers.get(header) ;\n    }\n  });\n\n  return allHeaders;\n}\n\nfunction getRequestHeaders(fetchArgs, allowedHeaders) {\n  if (fetchArgs.length === 1 && typeof fetchArgs[0] !== 'string') {\n    return getHeadersFromOptions(fetchArgs[0] , allowedHeaders);\n  }\n\n  if (fetchArgs.length === 2) {\n    return getHeadersFromOptions(fetchArgs[1] , allowedHeaders);\n  }\n\n  return {};\n}\n\nfunction getHeadersFromOptions(\n  input,\n  allowedHeaders,\n) {\n  if (!input) {\n    return {};\n  }\n\n  const headers = input.headers;\n\n  if (!headers) {\n    return {};\n  }\n\n  if (headers instanceof Headers) {\n    return getAllHeaders(headers, allowedHeaders);\n  }\n\n  // We do not support this, as it is not really documented (anymore?)\n  if (Array.isArray(headers)) {\n    return {};\n  }\n\n  return getAllowedHeaders(headers, allowedHeaders);\n}\n\nfunction _tryCloneResponse(response) {\n  try {\n    // We have to clone this, as the body can only be read once\n    return response.clone();\n  } catch (error) {\n    // this can throw if the response was already consumed before\n    DEBUG_BUILD && logger.exception(error, 'Failed to clone response body');\n  }\n}\n\n/**\n * Get the response body of a fetch request, or timeout after 500ms.\n * Fetch can return a streaming body, that may not resolve (or not for a long time).\n * If that happens, we rather abort after a short time than keep waiting for this.\n */\nfunction _tryGetResponseText(response) {\n  return new Promise((resolve, reject) => {\n    const timeout = setTimeout$3(() => reject(new Error('Timeout while trying to read response body')), 500);\n\n    _getResponseText(response)\n      .then(\n        txt => resolve(txt),\n        reason => reject(reason),\n      )\n      .finally(() => clearTimeout(timeout));\n  });\n}\n\nasync function _getResponseText(response) {\n  // Force this to be a promise, just to be safe\n  // eslint-disable-next-line no-return-await\n  return await response.text();\n}\n\n/**\n * Capture an XHR breadcrumb to a replay.\n * This adds additional data (where approriate).\n */\nasync function captureXhrBreadcrumbToReplay(\n  breadcrumb,\n  hint,\n  options,\n) {\n  try {\n    const data = _prepareXhrData(breadcrumb, hint, options);\n\n    // Create a replay performance entry from this breadcrumb\n    const result = makeNetworkReplayBreadcrumb('resource.xhr', data);\n    addNetworkBreadcrumb(options.replay, result);\n  } catch (error) {\n    DEBUG_BUILD && logger.exception(error, 'Failed to capture xhr breadcrumb');\n  }\n}\n\n/**\n * Enrich a breadcrumb with additional data.\n * This has to be sync & mutate the given breadcrumb,\n * as the breadcrumb is afterwards consumed by other handlers.\n */\nfunction enrichXhrBreadcrumb(\n  breadcrumb,\n  hint,\n) {\n  const { xhr, input } = hint;\n\n  if (!xhr) {\n    return;\n  }\n\n  const reqSize = getBodySize(input);\n  const resSize = xhr.getResponseHeader('content-length')\n    ? parseContentLengthHeader(xhr.getResponseHeader('content-length'))\n    : _getBodySize(xhr.response, xhr.responseType);\n\n  if (reqSize !== undefined) {\n    breadcrumb.data.request_body_size = reqSize;\n  }\n  if (resSize !== undefined) {\n    breadcrumb.data.response_body_size = resSize;\n  }\n}\n\nfunction _prepareXhrData(\n  breadcrumb,\n  hint,\n  options,\n) {\n  const now = Date.now();\n  const { startTimestamp = now, endTimestamp = now, input, xhr } = hint;\n\n  const {\n    url,\n    method,\n    status_code: statusCode = 0,\n    request_body_size: requestBodySize,\n    response_body_size: responseBodySize,\n  } = breadcrumb.data;\n\n  if (!url) {\n    return null;\n  }\n\n  if (!xhr || !urlMatches(url, options.networkDetailAllowUrls) || urlMatches(url, options.networkDetailDenyUrls)) {\n    const request = buildSkippedNetworkRequestOrResponse(requestBodySize);\n    const response = buildSkippedNetworkRequestOrResponse(responseBodySize);\n    return {\n      startTimestamp,\n      endTimestamp,\n      url,\n      method,\n      statusCode,\n      request,\n      response,\n    };\n  }\n\n  const xhrInfo = xhr[SENTRY_XHR_DATA_KEY];\n  const networkRequestHeaders = xhrInfo\n    ? getAllowedHeaders(xhrInfo.request_headers, options.networkRequestHeaders)\n    : {};\n  const networkResponseHeaders = getAllowedHeaders(getResponseHeaders(xhr), options.networkResponseHeaders);\n\n  const [requestBody, requestWarning] = options.networkCaptureBodies ? getBodyString(input) : [undefined];\n  const [responseBody, responseWarning] = options.networkCaptureBodies ? _getXhrResponseBody(xhr) : [undefined];\n\n  const request = buildNetworkRequestOrResponse(networkRequestHeaders, requestBodySize, requestBody);\n  const response = buildNetworkRequestOrResponse(networkResponseHeaders, responseBodySize, responseBody);\n\n  return {\n    startTimestamp,\n    endTimestamp,\n    url,\n    method,\n    statusCode,\n    request: requestWarning ? mergeWarning(request, requestWarning) : request,\n    response: responseWarning ? mergeWarning(response, responseWarning) : response,\n  };\n}\n\nfunction getResponseHeaders(xhr) {\n  const headers = xhr.getAllResponseHeaders();\n\n  if (!headers) {\n    return {};\n  }\n\n  return headers.split('\\r\\n').reduce((acc, line) => {\n    const [key, value] = line.split(': ') ;\n    if (value) {\n      acc[key.toLowerCase()] = value;\n    }\n    return acc;\n  }, {});\n}\n\nfunction _getXhrResponseBody(xhr) {\n  // We collect errors that happen, but only log them if we can't get any response body\n  const errors = [];\n\n  try {\n    return [xhr.responseText];\n  } catch (e) {\n    errors.push(e);\n  }\n\n  // Try to manually parse the response body, if responseText fails\n  try {\n    return _parseXhrResponse(xhr.response, xhr.responseType);\n  } catch (e) {\n    errors.push(e);\n  }\n\n  DEBUG_BUILD && logger.warn('Failed to get xhr response body', ...errors);\n\n  return [undefined];\n}\n\n/**\n * Get the string representation of the XHR response.\n * Based on MDN, these are the possible types of the response:\n * string\n * ArrayBuffer\n * Blob\n * Document\n * POJO\n *\n * Exported only for tests.\n */\nfunction _parseXhrResponse(\n  body,\n  responseType,\n) {\n  try {\n    if (typeof body === 'string') {\n      return [body];\n    }\n\n    if (body instanceof Document) {\n      return [body.body.outerHTML];\n    }\n\n    if (responseType === 'json' && body && typeof body === 'object') {\n      return [JSON.stringify(body)];\n    }\n\n    if (!body) {\n      return [undefined];\n    }\n  } catch (error) {\n    DEBUG_BUILD && logger.exception(error, 'Failed to serialize body', body);\n    return [undefined, 'BODY_PARSE_ERROR'];\n  }\n\n  DEBUG_BUILD && logger.info('Skipping network body because of body type', body);\n\n  return [undefined, 'UNPARSEABLE_BODY_TYPE'];\n}\n\nfunction _getBodySize(\n  body,\n  responseType,\n) {\n  try {\n    const bodyStr = responseType === 'json' && body && typeof body === 'object' ? JSON.stringify(body) : body;\n    return getBodySize(bodyStr);\n  } catch (e2) {\n    return undefined;\n  }\n}\n\n/**\n * This method does two things:\n * - It enriches the regular XHR/fetch breadcrumbs with request/response size data\n * - It captures the XHR/fetch breadcrumbs to the replay\n *   (enriching it with further data that is _not_ added to the regular breadcrumbs)\n */\nfunction handleNetworkBreadcrumbs(replay) {\n  const client = getClient();\n\n  try {\n    const {\n      networkDetailAllowUrls,\n      networkDetailDenyUrls,\n      networkCaptureBodies,\n      networkRequestHeaders,\n      networkResponseHeaders,\n    } = replay.getOptions();\n\n    const options = {\n      replay,\n      networkDetailAllowUrls,\n      networkDetailDenyUrls,\n      networkCaptureBodies,\n      networkRequestHeaders,\n      networkResponseHeaders,\n    };\n\n    if (client) {\n      client.on('beforeAddBreadcrumb', (breadcrumb, hint) => beforeAddNetworkBreadcrumb(options, breadcrumb, hint));\n    }\n  } catch (e2) {\n    // Do nothing\n  }\n}\n\n/** just exported for tests */\nfunction beforeAddNetworkBreadcrumb(\n  options,\n  breadcrumb,\n  hint,\n) {\n  if (!breadcrumb.data) {\n    return;\n  }\n\n  try {\n    if (_isXhrBreadcrumb(breadcrumb) && _isXhrHint(hint)) {\n      // This has to be sync, as we need to ensure the breadcrumb is enriched in the same tick\n      // Because the hook runs synchronously, and the breadcrumb is afterwards passed on\n      // So any async mutations to it will not be reflected in the final breadcrumb\n      enrichXhrBreadcrumb(breadcrumb, hint);\n\n      // This call should not reject\n      // eslint-disable-next-line @typescript-eslint/no-floating-promises\n      captureXhrBreadcrumbToReplay(breadcrumb, hint, options);\n    }\n\n    if (_isFetchBreadcrumb(breadcrumb) && _isFetchHint(hint)) {\n      // This has to be sync, as we need to ensure the breadcrumb is enriched in the same tick\n      // Because the hook runs synchronously, and the breadcrumb is afterwards passed on\n      // So any async mutations to it will not be reflected in the final breadcrumb\n      enrichFetchBreadcrumb(breadcrumb, hint);\n\n      // This call should not reject\n      // eslint-disable-next-line @typescript-eslint/no-floating-promises\n      captureFetchBreadcrumbToReplay(breadcrumb, hint, options);\n    }\n  } catch (e) {\n    DEBUG_BUILD && logger.exception(e, 'Error when enriching network breadcrumb');\n  }\n}\n\nfunction _isXhrBreadcrumb(breadcrumb) {\n  return breadcrumb.category === 'xhr';\n}\n\nfunction _isFetchBreadcrumb(breadcrumb) {\n  return breadcrumb.category === 'fetch';\n}\n\nfunction _isXhrHint(hint) {\n  return hint && hint.xhr;\n}\n\nfunction _isFetchHint(hint) {\n  return hint && hint.response;\n}\n\n/**\n * Add global listeners that cannot be removed.\n */\nfunction addGlobalListeners(replay) {\n  // Listeners from core SDK //\n  const client = getClient();\n\n  addClickKeypressInstrumentationHandler(handleDomListener(replay));\n  addHistoryInstrumentationHandler(handleHistorySpanListener(replay));\n  handleBreadcrumbs(replay);\n  handleNetworkBreadcrumbs(replay);\n\n  // Tag all (non replay) events that get sent to Sentry with the current\n  // replay ID so that we can reference them later in the UI\n  const eventProcessor = handleGlobalEventListener(replay);\n  addEventProcessor(eventProcessor);\n\n  // If a custom client has no hooks yet, we continue to use the \"old\" implementation\n  if (client) {\n    client.on('beforeSendEvent', handleBeforeSendEvent(replay));\n    client.on('afterSendEvent', handleAfterSendEvent(replay));\n    client.on('createDsc', (dsc) => {\n      const replayId = replay.getSessionId();\n      // We do not want to set the DSC when in buffer mode, as that means the replay has not been sent (yet)\n      if (replayId && replay.isEnabled() && replay.recordingMode === 'session') {\n        // Ensure to check that the session is still active - it could have expired in the meanwhile\n        const isSessionActive = replay.checkAndHandleExpiredSession();\n        if (isSessionActive) {\n          dsc.replay_id = replayId;\n        }\n      }\n    });\n\n    client.on('spanStart', span => {\n      replay.lastActiveSpan = span;\n    });\n\n    // We may be missing the initial spanStart due to timing issues,\n    // so we capture it on finish again.\n    client.on('spanEnd', span => {\n      replay.lastActiveSpan = span;\n    });\n\n    // We want to flush replay\n    client.on('beforeSendFeedback', (feedbackEvent, options) => {\n      const replayId = replay.getSessionId();\n      if (options && options.includeReplay && replay.isEnabled() && replayId) {\n        // This should never reject\n        if (feedbackEvent.contexts && feedbackEvent.contexts.feedback) {\n          feedbackEvent.contexts.feedback.replay_id = replayId;\n        }\n      }\n    });\n  }\n}\n\n/**\n * Create a \"span\" for the total amount of memory being used by JS objects\n * (including v8 internal objects).\n */\nasync function addMemoryEntry(replay) {\n  // window.performance.memory is a non-standard API and doesn't work on all browsers, so we try-catch this\n  try {\n    return Promise.all(\n      createPerformanceSpans(replay, [\n        // @ts-expect-error memory doesn't exist on type Performance as the API is non-standard (we check that it exists above)\n        createMemoryEntry(WINDOW.performance.memory),\n      ]),\n    );\n  } catch (error) {\n    // Do nothing\n    return [];\n  }\n}\n\nfunction createMemoryEntry(memoryEntry) {\n  const { jsHeapSizeLimit, totalJSHeapSize, usedJSHeapSize } = memoryEntry;\n  // we don't want to use `getAbsoluteTime` because it adds the event time to the\n  // time origin, so we get the current timestamp instead\n  const time = Date.now() / 1000;\n  return {\n    type: 'memory',\n    name: 'memory',\n    start: time,\n    end: time,\n    data: {\n      memory: {\n        jsHeapSizeLimit,\n        totalJSHeapSize,\n        usedJSHeapSize,\n      },\n    },\n  };\n}\n\n/**\n * Heavily simplified debounce function based on lodash.debounce.\n *\n * This function takes a callback function (@param fun) and delays its invocation\n * by @param wait milliseconds. Optionally, a maxWait can be specified in @param options,\n * which ensures that the callback is invoked at least once after the specified max. wait time.\n *\n * @param func the function whose invocation is to be debounced\n * @param wait the minimum time until the function is invoked after it was called once\n * @param options the options object, which can contain the `maxWait` property\n *\n * @returns the debounced version of the function, which needs to be called at least once to start the\n *          debouncing process. Subsequent calls will reset the debouncing timer and, in case @paramfunc\n *          was already invoked in the meantime, return @param func's return value.\n *          The debounced function has two additional properties:\n *          - `flush`: Invokes the debounced function immediately and returns its return value\n *          - `cancel`: Cancels the debouncing process and resets the debouncing timer\n */\nfunction debounce(func, wait, options) {\n  let callbackReturnValue;\n\n  let timerId;\n  let maxTimerId;\n\n  const maxWait = options && options.maxWait ? Math.max(options.maxWait, wait) : 0;\n\n  function invokeFunc() {\n    cancelTimers();\n    callbackReturnValue = func();\n    return callbackReturnValue;\n  }\n\n  function cancelTimers() {\n    timerId !== undefined && clearTimeout(timerId);\n    maxTimerId !== undefined && clearTimeout(maxTimerId);\n    timerId = maxTimerId = undefined;\n  }\n\n  function flush() {\n    if (timerId !== undefined || maxTimerId !== undefined) {\n      return invokeFunc();\n    }\n    return callbackReturnValue;\n  }\n\n  function debounced() {\n    if (timerId) {\n      clearTimeout(timerId);\n    }\n    timerId = setTimeout$3(invokeFunc, wait);\n\n    if (maxWait && maxTimerId === undefined) {\n      maxTimerId = setTimeout$3(invokeFunc, maxWait);\n    }\n\n    return callbackReturnValue;\n  }\n\n  debounced.cancel = cancelTimers;\n  debounced.flush = flush;\n  return debounced;\n}\n\n/**\n * Handler for recording events.\n *\n * Adds to event buffer, and has varying flushing behaviors if the event was a checkout.\n */\nfunction getHandleRecordingEmit(replay) {\n  let hadFirstEvent = false;\n\n  return (event, _isCheckout) => {\n    // If this is false, it means session is expired, create and a new session and wait for checkout\n    if (!replay.checkAndHandleExpiredSession()) {\n      DEBUG_BUILD && logger.warn('Received replay event after session expired.');\n\n      return;\n    }\n\n    // `_isCheckout` is only set when the checkout is due to `checkoutEveryNms`\n    // We also want to treat the first event as a checkout, so we handle this specifically here\n    const isCheckout = _isCheckout || !hadFirstEvent;\n    hadFirstEvent = true;\n\n    if (replay.clickDetector) {\n      updateClickDetectorForRecordingEvent(replay.clickDetector, event);\n    }\n\n    // The handler returns `true` if we do not want to trigger debounced flush, `false` if we want to debounce flush.\n    replay.addUpdate(() => {\n      // The session is always started immediately on pageload/init, but for\n      // error-only replays, it should reflect the most recent checkout\n      // when an error occurs. Clear any state that happens before this current\n      // checkout. This needs to happen before `addEvent()` which updates state\n      // dependent on this reset.\n      if (replay.recordingMode === 'buffer' && isCheckout) {\n        replay.setInitialState();\n      }\n\n      // If the event is not added (e.g. due to being paused, disabled, or out of the max replay duration),\n      // Skip all further steps\n      if (!addEventSync(replay, event, isCheckout)) {\n        // Return true to skip scheduling a debounced flush\n        return true;\n      }\n\n      // Different behavior for full snapshots (type=2), ignore other event types\n      // See https://github.com/rrweb-io/rrweb/blob/d8f9290ca496712aa1e7d472549480c4e7876594/packages/rrweb/src/types.ts#L16\n      if (!isCheckout) {\n        return false;\n      }\n\n      const session = replay.session;\n\n      // Additionally, create a meta event that will capture certain SDK settings.\n      // In order to handle buffer mode, this needs to either be done when we\n      // receive checkout events or at flush time. We have an experimental mode\n      // to perform multiple checkouts a session (the idea is to improve\n      // seeking during playback), so also only include if segmentId is 0\n      // (handled in `addSettingsEvent`).\n      //\n      // `isCheckout` is always true, but want to be explicit that it should\n      // only be added for checkouts\n      addSettingsEvent(replay, isCheckout);\n\n      // If there is a previousSessionId after a full snapshot occurs, then\n      // the replay session was started due to session expiration. The new session\n      // is started before triggering a new checkout and contains the id\n      // of the previous session. Do not immediately flush in this case\n      // to avoid capturing only the checkout and instead the replay will\n      // be captured if they perform any follow-up actions.\n      if (session && session.previousSessionId) {\n        return true;\n      }\n\n      // When in buffer mode, make sure we adjust the session started date to the current earliest event of the buffer\n      // this should usually be the timestamp of the checkout event, but to be safe...\n      if (replay.recordingMode === 'buffer' && session && replay.eventBuffer) {\n        const earliestEvent = replay.eventBuffer.getEarliestTimestamp();\n        if (earliestEvent) {\n          DEBUG_BUILD &&\n            logger.info(`Updating session start time to earliest event in buffer to ${new Date(earliestEvent)}`);\n\n          session.started = earliestEvent;\n\n          if (replay.getOptions().stickySession) {\n            saveSession(session);\n          }\n        }\n      }\n\n      if (replay.recordingMode === 'session') {\n        // If the full snapshot is due to an initial load, we will not have\n        // a previous session ID. In this case, we want to buffer events\n        // for a set amount of time before flushing. This can help avoid\n        // capturing replays of users that immediately close the window.\n\n        // This should never reject\n        // eslint-disable-next-line @typescript-eslint/no-floating-promises\n        void replay.flush();\n      }\n\n      return true;\n    });\n  };\n}\n\n/**\n * Exported for tests\n */\nfunction createOptionsEvent(replay) {\n  const options = replay.getOptions();\n  return {\n    type: EventType.Custom,\n    timestamp: Date.now(),\n    data: {\n      tag: 'options',\n      payload: {\n        shouldRecordCanvas: replay.isRecordingCanvas(),\n        sessionSampleRate: options.sessionSampleRate,\n        errorSampleRate: options.errorSampleRate,\n        useCompressionOption: options.useCompression,\n        blockAllMedia: options.blockAllMedia,\n        maskAllText: options.maskAllText,\n        maskAllInputs: options.maskAllInputs,\n        useCompression: replay.eventBuffer ? replay.eventBuffer.type === 'worker' : false,\n        networkDetailHasUrls: options.networkDetailAllowUrls.length > 0,\n        networkCaptureBodies: options.networkCaptureBodies,\n        networkRequestHasHeaders: options.networkRequestHeaders.length > 0,\n        networkResponseHasHeaders: options.networkResponseHeaders.length > 0,\n      },\n    },\n  };\n}\n\n/**\n * Add a \"meta\" event that contains a simplified view on current configuration\n * options. This should only be included on the first segment of a recording.\n */\nfunction addSettingsEvent(replay, isCheckout) {\n  // Only need to add this event when sending the first segment\n  if (!isCheckout || !replay.session || replay.session.segmentId !== 0) {\n    return;\n  }\n\n  addEventSync(replay, createOptionsEvent(replay), false);\n}\n\n/**\n * Reset the `replay_id` field on the DSC.\n */\nfunction resetReplayIdOnDynamicSamplingContext() {\n  // Reset DSC on the current scope, if there is one\n  const dsc = getCurrentScope().getPropagationContext().dsc;\n  if (dsc) {\n    delete dsc.replay_id;\n  }\n\n  // Clear it from frozen DSC on the active span\n  const activeSpan = getActiveSpan();\n  if (activeSpan) {\n    const dsc = getDynamicSamplingContextFromSpan(activeSpan);\n    delete (dsc ).replay_id;\n  }\n}\n\n/**\n * Create a replay envelope ready to be sent.\n * This includes both the replay event, as well as the recording data.\n */\nfunction createReplayEnvelope(\n  replayEvent,\n  recordingData,\n  dsn,\n  tunnel,\n) {\n  return createEnvelope(\n    createEventEnvelopeHeaders(replayEvent, getSdkMetadataForEnvelopeHeader(replayEvent), tunnel, dsn),\n    [\n      [{ type: 'replay_event' }, replayEvent],\n      [\n        {\n          type: 'replay_recording',\n          // If string then we need to encode to UTF8, otherwise will have\n          // wrong size. TextEncoder has similar browser support to\n          // MutationObserver, although it does not accept IE11.\n          length:\n            typeof recordingData === 'string' ? new TextEncoder().encode(recordingData).length : recordingData.length,\n        },\n        recordingData,\n      ],\n    ],\n  );\n}\n\n/**\n * Prepare the recording data ready to be sent.\n */\nfunction prepareRecordingData({\n  recordingData,\n  headers,\n}\n\n) {\n  let payloadWithSequence;\n\n  // XXX: newline is needed to separate sequence id from events\n  const replayHeaders = `${JSON.stringify(headers)}\n`;\n\n  if (typeof recordingData === 'string') {\n    payloadWithSequence = `${replayHeaders}${recordingData}`;\n  } else {\n    const enc = new TextEncoder();\n    // XXX: newline is needed to separate sequence id from events\n    const sequence = enc.encode(replayHeaders);\n    // Merge the two Uint8Arrays\n    payloadWithSequence = new Uint8Array(sequence.length + recordingData.length);\n    payloadWithSequence.set(sequence);\n    payloadWithSequence.set(recordingData, sequence.length);\n  }\n\n  return payloadWithSequence;\n}\n\n/**\n * Prepare a replay event & enrich it with the SDK metadata.\n */\nasync function prepareReplayEvent({\n  client,\n  scope,\n  replayId: event_id,\n  event,\n}\n\n) {\n  const integrations =\n    typeof client._integrations === 'object' && client._integrations !== null && !Array.isArray(client._integrations)\n      ? Object.keys(client._integrations)\n      : undefined;\n\n  const eventHint = { event_id, integrations };\n\n  client.emit('preprocessEvent', event, eventHint);\n\n  const preparedEvent = (await prepareEvent(\n    client.getOptions(),\n    event,\n    eventHint,\n    scope,\n    client,\n    getIsolationScope(),\n  )) ;\n\n  // If e.g. a global event processor returned null\n  if (!preparedEvent) {\n    return null;\n  }\n\n  // This normally happens in browser client \"_prepareEvent\"\n  // but since we do not use this private method from the client, but rather the plain import\n  // we need to do this manually.\n  preparedEvent.platform = preparedEvent.platform || 'javascript';\n\n  // extract the SDK name because `client._prepareEvent` doesn't add it to the event\n  const metadata = client.getSdkMetadata();\n  const { name, version } = (metadata && metadata.sdk) || {};\n\n  preparedEvent.sdk = {\n    ...preparedEvent.sdk,\n    name: name || 'sentry.javascript.unknown',\n    version: version || '0.0.0',\n  };\n\n  return preparedEvent;\n}\n\n/**\n * Send replay attachment using `fetch()`\n */\nasync function sendReplayRequest({\n  recordingData,\n  replayId,\n  segmentId: segment_id,\n  eventContext,\n  timestamp,\n  session,\n}) {\n  const preparedRecordingData = prepareRecordingData({\n    recordingData,\n    headers: {\n      segment_id,\n    },\n  });\n\n  const { urls, errorIds, traceIds, initialTimestamp } = eventContext;\n\n  const client = getClient();\n  const scope = getCurrentScope();\n  const transport = client && client.getTransport();\n  const dsn = client && client.getDsn();\n\n  if (!client || !transport || !dsn || !session.sampled) {\n    return resolvedSyncPromise({});\n  }\n\n  const baseEvent = {\n    type: REPLAY_EVENT_NAME,\n    replay_start_timestamp: initialTimestamp / 1000,\n    timestamp: timestamp / 1000,\n    error_ids: errorIds,\n    trace_ids: traceIds,\n    urls,\n    replay_id: replayId,\n    segment_id,\n    replay_type: session.sampled,\n  };\n\n  const replayEvent = await prepareReplayEvent({ scope, client, replayId, event: baseEvent });\n\n  if (!replayEvent) {\n    // Taken from baseclient's `_processEvent` method, where this is handled for errors/transactions\n    client.recordDroppedEvent('event_processor', 'replay', baseEvent);\n    DEBUG_BUILD && logger.info('An event processor returned `null`, will not send event.');\n    return resolvedSyncPromise({});\n  }\n\n  /*\n  For reference, the fully built event looks something like this:\n  {\n      \"type\": \"replay_event\",\n      \"timestamp\": 1670837008.634,\n      \"error_ids\": [\n          \"errorId\"\n      ],\n      \"trace_ids\": [\n          \"traceId\"\n      ],\n      \"urls\": [\n          \"https://example.com\"\n      ],\n      \"replay_id\": \"eventId\",\n      \"segment_id\": 3,\n      \"replay_type\": \"error\",\n      \"platform\": \"javascript\",\n      \"event_id\": \"eventId\",\n      \"environment\": \"production\",\n      \"sdk\": {\n          \"integrations\": [\n              \"BrowserTracing\",\n              \"Replay\"\n          ],\n          \"name\": \"sentry.javascript.browser\",\n          \"version\": \"7.25.0\"\n      },\n      \"sdkProcessingMetadata\": {},\n      \"contexts\": {\n      },\n  }\n  */\n\n  // Prevent this data (which, if it exists, was used in earlier steps in the processing pipeline) from being sent to\n  // sentry. (Note: Our use of this property comes and goes with whatever we might be debugging, whatever hacks we may\n  // have temporarily added, etc. Even if we don't happen to be using it at some point in the future, let's not get rid\n  // of this `delete`, lest we miss putting it back in the next time the property is in use.)\n  delete replayEvent.sdkProcessingMetadata;\n\n  const envelope = createReplayEnvelope(replayEvent, preparedRecordingData, dsn, client.getOptions().tunnel);\n\n  let response;\n\n  try {\n    response = await transport.send(envelope);\n  } catch (err) {\n    const error = new Error(UNABLE_TO_SEND_REPLAY);\n\n    try {\n      // In case browsers don't allow this property to be writable\n      // @ts-expect-error This needs lib es2022 and newer\n      error.cause = err;\n    } catch (e) {\n      // nothing to do\n    }\n    throw error;\n  }\n\n  // If the status code is invalid, we want to immediately stop & not retry\n  if (typeof response.statusCode === 'number' && (response.statusCode < 200 || response.statusCode >= 300)) {\n    throw new TransportStatusCodeError(response.statusCode);\n  }\n\n  const rateLimits = updateRateLimits({}, response);\n  if (isRateLimited(rateLimits, 'replay')) {\n    throw new RateLimitError(rateLimits);\n  }\n\n  return response;\n}\n\n/**\n * This error indicates that the transport returned an invalid status code.\n */\nclass TransportStatusCodeError extends Error {\n   constructor(statusCode) {\n    super(`Transport returned status code ${statusCode}`);\n  }\n}\n\n/**\n * This error indicates that we hit a rate limit API error.\n */\nclass RateLimitError extends Error {\n\n   constructor(rateLimits) {\n    super('Rate limit hit');\n    this.rateLimits = rateLimits;\n  }\n}\n\n/**\n * Finalize and send the current replay event to Sentry\n */\nasync function sendReplay(\n  replayData,\n  retryConfig = {\n    count: 0,\n    interval: RETRY_BASE_INTERVAL,\n  },\n) {\n  const { recordingData, onError } = replayData;\n\n  // short circuit if there's no events to upload (this shouldn't happen as _runFlush makes this check)\n  if (!recordingData.length) {\n    return;\n  }\n\n  try {\n    await sendReplayRequest(replayData);\n    return true;\n  } catch (err) {\n    if (err instanceof TransportStatusCodeError || err instanceof RateLimitError) {\n      throw err;\n    }\n\n    // Capture error for every failed replay\n    setContext('Replays', {\n      _retryCount: retryConfig.count,\n    });\n\n    if (onError) {\n      onError(err);\n    }\n\n    // If an error happened here, it's likely that uploading the attachment\n    // failed, we'll can retry with the same events payload\n    if (retryConfig.count >= RETRY_MAX_COUNT) {\n      const error = new Error(`${UNABLE_TO_SEND_REPLAY} - max retries exceeded`);\n\n      try {\n        // In case browsers don't allow this property to be writable\n        // @ts-expect-error This needs lib es2022 and newer\n        error.cause = err;\n      } catch (e) {\n        // nothing to do\n      }\n\n      throw error;\n    }\n\n    // will retry in intervals of 5, 10, 30\n    retryConfig.interval *= ++retryConfig.count;\n\n    return new Promise((resolve, reject) => {\n      setTimeout$3(async () => {\n        try {\n          await sendReplay(replayData, retryConfig);\n          resolve(true);\n        } catch (err) {\n          reject(err);\n        }\n      }, retryConfig.interval);\n    });\n  }\n}\n\nconst THROTTLED = '__THROTTLED';\nconst SKIPPED = '__SKIPPED';\n\n/**\n * Create a throttled function off a given function.\n * When calling the throttled function, it will call the original function only\n * if it hasn't been called more than `maxCount` times in the last `durationSeconds`.\n *\n * Returns `THROTTLED` if throttled for the first time, after that `SKIPPED`,\n * or else the return value of the original function.\n */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nfunction throttle(\n  fn,\n  maxCount,\n  durationSeconds,\n) {\n  const counter = new Map();\n\n  const _cleanup = (now) => {\n    const threshold = now - durationSeconds;\n    counter.forEach((_value, key) => {\n      if (key < threshold) {\n        counter.delete(key);\n      }\n    });\n  };\n\n  const _getTotalCount = () => {\n    return [...counter.values()].reduce((a, b) => a + b, 0);\n  };\n\n  let isThrottled = false;\n\n  return (...rest) => {\n    // Date in second-precision, which we use as basis for the throttling\n    const now = Math.floor(Date.now() / 1000);\n\n    // First, make sure to delete any old entries\n    _cleanup(now);\n\n    // If already over limit, do nothing\n    if (_getTotalCount() >= maxCount) {\n      const wasThrottled = isThrottled;\n      isThrottled = true;\n      return wasThrottled ? SKIPPED : THROTTLED;\n    }\n\n    isThrottled = false;\n    const count = counter.get(now) || 0;\n    counter.set(now, count + 1);\n\n    return fn(...rest);\n  };\n}\n\n/* eslint-disable max-lines */ // TODO: We might want to split this file up\n\n/**\n * The main replay container class, which holds all the state and methods for recording and sending replays.\n */\nclass ReplayContainer  {\n\n  /**\n   * Recording can happen in one of three modes:\n   *   - session: Record the whole session, sending it continuously\n   *   - buffer: Always keep the last 60s of recording, requires:\n   *     - having replaysOnErrorSampleRate > 0 to capture replay when an error occurs\n   *     - or calling `flush()` to send the replay\n   */\n\n  /**\n   * The current or last active span.\n   * This is only available when performance is enabled.\n   */\n\n  /**\n   * These are here so we can overwrite them in tests etc.\n   * @hidden\n   */\n\n  /** The replay has to be manually started, because no sample rate (neither session or error) was provided. */\n\n  /**\n   * Options to pass to `rrweb.record()`\n   */\n\n  /**\n   * Timestamp of the last user activity. This lives across sessions.\n   */\n\n  /**\n   * Is the integration currently active?\n   */\n\n  /**\n   * Paused is a state where:\n   * - DOM Recording is not listening at all\n   * - Nothing will be added to event buffer (e.g. core SDK events)\n   */\n\n  /**\n   * Have we attached listeners to the core SDK?\n   * Note we have to track this as there is no way to remove instrumentation handlers.\n   */\n\n  /**\n   * Function to stop recording\n   */\n\n  /**\n   * Internal use for canvas recording options\n   */\n\n   constructor({\n    options,\n    recordingOptions,\n  }\n\n) {ReplayContainer.prototype.__init.call(this);ReplayContainer.prototype.__init2.call(this);ReplayContainer.prototype.__init3.call(this);ReplayContainer.prototype.__init4.call(this);ReplayContainer.prototype.__init5.call(this);ReplayContainer.prototype.__init6.call(this);\n    this.eventBuffer = null;\n    this.performanceEntries = [];\n    this.replayPerformanceEntries = [];\n    this.recordingMode = 'session';\n    this.timeouts = {\n      sessionIdlePause: SESSION_IDLE_PAUSE_DURATION,\n      sessionIdleExpire: SESSION_IDLE_EXPIRE_DURATION,\n    } ;\n    this._lastActivity = Date.now();\n    this._isEnabled = false;\n    this._isPaused = false;\n    this._requiresManualStart = false;\n    this._hasInitializedCoreListeners = false;\n    this._context = {\n      errorIds: new Set(),\n      traceIds: new Set(),\n      urls: [],\n      initialTimestamp: Date.now(),\n      initialUrl: '',\n    };\n\n    this._recordingOptions = recordingOptions;\n    this._options = options;\n\n    this._debouncedFlush = debounce(() => this._flush(), this._options.flushMinDelay, {\n      maxWait: this._options.flushMaxDelay,\n    });\n\n    this._throttledAddEvent = throttle(\n      (event, isCheckout) => addEvent(this, event, isCheckout),\n      // Max 300 events...\n      300,\n      // ... per 5s\n      5,\n    );\n\n    const { slowClickTimeout, slowClickIgnoreSelectors } = this.getOptions();\n\n    const slowClickConfig = slowClickTimeout\n      ? {\n          threshold: Math.min(SLOW_CLICK_THRESHOLD, slowClickTimeout),\n          timeout: slowClickTimeout,\n          scrollTimeout: SLOW_CLICK_SCROLL_TIMEOUT,\n          ignoreSelector: slowClickIgnoreSelectors ? slowClickIgnoreSelectors.join(',') : '',\n        }\n      : undefined;\n\n    if (slowClickConfig) {\n      this.clickDetector = new ClickDetector(this, slowClickConfig);\n    }\n\n    // Configure replay logger w/ experimental options\n    if (DEBUG_BUILD) {\n      const experiments = options._experiments;\n      logger.setConfig({\n        captureExceptions: !!experiments.captureExceptions,\n        traceInternals: !!experiments.traceInternals,\n      });\n    }\n  }\n\n  /** Get the event context. */\n   getContext() {\n    return this._context;\n  }\n\n  /** If recording is currently enabled. */\n   isEnabled() {\n    return this._isEnabled;\n  }\n\n  /** If recording is currently paused. */\n   isPaused() {\n    return this._isPaused;\n  }\n\n  /**\n   * Determine if canvas recording is enabled\n   */\n   isRecordingCanvas() {\n    return Boolean(this._canvas);\n  }\n\n  /** Get the replay integration options. */\n   getOptions() {\n    return this._options;\n  }\n\n  /** A wrapper to conditionally capture exceptions. */\n   handleException(error) {\n    DEBUG_BUILD && logger.exception(error);\n    if (this._options.onError) {\n      this._options.onError(error);\n    }\n  }\n\n  /**\n   * Initializes the plugin based on sampling configuration. Should not be\n   * called outside of constructor.\n   */\n   initializeSampling(previousSessionId) {\n    const { errorSampleRate, sessionSampleRate } = this._options;\n\n    // If neither sample rate is > 0, then do nothing - user will need to call one of\n    // `start()` or `startBuffering` themselves.\n    const requiresManualStart = errorSampleRate <= 0 && sessionSampleRate <= 0;\n\n    this._requiresManualStart = requiresManualStart;\n\n    if (requiresManualStart) {\n      return;\n    }\n\n    // Otherwise if there is _any_ sample rate set, try to load an existing\n    // session, or create a new one.\n    this._initializeSessionForSampling(previousSessionId);\n\n    if (!this.session) {\n      // This should not happen, something wrong has occurred\n      DEBUG_BUILD && logger.exception(new Error('Unable to initialize and create session'));\n      return;\n    }\n\n    if (this.session.sampled === false) {\n      // This should only occur if `errorSampleRate` is 0 and was unsampled for\n      // session-based replay. In this case there is nothing to do.\n      return;\n    }\n\n    // If segmentId > 0, it means we've previously already captured this session\n    // In this case, we still want to continue in `session` recording mode\n    this.recordingMode = this.session.sampled === 'buffer' && this.session.segmentId === 0 ? 'buffer' : 'session';\n\n    DEBUG_BUILD && logger.infoTick(`Starting replay in ${this.recordingMode} mode`);\n\n    this._initializeRecording();\n  }\n\n  /**\n   * Start a replay regardless of sampling rate. Calling this will always\n   * create a new session. Will log a message if replay is already in progress.\n   *\n   * Creates or loads a session, attaches listeners to varying events (DOM,\n   * _performanceObserver, Recording, Sentry SDK, etc)\n   */\n   start() {\n    if (this._isEnabled && this.recordingMode === 'session') {\n      DEBUG_BUILD && logger.info('Recording is already in progress');\n      return;\n    }\n\n    if (this._isEnabled && this.recordingMode === 'buffer') {\n      DEBUG_BUILD && logger.info('Buffering is in progress, call `flush()` to save the replay');\n      return;\n    }\n\n    DEBUG_BUILD && logger.infoTick('Starting replay in session mode');\n\n    // Required as user activity is initially set in\n    // constructor, so if `start()` is called after\n    // session idle expiration, a replay will not be\n    // created due to an idle timeout.\n    this._updateUserActivity();\n\n    const session = loadOrCreateSession(\n      {\n        maxReplayDuration: this._options.maxReplayDuration,\n        sessionIdleExpire: this.timeouts.sessionIdleExpire,\n      },\n      {\n        stickySession: this._options.stickySession,\n        // This is intentional: create a new session-based replay when calling `start()`\n        sessionSampleRate: 1,\n        allowBuffering: false,\n      },\n    );\n\n    this.session = session;\n\n    this._initializeRecording();\n  }\n\n  /**\n   * Start replay buffering. Buffers until `flush()` is called or, if\n   * `replaysOnErrorSampleRate` > 0, an error occurs.\n   */\n   startBuffering() {\n    if (this._isEnabled) {\n      DEBUG_BUILD && logger.info('Buffering is in progress, call `flush()` to save the replay');\n      return;\n    }\n\n    DEBUG_BUILD && logger.infoTick('Starting replay in buffer mode');\n\n    const session = loadOrCreateSession(\n      {\n        sessionIdleExpire: this.timeouts.sessionIdleExpire,\n        maxReplayDuration: this._options.maxReplayDuration,\n      },\n      {\n        stickySession: this._options.stickySession,\n        sessionSampleRate: 0,\n        allowBuffering: true,\n      },\n    );\n\n    this.session = session;\n\n    this.recordingMode = 'buffer';\n    this._initializeRecording();\n  }\n\n  /**\n   * Start recording.\n   *\n   * Note that this will cause a new DOM checkout\n   */\n   startRecording() {\n    try {\n      const canvasOptions = this._canvas;\n\n      this._stopRecording = record({\n        ...this._recordingOptions,\n        // When running in error sampling mode, we need to overwrite `checkoutEveryNms`\n        // Without this, it would record forever, until an error happens, which we don't want\n        // instead, we'll always keep the last 60 seconds of replay before an error happened\n        ...(this.recordingMode === 'buffer'\n          ? { checkoutEveryNms: BUFFER_CHECKOUT_TIME }\n          : // Otherwise, use experimental option w/ min checkout time of 6 minutes\n            // This is to improve playback seeking as there could potentially be\n            // less mutations to process in the worse cases.\n            //\n            // checkout by \"N\" events is probably ideal, but means we have less\n            // control about the number of checkouts we make (which generally\n            // increases replay size)\n            this._options._experiments.continuousCheckout && {\n              // Minimum checkout time is 6 minutes\n              checkoutEveryNms: Math.max(360000, this._options._experiments.continuousCheckout),\n            }),\n        emit: getHandleRecordingEmit(this),\n        onMutation: this._onMutationHandler,\n        ...(canvasOptions\n          ? {\n              recordCanvas: canvasOptions.recordCanvas,\n              getCanvasManager: canvasOptions.getCanvasManager,\n              sampling: canvasOptions.sampling,\n              dataURLOptions: canvasOptions.dataURLOptions,\n            }\n          : {}),\n      });\n    } catch (err) {\n      this.handleException(err);\n    }\n  }\n\n  /**\n   * Stops the recording, if it was running.\n   *\n   * Returns true if it was previously stopped, or is now stopped,\n   * otherwise false.\n   */\n   stopRecording() {\n    try {\n      if (this._stopRecording) {\n        this._stopRecording();\n        this._stopRecording = undefined;\n      }\n\n      return true;\n    } catch (err) {\n      this.handleException(err);\n      return false;\n    }\n  }\n\n  /**\n   * Currently, this needs to be manually called (e.g. for tests). Sentry SDK\n   * does not support a teardown\n   */\n   async stop({ forceFlush = false, reason } = {}) {\n    if (!this._isEnabled) {\n      return;\n    }\n\n    // We can't move `_isEnabled` after awaiting a flush, otherwise we can\n    // enter into an infinite loop when `stop()` is called while flushing.\n    this._isEnabled = false;\n\n    try {\n      DEBUG_BUILD && logger.info(`Stopping Replay${reason ? ` triggered by ${reason}` : ''}`);\n\n      resetReplayIdOnDynamicSamplingContext();\n\n      this._removeListeners();\n      this.stopRecording();\n\n      this._debouncedFlush.cancel();\n      // See comment above re: `_isEnabled`, we \"force\" a flush, ignoring the\n      // `_isEnabled` state of the plugin since it was disabled above.\n      if (forceFlush) {\n        await this._flush({ force: true });\n      }\n\n      // After flush, destroy event buffer\n      this.eventBuffer && this.eventBuffer.destroy();\n      this.eventBuffer = null;\n\n      // Clear session from session storage, note this means if a new session\n      // is started after, it will not have `previousSessionId`\n      clearSession(this);\n    } catch (err) {\n      this.handleException(err);\n    }\n  }\n\n  /**\n   * Pause some replay functionality. See comments for `_isPaused`.\n   * This differs from stop as this only stops DOM recording, it is\n   * not as thorough of a shutdown as `stop()`.\n   */\n   pause() {\n    if (this._isPaused) {\n      return;\n    }\n\n    this._isPaused = true;\n    this.stopRecording();\n\n    DEBUG_BUILD && logger.info('Pausing replay');\n  }\n\n  /**\n   * Resumes recording, see notes for `pause().\n   *\n   * Note that calling `startRecording()` here will cause a\n   * new DOM checkout.`\n   */\n   resume() {\n    if (!this._isPaused || !this._checkSession()) {\n      return;\n    }\n\n    this._isPaused = false;\n    this.startRecording();\n\n    DEBUG_BUILD && logger.info('Resuming replay');\n  }\n\n  /**\n   * If not in \"session\" recording mode, flush event buffer which will create a new replay.\n   * Unless `continueRecording` is false, the replay will continue to record and\n   * behave as a \"session\"-based replay.\n   *\n   * Otherwise, queue up a flush.\n   */\n   async sendBufferedReplayOrFlush({ continueRecording = true } = {}) {\n    if (this.recordingMode === 'session') {\n      return this.flushImmediate();\n    }\n\n    const activityTime = Date.now();\n\n    DEBUG_BUILD && logger.info('Converting buffer to session');\n\n    // Allow flush to complete before resuming as a session recording, otherwise\n    // the checkout from `startRecording` may be included in the payload.\n    // Prefer to keep the error replay as a separate (and smaller) segment\n    // than the session replay.\n    await this.flushImmediate();\n\n    const hasStoppedRecording = this.stopRecording();\n\n    if (!continueRecording || !hasStoppedRecording) {\n      return;\n    }\n\n    // To avoid race conditions where this is called multiple times, we check here again that we are still buffering\n    if ((this.recordingMode ) === 'session') {\n      return;\n    }\n\n    // Re-start recording in session-mode\n    this.recordingMode = 'session';\n\n    // Once this session ends, we do not want to refresh it\n    if (this.session) {\n      this._updateUserActivity(activityTime);\n      this._updateSessionActivity(activityTime);\n      this._maybeSaveSession();\n    }\n\n    this.startRecording();\n  }\n\n  /**\n   * We want to batch uploads of replay events. Save events only if\n   * `<flushMinDelay>` milliseconds have elapsed since the last event\n   * *OR* if `<flushMaxDelay>` milliseconds have elapsed.\n   *\n   * Accepts a callback to perform side-effects and returns true to stop batch\n   * processing and hand back control to caller.\n   */\n   addUpdate(cb) {\n    // We need to always run `cb` (e.g. in the case of `this.recordingMode == 'buffer'`)\n    const cbResult = cb();\n\n    // If this option is turned on then we will only want to call `flush`\n    // explicitly\n    if (this.recordingMode === 'buffer') {\n      return;\n    }\n\n    // If callback is true, we do not want to continue with flushing -- the\n    // caller will need to handle it.\n    if (cbResult === true) {\n      return;\n    }\n\n    // addUpdate is called quite frequently - use _debouncedFlush so that it\n    // respects the flush delays and does not flush immediately\n    this._debouncedFlush();\n  }\n\n  /**\n   * Updates the user activity timestamp and resumes recording. This should be\n   * called in an event handler for a user action that we consider as the user\n   * being \"active\" (e.g. a mouse click).\n   */\n   triggerUserActivity() {\n    this._updateUserActivity();\n\n    // This case means that recording was once stopped due to inactivity.\n    // Ensure that recording is resumed.\n    if (!this._stopRecording) {\n      // Create a new session, otherwise when the user action is flushed, it\n      // will get rejected due to an expired session.\n      if (!this._checkSession()) {\n        return;\n      }\n\n      // Note: This will cause a new DOM checkout\n      this.resume();\n      return;\n    }\n\n    // Otherwise... recording was never suspended, continue as normalish\n    this.checkAndHandleExpiredSession();\n\n    this._updateSessionActivity();\n  }\n\n  /**\n   * Updates the user activity timestamp *without* resuming\n   * recording. Some user events (e.g. keydown) can be create\n   * low-value replays that only contain the keypress as a\n   * breadcrumb. Instead this would require other events to\n   * create a new replay after a session has expired.\n   */\n   updateUserActivity() {\n    this._updateUserActivity();\n    this._updateSessionActivity();\n  }\n\n  /**\n   * Only flush if `this.recordingMode === 'session'`\n   */\n   conditionalFlush() {\n    if (this.recordingMode === 'buffer') {\n      return Promise.resolve();\n    }\n\n    return this.flushImmediate();\n  }\n\n  /**\n   * Flush using debounce flush\n   */\n   flush() {\n    return this._debouncedFlush() ;\n  }\n\n  /**\n   * Always flush via `_debouncedFlush` so that we do not have flushes triggered\n   * from calling both `flush` and `_debouncedFlush`. Otherwise, there could be\n   * cases of mulitple flushes happening closely together.\n   */\n   flushImmediate() {\n    this._debouncedFlush();\n    // `.flush` is provided by the debounced function, analogously to lodash.debounce\n    return this._debouncedFlush.flush() ;\n  }\n\n  /**\n   * Cancels queued up flushes.\n   */\n   cancelFlush() {\n    this._debouncedFlush.cancel();\n  }\n\n  /** Get the current sesion (=replay) ID */\n   getSessionId() {\n    return this.session && this.session.id;\n  }\n\n  /**\n   * Checks if recording should be stopped due to user inactivity. Otherwise\n   * check if session is expired and create a new session if so. Triggers a new\n   * full snapshot on new session.\n   *\n   * Returns true if session is not expired, false otherwise.\n   * @hidden\n   */\n   checkAndHandleExpiredSession() {\n    // Prevent starting a new session if the last user activity is older than\n    // SESSION_IDLE_PAUSE_DURATION. Otherwise non-user activity can trigger a new\n    // session+recording. This creates noisy replays that do not have much\n    // content in them.\n    if (\n      this._lastActivity &&\n      isExpired(this._lastActivity, this.timeouts.sessionIdlePause) &&\n      this.session &&\n      this.session.sampled === 'session'\n    ) {\n      // Pause recording only for session-based replays. Otherwise, resuming\n      // will create a new replay and will conflict with users who only choose\n      // to record error-based replays only. (e.g. the resumed replay will not\n      // contain a reference to an error)\n      this.pause();\n      return;\n    }\n\n    // --- There is recent user activity --- //\n    // This will create a new session if expired, based on expiry length\n    if (!this._checkSession()) {\n      // Check session handles the refreshing itself\n      return false;\n    }\n\n    return true;\n  }\n\n  /**\n   * Capture some initial state that can change throughout the lifespan of the\n   * replay. This is required because otherwise they would be captured at the\n   * first flush.\n   */\n   setInitialState() {\n    const urlPath = `${WINDOW.location.pathname}${WINDOW.location.hash}${WINDOW.location.search}`;\n    const url = `${WINDOW.location.origin}${urlPath}`;\n\n    this.performanceEntries = [];\n    this.replayPerformanceEntries = [];\n\n    // Reset _context as well\n    this._clearContext();\n\n    this._context.initialUrl = url;\n    this._context.initialTimestamp = Date.now();\n    this._context.urls.push(url);\n  }\n\n  /**\n   * Add a breadcrumb event, that may be throttled.\n   * If it was throttled, we add a custom breadcrumb to indicate that.\n   */\n   throttledAddEvent(\n    event,\n    isCheckout,\n  ) {\n    const res = this._throttledAddEvent(event, isCheckout);\n\n    // If this is THROTTLED, it means we have throttled the event for the first time\n    // In this case, we want to add a breadcrumb indicating that something was skipped\n    if (res === THROTTLED) {\n      const breadcrumb = createBreadcrumb({\n        category: 'replay.throttled',\n      });\n\n      this.addUpdate(() => {\n        // Return `false` if the event _was_ added, as that means we schedule a flush\n        return !addEventSync(this, {\n          type: ReplayEventTypeCustom,\n          timestamp: breadcrumb.timestamp || 0,\n          data: {\n            tag: 'breadcrumb',\n            payload: breadcrumb,\n            metric: true,\n          },\n        });\n      });\n    }\n\n    return res;\n  }\n\n  /**\n   * This will get the parametrized route name of the current page.\n   * This is only available if performance is enabled, and if an instrumented router is used.\n   */\n   getCurrentRoute() {\n    const lastActiveSpan = this.lastActiveSpan || getActiveSpan();\n    const lastRootSpan = lastActiveSpan && getRootSpan(lastActiveSpan);\n\n    const attributes = (lastRootSpan && spanToJSON(lastRootSpan).data) || {};\n    const source = attributes[SEMANTIC_ATTRIBUTE_SENTRY_SOURCE];\n    if (!lastRootSpan || !source || !['route', 'custom'].includes(source)) {\n      return undefined;\n    }\n\n    return spanToJSON(lastRootSpan).description;\n  }\n\n  /**\n   * Initialize and start all listeners to varying events (DOM,\n   * Performance Observer, Recording, Sentry SDK, etc)\n   */\n   _initializeRecording() {\n    this.setInitialState();\n\n    // this method is generally called on page load or manually - in both cases\n    // we should treat it as an activity\n    this._updateSessionActivity();\n\n    this.eventBuffer = createEventBuffer({\n      useCompression: this._options.useCompression,\n      workerUrl: this._options.workerUrl,\n    });\n\n    this._removeListeners();\n    this._addListeners();\n\n    // Need to set as enabled before we start recording, as `record()` can trigger a flush with a new checkout\n    this._isEnabled = true;\n    this._isPaused = false;\n\n    this.startRecording();\n  }\n\n  /**\n   * Loads (or refreshes) the current session.\n   */\n   _initializeSessionForSampling(previousSessionId) {\n    // Whenever there is _any_ error sample rate, we always allow buffering\n    // Because we decide on sampling when an error occurs, we need to buffer at all times if sampling for errors\n    const allowBuffering = this._options.errorSampleRate > 0;\n\n    const session = loadOrCreateSession(\n      {\n        sessionIdleExpire: this.timeouts.sessionIdleExpire,\n        maxReplayDuration: this._options.maxReplayDuration,\n        previousSessionId,\n      },\n      {\n        stickySession: this._options.stickySession,\n        sessionSampleRate: this._options.sessionSampleRate,\n        allowBuffering,\n      },\n    );\n\n    this.session = session;\n  }\n\n  /**\n   * Checks and potentially refreshes the current session.\n   * Returns false if session is not recorded.\n   */\n   _checkSession() {\n    // If there is no session yet, we do not want to refresh anything\n    // This should generally not happen, but to be safe....\n    if (!this.session) {\n      return false;\n    }\n\n    const currentSession = this.session;\n\n    if (\n      shouldRefreshSession(currentSession, {\n        sessionIdleExpire: this.timeouts.sessionIdleExpire,\n        maxReplayDuration: this._options.maxReplayDuration,\n      })\n    ) {\n      // This should never reject\n      // eslint-disable-next-line @typescript-eslint/no-floating-promises\n      this._refreshSession(currentSession);\n      return false;\n    }\n\n    return true;\n  }\n\n  /**\n   * Refresh a session with a new one.\n   * This stops the current session (without forcing a flush, as that would never work since we are expired),\n   * and then does a new sampling based on the refreshed session.\n   */\n   async _refreshSession(session) {\n    if (!this._isEnabled) {\n      return;\n    }\n    await this.stop({ reason: 'refresh session' });\n    this.initializeSampling(session.id);\n  }\n\n  /**\n   * Adds listeners to record events for the replay\n   */\n   _addListeners() {\n    try {\n      WINDOW.document.addEventListener('visibilitychange', this._handleVisibilityChange);\n      WINDOW.addEventListener('blur', this._handleWindowBlur);\n      WINDOW.addEventListener('focus', this._handleWindowFocus);\n      WINDOW.addEventListener('keydown', this._handleKeyboardEvent);\n\n      if (this.clickDetector) {\n        this.clickDetector.addListeners();\n      }\n\n      // There is no way to remove these listeners, so ensure they are only added once\n      if (!this._hasInitializedCoreListeners) {\n        addGlobalListeners(this);\n\n        this._hasInitializedCoreListeners = true;\n      }\n    } catch (err) {\n      this.handleException(err);\n    }\n\n    this._performanceCleanupCallback = setupPerformanceObserver(this);\n  }\n\n  /**\n   * Cleans up listeners that were created in `_addListeners`\n   */\n   _removeListeners() {\n    try {\n      WINDOW.document.removeEventListener('visibilitychange', this._handleVisibilityChange);\n\n      WINDOW.removeEventListener('blur', this._handleWindowBlur);\n      WINDOW.removeEventListener('focus', this._handleWindowFocus);\n      WINDOW.removeEventListener('keydown', this._handleKeyboardEvent);\n\n      if (this.clickDetector) {\n        this.clickDetector.removeListeners();\n      }\n\n      if (this._performanceCleanupCallback) {\n        this._performanceCleanupCallback();\n      }\n    } catch (err) {\n      this.handleException(err);\n    }\n  }\n\n  /**\n   * Handle when visibility of the page content changes. Opening a new tab will\n   * cause the state to change to hidden because of content of current page will\n   * be hidden. Likewise, moving a different window to cover the contents of the\n   * page will also trigger a change to a hidden state.\n   */\n   __init() {this._handleVisibilityChange = () => {\n    if (WINDOW.document.visibilityState === 'visible') {\n      this._doChangeToForegroundTasks();\n    } else {\n      this._doChangeToBackgroundTasks();\n    }\n  };}\n\n  /**\n   * Handle when page is blurred\n   */\n   __init2() {this._handleWindowBlur = () => {\n    const breadcrumb = createBreadcrumb({\n      category: 'ui.blur',\n    });\n\n    // Do not count blur as a user action -- it's part of the process of them\n    // leaving the page\n    this._doChangeToBackgroundTasks(breadcrumb);\n  };}\n\n  /**\n   * Handle when page is focused\n   */\n   __init3() {this._handleWindowFocus = () => {\n    const breadcrumb = createBreadcrumb({\n      category: 'ui.focus',\n    });\n\n    // Do not count focus as a user action -- instead wait until they focus and\n    // interactive with page\n    this._doChangeToForegroundTasks(breadcrumb);\n  };}\n\n  /** Ensure page remains active when a key is pressed. */\n   __init4() {this._handleKeyboardEvent = (event) => {\n    handleKeyboardEvent(this, event);\n  };}\n\n  /**\n   * Tasks to run when we consider a page to be hidden (via blurring and/or visibility)\n   */\n   _doChangeToBackgroundTasks(breadcrumb) {\n    if (!this.session) {\n      return;\n    }\n\n    const expired = isSessionExpired(this.session, {\n      maxReplayDuration: this._options.maxReplayDuration,\n      sessionIdleExpire: this.timeouts.sessionIdleExpire,\n    });\n\n    if (expired) {\n      return;\n    }\n\n    if (breadcrumb) {\n      this._createCustomBreadcrumb(breadcrumb);\n    }\n\n    // Send replay when the page/tab becomes hidden. There is no reason to send\n    // replay if it becomes visible, since no actions we care about were done\n    // while it was hidden\n    // This should never reject\n    // eslint-disable-next-line @typescript-eslint/no-floating-promises\n    void this.conditionalFlush();\n  }\n\n  /**\n   * Tasks to run when we consider a page to be visible (via focus and/or visibility)\n   */\n   _doChangeToForegroundTasks(breadcrumb) {\n    if (!this.session) {\n      return;\n    }\n\n    const isSessionActive = this.checkAndHandleExpiredSession();\n\n    if (!isSessionActive) {\n      // If the user has come back to the page within SESSION_IDLE_PAUSE_DURATION\n      // ms, we will re-use the existing session, otherwise create a new\n      // session\n      DEBUG_BUILD && logger.info('Document has become active, but session has expired');\n      return;\n    }\n\n    if (breadcrumb) {\n      this._createCustomBreadcrumb(breadcrumb);\n    }\n  }\n\n  /**\n   * Update user activity (across session lifespans)\n   */\n   _updateUserActivity(_lastActivity = Date.now()) {\n    this._lastActivity = _lastActivity;\n  }\n\n  /**\n   * Updates the session's last activity timestamp\n   */\n   _updateSessionActivity(_lastActivity = Date.now()) {\n    if (this.session) {\n      this.session.lastActivity = _lastActivity;\n      this._maybeSaveSession();\n    }\n  }\n\n  /**\n   * Helper to create (and buffer) a replay breadcrumb from a core SDK breadcrumb\n   */\n   _createCustomBreadcrumb(breadcrumb) {\n    this.addUpdate(() => {\n      // This should never reject\n      // eslint-disable-next-line @typescript-eslint/no-floating-promises\n      this.throttledAddEvent({\n        type: EventType.Custom,\n        timestamp: breadcrumb.timestamp || 0,\n        data: {\n          tag: 'breadcrumb',\n          payload: breadcrumb,\n        },\n      });\n    });\n  }\n\n  /**\n   * Observed performance events are added to `this.performanceEntries`. These\n   * are included in the replay event before it is finished and sent to Sentry.\n   */\n   _addPerformanceEntries() {\n    const performanceEntries = createPerformanceEntries(this.performanceEntries).concat(this.replayPerformanceEntries);\n\n    this.performanceEntries = [];\n    this.replayPerformanceEntries = [];\n\n    return Promise.all(createPerformanceSpans(this, performanceEntries));\n  }\n\n  /**\n   * Clear _context\n   */\n   _clearContext() {\n    // XXX: `initialTimestamp` and `initialUrl` do not get cleared\n    this._context.errorIds.clear();\n    this._context.traceIds.clear();\n    this._context.urls = [];\n  }\n\n  /** Update the initial timestamp based on the buffer content. */\n   _updateInitialTimestampFromEventBuffer() {\n    const { session, eventBuffer } = this;\n    // If replay was started manually (=no sample rate was given),\n    // We do not want to back-port the initial timestamp\n    if (!session || !eventBuffer || this._requiresManualStart) {\n      return;\n    }\n\n    // we only ever update this on the initial segment\n    if (session.segmentId) {\n      return;\n    }\n\n    const earliestEvent = eventBuffer.getEarliestTimestamp();\n    if (earliestEvent && earliestEvent < this._context.initialTimestamp) {\n      this._context.initialTimestamp = earliestEvent;\n    }\n  }\n\n  /**\n   * Return and clear _context\n   */\n   _popEventContext() {\n    const _context = {\n      initialTimestamp: this._context.initialTimestamp,\n      initialUrl: this._context.initialUrl,\n      errorIds: Array.from(this._context.errorIds),\n      traceIds: Array.from(this._context.traceIds),\n      urls: this._context.urls,\n    };\n\n    this._clearContext();\n\n    return _context;\n  }\n\n  /**\n   * Flushes replay event buffer to Sentry.\n   *\n   * Performance events are only added right before flushing - this is\n   * due to the buffered performance observer events.\n   *\n   * Should never be called directly, only by `flush`\n   */\n   async _runFlush() {\n    const replayId = this.getSessionId();\n\n    if (!this.session || !this.eventBuffer || !replayId) {\n      DEBUG_BUILD && logger.error('No session or eventBuffer found to flush.');\n      return;\n    }\n\n    await this._addPerformanceEntries();\n\n    // Check eventBuffer again, as it could have been stopped in the meanwhile\n    if (!this.eventBuffer || !this.eventBuffer.hasEvents) {\n      return;\n    }\n\n    // Only attach memory event if eventBuffer is not empty\n    await addMemoryEntry(this);\n\n    // Check eventBuffer again, as it could have been stopped in the meanwhile\n    if (!this.eventBuffer) {\n      return;\n    }\n\n    // if this changed in the meanwhile, e.g. because the session was refreshed or similar, we abort here\n    if (replayId !== this.getSessionId()) {\n      return;\n    }\n\n    try {\n      // This uses the data from the eventBuffer, so we need to call this before `finish()\n      this._updateInitialTimestampFromEventBuffer();\n\n      const timestamp = Date.now();\n\n      // Check total duration again, to avoid sending outdated stuff\n      // We leave 30s wiggle room to accomodate late flushing etc.\n      // This _could_ happen when the browser is suspended during flushing, in which case we just want to stop\n      if (timestamp - this._context.initialTimestamp > this._options.maxReplayDuration + 30000) {\n        throw new Error('Session is too long, not sending replay');\n      }\n\n      const eventContext = this._popEventContext();\n      // Always increment segmentId regardless of outcome of sending replay\n      const segmentId = this.session.segmentId++;\n      this._maybeSaveSession();\n\n      // Note this empties the event buffer regardless of outcome of sending replay\n      const recordingData = await this.eventBuffer.finish();\n\n      await sendReplay({\n        replayId,\n        recordingData,\n        segmentId,\n        eventContext,\n        session: this.session,\n        timestamp,\n        onError: err => this.handleException(err),\n      });\n    } catch (err) {\n      this.handleException(err);\n\n      // This means we retried 3 times and all of them failed,\n      // or we ran into a problem we don't want to retry, like rate limiting.\n      // In this case, we want to completely stop the replay - otherwise, we may get inconsistent segments\n      // This should never reject\n      // eslint-disable-next-line @typescript-eslint/no-floating-promises\n      this.stop({ reason: 'sendReplay' });\n\n      const client = getClient();\n\n      if (client) {\n        const dropReason = err instanceof RateLimitError ? 'ratelimit_backoff' : 'send_error';\n        client.recordDroppedEvent(dropReason, 'replay');\n      }\n    }\n  }\n\n  /**\n   * Flush recording data to Sentry. Creates a lock so that only a single flush\n   * can be active at a time. Do not call this directly.\n   */\n   __init5() {this._flush = async ({\n    force = false,\n  }\n\n = {}) => {\n    if (!this._isEnabled && !force) {\n      // This can happen if e.g. the replay was stopped because of exceeding the retry limit\n      return;\n    }\n\n    if (!this.checkAndHandleExpiredSession()) {\n      DEBUG_BUILD && logger.error('Attempting to finish replay event after session expired.');\n      return;\n    }\n\n    if (!this.session) {\n      // should never happen, as we would have bailed out before\n      return;\n    }\n\n    const start = this.session.started;\n    const now = Date.now();\n    const duration = now - start;\n\n    // A flush is about to happen, cancel any queued flushes\n    this._debouncedFlush.cancel();\n\n    // If session is too short, or too long (allow some wiggle room over maxReplayDuration), do not send it\n    // This _should_ not happen, but it may happen if flush is triggered due to a page activity change or similar\n    const tooShort = duration < this._options.minReplayDuration;\n    const tooLong = duration > this._options.maxReplayDuration + 5000;\n    if (tooShort || tooLong) {\n      DEBUG_BUILD &&\n        logger.info(\n          `Session duration (${Math.floor(duration / 1000)}s) is too ${\n            tooShort ? 'short' : 'long'\n          }, not sending replay.`,\n        );\n\n      if (tooShort) {\n        this._debouncedFlush();\n      }\n      return;\n    }\n\n    const eventBuffer = this.eventBuffer;\n    if (eventBuffer && this.session.segmentId === 0 && !eventBuffer.hasCheckout) {\n      DEBUG_BUILD && logger.info('Flushing initial segment without checkout.');\n      // TODO FN: Evaluate if we want to stop here, or remove this again?\n    }\n\n    const _flushInProgress = !!this._flushLock;\n\n    // this._flushLock acts as a lock so that future calls to `_flush()` will\n    // be blocked until current flush is finished (i.e. this promise resolves)\n    if (!this._flushLock) {\n      this._flushLock = this._runFlush();\n    }\n\n    try {\n      await this._flushLock;\n    } catch (err) {\n      this.handleException(err);\n    } finally {\n      this._flushLock = undefined;\n\n      if (_flushInProgress) {\n        // Wait for previous flush to finish, then call the debounced\n        // `_flush()`. It's possible there are other flush requests queued and\n        // waiting for it to resolve. We want to reduce all outstanding\n        // requests (as well as any new flush requests that occur within a\n        // second of the locked flush completing) into a single flush.\n        this._debouncedFlush();\n      }\n    }\n  };}\n\n  /** Save the session, if it is sticky */\n   _maybeSaveSession() {\n    if (this.session && this._options.stickySession) {\n      saveSession(this.session);\n    }\n  }\n\n  /** Handler for rrweb.record.onMutation */\n   __init6() {this._onMutationHandler = (mutations) => {\n    const count = mutations.length;\n\n    const mutationLimit = this._options.mutationLimit;\n    const mutationBreadcrumbLimit = this._options.mutationBreadcrumbLimit;\n    const overMutationLimit = mutationLimit && count > mutationLimit;\n\n    // Create a breadcrumb if a lot of mutations happen at the same time\n    // We can show this in the UI as an information with potential performance improvements\n    if (count > mutationBreadcrumbLimit || overMutationLimit) {\n      const breadcrumb = createBreadcrumb({\n        category: 'replay.mutations',\n        data: {\n          count,\n          limit: overMutationLimit,\n        },\n      });\n      this._createCustomBreadcrumb(breadcrumb);\n    }\n\n    // Stop replay if over the mutation limit\n    if (overMutationLimit) {\n      // This should never reject\n      // eslint-disable-next-line @typescript-eslint/no-floating-promises\n      this.stop({ reason: 'mutationLimit', forceFlush: this.recordingMode === 'session' });\n      return false;\n    }\n\n    // `true` means we use the regular mutation handling by rrweb\n    return true;\n  };}\n}\n\nfunction getOption(selectors, defaultSelectors) {\n  return [\n    ...selectors,\n    // sentry defaults\n    ...defaultSelectors,\n  ].join(',');\n}\n\n/**\n * Returns privacy related configuration for use in rrweb\n */\nfunction getPrivacyOptions({ mask, unmask, block, unblock, ignore }) {\n  const defaultBlockedElements = ['base[href=\"/\"]'];\n\n  const maskSelector = getOption(mask, ['.sentry-mask', '[data-sentry-mask]']);\n  const unmaskSelector = getOption(unmask, []);\n\n  const options = {\n    // We are making the decision to make text and input selectors the same\n    maskTextSelector: maskSelector,\n    unmaskTextSelector: unmaskSelector,\n\n    blockSelector: getOption(block, ['.sentry-block', '[data-sentry-block]', ...defaultBlockedElements]),\n    unblockSelector: getOption(unblock, []),\n    ignoreSelector: getOption(ignore, ['.sentry-ignore', '[data-sentry-ignore]', 'input[type=\"file\"]']),\n  };\n\n  return options;\n}\n\n/**\n * Masks an attribute if necessary, otherwise return attribute value as-is.\n */\nfunction maskAttribute({\n  el,\n  key,\n  maskAttributes,\n  maskAllText,\n  privacyOptions,\n  value,\n}) {\n  // We only mask attributes if `maskAllText` is true\n  if (!maskAllText) {\n    return value;\n  }\n\n  // unmaskTextSelector takes precendence\n  if (privacyOptions.unmaskTextSelector && el.matches(privacyOptions.unmaskTextSelector)) {\n    return value;\n  }\n\n  if (\n    maskAttributes.includes(key) ||\n    // Need to mask `value` attribute for `<input>` if it's a button-like\n    // type\n    (key === 'value' && el.tagName === 'INPUT' && ['submit', 'button'].includes(el.getAttribute('type') || ''))\n  ) {\n    return value.replace(/[\\S]/g, '*');\n  }\n\n  return value;\n}\n\nconst MEDIA_SELECTORS =\n  'img,image,svg,video,object,picture,embed,map,audio,link[rel=\"icon\"],link[rel=\"apple-touch-icon\"]';\n\nconst DEFAULT_NETWORK_HEADERS = ['content-length', 'content-type', 'accept'];\n\nlet _initialized = false;\n\n/**\n * Sentry integration for [Session Replay](https://sentry.io/for/session-replay/).\n *\n * See the [Replay documentation](https://docs.sentry.io/platforms/javascript/guides/session-replay/) for more information.\n *\n * @example\n *\n * ```\n * Sentry.init({\n *   dsn: '__DSN__',\n *   integrations: [Sentry.replayIntegration()],\n * });\n * ```\n */\nconst replayIntegration = ((options) => {\n  return new Replay(options);\n}) ;\n\n/**\n * Replay integration\n *\n * TODO: Rewrite this to be functional integration\n * Exported for tests.\n */\nclass Replay  {\n  /**\n   * @inheritDoc\n   */\n   static __initStatic() {this.id = 'Replay';}\n\n  /**\n   * @inheritDoc\n   */\n\n  /**\n   * Options to pass to `rrweb.record()`\n   */\n\n  /**\n   * Initial options passed to the replay integration, merged with default values.\n   * Note: `sessionSampleRate` and `errorSampleRate` are not required here, as they\n   * can only be finally set when setupOnce() is called.\n   *\n   * @private\n   */\n\n   constructor({\n    flushMinDelay = DEFAULT_FLUSH_MIN_DELAY,\n    flushMaxDelay = DEFAULT_FLUSH_MAX_DELAY,\n    minReplayDuration = MIN_REPLAY_DURATION,\n    maxReplayDuration = MAX_REPLAY_DURATION,\n    stickySession = true,\n    useCompression = true,\n    workerUrl,\n    _experiments = {},\n    maskAllText = true,\n    maskAllInputs = true,\n    blockAllMedia = true,\n\n    mutationBreadcrumbLimit = 750,\n    mutationLimit = 10000,\n\n    slowClickTimeout = 7000,\n    slowClickIgnoreSelectors = [],\n\n    networkDetailAllowUrls = [],\n    networkDetailDenyUrls = [],\n    networkCaptureBodies = true,\n    networkRequestHeaders = [],\n    networkResponseHeaders = [],\n\n    mask = [],\n    maskAttributes = ['title', 'placeholder'],\n    unmask = [],\n    block = [],\n    unblock = [],\n    ignore = [],\n    maskFn,\n\n    beforeAddRecordingEvent,\n    beforeErrorSampling,\n  } = {}) {\n    this.name = Replay.id;\n\n    const privacyOptions = getPrivacyOptions({\n      mask,\n      unmask,\n      block,\n      unblock,\n      ignore,\n    });\n\n    this._recordingOptions = {\n      maskAllInputs,\n      maskAllText,\n      maskInputOptions: { password: true },\n      maskTextFn: maskFn,\n      maskInputFn: maskFn,\n      maskAttributeFn: (key, value, el) =>\n        maskAttribute({\n          maskAttributes,\n          maskAllText,\n          privacyOptions,\n          key,\n          value,\n          el,\n        }),\n\n      ...privacyOptions,\n\n      // Our defaults\n      slimDOMOptions: 'all',\n      inlineStylesheet: true,\n      // Disable inline images as it will increase segment/replay size\n      inlineImages: false,\n      // collect fonts, but be aware that `sentry.io` needs to be an allowed\n      // origin for playback\n      collectFonts: true,\n      errorHandler: (err) => {\n        try {\n          err.__rrweb__ = true;\n        } catch (error) {\n          // ignore errors here\n          // this can happen if the error is frozen or does not allow mutation for other reasons\n        }\n      },\n    };\n\n    this._initialOptions = {\n      flushMinDelay,\n      flushMaxDelay,\n      minReplayDuration: Math.min(minReplayDuration, MIN_REPLAY_DURATION_LIMIT),\n      maxReplayDuration: Math.min(maxReplayDuration, MAX_REPLAY_DURATION),\n      stickySession,\n      useCompression,\n      workerUrl,\n      blockAllMedia,\n      maskAllInputs,\n      maskAllText,\n      mutationBreadcrumbLimit,\n      mutationLimit,\n      slowClickTimeout,\n      slowClickIgnoreSelectors,\n      networkDetailAllowUrls,\n      networkDetailDenyUrls,\n      networkCaptureBodies,\n      networkRequestHeaders: _getMergedNetworkHeaders(networkRequestHeaders),\n      networkResponseHeaders: _getMergedNetworkHeaders(networkResponseHeaders),\n      beforeAddRecordingEvent,\n      beforeErrorSampling,\n\n      _experiments,\n    };\n\n    if (this._initialOptions.blockAllMedia) {\n      // `blockAllMedia` is a more user friendly option to configure blocking\n      // embedded media elements\n      this._recordingOptions.blockSelector = !this._recordingOptions.blockSelector\n        ? MEDIA_SELECTORS\n        : `${this._recordingOptions.blockSelector},${MEDIA_SELECTORS}`;\n    }\n\n    if (this._isInitialized && isBrowser()) {\n      throw new Error('Multiple Sentry Session Replay instances are not supported');\n    }\n\n    this._isInitialized = true;\n  }\n\n  /** If replay has already been initialized */\n   get _isInitialized() {\n    return _initialized;\n  }\n\n  /** Update _isInitialized */\n   set _isInitialized(value) {\n    _initialized = value;\n  }\n\n  /**\n   * Setup and initialize replay container\n   */\n   afterAllSetup(client) {\n    if (!isBrowser() || this._replay) {\n      return;\n    }\n\n    this._setup(client);\n    this._initialize(client);\n  }\n\n  /**\n   * Start a replay regardless of sampling rate. Calling this will always\n   * create a new session. Will log a message if replay is already in progress.\n   *\n   * Creates or loads a session, attaches listeners to varying events (DOM,\n   * PerformanceObserver, Recording, Sentry SDK, etc)\n   */\n   start() {\n    if (!this._replay) {\n      return;\n    }\n    this._replay.start();\n  }\n\n  /**\n   * Start replay buffering. Buffers until `flush()` is called or, if\n   * `replaysOnErrorSampleRate` > 0, until an error occurs.\n   */\n   startBuffering() {\n    if (!this._replay) {\n      return;\n    }\n\n    this._replay.startBuffering();\n  }\n\n  /**\n   * Currently, this needs to be manually called (e.g. for tests). Sentry SDK\n   * does not support a teardown\n   */\n   stop() {\n    if (!this._replay) {\n      return Promise.resolve();\n    }\n\n    return this._replay.stop({ forceFlush: this._replay.recordingMode === 'session' });\n  }\n\n  /**\n   * If not in \"session\" recording mode, flush event buffer which will create a new replay.\n   * If replay is not enabled, a new session replay is started.\n   * Unless `continueRecording` is false, the replay will continue to record and\n   * behave as a \"session\"-based replay.\n   *\n   * Otherwise, queue up a flush.\n   */\n   flush(options) {\n    if (!this._replay) {\n      return Promise.resolve();\n    }\n\n    // assuming a session should be recorded in this case\n    if (!this._replay.isEnabled()) {\n      this._replay.start();\n      return Promise.resolve();\n    }\n\n    return this._replay.sendBufferedReplayOrFlush(options);\n  }\n\n  /**\n   * Get the current session ID.\n   */\n   getReplayId() {\n    if (!this._replay || !this._replay.isEnabled()) {\n      return;\n    }\n\n    return this._replay.getSessionId();\n  }\n\n  /**\n   * Initializes replay.\n   */\n   _initialize(client) {\n    if (!this._replay) {\n      return;\n    }\n\n    this._maybeLoadFromReplayCanvasIntegration(client);\n    this._replay.initializeSampling();\n  }\n\n  /** Setup the integration. */\n   _setup(client) {\n    // Client is not available in constructor, so we need to wait until setupOnce\n    const finalOptions = loadReplayOptionsFromClient(this._initialOptions, client);\n\n    this._replay = new ReplayContainer({\n      options: finalOptions,\n      recordingOptions: this._recordingOptions,\n    });\n  }\n\n  /** Get canvas options from ReplayCanvas integration, if it is also added. */\n   _maybeLoadFromReplayCanvasIntegration(client) {\n    // To save bundle size, we skip checking for stuff here\n    // and instead just try-catch everything - as generally this should all be defined\n    /* eslint-disable @typescript-eslint/no-non-null-assertion */\n    try {\n      const canvasIntegration = client.getIntegrationByName('ReplayCanvas')\n\n;\n      if (!canvasIntegration) {\n        return;\n      }\n\n      this._replay['_canvas'] = canvasIntegration.getOptions();\n    } catch (e) {\n      // ignore errors here\n    }\n    /* eslint-enable @typescript-eslint/no-non-null-assertion */\n  }\n}Replay.__initStatic();\n\n/** Parse Replay-related options from SDK options */\nfunction loadReplayOptionsFromClient(initialOptions, client) {\n  const opt = client.getOptions() ;\n\n  const finalOptions = {\n    sessionSampleRate: 0,\n    errorSampleRate: 0,\n    ...dropUndefinedKeys(initialOptions),\n  };\n\n  const replaysSessionSampleRate = parseSampleRate(opt.replaysSessionSampleRate);\n  const replaysOnErrorSampleRate = parseSampleRate(opt.replaysOnErrorSampleRate);\n\n  if (replaysSessionSampleRate == null && replaysOnErrorSampleRate == null) {\n    consoleSandbox(() => {\n      // eslint-disable-next-line no-console\n      console.warn(\n        'Replay is disabled because neither `replaysSessionSampleRate` nor `replaysOnErrorSampleRate` are set.',\n      );\n    });\n  }\n\n  if (replaysSessionSampleRate != null) {\n    finalOptions.sessionSampleRate = replaysSessionSampleRate;\n  }\n\n  if (replaysOnErrorSampleRate != null) {\n    finalOptions.errorSampleRate = replaysOnErrorSampleRate;\n  }\n\n  return finalOptions;\n}\n\nfunction _getMergedNetworkHeaders(headers) {\n  return [...DEFAULT_NETWORK_HEADERS, ...headers.map(header => header.toLowerCase())];\n}\n\n/**\n * This is a small utility to get a type-safe instance of the Replay integration.\n */\nfunction getReplay() {\n  const client = getClient();\n  return client && client.getIntegrationByName('Replay');\n}\n\nexport { getReplay, replayIntegration };\n//# sourceMappingURL=index.js.map\n"],"names":[],"sourceRoot":"","ignoreList":[0]}