telegram-tt/dist/8688.6cda6506154e2e3e5b90.js.map
Alexander Zinchuk ed07bcaff3 [Build]
2022-09-24 01:42:13 +02:00

1 line
527 KiB
Plaintext
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

{"version":3,"file":"8688.6cda6506154e2e3e5b90.js","mappings":"wXAyCA,SAAeA,EAAAA,EAAAA,KA3Bf,SAAiCC,GAAiB,MAChD,MAAM,QACJC,EADI,OACKC,EADL,aACaC,EADb,aAC2BC,KAAiBC,GAC9CL,EAEEM,EAAeL,MAAAA,GAAH,UAAGA,EAASM,iBAAZ,aAAG,EAAoBC,QACnCC,EAAkB,UAASR,MAAAA,OAAV,EAAUA,EAASS,KACpCC,GAAiBC,EAAAA,EAAAA,GACrBX,EAAW,GAAEQ,gBAA0BI,EACvCX,IAAWC,EACXW,EAAAA,GAAAA,QACAV,GAEIW,GAASH,EAAAA,EAAAA,GAASH,EAAgBP,OAAQW,EAAWT,GAE3D,OACE,mBAAC,IAAD,GACEW,OAAQA,EACRC,WAAYL,EACZM,qBAAmB,EACnBX,aAAcA,GAEVD,Q,iFCnCV,QAAwD,uB,0OCexD,MAAMa,EAAoB,IAAIC,IAyC9B,GAAepB,EAAAA,EAAAA,KAvCf,SAAiCC,GAC/B,MAAM,WACJgB,EADI,aACQV,EADR,oBACsBW,EADtB,UAC2CG,KAAcf,GAC3DL,GAEGqB,EAAiBC,IAAqBC,EAAAA,EAAAA,GAAQL,EAAkBM,IAAIR,IACrES,GAAoBC,EAAAA,EAAAA,GAAmBT,GAAuBI,IAC7DM,EAAkBC,IAAsBL,EAAAA,EAAAA,IAAQ,GAEjDM,GAAoBC,EAAAA,EAAAA,KAAY,KACpCR,IACAJ,EAAkBa,IAAIf,KACrB,CAACM,EAAmBN,KAEjB,KAAEgB,GAAShC,EAEjB,OACE,0BACEoB,WAAWa,EAAAA,EAAAA,GAAeb,EDnCT,wBCoCjBc,OAAOC,EAAAA,EAAAA,QAAoBtB,IAATmB,GAAuB,UAASA,gBAAmBA,UAEnEL,GAAoBrB,GAEpB,0BAAK8B,IAAK9B,EAAcc,WAAWa,EAAAA,EAAAA,GAAeI,MAElDV,GAAoBX,GAEpB,0BACEoB,IAAKpB,EACLI,WAAWa,EAAAA,EAAAA,GAAeI,EAAgBZ,GAC1Ca,OAAQT,IAIZ,mBAACU,EAAA,EAAD,KAAkBlC,EAAlB,CAA8BiC,OAAQV,EAAoBY,cAAY,U,gHCxCrE,SAASC,EACdC,EACAC,EACAC,EAHK,GAOL,IAHA,KACEC,EADF,UACQC,EADR,kBACmBC,GAEnB,EACA,MAAMC,EAZW,EAYHL,EAAOM,OAGrBP,EAAOM,MAAgB,EAARA,EACfN,EAAOQ,OAASA,GAChBR,EAAOR,MAAMc,MAAS,GAAEA,MACxBN,EAAOR,MAAMgB,OAAU,OAEvB,MAAMC,EAAMT,EAAOU,WAAW,MAC9BD,EAAIE,MAAM,EAAG,GAEbV,EAAOW,SAAQ,CAACC,EAAMC,KACpBL,EAAIM,YAAeD,EAAIb,EAAOM,QAAUL,EAAY,GAAM,EAC1DO,EAAIL,UAAYF,EAAWY,EAAIb,EAAOM,OAASF,EAAoBD,EACnE,MAAMY,EAAcC,KAAKC,IAAI,EAAaL,EAAOI,KAAKC,IAAI,EAAGf,GAxBlD,KA8Bf,SACEM,EAA+BU,EAAWC,EAAWd,EAAeE,EAAgBa,GAlClE,EAoCN,EAAIA,IACdA,EAASf,GAEPE,EAAS,EAAIa,IACfA,EAASb,EAAS,GAGpBC,EAAIa,YACJb,EAAIc,OAAOJ,EAAIE,EAAQD,GACvBX,EAAIe,MAAML,EA7CQ,EA6CGC,EAAGD,EA7CN,EA6CiBC,EAAIZ,EAAQa,GAC/CZ,EAAIe,MAAML,EA9CQ,EA8CGC,EAAIZ,EAAQW,EAAGC,EAAIZ,EAAQa,GAChDZ,EAAIe,MAAML,EAAGC,EAAIZ,EAAQW,EAAGC,EAAGC,GAC/BZ,EAAIe,MAAML,EAAGC,EAAGD,EAhDE,EAgDSC,EAAGC,GAC9BZ,EAAIgB,YArBFC,CAAiBjB,EA3BF,EA2BOK,GAzBX,GAyBqCE,GAAe,EA5B/C,EA4B+DA,EA1B9D,GA2BjBP,EAAIkB,U,qCChCD,SAASC,EAAeC,GAC7B,MAAMC,EAAiC,EAArBD,EAAYtB,OACxBwB,EAAcd,KAAKe,MAAMF,EAAY,GAC3C,IAAKC,EACH,MAAO,GAWT,MAAME,EAASC,MAAMH,GACfI,EAAWN,EACjB,IAAK,IAAIf,EAAI,EAAGsB,EAAIL,EAAc,EAAGjB,IAAMsB,IAAKtB,EAAG,CACjD,MAAMuB,EAAYpB,KAAKe,MAAW,EAAJlB,EAAS,GACjCwB,EAAWrB,KAAKe,MAAW,EAAJlB,EAAS,GAChCyB,EAAQJ,EAASE,IAAcF,EAASE,EAAY,IAAM,GAChEJ,EAAOnB,GAAOyB,GAASD,EAAY,GAErC,MAAME,EAAgBvB,KAAKe,MAA2B,GAAnBD,EAAc,GAAU,GACrDU,EAAexB,KAAKe,MAA2B,GAAnBD,EAAc,GAAU,GACpDW,EAAYP,EAASK,IAAkBL,EAASK,EAAgB,IAAM,GAG5E,OAFAP,EAAOF,EAAc,GAAMW,GAAaD,EAAgB,GAEjDR,EAGF,SAASU,EAAiBC,EAAgBC,GAC/C,IAAI1C,EAAO,EACX,MAAM2C,EAAU,IAAIZ,MAAMW,GACpBE,EAAeH,EAAKrC,OAASsC,EAC7BG,EAAaJ,EAAK,GAClBK,EAAcL,EAAKA,EAAKrC,OAAS,GACvC,IAAK,IAAIO,EAAI,EAAGA,EAAI+B,EAAU/B,IAAK,WACjC,MAAMoC,EAAMjC,KAAKe,MAAMlB,EAAIiC,GACrBI,IAAO,UAACP,EAAKM,EAAM,UAAZ,QAAkBF,IAAlB,UAAiCJ,EAAKM,UAAtC,QAA8CF,IAA9C,UAA6DJ,EAAKM,EAAM,UAAxE,QAA8ED,IAAgB,EAC3GH,EAAQhC,GAAKqC,EACThD,EAAOgD,IACThD,EAAOgD,GAGX,MAAO,CAAEP,KAAME,EAAS3C,KAAAA,G,oICqBnB,MAAMiD,EAAwBC,OAAOC,WAAW,sBAC1CC,EAAoCF,OAAOC,WAAW,sBAyVnE,SAASE,EAAwBC,GAC/B,MAAO,CACLC,WAAYC,EAAAA,GAA2BP,EAAsBQ,QAAU,GAAK,GAAM,GAClFC,WAAYF,EAAAA,GACPP,EAAsBQ,QACrB,GACCH,GAAcF,EAAkCK,QAAU,GAAK,GAClE,IAsKR,SAASE,EACPC,EACAC,EACAC,GAEA,OACE,0BACEvF,UAAU,wBACVwF,IAAKD,GAEJD,EAAeG,KAAI,QAAC,MAAEC,EAAF,IAASC,GAAV,SAClB,0BACE3F,UAAU,6BACVc,MAAQ,SAAgB,IAAR4E,cAAwB,IAAY,IAANC,UAGlD,2BAAM3F,UAAU,0BACd,wBACEc,MAAQ,yBAAuC,IAAfuE,SAGpC,2BAAMrF,UAAU,kBACd,wBACEc,MAAQ,yBAAuC,IAAfuE,UAO1C,SAAe1G,EAAAA,EAAAA,KA7hBa,IAwBtB,IAxBuB,MAC3BiH,EAD2B,QAE3BC,EAF2B,YAG3BC,EAH2B,eAI3BC,EAJ2B,OAK3BC,EAL2B,KAM3BC,EAN2B,aAO3BjH,EAP2B,UAQ3BkH,EAR2B,UAS3BlG,EAT2B,aAU3BmG,EAV2B,WAW3BC,EAX2B,cAY3BC,EAZ2B,eAa3BC,EAb2B,sBAc3BC,EAd2B,cAe3BC,EAf2B,qBAgB3BC,EAhB2B,YAiB3BC,EAjB2B,cAkB3BC,EAlB2B,oBAmB3BC,EAnB2B,OAoB3BC,EApB2B,YAqB3BC,EArB2B,eAsB3BC,EAtB2B,YAuB3BC,GACI,EACJ,MAAM,2BAAEC,EAAF,qBAA8BC,EAA9B,gBAAoDC,IAAoBC,EAAAA,EAAAA,OAEtEC,SAAS,MAAEC,GAAF,MAASC,GAAT,MAAgBC,IAA3B,cAAoCC,IAAkB5B,EACtD6B,GAAUC,QAAQJ,IAASC,IAC3BI,IAAYC,EAAAA,EAAAA,KAAgB,GAE5BtC,IAAYsC,EAAAA,EAAAA,IAAuB,MACnCC,IAAOC,EAAAA,EAAAA,MACP,MAAEC,IAAUF,IAEXG,GAAaC,KAAkBC,EAAAA,EAAAA,KAAS,GACzCC,GAAyCpJ,EACzCqJ,IAAYC,EAAAA,EAAAA,IAAoBzC,EAAS,aACzC0C,IAAe/I,EAAAA,EAAAA,GAAS6I,IAAW,EAAO3I,EAAAA,GAAAA,SAE1C8I,IAAYhJ,EAAAA,EAAAA,IAChB8I,EAAAA,EAAAA,IAAoBzC,EAAS,WAC5BuC,IACDK,EAAAA,EAAAA,IAAsB5C,EAAS,YAGzB6C,aAAcC,KAAqBC,EAAAA,EAAAA,IACzCN,EAAAA,EAAAA,IAAoBzC,EAAS,aAC5BQ,GACDoC,EAAAA,EAAAA,IAAsB5C,EAAS,aAG3BgD,IAAkBnI,EAAAA,EAAAA,KAAY,KAClCwH,IAAe,GACfrB,EAAOhB,EAAQvG,GAAIuG,EAAQiD,UAC1B,CAACjD,EAASgB,IAEPkC,IAAoBrI,EAAAA,EAAAA,KAAY,KACpCwH,IAAe,KACd,KAEG,WACJc,GADI,eACQ1D,GADR,kBACwB2D,GADxB,eAC2CC,KAC7CC,EAAAA,EAAAA,MAEE,UACJC,GADI,aACO/D,GADP,UACqBgE,GADrB,eACgCC,GADhC,SACgDC,KAClDC,EAAAA,EAAAA,IACFC,EAAAA,EAAAA,IAAY5D,IACZ6D,EAAAA,EAAAA,IAAiB7D,GACjB6B,GAAU,QAAU,QACpBc,GACAS,QACAxJ,EACAyJ,GACAjB,GACAY,GACAE,IACAY,EAAAA,EAAAA,IAAe9D,IAGX+D,IAAQC,EAAAA,EAAAA,IAAahE,GACrBiE,GAwXR,SACElE,EACA2B,GAIA,IAHAlC,EAGA,uDAHe,EACfuE,EAEA,wDADA7E,EACA,wDAEA,MAAMgF,GAAYlC,EAAAA,EAAAA,IAA0B,OAEpC3D,KAAM3C,EAAR,KAAgBE,IAASuI,EAAAA,EAAAA,KAAQ,KACrC,IAAKzC,EACH,OAGF,MAAM,SAAE0C,EAAF,SAAYV,GAAahC,EAC/B,IAAK0C,EACH,MAAO,CACL/F,KAAM,IAAIV,MAAMjB,KAAK2H,IAAIX,EFpiBQ,KEoiB8BtG,KAAK,GACpExB,KAAM,GAIV,MAAM,WAAEuD,EAAF,WAAcG,GAAeL,EAAwBC,GACrDoF,EAAiB5H,KAAK2H,IAAIX,EAxeT,GAwewC,GACzDa,EAAc7H,KAAK8H,MAAMrF,GAAcG,EAAaH,GAAcmF,GAGxE,OAAOlG,EAFiBf,EAAe,IAAIoH,WAAWL,IAEbG,KACxC,CAAC7C,EAAOxC,KAAgB,GAqB3B,OAnBAwF,EAAAA,EAAAA,KAAgB,KACd,MAAMjJ,EAASyI,EAAUS,QAEpBlJ,GAAWC,QAAmB9B,IAATgC,GAS1BJ,EAAeC,EAAQC,EAAQ8D,EAAc,CAC3C5D,KAAAA,EACAC,UAAWkI,EANkB,SAAVhE,EAAmB,UAAY,UADxB,SAAVA,EAAmB,UAAY,UAQ/CjE,kBAAmBiI,EALkB,SAAVhE,EAAmB,UAAY,UADxB,SAAVA,EAAmB,UAAY,cAQxD,CAACgE,EAAOnI,EAAM4D,EAAc9D,EAAQqE,IAEhCmE,EA1amBU,CACxB7E,EAAO2B,GAAQE,KAAkBmC,GAAS,EAAIvE,GAAcuE,IAAQ1D,GAGhEwE,GAAetB,IAAc/D,GAAe,GAAKA,GAAe,GAEtEsF,EAAAA,EAAAA,KAAU,KACRzC,GAAekB,MACd,CAACA,KAEJ,MAAMwB,GAAsB3C,KAAgBe,IAEtC,YACJ6B,GADI,eACSC,GADT,iBACyBC,KAC3BC,EAAAA,EAAAA,IACFnF,EACAE,GAAkB4C,GAClBiC,IAAuBvE,IAIvB4E,aAAcC,GACdC,qBAAsBC,KACpBC,EAAAA,EAAAA,GAAkBP,IAEhBQ,GAAoBJ,KAAwBN,IAAuBC,IAEnEU,IAAoB7K,EAAAA,EAAAA,KAAY,KAChCmK,GACF9D,MAAAA,GAAAA,KAIGqC,IACHvC,EAAOhB,EAAQvG,GAAIuG,EAAQiD,SAG7B1B,EAAAA,EAAAA,MAAaoE,qBAAqB,CAAExF,OAAAA,IACpCkC,IAAgBD,IAChBoB,QACC,CAACwB,GAAazB,GAAWnB,GAAaoB,GAAWtC,EAAgBF,EAAQhB,EAAQvG,GAAIuG,EAAQiD,OAAQ9C,KAExG2E,EAAAA,EAAAA,KAAU,KACJ7D,GAAeW,KAAkB2B,IAAa/C,IAChDS,MAED,CAACsC,GAAW3B,GAAeX,EAAaT,IAE3C,MAAMoF,IAAsB/K,EAAAA,EAAAA,KAAY,KAClC2F,EACFY,EAA2B,CAAEpB,QAAAA,IAE7BqB,EAAqB,CAAErB,QAAAA,MAExB,CAACoB,EAA4BC,EAAsBb,EAAeR,IAE/D6F,IAAahL,EAAAA,EAAAA,KAAaiL,IAC9B,GAAI/D,GAAU4C,SAAWjF,GAAUiF,QAAS,CAC1C,MAAM,MAAE5I,EAAF,KAASgK,GAASrG,GAAUiF,QAAQqB,wBACpCC,EAAUH,aAAaI,WAAaJ,EAAEG,QAAUH,EAAEK,cAAc,GAAGF,QACzEH,EAAEM,kBAEF3C,GAAe/G,KAAKC,IAAID,KAAK2H,IAAIX,KAAauC,EAAUF,GAAQhK,GAAQ2H,GAAW,IAAM,UAE1F,CAACA,GAAUD,KAER4C,IAAkBxL,EAAAA,EAAAA,KAAaiL,IAC/BA,aAAaI,YAA2B,IAAbJ,EAAEQ,SACjCvE,GAAU4C,SAAU,EACpBkB,GAAWC,MACV,CAACD,KAEEU,IAAiB1L,EAAAA,EAAAA,KAAY,KACjCkH,GAAU4C,SAAU,IACnB,IAEG6B,IAAkB3L,EAAAA,EAAAA,KAAY,KAClCsG,EAAanB,EAAQvG,GAAIuG,EAAQiD,UAChC,CAAC9B,EAAanB,EAAQvG,GAAIuG,EAAQiD,SAE/BwD,IAAmB5L,EAAAA,EAAAA,KAAY,KACnCyG,EAAgB,CAAE2B,OAAQjD,EAAQiD,OAAQyD,UAAW1G,EAAQvG,OAC5D,CAACuG,EAAQiD,OAAQjD,EAAQvG,GAAI6H,KAEhCwD,EAAAA,EAAAA,KAAU,KACR,GAAKpF,GAAUiF,SAAYE,GAC3B,OAAO8B,EAAAA,EAAAA,IAAcjH,GAAUiF,QAAS,CACtCiC,UAAWP,GACXQ,UAAWN,GACXO,QAASP,GACTQ,OAAQlB,OAET,CAAChB,GAAcwB,GAAiBR,GAAYU,KAE/C,MAAMS,IAAoB7C,EAAAA,EAAAA,KAAQ,IAChC,0BAAK8C,wBAAyB,CAAEC,OAnLb,4SAoLlB,IAEH,SAASC,KACP,GAAItF,GACF,OAAO5B,GAAe,QAGxB,MAAM,MAAEmH,EAAF,SAASC,GAAa5F,GAE5B,OAAO2F,GAASC,EAyBlB,MAAMC,IAAgBtM,EAAAA,EAAAA,GACpB,QACAb,EACA4J,IAAS5D,IAAWoH,EAAAA,GAAAA,QAAsB,OACzCpH,IAAWoH,EAAAA,GAAAA,QAAsBpH,IAAWoH,EAAAA,GAAAA,cAA4B,SACzEhH,GAAc,qBAGViH,GAAmB,CAAC,eACtB/B,GACF+B,GAAiBC,KAAK,WAEtBD,GAAiBC,KAAKlE,GAAY,QAAU,QAG9C,MAAMmE,IAAmB1M,EAAAA,EAAAA,GAAe,UAAW6J,IAAgB,iBAEnE,SAAS8C,KACP,OACE,0BAAKxN,UAAWuN,IACd,0BAAKvN,UAAU,eACb,wBAAGA,UAAU,QAAQyN,IAAI,OAAOR,MAAOD,OAAoBU,EAAAA,EAAAA,GAAWV,OAEtE,0BAAKhN,UAAU,gBACZiG,GACC,mBAAC0H,EAAA,EAAD,CACE3N,UAAU,OACV2M,QAASN,KAERuB,EAAAA,EAAAA,IAAoB9F,GAAa,IAAP7B,MAMlCyE,IACC,0BAAK1K,UAAU,qBAAqByN,IAAKzF,GAAQ,WAAQvI,GACvD,2BAAMO,UAAU,yBAAyByN,IAAI,QAC1CpI,GAAe,GAAM,IAAEwI,EAAAA,EAAAA,IAAoBtE,GAAWlE,GAAckE,OAEtEnE,EAAeC,GAAcC,GAAgBC,MAGhDmF,IAjER,WACE,GAAIhD,GACF,OACE,0BAAK1H,UAAU,OAAOyN,IAAKzF,GAAQ,WAAQvI,IACxCoO,EAAAA,EAAAA,KAAqBtG,IAASC,IAAQ+B,WAK7C,MAAM,UAAEuE,GAAcxG,GAEtB,OACE,0BAAKtH,UAAU,OAAOyN,IAAKzF,GAAQ,WAAQvI,IACxCoO,EAAAA,EAAAA,IAAoBtE,IACrB,2BAAMvJ,UAAU,UAAhB,KACC8N,GAAa,2BAAM9N,UAAU,YAAYiN,MAAOa,IAAYJ,EAAAA,EAAAA,GAAWI,IACvEA,GAAahI,GAAe,2BAAM9F,UAAU,UAAhB,KAC5B8F,GAAe,2BAAMmH,MAAOnH,IAAc4H,EAAAA,EAAAA,GAAW5H,KAgDpCiI,IAKxB,OACE,0BAAK/N,UAAWmN,GAAeM,IAAK3F,GAAKE,MAAQ,MAAQ,OACtD7B,GACC,0BAAKnG,UAAU,0BACZoG,GAAc,wBAAGpG,UAAU,iBAGhC,mBAACgO,EAAA,EAAD,CACE3D,OAAK,EACL4D,QAAShJ,EAAAA,GACTrE,KAAK,UACLsN,MAAO3F,GAAe,oBAAsB,UAC5CvI,UAAWqN,GAAiBc,KAAK,KACjCC,UAAWhF,GAAY,cAAgB,aACvCuD,QAASpB,GACTvD,MAAOF,GAAKE,MACZqG,gBAAiB9F,IAEjB,wBAAGvI,UAAU,cACb,wBAAGA,UAAU,gBAEdkL,IACC,0BAAKlL,WAAWa,EAAAA,EAAAA,GAAe,gBAAiBuK,GAAmBE,IAAqB,gBACtF,mBAACgD,EAAA,EAAD,CACE9M,SAAUuJ,GACVwD,aAAW,EACX3N,KAAK,IACL+L,QAASrB,GAAoBC,QAAoB9L,EACjD+O,SAAUlD,MAIfhE,IAASZ,IAAgBmE,IACxB,mBAACmD,EAAA,EAAD,CACE3D,OAAK,EACLzJ,KAAK,OACLZ,UAAU,kBACVoO,UAAW/H,EAAgB,kBAAoB,WAC/CsG,QAASlB,IAET,wBAAGzL,UAAWqG,EAAgB,aAAe,qBAGhDL,IAAWoH,EAAAA,GAAAA,QAAsBI,KACjCxH,IAAWoH,EAAAA,GAAAA,QAAsB9F,IA6CxC,SACEQ,EACAR,EACAiC,EACAH,EACA/D,EACAC,EACAC,EACAkJ,EACAxI,EACAzE,EACA6K,GAEA,MAAM,MACJY,EADI,UACGa,EADH,SACcZ,GAChB5F,EACEoH,EAAetF,GAAc/D,EAAe,GAAKA,EAAe,GAChE,MAAE2C,GAAU2G,EAAAA,GAElB,OACE,0BAAK3O,UAAU,WACb,wBAAGA,UAAU,QAAQyN,IAAI,OAAOR,MAAOA,IAAQS,EAAAA,EAAAA,GAAWT,GAASC,IAClEwB,GACC,0BAAK1O,UAAU,OAAOyN,IAAKzF,EAAQ,WAAQvI,GACzC,2BAAMO,UAAU,yBAAyByN,IAAI,SAC1CI,EAAAA,EAAAA,IAAoBtE,EAAWlE,EAAckE,IAE/CnE,EAAeC,EAAcC,EAAgBC,KAGhDmJ,GAAgBD,GAChB,0BAAKzO,UAAU,OAAOyN,IAAKzF,EAAQ,WAAQvI,GACxC+B,EAAY,IAAEoN,EAAAA,EAAAA,IAAkBtH,EAAO1G,KAAOY,aAAiB/B,GAAWmP,EAAAA,EAAAA,IAAkBtH,EAAO1G,QAGtG8N,IAAiBD,GACjB,0BAAKzO,UAAU,OAAOyN,IAAKzF,EAAQ,WAAQvI,GACzC,2BAAMO,UAAU,WAAWyN,IAAI,SAAQI,EAAAA,EAAAA,IAAoBtE,IAC1DuE,GACC,sCACE,2BAAM9N,UAAU,UAAhB,KACA,2BAAMA,UAAU,YAAYyN,IAAI,OAAOR,MAAOa,IAAYJ,EAAAA,EAAAA,GAAWI,KAGxE7H,GACC,sCACE,2BAAMjG,UAAU,UAAhB,KACA,mBAAC2N,EAAA,EAAD,CAAM3N,UAAU,OAAO2M,QAASN,IAC7BwC,EAAAA,EAAAA,IAAoB/G,EAAa,IAAP7B,GAAa,OA7FP6I,CACzChH,GACAR,GACAiC,GACAH,GACA/D,GACAC,GACAC,GACCc,GAAiBwE,GAClB5E,EACA8E,GACA/D,EAAcqF,QAAkB5M,GAEjCuG,IAAWoH,EAAAA,GAAAA,cAA4B7F,IAASC,KAAUgG,KAC1DxH,IAAWoH,EAAAA,GAAAA,QAAsB7F,IAyFxC,SACEA,EACAhC,EACAuE,EACAzE,EACAoC,EACAnB,EACAC,EACAC,EACAC,EACAsI,EACAC,EACApI,GAEA,OACE,0BAAK5G,UAAU,WACb,0BAAKA,UAAU,oBACb,0BACEA,UAAU,WACViP,WAAW,EACXzJ,IAAKD,GAEL,6BAAQC,IAAKsE,KAEdkF,GAEC,mBAAChB,EAAA,EAAD,CAAQrB,QAAS,MACVnG,GAAiBC,IAAyBG,EAC7CA,GAAqBL,GACXD,GACV0I,MAIF,wBAAGhP,WAAWa,EAAAA,EAAAA,GACZ,kBACC2F,GAAiBC,EAAwB,YAAc,mBACvDD,GAAiBC,KAA0BF,GAAyB,sBAGtED,GAAkByI,IAIzB,wBAAG/O,WAAWa,EAAAA,EAAAA,GAAe,iBAAkB4G,GAAiB,UAAWgG,IAAI,QAC3D,IAAjBpI,GAAqBwI,EAAAA,EAAAA,IAAoBtG,EAAMgC,WAAYsE,EAAAA,EAAAA,IAAoBtG,EAAMgC,SAAWlE,KArIjG6J,CACE3H,GACAhC,GACAuE,GACAzE,GACAoC,GACAnB,EACAC,EACAC,EACAC,EACAoG,GACAlG,EAAgB2F,QAAmB7M,EACnCmH,Q,kJCrXV,MA+GA,GAAejI,EAAAA,EAAAA,KAAKwQ,EAAAA,EAAAA,KAClB,CAACC,EAAD,KAA0C,IAAjC,aAAEC,GAA+B,EACxC,MAAM,aAAErQ,EAAcsQ,aAAeC,WAAYC,IAAoBJ,EAE/DK,EAAOJ,GAAeK,EAAAA,EAAAA,IAAWN,EAAQC,QAAgB5P,EACzDkQ,GAAOC,EAAAA,EAAAA,IAASP,IAAgBQ,EAAAA,EAAAA,IAAWT,EAAQC,QAAgB5P,EACnEqQ,EAAUL,IAAQM,EAAAA,EAAAA,IAAkBN,GAAMO,EAAAA,EAAAA,IAAqBZ,IAASa,EAAAA,EAAAA,IAAuBb,IAOrG,MAAO,CACLpQ,aAAAA,EAAcwQ,cAAAA,EAAeC,KAAAA,EAAME,KAAAA,EAAMO,eANpBT,IAASE,MAC5BQ,EAAAA,EAAAA,IAAcV,MAAUW,EAAAA,EAAAA,IAAkBX,EAAM,iBAC/CY,EAAAA,EAAAA,IAAiBZ,EAAM,gBAI+BK,QAAAA,KAd3CX,EA/GyB,IAQvC,IARwC,aAC5CnQ,EAD4C,KAE5C2Q,EAF4C,KAG5CF,EAH4C,cAI5Ca,EAJ4C,eAK5CJ,EAL4C,QAM5CJ,EAN4C,cAO5CN,GACI,EACJ,MAAM,aACJe,EADI,iBAEJC,EAFI,qBAGJC,IACErJ,EAAAA,EAAAA,OAGF9H,GAAIoR,EADA,SAEJC,EAFI,SAGJC,EAHI,YAIJC,EAJI,OAKJC,GACEnB,GAAQ,IACJrQ,GAAIwJ,GAAW2G,GAAQ,GACzB3H,GAAOC,EAAAA,EAAAA,MAEb4C,EAAAA,EAAAA,KAAU,KACJ3L,GAAgB0R,GAClBH,EAAa,CAAEG,OAAAA,MAEhB,CAACH,EAAcG,EAAQ1R,IAE1B,MAAM+R,GAA2BrQ,EAAAA,EAAAA,KAAY,KAC3C+P,EAAqB,CAAE3H,OAAAA,EAAQgH,SAAUA,MACxC,CAAChH,EAAQgH,EAASW,IAErB,IAAKhB,GAAQA,EAAKuB,cAAiBF,IAAWR,EAC5C,OAGF,SAASW,EAAKC,EAAcC,IAC1BC,EAAAA,EAAAA,IAAoBF,GACpBV,EAAiB,CAAE3K,QAAU,GAAEsL,iBAGjC,MAAME,EAAkBR,IAAeS,EAAAA,EAAAA,IAA0B9B,EAAeqB,GAC1EU,GAAOC,EAAAA,EAAAA,IAAY/B,GACnBgC,GAAed,MAAAA,OAAD,EAACA,EAAUe,OAAQC,EAAAA,EAAAA,IAAmBlC,GAE1D,OACE,0BAAKzP,UAAU,aACZqR,GAAmB1J,QAAQ0J,EAAgBxP,SAE1C,mBAAC,IAAD,CAAU+P,KAAK,QAAQC,WAAS,EAACC,QAAM,EAAC7D,QAAM,EAACtB,QAAS,IAAMsE,EAAKI,EAAiBvJ,EAAK,WACvF,2BAAM9H,UAAU,QAAQyN,IAAI,QAAQ4D,GACpC,2BAAMrR,UAAU,YAAY8H,EAAK,WAGpC8I,GACC,mBAAC,IAAD,CACEgB,KAAK,UACLC,WAAS,EACTC,QAAM,EACN7D,QAAM,EAENtB,QAAS,IAAMsE,EAAM,IAAGL,IAAY9I,EAAK,cAEzC,2BAAM9H,UAAU,QAAQyN,IAAI,SAAQC,EAAAA,EAAAA,GAAWkD,IAC/C,2BAAM5Q,UAAU,YAAY8H,EAAK,cAGpC2J,GAAe9J,QAAQ8J,EAAY5P,SAClC,mBAAC,IAAD,CACE+P,KAAK,OACLC,WAAS,EACTC,QAAM,EACNC,UAAQ,GAER,2BAAM/R,UAAU,mBAAmByN,IAAI,SACpCC,EAAAA,EAAAA,GAAW+D,EAAa,CAAC,KAAM,QAAS,WAE3C,2BAAMzR,UAAU,YAAY8H,EAAK4I,EAAS,UAAY,WAGxDR,IAAmBU,IAAaW,GAChC,mBAAC,IAAD,CACEK,KAAMnC,EAAKmB,SAAW,UAAY,OAClCiB,WAAS,EACTC,QAAM,EACN7D,QAAM,EAENtB,QAAS,IAAMsE,EAAKM,EAAMzJ,EAAK,uBAE/B,0BAAK9H,UAAU,SAASuR,GACxB,2BAAMvR,UAAU,YAAY8H,EAAK,wBAGnCwI,GACA,mBAAC,IAAD,CAAUsB,KAAK,SAAS3D,QAAM,EAACtB,QAASoE,GACtC,+BAAOjJ,EAAK,kBACZ,mBAAC,IAAD,CACExI,GAAG,sBACH0S,MAAOtB,EAAS,4BAA8B,4BAC9CuB,SAAUnC,EACVoC,UAAQ,W,sIC5FpB,MA+KA,GAAevT,EAAAA,EAAAA,KAAKwQ,EAAAA,EAAAA,KAClB,CAACC,EAAD,KAAkC,IAAzB,KAAEK,GAAuB,EAChC,MAAM0C,GAAgBvC,EAAAA,EAAAA,IAASH,EAAKnQ,IAC9B8S,GAAiBC,EAAAA,EAAAA,IAAqBjD,EAAQK,EAAKnQ,IACnDqQ,EAAOwC,IAAiBtC,EAAAA,EAAAA,IAAWT,GAAQkD,EAAAA,EAAAA,IAAqB7C,IAChE8C,EAAQ5C,IAAQ6C,EAAAA,EAAAA,IAAU7C,KAAUF,EAAKgD,UACzCC,EAAmBP,IAAkBC,IAAmBG,EACxDI,EAAcR,GAChBS,EAAAA,EAAAA,KAAuB/C,EAAAA,EAAAA,IAAWT,GAAQkD,EAAAA,EAAAA,IAAqB7C,UAC/DhQ,EAEJ,MAAO,CACL0S,cAAAA,EACAC,eAAAA,EACAG,MAAAA,EACAM,WAAW1C,EAAAA,EAAAA,IAAcV,GACzBqD,cAAcC,EAAAA,EAAAA,IAAiBtD,GAC/BuD,cAAcC,EAAAA,EAAAA,IAAiBxD,GAC/ByD,cAAe9D,EAAO8D,cACtBR,gBAAAA,EACAC,YAAAA,EACAQ,eAAgB/D,EAAOgE,SAASC,MAAMF,kBArBxBhE,EA/K+B,IAe7C,IAf8C,OAClDmE,EADkD,KAElD7D,EAFkD,UAGlDoD,EAHkD,cAIlDV,EAJkD,eAKlDC,EALkD,MAMlDG,EANkD,aAOlDO,EAPkD,aAQlDE,EARkD,cASlDE,EATkD,gBAUlDR,EAVkD,YAWlDC,EAXkD,eAYlDQ,EAZkD,QAalDI,EAbkD,oBAclDC,GACI,EACJ,MAAM,aACJC,EADI,cAEJC,EAFI,cAGJC,EAHI,eAIJC,EAJI,aAKJC,IACEzM,EAAAA,EAAAA,MAEEU,GAAOC,EAAAA,EAAAA,KACP+L,GAAYC,EAAAA,EAAAA,GAAajM,EAAM2H,GAE/BuE,GAAqBtT,EAAAA,EAAAA,KAAY,KACrCgT,EAAc,CAAE5K,OAAQ2G,EAAKnQ,GAAI2U,oBAAoB,IAErDV,MACC,CAACG,EAAejE,EAAKnQ,GAAIiU,IAEtBW,GAAsBxT,EAAAA,EAAAA,KAAY,KACtCgT,EAAc,CAAE5K,OAAQ2G,EAAKnQ,GAAI2U,oBAAoB,IACrDJ,EAAa,CAAEM,UAAW1E,EAAKnQ,GAAI8U,WAAY3E,EAAK2E,aAEpDb,MACC,CAACG,EAAejE,EAAKnQ,GAAImQ,EAAK2E,WAAYP,EAAcN,IAErDc,GAAmB3T,EAAAA,EAAAA,KAAY,KAC/ByR,EACFuB,EAAc,CAAE5K,OAAQ2G,EAAKnQ,GAAI2U,oBAAoB,IAC5CnB,GACTc,EAAe,CAAE9K,OAAQ2G,EAAKnQ,GAAIoR,OAAQwC,IAC1CQ,EAAc,CAAE5K,OAAQ2G,EAAKnQ,GAAI2U,oBAAoB,MAC3CpB,IAAaG,GAAkBvD,EAAK6E,WAEpCzB,GAAaG,IAAiBvD,EAAK6E,WAC7CX,EAAc,CAAE7K,OAAQ2G,EAAKnQ,KAF7BmU,EAAa,CAAE3K,OAAQ2G,EAAKnQ,KAI9BiU,MACC,CACDpB,EACAW,EACAD,EACAG,EACAE,EACAzD,EAAK6E,UACL7E,EAAKnQ,GACLiU,EACAG,EACAE,EACAH,EACAE,IAGIY,GAAkB7T,EAAAA,EAAAA,KAAY,KAC9BmS,GAAaG,GACfS,EAAa,CAAE3K,OAAQ2G,EAAKnQ,KAC5BiU,KAEAc,MAED,CAAC5E,EAAKnQ,GAAI+U,EAAkBxB,EAAWG,EAAcS,EAAcF,IAgEtE,OACE,mBAAC,IAAD,CACED,OAAQA,EACRtT,UAAU,kBACVwU,OAhEA,0BAAKxU,UAAU,eAAeyN,IAAK3F,EAAKE,MAAQ,WAAQvI,GACtD,mBAAC,IAAD,CACEmB,KAAK,OACL6O,KAAMA,EACNgF,gBAAiBrC,EACjBe,eAAgBA,EAChBuB,WAAS,IAEX,yBAAI1U,UAAU,eAAe8H,EAM7B+K,IAAcpD,EAAK6E,UACd,eAGLzB,GAAapD,EAAK6E,UACb,gBAGLxB,GAAgBE,EACX,mBAGF,oBAuCLO,QAASA,EACTC,oBAAqBA,GApCnBX,GAAapD,EAAK6E,UAElB,6BACG5G,EAAAA,EAAAA,GAAW5F,EAAK,2CAA4CgM,GAAY,CAAC,kBAAmB,WAK9FjB,IAAcpD,EAAK6E,WAAcxB,GAAgBE,EAC7C,6BAAItF,EAAAA,EAAAA,GAAW5F,EAAK,4BAA6BgM,GAAY,CAAC,kBAAmB,WAGnF,6BAAIpG,EAAAA,EAAAA,GAAW5F,EAAK,kCAAmC6K,GAAc,CAAC,kBAAmB,WA2B7FJ,GACC,mBAAC,IAAD,CAAQrE,MAAM,SAASlO,UAAU,wBAAwB2U,QAAM,EAAChI,QAASuH,GACtEpM,EAAK,kBAGT4K,GACC,mBAAC,IAAD,CAAQxE,MAAM,SAASlO,UAAU,wBAAwB2U,QAAM,EAAChI,QAASqH,GACtErB,GAAcjF,EAAAA,EAAAA,GAAW5F,EAAK,6BAA8B6K,IAAgB7K,EAAK,kBAGpFqK,GAAiB1C,EAAK6E,WACtB,mBAAC,IAAD,CAAQpG,MAAM,SAASlO,UAAU,wBAAwB2U,QAAM,EAAChI,QAAS0H,GACtEvM,EAAK,iBAGV,mBAAC,IAAD,CACEoG,MAAM,SACNlO,UAAU,wBACV2U,QAAM,EACNhI,QAASwF,EAAgBkC,EAAmBE,GAE3CzM,EA5CD+K,IAAcpD,EAAK6E,UACd,eAELzB,GAAapD,EAAK6E,UACb,oBAGLxB,GAAgBE,EACX,mBAGFN,EAAkB,gCAAkC,WAmCzD,mBAAC,IAAD,CAAQ1S,UAAU,wBAAwB2U,QAAM,EAAChI,QAAS4G,GAAUzL,EAAK,iB,sIC9K/E,MAoHA,GAAenJ,EAAAA,EAAAA,KAlHgB,IAiBzB,IAjB0B,QAC9BkH,EAD8B,oBAE9B+O,EAF8B,QAG9BC,EAH8B,YAI9BC,EAJ8B,sBAK9BC,EAL8B,eAM9BhP,EAN8B,SAO9BiP,EAP8B,SAQ9BC,EAR8B,UAS9BjV,EAT8B,OAU9BkV,EAV8B,WAW9B9O,EAX8B,aAY9BD,EAZ8B,eAa9BY,EAb8B,aAc9BoO,EAd8B,YAe9BnO,EAf8B,cAgB9BX,GACI,EACJ,MAAM+O,GAAWhO,EAAAA,EAAAA,MAGX5B,GAAMqC,EAAAA,EAAAA,IAAuB,MAE7BwN,EAAWxP,EAAQwB,QAAQgO,UAC3B,SAAEnI,EAAF,KAAYtM,EAAZ,UAAkB0U,GAAcD,EAChCE,GAAYC,EAAAA,EAAAA,IAAqBH,IAAa,GAE9CI,GAAiBC,EAAAA,EAAAA,IAAkBlQ,EAAKoP,IACvCe,EAAgBC,IAAmBzV,EAAAA,EAAAA,MAC1CwK,EAAAA,EAAAA,KAAU,KACJ8K,GACFG,MAED,CAACH,EAAgBG,IAGpB,MAAOC,EAAeC,IAAoB3N,EAAAA,EAAAA,IACxC2M,KAAiBC,GAAyBnU,GAvCzB,QAuCiCmU,IAG9CgB,EAAiBpO,QAAQtB,GAAkBwP,GAAiBF,GAE5DK,GAAe1N,EAAAA,EAAAA,IAAoBzC,EAAS,aAC1C6C,aAAcC,EAAhB,UAAkCH,IAAcI,EAAAA,EAAAA,GACpDoN,GAAeD,GAAgBtN,EAAAA,EAAAA,IAAsB5C,EAAS,iBAAapG,OAAWA,GAAW,GAE7FwW,EAAWtO,QAAQa,IAEnB,YACJqC,EADI,eACSC,EADT,iBACyBC,IAC3BC,EAAAA,EAAAA,IAAsBnF,EAASE,GAAkB4C,EAAkBoN,IAAmBE,GAEpFC,GAAaC,EAAAA,EAAAA,IAAsBd,GACnCnW,EAAegX,GAAaE,EAAAA,EAAAA,IAA4BvQ,QAAWpG,EACnE4W,EAAeH,EAAab,EAAS9V,oBAAiBE,EACtD6W,GAAc9W,EAAAA,EAAAA,IAAS8I,EAAAA,EAAAA,IAAoBzC,EAAS,cAAe4P,GAEnEc,EAAkBpB,GAAgBxN,QAAQ0N,EAASmB,WAEnDC,GAAc/V,EAAAA,EAAAA,KAAY,KAC1BmK,EACE9D,GACFA,IAKAV,EACF+O,EAASnO,2BAA2B,CAAEpB,QAAAA,IAIpCiF,EACFgL,GAAiB,GAIfS,EACFpB,IAEAC,EAASlO,qBAAqB,CAAErB,QAAAA,MAEjC,CACDgF,EAAaxE,EAAeyE,EAAgByL,EAAiBxP,EAAgBqO,EAAUvP,EAASsP,IAG5F9I,GAAkB3L,EAAAA,EAAAA,KAAY,KAClCsG,EAAanB,EAAQvG,GAAIuG,EAAQiD,UAChC,CAAC9B,EAAanB,EAAQvG,GAAIuG,EAAQiD,SAErC,OACE,mBAAC,IAAD,CACEtD,IAAKA,EACLkR,KAAMxJ,EACNqI,UAAWA,EACX3U,KAAMA,EACN0U,UAAWN,EAAWC,GAAYK,OAAY7V,EAC9CkX,iBAAkBzX,EAClBoX,YAAaD,GAAgBC,EAC7BzB,QAASA,EACT/J,eAAgBA,EAChBD,YAAaA,EACbE,iBAAkBA,EAClB/K,UAAWA,EACXkV,OAAQA,EACR/O,aAAcA,EACdC,WAAYA,EACZwQ,WAAYL,GAAmBM,EAAAA,EAAAA,IAAuBhR,GAAW,YAAc,WAAc,gBAC7F8G,QAAS8J,EACTzP,YAAaA,EAAcqF,OAAkB5M,Q,sEC7InD,MAUA,EAVmC,IAA4B,IAA3B,QAAE4H,EAAF,UAAWrH,GAAgB,EAC7D,MAAM8H,GAAOC,EAAAA,EAAAA,KACb,OACE,2BAAM/H,WAAWa,EAAAA,EAAAA,GAAe,eAAgBb,GAAYyN,IAAK3F,EAAKE,MAAQ,MAAQ,QACnFX,EACD,2BAAMrH,UAAU,gB,2DCLtB,MAQA,GAAerB,EAAAA,EAAAA,KARgB,IAEzB,IAF0B,SAC9BmY,GACI,EACJ,MAAMhP,GAAOC,EAAAA,EAAAA,KAEb,OAAO,2BAAM/H,UAAU,YAAY8H,EAAkB,SAAbgP,EAAsB,cAAgB,oB,2JCqBhF,MAuHA,GAAenY,EAAAA,EAAAA,KAvHY,IAmBrB,IAnBsB,IAC1B6G,EAD0B,KAE1BkR,EAF0B,KAG1B9V,EAH0B,UAI1B2U,EAAY,GAJc,UAK1BD,EAL0B,OAM1BJ,EAN0B,iBAO1ByB,EAP0B,YAQ1BL,EAR0B,UAS1BtW,EAT0B,QAU1B6U,EAV0B,eAW1B/J,EAX0B,YAY1BD,EAZ0B,aAa1B1E,EAb0B,WAc1BC,EAd0B,iBAe1B2E,EAf0B,WAgB1B6L,EAhB0B,QAiB1BjK,EAjB0B,YAkB1B3F,GACI,EACJ,MAAMc,GAAOC,EAAAA,EAAAA,KAEb,IAAIgP,GAAalP,EAAAA,EAAAA,IAAuB,MACpCrC,IACFuR,EAAavR,GAGf,MAAM2F,GAAuB7K,EAAAA,EAAAA,GAAmBgW,IAE9CrL,aAAc+L,EACd7L,qBAAsBC,IACpBC,EAAAA,EAAAA,GAAkBP,OAAgBrL,GAAW,GAE3CyO,GAAQ+I,EAAAA,EAAAA,IAAsB1B,GAC9B2B,GAAatI,EAAAA,EAAAA,IAAkBhO,IAE/B,MAAEgB,EAAF,OAASE,IAAWqV,EAAAA,EAAAA,IAA+BtC,GAEnD1H,GAAgBtM,EAAAA,EAAAA,GACpB,OACAb,EACA6U,GAAW,UACXlI,IAAY9B,GAAe,cAC3BzE,GAAc,oBAGhB,OACE,0BAAKZ,IAAKuR,EAAY/W,UAAWmN,EAAeM,IAAK3F,EAAKE,MAAQ,WAAQvI,GACvE0G,GACC,0BAAKnG,UAAU,0BACZoG,GAAc,wBAAGpG,UAAU,iBAGhC,0BAAKA,UAAU,sBAAsB2M,QAAS9B,OAAcpL,EAAYkN,GACrEgK,GAAoBL,EACnB,0BAAKtW,UAAU,4BACb,0BACEgB,IAAK2V,EACL/U,MAAOA,EACPE,OAAQA,EACR9B,UAAU,YACVoX,IAAI,KAEN,0BACEpW,IAAKsV,EACLtW,WAAWa,EAAAA,EAAAA,GAAe,aAAcsK,GACxCvJ,MAAOA,EACPE,OAAQA,EACRsV,IAAI,MAIR,0BAAKpX,UAAY,aAAYkO,KAC1BqH,EAAU1T,QAAU,GACnB,2BAAM7B,UAAU,WAAWyN,IAAI,QAAQ8H,IAI5CyB,GACC,0BAAKhX,WAAWa,EAAAA,EAAAA,GAAe,gBAAiBqN,EAAO9C,IACrD,mBAAC,IAAD,CACE5J,SAAUuJ,EACVnK,KAAMiU,EAAU,IAAM,IACtBlI,QAAS9B,EAAc8B,OAAUlN,KAItCkN,GACC,wBACE3M,WAAWa,EAAAA,EAAAA,GACT,cACA+V,GAAc,gBACdI,GAAuB,aAK/B,0BAAKhX,UAAU,aACb,0BAAKA,UAAU,aAAayN,IAAI,SAAQC,EAAAA,EAAAA,GAAWgJ,IACnD,0BAAK1W,UAAU,gBAAgByN,IAAI,QACjC,+BACG3C,GAAkBC,EAAoB,GAAExI,KAAK8H,MAAyB,IAAnBU,MAA6BmM,GAElFhC,GAAU,2BAAMlV,UAAU,gBAAe0N,EAAAA,EAAAA,GAAWwH,KACnDA,GAAUI,GACV,sCACE,2BAAMtV,UAAU,WAChB,mBAAC,IAAD,CAAM2M,QAAS3F,IAAc6H,EAAAA,EAAAA,IAAoB/G,EAAkB,IAAZwN,GAAkB,OAKhFJ,GAAUI,GACT,mBAAC,IAAD,CAAM3I,QAAS3F,IAAc4G,EAAAA,EAAAA,IAAoB9F,EAAkB,IAAZwN,S,yKC8B/D,SAAe3W,EAAAA,EAAAA,KAAKwQ,EAAAA,EAAAA,KAClB,CAACC,EAAD,KAAoC,IAA3B,OAAEtG,GAAyB,EAClC,MAAM,aAAE9J,GAAiBoQ,EACnBK,GAAOC,EAAAA,EAAAA,IAAWN,EAAQtG,GAIhC,MAAO,CACL9J,aAAAA,EACAyQ,KAAAA,EACA4H,YANkB5H,GAAO6H,EAAAA,EAAAA,IAAsBlI,EAAQK,QAAQhQ,EAO/D8X,kBANwB5P,SAAQ6P,EAAAA,EAAAA,IAAmBpI,EAAQtG,IAO3DqK,eAAgB/D,EAAOgE,SAASC,MAAMF,kBAZxBhE,EApI6B,IAiB3C,IAjB4C,aAChDsI,EADgD,WAEhDC,EAAa,SAFmC,OAGhDC,EAHgD,SAIhDC,EAJgD,gBAKhDrB,EALgD,aAMhDsB,EANgD,aAOhDC,EAPgD,mBAQhDC,EARgD,aAShDC,EATgD,gBAUhDC,EAVgD,MAWhDC,EAXgD,KAYhDzI,EAZgD,YAahD4H,EAbgD,kBAchDE,EAdgD,eAehDpE,EAfgD,aAgBhDnU,GACI,EACJ,MAAM,aACJmZ,EADI,gBAEJC,EAFI,kBAGJC,IACEjR,EAAAA,EAAAA,MAEE4L,EAAevD,IAAQwD,EAAAA,EAAAA,IAAiBxD,IACtCnQ,GAAIwJ,EAAN,MAAcwP,EAAd,aAAqBtH,GAAiBvB,GAAQ,IAEpD9E,EAAAA,EAAAA,KAAU,KACJ7B,IAAWwP,GAAStZ,IAClB8Y,GAAcK,EAAa,CAAErP,OAAAA,IAC7ByN,GAAiB8B,EAAkB,CAAEE,UAAWzP,OAErD,CAACA,EAAQwP,EAAOtZ,EAAc8Y,EAAcK,EAAcE,EAAmBrF,EAAcuD,IAE9F,MAAMiC,GAAyB9X,EAAAA,EAAAA,KAAY,CAACiL,EAAgD8M,KACtFhJ,GAAQgJ,IACV9M,EAAEM,kBACFmM,EAAgB,CACdM,cAAejJ,EAAKnQ,GACpBqZ,QAAS,EACT3S,OAAuB,UAAf0R,EAAyBkB,EAAAA,GAAAA,cAAkCA,EAAAA,GAAAA,wBAGtE,CAACnJ,EAAMiI,EAAYU,IAEhBtQ,GAAOC,EAAAA,EAAAA,KAEb,GAAK0H,EA8CL,OACE,0BAAKzP,UAAU,WAAWyN,KAAMyK,GAASpQ,EAAKE,MAAQ,WAAQvI,GAC5D,mBAAC,IAAD,CACEoZ,IAAKpJ,EAAKnQ,GACVsB,KAAM8W,EACNjI,KAAMA,EACN9C,QAAS4J,EAAkBiC,OAAyB/Y,EACpDiV,UAAWuD,EACX9E,eAAgBA,IAElB,0BAAKnT,UAAU,QACb,0BAAKA,UAAU,SACb,yBAAIyN,IAAI,SAAQC,EAAAA,EAAAA,IAAWqG,EAAAA,EAAAA,GAAajM,EAAM2H,KAC7CA,EAAKqJ,YAAc,mBAAC,IAAD,MACnBrJ,EAAKqH,UAAY,mBAAC,IAAD,CAAUA,SAAUrH,EAAKqH,YAxDnD,WACE,GAAIa,EACF,OAAOC,EACL,mBAAC,IAAD,CAAc5X,UAAU,SAASqH,QAASsQ,IAE1C,2BAAM3X,UAAU,SAASyN,IAAI,QAAQkK,GAIzC,GAAII,IAAuBR,IAAsBvG,EAC/C,OACE,mBAAC,IAAD,CAAchR,UAAU,SAASqH,QAASS,EAAK,cAInD,IAAK2H,EACH,OAGF,GAAIgI,EACF,OAAO,mBAAC,IAAD,CAAcA,aAAcA,IAGrC,GAAIO,EACF,OACE,2BAAMhY,UAAU,SAASyN,IAAI,QAAQ3F,GAAKiR,EAAAA,EAAAA,IAAkBtJ,KAIhE,MAAMuJ,EAASnB,EAAepI,EAAKmB,cAAWnR,EACxCwZ,EAkCV,SAAwBnR,EAAc2H,GACpC,MAAMyJ,EAAiBpR,GAAKiR,EAAAA,EAAAA,IAAkBtJ,KACxC,aAAE0J,GAAiB1J,EAEzB,OAAIA,EAAKuB,aACmB,YAAnBkI,EAA+B,0BAA4B,wBAG/DC,EAKDrR,EADsB,YAAnBoR,EACE,cACA,UADeC,EAAc,KAJ7BD,EA3CaE,CAAetR,EAAM2H,GACnC4J,EAAehC,EAAe,KAAIvP,EAAK,cAAeuP,EAAa,YAAS5X,EAElF,OACE,2BAAMO,UAAU,UACbgZ,GAAU,2BAAMhZ,UAAU,UAAUgZ,GACrC,2BAAMhZ,UAAU,gBAAgBiZ,GAC/BI,GAAgB,2BAAMrZ,UAAU,iBAAiBqZ,IAqBjDC,U,8EC9IT,MAYA,GAAe3a,EAAAA,EAAAA,KAZuB,IAAiC,IAAhC,QAAEkH,EAAF,eAAW0T,GAAqB,EACrE,MAAMzR,GAAOC,EAAAA,EAAAA,KACb,OACE,0BAAK/H,UAAU,mBACZuZ,GACC,mBAAC,IAAD,CAAuB5B,OAAQ4B,IAEjC,2BAAMvZ,UAAU,SAAQ4N,EAAAA,EAAAA,IAAoB9F,EAAqB,IAAfjC,EAAQI,Y,wHCKhE,MAiDA,GAAetH,EAAAA,EAAAA,KAjDa,IAMtB,IANuB,QAC3BkH,EAD2B,SAE3B2T,EAAW,eAFgB,YAG3BC,EAH2B,oBAI3B7E,EAJ2B,QAK3BjI,GACI,EAEJ,MAAMnH,GAAMqC,EAAAA,EAAAA,IAAuB,MAE7B4N,GAAiBC,EAAAA,EAAAA,IAAkBlQ,EAAKoP,GACxC1V,GAAekX,EAAAA,EAAAA,IAA4BvQ,GAC3C6T,GAAela,EAAAA,EAAAA,IAAS8I,EAAAA,EAAAA,IAAoBzC,EAAS,cAAe4P,GACpEtK,GAAuB7K,EAAAA,EAAAA,GAAmBoZ,GAE1ClS,GAAQmS,EAAAA,EAAAA,IAAgB9T,GAExB4Q,GAAc/V,EAAAA,EAAAA,KAAY,KAC9BiM,EAAS9G,EAAQvG,GAAIuG,EAAQiD,UAC5B,CAACjD,EAAQvG,GAAIuG,EAAQiD,OAAQ6D,IAEhC,OACE,0BACEnH,IAAKA,EACLlG,GAAK,GAAEka,KAAWI,EAAAA,EAAAA,IAAiB/T,EAAQvG,MAC3CU,UAAU,oBACV2M,QAASA,EAAU8J,OAAchX,GAEjC,0BACEuB,IAAK9B,EACLkY,IAAI,GACJnI,WAAYwK,EACZI,SAAS,QACTC,cAAeL,EAAcM,EAAAA,OAAYta,IAE3C,0BACEuB,IAAK0Y,EACL1Z,WAAWa,EAAAA,EAAAA,GAAe,aAAcsK,GACxCiM,IAAI,GACJnI,WAAYwK,EACZI,SAAS,QACTC,cAAeL,EAAcM,EAAAA,OAAYta,IAE1C+H,GAAS,2BAAMxH,UAAU,kBAAkBwH,EAAMwS,MAAQ,OAAQnM,EAAAA,EAAAA,IAAoBrG,EAAM+B,WAC3FkQ,GAAe,2BAAMzZ,UAAU,mB,oCC5DjCia,E,+BAAAA,GAAAA,EAAAA,EAAAA,OAAAA,GAAAA,SAAAA,EAAAA,EAAAA,QAAAA,GAAAA,UAAAA,EAAAA,EAAAA,UAAAA,GAAAA,YAAAA,EAAAA,EAAAA,KAAAA,GAAAA,O,CAAAA,IAAAA,EAAAA,KAIL,MAUA,GAAetb,EAAAA,EAAAA,KAV6B,IAAgB,IAAf,OAAEgZ,GAAa,EAC1D,OACE,0BAAK3X,UAAU,yBACb,mBAAC,IAAD,CAAY0W,KAAK,SAASwD,UAAWD,EAAKtC,IACxC,wBAAG3X,UAAY,gBAAe2X,Y,4FCNtC,MAAMwC,EAAe,iBAcrB,GAAexb,EAAAA,EAAAA,KAZoB,IAA0C,IAAzC,KAAEuS,EAAOiJ,EAAT,YAAuB1I,GAAkB,EAC3E,MAAM3J,GAAOC,EAAAA,EAAAA,MACP,qBAAEoD,IAAyBE,EAAAA,EAAAA,IAAkB,GAEnD,OACE,0BAAKrL,WAAWa,EAAAA,EAAAA,GAAe,eAAgBsK,EAAsBsG,GAAe,qBACjFP,EACAO,GAAe,wBAAGzR,UAAU,gBAAe0N,EAAAA,EAAAA,GAAW5F,EAAK2J,GAAc,CAAC,a,gHCOjF,MAAM2I,EAAyBnV,EAAAA,GAA0B,IAAM,IA6H/D,GAAetG,EAAAA,EAAAA,KA3HoB,IAe7B,IAf8B,UAClC0b,GAAY,EADsB,kBAElCC,EAFkC,MAGlCC,EAHkC,KAIlCC,EAJkC,YAKlCC,EAAc,WALoB,YAMlCC,EAAc,OANoB,iBAOlCC,EAPkC,iBAQlCC,EARkC,6BASlCC,GAA+B,EATG,SAUlCC,GAAW,EAVuB,WAWlCC,EAXkC,2BAYlCC,EAZkC,cAalCC,EAbkC,SAclCC,GACI,EAEJ,MAAMC,GAAWtT,EAAAA,EAAAA,IAAyB,MACpCC,GAAOC,EAAAA,EAAAA,MAENqT,EAAUC,IAAelT,EAAAA,EAAAA,IAAS,KAClCmT,EAAWC,IAAgBpT,EAAAA,EAAAA,KAAS,GAgE3C,OA9DAwC,EAAAA,EAAAA,KAAU,KACJiQ,GACFS,EAAY,MAEb,CAACT,KAEJY,EAAAA,EAAAA,IAAW,KACJC,EAAAA,IACHN,EAAS3Q,QAASkR,UAEnBtB,IAEHzP,EAAAA,EAAAA,KAAU,KACJ4P,GACFoB,uBAAsB,KACpBR,EAAS3Q,QAASkR,QAClBP,EAAS3Q,QAASoR,cAGrB,CAACrB,IA4CF,2BAAMsB,OAAO,GAAGX,SAzBlB,SAAsBY,GACpBA,EAAMC,iBAEF1B,GAIAiB,GACFJ,EAASE,IAiB6BY,aAAa,OACnD,0BACEhc,WAAWa,EAAAA,EAAAA,GAAe,6BAA8Bua,GAAY,UAAWb,GAAS,SACxF9M,IAAK3F,EAAKE,MAAQ,WAAQvI,GAEzBob,GAhBH,4BACEoB,KAAK,WACL3c,GAAG,mBACH0c,aAAa,MACbhc,UAAU,kBACVkc,UAAW,IAYX,4BACE1W,IAAK2V,EACLnb,UAAU,eACVic,KAAM3B,EAAoB,OAAS,WACnChb,GAAG,mBACHuE,MAAOuX,GAAY,GACnBY,aAAcnB,EAA+B,gBAAkB,mBAC/DsB,SAvDR,SAA0BxQ,GACpB4O,GACFQ,IAGF,MAAM,OAAEqB,GAAWzQ,EACnB0P,EAAYe,EAAOvY,OACnB0X,EAAaa,EAAOvY,MAAMhC,QAAUwa,EAAAA,IAChCpB,GACFA,EAAcmB,EAAOvY,QA+CjByY,UAAW,IACX7O,IAAI,SAEN,gCAAQ8M,GAASC,GAAQC,GACzB,0BACEza,UAAU,kBACV2M,QAjDR,WACEqO,GAA4BV,IAiDtBiC,KAAK,SACLL,SAAU,EACVjP,MAAM,8BAEN,wBAAGjN,UAAWsa,EAAoB,WAAa,uBAGjDgB,GAAaX,IACb,mBAAC,IAAD,CAAQsB,KAAK,SAAShO,QAAS6M,EAAUT,UAAWA,EAAWmC,UAAWlB,GACvEZ,Q,wKCjHX,MAwGA,GAAe/b,EAAAA,EAAAA,KAnGc,IAYvB,IAZwB,QAC5B8d,EAD4B,YAE5BC,EAF4B,YAG5BC,EAH4B,kBAI5BC,EAJ4B,aAK5BC,EAL4B,cAM5BC,EAN4B,UAO5BzC,EAP4B,gBAQ5B0C,EAR4B,oBAS5BC,EAT4B,eAU5BC,EAV4B,WAW5BC,GACI,EAEJ,MAAM/B,GAAWtT,EAAAA,EAAAA,IAAyB,MACpCsV,EAAiBT,EAAY7a,OAlBd,IAoBrB8I,EAAAA,EAAAA,KAAU,KACRyS,YAAW,KACTzB,uBAAsB,KACpBR,EAAS3Q,QAASkR,aAzBH,OA4BlB,IAEH,MAAM2B,GAAkB3c,EAAAA,EAAAA,KAAapB,IACnC,MAAMge,EAAiB,IAAIZ,GACvBY,EAAeC,SAASje,GAC1Bge,EAAeE,OAAOF,EAAeG,QAAQne,GAAK,GAElDge,EAAehQ,KAAKhO,GAEtB0d,EAAoBM,GACpBL,EAAe,MACd,CAACP,EAAaM,EAAqBC,IAEhCS,GAAqBhd,EAAAA,EAAAA,KAAaiL,IACtC,MAAM,MAAE9H,GAAU8H,EAAEgS,cACpBV,EAAepZ,KACd,CAACoZ,KAEGW,EAAaC,IAAWC,EAAAA,EAAAA,GAAkBZ,EAAYT,EAAS9U,QAAQgV,IAExE7U,GAAOC,EAAAA,EAAAA,KAEb,OACE,0BAAK/H,UAAU,UACb,0BAAKA,UAAU,8BAA8ByN,IAAK3F,EAAKE,MAAQ,WAAQvI,GACpEid,EAAYjX,KAAI,CAACnG,EAAI8C,IACpB,mBAAC,IAAD,CACEiN,aAAc/P,EACdye,YAAaZ,GAAkB/a,EAAIsa,EAAY7a,OArD3B,EAsDpBmc,UAAQ,EACRrR,QAAS0Q,EACTY,SAAU3e,MAGd,mBAAC,IAAD,CACEA,GAAIwd,EACJtX,IAAK2V,EACLtX,MAAO8Y,EACPR,SAAUuB,EACVjD,YAAamC,GAAqB9U,EAAK,iBAI1C8V,MAAAA,GAAAA,EAAa/b,OACZ,mBAAC,IAAD,CACE7B,UAAU,4BACVke,MAAON,EACPV,WAAYW,EACZd,gBAAiBA,GAEhBa,EAAYnY,KAAKnG,GAChB,mBAAC,IAAD,CACEuZ,IAAKvZ,EACLU,UAAU,uCAEV2M,QAAS,IAAM0Q,EAAgB/d,GAC/B2O,QAAM,GAEN,mBAAC,IAAD,CAAU+D,MAAM,GAAGC,QAASyK,EAAYa,SAASje,MAChDsQ,EAAAA,EAAAA,IAAStQ,GACR,mBAAC,IAAD,CAAiBoR,OAAQpR,IAEzB,mBAAC,IAAD,CAAewJ,OAAQxJ,QAK5B+a,IAAauD,GAAgBA,EAAY/b,OAG5C,mBAAC,IAAD,MAFA,wBAAG7B,UAAU,cAAc6c,GAAgB,8B,6HCpGnD,MAsEA,GAAele,EAAAA,EAAAA,KAAKwQ,EAAAA,EAAAA,KAClB,CAACC,EAAD,KAA0C,IAAjC,aAAEC,GAA+B,EACxC,OAAKA,EAOE,CACLI,KAJWJ,GAAeK,EAAAA,EAAAA,IAAWN,EAAQC,QAAgB5P,EAK7DkQ,MAJWC,EAAAA,EAAAA,IAASP,IAAgBQ,EAAAA,EAAAA,IAAWT,EAAQC,QAAgB5P,GAJhE,KAHO0P,EAtEkC,IAUhD,IAViD,KACrDyC,EADqD,MAErD3E,EAFqD,YAGrD8Q,EAHqD,SAIrDC,EAJqD,QAKrDrR,EALqD,SAMrDsR,EANqD,KAOrDxO,EAPqD,KAQrDE,EARqD,UASrD3P,GACI,EACJ,MAAM8H,GAAOC,EAAAA,EAAAA,KAEb,IAAIoW,EACAC,EAEJ,GAAIxM,GAAQ3E,EACVkR,EACE,0BAAKne,UAAU,aACb,wBAAGA,UAAY,QAAO4R,OAI1BwM,EAAYnR,OACP,GAAIwC,GAAQE,EAAM,CACvBwO,EACE,mBAAC,IAAD,CACE1O,KAAMA,EACNE,KAAMA,EACN/O,KAAK,QACL6T,gBAAiB9E,MAAAA,OAAF,EAAEA,EAAMmB,SAI3B,MAAM4F,GAAQjH,GAASE,IAASA,EAAKmB,QACjC8B,EAAAA,EAAAA,IAAuBjD,IACvBoE,EAAAA,EAAAA,GAAajM,EAAM2H,EAAME,GAE7ByO,EAAY1H,GAAOhJ,EAAAA,EAAAA,GAAWgJ,QAAQjX,EAGxC,MAAM0N,GAAgBtM,EAAAA,EAAAA,GACpB,qBACAb,EACA+d,GAAe,YACfC,GAAY,aAGd,OACE,0BACEhe,UAAWmN,EACXR,QAAS,IAAMA,EAAQsR,GACvBhR,MAAO8Q,EAAcK,OAAY3e,EACjCgO,IAAK3F,EAAKE,MAAQ,WAAQvI,GAEzB0e,GACCJ,GACA,0BAAK/d,UAAU,YAAYyN,IAAI,QAC5B2Q,GAGJJ,GACC,0BAAKhe,UAAU,eACb,wBAAGA,UAAU,sB,qECrFvB,MAAMqe,EAAe,CAAEtR,OAAQ,uuCACzBuR,EAAiC,GAuCvC,GAAe3f,EAAAA,EAAAA,KA9BmB,IAK5B,IAL6B,aACjC4f,EADiC,IAEjCC,EAFiC,UAGjCxe,EAHiC,QAIjC2M,GACI,EACJ,MAAM8R,GAAOzU,EAAAA,EAAAA,KAAQ,IACZuU,EAeX,WACE,MAAMjf,GAAKof,EAAAA,EAAAA,GAAcJ,GACzB,MAAO,CAELvR,OAAS,4HAA2HzN,40CAA60CA,eAnB37Cqf,GAA2BN,GAChD,CAACE,IAEJ,OACE,wBACE5R,QAASA,EACT3M,WAAWa,EAAAA,EAAAA,GACT,cAAeb,EAAWue,GAAgB,WAAY5R,GAAW,YAAa6R,GAAO,OAEvF1R,wBAAyB2R,EACzBxR,MAAM,gB,kLCYZ,MAkHA,GAAetO,EAAAA,EAAAA,KAAKwQ,EAAAA,EAAAA,KAClB,CAACC,EAAD,KAAmD,IAA1C,OAAEsB,EAAF,cAAUJ,GAAgC,EACjD,MAAM,aAAEtR,EAAF,iBAAgB4f,GAAqBxP,EACrCO,GAAOE,EAAAA,EAAAA,IAAWT,EAAQsB,GAKhC,MAAO,CACL1R,aAAAA,EACA2Q,KAAAA,EACAkP,YAPiBC,EAAAA,EAAAA,IAAiB1P,EAAQsB,GAQ1C+D,iBAPuBnE,GAAiBX,GAAQA,EAAKmB,OAQrDyG,kBAPwB5P,SAAQ6P,EAAAA,EAAAA,IAAmBpI,EAAQsB,IAQ3DkO,iBAAAA,EACAzL,eAAgB/D,EAAOgE,SAASC,MAAMF,kBAfxBhE,EAlH+B,IAmB7C,IAnB8C,aAClDsI,EADkD,WAElDC,EAAa,SAFqC,OAGlDC,EAHkD,SAIlDC,EAJkD,gBAKlDrB,EALkD,aAMlDsB,EANkD,aAOlDC,EAPkD,mBAQlDC,EARkD,gBASlDE,EATkD,iBAUlD8G,EAVkD,MAWlD7G,EAXkD,KAYlDvI,EAZkD,WAalDkP,EAbkD,gBAclDpK,EAdkD,kBAelD8C,EAfkD,eAgBlDpE,EAhBkD,aAiBlDnU,EAjBkD,iBAkBlD4f,GACI,EACJ,MAAM,aACJrO,EADI,gBAEJ6H,EAFI,kBAGJC,IACEjR,EAAAA,EAAAA,OAEI9H,GAAIoR,GAAWf,GAAQ,GACzBqP,GAAWC,EAAAA,EAAAA,IAAgBtP,IAEjChF,EAAAA,EAAAA,KAAU,KACJ+F,GAAU1R,IACR8Y,GAAcvH,EAAa,CAAEG,OAAAA,IAC7B6F,GAAiB8B,EAAkB,CAAEE,UAAW7H,OAErD,CAACA,EAAQH,EAAc8H,EAAmBrZ,EAAc8Y,EAAcvB,IAEzE,MAAMiC,GAAyB9X,EAAAA,EAAAA,KAAY,CAACiL,EAAgD8M,KACtF9I,GAAQ8I,IACV9M,EAAEM,kBACFmM,EAAgB,CACdM,cAAe/I,EAAKrQ,GACpBqZ,QAAS,EACT3S,OAAuB,UAAf0R,EAAyBkB,EAAAA,GAAAA,cAAkCA,EAAAA,GAAAA,wBAGtE,CAACjJ,EAAM+H,EAAYU,IAEhBtQ,GAAOC,EAAAA,EAAAA,KAEb,GAAK4H,EAmCL,OACE,0BAAK3P,UAAU,WAAWyN,KAAMyK,GAASpQ,EAAKE,MAAQ,WAAQvI,GAC5D,mBAAC,IAAD,CACEoZ,IAAKlJ,EAAKrQ,GACVsB,KAAM8W,EACN/H,KAAMA,EACN8E,gBAAiBA,EACjB9H,QAAS4J,EAAkBiC,OAAyB/Y,EACpDiV,UAAWuD,EACX9E,eAAgBA,IAElB,0BAAKnT,UAAU,QACZyU,EACC,0BAAKzU,UAAU,SACb,6BAAK8H,EAAK,mBAGZ,0BAAK9H,UAAU,SACb,yBAAIyN,IAAI,QAAQuR,IAAYtR,EAAAA,EAAAA,GAAWsR,KACtCrP,MAAAA,OAAA,EAAAA,EAAMmJ,aAAc,mBAAC,IAAD,MACpBnJ,EAAKuP,WAAa,mBAAC,IAAD,MAClBvP,EAAKmH,UAAY,mBAAC,IAAD,CAAUA,SAAUnH,EAAKmH,aAG7Ca,IAAYlD,IAAoBsK,KAtDlCpH,EACKC,EACL,mBAAC,IAAD,CAAc5X,UAAU,SAASqH,QAASsQ,IAE1C,2BAAM3X,UAAU,SAASyN,IAAI,QAAQkK,GAIrCI,IAAuBR,EAEvB,mBAAC,IAAD,CAAcvX,UAAU,SAASqH,QAASS,EAAK,cAI9C6H,EAID8H,EACK,mBAAC,IAAD,CAAcA,aAAcA,IAInC,2BAAMzX,UAAY,YAASmf,EAAAA,EAAAA,IAAaxP,EAAMkP,GAAc,SAAW,KACpEhH,GAAgBlI,EAAKiB,UAAY,2BAAM5Q,UAAU,UAAU2P,EAAKiB,UACjE,2BAAM5Q,UAAU,cAAcyN,IAAI,SAAQ2R,EAAAA,EAAAA,IAActX,EAAM6H,EAAMkP,EAAYD,UAXpF,U,mPChFJ,MA+GA,GAAejgB,EAAAA,EAAAA,KA/GoB,IAS7B,UAT8B,KAClC8Q,EADkC,KAElCE,EAFkC,MAGlC0P,EAHkC,aAIlCC,EAJkC,gBAKlC7K,EALkC,UAMlC8K,EANkC,aAOlCvgB,EAPkC,QAQlC2N,GACI,EAEJ,MAAM6S,GAAW3X,EAAAA,EAAAA,IAAyB,MACpCC,GAAOC,EAAAA,EAAAA,KACP0X,EAAY9P,IAAQ+P,EAAAA,EAAAA,IAAc/P,GAClCgQ,EAAgBlQ,IAAQmQ,EAAAA,EAAAA,IAAqBnQ,EAAKnQ,IAExD,SAASugB,EAAajf,GAA2D,UAAnCqb,EAAmC,uDAAT,QACtE,MAAM6D,EAAanQ,GAAQF,EACrBsQ,EAAeV,IAASS,MAAAA,GAAJ,UAAIA,EAAYnP,gBAAhB,aAAI,EAAsBoP,cAC9CC,EAAWD,MAAAA,OAAH,EAAGA,EAAcE,QACzBC,EAAcZ,EAEpB,GAAa,UAATrD,GAAqB+D,EAAzB,CAEA,GAAIX,IAAUa,EAAa,CACzB,GAAIF,GAAqB,UAAT/D,EACd,OAAOkE,EAAAA,EAAAA,IAAwBd,GAEjC,GAAa,UAATpD,EACF,MAAQ,QAAOoD,EAAM/f,YAIzB,OAAKmV,GAAoBgL,GAAcE,IAAiBG,OAAxD,GACSM,EAAAA,EAAAA,IAAkBN,EAAYlf,EAAMqb,KAM/CtR,EAAAA,EAAAA,KAAU,KACH6U,EAAShV,UACV+U,GACFC,EAAShV,QAAQ6V,QACjBb,EAAShV,QAAQ8V,YAAc,IAE/BC,EAAAA,EAAAA,GAASf,EAAShV,YAEnB,CAAC+U,IAEJ,MAAMiB,EAAYX,EAAa,MAAO,SAChCY,GAAejhB,EAAAA,EAAAA,GAASghB,GAAW,EAAO9gB,EAAAA,GAAAA,QAAwBV,GAClE0hB,EAAYb,EAAa,SAAU,SACnCc,GAAenhB,EAAAA,EAAAA,GAASkhB,GAAW,EAAOhhB,EAAAA,GAAAA,QAAwBV,GAClE4hB,EAAWD,GAAgBF,IAAgBpB,MAAAA,GAAhC,UAAgCA,EAAOlgB,iBAAvC,aAAgC,EAAkBC,SAEnE,IAAIiI,EAEJ,GAAIoN,EACFpN,EAAU,wBAAGrH,UAAU,oCAClB,GAAIyf,EACTpY,EAAU,wBAAGrH,UAAU,qCAClB,GAAI2f,EACTtY,EAAU,wBAAGrH,UAAU,2BAClB,GAAI4gB,EAEPvZ,EADEsZ,EAEA,4BACEnb,IAAKga,EACLxe,IAAK4f,EACL5gB,UAAU,eACV6gB,OAAK,EACLC,yBAAuB,EACvBC,UAAWxB,EACXyB,MAAI,EACJC,aAAW,IAIL,0BAAKjgB,IAAK4f,EAAU5gB,UAAU,eAAeoX,IAAI,UAExD,GAAIzH,EAAM,CACf,MAAMuR,GAAejC,EAAAA,EAAAA,IAAgBtP,GACrCtI,EAAU6Z,GAAeC,EAAAA,EAAAA,IAAgBD,EAAc,QAAKzhB,OACvD,GAAIgQ,EAAM,CACf,MAAMxC,GAAQ8G,EAAAA,EAAAA,GAAajM,EAAM2H,GACjCpI,EAAU4F,IAASkU,EAAAA,EAAAA,IAAgBlU,GAAO2C,EAAAA,EAAAA,IAASH,EAAKnQ,IAAM,EAAI,QAElE+H,EACE,0BAAKrH,UAAU,mBACb,mBAACohB,EAAA,EAAD,CAASlT,MAAM,WAKrB,MAAMf,GAAgBtM,EAAAA,EAAAA,GACpB,eACC,aAAWwgB,EAAAA,EAAAA,IAAgB1R,GAAQF,KACpCgF,GAAmB,iBACnBgL,GAAa,kBACbE,GAAiB,uBACflL,IAAoBmM,GAAa,YAGrC,OACE,0BAAK5gB,UAAWmN,EAAeR,QAASiU,EAAWjU,OAAUlN,GACvC,iBAAZ4H,GAAuBqG,EAAAA,EAAAA,GAAWrG,EAAS,CAAC,aAAeA,M,mCC7FzE,MAqNA,GAAe1I,EAAAA,EAAAA,KAAKwQ,EAAAA,EAAAA,KAClB,CAACC,EAAD,KAAmD,IAA1C,OAAEsB,EAAF,cAAUJ,GAAgC,EACjD,MAAM,gBAAEgR,EAAF,iBAAmB1C,GAAqBxP,EACxCO,GAAOE,EAAAA,EAAAA,IAAWT,EAAQsB,GAC1BmO,GAAaC,EAAAA,EAAAA,IAAiB1P,EAAQsB,GACtCjB,GAAOC,EAAAA,EAAAA,IAAWN,EAAQsB,GAC1B+D,GAAmBnE,GAAiBX,GAAQA,EAAKmB,QACjD,eAAEqC,GAAmB/D,EAAOgE,SAASC,OACrC,QAAEsF,EAAF,cAAWD,GAAkBtJ,EAAOmS,YAE1C,MAAO,CACLD,gBAAAA,EACA3R,KAAAA,EACAkP,WAAAA,EACApP,KAAAA,EACAgF,gBAAAA,EACAtB,eAAAA,EACAyL,iBAAAA,EACAjG,QAAAA,EACAD,cAAAA,KAnBcvJ,EArN2B,IAWzC,YAX0C,cAC9CmB,EAD8C,KAE9CX,EAF8C,WAG9CkP,EAH8C,KAI9CpP,EAJ8C,gBAK9CgF,EAL8C,gBAM9C6M,EAN8C,eAO9CnO,EAP8C,iBAQ9CyL,EAR8C,QAS9CjG,EAT8C,cAU9CD,GACI,EACJ,MAAM,aACJnI,EADI,gBAEJ6H,EAFI,iBAGJoJ,IACEpa,EAAAA,EAAAA,MAEEU,GAAOC,EAAAA,EAAAA,MAELzI,GAAIoR,GAAWf,GAAQ,IACvBrQ,GAAIwJ,GAAW2G,GAAQ,GACzBuP,EAAWrP,GAAOsP,EAAAA,EAAAA,IAAgBtP,GAASF,EAAOA,EAAKxC,MAAQ,GAC/DwU,GAAS9R,MAAAA,OAAA,EAAAA,EAAM8R,UAAUhS,MAAAA,OAAhB,EAAgBA,EAAMgS,SAAUC,EAAAA,EACzCC,GAAcC,EAAAA,EAAAA,GAAYjJ,GAC1BkJ,GAAoBD,EAAAA,EAAAA,GAAYlJ,IAC/BoJ,EAAmBC,IAAwB5Z,EAAAA,EAAAA,KAAS,GACrD6Z,EAAiBF,GACnB3O,GAAkB,EAAKrL,EAAKE,MAAQ,sBAAwB,kBAC5D,QAEGia,EAAmBC,IAAwB/Z,EAAAA,EAAAA,IAAS,GACrDga,EAAU1N,GAAmBgN,EAAO5f,QAAU,GAA2B,IAAtBogB,EACnDG,EAAS3N,GAAmBgN,EAAO5f,QAAU,GAAKogB,IAAsBR,EAAO5f,OAAS,GAG9F8I,EAAAA,EAAAA,KAAU,KACJkX,QAAqCpiB,IAAhBkiB,QAAyCliB,IAAZkZ,IACpDoJ,GAAqB,GACrBG,EAAqBP,MAEtB,CAAChJ,EAASgJ,EAAaE,KAG1BlX,EAAAA,EAAAA,KAAU,KACJsX,EAAoBR,EAAO5f,QAC7BqgB,EAAqB3f,KAAKC,IAAI,EAAGif,EAAO5f,OAAS,MAElD,CAACogB,EAAmBR,EAAO5f,UAE9B8I,EAAAA,EAAAA,KAAU,KACgB,yBAApB2W,GAA8C5Q,IAAWJ,GAC3DC,EAAa,CAAEG,OAAAA,MAEhB,CAACA,EAAQH,EAAc+Q,EAAiBhR,ICjG9B,SACb+R,EACAZ,EACAa,IAEA3X,EAAAA,EAAAA,KAAU,KACR8W,EAAOc,MAAMD,EAAcA,EARL,GAQuCpgB,SAASmd,IAClDmD,EAAAA,GAA2B,QAAOnD,EAAM/f,cAExDkjB,EAAAA,GAAmB,QAAOnD,EAAM/f,YAAaI,EAAAA,GAAAA,cAGhD,CAAC4iB,EAAcb,IDuFlBgB,CAAiB9S,EAAc8R,EAAQQ,GAEvC,MAAMS,GAA0BhiB,EAAAA,EAAAA,KAAY,KAC1C0X,EAAgB,CACdM,cAAehI,GAAU5H,EACzB6P,QAASsJ,EACTjc,OAAQsK,EAAgBsI,EAAAA,GAAAA,eAAmCA,EAAAA,GAAAA,kBAE5D,CAACR,EAAiB1H,EAAQ5H,EAAQmZ,EAAmB3R,IAElDqS,GAAqBjiB,EAAAA,EAAAA,KAAY,KAChCiP,GAEL6R,EAAiB,CAAEoB,WAAYjT,EAAKrQ,OACnC,CAACkiB,EAAkB7R,IAEhBkT,GAAsBniB,EAAAA,EAAAA,KAAY,KAClCyhB,IAGJJ,GAAqB,GACrBG,EAAqBD,EAAoB,MACxC,CAACA,EAAmBE,IAEjBW,GAAkBpiB,EAAAA,EAAAA,KAAY,KAC9B0hB,IAGJL,GAAqB,GACrBG,EAAqBD,EAAoB,MACxC,CAACA,EAAmBG,IAyBvB,IAtBAzX,EAAAA,EAAAA,KAAU,KACR,MAAMoY,EAAU1N,SAAS2N,cAA8B,kBACvD,GAAKD,EAIL,OAAOvW,EAAAA,EAAAA,IAAcuW,EAAS,CAC5BE,wBAAyB,8BACzBC,QAASzH,EAAAA,GAAe,CAAC9P,EAAGwX,IACtBA,IAAcC,EAAAA,GAAAA,OAChBP,KACO,GACEM,IAAcC,EAAAA,GAAAA,OACvBN,KACO,QAIPrjB,MAEL,CAACqjB,EAAiBD,KAEhBlT,IAASF,EACZ,OAiBF,SAAS4T,EAAYC,GACnB,MAAMjE,GAAS5K,GAAmBgN,EAAO5f,OAAS,EAAI4f,EAAOQ,QAAqBxiB,EAClF,OACE,mBAAC,EAAD,CACEoZ,IAAKoJ,EACLtS,KAAMA,EACNF,KAAMA,EACN4P,MAAOA,EACP5K,gBAAiBA,EACjB6K,aAAc6C,EACd5C,WAAY+D,EACZ3W,QAAS+V,IAwBf,MAAMa,EAAmB,QAAI,EAAA5T,GAAQF,SAAZ,aAAG,EAAgBqJ,WACtC0K,GAAqB7T,MAAAA,OAAH,EAAGA,EAAMuP,UAC3BpI,GAAQ,QAAI,EAAAnH,GAAQF,SAAZ,aAAG,EAAgBqH,SAEjC,OACE,0BAAK9W,WAAWa,EAAAA,EAAAA,GAAe,cAAeyP,GAAiB,QAAS7C,IAAK3F,EAAKE,MAAQ,WAAQvI,GAChG,0BAAKO,UAAU,iBAvDnB,WACE,KAAIyU,IAAoBgN,GAAUA,EAAO5f,QAAU,GAInD,OACE,0BAAK7B,UAAU,gBACZyhB,EAAOhc,KAAI,CAACge,EAAGrhB,IACd,2BAAMpC,UAAY,eAAaoC,IAAM6f,EAAoB,UAAY,SAgDtEyB,GACD,mBAACC,EAAA,EAAD,CAAYzJ,UAAW+H,EAAmBvL,KAAMsL,EAAgBhiB,UAAU,2BACvEqjB,IAGDlB,GACA,6BACElG,KAAK,SACLjc,UAAU,kBACV,aAAY8H,EAAK,oBACjB6E,QAASkW,KAGXT,GACA,6BACEnG,KAAK,SACLjc,UAAU,kBACV,aAAY8H,EAAK,QACjB6E,QAASmW,KAKf,0BAAK9iB,UAAU,OAAOyN,IAAK3F,EAAKE,MAAQ,MAAQ,QAC7CyM,EACC,0BAAKzU,UAAU,SACb,0BAAKA,UAAU,WAAWyN,IAAI,QAAQ3F,EAAK,mBAG7C,0BAAK9H,UAAU,SACb,0BAAKA,UAAU,WAAWyN,IAAI,QAAQuR,IAAYtR,EAAAA,EAAAA,GAAWsR,IAC5DuE,GAAuB,mBAACK,EAAA,EAAD,MACvBJ,IAAsB,mBAACK,EAAA,EAAD,CAAalX,QAASgW,IAC5C7L,IAAY,mBAACgN,EAAA,EAAD,CAAUhN,SAAUA,OAGnCrC,IA7DF9E,EAEA,0BAAK3P,UAAY,YAASmf,EAAAA,EAAAA,IAAaxP,EAAMkP,GAAc,SAAW,KACpE,2BAAM7e,UAAU,cAAcyN,IAAI,SAAQ2R,EAAAA,EAAAA,IAActX,EAAM6H,EAAMkP,EAAYD,KAMpF,2BAAM5e,UAAU,SAASyN,IAAI,SAC3B0C,EAAAA,EAAAA,IAAcV,GACV3H,EAAK,cAAD,WAAgB2H,EAAM0J,oBAAtB,UAAsC,EAAG,KAC7CrR,EAAK,UAAD,WAAY2H,EAAM0J,oBAAlB,UAAkC,EAAG,SAbnD,IAAwB,W,0FEjL1B,MAkBA,GAAexa,EAAAA,EAAAA,KAlB2B,IAIpC,cAJqC,SACzColB,EADyC,IAEzCve,EAFyC,UAGzCxF,GACI,EACJ,MAAMgkB,EAAY,WAAGC,EAAAA,EAAAA,MAAYC,0BAAf,iBAAG,EAAgCC,MAAMzgB,GAAMA,EAAEqgB,WAAaA,WAA9D,iBAAG,EAAsEK,kBAAzE,aAAG,EAAkF9kB,GACjGkJ,GAAYhJ,EAAAA,EAAAA,GAAU,WAAUwkB,KAAiBA,EAActkB,EAAAA,GAAAA,SAErE,OACE,0BACEM,WAAWa,EAAAA,EAAAA,GAAe,sBAAuBb,GACjDwF,IAAKA,EACLxE,IAAKwH,EACL4O,IAAI,S,gHCJV,MA8GA,GAAezY,EAAAA,EAAAA,KA9GmB,IAQ5B,IAR6B,OACjC2U,EADiC,QAEjC+Q,EAAU,WAFuB,OAGjCvb,EAHiC,MAIjCuW,EAJiC,WAKjCiF,EALiC,QAMjC/Q,EANiC,oBAOjCC,GACI,EACJ,MAAM,eACJ+Q,EADI,WAEJC,EAFI,mBAGJC,EAHI,sBAIJC,IACEtd,EAAAA,EAAAA,OAEGud,EAAgBC,IAAqBzc,EAAAA,EAAAA,IAA0B,SAC/DsJ,EAAaoT,IAAkB1c,EAAAA,EAAAA,IAAS,IAEzC2c,GAAepkB,EAAAA,EAAAA,KAAY,KAC/B,OAAQ2jB,GACN,IAAK,WACHE,EAAe,CAAED,WAAAA,EAAYS,OAAQJ,EAAgBlT,YAAAA,IACrDiT,IACA,MACF,IAAK,OACHF,EAAW,CAAE1b,OAAAA,EAAQic,OAAQJ,EAAgBlT,YAAAA,IAC7C,MACF,IAAK,QACHgT,EAAmB,CACjB3b,OAAAA,EAAQuW,MAAAA,EAAO0F,OAAQJ,EAAgBlT,YAAAA,IAI7C8B,MACC,CACD9B,EACAiT,EACAJ,EACAjF,EACA9L,EACAgR,EACAI,EACA7b,EACA2b,EACAD,EACAH,IAGIW,GAAqBtkB,EAAAA,EAAAA,KAAamD,IACtC+gB,EAAkB/gB,KACjB,IAEGohB,GAA0BvkB,EAAAA,EAAAA,KAAaiL,IAC3CkZ,EAAelZ,EAAEyQ,OAAOvY,SACvB,IAEGiE,GAAOC,EAAAA,EAAAA,KAEPmd,GAA8Dlb,EAAAA,EAAAA,KAAQ,IAAM,CAChF,CAAEnG,MAAO,OAAQmO,MAAOlK,EAAK,2BAC7B,CAAEjE,MAAO,WAAYmO,MAAOlK,EAAK,+BACjC,CAAEjE,MAAO,cAAemO,MAAOlK,EAAK,kCACpC,CAAEjE,MAAO,aAAcmO,MAAOlK,EAAK,kCACnC,CAAEjE,MAAO,YAAamO,MAAOlK,EAAK,+BAClC,CAAEjE,MAAO,eAAgBmO,MAAO,iBAChC,CAAEnO,MAAO,kBAAmBmO,MAAO,oBACnC,CAAEnO,MAAO,QAASmO,MAAOlK,EAAK,8BAC7B,CAACA,IAEJ,GACe,aAAZuc,IAA2BC,GACZ,SAAZD,IAAuBvb,GACX,UAAZub,KAAyBvb,IAAWuW,GAExC,OAGF,MAAMpS,EACFnF,EADsB,aAAZuc,EACL,2BACA,qBAET,OACE,mBAAC,IAAD,CACE/Q,OAAQA,EACRC,QAASA,EACT4R,QAAS7R,EAASwR,OAAerlB,EACjC+T,oBAAqBA,EACrBxT,UAAU,SACViN,MAAOA,GAEP,mBAAC,IAAD,CACEyJ,KAAK,iBACL0O,QAASF,EACT/I,SAAU6I,EACVK,SAAUV,IAEZ,mBAAC,IAAD,CACE3S,MAAOlK,EAAK,iCACZjE,MAAO4N,EACP0K,SAAU8I,IAEZ,mBAAC,IAAD,CAAQ/W,MAAM,SAASlO,UAAU,wBAAwB2U,QAAM,EAAChI,QAASmY,GACtEhd,EAAK,sBAER,mBAAC,IAAD,CAAQ9H,UAAU,wBAAwB2U,QAAM,EAAChI,QAAS4G,GAAUzL,EAAK,gB,gPCnF/E,MA2RA,GAAenJ,EAAAA,EAAAA,KA3RO,IAgBH,IAhBqF,QACtGE,EADsG,KAEtG+B,EAFsG,UAGtG0kB,EAHsG,MAItGrY,EAJsG,UAKtGjN,EALsG,SAMtGie,EANsG,cAOtGsH,EAPsG,gBAQtG9Q,EARsG,WAStG+Q,EATsG,oBAUtG5Q,EAVsG,QAWtGjI,EAXsG,YAYtG8Y,EAZsG,cAatGC,EAbsG,oBActGC,EAdsG,qBAetGC,GACiB,EACjB,MAAM,eAAEC,EAAF,iBAAkBrE,IAAqBpa,EAAAA,EAAAA,MAEvC5B,GAAMqC,EAAAA,EAAAA,IAAuB,MAC7BC,GAAOC,EAAAA,EAAAA,KAEP1I,EAAkB,UAASR,EAAQS,KACnCwmB,EAAmB,kBAAiBjnB,EAAQS,KAE5CmW,GAAiBC,EAAAA,EAAAA,IAAkBlQ,EAAKoP,GAExC1V,GAAe6mB,EAAAA,EAAAA,GAAalnB,GAC5BU,GAAiBC,EAAAA,EAAAA,GAAU,GAAEH,YAA0BoW,EAAgB/V,EAAAA,GAAAA,SAEvEsmB,EAAavQ,IAAmB6P,EAChCW,GAAazmB,EAAAA,EAAAA,GAASX,EAAQqnB,UAAY7mB,GAAiB2mB,IAC1DG,EAAgBC,EAAYC,IAAgBlmB,EAAAA,EAAAA,GAAQwH,QAAQse,IAC7DK,EAAgBH,GAAkBH,EAClC/F,EAAUphB,EAAQohB,SAAWsG,EAAAA,GAC7BC,EAAgB3nB,EAAQ2nB,cACxB7F,GAAenhB,EAAAA,EAAAA,GAASygB,GAAW5gB,GAAiB2mB,EAAYtmB,EAAAA,GAAAA,SAChE+mB,EAAe9e,QAAQsY,GAAWU,GAAgBqF,GAClDU,GAAmB7nB,EAAQ8nB,UAC3BC,IAAYhB,GAAwBc,IAElCvb,qBAAsB0b,KAAgCxb,EAAAA,EAAAA,GAC5D1D,QAAQpI,GAAkB+mB,QAC1B7mB,OACAA,EACA,SAGI,kBACJqnB,GADI,oBACeC,GADf,wBAEJC,GAFI,kBAEqBC,GAFrB,uBAGJC,GAHI,sBAGoBC,KACtBC,EAAAA,EAAAA,GAAuB5hB,GAErB6hB,IAAoB3mB,EAAAA,EAAAA,KAAY,IAAM8E,EAAIgF,SAAS,IAEnD8c,IAAiB5mB,EAAAA,EAAAA,KACrB,IAAM8E,EAAIgF,QAAS+c,QAAQ,kCAC3B,IAGIC,IAAiB9mB,EAAAA,EAAAA,KACrB,IAAM8E,EAAIgF,QAASwY,cAAc,kCACjC,KAGI,UACJyE,GADI,UACOC,GADP,iBACkBC,GADlB,iBACoCC,GAAkB9mB,MAAO+mB,KAC/DC,EAAAA,EAAAA,GACFf,GACAM,GACAC,GACAE,KAIF7c,EAAAA,EAAAA,KAAU,KACHqb,GACHK,MAED,CAACA,EAAcL,KAElBrb,EAAAA,EAAAA,KAAU,KACR,IAAKsV,IAAYza,EAAIgF,QAAS,OAC9B,MAAMhD,EAAQhC,EAAIgF,QAAQwY,cAAc,SACnCxb,IACDif,GACFlG,EAAAA,EAAAA,GAAS/Y,GAETA,EAAM6Y,WAEP,CAACJ,EAASwG,KAEb9b,EAAAA,EAAAA,KAAU,KACH8K,GAAgByR,OACpB,CAACA,GAAwBzR,IAE5B,MAcMsS,IAAoBrnB,EAAAA,EAAAA,KAAaiL,IACrCA,EAAEM,kBACFN,EAAEoQ,iBAEF4J,EAAqB9mB,KACpB,CAAC8mB,EAAqB9mB,IAEnBmpB,IAA4BtnB,EAAAA,EAAAA,KAAY,KAC5CilB,EAAqB9mB,KACpB,CAAC8mB,EAAqB9mB,IAEnBopB,IAAsBvnB,EAAAA,EAAAA,KAAY,KACtCglB,EAAe7mB,KACd,CAAC6mB,EAAe7mB,IAEbqpB,IAAoBxnB,EAAAA,EAAAA,KAAY,KACpC+kB,EAAa5mB,KACZ,CAAC4mB,EAAa5mB,IAEXspB,IAAkBznB,EAAAA,EAAAA,KAAY,KAClCiM,MAAAA,GAAAA,EAAUsR,GAAU,KACnB,CAACA,EAAUtR,IAERyb,IAAsB1nB,EAAAA,EAAAA,KAAY,KACtCiM,MAAAA,GAAAA,EAAUsR,OAAUxe,GAAW,KAC9B,CAACwe,EAAUtR,IAER0b,IAAgB3nB,EAAAA,EAAAA,KAAY,KAChCmlB,EAAe,CAAEyC,eAAgBzpB,EAAQypB,mBACxC,CAACzC,EAAgBhnB,IAEd0pB,IAAyB9M,EAAAA,IAAgBkK,EAEzCxY,IAAgBtM,EAAAA,EAAAA,GACpB,gBACA8L,GAAW,cACX6Z,GAAiB,eACjBV,EACA9lB,GAGIc,IAAS5B,GAAiBonB,GAAkBG,EAA8D,GAA7C,0BAAyBvnB,OAEtFspB,IAAmBxe,EAAAA,EAAAA,KAAQ,KAC/B,MAAMkU,EAAqB,GAC3B,OAAIqH,GAAiBiB,IAEjBd,GACFxH,EAAM5Q,KACJ,mBAAC,IAAD,CAAUsE,KAAK,WAAWjF,QAASsb,IAChCngB,EAAK,kCAKR2d,GACFvH,EAAM5Q,KACJ,mBAAC,IAAD,CAAUsE,KAAK,WAAWjF,QAASub,IAChCpgB,EAAK,8BAKP8e,IAAYja,IACV8H,GACHyJ,EAAM5Q,KAAK,mBAAC,IAAD,CAAUX,QAASwb,GAAiBvW,KAAK,SAAS9J,EAAK,sBAEpEoW,EAAM5Q,KACJ,mBAAC,IAAD,CAAUX,QAASyb,GAAqBxW,KAAK,YAC1C9J,EAAK2M,EAAkB,cAAgB,sBAK1C+Q,GACFtH,EAAM5Q,KACJ,mBAAC,IAAD,CAAUX,QAAS0b,GAAezW,KAAK,YACpC9J,EAAK,qBAIR6d,GACFzH,EAAM5Q,KACJ,mBAAC,IAAD,CAAUsE,KAAK,SAASjF,QAASqb,IAC9BlgB,EAAK,uBAvC+BoW,IA4C1C,CACDsH,EAAY0C,GAAmBF,GAA2BC,GAAqBI,GAAeF,GAC9FC,GAAqBxB,GAAUnS,EAAiB3M,EAAM2d,EAAaE,EAAqBD,EAAe/Y,EACvG4Y,EAAeiB,IAGjB,OACE,0BACEhhB,IAAKA,EACLxF,UAAWmN,GACXF,MAAOA,IAAUpO,MAAAA,OAAL,EAAKA,EAAS4pB,OAC1B3nB,MAAOA,GACP,kBAAiBjC,EAAQS,GACzBopB,YA3GqB/c,KACvBgd,EAAAA,EAAAA,GAAoChd,GACpCqb,GAAwBrb,IA0GtBgB,QArHgB,KACdma,KACAF,GACFpF,EAAiB,CAAEoH,eAAgB,qBAGrCjc,MAAAA,GAAAA,EAAUsR,KAgHRnE,cAAemN,KAEbX,IAAkBG,GAElB,0BAAKzlB,IAAKzB,EAAgBS,UAAW6mB,KAEtC5G,GACC,4BACEjgB,UAAW6mB,GACX7lB,IAAK2f,EACLI,SAAU0F,EACVzF,MAAI,EACJC,aAAW,EACXH,yBAAuB,EACvBD,OAAK,IAGRmF,GAAcC,GACb,mBAAC,IAAD,CACEtmB,OAAQsmB,EACR4C,MAAI,EACJjoB,KAAMA,EACNkoB,eAAa,EACb5nB,OAAQklB,IAGXQ,IACC,0BACE5mB,UAAU,kBAEV,wBAAGA,UAAU,qBAGhB0mB,KAAqBE,IACpB,0BAAK5mB,UAAU,mBACb,wBAAGA,UAAU,kBAGhBuoB,IACC,mBAAC,IAAD,CACEvoB,UAAU,wBACVkO,MAAM,OACN7D,OAAK,EACLsC,QAASob,IAET,wBAAG/nB,UAAU,gBAGhB2H,QAAQ6gB,GAAiB3mB,cAAmCpC,IAAxBsnB,IACnC,mBAAC,IAAD,CACEzT,OAAQwT,GACRa,iBAAkBA,GAClBC,iBAAkBA,GAClBH,UAAWA,GACXC,UAAWA,GACX5mB,MAAO+mB,GACP7nB,UAAU,uBACV+oB,WAAS,EACTxV,QAAS2T,GACT1T,oBAAqB2T,IAEpBqB,S,kHC9SX,MAkBA,GAAe7pB,EAAAA,EAAAA,KAAKwQ,EAAAA,EAAAA,KAClB,CAACC,EAAD,KAA0C,IAAjC,aAAEqI,GAA+B,EACxC,OAAKA,EAAa/G,OAMX,CAAEsY,YAFUnZ,EAAAA,EAAAA,IAAWT,EAAQqI,EAAa/G,SAH1C,KAHOvB,EAlB4B,IAAkC,IAAjC,aAAEsI,EAAF,WAAgBuR,GAAiB,EAChF,MAAMlhB,GAAOC,EAAAA,EAAAA,KACPkhB,EAAiBD,IAAeA,EAAWlY,SAAU8B,EAAAA,EAAAA,IAAuBoW,GAC5E3hB,EAAUS,EAAK2P,EAAaoE,QAE/BqN,QAAQ,SAAU,IAClBA,QAAQ,UAAWzR,EAAagR,OAAOU,OAE1C,OACE,wBAAGnpB,UAAU,gBAAgByN,IAAK3F,EAAKE,MAAQ,MAAQ,QACpDihB,GACC,2BAAMjpB,UAAU,cAAcyN,IAAI,SAAQC,EAAAA,EAAAA,GAAWub,IAEvD,mBAAC,IAAD,CAAc5hB,QAASA,U,gDC9B7B,MAAM+hB,EAAgB,CAAErc,OAAQ,g5BAShC,EAPyB,IAGrB,2BAAM/M,UAAU,eAAe8M,wBAAyBsc,K,yJCa5D,MAyGA,GAAezqB,EAAAA,EAAAA,KA3Fe,IAExB,IAFyB,QAC7BkH,EAD6B,YACpBC,EADoB,YACP2T,EADO,oBACM7E,EADN,eAC2ByU,GACpD,EACJ,MAAMvhB,GAAOC,EAAAA,EAAAA,KAEb,IAAIuhB,GAAgDC,EAAAA,EAAAA,IAAkB1jB,GAEtE,IAAKyjB,EAAU,CACb,MAAM/X,GAAOiY,EAAAA,EAAAA,IAAsB3jB,GACnC,GAAI0L,EAAM,CACR,MAAM,IAAEkY,EAAF,OAAOC,GAAWnY,EAExB+X,EAAW,CACTK,SAAUD,EAAOR,QAAQ,QAAS,IAClCO,IAAKA,EAAIlM,SAAS,OAASkM,EAAMA,EAAIlM,SAAS,KAAQ,UAASkM,IAAS,UAASA,IACjFG,sBAAsBC,EAAAA,EAAAA,IAAehkB,KAAa4jB,GAC9CK,EAAAA,EAAAA,GAAqBhiB,EAAMjC,OAASpG,OAAWA,EA9BnC,UA+BZA,IAKV,MAAMsqB,GAAqBrpB,EAAAA,EAAAA,KAAY,KACrC2oB,EAAexjB,EAAQvG,GAAIuG,EAAQiD,UAClC,CAACugB,EAAgBxjB,EAAQvG,GAAIuG,EAAQiD,SAExC,IAAKwgB,EACH,OAGF,MAAM,SACJK,EADI,IAEJF,EAFI,WAGJO,EAHI,MAIJ/c,EAJI,YAKJwE,EALI,qBAMJmY,EANI,MAOJvK,EAPI,MAQJ7X,GACE8hB,EAEEW,GAAwBnkB,GAAe2L,IAAeyY,EAAAA,EAAAA,GAASzY,EAvD/C,KAyDhBzR,GAAYa,EAAAA,EAAAA,GAChB,uBACEwe,IAAU7X,GAAU,iBAGxB,OACE,0BACExH,UAAWA,EACX,gBAAe2pB,GAAYK,GAAY,GACvCvc,IAAK3F,EAAKE,MAAQ,WAAQvI,GAEzB4f,GACC,mBAAC,IAAD,CAAOxZ,QAASA,EAAS4T,YAAaA,EAAa7E,oBAAqBA,IAE1E,0BAAK5U,UAAU,WACb,mBAAC,IAAD,CAAMgI,MAAOF,EAAKE,MAAOhI,UAAU,aAAa2M,QAASod,IACtDrc,EAAAA,EAAAA,GAAWT,GAAS0c,GAAYK,KAEjCC,GAAwBL,IACxB,mBAAC,IAAD,CAAM5hB,MAAOF,EAAKE,MAAOhI,UAAU,mBAAmB2M,QAASod,GAC5DH,GAAyBK,IAAwBvc,EAAAA,EAAAA,GAAWuc,IAGjE,mBAAC,IAAD,CACER,IAAKA,EACLzpB,UAAU,YACVkR,KAAK,GACLlJ,MAAOF,EAAKE,OAEXyhB,EAAIP,QAAQ,UAAW,KAAOc,GAEhClkB,GAAe,0BAAK9F,UAAU,gBAAe0N,EAAAA,EAAAA,GAAW5H,KAE1DA,GACC,0BAAK9F,UAAU,gBACb,mBAAC,IAAD,CACEA,UAAU,OACV2M,QAASod,EACT/hB,MAAOF,EAAKE,QAEX4F,EAAAA,EAAAA,IAAoB9F,EAAqB,IAAfjC,EAAQI,a,gNChHxC,MAAMkkB,EAA2B,sBAC3BC,EAAMC,SAASC,iBAAiBjV,SAASkV,iBAAiBC,SAAU,IACpEC,EAA4B,IAE5BC,EAAyB,CAAE9oB,MAAO,IAAKE,OAAQ,KAC/C6oB,EAA+B,CAAE/oB,MAAO,IAAKE,OAAQ,KACrD8oB,EAAkB,sBAEzBC,EAA0C,CAAEjpB,MAAO,IAAKE,OAAQ,KAMtE,IAAIgpB,EACAC,EACAC,EAmCG,SAASC,EACdC,EACAC,EACAC,EACAllB,GAEA,MAAMmlB,EAAkBF,GAAeC,EAAiB,MAAQ,EAC1DE,EAxCR,SAA+BJ,EAAyBhlB,GACtD,MAAMqlB,EAAkBL,EAPQ,GADJ,GAS5B,IAAKjmB,EAAAA,GACH,OAAOsmB,EAGT,MAAQ3pB,MAAO4pB,GAAgBC,EAAAA,EAAAA,MAsB/B,OAnBKX,IACHA,EAAoBvoB,KAAK2H,IAhBK,GAkB5BshB,EAAcpB,EArBqC,MAwBlDW,IACHA,EAAiBxoB,KAAK2H,IAvBI,GAyBxBshB,EAAcpB,EA1B0B,IA6BvCY,IACHA,EAAyBzoB,KAAK2H,IA7BJ,GA+BxBshB,EAAcpB,EAjCqC,MAqChDc,EACHJ,EACC5kB,EAAY8kB,EAAyBD,EAUhBW,CAAsBR,EAAgBhlB,GAAamlB,EAE7E,OAAOC,EAAoBlB,EAc7B,SAASuB,EAAT,GAgBkB,IAhB0B,MAC1C/pB,EAD0C,OAE1CE,EAF0C,eAG1CopB,EAH0C,YAI1CC,EAJ0C,eAK1CC,EAL0C,MAM1CpR,EAN0C,UAO1C9T,GASgB,EAChB,MAAM0lB,EAAc9pB,EAASF,EACvBiqB,EAAiBZ,EAAkBC,EAAgBC,EAAaC,EAAgBllB,GAChF4lB,EA9BR,SAA4B9R,EAAiB4R,GAC3C,OACE5R,GAAS4R,GACNA,GAAe,KAAQA,GAAe,KAElC,GAAKxB,EAGP,GAAKA,EAsBY2B,CAAmB/R,EAAO4R,GAC5CI,EAAahS,EAAQzX,KAAKC,IA3FL,IA2FwBZ,GAASA,EAG5D,OAAOqqB,EAAoBJ,EAAgBC,EAAiBE,EAFxChS,EAAQlY,GAAUkqB,EAAapqB,GAASE,GAKvD,SAASoqB,EAAkCC,EAAqBlM,GACrE,MAAMmM,EAAMznB,OAAOC,WAAWulB,IACtBvoB,MAAO4pB,EAAa1pB,OAAQuqB,GAAiBZ,EAAAA,EAAAA,MACrD,IAAIa,EAAoBrM,GAAWmM,EAAIlnB,QAAU,GAAK,KAItD,OAHIinB,IAAe1Q,EAAAA,KACjB6Q,EAAoBF,EAAIlnB,QAAU,GAAK,MAElC,CACLtD,MAAO4pB,EACP1pB,OAAQuqB,EAAeC,EAAoBlC,GAIxC,SAASmC,EACdlN,EACA6L,EACAC,EACAC,EACAllB,GAEA,MAAM,MAAEtE,EAAF,OAASE,IAAW0qB,EAAAA,EAAAA,IAAyBnN,IAAUwL,EAE7D,OAAOc,EAAmC,CACxC/pB,MAAAA,EACAE,OAAAA,EACAopB,eAAAA,EACAC,YAAAA,EACAC,eAAAA,EACAllB,UAAAA,IAIG,SAASumB,EACdjlB,EACA0jB,EACAC,EACAjlB,GAEA,MAAM,MAAEtE,EAAF,OAASE,IAAW4qB,EAAAA,EAAAA,IAAmBllB,IAAUqjB,EAEvD,OAAOc,EAAmC,CACxC/pB,MAAAA,EACAE,OAAAA,EACAopB,eAAAA,EACAC,YAAAA,EACAnR,MAAOxS,EAAMwS,MACb9T,UAAAA,IAIG,SAASymB,IACd,MAAO,CACL/qB,MAAO,EAAIwoB,EACXtoB,OAAQ,EAAIsoB,GAIT,SAASjT,EAA+BtC,GAC7C,OAAIA,EACK,CACLjT,MAAO,EAAIwoB,EACXtoB,OAAQ,EAAIsoB,GAIT,CACLxoB,MAAO,MAAQwoB,EACftoB,OAAQ,MAAQsoB,GAIb,SAASwC,EAAqB/tB,GACnC,MAAM,MAAE+C,GAAU/C,EAClB,IAAI,OAAEiD,GAAWjD,EAGbA,EAAQS,KAAOsrB,IACjB9oB,EAASF,GAGX,MAAMgqB,EAAe9pB,GAAUF,GAAUE,EAASF,EAC5CirB,EAAYzC,GAChBnlB,EAAAA,GACI6nB,EAAAA,GACAC,EAAAA,IAEAC,EAAmBpB,EAAciB,EAAYjB,EAAciB,EAEjE,OAAIjB,GAAeoB,EAAmBH,EAC7B,CACLjrB,MAAOW,KAAK8H,MAAMwiB,EAAYjB,GAC9B9pB,OAAQ+qB,GAIL,CACLjrB,MAAOirB,EACP/qB,OAAQkrB,GAIL,SAASC,EAAT,EAC6Bd,GACnB,IADf,MAAEvqB,EAAF,OAASE,GACM,EADwCme,EACxC,wDACf,MAAQre,MAAOiqB,EAAgB/pB,OAAQgqB,GAAoBI,EAAkCC,EAAYlM,GAEzG,OAAOgM,EAAoBJ,EAAgBC,EAAiBlqB,EAAOE,GAG9D,SAASmqB,EACdJ,EACAC,EACAE,EACAkB,GAEA,MAAMtB,EAAcsB,EAAclB,EAC5BmB,EAAkB5qB,KAAK2H,IAAI8hB,EAAYH,GAG7C,OAFyBtpB,KAAK8H,MAAM8iB,EAAkBvB,GAE/BE,EACd,CACLlqB,MAAOW,KAAK8H,MAAMyhB,EAAkBF,GACpC9pB,OAAQgqB,GAIL,CACLlqB,MAAOurB,EACPrrB,OAAQS,KAAK8H,MAAM8iB,EAAkBvB,M,sECtOzC,MAQA,GAAejtB,EAAAA,EAAAA,KAR6BC,IAC1C,MAAM,OAAE0U,GAAW1U,EACbwuB,GAAkBC,EAAAA,EAAAA,GAAgBC,EAAAA,GAAAA,MAAe,mBAAoBha,GAG3E,OAAO8Z,EAAkB,mBAACA,EAAoBxuB,QAAYa,M,uICVrD,IAAK8tB,G,SAAAA,GAAAA,EAAAA,EAAAA,KAAAA,GAAAA,OAAAA,EAAAA,EAAAA,QAAAA,GAAAA,UAAAA,EAAAA,EAAAA,KAAAA,GAAAA,O,CAAAA,IAAAA,EAAAA,K,4RCgBZ,MAyDA,GAAe5uB,EAAAA,EAAAA,KAzDa,IAAiC,IAAhC,KAAE8Q,EAAF,SAAQ+d,EAAR,QAAkB1d,GAAc,EAC3D,MAAM2d,EAAU9lB,QACd8H,EAAKie,aAAeje,EAAKke,qBAAuBle,EAAKme,eAAiBJ,GAAY/d,EAAKoe,sBAEnFC,EAAWnmB,QAAQ8H,EAAKie,aAAeje,EAAKme,eAC5C5tB,GAAYa,EAAAA,EAAAA,GAChB,QACAiP,GAAW,SACVge,GAAYN,GAAY,SACzBM,GAAY,UAyCd,OACE,mBAACC,EAAA,EAAD,CAAgBC,UAAQ,EAAChuB,UAAU,mBAAmBsT,OAAQma,GAvChE,WACE,MAAMQ,EAAyBxe,EAAKoe,sBAClC,0BAAK7tB,WAAWa,EAAAA,EAAAA,GAAe,iBAAkBiP,GAAW,UAC1D,wBAAG9P,UAAU,gBAIXkuB,EAAwBze,EAAKke,qBACjC,0BAAK3tB,UAAU,iBACb,wBAAGA,UAAU,kBAIXmuB,EAAsB1e,EAAKme,eAAiBne,EAAKie,YACrD,0BAAK1tB,UAAWA,IACZyP,EAAKme,gBAAiBQ,EAAAA,EAAAA,IAAqB3e,EAAKie,mBAElDjuB,EAQE4uB,EAAW,CAACJ,EAAwBC,EAAuBC,EAN3CX,IAAaW,IAAuBD,IAA0BD,GAClF,0BAAKjuB,UAAWA,GACd,wBAAGA,UAAU,uBAImFsuB,OAAO3mB,SAE3G,GAAwB,IAApB0mB,EAASxsB,OAEb,OAAwB,IAApBwsB,EAASxsB,OAAqBwsB,EAAS,GAGzC,0BAAKruB,UAAU,iBACZquB,GAOFE,O,eCzDP,MAoBA,GAAe5vB,EAAAA,EAAAA,KApBsB,IAG/B,IAHgC,WACpCyH,EADoC,SAEpCkd,GACI,EACJ,OACE,0BAAKtjB,WAAWa,EAAAA,EAAAA,GACd,iBACAyiB,GAAY,SACZld,IAAenB,EAAAA,IAA2B,aAG1C,0BAAKjF,UAAU,aACb,+BACA,+BACA,oC,oCC2WR,SAAerB,EAAAA,EAAAA,KAAKwQ,EAAAA,EAAAA,KAClB,CAACC,EAAD,KAAoC,UAA3B,OAAEtG,GAAyB,EAClC,MAAM2G,GAAOC,EAAAA,EAAAA,IAAWN,EAAQtG,GAChC,IAAK2G,EACH,MAAO,GAGT,MAAM,SAAE+e,EAAF,iBAAYC,EAAZ,WAA8BC,GAAejf,EAAKkf,aAAe,GACjEC,EAAoBJ,GAAW3e,EAAAA,EAAAA,IAAWT,EAAQof,QAAY/uB,EAC9DovB,EAAoBpf,EAAKkf,aAAcG,EAAAA,EAAAA,IAAiBrf,EAAKkf,kBAAelvB,EAC5EsvB,EAAsBF,GAAqBJ,GAC7CO,EAAAA,EAAAA,IAAkB5f,EAAQK,EAAKnQ,GAAImvB,QACnChvB,GACIwvB,cAAeC,EAAqBC,aAAcC,GAAuBP,GAAqB,GAChGQ,GAAoB/c,EAAAA,EAAAA,IAAqB7C,IAE7C3G,OAAQwmB,EACRC,SAAUC,EACVvT,KAAMwT,IACJC,EAAAA,EAAAA,IAAyBtgB,IAAW,GAClChJ,EAAa0C,IAAWwmB,GAAiBE,IAAoBG,EAAAA,GAEnE,MAAO,CACLlgB,KAAAA,EACAK,SAASC,EAAAA,EAAAA,IAAkBN,GAAMO,EAAAA,EAAAA,IAAqBZ,IAASa,EAAAA,EAAAA,IAAuBb,IACtFwf,kBAAAA,EACAM,oBAAAA,EACAE,mBAAAA,EACAL,oBAAAA,EACAa,OAAOC,EAAAA,EAAAA,IAAYzgB,EAAQtG,EAAQ6mB,EAAAA,IACnCxc,eAAgB/D,EAAOgE,SAASC,MAAMF,eACtC/M,WAAAA,EACA0pB,cAAe1pB,GAAkC,WAApBqpB,EAC7BM,kBAAkB,UAAA3gB,EAAO4gB,YAAYC,kBAAnB,eAA+BpuB,SAAU,GAAK,EAChE7C,aAAcoQ,EAAOpQ,gBACjB0vB,GAAcjf,EAAKkf,aAAe,CACpCuB,2BAA2BC,EAAAA,EAAAA,IAAqB/gB,EAAQK,EAAKkf,iBAE3DU,GAAqB,CACvB1f,MAAME,EAAAA,EAAAA,IAAWT,EAAQigB,GACzBxQ,YAAYC,EAAAA,EAAAA,IAAiB1P,EAAQigB,OAxCzBlgB,EAxSoB,IAwBlC,IAxBmC,MACvCrO,EADuC,OAEvCgI,EAFuC,SAGvCsnB,EAHuC,UAIvCC,EAJuC,cAKvCC,EALuC,SAMvC9C,EANuC,oBAOvC5Y,EAPuC,KAQvCnF,EARuC,QASvCK,EATuC,KAUvCH,EAVuC,WAWvCkP,EAXuC,oBAYvCqQ,EAZuC,kBAavCN,EAbuC,0BAcvCsB,EAduC,oBAevCnB,EAfuC,mBAgBvCK,EAhBuC,MAiBvCQ,EAjBuC,eAkBvCzc,EAlBuC,WAmBvC/M,EAnBuC,cAoBvC0pB,EApBuC,gBAqBvCC,EArBuC,aAsBvC/wB,EAtBuC,YAuBvCuxB,GACI,EACJ,MAAM,SACJC,EADI,iBAEJC,IACErpB,EAAAA,EAAAA,MAGE5B,IAAMqC,EAAAA,EAAAA,IAAuB,OAE5B6oB,GAAmBC,GAAiBC,KAAoBzwB,EAAAA,EAAAA,MACxD0wB,GAAuBC,GAAqBC,KAAwB5wB,EAAAA,EAAAA,MACpE6wB,GAAmBC,GAAiBC,KAAoB/wB,EAAAA,EAAAA,MACxDgxB,GAAyBC,GAAuBC,KAA2BlxB,EAAAA,EAAAA,MAC3EmxB,GAA6BC,GAA2BC,KAA+BrxB,EAAAA,EAAAA,MACvFsxB,GAAyBC,GAAuBC,KAA2BxxB,EAAAA,EAAAA,MAE5E,YAAEwuB,GAAF,aAAelX,IAAiBhI,GAAQ,GACxCmiB,GAAWjD,KAAekD,EAAAA,EAAAA,IAAgBlD,KAEhDmD,EAAAA,EAAAA,GAAiBhpB,EAAQ8oB,GAAWjD,GAAYF,sBAAmBhvB,EAAWsvB,GAE9E,MAAMgD,GAAiBpD,MAAgBqD,EAAAA,EAAAA,IAAkBrD,KACrDvY,EAAAA,EAAAA,IAA4BuY,SAC5BlvB,EACEia,IAAela,EAAAA,EAAAA,GAASmvB,IAAcrmB,EAAAA,EAAAA,IAAoBqmB,GAAa,cAAWlvB,GAClFwyB,GAAetqB,QAAQgnB,KAAeuD,EAAAA,EAAAA,IAAqBvD,KAE3DwD,IAAoBnoB,EAAAA,EAAAA,KAAQ,KAChC,IAAKklB,EACH,OAIF,MAAMkD,GAAYnO,EAAAA,EAAAA,MAAYoO,MAAMC,KACpC,OAAOpD,EAAoBzpB,KAAKiL,GAAW0hB,EAAU1hB,KAAS4d,OAAgB3mB,WAC7E,CAACunB,KAGJ3kB,EAAAA,EAAAA,KAAgB,KACd,MAAMwY,EAAUvd,GAAIgF,QAEpB,GAAuB,IAAnB2I,GAAyB4P,EAA7B,CAKA,GAAIuN,IAAkB/C,EAAmBgF,QACvCxP,EAAQjiB,MAAM0xB,QAAU,KAExBC,EAAAA,EAAAA,KAAQ,KACN1P,EAAQ2P,UAAU/xB,IAAI,mBACtBoiB,EAAQjiB,MAAM0xB,QAAU,WAErB,IAAIlC,IAAkB/C,EAAmBoF,KAQ9C,OAPA5P,EAAQjiB,MAAM8xB,UAAa,kBAA8B,KAAZvC,UAE7CoC,EAAAA,EAAAA,KAAQ,KACN1P,EAAQ2P,UAAU/xB,IAAI,qBACtBoiB,EAAQjiB,MAAM8xB,UAAY,MAM9BxV,YAAW,MACTqV,EAAAA,EAAAA,KAAQ,KACN1P,EAAQ2P,UAAUG,OAAO,kBAAmB,qBAC5C9P,EAAQjiB,MAAM0xB,QAAU,GACxBzP,EAAQjiB,MAAM8xB,UAAY,QA9FP,IAgGCE,EAAAA,OACvB,CAAC3f,EAAgBkd,EAAWC,IAE/B,MAAM7Z,IAAc/V,EAAAA,EAAAA,KAAY,KAC9B8vB,EAAS,CAAElxB,GAAIwJ,EAAQiqB,sBAAsB,GAAQ,CAAEC,uBAAuB,IAE1E5sB,GAAc0pB,GAChBW,MAED,CACDrqB,EACA0pB,EACAU,EACA1nB,EACA2nB,IAGIwC,IAAkBvyB,EAAAA,EAAAA,KAAaiL,IACnCA,EAAEoQ,iBACFwU,MAAAA,GAAAA,EAAcznB,KACb,CAACA,EAAQynB,IAEN2C,IAAexyB,EAAAA,EAAAA,KAAY,KAC/B0wB,KACAT,OACC,CAACS,GAAuBT,KAErBwC,IAAyBzyB,EAAAA,EAAAA,KAAY,KACzC6wB,KACAT,OACC,CAACS,GAA2BT,KAEzBhM,IAAepkB,EAAAA,EAAAA,KAAY,KAC/BgxB,KACAT,OACC,CAACS,GAAuBT,KAErBmC,IAAiBC,EAAAA,EAAAA,GAAsB,CAC3C5jB,KAAAA,EACAE,KAAAA,EACAujB,aAAAA,GACAC,uBAAAA,GACArO,aAAAA,GACAsL,SAAAA,EACA5C,SAAAA,EACA1d,QAAAA,EACAigB,gBAAAA,IAGIjoB,IAAOC,EAAAA,EAAAA,KAEb,IAAK0H,EACH,OAuDF,MAAMzP,IAAYa,EAAAA,EAAAA,GAChB,4BACA+O,EAAAA,EAAAA,IAAS9G,GAAU,UAAY,QAC/B1C,GAAc,YAGhB,OACE,mBAACktB,EAAA,EAAD,CACE9tB,IAAKA,GACLxF,UAAWA,GACXc,MAAOA,EACPmN,QAAShJ,EAAAA,GACTmuB,eAAgBA,GAChBzmB,QAAS8J,GACT8Z,YAAa0C,IAEb,0BAAKjzB,UAAU,UACb,mBAACuzB,EAAA,EAAD,CACE9jB,KAAMA,EACNE,KAAMA,EACNkP,WAAYA,EACZpK,gBAAiB9E,MAAAA,OAAF,EAAEA,EAAMmB,OACvB9R,aAAcA,EACdmU,eAAgBA,EAChBuB,WAAS,EACTE,oBAAqBA,IAEtBnF,EAAK+jB,cAAgB/jB,EAAKgkB,gBACzB,mBAAC,EAAD,CAAgBrtB,WAAYA,EAAYkd,SAA6B,IAAnBnQ,KAGtD,0BAAKnT,UAAU,QACb,0BAAKA,UAAU,SACb,8BAAK0N,EAAAA,EAAAA,IAAWqG,EAAAA,EAAAA,GAAajM,GAAM2H,EAAME,KACxCF,EAAKqJ,YAAc,mBAAC8K,EAAA,EAAD,OACnBjU,MAAAA,OAAA,EAAAA,EAAMuP,aAAcvP,EAAKmB,QAAU,mBAAC+S,EAAA,EAAD,MACnCpU,EAAKqH,UAAY,mBAACgN,EAAA,EAAD,CAAUhN,SAAUrH,EAAKqH,WAC1ChH,GAAW,wBAAG9P,UAAU,eACxByP,EAAKkf,aACJ,mBAAC+E,EAAA,EAAD,CACE7tB,QAAS4J,EAAKkf,YACdpV,eAAgB2W,KAItB,0BAAKlwB,UAAU,YAjGrB,WACE,GAAIyX,IAAgBkX,IAAelX,GAAanC,UAA+B,IAAnBqZ,GAAY1oB,KACtE,OAAO,mBAAC0tB,EAAA,EAAD,CAAclc,aAAcA,KAGrC,GAAImY,MAAAA,GAAAA,EAAO1e,KAAKrP,OACd,OACE,wBAAG7B,UAAU,eAAeyN,IAAK3F,GAAKE,MAAQ,OAAS,OACrD,2BAAMhI,UAAU,SAAS8H,GAAK,WAC7B4F,EAAAA,EAAAA,GAAWkiB,EAAM1e,OAKxB,IAAKyd,GACH,OAGF,GAAIiD,GAAU,CACZ,MAAMgC,EAASnkB,KAASU,EAAAA,EAAAA,IAAcV,IAASkf,GAAYH,WAAaG,GAAY7lB,QAEpF,OACE,wBAAG9I,UAAU,eAAeyN,IAAK3F,GAAKE,MAAQ,OAAS,QACpD6rB,EAAAA,EAAAA,GACC/rB,GACA6mB,GACCiF,OAA6Bn0B,EAApBmvB,EACVgF,EAASnkB,OAAOhQ,EAChB0yB,GACApD,EACAK,EACA,CAAE0E,oBAAoB,KAM9B,MAAMC,GAAaC,EAAAA,EAAAA,IAAqBlsB,GAAMgB,EAAQ8lB,GAEtD,OACE,wBAAG5uB,UAAU,eAAeyN,IAAK3F,GAAKE,MAAQ,OAAS,OACpD+rB,GACC,sCACE,2BAAM/zB,UAAU,gBAAe0N,EAAAA,EAAAA,GAAWqmB,IAC1C,2BAAM/zB,UAAU,SAAhB,MAuFZ,SACE8H,EAAcjC,EAAqB+O,EAAiCqf,EAAkBhC,GAEtF,OAAKgC,EAKH,2BAAMj0B,UAAU,iBACd,0BAAKgB,IAAKizB,EAAS7c,IAAI,GAAGpX,WAAWa,EAAAA,EAAAA,GAAe,uBAAwBoxB,GAAgB,YAC3FtY,EAAAA,EAAAA,IAAgB9T,IAAY,wBAAG7F,UAAU,eACzC8pB,EAAAA,EAAAA,GAAqBhiB,EAAMjC,GAAS,OAAMpG,OAAWA,EAAWmV,KAP5DkV,EAAAA,EAAAA,GAAqBhiB,EAAMjC,OAASpG,OAAWA,OAAWA,EAAWmV,GAxFvEsf,CAAcpsB,GAAM6mB,GAAa/Z,EAAqB8E,IAAgBqY,GAAgBE,KAmDpFkC,GACD,mBAAC,EAAD,CAAO1kB,KAAMA,EAAM+d,SAAUA,EAAU1d,QAASA,MAGnDqhB,IACC,mBAACiD,EAAA,EAAD,CACE9gB,OAAQod,GACRnd,QAASqd,GACTpd,oBAAqB6d,GACrB5hB,KAAMA,IAGT6hB,IACC,mBAAC,IAAD,CACEhe,OAAQud,GACRtd,QAASwd,GACTvd,oBAAqBge,GACrB1oB,OAAQA,IAGX2oB,IACC,mBAAC4C,EAAA,EAAD,CACE/gB,OAAQ0d,GACRzd,QAAS2d,GACT1d,oBAAqBme,GACrB7oB,OAAQA,EACRub,QAAQ,c,mCClVlB,MAsCA,GAAe1lB,EAAAA,EAAAA,KAAKwQ,EAAAA,EAAAA,KAAqB,CAACC,EAAD,KAAkD,IAAzC,SAAEghB,EAAF,WAAYkE,GAA6B,EAGzF,MAAO,CACLC,WAHiBnE,GAA2B,WAAfkE,GAA0BE,EAAAA,EAAAA,IAAiBplB,EAAQghB,QAAY3wB,EAI5Fg1B,eAAeC,EAAAA,EAAAA,IAAoBtlB,EAAQ,SAL3BD,EApC2B,IAEzC,IAF0C,WAC9ColB,EAD8C,cAClCE,EADkC,gBACnBE,EADmB,eACFC,GACxC,EACJ,MAAM9sB,GAAOC,EAAAA,EAAAA,KAEP8sB,GAAmBn0B,EAAAA,EAAAA,KAAY,KACnCi0B,EAAiB,CAAE1Y,KAAM,aAAc6Y,QAASP,IAChDK,EAAgBG,EAAAA,GAAAA,iCACf,CAACR,EAAYI,EAAiBC,IAEjC,OACE,0BAAK50B,UAAU,eACb,0BAAKA,UAAU,WACZy0B,GAAiB,mBAACO,EAAA,EAAD,CAAyBn2B,QAAS41B,EAAe7zB,KAfzD,OAiBZ,yBAAIZ,UAAU,QAAQyN,IAAI,QAAQ3F,EAAK,2BACvC,wBAAG9H,UAAU,cAAcyN,IAAI,QAC5B3F,EAAKysB,EAAa,mCAAqC,mBAEzDA,GAAcI,GAAmBC,GAChC,mBAAC5mB,EAAA,EAAD,CACEC,QAAShJ,EAAAA,GACTgwB,OAAK,EACLC,MAAI,EACJvoB,QAASkoB,EACTj0B,KAAK,UACLoH,MAAOF,EAAKE,OAEZ,wBAAGhI,UAAU,kBACZ8H,EAAK,0CC4IhB,GAAenJ,EAAAA,EAAAA,KA5JgB,IAMzB,IAN0B,WAC9B21B,EAD8B,SAE9BlE,EAF8B,SAG9B9M,EAH8B,gBAI9BqR,EAJ8B,eAK9BC,GACI,EACJ,MAAM,SAAEpE,EAAF,aAAY2E,IAAiB/tB,EAAAA,EAAAA,MAE7BguB,GAAevtB,EAAAA,EAAAA,IAAuB,MACtCwtB,GAAsBxtB,EAAAA,EAAAA,KAAO,GAE7BytB,EACW,QAAfhB,EAAuBiB,EAAAA,GAA+B,aAAfjB,EAA4BkB,EAAAA,GAAqBpF,EAGpFH,GAAawF,EAAAA,EAAAA,IAA8BH,GAE3CI,GAAY1rB,EAAAA,EAAAA,KAAQ,KACxB,GAAKimB,EAIL,OAAOA,EAAW0F,QAAO,CAACC,EAAKt2B,EAAI8C,KACjCwzB,EAAIt2B,GAAM8C,EACHwzB,IACN,MACF,CAAC3F,IAEE4F,GAAgBjU,EAAAA,EAAAA,GAAY8T,GAE5BI,GAAgB9rB,EAAAA,EAAAA,KAAQ,IACvB0rB,GAAcG,GAIZE,EAAAA,EAAAA,IAAUL,GAAW,CAACM,EAAO12B,SACLG,IAAtBo2B,EAAcv2B,GAAoB02B,EAAQH,EAAcv2B,IAAM,MAJ9D,IAMR,CAACo2B,EAAWG,KAERjY,EAAaC,IAAWC,EAAAA,EAAAA,QAAkBre,EAAWwwB,OAAYxwB,EAAWw2B,EAAAA,KAGnFC,EAAAA,EAAAA,GAAW5S,GAAAA,MAAY2M,GAAAA,EAAYpuB,OAAS,CAC1C,cAAgB8J,IACdA,EAAEoQ,iBACFoZ,EAAa,CAAEgB,kBAAmB,EAAGlG,WAAAA,KAEvC,gBAAkBtkB,IAChBA,EAAEoQ,iBACFoZ,EAAa,CAAEgB,iBAAkB,EAAGlG,WAAAA,WAEpCxwB,IAGJkL,EAAAA,EAAAA,KAAU,KACR,GAAK2Y,GAAa2M,GAAemG,EAAAA,GAkBjC,OAFA/gB,SAASghB,iBAAiB,UAAWC,GAE9B,KACLjhB,SAASkhB,oBAAoB,UAAWD,IAf1C,SAASA,EAAc3qB,GACrB,IAAM6qB,EAAAA,IAAa7qB,EAAE8qB,UAAcD,EAAAA,IAAa7qB,EAAE+qB,UAAa/qB,EAAEgrB,KAAKC,WAAW,SAAU,CACzF,MAAO,CAAEC,GAASlrB,EAAEgrB,KAAKG,MAAM,cAAgB,GAC/C,IAAKD,EAAO,OAEZ,MAAME,EAAWC,OAAOH,GAAS,EACjC,GAAIE,EAAW9G,EAAYpuB,OAAS,GAAKk1B,EAAW,EAAG,OAEvDvG,EAAS,CAAElxB,GAAI2wB,EAAY8G,GAAWhE,sBAAsB,QAS/D,CAACzP,EAAUkN,EAAU2E,EAAclF,IAEtC,MAAMgH,ELpHD,SAA8BnB,GACnC,OAAO9rB,EAAAA,EAAAA,KAAQ,KACb,MAAMktB,EAAaC,OAAOC,OAAOtB,GAC3BuB,EAAaH,EAAW5I,QAAQgJ,GAASA,EAAO,IAAGz1B,OACnD01B,EAAeL,EAAW5I,QAAQgJ,GAASA,EAAO,IAAGz1B,OAE3D,OAAQiH,IACN,MAAMunB,EAAYyF,EAAchtB,GAChC,OAAkB,IAAdunB,EACK9C,EAAmBiK,KAI1BnH,IAAcoH,EAAAA,GACXpH,KAAc,KACbgH,GAAcE,GAAgBlH,EAAY,GAC1CkH,EAAeF,GAAchH,EAAY,EAEtC9C,EAAmBgF,QAGrBhF,EAAmBoF,QAE3B,CAACmD,IK6FqB4B,CAAqB5B,IAExC,QAAE6B,IAAYC,EAAAA,EAAAA,IAAwB,CAC1CC,QAASzC,EACT0C,WAvF0B,MA0FtB7E,GAAkB8E,EAAAA,EAAAA,IAAsBjvB,IACxCusB,EAAoB7qB,QACtB6qB,EAAoB7qB,SAAU,EAGhCgmB,EAAS,CAAElxB,GAAIwJ,EAAQiqB,sBAAsB,MAC5C,GA/FuB,KA+FE,GAEtBiF,GAAkBt3B,EAAAA,EAAAA,KAAaiL,IACnC,MAAMssB,EAAOtsB,EAAEgS,cAAc9R,wBACvBpJ,EAAIkJ,EAAEG,QAAUmsB,EAAKrsB,KACrBlJ,EAAIiJ,EAAEusB,QAAUD,EAAKE,IACvB11B,EAAIw1B,EAAKr2B,OAASc,EAAIu1B,EAAKv1B,IAC/B2yB,EAAoB7qB,SAAU,KAC7B,IA0BH,OACE,mBAAC4tB,EAAA,EAAD,CACEp4B,UAAU,0BACVwF,IAAK4vB,EACLlX,MAAON,EACPya,iBAAkBpC,EAAAA,GAClBqC,yBAAuB,EACvBC,YAAYtI,MAAAA,OAAA,EAAAA,EAAYpuB,SAAU,GAAK22B,EAAAA,GACvCtb,WAAYW,EACZ4a,YAAaT,GAEZpa,MAAAA,GAAAA,EAAa/b,OAnClB,WACE,MAAM62B,EAAiBzI,EAAYxS,QAAQG,EAAa,IAClD+a,GAAcC,EAAAA,EAAAA,IAAoBtD,IAAqB,EAE7D,OAAO1X,EAAanY,KAAI,CAACnG,EAAI8C,KAC3B,MAAMorB,EAAWkL,EAAiBt2B,EAAIu2B,EAEtC,OACE,mBAAC,EAAD,CACE9f,IAAKvZ,EACLu5B,cAAerL,EAAWprB,GAAI02B,EAAAA,EAAAA,IAAYx5B,GAC1CwJ,OAAQxJ,EACRkuB,SAAUA,EACV4C,SAAUA,EACVE,cAAe2G,EAAiB33B,GAChC+wB,UAAWyF,EAAcx2B,GACzBwB,MAAQ,SAAQ43B,EAAiBt2B,GAAKo2B,EAAAA,QACtC5jB,oBAAqB+iB,EACrBpH,YAAa0C,OAkBf8F,GACEnb,IAAgBA,EAAY/b,OAE5B,mBAAC,EAAD,CACEuuB,SAAUA,EACVkE,WAAYA,EACZK,gBAAiBA,EACjBC,eAAgBA,IAIpB,mBAACoE,EAAA,EAAD,CAASngB,IAAI,iB,6CCzLd,SAASogB,EACdnxB,EAAcjC,EAAqBqzB,EAAoC9G,GAEvE,MAAM,SAAE5D,GAAa3oB,EACrB,IAAK2oB,EACH,OAGF,MAAMtZ,GAAStF,EAAAA,EAAAA,IAAS4e,GAAY4D,EAAU5D,GAAY0K,EAAU1K,GAEpE,IAAIuF,GAAaoF,EAAAA,EAAAA,IAAerxB,EAAMoN,GAEtC,MAAMzF,EAAOypB,EAAUrzB,EAAQiD,QAS/B,OARI2G,KACEG,EAAAA,EAAAA,IAAS4e,IAActZ,EAAmBpE,OAC5CijB,EAAc,GAAEjsB,EAAK,iBAAgBiM,EAAAA,EAAAA,GAAajM,EAAM2H,MAC/C2pB,EAAAA,EAAAA,IAAY3pB,KACrBskB,GAAe,OAAKhgB,EAAAA,EAAAA,GAAajM,EAAM2H,OAIpCskB,I,sECvBT,MAQA,GAAep1B,EAAAA,EAAAA,KAR4BC,IACzC,MAAM,OAAE0U,GAAW1U,EACby6B,GAAahM,EAAAA,EAAAA,GAAgBC,EAAAA,GAAAA,MAAe,kBAAmBha,GAGrE,OAAO+lB,EAAa,mBAACA,EAAez6B,QAAYa,M,qICClD,MAmCA,GAAed,EAAAA,EAAAA,KAnCkB,IAA+B,IAA9B,QAAE26B,EAAF,aAAWC,GAAmB,EAC9D,MAAOC,EAAWC,EAAaC,IAAiBv5B,EAAAA,EAAAA,KAY1CH,GAAYa,EAAAA,EAAAA,GAChB,aACA24B,GAAa,WAGf,OACE,0BACEx5B,UAAWA,EACX25B,OAAQJ,EACRhJ,YAAakJ,EACbhB,YApBqB9sB,IACvB,MAAQiuB,cAAeC,GAAaluB,EAEhCkuB,GACFluB,EAAEM,kBAGJytB,KAcE,oBAEA,0BAAK15B,UAAU,kBACb,0BAAKA,UAAY,cAAYs5B,EAAU,QAAU,cACjD,0BAAKt5B,UAAU,SAAf,gCACA,0BAAKA,UAAU,eAAes5B,EAAU,iBAAmB,4BClB5D,IAAKQ,G,SAAAA,GAAAA,EAAAA,KAAAA,OAAAA,EAAAA,SAAAA,WAAAA,EAAAA,UAAAA,a,CAAAA,IAAAA,EAAAA,KAMZ,MAkFA,GAAen7B,EAAAA,EAAAA,KAhFgB,IAEzB,IAF0B,OAC9B2U,EAD8B,UACtBymB,EADsB,OACXC,EADW,aACHT,GACvB,EAEJ,MAAMU,GAAiBpyB,EAAAA,EAAAA,IAAe,MAChCqyB,GAAgBtY,EAAAA,EAAAA,GAAYmY,IAC5B,aAAE9uB,EAAF,qBAAgBE,IAAyBE,EAAAA,EAAAA,GAAkBiI,IAEjE3I,EAAAA,EAAAA,KAAU,IAAO2I,GAAS6mB,EAAAA,EAAAA,GAAsBH,QAAUv6B,GAAY,CAAC6T,EAAQ0mB,IAE/E,MAAMI,GAAkB15B,EAAAA,EAAAA,KAAY25B,MAAAA,IAClC,MAAQC,aAAcC,GAAO5uB,EAC7B,IAAI6uB,EAAgB,GAEpB,KAAID,EAAGC,OAASD,EAAGC,MAAM34B,OAAS,IAAO04B,EAAGrc,OAAUqc,EAAGrc,MAAMrc,QAExD,GAAI04B,EAAGrc,OAASqc,EAAGrc,MAAMrc,OAAS,EAAG,CAC1C,MAAM44B,QAAoBC,EAAAA,EAAAA,GAA8BH,EAAGrc,OACvDuc,EAAY54B,SACd24B,EAAQA,EAAMG,OAAOF,UAJvBD,EAAQA,EAAMG,OAAOn3B,MAAMo3B,KAAKL,EAAGC,QAQrCR,IACAT,EAAaiB,GAAO,KACnB,CAACjB,EAAcS,IAEZa,GAAuBn6B,EAAAA,EAAAA,KAAaiL,IACxC,MAAQ2uB,aAAcC,GAAO5uB,EAEzB4uB,EAAGC,OAASD,EAAGC,MAAM34B,OAAS,IAChCm4B,IACAT,EAAa/1B,MAAMo3B,KAAKL,EAAGC,QAAQ,MAEpC,CAACjB,EAAcS,IAEZhC,GAAkBt3B,EAAAA,EAAAA,KAAaiL,IACnCA,EAAEM,kBAEF,MAAQmQ,OAAQ0e,EAAYlB,cAAeC,GAAaluB,EAGnDmvB,EAA8B51B,QAAQ,4BAA8B20B,IACvEI,EAAezvB,QAAU7F,OAAOyY,YAAW,KACzC4c,MA9CsB,QAiDzB,CAACA,IAQJ,IAAK/uB,EACH,OAGF,MAAMjL,GAAYa,EAAAA,EAAAA,GAChB,WACAsK,GAGF,OACE,mBAAC4vB,EAAA,EAAD,CAAQC,YAAY,0BAClB,0BACEh7B,UAAWA,EACXy4B,YAAaT,EACbiD,WApBiB,KACjBhB,EAAezvB,SACjB7F,OAAOu2B,aAAajB,EAAezvB,UAmBjCmvB,OAAQK,EACRrtB,QAASqtB,GAET,mBAAC,EAAD,CAAYT,aAAca,KACxBL,GAAaG,IAAkB,mBAAC,EAAD,CAAYX,aAAcsB,EAAsBvB,SAAO,U,sECnGhG,MAQA,GAAe36B,EAAAA,EAAAA,KAR0BC,IACvC,MAAM,OAAE0U,GAAW1U,EACbu8B,GAAe9N,EAAAA,EAAAA,GAAgBC,EAAAA,GAAAA,MAAe,gBAAiBha,GAGrE,OAAO6nB,EAAe,mBAACA,EAAiBv8B,QAAYa,M,8NCgBtD,MA6BM27B,EAAmBn2B,EAAAA,GAA0B,IAAM,IA6WzD,GAAetG,EAAAA,EAAAA,KAAKwQ,EAAAA,EAAAA,KAClB,CAACC,EAAD,KAAwD,IAA/C,OAAEtG,EAAF,SAAUymB,GAAqC,EACtD,MAAM,oBAAE8L,GAAwBjsB,EAAOgE,SAASC,MAEhD,MAAO,CACLgoB,oBAAAA,EACAC,aAAcxyB,GAAUymB,GAAWgM,EAAAA,EAAAA,IAAmBnsB,EAAQtG,EAAQymB,QAAY9vB,EAClF+7B,aAAcpsB,EAAOqsB,UAAUnoB,QAAUlE,EAAOssB,QAAQC,sBAP1CxsB,EAxV4B,IAkB1C,IAlB2C,GAC/C7P,EAD+C,OAE/CwJ,EAF+C,aAG/C8yB,EAH+C,uBAI/CC,EAJ+C,gBAK/CC,EAL+C,KAM/Crd,EAN+C,YAO/ChE,EAP+C,kBAQ/CshB,EAR+C,aAS/CC,EAT+C,oBAU/CC,EAV+C,4BAW/CC,EAX+C,aAY/CZ,EAZ+C,aAa/CE,EAb+C,oBAc/CH,EAd+C,SAe/Cc,EAf+C,kBAgB/CC,EAhB+C,OAiB/CC,GACI,EACJ,MAAM,gBACJC,EADI,mBAEJC,IACEn1B,EAAAA,EAAAA,MAGE+T,GAAWtT,EAAAA,EAAAA,IAAuB,MAElC20B,GAAsB30B,EAAAA,EAAAA,IAAe,MAErC40B,GAAW50B,EAAAA,EAAAA,IAAuB,MAElCC,GAAOC,EAAAA,EAAAA,KACP20B,GAAuB70B,EAAAA,EAAAA,KAAO,IAC7B80B,EAAqBC,EAAmBC,IAAsB18B,EAAAA,EAAAA,MAC9D28B,EAA6BC,IAAkC50B,EAAAA,EAAAA,OAC/D60B,EAAeC,IAAoB90B,EAAAA,EAAAA,OAE1CwC,EAAAA,EAAAA,KAAU,KACHkxB,GACLqB,IAAkB,KACjB,CAACrB,KAEJsB,EAAAA,EAAAA,IAA4B,IAAgB,IAAdC,GAAc,EACtC3e,IAAStD,EAAS3Q,QAAS6yB,YAC7BliB,EAAS3Q,QAAS6yB,UAAY5e,GAG5BA,IAASge,EAASjyB,QAAS6yB,YAC7BZ,EAASjyB,QAAS6yB,UAAY5e,QAGfhf,IAAb29B,GAA0BA,IAAa3e,GACzCye,IAAmBze,EAAK5c,UAEzB,CAAC4c,KAEc5W,EAAAA,EAAAA,IAAOiB,GACf0B,QAAU1B,EACpB,MAAMw0B,GAAa58B,EAAAA,EAAAA,KAAY,KACxBya,EAAS3Q,WAIV+yB,EAAAA,EAAAA,MACFngB,WAAWkgB,EAhHM,MAoHnBE,EAAAA,EAAAA,GAAqBriB,EAAS3Q,YAC7B,IAEGizB,GAA2B/8B,EAAAA,EAAAA,KAAY,KAC3Cm8B,IArFJ,WACE,MAAMa,EAAY/4B,OAAOg5B,eACpBD,IAIDA,EAAUE,gBACZF,EAAUE,kBACDF,EAAUG,OACnBH,EAAUG,SA6EVC,KACC,CAACjB,IAEJ,SAASkB,IAEP,GAAIC,EAAAA,GACF,OAAO,EAGT,MAAMN,EAAY/4B,OAAOg5B,eACzB,IAAKD,IAAcA,EAAUO,YAAcvB,EAAqBlyB,QAE9D,OADAqyB,KACO,EAGT,MAAMqB,EAAiBR,EAAUS,WAAW,GACtCC,EAAeF,EAAeG,WAAWlV,OAC/C,QACE+S,KACIoC,EAAAA,EAAAA,GAAuBJ,EAAgBpC,GAAmByC,EAAAA,MAC1DH,IACDI,EAAAA,EAAAA,GAAqBJ,KACpBF,EAAeO,gBAEnB5B,KACO,GAMX,SAAS6B,IACP,IAAKX,IACH,OAGF,MAAMG,EAAiBv5B,OAAOg5B,eAAgBQ,WAAW,GACnDQ,EAAgBT,EAAeryB,wBAC/B+yB,EAAYzjB,EAAS3Q,QAASqB,wBAEpC,IAAIpJ,EAAKk8B,EAAc/yB,KAAO+yB,EAAc/8B,MAAQ,EAAKg9B,EAAUhzB,KAE/DnJ,EApI4B,GAqI9BA,EArI8B,GAsIrBA,EAAIm8B,EAAUh9B,MAtIO,KAuI9Ba,EAAIm8B,EAAUh9B,MAvIgB,IA0IhCm7B,EAA+B,CAC7Bt6B,EAAAA,EACAC,EAAGi8B,EAAcxG,IAAMyG,EAAUzG,MAGnC8E,EAAiBiB,GACjBtB,IAGF,SAASiC,IACHrC,EAAoBhyB,SACtB7F,OAAOu2B,aAAasB,EAAoBhyB,SAG1CgyB,EAAoBhyB,QAAU7F,OAAOyY,WAAWshB,EAzJb,KA0PrC,SAASxB,KAAoC,IAAlB4B,EAAkB,wDAC3C,MAAMC,EAAQ5jB,EAAS3Q,QACjBw0B,EAAQvC,EAASjyB,QACjBy0B,EAAgBjI,OAAO+H,EAAMj+B,MAAMgB,OAAOonB,QAAQ,KAAM,KACxDgW,EAAY38B,KAAK2H,IAAI80B,EAAMG,aAAc/D,GAC/C,GAAI8D,IAAcD,EAChB,OAGF,MAAMG,EAAqB78B,KAAK8H,MAhSD,GAiSA9H,KAAK88B,IAAI98B,KAAK+8B,IAAIJ,EAAYD,KAGvDM,EAAO,KACXR,EAAMj+B,MAAMgB,OAAU,GAAEo9B,MACxBH,EAAMj+B,MAAMs+B,mBAAsB,GAAEA,MACpCL,EAAMrM,UAAU8M,OAAO,YAAaR,EAAMG,aAAe/D,IAGvD0D,EAEFnjB,sBAAsB4jB,GAEtBA,KAIJ50B,EAAAA,EAAAA,KAAU,KACJ8Q,EAAAA,IAIAugB,GACFsB,MAED,CAACx0B,EAAQw0B,EAAYhC,EAAcU,KAEtCrxB,EAAAA,EAAAA,KAAU,KACR,GAAI6wB,EACF,OAGF,MAAMiE,GAAkBC,EAAAA,EAAAA,KAAU/zB,IAClB,QAAVA,EAAEkN,MACJlN,EAAEoQ,iBACFJ,sBAAsB2hB,MAzSK,KA2SA,GAAM,GAErC,OAAOqC,EAAAA,EAAAA,GAAyB,CAAEC,MAAOH,MACxC,CAACnC,EAAY9B,KAEhB7wB,EAAAA,EAAAA,KAAU,KACR,MAAMo0B,EAAQ5jB,EAAS3Q,QAEvB,SAASq1B,IACPd,EAAMe,OAOR,OAJI7D,GACF8C,EAAM1I,iBAAiB,QAASwJ,GAG3B,KACLd,EAAMxI,oBAAoB,QAASsJ,MAEpC,CAAC5D,IAEJ,MAAMj8B,IAAYa,EAAAA,EAAAA,GAChB,6BACA4d,EAAK5c,OAAS,GAAK,UACnBo6B,GAAuB,kBAGzB,OACE,0BAAK38B,GAAIA,EAAIqN,QAASsvB,EAAsBG,OAAoB38B,EAAWgO,IAAK3F,EAAKE,MAAQ,WAAQvI,GACnG,0BACE+F,IAAK2V,EACL7b,GAAIw8B,GAAmByC,EAAAA,GACvBv+B,UAAWA,GACX+/B,iBAAe,EACfxjB,KAAK,UACL9O,IAAI,OACJyO,SAAU,EACVvP,QAAS2wB,EACTnhB,SAnHN,SAAsBxQ,GACpB,MAAM,UAAE0xB,EAAF,YAAa2C,GAAgBr0B,EAAEgS,cAKrC,GAHAwe,EA5Nc,SA4NLkB,EAA0B,GAAKA,IAIrC5hB,EAAAA,MACIukB,IAAgBA,EAAYn+B,UAE3Bo+B,EAAAA,KAAsB5C,EAAU9f,SAAS,gBAC/C,CACA,MAAMmgB,EAAY/4B,OAAOg5B,eACrBD,IACFviB,EAAS3Q,QAASs1B,OAClBpC,EAAUE,mBACVJ,EAAAA,EAAAA,GAAqBriB,EAAS3Q,SAAU,MAoGxC01B,UAvJN,SAAuBv0B,GAErB,MAAM,YAAEw0B,GAAgBx0B,EAExB,IAAKw0B,IAAgB1hB,EAAK5c,SAAW8J,EAAE8qB,SAAW9qB,EAAE+qB,SAAU,CAC5D,MAAMP,EAA6B,cAAVxqB,EAAEkN,IAAsB,EAAc,YAAVlN,EAAEkN,KAAqB,OAAIpZ,EAChF,GAAI02B,EAIF,OAHAxqB,EAAEoQ,sBAEFwgB,EAAmB,CAAEpG,iBAAAA,IAKpBgK,GAAyB,UAAVx0B,EAAEkN,KAAoBlN,EAAEy0B,SAahCD,GAAyB,YAAVx0B,EAAEkN,KAAsB4F,EAAK5c,QAAW8J,EAAE8qB,SAAY9qB,EAAE+qB,SAAY/qB,EAAE00B,OAI/F10B,EAAEyQ,OAAOia,iBAAiB,QAASwI,EAA6B,CAAEyB,MAAM,KAHxE30B,EAAEoQ,iBACFugB,KAbI0B,EAAAA,IAAUuC,EAAAA,MAEe,UAAxBlF,IAAoC1vB,EAAEy0B,UACX,eAAxB/E,IAAyC1vB,EAAE+qB,SAAW/qB,EAAE8qB,YAG9D9qB,EAAEoQ,iBAEF8gB,IACAR,MA+HA3T,YArLN,SAAyB/c,GAYvB,SAAS60B,EAAuBC,GAC1BA,aAAcC,eAA4B,QAAXD,EAAG5nB,KAA4B,WAAX4nB,EAAG5nB,MAI1DuE,YAAW,KACTsf,EAAqBlyB,SAAU,IA9MH,KAiN9B7F,OAAO4xB,oBAAoB,UAAWiK,GACtC77B,OAAO4xB,oBAAoB,YAAaiK,IArBzB,IAAb70B,EAAEQ,OAKFuwB,EAAqBlyB,UAIzBkyB,EAAqBlyB,SAAU,EAe/B6K,SAASghB,iBAAiB,YAAamK,GACvCnrB,SAASghB,iBAAiB,UAAWmK,IAxBnC70B,EAAEyQ,OAAOia,iBAAiB,UAAWwI,EAA6B,CAAEyB,MAAM,KAoLxExmB,cAAeymB,EAAAA,GAjGrB,SAAmB50B,GACZoyB,MAILpyB,EAAEoQ,iBACFpQ,EAAEM,yBA2F0CxM,EACxCkhC,cAAeJ,EAAAA,GAAa1B,OAA8Bp/B,EAC1D,aAAYgb,IAEbmhB,GACC,0BAAK57B,UAAU,uBAAuByN,IAAI,QACvCmuB,GAIL,0BAAKp2B,IAAKi3B,EAAUz8B,WAAWa,EAAAA,EAAAA,GAAeb,GAAW,SAAUyN,IAAI,UACrEsuB,GAAqB,2BAAM/7B,UAAU,mBAAmByN,IAAI,QAAQgN,GACtE,mBAAC,IAAD,CACEnH,OAAQqpB,EACRiE,eAAgB9D,EAChBE,cAAeA,EACfC,iBAAkBA,EAClB1pB,QAASkqB,IAEV1B,GAAqB,2BAAM/7B,UAAU,uBAAsB0N,EAAAA,EAAAA,GAAWquB,U,2JC1X7E,MAAM8E,EAAsE,CAC1EC,EAAG,OACHC,OAAQ,OACRC,EAAG,SACHC,GAAI,SACJC,EAAG,YACHC,IAAK,gBACLC,KAAM,YACNC,KAAM,WAEFC,EAAajsB,SAASksB,cAAc,OA2c1C,GAAe5iC,EAAAA,EAAAA,KAzcqB,IAM9B,IAN+B,OACnC2U,EADmC,eAEnCstB,EAFmC,cAGnC5D,EAHmC,iBAInCC,EAJmC,QAKnC1pB,GACI,EAEJ,MAAM6hB,GAAevtB,EAAAA,EAAAA,IAAuB,MAEtC25B,GAAkB35B,EAAAA,EAAAA,IAAyB,OAC3C,aAAEoD,EAAF,qBAAgBE,IAAyBE,EAAAA,EAAAA,GAAkBiI,IAC1DmuB,EAAmBC,EAAiBC,IAAoBxhC,EAAAA,EAAAA,MACxDyhC,EAASC,IAAc15B,EAAAA,EAAAA,IAAS,KAChC25B,EAAeC,IAAoB55B,EAAAA,EAAAA,KAAS,IAC5C65B,EAAgBC,IAAqB95B,EAAAA,EAAAA,OACrC+5B,EAAqBC,IAA0Bh6B,EAAAA,EAAAA,IAA+B,KAErFwC,EAAAA,EAAAA,KAAU,IAAO2I,GAAS6mB,EAAAA,EAAAA,GAAsB5mB,QAAW9T,GAAY,CAAC6T,EAAQC,KAChF6uB,EAAAA,EAAAA,GACE9uB,EACA8hB,EACA7hB,IAGF5I,EAAAA,EAAAA,KAAU,KACJ82B,EACFD,EAAgBh3B,QAASkR,SAEzBmmB,EAAW,IACXE,GAAiB,MAElB,CAACN,KAEJ92B,EAAAA,EAAAA,KAAU,KACHM,IACH02B,IACAQ,EAAuB,IACvBF,OAAkBxiC,MAEnB,CAACkiC,EAAkB12B,KAEtBN,EAAAA,EAAAA,KAAU,KACR,IAAK2I,IAAW0pB,EACd,OAGF,MAAMqF,EAAwC,GAC9C,IAAI,cAAEC,GAAkBtF,EAAcuF,wBACtC,KAAOD,GAAiBA,EAAchjC,KAAOi/B,EAAAA,IAAmB,CAC9D,MAAMiE,EAAa3B,EAAwByB,EAAcG,SACrDD,IACFH,EAAgBG,IAAc,GAGhCF,EAAgBA,EAAcA,cAGhCH,EAAuBE,KACtB,CAAC/uB,EAAQ0pB,EAAe0E,IAE3B,MAAMgB,GAAmBhiC,EAAAA,EAAAA,KAAY,KACnC,IAAKs8B,EACH,OAGF,MAAMU,EAAY/4B,OAAOg5B,eACrBD,IACFA,EAAUE,kBACVF,EAAUiF,SAAS3F,MAEpB,CAACA,IAEE4F,GAAsBliC,EAAAA,EAAAA,KAAY,KACtC,MAAMg9B,EAAY/4B,OAAOg5B,eACrBD,GACFT,EAAiBS,EAAUS,WAAW,MAEvC,CAAClB,IAEE4F,GAAkBniC,EAAAA,EAAAA,KAAY,KAClC,GAAKs8B,EAIL,OADAsE,EAAWwB,gBAAgB9F,EAAc+F,iBAClCzB,EAAWjE,YACjB,CAACL,IAEEgG,GAAqBtiC,EAAAA,EAAAA,KAAY,KACrC,GAAKs8B,EAIL,OAAOA,EAAcuF,wBAAwBD,gBAC5C,CAACtF,IAEJ,SAASiG,IACP,MAAMlE,EAAQyC,EAAgBh3B,QAC9B,IAAKu0B,EACH,OAGF,MAAM,YAAEmE,EAAF,YAAeC,EAAf,WAA4BC,GAAerE,EACjD,GAAIoE,GAAeD,EAEjB,YADAjB,OAAkBxiC,GAIpB,IAAIO,EAAY,GACZojC,EAAaD,EAAcD,IAC7BljC,EAAY,cAEVojC,EAAa,IACfpjC,GAAa,cAGfiiC,EAAkBjiC,GAQpB,SAASqjC,EAAyBxqB,GAChC,GAAIqpB,EAAoBrpB,GACtB,MAAO,SAGT,GAAY,cAARA,GAA+B,kBAARA,GACzB,GAAIse,OAAOmM,KAAKpB,GAAqBqB,MAClCC,GAASA,IAAS3qB,GAAOlR,QAAQu6B,EAAoBsB,MAEtD,MAAO,gBAEJ,GAAItB,EAAoBuB,WAAavB,EAAoBwB,cAC9D,MAAO,WAMX,MAAMC,GAAoBjjC,EAAAA,EAAAA,KAAY,KACpC,GAAIwhC,EAAoB0B,QAAS,CAC/B,MAAM7gB,EAAUigB,IAChB,IACGhG,IACGja,GACDA,EAAQ8gB,QAAQC,aAAeC,EAAAA,GAAAA,UAC9BhhB,EAAQid,YAEZ,OASF,OANAjd,EAAQihB,YAAYjhB,EAAQid,kBAC5BmC,GAAwBE,IAAD,IAClBA,EACHuB,SAAS,MAMb,MAAM1yB,EAAO2xB,IACbxtB,SAAS4uB,YACP,cAAc,EAAQ,2CAA0CF,EAAAA,GAAAA,YAAkC7yB,YAEpGqC,MACC,CAACyvB,EAAoBH,EAAiBtvB,EAASypB,EAAekF,EAAoB0B,UAE/EM,GAAiBxjC,EAAAA,EAAAA,KAAY,KACjCyhC,GAAwBE,IAEtBhtB,SAAS4uB,YAAY5B,EAAgB8B,KAAO,eAAiB,QAC7DhN,OAAOmM,KAAKjB,GAAiBngC,SAAS2W,IACvB,WAARA,GAA4B,cAARA,IAAwBlR,QAAQ06B,EAAgBxpB,KACvExD,SAAS4uB,YAAYprB,MAIzB+pB,IACO,IACFP,EACH8B,MAAO9B,EAAgB8B,WAG1B,CAACvB,IAEEwB,GAAmB1jC,EAAAA,EAAAA,KAAY,KACnC2U,SAAS4uB,YAAY,UACrBrB,IACAT,GAAwBE,IAAD,IAClBA,EACHgC,QAAShC,EAAgBgC,aAE1B,CAACzB,IAEE0B,GAAsB5jC,EAAAA,EAAAA,KAAY,KACtC2U,SAAS4uB,YAAY,aACrBrB,IACAT,GAAwBE,IAAD,IAClBA,EACHkC,WAAYlC,EAAgBkC,gBAE7B,CAAC3B,IAEE4B,GAA0B9jC,EAAAA,EAAAA,KAAY,KAC1C,GAAIwhC,EAAoBwB,cAAe,CACrC,MAAM3gB,EAAUigB,IAChB,IACGhG,IACGja,GACmB,QAApBA,EAAQ0f,UACP1f,EAAQid,YAEZ,OASF,OANAjd,EAAQihB,YAAYjhB,EAAQid,kBAC5BmC,GAAwBE,IAAD,IAClBA,EACHqB,eAAe,MAMnB,MAAMxyB,EAAO2xB,IACbxtB,SAAS4uB,YAAY,cAAc,EAAQ,QAAO/yB,WAClDqC,MACC,CACDyvB,EAAoBH,EAAiBtvB,EAASypB,EAAekF,EAAoBwB,gBAG7Ee,GAAsB/jC,EAAAA,EAAAA,KAAY,KACtC,GAAIwhC,EAAoBuB,UAAW,CACjC,MAAM1gB,EAAUigB,IAChB,IACGhG,IACGja,GACmB,SAApBA,EAAQ0f,UACP1f,EAAQid,YAEZ,OASF,OANAjd,EAAQihB,YAAYjhB,EAAQid,kBAC5BmC,GAAwBE,IAAD,IAClBA,EACHoB,WAAW,MAMf,MAAMvyB,EAAO2xB,IACbxtB,SAAS4uB,YAAY,cAAc,EAAQ,6CAA4C/yB,YACvFqC,MACC,CACDyvB,EAAoBH,EAAiBtvB,EAASypB,EAAekF,EAAoBuB,YAG7EiB,GAAuBhkC,EAAAA,EAAAA,KAAY,KACvC,MAAMikC,IAAoBC,EAAAA,EAAAA,GAAehD,IAAY,IAAIiD,MAAM,KAAKp/B,IAAIq/B,WAAW32B,KAAK,KAExF,GAAI2zB,EAAe,CACjB,MAAM/e,EAAUigB,IAChB,IAAKjgB,GAA+B,MAApBA,EAAQ0f,QACtB,OAOF,OAJC1f,EAA8BgiB,KAAOJ,OAEtCpxB,IAKF,MAAMrC,EAAO2xB,IACbH,IACArtB,SAAS4uB,YACP,cACA,EACC,WAAUU,yCAAwDzzB,SAErEqC,MACC,CAACyvB,EAAoBH,EAAiBf,EAAeF,EAASruB,EAASmvB,IAEpEpM,GAAgB51B,EAAAA,EAAAA,KAAaiL,IACjC,MAUMq5B,EAVqD,CACzDC,EAAGvD,EACHwD,EAAGhB,EACHiB,EAAGb,EACHliC,EAAGgiC,EACHgB,EAAGX,EACHY,EAAGb,EACHc,EAAG3B,GC3VM,SAAyBh4B,GACtC,MAAMkN,EAAM,QAASlN,EAAIA,EAAEkN,IAAMlN,EAAEgrB,KAEnC,OAAO9d,EAAI+d,WAAW,OAAS/d,EAAI0J,MAAM,GAAGgjB,cAAgB1sB,ED2V1B2sB,CAAgB75B,KAG9CA,EAAE00B,SACG10B,EAAE+qB,SAAW/qB,EAAE8qB,UAChBuO,IAKNr5B,EAAEoQ,iBACFpQ,EAAEM,kBACF+4B,OACC,CACDtD,EAAiBwC,EAAgBI,EAAqBF,EAAkBK,EACxED,EAAyBb,KAG3Bh5B,EAAAA,EAAAA,KAAU,KACJ2I,GACF+B,SAASghB,iBAAiB,UAAWC,GAGhC,IAAMjhB,SAASkhB,oBAAoB,UAAWD,KACpD,CAAChjB,EAAQgjB,IAEZ,MAAMxuB,GAAOC,EAAAA,EAAAA,KASb,IAAKkD,EACH,OAGF,MAAMjL,GAAYa,EAAAA,EAAAA,GAChB,gBACAsK,EACAs2B,GAAqB,sBAGjBgE,GAA0B5kC,EAAAA,EAAAA,GAC9B,iCACA8G,QAAQi6B,EAAQ//B,SAAW,SAGvBf,EAAQ8/B,EACT,SAAQA,EAAen+B,aAAam+B,EAAel+B,8BAA8Bk+B,EAAen+B,OACjG,GAEJ,OACE,0BACE+C,IAAK4vB,EACLp1B,UAAWA,EACXc,MAAOA,EACPo/B,UA/BJ,SAAgCv0B,GAChB,UAAVA,EAAEkN,KAAmB4oB,IACvBiD,IACA/4B,EAAEoQ,oBA8BF,0BAAK/b,UAAU,yBACb,mBAACgO,EAAA,EAAD,CACEE,MAAM,cACNE,UAAU,eACVpO,UAAWqjC,EAAyB,WACpC12B,QAASg3B,GAET,wBAAG3jC,UAAU,qBAEf,0BAAKA,UAAU,0BACf,mBAACgO,EAAA,EAAD,CACEE,MAAM,cACNE,UAAU,YACVpO,UAAWqjC,EAAyB,QACpC12B,QAASu3B,GAET,wBAAGlkC,UAAU,eAEf,mBAACgO,EAAA,EAAD,CACEE,MAAM,cACNE,UAAU,cACVpO,UAAWqjC,EAAyB,UACpC12B,QAASy3B,GAET,wBAAGpkC,UAAU,iBAEf,mBAACgO,EAAA,EAAD,CACEE,MAAM,cACNE,UAAU,kBACVpO,UAAWqjC,EAAyB,aACpC12B,QAAS23B,GAET,wBAAGtkC,UAAU,qBAEf,mBAACgO,EAAA,EAAD,CACEE,MAAM,cACNE,UAAU,qBACVpO,UAAWqjC,EAAyB,iBACpC12B,QAAS63B,GAET,wBAAGxkC,UAAU,wBAEf,mBAACgO,EAAA,EAAD,CACEE,MAAM,cACNE,UAAU,iBACVpO,UAAWqjC,EAAyB,aACpC12B,QAAS83B,GAET,wBAAGzkC,UAAU,oBAEf,0BAAKA,UAAU,0BACf,mBAACgO,EAAA,EAAD,CAAQE,MAAM,cAAcE,UAAWtG,EAAK,2BAA4B6E,QAAS+0B,GAC/E,wBAAG1hC,UAAU,gBAIjB,0BAAKA,UAAU,8BACb,0BAAKA,UAAU,yBACb,mBAACgO,EAAA,EAAD,CAAQE,MAAM,cAAcE,UAAWtG,EAAK,UAAW6E,QAASg1B,GAC9D,wBAAG3hC,UAAU,qBAEf,0BAAKA,UAAU,0BAEf,0BACEA,WAAWa,EAAAA,EAAAA,GAAe,uCAAwCmhC,IAElE,4BACEx8B,IAAKg8B,EACLxhC,UAAU,+BACVic,KAAK,OACLpY,MAAO+9B,EACPnnB,YAAY,eACZuB,aAAa,MACb0pB,UAAU,MACVj4B,IAAI,OACJ0O,SA5TZ,SAA6BxQ,GAC3Bk2B,EAAWl2B,EAAEyQ,OAAOvY,OACpBo/B,KA2TU0C,SAAU1C,KAId,0BAAKjjC,UAAWylC,GACd,0BAAKzlC,UAAU,0BACf,mBAACgO,EAAA,EAAD,CACEE,MAAM,cACNE,UAAWtG,EAAK,QAChB9H,UAAU,gBACV2M,QAAS+3B,GAET,wBAAG1kC,UAAU,wB,gBEnfZq6B,eAAeK,EAA8BkL,GAC1D,MAAMpL,EAAgB,GAEtB,SAASqL,EAAwBC,EAA+B3jC,GAC9D,OAAO,IAAI4jC,SAASC,IAClB,GAAIF,aAAiBG,KACnBzL,EAAMltB,KAAKw4B,GACXE,EAAQF,QACH,GAAIA,EAAMI,OAAQ,CACvB,MAAMC,EAAWhkC,EAAKikC,YACrBN,EAA8BO,MAAMA,IACnC7L,EAAMltB,KAAK+4B,GACXL,EAAQK,MACP,KAGGF,GACF3L,EAAMltB,KAAK64B,GAEbH,EAAQG,WAEDL,EAAMQ,aACIR,EAAmCS,eAC5CC,aAAaC,IACrB,MAAMC,EAAkB,GACxB,IAAK,IAAItkC,EAAI,EAAGA,EAAIqkC,EAAQ5kC,OAAQO,IAClCskC,EAAgBp5B,KAAKu4B,EAAwBY,EAAQrkC,GAAID,IAE3D6jC,EAAQD,QAAQY,IAAID,UAM5B,MAAMA,EAAkB,GACxB,IAAK,IAAItkC,EAAI,EAAGA,EAAIwjC,EAAkB/jC,OAAQO,IAAK,CACjD,MAAMD,EAAOyjC,EAAkBxjC,GAC/B,GAAkB,SAAdD,EAAKykC,KAAiB,CACxB,MAAMd,EAAQ3jC,EAAK0kC,oBAAsB1kC,EAAKikC,YAC1CN,GACFY,EAAgBp5B,KAAKu4B,EAAwBC,EAAO3jC,KAO1D,aAFM4jC,QAAQY,IAAID,GAEXlM,EAAM/0B,IAAIqhC,GAInB,SAASA,EAAWT,GAClB,MAAMU,EAAMV,EAAK3vB,KAAKmuB,MAAM,KAAKmC,MACjC,OAAKX,EAAKpqB,MAA8B,QAAtB8qB,EAAIxB,cAGfc,EAFE,IAAIJ,KAAK,CAACI,GAAOA,EAAK3vB,KAAM,CAAEuF,KAAM,oB,mDCtD/C,MAAMgrB,EAAQ,oBACRC,EAAW,mBACXC,EAAgB,oBAChBC,EAAoB,OAEnB,SAASC,EAAiB5oB,GAC/B,OAAOA,EACJyK,QAAQge,EAAU,KAClBhe,QAAQ+d,EAAO,MACf/d,QAAQie,EAAe,IACvBje,QAAQke,EAAmB,M,gBCRzB,SAAS9I,EAAuBJ,EAAuBoJ,GAC5D,MAAM,wBAAE/E,GAA4BrE,EACpC,IAAIqJ,EAAiChF,EACjCiF,EAAa,EACjB,KAAOD,GAAcA,EAAWjoC,KAAOgoC,GAAWE,EANxB,GAOxBD,EAAaA,EAAWjF,cACxBkF,IAGF,OAAO7/B,QAAQ4/B,GAAcA,EAAWjoC,KAAOgoC,G,oICTjD,MAAMG,EAAQ,IAAIC,QAKH,SAASC,EAAgCC,GACtD,OAAO,WACL,MAAMC,EAASJ,EAAMK,IAAIF,GADuB,2BAAvCG,EAAuC,yBAAvCA,EAAuC,gBAEhD,GAAIF,IAAUG,EAAAA,EAAAA,IAAqBH,EAAOI,SAAUF,GAClD,OAAOF,EAAOK,WAGhB,MAAM3kC,EAASqkC,KAAMG,GAErB,OADAN,EAAMU,IAAIP,EAAI,CAAEK,SAAUF,EAAMG,WAAY3kC,IACrCA,G,0BCQX,IAAI6kC,EACAC,EACAC,EAEAC,EACJ,MAGMC,EAA0Bb,GAmIhC,SAA6BrV,EAA6BmW,EAA0BC,GAClF,OAAKpW,GAASmW,EAAe5mC,OAItBs1B,OAAOC,QAAOuR,EAAAA,EAAAA,IAAWrW,EAAMmW,IAAiBlmB,MAAM,EAAGmmB,GAHvDhnB,EAAAA,KApILknB,EAAqBjB,GA0I3B,SACErV,EACAuW,EACAC,GAEA,MAAMC,EAAS5R,OAAOC,OAAO9E,GAEvB0W,GAAWC,EAAAA,EAAAA,IAA4BF,EAAQ,UAC/CG,EAAsBL,GACxB9S,EAAAA,EAAAA,IAAU8S,GAAoBM,GACvBhS,OAAOC,QAAOuR,EAAAA,EAAAA,IAAWK,EAAUG,MAE1C,GACEC,EAAkBN,GACpB/S,EAAAA,EAAAA,IAAU+S,GAAgBK,GACnBhS,OAAOC,QAAOuR,EAAAA,EAAAA,IAAWK,EAAUG,MAE1C,GAEEE,EAAY,IAAKH,KAAwBE,GACzCE,EAAY,GAAgB3O,OAAOxD,OAAOmM,KAAK4F,GAAsB/R,OAAOmM,KAAK8F,IAEjFG,EAASR,EAAOpT,QAAO,CAACpyB,EAAQklB,KACpCA,EAAM+gB,MAAMtnC,SAASwU,IACdnT,EAAOmT,KACVnT,EAAOmT,GAAQ,IAGjBnT,EAAOmT,GAAMpJ,KAAKmb,MAGbllB,IACN,IAIH,MAAO,CACL8lC,UAAAA,EACAC,SAAAA,EACAC,OAAAA,EACAC,MANYrS,OAAOmM,KAAKiG,OA3KtBE,EAAsB9B,GAqL5B,SAAyB+B,EAAkBpb,EAAgBoa,GACzD,MAAM,UACJW,EADI,SACOC,EADP,OACiBC,EADjB,MACyBC,GAC3BE,EAEJ,IAAIC,EAAmBjoB,EAAAA,EAEvB,MAAMkoB,EAAkBN,EAAShb,QAAQub,GAAYA,EAAQjT,WAAWtI,KAASwb,OACjFH,EAAUA,EAAQhP,OAAOxD,OAAOC,QAAOuR,EAAAA,EAAAA,IAAWU,EAAYO,IAAkBG,QAGhF,MAAMC,EAAeR,EAAMlb,QAAQ5X,GAASA,EAAKkgB,WAAWtI,KAK5D,OAJAqb,EAAUA,EAAQhP,OAAOxD,OAAOC,QAAOuR,EAAAA,EAAAA,IAAWY,EAAQS,IAAeD,QAEzEJ,GAAUM,EAAAA,EAAAA,IAAON,GAEVA,EAAQpnB,MAAM,EAAGmmB,MAnM1B,IACEH,EAAkB,+BAClB,MAAO58B,GAEP48B,EAAkB,4BAGL,SAAS2B,EACtBC,EACAC,EACA3B,GAMA,IALAnB,EAKA,uDALU/I,EAAAA,GACV8L,EAIA,uCAHAxB,EAGA,uCAFAC,EAEA,uCADAwB,EACA,wDACA,MAAOh3B,EAAQi3B,EAAYC,IAAgBrqC,EAAAA,EAAAA,MACpCmyB,EAAMmY,IAAWtiC,EAAAA,EAAAA,OACjBuiC,EAAwBC,IAA6BxiC,EAAAA,EAAAA,KAAS,IAC9DyiC,EAAgBC,IAAqB1iC,EAAAA,EAAAA,IAAkBuZ,EAAAA,IAG9D/W,EAAAA,EAAAA,KAAU,KACR,GAAI2/B,EAAY,OAChB,MAAM/K,EAAO,KACXkL,EAAQnC,EAAUS,SAGhBT,EACF/I,IAEAuL,IACGC,KAAKxL,KAET,CAAC+K,IAEJ,MAAM7rB,EAAO2rB,EAAQ5/B,SACrBG,EAAAA,EAAAA,KAAU,KACR,IAAKw/B,IAAc1rB,IAAS6T,GAAQgY,EAElC,YADAE,IAIF,MAAM7T,EAAOlY,EAAKlB,SAAS,MAAQytB,EAAavsB,GAChD,IAAKkY,EAGH,OAFAkU,EAAkBnpB,EAAAA,QAClB8oB,IAIF,MAAMS,EAAYtU,EAAK90B,OAAS,GAAK80B,EAAKuU,SAAS,KAC7C5c,EAASqI,EAAKwU,OAAO,EAAGF,EAAYtU,EAAK90B,OAAS,OAAIpC,GAC5D,IAAIkqC,EAAmBjoB,EAAAA,EAIvB,GAFAipB,EAA0BM,GAErB3c,GAEE,GAAIA,EAAOzsB,QAjEI,EAiEyB,CAC7C,MAAM6nC,EAAUd,EAAmBtW,EAAMuW,EAAmBC,GAC5Da,EAAUF,EAAoBC,EAASpb,EApExB,UAiEfqb,EAAUnB,EAAwBlW,EAAMmW,EAjEzB,IAuEbkB,EAAQ9nC,QACLopC,GACHV,IAEFM,EAAkBlB,IAElBa,MAED,CACDlY,EAAM7T,EAAM0rB,EAAWI,EAAY9B,EAAgB+B,EAAcG,EACjEL,EAAYzB,EAAmBC,IAGjC,MAAMsC,GAAc1qC,EAAAA,EAAAA,KAAY,CAAC2qC,EAAmBC,KAClD,MAAMC,EAAcnB,EAAQ5/B,QACtBghC,EAAUD,EAAYE,YAAY,IAAKH,EAAUC,EAAYE,YAAY,KAAO,OAAIhsC,GAC1F,IAAiB,IAAb+rC,EAAgB,CAElB,IAAIE,EADJrB,EAAc,GAAEkB,EAAYJ,OAAO,EAAGK,MAAW99B,EAAAA,EAAAA,GAAW29B,EAAW,CAAC,kBAGtEK,EADEpE,IAAY/I,EAAAA,GACClpB,SAAS2N,cAA8B2oB,EAAAA,IAEvCt2B,SAASu2B,eAAetE,GAEzC3rB,uBAAsB,MACpB6hB,EAAAA,EAAAA,GAAqBkO,GAAc,GAAM,MAI7ClB,MACC,CAACJ,EAAS9C,EAAS+C,EAAcG,IAQpC,OANA7/B,EAAAA,EAAAA,KAAU,KACJ2I,GAAUo3B,GAA0BE,EAAe/oC,QACrDupC,EAAYR,EAAe,GAAGiB,QAAQ,KAEvC,CAACjB,EAAgBQ,EAAa93B,EAAQo3B,IAElC,CACLoB,mBAAoBx4B,EACpBy4B,kBAAmBvB,EACnBI,eAAAA,EACAQ,YAAAA,GAIJ,SAASJ,EAAavsB,GACpB,MAAMsqB,GAAS1B,EAAAA,EAAAA,GAAiB5oB,GAAMqY,MAAMyR,GAE5C,OAAOQ,EAASA,EAAO,GAAG5f,YAAS1pB,EAGrC46B,eAAeyQ,IAQb,OAPK1C,IACHA,EAAmB,qCACnBC,SAAsBD,GAAkB4D,QAExC1D,GAAY2D,EAAAA,EAAAA,IAAgB5D,IAGvBD,I,uICjJT,MAAM8D,GAAeC,E,SAAAA,KAAUC,GAAOA,KAAM,KAAK,GACjD,IAAIC,EAEJ,IACEA,EAAqB,kCACrB,MAAO1gC,GAEP0gC,EAAqB,0BAGR,SAASC,EACtBC,EACAnC,EACAC,GAKA,IAJA/C,EAIA,uDAJkB/I,EAAAA,GAClBiO,EAGA,uCAFAC,EAEA,uCADAv5B,EACA,uCACA,MAAOI,EAAQi3B,EAAYC,IAAgBrqC,EAAAA,EAAAA,MACpCusC,EAAgBC,IAAqBxkC,EAAAA,EAAAA,MAEtCykC,GAAsBlsC,EAAAA,EAAAA,KAAY,CAAC4tB,EAAQue,KAE/C,MAAMza,GAAYnO,EAAAA,EAAAA,MAAYoO,MAAMC,MAE9Bka,GAAoBC,IAAqBra,EAM/C8Z,GAAa,KACX,MAAMY,EAAYN,MAAAA,OAAH,EAAGA,EAAkB7W,QAAO,CAACC,EAAemX,KACrDA,EAAOr8B,SAAWwC,GACpB0iB,EAAItoB,KAAKy/B,EAAOr8B,QAGXklB,IACN,IAEGoX,GAAcC,EAAAA,EAAAA,KAAkBhD,EAAAA,EAAAA,IAAO,IACtC4C,GAAkBJ,GAAoB,MACvCK,GAAa,KACf1a,EAAW9D,GAEfqe,EAAkBxV,OAAOC,QAAOuR,EAAAA,EAAAA,IAAWvW,EAAW4a,QAnBtDL,OAAkBltC,KAqBnB,CAACyT,EAAes5B,EAAkBC,IAE/BhuB,EAAO2rB,EAAQ5/B,SACrBG,EAAAA,EAAAA,KAAU,KACR,IAAK4hC,IAAsB9tB,EAAK5c,OAE9B,YADA2oC,IAIF,MAAM0C,EAAiBzuB,EAAKlB,SAAS,MAAQ4vB,EAAkB1uB,GAE/D,GAAIyuB,EAAgB,CAClB,MAAM5e,EAAS4e,EAAiBA,EAAe/B,OAAO,GAAK,GAC3DyB,EAAoBte,EAAQ8e,EAAqB3uB,SAEjD+rB,MAED,CAAC+B,EAAmBK,EAAqBrC,EAAYC,EAAc/rB,KAEtE9T,EAAAA,EAAAA,KAAU,KACJ+hC,MAAAA,GAAAA,EAAgB7qC,OAClB0oC,IAEAC,MAED,CAACD,EAAYC,EAAckC,IAE9B,MAAMW,GAAgB3sC,EAAAA,EAAAA,KAAY,SAACiP,GAAsC,IAAvB29B,EAAuB,wDACvE,IAAK39B,EAAKiB,YAAagC,EAAAA,EAAAA,IAAuBjD,GAC5C,OAGF,MAAM49B,EAAe59B,EAAKiB,SACrB,IAAGjB,EAAKiB,WACR,uEAEqBmzB,EAAAA,GAAAA,yCACJp0B,EAAKrQ,2EAGpBsT,EAAAA,EAAAA,IAAuBjD,SAExB47B,EAAcnB,EAAQ5/B,QACtBghC,EAAUD,EAAYE,YAAY,KACxC,IAAiB,IAAbD,EAAgB,CAClBnB,EAAc,GAAEkB,EAAYJ,OAAO,EAAGK,KAAW+B,WACjD,MAAM7B,EAAer2B,SAASu2B,eAAetE,GAC7C3rB,uBAAsB,MACpB6hB,EAAAA,EAAAA,GAAqBkO,EAAc4B,MAIvC9C,MACC,CAACJ,EAAS9C,EAAS+C,EAAcG,IAEpC,MAAO,CACLgD,qBAAsBl6B,EACtBm6B,oBAAqBjD,EACrB6C,cAAAA,EACAK,qBAAsBhB,GAI1B,SAASS,EAAkB1uB,GACzB,MAAM7N,GAAWy2B,EAAAA,EAAAA,GAAiB5oB,GAAMqY,MAAMuV,GAE9C,OAAOz7B,EAAWA,EAAS,GAAGuY,YAAS1pB,EAGzC,SAAS2tC,EAAqB3uB,GAC5B,OAAOA,EAAKmY,WAAW,O,sEChIV,SAAS+W,EAAmCC,EAAiBC,GAC1E,MAAMvD,OAAuB7qC,IAAVouC,EACbC,GAAkBjmC,EAAAA,EAAAA,IAAOyiC,GACzByD,GAAalmC,EAAAA,EAAAA,MACbmmC,GAAcC,EAAAA,EAAAA,KAiCpB,OA/BAC,EAAAA,EAAAA,IAAY,KACN5D,IAIJwD,EAAgBtjC,SAAU,EAEtBujC,EAAWvjC,UACb0wB,aAAa6S,EAAWvjC,SACxBujC,EAAWvjC,aAAU/K,MAEtBmuC,IAEHjjC,EAAAA,EAAAA,KAAU,KACR,GAAI2/B,GAAcwD,EAAgBtjC,QAChC,OAGF,MAAM+0B,EAAO,KACXuO,EAAgBtjC,SAAU,EAC1BwjC,KAGEH,EAAS,EACXE,EAAWvjC,QAAU7F,OAAOyY,WAAWmiB,EAAMsO,GAE7CtO,MAGDqO,GAEIE,EAAgBtjC,U,2DCpBzB,MA0CA,GAAe7L,EAAAA,EAAAA,KA1CqB,IAQ9B,IAR+B,GACnCW,EADmC,QAEnC8lB,EAFmC,SAGnCC,EAAW,GAHwB,SAInC7I,EAJmC,MAKnCnS,EALmC,eAMnC8jC,EANmC,SAOnChyB,GACI,EACJ,MAAOib,EAAQgX,IAAajmC,EAAAA,EAAAA,IAAmBkd,GAAY,IAErDgpB,GAAe3tC,EAAAA,EAAAA,KAAaob,IAChC,MAAM,MAAEjY,EAAF,QAASoO,GAAY6J,EAAM6B,cACjC,IAAI2wB,EAEFA,EADEr8B,EACU,IAAImlB,EAAQvzB,GAEZuzB,EAAO9I,QAAQigB,GAAMA,IAAM1qC,IAGzCuqC,EAAUE,GACVnyB,EAASmyB,KACR,CAACnyB,EAAUib,IAEd,OACE,0BAAK93B,GAAIA,EAAIU,UAAU,eACpBolB,EAAQ3f,KAAK+oC,GACZ,mBAAC,IAAD,CACEx8B,MAAOw8B,EAAOx8B,MACdy8B,SAAUD,EAAOC,SACjB5qC,MAAO2qC,EAAO3qC,MACdoO,SAA6C,IAApCoT,EAAS5H,QAAQ+wB,EAAO3qC,OACjC2Y,SAAUA,EACVnS,MAAOA,EACPgQ,UAAW8zB,GAA2D,IAA1CA,EAAe1wB,QAAQ+wB,EAAO3qC,YAAgBpE,EAC1E0c,SAAUkyB,W,0FC/BpB,MAqDA,GAAe1vC,EAAAA,EAAAA,KArDqB,IAa9B,IAb+B,OACnC2U,EADmC,QAEnCC,EAFmC,oBAGnCC,EAHmC,MAInCvG,EAJmC,OAKnCuH,EALmC,KAMnCtD,EANmC,UAOnCw9B,EAPmC,aAQnCC,EAAe,UARoB,eASnCC,EATmC,qBAUnCC,EAVmC,kBAWnCC,EAXmC,SAYnCC,GACI,EACJ,MAAMjnC,GAAOC,EAAAA,EAAAA,KAGPqtB,GAAevtB,EAAAA,EAAAA,IAAuB,MAEtCmnC,GAAwBtuC,EAAAA,EAAAA,KAAauuC,KAC1B,IAAXA,GAAcL,MACjB,CAACA,IAEEtY,GAAgB4Y,EAAAA,EAAAA,GAA0B9Z,EAAc9hB,EAAQ07B,EAAuB,WAE7F,OACE,mBAAC,IAAD,CACEhvC,UAAU,UACViN,MAAOA,GAASnF,EAAK,YACrB0M,OAAQA,EACRlB,OAAQA,EACRC,QAASA,EACTC,oBAAqBA,GAEpBtC,GAAQA,EAAK2zB,MAAM,OAAOp/B,KAAK0pC,GAC9B,4BAAIA,KAELT,GAAaK,EACd,0BAAK/uC,UAAW8uC,EAAoB,sBAAwB,GAAItpC,IAAK4vB,EAAc8K,UAAW5J,GAC5F,mBAAC,IAAD,CACEt2B,UAAU,wBACV2U,QAAM,EACNhI,QAASiiC,EACT1gC,MAAO2gC,EAAuB,SAAW,WAExCF,GAEH,mBAAC,IAAD,CAAQ3uC,UAAU,wBAAwB2U,QAAM,EAAChI,QAAS4G,GAAUzL,EAAK,iB,+ECnDjF,MAiCA,EAjC2C,IAQrC,IARsC,QAC1C2lB,EAD0C,UAE1CztB,EAF0C,MAG1CkO,EAAQ,UAHkC,UAI1CE,EAJ0C,SAK1CoO,EAL0C,QAM1C7P,EAN0C,SAO1CoiC,GACI,EACJ,MAAMjnC,GAAOC,EAAAA,EAAAA,KAEPqnC,GAAkBvuC,EAAAA,EAAAA,GACtB,uBACA4sB,GAAW,WACXztB,GAGF,OACE,mBAAC,IAAD,CACEA,UAAWovC,EACXlhC,MAAOA,EACP7D,OAAK,EACLmS,SAAUA,EACV7P,QAAS8gB,IAAYjR,EAAW7P,OAAUlN,EAC1C2O,UAAWA,EACX8N,UAAW,EACXlU,MAAOF,EAAKE,OAEX+mC,K,uKCGP,MA2LA,EA3L+B,IAyBzB,IAzB0B,IAC9BvpC,EAD8B,UAE9B6pC,EAF8B,KAG9Bz9B,EAH8B,YAI9B09B,EAJ8B,gBAK9BF,EAL8B,cAM9BG,EAN8B,aAO9BC,EAP8B,UAQ9BxvC,EAR8B,MAS9Bc,EAT8B,SAU9BiuC,EAV8B,SAW9BvyB,EAX8B,mBAY9BizB,EAZ8B,OAa9BxhC,EAb8B,OAc9B6D,EAd8B,SAe9BI,EAf8B,MAgB9BwJ,EAhB8B,YAiB9Bg0B,EAjB8B,UAkB9B79B,EAlB8B,SAmB9BE,EAnB8B,eAoB9BqhB,EApB8B,YAqB9B1K,EArB8B,QAsB9B/b,EAtB8B,qBAuB9BgjC,EAvB8B,YAwB9Bpf,GACI,EAEA6E,GAAevtB,EAAAA,EAAAA,IAAuB,MACtCrC,IACF4vB,EAAe5vB,GAEjB,MAAOoqC,EAAWC,EAAeC,IAAmB3vC,EAAAA,EAAAA,MAE9C,kBACJ2mB,EADI,oBACeC,EADf,wBAEJC,EAFI,kBAEqBC,EAFrB,uBAGJC,EAHI,sBAGoBC,IACtBC,EAAAA,EAAAA,GAAuBgO,GAAehC,GAEpC/L,GAAoB3mB,EAAAA,EAAAA,KAAY,IAAM00B,EAAa5qB,SAAS,IAE5D8c,GAAiB5mB,EAAAA,EAAAA,KACrB,IAAM00B,EAAa5qB,QAAS+c,QAAQ,mBACpC,IAGIC,GAAiB9mB,EAAAA,EAAAA,KACrB,IAAM00B,EAAa5qB,QAASwY,cAAc,mCAC1C,KAGI,UACJyE,EADI,UACOC,EADP,iBACkBC,EADlB,iBACoCC,EAAkB9mB,MAAO+mB,KAC/DC,EAAAA,EAAAA,GACFf,EACAM,EACAC,EACAE,GAGI/Q,IAAc/V,EAAAA,EAAAA,KAAaiL,IAC1B6Q,IAAaizB,IAAwB9iC,IAG1CA,EAAQhB,GAEJ8P,EAAAA,KAAiBxN,IACnB4hC,KACApd,EAAAA,EAAAA,IAAQqd,OAET,CAACL,EAAoBjzB,EAAUqzB,EAAeljC,EAASsB,EAAQ6hC,IAE5DC,GAA4BpkC,IAC3B6Q,IAAaizB,GAAoC,IAAb9jC,EAAEQ,SAAkBwjC,IAAyBvc,IACtFznB,EAAEM,kBACE0jC,EACFA,EAAqBhkC,GAErBsb,EAAkBtb,KAIhBqkC,IAAkBtvC,EAAAA,EAAAA,KAAaiL,IAC/BuG,GAAYuJ,EAAAA,MAGZ2X,GAAgC,IAAbznB,EAAEQ,QAAiBQ,GACxCqa,EAAwBrb,GAET,IAAbA,EAAEQ,SACCQ,EAGH8J,GAAY9K,GAFZsb,EAAkBtb,OAKrB,CAACuG,EAAUkhB,EAAgBzmB,EAASqa,EAAyBC,EAAmBxQ,KAE7E3O,IAAOC,EAAAA,EAAAA,KAEPoF,IAAgBtM,EAAAA,EAAAA,GACpB,WACAb,GACC+R,GAAY,eACb9D,GAAU,aACV6D,GAAU,SACV0K,GAAY,WACZizB,GAAsB,gBACtBv9B,GAAY,WACZ6U,GAAuB,gBACvBrL,GAAS,QACTg0B,GAAe,cACf79B,GAAa,YACbE,GAAY,aAGd,OACE,0BACEvM,IAAK4vB,EACLp1B,UAAWmN,GACXM,IAAK3F,GAAKE,MAAQ,WAAQvI,EAC1BqB,MAAOA,EACP4nB,YAAaA,EACb6H,YAAaA,GAEb,0BACEvwB,WAAWa,EAAAA,EAAAA,GAAe,kBAAmB+uC,GAAa,SAAUR,GACpE7yB,KAAOxK,OAAsBtS,EAAX,SAClB+F,IAAK6pC,EACLnzB,SAAWnK,OAAetS,EAAJ,EACtBkN,SAAWuF,GAAYuJ,EAAAA,GAAgBhF,QAAchX,EACrDipB,YAAasnB,GACbl2B,eAAiB5H,GAAYkhB,EAAkBnM,OAAoBxnB,GAElE6vC,EACA19B,GACC,wBAAG5R,UAAY,QAAO4R,MAEvBC,GAAc,0BAAK7R,UAAU,kBAAkB+uC,IAC9Cl9B,GAAak9B,GACbvyB,IAAatK,GAAYjE,GACzB,mBAAC,IAAD,MAEDshC,GACC,mBAAC,IAAD,CACEvvC,UAAU,iBACVqK,OAAK,EACL6D,MAAM,cACNtN,KAAK,UACL+L,QAAS8O,EAAAA,GAAes0B,QAA2BtwC,EACnDipB,YAAcjN,EAAAA,QAA0Chc,EAA3BswC,IAE7B,wBAAG/vC,UAAY,QAAOuvC,OAGzBC,GAEFpc,QAA0C3zB,IAAxBsnB,GACjB,mBAAC,IAAD,CACEzT,OAAQwT,EACRa,iBAAkBA,EAClBC,iBAAkBA,EAClBH,UAAWA,EACXC,UAAWA,EACX5mB,MAAO+mB,GACP7nB,UAAU,wBACV+oB,WAAS,EACTxV,QAAS2T,EACT1T,oBAAqB2T,GAEpBiM,EAAe3tB,KAAKoW,GACnB,mBAAC,IAAD,CACEhD,IAAKgD,EAAO5O,MACZ2E,KAAMiK,EAAOjK,KACb89B,YAAa7zB,EAAO6zB,YACpBlzB,UAAWX,EAAOmpB,QAClBr4B,QAASkP,EAAOmpB,SAEfnpB,EAAO5O,a,2DCtOtB,MCiBA,EANoC,IAAmB,IAAlB,UAAEjN,GAAgB,EACrD,OACE,0BAAKA,WAAWa,EAAAA,EAAAA,GDbG,uBCayBb,O,gHCiBhD,MAAMiwC,EAAmB,IAyEzB,EAtEmC,IAI7B,IAJ8B,MAClChjC,EADkC,UAC3BjN,EAD2B,QAElC6F,EAFkC,SAEzB0D,EAAW0mC,EAFc,YAEIjV,EAFJ,UAEiBkV,EAFjB,OAGlCr0B,EAHkC,WAG1Bs0B,GACJ,EACJ,MAAO78B,EAAQ88B,IAAajoC,EAAAA,EAAAA,KAAS,GAE/BkoC,GAAWxoC,EAAAA,EAAAA,IAA2B,OACtC,qBAAEsD,IAAyBE,EAAAA,EAAAA,GAAkBiI,GAE7Cg9B,GAAkB5vC,EAAAA,EAAAA,KAAY,KAClC0vC,GAAU,GACVhzB,WAAW8yB,EAdY,IAcoBpd,EAAAA,MAC1C,CAACod,KAOJvlC,EAAAA,EAAAA,KAAU,IAAO2I,GAAS6mB,EAAAA,EAAAA,GAAsBmW,QAAmB7wC,GAAY,CAAC6T,EAAQg9B,KAExF3lC,EAAAA,EAAAA,KAAU,KACR0lC,EAAS7lC,QAAU7F,OAAOyY,WAAWkzB,EAAiB/mC,GAE/C,KACD8mC,EAAS7lC,UACX0wB,aAAamV,EAAS7lC,SACtB6lC,EAAS7lC,aAAU/K,MAGtB,CAAC8J,EAAU+mC,IAEd,MAAMC,GAAmB7vC,EAAAA,EAAAA,KAAY,KAC/B2vC,EAAS7lC,UACX0wB,aAAamV,EAAS7lC,SACtB6lC,EAAS7lC,aAAU/K,KAEpB,IAEG+wC,GAAmB9vC,EAAAA,EAAAA,KAAY,KACnC2vC,EAAS7lC,QAAU7F,OAAOyY,WAAWkzB,EAAiB/mC,KACrD,CAACA,EAAU+mC,IAEd,OACE,mBAAC,IAAD,CAAQtwC,UAAU,yBAAyBg7B,YAAaA,GACtD,0BACEh7B,WAAWa,EAAAA,EAAAA,GAAe,eAAgBsK,EAAsBnL,GAChE2M,QAjCN,WACEkP,MAAAA,GAAAA,IACAy0B,KAgCIG,aAAcF,EACdG,aAAcF,GAEd,0BAAKxwC,UAAU,WACZiN,GAAS,0BAAKjN,UAAU,sBAAsBiN,GAC9CpH,GAEFgW,GAAUs0B,GACT,mBAAC,IAAD,CACEjiC,MAAM,oBACNvB,QAASkP,EACT7b,UAAU,uBAETmwC,O,2DCzFb,MAAMQ,EAAW,CACftL,EAAG,GAAID,EAAG,GAAI1hC,EAAG,GAAIktC,GAAI,IA2E3B,GAAejyC,EAAAA,EAAAA,KA9DV,IAOC,IAPA,SACJ6C,EAAW,EADP,KAEJZ,EAAO,IAFH,OAGJiwC,EAHI,YAIJtiC,EAJI,QAKJC,EALI,QAMJ7B,GACI,EACJ,MAAMhK,EAASguC,EAAS/vC,GAClBkwC,EAAenuC,EAASouC,EACxBC,EAAeruC,EAAS,EACxBsuC,EAA+B,EAAfH,EAAmBvuC,KAAK2uC,GAExCC,GAAYtpC,EAAAA,EAAAA,IAAuB,OAEzC8C,EAAAA,EAAAA,KAAU,KACR,IAAKwmC,EAAU3mC,QACb,OAGF,MAAM4mC,EAAMD,EAAU3mC,QAAQ6mC,kBACxBC,EAAmBL,EAAgB1uC,KAAK2H,IAAI3H,KAAKC,IA/BtC,IA+BwDhB,GA9BxD,GA8BmFyvC,EAE/FG,EAmBFA,EAAIC,kBAAiCE,aAAa,oBAAqBD,EAAiBjT,YAlBzF8S,EAAU3mC,QAAQ6yB,UAAa,8BACC,EAAf2T,KAAmC,EAAfA,uBACV,EAAfA,sBACc,EAAfA,+IAMaC,KAAiBA,qCAChBK,qDAEjBR,mBACCE,mBACAA,gCAMV,CAACG,EAAWF,EAAeD,EAAcF,EAActvC,IAE1D,MAAMxB,GAAYa,EAAAA,EAAAA,GACf,wBAAuBD,IACxB2N,GAAe,cACfsiC,GAAU,SACVriC,GAAW,YAGb,OACE,0BACEhJ,IAAK2rC,EACLnxC,UAAWA,EACX2M,QAASA,Q,iFCtDf,MAwCA,GAAehO,EAAAA,EAAAA,KAxCa,IAWtB,IAXuB,GAC3BW,EAD2B,MAE3B0S,EAF2B,SAG3By8B,EAH2B,MAI3B5qC,EAJ2B,KAK3B6S,EAL2B,QAM3BzE,EAN2B,SAO3BuK,EAP2B,OAQ3Bg1B,EAR2B,UAS3Bn3B,EAT2B,SAU3B8B,GACI,EACJ,MAAMrU,GAAOC,EAAAA,EAAAA,KACP/H,GAAYa,EAAAA,EAAAA,GAChB,QACA2b,GAAY,WACZg1B,GAAU,gBACVn3B,GAAa,WAGf,OACE,4BAAOra,UAAWA,EAAWyN,IAAK3F,EAAKE,MAAQ,WAAQvI,GACrD,4BACEwc,KAAK,QACLvF,KAAMA,EACN7S,MAAOA,EACPvE,GAAIA,EACJ2S,QAASA,EACTkK,SAAUA,EACVK,SAAUA,GAAYg1B,IAExB,0BAAKxxC,UAAU,cACb,2BAAMA,UAAU,QAAQyN,IAAK3F,EAAKE,MAAQ,YAASvI,GAAYuS,GAC9Dy8B,GAAY,2BAAMzuC,UAAU,WAAWyN,IAAK3F,EAAKE,MAAQ,YAASvI,GAAYgvC,IAEhFp0B,GAAa,mBAAC+G,EAAA,EAAD,UCHpB,GAAeziB,EAAAA,EAAAA,KAjCkB,IAQ3B,IAR4B,GAChCW,EADgC,KAEhCoX,EAFgC,QAGhC0O,EAHgC,SAIhCC,EAJgC,SAKhC7I,EALgC,cAMhCi1B,EANgC,SAOhCt1B,GACI,EACJ,MAAMkyB,GAAe3tC,EAAAA,EAAAA,KAAaob,IAChC,MAAM,MAAEjY,GAAUiY,EAAM6B,cACxBxB,EAAStY,EAAOiY,KACf,CAACK,IAEJ,OACE,0BAAK7c,GAAIA,EAAIU,UAAU,eACpBolB,EAAQ3f,KAAK+oC,GACZ,mBAAC,EAAD,CACE93B,KAAMA,EACN1E,MAAOw8B,EAAOx8B,MACdy8B,SAAUD,EAAOC,SACjB5qC,MAAO2qC,EAAO3qC,MACdoO,QAASu8B,EAAO3qC,QAAUwhB,EAC1BmsB,OAAQhD,EAAOgD,OACfh1B,SAAUA,EACVnC,UAAWo3B,EAAgBA,IAAkBjD,EAAO3qC,WAAQpE,EAC5D0c,SAAUkyB,W,sEC1BpB,MA2EA,GAAe1vC,EAAAA,EAAAA,KA3EmB,IAY5B,IAZ6B,QACjCymB,EADiC,IAEjClb,EAAM,EAF2B,IAGjC1H,GAAM4iB,EAAUA,EAAQvjB,OAAS,EAAI,KAHJ,KAIjC6vC,EAAO,EAJ0B,MAKjC1/B,EALiC,MAMjCnO,EANiC,SAOjC2Y,EAPiC,KAQjC2nB,EARiC,UASjCnkC,EATiC,YAUjC2xC,EAViC,SAWjCx1B,GACI,EACJ,MAAMrU,GAAOC,EAAAA,EAAAA,KACPsmC,GAAe3tC,EAAAA,EAAAA,KAAaob,IAChCK,EAAS6a,OAAOlb,EAAM6B,cAAc9Z,UACnC,CAACsY,IAEEy1B,GAAgB/wC,EAAAA,EAAAA,GACpBb,EACA,cACAwc,GAAY,WACZ2nB,GAAQ,QAGJ0N,GAAa7nC,EAAAA,EAAAA,KAAQ,IACrBob,EACMvhB,GAASuhB,EAAQvjB,OAAS,GAAM,KAG/BgC,EAAQqG,KADa1H,EAAM0H,GAAOwnC,GACK,KAEjD,CAACtsB,EAASvhB,EAAOrB,EAAK0H,EAAKwnC,IAE9B,OACE,0BAAK1xC,UAAW4xC,GACb5/B,GACC,0BAAKhS,UAAU,iBAAiByN,IAAK3F,EAAKE,MAAQ,WAAQvI,GACxD,2BAAMO,UAAU,QAAQyN,IAAI,QAAQuE,IAClCoT,GACA,2BAAMplB,UAAU,QAAQyN,IAAI,QAAQkkC,EAAcA,EAAY9tC,GAASA,IAI7E,0BAAK7D,UAAU,eACb,0BACEA,UAAU,oBACVc,MAAQ,UAAS+wC,OAEnB,4BACE3nC,IAAKA,EACL1H,IAAKA,EACLqB,MAAOA,EACP6tC,KAAMA,EACNz1B,KAAK,QACLjc,UAAU,qBACVmc,SAAUkyB,IAEXjpB,GACC,0BAAKplB,UAAU,kBACZolB,EAAQ3f,KAAI,CAAC+oC,EAAQS,IACpB,0BACEjvC,WAAWa,EAAAA,EAAAA,GAAe,6BAA8BouC,IAAUprC,GAAS,UAC3E8I,QAAS,IAAMwP,EAAS8yB,IAEvBT,Y,2HChDjB,MAiHA,GAAe7vC,EAAAA,EAAAA,KAjHmB,IAqB5B,IArB6B,IACjC6G,EADiC,SAEjCupC,EAFiC,yBAGjC+C,EAHiC,MAIjCjuC,EAJiC,QAKjCyjC,EALiC,UAMjCtnC,EANiC,QAOjC+xC,EAPiC,UAQjC13B,EARiC,aASjC23B,EATiC,uBAUjCC,EAViC,YAWjCx3B,EAXiC,SAYjC+B,EAZiC,aAajCR,EAbiC,SAcjCgC,EAdiC,gBAejCk0B,EAfiC,SAgBjC/1B,EAhBiC,QAiBjCg2B,EAjBiC,QAkBjCC,EAlBiC,OAmBjCC,EAnBiC,eAoBjCC,GACI,EAEAn3B,GAAWtT,EAAAA,EAAAA,IAAyB,MACpCrC,IACF2V,EAAW3V,GAGb,MAAO+sC,EAAgBC,EAAkBC,IAAsBtyC,EAAAA,EAAAA,GAAQ4xC,IAEvEW,EAAAA,EAAAA,GAAoBv3B,EAAU+2B,EAAiBO,IAE/C9nC,EAAAA,EAAAA,KAAU,KACHwQ,EAAS3Q,UAIVunC,EACF52B,EAAS3Q,QAAQkR,QAEjBP,EAAS3Q,QAAQs1B,UAElB,CAACiS,EAASt3B,IAEb,MAAM3S,GAAOC,EAAAA,EAAAA,KAqBPuuB,GAAgB51B,EAAAA,EAAAA,KAAaiL,IACjC,GAAc,cAAVA,EAAEkN,KAAiC,UAAVlN,EAAEkN,IAAiB,CAC9C,MAAMkK,EAAU1N,SAAS2N,cAAe,IAAG8uB,sBACvC/uB,GACFA,EAAQrH,WAGX,CAACo2B,IAEJ,OACE,0BACE9xC,WAAWa,EAAAA,EAAAA,GAAe,cAAeb,EAAWuyC,GAAkB,aACtE9kC,IAAK3F,EAAKE,MAAQ,WAAQvI,GAEzBsvC,EACD,4BACEvpC,IAAK2V,EACL7b,GAAIgoC,EACJrrB,KAAK,OACLxO,IAAI,OACJgN,YAAaA,GAAe3S,EAAK,UACjC9H,UAAU,eACV6D,MAAOA,EACP2Y,SAAUA,EACVR,aAAcA,EACdG,SA5CN,SAAsBL,GACpB,MAAM,cAAE6B,GAAkB7B,EAC1BK,EAASwB,EAAc9Z,QA2CnBuuC,QAxCN,WACEI,IACIJ,GACFA,KAsCEC,OAlCN,WACEI,IACIJ,GACFA,KAgCEnS,UAAW5J,IAEb,wBAAGt2B,UAAU,gBACb,mBAAC,IAAD,CAAgBsT,OAAQ3L,QAAQ0S,GAAYra,UAAU,QACpD,mBAAC,IAAD,CAASkO,MAAO8jC,EAAcW,gBAAiBV,EAAwBtlC,QAAS2lC,MAEhFj4B,IAAcxW,GAASma,IAAam0B,GACpC,mBAAC,IAAD,CACE9nC,OAAK,EACLzJ,KAAK,OACLsN,MAAM,cACNvB,QAASwlC,GAET,2BAAMnyC,UAAU,qB,iFClI1B,MAuBA,EAvBqC,IAE/B,IAFgC,OACpCsT,EADoC,SAC5B0a,EAD4B,GAClB1uB,EADkB,UACdU,EADc,QACH2M,EADG,SACMoiC,GACtC,EACJ,MAAM,aAAE9jC,EAAF,qBAAgBE,IAAyBE,EAAAA,EAAAA,GAC7CiI,OAAQ7T,OAAWA,GAAWuuB,QAAmBvuB,GAE7CmzC,GAAahxB,EAAAA,EAAAA,GAAYtO,GACzBu/B,GAAejxB,EAAAA,EAAAA,GAAYmtB,GAC3B+D,GAAkBjrC,EAAAA,EAAAA,MAMxB,OAJI+qC,IAAet/B,IACjBw/B,EAAgBtoC,QAAUqoC,GAI1B5nC,GACE,0BAAK3L,GAAIA,EAAIU,WAAWa,EAAAA,EAAAA,GAAeb,EAAWmL,GAAuBwB,QAASA,GAC/E2G,EAASy7B,EAAW+D,EAAgBtoC,W,sECf7C,MAkBA,EAlB+B,IAQzB,IAR0B,QAC9BuoC,EAAU,cADoB,UAE9BC,EAAY,OAFkB,MAG9BpxC,EAH8B,OAI9BE,EAJ8B,iBAK9BmxC,EAL8B,OAM9BC,EAN8B,UAO9BlzC,GACI,EACJ,MAAMmzC,GAAatyC,EAAAA,EAAAA,GAAe,WAAYkyC,EAASC,EAAWhzC,EAAWkzC,GAAU,UAEjFpyC,EAAQmyC,EADOrxC,GAASE,EAAW,iBAAgBF,KAASE,SAAWrC,GAEzEsB,EAAAA,EAAAA,GAAW4G,QAAQ/F,IAAW,UAASA,MAAW+F,QAAQ7F,IAAY,WAAUA,OACpF,OACE,0BAAK9B,UAAWmzC,EAAYryC,MAAOA,GAAQoyC,GAAU,O,2DCXzD,MA6CA,GAAev0C,EAAAA,EAAAA,KA7CgB,IAWzB,IAX0B,GAC9BW,EAD8B,KAE9BoX,EAF8B,MAG9B7S,EAH8B,MAI9BmO,EAJ8B,QAK9BC,GAAU,EALoB,SAM9BuK,EAN8B,SAO9BtK,EAP8B,YAQ9BkhC,EAR8B,SAS9Bj3B,EAT8B,QAU9Bk3B,GACI,EACJ,MAAMhF,GAAe3tC,EAAAA,EAAAA,KAAaiL,IAC5BwQ,GACFA,EAASxQ,GAGP0nC,GACFA,EAAQ1nC,EAAEgS,cAAc1L,WAEzB,CAACkK,EAAUk3B,IAERrzC,GAAYa,EAAAA,EAAAA,GAChB,WACA2b,GAAY,WACZtK,GAAY,WACZkhC,GAAe,gBAGjB,OACE,4BAAOpzC,UAAWA,EAAWiN,MAAO+E,GAClC,4BACEiK,KAAK,WACL3c,GAAIA,EACJoX,KAAMA,EACN7S,MAAOA,EACPoO,QAASA,EACTuK,SAAUA,EACVL,SAAUkyB,IAEZ,2BAAMruC,UAAU,gB,mJCxCtB,MAAMmzC,EACI,cAsEV,GAAex0C,EAAAA,EAAAA,KAlEW,IAUpB,IAVqB,UACzBqB,EADyB,MAEzBiN,EAFyB,SAGzBqW,EAHyB,UAIzBgwB,EAJyB,WAKzBC,EALyB,cAMzBC,EANyB,kBAOzBC,EAPyB,QAQzB9mC,EARyB,SASzBsR,GACI,EAEJ,MAAMy1B,GAAS7rC,EAAAA,EAAAA,IAAuB,MAoCtC,OAlCA8C,EAAAA,EAAAA,KAAU,KAMR,GAJI2Y,QAAkC7jB,IAAtBg0C,GAAmCC,EAAOlpC,SACxDkpC,EAAOlpC,QAAQkoB,UAAU/xB,IAAIwyC,IAG1B7vB,QAAkC7jB,IAAtBg0C,EACf,OAGF,MAAME,EAAQD,EAAOlpC,QACfopC,EAAYD,EAAMrR,cAAeyM,SAAS0E,GAChD,IAAKG,EACH,OAGF,MAAMC,EAAaF,EAAM3wB,cAA2B,aAC9C8wB,EAAiBF,EAAU5wB,cAA2B,aAGtD+wB,EAAYD,EAAexR,cAAe0R,WAAaH,EAAWvR,cAAe0R,WACjFC,EAAcH,EAAeI,YAAcL,EAAWK,YAE5DJ,EAAephB,UAAUG,OAAO,WAChCghB,EAAWnhB,UAAUG,OAAO,WAC5BghB,EAAW/yC,MAAM8xB,UAAa,eAAcmhB,sBAA8BE,YAC1EE,EAAAA,EAAAA,GAAYN,GACZA,EAAWnhB,UAAU/xB,IAAI,WACzBkzC,EAAW/yC,MAAM8xB,UAAY,OAE7BghB,EAAUlhB,UAAUG,OAAOsgB,GAC3BQ,EAAMjhB,UAAU/xB,IAAIwyC,KACnB,CAAC7vB,EAAUmwB,IAGZ,0BACEzzC,WAAWa,EAAAA,EAAAA,GAAe,MAAOb,GACjC2M,QAAS,IAAMA,EAAQsR,GACvBzY,IAAKkuC,GAEL,gCACGhmC,EAAAA,EAAAA,GAAWT,GACXtF,QAAQ4rC,IACP,2BAAMvzC,WAAWa,EAAAA,EAAAA,GAAe,QAAS2yC,GA5DpC,uBA4D+ED,GAErFD,GAAa,wBAAGtzC,UAAU,4BAC3B,wBAAGA,UAAU,kBCrDfo0C,EAAkBpW,EAAAA,GAAS,IAAMuC,EAAAA,GAAa,IAAM,IA6D1D,GAAe5hC,EAAAA,EAAAA,KA3De,IAExB,IAFyB,KAC7B01C,EAD6B,WACvBC,EADuB,UACXC,EADW,IACA/1B,EADA,YACKg2B,GAC9B,EAEJ,MAAMpf,GAAevtB,EAAAA,EAAAA,IAAuB,MACtC4rC,GAAoB7xB,EAAAA,EAAAA,GAAY2yB,IAEtCE,EAAAA,EAAAA,GAAoBrf,EAAa5qB,aAAS/K,GAAW,IAGrDkL,EAAAA,EAAAA,KAAU,KACR,MAAMwmC,EAAY/b,EAAa5qB,SACzB,YAAE24B,EAAF,YAAeD,EAAf,WAA4BE,GAAe+N,EACjD,GAAIhO,GAAeD,EACjB,OAGF,MAAMwR,EAAmBvD,EAAUwD,WAAWJ,GAC9C,IAAKG,EACH,OAGF,MAAQV,WAAYY,EAAqB1R,YAAa2R,GAAyBH,EACzEI,EAAUF,EAAuB1R,EAAc,EAAM2R,EAAuB,EAG9EtyC,KAAK+8B,IAAIwV,EAAU1R,GA9BK,KAkC5B2R,EAAAA,EAAAA,GAA2B5D,EAAW2D,EAASV,KAC9C,CAACG,IAEJ,MAAMzsC,GAAOC,EAAAA,EAAAA,KAEb,OACE,0BACE/H,UAAY,sCAAoCwe,EAAM,MAAQ,IAC9DhZ,IAAK4vB,EACL3nB,IAAK3F,EAAKE,MAAQ,WAAQvI,GAEzB40C,EAAK5uC,KAAI,CAACuvC,EAAK5yC,KAAN,aACR,mBAAC,EAAD,CACEyW,IAAG,UAAEm8B,EAAI11C,UAAN,QAAY01C,EAAI/nC,MAEnBA,MAASqnC,GAAcU,EAAI11C,KAAOi2B,EAAAA,GAAmCyf,EAAI/nC,MAAtBnF,EAAKktC,EAAI/nC,OAC5DqW,SAAUlhB,IAAMmyC,EAChBjB,UAAW0B,EAAI1B,UACfC,WAAYyB,EAAIzB,WAChBC,cAAewB,EAAIxB,cACnBC,kBAAmBA,EACnB9mC,QAAS6nC,EACTv2B,SAAU7b,Y,uFCzEb,MAAM6yC,EAAwC,CACnD,CAAErjC,KAAM,OAAQ3E,MAAO,iBAAkB4L,IAAK,YAC9C,CAAEjH,KAAM,eAAgB3E,MAAO,oBAAqB4L,IAAK,eACzD,CAAEjH,KAAM,QAAS3E,MAAO,eAAgB4L,IAAK,UAC7C,CAAEjH,KAAM,UAAW3E,MAAO,iBAAkB4L,IAAK,YACjD,CAAEjH,KAAM,OAAQ3E,MAAO,aAAc4L,IAAK,SAG/Bq8B,EAAwC,CACnD,CAAEtjC,KAAM,OAAQ3E,MAAO,cAAe4L,IAAK,gBAC3C,CAAEjH,KAAM,UAAW3E,MAAO,iBAAkB4L,IAAK,mBACjD,CAAEjH,KAAM,YAAa3E,MAAO,aAAc4L,IAAK,gBAG3Cs8B,EAA2D,CAC/D,kBAAmB,OAAQ,WAAY,SAAU,WAAY,eAEzDC,EAA2D,CAC/D,kBAAmB,kBAAmB,eAAgB,eAGjD,SAASC,EAAkBC,EAAqBC,EAA+BC,GACpF,IAAIC,EAA4B,GAC5BC,EAA6C,GAEjD,GAAa,aAATH,EAAqB,CACvB,MAAM,gBACJI,KACGC,GACDJ,EACAF,EAAMM,gBAAkB,IACxBC,EAAAA,EAAAA,IACAP,EAAMQ,OACNX,GAGJM,EAAkBE,GAAmB,GACrCD,EAAqBve,OAAOmM,KAAKsS,GAC9BtnB,QAAQzV,GAAQlR,QAAQiuC,EAAe/8B,UACrC,CACL,MAAM,gBACJk9B,KACGC,GACDR,EACAF,EAAMU,gBAAkB,IACxBH,EAAAA,EAAAA,IACAP,EAAMQ,OACNV,GAGJK,EAAkBM,GAAmB,GACrCL,EAAqBve,OAAOmM,KAAK0S,GAC9B1nB,QAAQzV,GAAQlR,QAAQquC,EAAen9B,MAG5C,MAAO,CACL48B,gBAAAA,EACAC,kBAAAA,GAIJ,SAASO,EAAuBL,GAC9B,GAAIA,EAAgB,CAClB,MAAM,gBACJD,KACGO,GACDN,EAEJ,GACEze,OAAOC,OAAO8e,GAAS5nB,OAAO3mB,SAAS9F,OAAS,GAC5C8zC,MAAAA,GAAAA,EAAiB9zC,OAErB,MAAO,GAGT,GAAIq0C,EAAQC,KACV,MAAO,OACF,GAAID,EAAQE,OACjB,MAAO,SACF,GAAIF,EAAQG,SACjB,MAAO,WACF,GAAIH,EAAQI,SACjB,MAAO,WACF,GAAIJ,EAAQK,YACjB,MAAO,eAIX,MAAO,GAyBT,MAAMC,EAA8B,CAClCjB,KAAM,SACNkB,WAAY,GACZX,OAAQ,CACN7oC,MAAO,GACP0oC,gBAAiB,GACjBI,gBAAiB,KAIfW,EAA6D,CACjEpB,EACAz5B,KAEA,OAAQA,EAAOI,MACb,IAAK,WACH,MAAO,IACFq5B,EACHQ,OAAQ,IACHR,EAAMQ,OACT7oC,MAAO4O,EAAOiZ,SAEhB8a,WAAW,GAEf,IAAK,qBACH,MAAO,IACF0F,EACHM,gBAAgBC,EAAAA,EAAAA,IACdP,EAAMQ,OACNX,IAGN,IAAK,qBACH,MAAO,IACFG,EACHU,gBAAgBH,EAAAA,EAAAA,IACdP,EAAMQ,OACNV,IAGN,IAAK,oBACH,MAAO,IACFE,EACHM,eAAgB/5B,EAAOiZ,QACvB2hB,WAAY,IAEhB,IAAK,oBACH,MAAO,IACFnB,EACHU,eAAgBn6B,EAAOiZ,QACvB2hB,WAAY,IAEhB,IAAK,cACH,OAAInB,EAAMM,eACD,IACFN,EACHQ,OAAQ,KACHa,EAAAA,EAAAA,IAAKrB,EAAMQ,OAAQX,GACtBloC,MAAOqoC,EAAMQ,OAAO7oC,MAAQqoC,EAAMQ,OAAO7oC,MAAQgpC,EAAuBX,EAAMM,mBAC3EN,EAAMM,gBAEXA,oBAAgBn2C,EAChBg3C,WAAY,GACZ7G,WAAW,GAEJ0F,EAAMU,eACR,IACFV,EACHQ,OAAQ,KACHa,EAAAA,EAAAA,IAAKrB,EAAMQ,OAAQV,MACnBE,EAAMU,gBAEXA,oBAAgBv2C,EAChBg3C,WAAY,GACZ7G,WAAW,GAGN0F,EAEX,IAAK,aAAc,CACjB,MAAQh2C,GAAI8wB,EAAN,YAAgB3e,KAAgBqkC,GAAWj6B,EAAOiZ,QAExD,MAAO,CACLygB,KAAM,OACNnlB,SAAAA,EACA0lB,OAAAA,EACAW,WAAY,IAGhB,IAAK,gBACH,MAAO,IACFnB,EACHmB,WAAY56B,EAAOiZ,SAGvB,IAAK,eACH,MAAO,IACFwgB,EACHj7B,UAAWwB,EAAOiZ,SAGtB,IAAK,WACH,MAAO,IACFwgB,EACH/6B,MAAOsB,EAAOiZ,SAGlB,IAAK,QACH,OAAO0hB,EACT,QACE,OAAOlB,IAQb,EAJ0B,KACjBsB,EAAAA,EAAAA,GAAWF,EAAgBF,I,2HCvCpC,SAASK,EAAkBC,GACzB,IAAIC,EAAsC,GAC1C,GAAID,GAAiBA,EAActsC,QAAS,CAC1C,MAAM,KACJqe,EADI,MACExI,EADF,eACS/W,EADT,MACyB0tC,EADzB,iBACgCC,EADhC,qBACkDC,EADlD,QACwE/0B,EADxE,OACiFC,GACnF00B,EAActsC,QAClBusC,EAAgB,CACdluB,KAAM,KACJA,EAAKmuB,EAAMh2C,MAEbqf,MAAO,KACLA,KAEF82B,KAAM,KACJ92B,IACA/W,EAAe,IACflC,EAAAA,EAAAA,MAAagwC,oBAEfC,aAAev7B,IACb,MAAMw7B,EAAWx7B,EAAMy7B,YA3ML,GA4MlBjuC,EAAe/G,KAAKC,IAAIw0C,EAAM12B,YAAcg3B,EAAU,KAExDE,YAAc17B,IACZ,MAAMw7B,EAAWx7B,EAAMy7B,YA/ML,GAgNlBjuC,EAAe/G,KAAK2H,IAAI8sC,EAAM12B,YAAcg3B,EAAUN,EAAMztC,YAE9DkuC,OAAS37B,IACHA,EAAM47B,UACRpuC,EAAewS,EAAM47B,YAKtBt1B,MACH20B,EAAcY,UAAY,KACxBV,MAGC90B,MACH40B,EAAca,cAAgB,KAC5BV,MAIN,OAAOH,EAGT,QArOuB,SACrBc,EACAC,EACAC,EACA/2C,EACAg3C,EACAC,EACAC,GAMG,IALHlyB,EAKG,wDAJHmyB,EAIG,uCAHHC,EAGG,uCAFHC,EAEG,2DADHC,EACG,2DAEH,MAAMxB,GAAgBjvC,EAAAA,EAAAA,IAAoC,OAEnDuB,EAAWmvC,IAAgBpwC,EAAAA,EAAAA,KAAS,GAC3C,IAAIqwC,EAAgBpvC,EAEpB,MAAO/D,EAAcozC,IAAmBtwC,EAAAA,EAAAA,IAAiB,GAEnDY,GAAoBrI,EAAAA,EAAAA,KAAY,KACpC63C,GAAa,GACTH,GAAeA,MAClB,CAACA,KAEJlK,EAAAA,EAAAA,IAAY,KACV4I,EAActsC,SAAUkuC,EAAAA,EAAAA,IAASb,EAASE,GAAW,CAACY,EAAWhtC,KAAM,MACrE,OAAQgtC,GACN,IAAK,SAAU,CACb,MAAM,UACJC,EADI,gBACOC,EADP,YACwBC,EADxB,MACqC9B,GACvCF,EAActsC,QAClB+tC,GAAa,IAEbQ,EAAAA,EAAAA,GAAqBd,EAAUpB,EAAkBC,KACjDkC,EAAAA,EAAAA,IAAiB,WACjBJ,GAAU30B,EAAAA,EAAAA,MAAYg1B,YAAYC,QAClCJ,EAAYnxC,SAAQsc,EAAAA,EAAAA,MAAYg1B,YAAYnpC,UAC5C,MAAMvG,EAAWytC,EAAMztC,UAAYytB,OAAOmiB,SAASnC,EAAMztC,UAAYytC,EAAMztC,SAAWuuC,GACpE,UAAdC,GAAyBxuC,EAAW6vC,EAAAA,KACtCP,GAAgB50B,EAAAA,EAAAA,MAAYg1B,YAAYI,eAG1CC,EAAAA,EAAAA,IAAiB,CACf/vC,SAAUytC,EAAMztC,UAAY,EAC5B8vC,aAAcrC,EAAMqC,aACpBtiB,SAAUigB,EAAM12B,cAElB,MAEF,IAAK,eAAgB,CACnB,MAAM,MAAE02B,GAAUF,EAActsC,SAChC8uC,EAAAA,EAAAA,IAAiB,CACf/vC,SAAUytC,EAAMztC,UAAY,EAC5B8vC,aAAcrC,EAAMqC,aACpBtiB,SAAUigB,EAAM12B,cAElB,MAEF,IAAK,UACHi4B,GAAa,IACbS,EAAAA,EAAAA,IAAiB,UACjB,MACF,IAAK,eAAgB,CACnB,MAAM,MAAEhC,GAAUF,EAActsC,QAC1BjB,EAAWytC,EAAMztC,UAAYytB,OAAOmiB,SAASnC,EAAMztC,UAAYytC,EAAMztC,SAAWuuC,EACjFQ,GAAmBG,EAAgBzB,EAAM12B,YAAc/W,GAC5D,MAEF,IAAK,WACHyvC,EAAAA,EAAAA,IAAiB,UAKrBhB,MAAAA,GAAA,UAAAA,EAAWW,UAAX,cAAAX,EAAwBrsC,KACvBwsC,EAAapvC,GAEhB,MAAM,MAAEiuC,GAAUF,EAActsC,QAE3BpB,GAAc4tC,EAAMuC,SACvBhB,GAAa,GACbC,GAAgB,GAGdN,GACFA,EAAOlB,KAER,CAACa,KAEJltC,EAAAA,EAAAA,KAAU,KACJvB,GAAa6uC,IAAUuB,EAAAA,EAAAA,IAAevB,KACzC,CAACA,EAAU7uC,IAEd,MAAM,KACJyf,EADI,MAEJxI,EAFI,eAGJ/W,EAHI,MAIJ0tC,EAJI,QAKJyC,EALI,UAMJb,EANI,KAOJzB,EAPI,QAQJh1B,EARI,OASJC,EATI,iBAUJ60B,EAVI,qBAWJC,EAXI,gBAYJ2B,EAZI,YAaJC,GACEhC,EAActsC,QACZjB,EAAWytC,EAAMztC,UAAYytB,OAAOmiB,SAASnC,EAAMztC,UAAYytC,EAAMztC,SAAWuuC,GAGtFntC,EAAAA,EAAAA,KAAU,MACJpB,IAAamwC,EAAAA,EAAAA,GAAwB1C,IAAWsB,GAClDG,EAAgBzB,EAAM12B,YAAc/W,KAErC,CAACA,EAAUlE,EAAc2xC,EAAOsB,KAGnC3tC,EAAAA,EAAAA,KAAU,IAAM,KACd8uC,EAAQpB,KACP,CAACoB,EAASpB,KAGbsB,EAAAA,EAAAA,IAAsB,IAA+B,IAA7BC,EAAgBC,GAAa,EAC/CD,IAAmB5zB,GAAchlB,IAAQ64C,GAKzC7C,EAAMh2C,KAAOg2C,EAAMuC,QAInBvzB,GAAchlB,IAAQoI,GACxByf,EAAK7nB,KAEN,CAACglB,EAAYhlB,EAAKoI,EAAWyf,EAAMmuB,EAAMh2C,IAAKg2C,EAAMuC,SAEvD,MAAMO,GAAgBp5C,EAAAA,EAAAA,KAAY,KAC5BM,GACF6nB,EAAK7nB,KAEN,CAACA,EAAK6nB,IAEHxf,GAAY3I,EAAAA,EAAAA,KAAY,KACxB0I,EACFiX,IAEAy5B,MAED,CAACz5B,EAAOy5B,EAAe1wC,IAEpB2wC,GAAUr5C,EAAAA,EAAAA,KAAas5C,IAC3B1wC,EAAe0wC,GACXzwC,GACFkvC,EAAgBzB,EAAM12B,YAAc/W,KAErC,CAACA,EAAUytC,EAAO1tC,IAErB,MAAO,CACLF,UAAWovC,EACXnzC,aAAAA,EACAgE,UAAAA,EACAgX,MAAAA,EACAwI,KAAMixB,EACN3C,KAAAA,EACA7tC,eAAgBywC,EAChBnB,UAAAA,EACAqB,WAAYjD,EACZztC,SAAAA,EACA0tC,iBAAAA,EACAC,qBAAAA,EACA/0B,QAAAA,EACAC,OAAAA,EACAy2B,gBAAAA,EACAC,YAAAA,K,sEC3IJ,SAASoB,EAAcC,EAAoB5wC,GACzC,MAAMhG,EAA0B,GAChC,IAAK,IAAInB,EAAI,EAAGA,EAAI+3C,EAAOt4C,OAAQO,IACjCmB,EAAO+J,KAAK,CACV5H,MAAOy0C,EAAOz0C,MAAMtD,GAAKmH,EACzB5D,IAAKw0C,EAAOx0C,IAAIvD,GAAKmH,IAGzB,OAAOhG,EAGT,QAvDqB,WAAiC,IAAhC62C,EAAgC,wDACpD,MAAOpxC,EAAYqxC,IAAiBlyC,EAAAA,EAAAA,KAAUiyC,IACvCE,EAAkBC,IAAuBpyC,EAAAA,EAAAA,IAAS,IAClD7C,EAAgBk1C,IAAqBryC,EAAAA,EAAAA,IAA0B,IAEhEsyC,GAAyBzwC,EAAAA,EAAAA,KAAQ,KAC9B01B,EAAAA,EAAAA,IAAS2a,EAbH,KAa4B,GAAO,IAC/C,IAEGK,GAAkBh6C,EAAAA,EAAAA,KAA6BiL,IACnD,MAAMgvC,EAAQhvC,EAAEgS,cAEhB,KAAK+7B,EAAAA,EAAAA,GAAwBiB,GAAQ,CACnC,GAAIA,EAAMC,SAAS/4C,OAAQ,CACzB,MAAMs4C,EAASD,EAAcS,EAAMC,SAAUD,EAAMpxC,UACnDixC,EAAkBL,GAClB,MAAMU,EAAiBV,EAAOxkB,QAAO,CAACC,EAAD,SAAM,MAAElwB,EAAF,IAASC,GAAf,SAAyBiwB,EAAMjwB,EAAMD,IAAO,GACjF60C,EAAoBM,EAAiBF,EAAMpxC,UAG7CkxC,EAAuBE,EAAMG,YA7BX,GA6B4CH,EAAMr6B,YAAc,MAEnF,CAACm6B,IAEExxC,EAAoB,CACxB8xC,aAAcL,EACdM,UAAWN,EACXO,YAAaP,EACbQ,QAASR,EACTS,aAAcT,EACdU,WAAYV,GAGd,MAAO,CACL1xC,WAAAA,EACAsxC,iBAAAA,EACAh1C,eAAAA,EACA2D,kBAAAA,EACAC,eAAe6Z,GACb03B,EAAuB13B,EAAQ+3B,YAhDb,O,iFCET,SAASO,EAAcj8C,GAAyD,IAAvCkrC,EAAuC,wDAAnBgR,EAAmB,uCAE7F,MAAMvxC,GAAYlC,EAAAA,EAAAA,IAA0B,MACtCmmC,GAAcC,EAAAA,EAAAA,KAuCpB,OArCAtjC,EAAAA,EAAAA,KAAU,KACR,MAAMrJ,EAASyI,EAAUS,QAEzB,IAAKpL,IAAYkC,GAAUgpC,EACzB,OAGF,MAAMiR,EAAM,IAAIC,MAEVC,EAAc,KAClBn6C,EAAOM,MAAQ25C,EAAI35C,MACnBN,EAAOQ,OAASy5C,EAAIz5C,OAEpB,MAAMC,EAAMT,EAAOU,WAAW,KAAM,CAAE05C,OAAO,IAEzCC,EAAAA,KACF55C,EAAIusB,OAAU,aAGhBvsB,EAAI65C,UAAUL,GAAK,GAAa,EAAaj6C,EAAOM,MAAQi6C,EAAYv6C,EAAOQ,OAAS+5C,GAEnFF,EAAAA,KACHG,EAAAA,EAAAA,GAAS/5C,EAAK,EAAG,EAAGT,EAAOM,MAAON,EAAOQ,OA9BlC,EACI,IAiCfy5C,EAAIQ,OAAS,KACPT,EACF3/B,sBAAsB8/B,GAEtBA,KAIJF,EAAIv6C,IAAM5B,IACT,CAAC2K,EAAW3K,EAAS4uC,EAAa1D,EAAYgR,IAE1CvxC,I,uGCvCT,MA6GA,EA7G8B,YAoBJ,IApBK,KAC7B0F,EAD6B,KAE7BE,EAF6B,SAG7BygB,EAH6B,SAI7B5C,EAJ6B,QAK7B1d,EAL6B,gBAM7BigB,EAN6B,aAO7BmD,EAP6B,uBAQ7BC,EAR6B,aAS7BrO,GAWwB,EAAvBk3B,EAAuB,wDACxB,MAAMl0C,GAAOC,EAAAA,EAAAA,MAEP,OAAE+I,GAAWnB,GAAQ,GACrBssC,GAAyBtsC,MAAAA,OAAA,EAAAA,EAAMrQ,MAAO48C,EAAAA,GAE5C,OAAOlyC,EAAAA,EAAAA,KAAQ,KACb,IAAKyF,EACH,OAGF,MAAM,iBACJ0sC,EADI,qBAEJ1rC,EAFI,mBAGJ2rC,EAHI,iBAIJC,IACEj1C,EAAAA,EAAAA,MAEEk1C,EAAoBvsB,EAAkB,CAC1C9iB,MAAOnF,EAAK,+BACZ8J,KAAM,SACNozB,QAAS7R,QACP1zB,EAEE88C,EAAY/uB,EACd,CACAvgB,MAAOnF,EAAK,gBACZ8J,KAAM,QACNozB,QAAS,IAAMmX,EAAiB,CAAE78C,GAAImQ,EAAKnQ,GAAI8wB,SAAAA,KAE/C,CAAEnjB,MAAOnF,EAAK,YAAa8J,KAAM,MAAOozB,QAAS,IAAMmX,EAAiB,CAAE78C,GAAImQ,EAAKnQ,GAAI8wB,SAAAA,KAE3F,GAAI4rB,EACF,OAAOQ,EAAAA,EAAAA,IAAQ,CAACD,EAAWD,IAG7B,MAAMG,EAAmBhtC,EAAKie,aAAeje,EAAKme,cAC9C,CAAE3gB,MAAOnF,EAAK,cAAe8J,KAAM,YAAaozB,QAAS,IAAMqX,EAAiB,CAAE/8C,GAAImQ,EAAKnQ,MAC3F,CAAE2N,MAAOnF,EAAK,gBAAiB8J,KAAM,SAAUozB,QAAS,IAAMqX,EAAiB,CAAE/8C,GAAImQ,EAAKnQ,MAExFo9C,EAAa5sC,EACf,CACA7C,MAAOnF,EAAK,mBACZ8J,KAAM,SACNozB,QAAS,IAAMv0B,EAAqB,CAAE3H,OAAQ2G,EAAKnQ,GAAIwQ,SAAS,KAEhE,CACA7C,MAAOnF,EAAK,iBACZ8J,KAAM,OACNozB,QAAS,IAAMv0B,EAAqB,CAAE3H,OAAQ2G,EAAKnQ,GAAIwQ,SAAS,KAG9D6sC,GAAgBC,EAAAA,EAAAA,IAAentC,GACjC,CAAExC,MAAOnF,EAAK,aAAc8J,KAAM,YAAaozB,QAAS,IAAMoX,EAAmB,CAAE98C,GAAImQ,EAAKnQ,MAC5F,CAAE2N,MAAOnF,EAAK,WAAY8J,KAAM,UAAWozB,QAAS,IAAMoX,EAAmB,CAAE98C,GAAImQ,EAAKnQ,MAGtFu9C,EADY/3B,KAAiB3U,EAAAA,EAAAA,IAAcV,KAAS2pB,EAAAA,EAAAA,IAAY3pB,IAAUE,IAASA,EAAKmB,QAE1F,CAAE7D,MAAOnF,EAAK,qBAAsB8J,KAAM,OAAQozB,QAASlgB,QAC3DrlB,EAEEq9C,EAAe,CACnB7vC,OAAO2C,EAAAA,EAAAA,IAASH,EAAKnQ,IACjBwI,EAAK,UACLA,GAAKi1C,EAAAA,EAAAA,IAAiBttC,GACpB,cACCU,EAAAA,EAAAA,IAAcV,GAAQ,eAAiB,oBAC9CmC,KAAM,SACN89B,aAAa,EACb1K,QAAS9R,GAGL8pB,OAA0Bv9C,IAAb2wB,EAEnB,OAAOosB,EAAAA,EAAAA,IAAQ,CACbF,EACAG,EACAF,GACCzrC,GAAU4rC,GACV5rC,IAAWmrC,IAA2Be,GAAcL,EACrDE,EACAC,MAED,CACDrtC,EAAME,EAAMogB,EAAiBjoB,EAAMqrB,EAAwB3F,EAAUwuB,EAAYlsC,EACjFojB,EAAcpO,EAAcsL,EAAUtf,EAAQmrC,M,2DC3GlD,SAASliC,EAAUpO,GACjBA,EAAEsxC,2BACFtxC,EAAEoQ,iBACFpQ,EAAEM,kBAGJ,MAwHA,EAxH+B,CAC7B8K,EACAmmC,EACAC,EACAC,KAEA,MAAOt2B,EAAmBu2B,IAAwBl1C,EAAAA,EAAAA,KAAS,IACpD4e,EAAqBu2B,IAA0Bn1C,EAAAA,EAAAA,SAAsC1I,GAEtFunB,GAA0BtmB,EAAAA,EAAAA,KAAaiL,IACtCuxC,GAA+B,IAAbvxC,EAAEQ,QACtBR,EAAEyQ,OAAuBsW,UAAU/xB,IAAI,kBAEzC,CAACu8C,IAEEj2B,GAAoBvmB,EAAAA,EAAAA,KAAaiL,IACpCA,EAAEyQ,OAAuBsW,UAAUG,OAAO,gBAEvCqqB,GAAmBC,GAAwBxxC,EAAEyQ,OAAuBlX,QAAQ,aAGhFyG,EAAEoQ,iBAEEgL,IAIJs2B,GAAqB,GACrBC,EAAuB,CAAE76C,EAAGkJ,EAAEG,QAASpJ,EAAGiJ,EAAEusB,cAC3C,CAACglB,EAAgBC,EAAqBp2B,IAEnCG,GAAyBxmB,EAAAA,EAAAA,KAAY,KACzC28C,GAAqB,KACpB,IAEGl2B,GAAwBzmB,EAAAA,EAAAA,KAAY,KACxC48C,OAAuB79C,KACtB,IAyEH,OAtEAkL,EAAAA,EAAAA,KAAU,KACR,GAAIuyC,IAAmBzhC,EAAAA,IAAgB2hC,EACrC,OAGF,MAAMr6B,EAAUhM,EAAWvM,QAC3B,IAAKuY,EACH,OAGF,IAAIw6B,EAEJ,MAAMC,EAAsB,KACtBD,IACFriB,aAAaqiB,GACbA,OAAQ99C,IA+BNg+C,EAAuB9xC,IACvBuxC,IAGJM,IAEAD,EAAQ54C,OAAOyY,YAAW,IAjCKsgC,CAAAA,IAC/BF,IAEA,MAAM,QAAE1xC,EAAF,QAAWosB,EAAX,OAAoB9b,GAAWshC,EAAcC,QAAQ,GAEvD52B,GAAwBo2B,GAAwB/gC,EAAuBlX,QAAQ,aAKnF6d,EAAQsT,iBAAiB,YAAY,SAASunB,EAAgBjyC,GAC5DoX,EAAQwT,oBAAoB,WAAYqnB,GAAiB,GACzD7jC,EAAUpO,MACT,GAGCyqB,EAAAA,IAAU4H,EAAAA,IACZjb,EAAQsT,iBAAiB,aAAa,SAASunB,EAAgBjyC,GAC7DoX,EAAQwT,oBAAoB,YAAaqnB,GAAiB,GAC1D7jC,EAAUpO,MACT,GAGL0xC,GAAqB,GACrBC,EAAuB,CAAE76C,EAAGqJ,EAASpJ,EAAGw1B,MASR2lB,CAAwBlyC,IApGjC,OA6GzB,OALAoX,EAAQsT,iBAAiB,aAAconB,EAAqB,CAAEK,SAAS,IACvE/6B,EAAQsT,iBAAiB,cAAemnB,GAAqB,GAC7Dz6B,EAAQsT,iBAAiB,WAAYmnB,GAAqB,GAC1Dz6B,EAAQsT,iBAAiB,YAAamnB,EAAqB,CAAEM,SAAS,IAE/D,KACLN,IACAz6B,EAAQwT,oBAAoB,aAAcknB,GAC1C16B,EAAQwT,oBAAoB,cAAeinB,GAAqB,GAChEz6B,EAAQwT,oBAAoB,WAAYinB,GAAqB,GAC7Dz6B,EAAQwT,oBAAoB,YAAainB,MAE1C,CAACz2B,EAAqBm2B,EAAgBE,EAAwBrmC,EAAYomC,IAEtE,CACLr2B,kBAAAA,EACAC,oBAAAA,EACAC,wBAAAA,EACAC,kBAAAA,EACAC,uBAAAA,EACAC,sBAAAA,K,gDC1HJ,MAEM42B,EAAa,CACjBn8C,MAAO,EAAGgK,KAAM,EAAG9J,OAAQ,EAAGq2B,IAAK,GAGtB,SAASrQ,EACtBk2B,EACA32B,EACAC,EACAE,EACAy2B,GAEA,MAAOx2B,EAAWy2B,IAAgB/1C,EAAAA,EAAAA,IAA2B,UACtDuf,EAAWy2B,IAAgBh2C,EAAAA,EAAAA,IAA2B,WACtDwf,EAAkBy2B,IAAuBj2C,EAAAA,EAAAA,OACzCyf,EAAkBy2B,IAAuBl2C,EAAAA,EAAAA,OACzCm2C,EAAYC,IAAiBp2C,EAAAA,EAAAA,KAAS,IACtCrH,EAAO09C,IAAYr2C,EAAAA,EAAAA,IAAS,KAC5B0f,EAAW42B,IAAgBt2C,EAAAA,EAAAA,IAAS,eAwF3C,OAtFAwC,EAAAA,EAAAA,KAAU,KACR,MAAM+zC,EAAYr3B,IAClB,IAAK22B,IAAWU,EACd,OAGF,IAAI,EAAEj8C,EAAF,EAAKC,GAAMs7C,EACf,MAAMW,EAAUl8C,EACVm8C,EAAUl8C,EAEVm8C,EAASr3B,IACTs3B,EAASx3B,KAET,cACJy3B,EAAgB,EADZ,gBAEJC,EAAkB,EAFd,YAGJC,EAAc,EAHV,eAIJC,EAAiB,IACfjB,MAAAA,OAAA,EAAAA,MAAiB,GAEfkB,EAAYN,EAASx0B,SAASC,iBAAiBu0B,GAAQM,UAAW,IAAMD,OAAiBz/C,EAEzF2/C,EAAWP,EAAS,CACxBj9C,MAAOi9C,EAAO3b,YACdphC,OAAQ+8C,EAAOQ,aAAeF,GAC5BpB,EAEEuB,EAAWR,EAASA,EAAOjzC,wBAA0BkyC,EAE3D,IAAIwB,EACAC,EACA/8C,EAAI28C,EAASx9C,MAAQm9C,EAAgBO,EAAS19C,MAAQ09C,EAAS1zC,MACjEnJ,GAAK,EACL88C,EAAqB,QACZ98C,EAAI28C,EAASx9C,MAAQ,GAC9B29C,EAAqB,QACrB98C,GAAK,IAEL88C,EAAqB,OACrB98C,EAAI,IAENy7C,EAAaqB,GAETN,GACwB,UAAvBM,GAAmC98C,EAAIs8C,EAAgBE,GAAeK,EAAS19C,MAAQ09C,EAAS1zC,OACnGnJ,GAAKw8C,GAGHA,GAAsC,SAAvBM,IACb98C,EAAIs8C,EAAgBE,EAAcG,EAASx9C,OAAS09C,EAAS19C,MAAQ09C,EAAS1zC,KAChFnJ,GAAKw8C,EACIx8C,EAAIw8C,GAAe,IAC5Bx8C,GAAKw8C,IAILv8C,EAAI08C,EAASt9C,OAASw9C,EAASx9C,OAASw9C,EAASnnB,IACnDqnB,EAAmB,OAEnBA,EAAmB,SAEf98C,EAAI08C,EAASt9C,OAASw9C,EAASnnB,IAAM6mB,IACvCt8C,EAAI48C,EAASnnB,IAAMmnB,EAASx9C,SAGhCq8C,EAAaqB,GAEb,MAAMC,EAAcf,EAAU7yC,wBACxBD,EAA8B,SAAvB2zC,EACTh9C,KAAK2H,IAAIzH,EAAIg9C,EAAY7zC,KAAM0zC,EAAS19C,MAAQw9C,EAASx9C,MA1FnB,IA2FrCa,EAAIg9C,EAAY7zC,KACfusB,EAAMz1B,EAAI+8C,EAAYtnB,IAEtBunB,EAAgBJ,EAASx9C,OA7FC,IA6FuCq9C,GAAa,GAEpFZ,EAAcmB,EAAgBN,EAASt9C,QACvC28C,EAAc,eAAciB,QAC5BlB,EAAU,SAAQ5yC,aAAgBusB,OAClC,MAAMwnB,EAAWhB,EAAUc,EAAY7zC,KAAQA,EACzCg0C,EAAWhB,EAAUa,EAAYtnB,IAAOA,GAAOgnB,GAAa,GAClEf,EAA2C,SAAvBmB,EAAgCI,EAAUP,EAASx9C,MAAQ+9C,GAC/EtB,EAAyC,WAArBmB,EAAgCJ,EAASt9C,OAAS89C,EAAUA,KAC/E,CACD5B,EAAQx2B,EAAgBF,EAAgBD,EAAmB42B,IAGtD,CACLx2B,UAAAA,EACAC,UAAAA,EACAC,iBAAAA,EACAC,iBAAAA,EACA9mB,MAAAA,EACA+mB,UAAAA,EACAy2B,WAAAA,K,sECrHJ,MAqBA,EArByB,CACvBx1C,EACAyD,EACA1G,EACAg6C,KAEA,MAAM,YAAEC,IAAgB14C,EAAAA,EAAAA,MAClB24C,GAAuB/1C,EAAAA,EAAAA,KAAQ,KACnC,MAAMg2C,GAAY7T,EAAAA,EAAAA,IAAS2T,EAAa,KAAK,GAC7C,MAAO,KACLE,EAAU,CAAEl3C,OAAAA,EAAQyD,UAAAA,EAAWszC,iBAAAA,OAEhC,CAACC,EAAah3C,EAAQyD,EAAWszC,KAEpCl1C,EAAAA,EAAAA,KAAU,KACJ4B,IAAc1G,GAChBk6C,S,yFCXC,SAAStqB,EAA8BrF,GAC5C,MAAM4d,GAAcC,EAAAA,EAAAA,KAIpB,OAFAtjC,EAAAA,EAAAA,KAAU,KAAMs1C,EAAAA,EAAAA,IAAsB7vB,EAAU4d,IAAc,CAAC5d,EAAU4d,KAElEkS,EAAAA,EAAAA,IAAc9vB,GAGhB,SAAS+vB,IACd,MAAMnS,GAAcC,EAAAA,EAAAA,KAIpB,OAFAtjC,EAAAA,EAAAA,KAAU,KAAMy1C,EAAAA,EAAAA,IAA0BpS,IAAc,CAACA,KAElDqS,EAAAA,EAAAA,MAGF,SAASC,IACd,MAAMtS,GAAcC,EAAAA,EAAAA,KAIpB,OAFAtjC,EAAAA,EAAAA,KAAU,KAAM41C,EAAAA,EAAAA,IAAsBvS,IAAc,CAACA,KAE9CwS,EAAAA,EAAAA,Q,gDC/BT,MAsBA,EAtB4B,SAACrP,EAA+B7G,GAAuD,IAAjCmW,EAAiC,yDACjH91C,EAAAA,EAAAA,KAAU,KACR,GAAKwmC,IAAa7G,EAclB,OAFA6G,EAAU9a,iBAAiB,QAASqqB,EAAc,CAAE5C,SAAU2C,IAEvD,KACLtP,EAAU5a,oBAAoB,QAASmqB,IAXzC,SAASA,EAAa/0C,GAEfA,EAAEg1C,SACLxP,EAAW/N,YAAcz3B,EAAEi1C,OAAS,EAChCH,GAAsB90C,EAAEoQ,qBAS/B,CAACo1B,EAAW7G,EAAYmW,M,+DCjB7B,MAAMI,EAAc,IAAI9gD,IAAI,CAAC,QAAS,WAAY,WAE5Ci4C,GAAW8I,EAAAA,EAAAA,KAGV,SAAS5qB,EAAW6qB,IACzBp2C,EAAAA,EAAAA,KAAU,KACR,IAAKo2C,EACH,OAGF,MAAMta,EAAUtP,OAAOsP,QAAQsa,GAc/B,OAAO/I,EAASgJ,aAZhB,SAAuBr1C,IAgB3B,SAAyBA,GACvB,QAAIA,EAAEyQ,kBAAkB6kC,eACdJ,EAAYzgD,IAAIuL,EAAEyQ,OAAOqmB,UAjB1Bye,CAAgBv1C,IAIrB86B,EAAQvkC,SAAQ,IAAuB,IAArBi/C,EAAQnc,GAAa,GCoDtC,SAA0Bmc,GAC/B,OAAQrlC,GAlCV,SAAuBqlC,EAAgBrlC,GACrC,MAAM,IACJ1E,EADI,KACCgqC,EADD,KACOC,EADP,IACaC,EADb,MACkBC,EADlB,IACyB1oC,GAC3BsoC,GACE,OACJ9gB,EADI,QACI3J,EADJ,QACaD,EADb,SACsB2J,EAAUvnB,IAAK2oC,GACvC1lC,EAEJ,GAAI1E,IAAQipB,EACV,OAAO,EAGT,GAAIihB,GACF,IAAK5qB,IAAYD,EACf,OAAO,MAEJ,CACL,GAAI2qB,IAAS1qB,EACX,OAAO,EAET,GAAI2qB,IAAS5qB,EACX,OAAO,EAGX,OAAI8qB,IAAUnhB,GAIPz4B,QAAQkR,IACT2oC,EAAWjc,gBAAkB1sB,EAAI0sB,eAChCzpB,EAAM6a,KAAKzN,QAAQ,MAAO,IAAIqc,gBAAkB1sB,EAAI0sB,gBAIzCkc,CA1Db,SAAqBN,GAC1B,MAAM7d,EAAO6d,EACV5b,cACAV,MAAM,KACNp/B,KAAKi8C,GAASA,EAAKv4B,SAEhBw4B,EAA+B,CACnCvqC,IAAKksB,EAAK/lB,SAAS,OACnB6jC,KAAM9d,EAAK/lB,SAAS,QACpB8jC,KAAM/d,EAAK/lB,SAAS,QACpB+jC,IAAKhe,EAAK/lB,SAAS,OACnBgkC,MAAOje,EAAK/lB,SAAS,UAGjBqkC,EAAe,CAAC,MAAO,OAAQ,OAAQ,QAAS,OAItD,MAAO,IACFD,EACH9oC,IAJcyqB,EAAKnf,MAAMtL,IAAS+oC,EAAarkC,SAAS1E,MA0C1BgpC,CAAYV,GAASrlC,IDpD3CgmC,CAAiBX,EAAjBW,CAAyBn2C,IAC3Bq5B,EAAQr5B,WAMb,CAACo1C,IAvBN1rC,SAASkV,gBAAgB8L,iBAAiB,UAAW2hB,EAAS+J,e,2DEC/C,SAASrP,EACtBv3B,EACA7H,EACAC,IAEA5I,EAAAA,EAAAA,KAAU,KACJ2I,EACGrO,EAAAA,IACHmY,YAAW,KACTzB,uBAAsB,KAChBR,EAAS3Q,SACX2Q,EAAS3Q,QAAQkR,aAdR,MAoBbP,EAAS3Q,SACX2Q,EAAS3Q,QAAQs1B,OAGfvsB,GACF6J,WAAW7J,EAxBS,QA2BvB,CAAC4H,EAAU7H,EAAQC,M,2DC9BxB,MAUA,EAVoC,CAClC64B,EAAqCwB,EAAiBoU,KAEtD,MAAMC,GAAWrgC,EAAAA,EAAAA,GAAegsB,GAChC,OAAOrjC,EAAAA,EAAAA,KAAgB,IACd6hC,EAAG6V,GAAY,KAErBrU,EAAcoU,K,iHCPnB,MAAM1jC,EAAiC,GAavC,EAXoB,KAClB,MAAM4jC,GAAQr6C,EAAAA,EAAAA,MAOd,OALKq6C,EAAM13C,UACT03C,EAAM13C,SAAUkU,EAAAA,EAAAA,GAAcJ,GAC9BA,EAAM4jC,EAAM13C,UAAW,GAGlB03C,EAAM13C,SCEA,SAAS5B,EACtBu5C,GAMA,IALArjD,EAKA,wDAJAsjD,EAIA,uDAJc1iD,EAAAA,GAAAA,QACd2iD,EAGA,uCAFAxU,EAEA,uCADAyU,EACA,wDACA,MAAM95C,EAAY25C,EAAY3/B,EAAAA,GAA0B2/B,QAAa1iD,EAC/D8iD,EAAcH,IAAgB1iD,EAAAA,GAAAA,QAClC8iD,EAAAA,IAA4BJ,IAAgB1iD,EAAAA,GAAAA,YAExCsuC,GAAcC,EAAAA,EAAAA,KACd3uC,EAAKmjD,KACJ/5C,EAAcg6C,IAAmBv6C,EAAAA,EAAAA,IAASK,IAAc+5C,EAAc,EAAI,GAC3EI,GAAe96C,EAAAA,EAAAA,MAEf+6C,GAAiB54C,EAAAA,EAAAA,KAAQ,KACtBmiC,EAAAA,EAAAA,KAAU3qC,IACXmhD,EAAan4C,WAAaqjC,GAAUgV,KAAKC,MAAQH,EAAan4C,QAAUqjC,IAC1E6U,EAAgBlhD,KAtBE,KAwBA,IACrB,CAACqsC,IAkDJ,OAhDAljC,EAAAA,EAAAA,KAAU,MACH7L,GAAUqjD,IACR35C,EAmBM+5C,GACTnlC,YAAW,KACTslC,EApDiB,OACD,OA+BlBA,EAAgB,GAEZC,EAAan4C,SACfgY,EAAAA,GAA2BogC,GAG7BD,EAAan4C,QAAUq4C,KAAKC,MAE5BtgC,EAAAA,GAAkB2/B,EAAWC,EAAaE,EAAeM,EAAgBtjD,GAAIyrC,MAAK,KAChF,MAAMgY,EAAYF,KAAKC,MAAQH,EAAan4C,QAC5Cm4C,EAAan4C,aAAU/K,GAElBouC,GAASkV,GAAalV,EACzBG,IAEA5wB,WAAW4wB,EAAaH,EAAQkV,UASvC,CACDjkD,EAAQqjD,EAAW35C,EAAW45C,EAAaC,EAAarU,EAAauU,EAAa1U,EAAO+U,EACzFN,EAAehjD,KAGjBqL,EAAAA,EAAAA,KAAU,KACJ7L,GAAU6jD,EAAan4C,UACzBgY,EAAAA,GAA2BogC,GAC3BF,EAAgB,GAChBC,EAAan4C,aAAU/K,KAExB,CAACmjD,EAAgB9jD,KAEpB6L,EAAAA,EAAAA,KAAU,IACD,KACDw3C,GACF3/B,EAAAA,GAA2B2/B,EAAW7iD,KAGzC,CAACA,EAAI6iD,IAED,CAAE35C,UAAAA,EAAWE,aAAAA,K,2DCnFtB,IAAIs6C,EAEW,SAASC,EACtB3vC,EAAiBC,GACjB,IAD8C2vC,EAC9C,uDALyB,IAI4D5Y,EACrF,wDACA,MAAM6Y,GAAgBt7C,EAAAA,EAAAA,KAAO,GAEvBu7C,GAAkB1iD,EAAAA,EAAAA,KAAY,KAClCyiD,EAAc34C,SAAU,IACvB,KAEHG,EAAAA,EAAAA,KAAU,KACJq4C,IACF9nB,aAAa8nB,GACbA,OAAevjD,IAGb6T,GAAWmI,EAAAA,IAAiB6uB,IAC9B0Y,EAAer+C,OAAOyY,YAAW,KAC1B+lC,EAAc34C,SACjB+I,MAEkB,EAAnB2vC,MAEJ,CAAC5Y,EAAYh3B,EAAQ4vC,EAAkB3vC,IAE1C,MAAMg9B,GAAmB7vC,EAAAA,EAAAA,KAAY,KACnCyiD,EAAc34C,SAAU,IACvB,IAEGgmC,GAAmB9vC,EAAAA,EAAAA,KAAY,KACnCyiD,EAAc34C,SAAU,EAEpBw4C,IACF9nB,aAAa8nB,GACbA,OAAevjD,GAGjBujD,EAAer+C,OAAOyY,YAAW,KAC1B+lC,EAAc34C,SACjB+I,MAED2vC,KACF,CAACA,EAAkB3vC,IAEtB,MAAO,CAACg9B,EAAkBC,EAAkB4S,K,iFC5C/B,SAASC,EAAuB74C,EAAcjB,GAC3D,MAAM+5C,GAAO1hC,EAAAA,EAAAA,GAAYpX,GAAS,GAC5BujC,GAAalmC,EAAAA,EAAAA,MACbmmC,GAAcC,EAAAA,EAAAA,KAEdsV,EAAmB/4C,MAAAA,EAEnBg5C,EAAgBF,MAAAA,EAiBtB,OAfIC,GAAoBxV,EAAWvjC,UACjC0wB,aAAa6S,EAAWvjC,SACxBujC,EAAWvjC,aAAU/K,IAGvByuC,EAAAA,EAAAA,IAAY,KAEN3kC,IAAag6C,GAAoBC,IAAkBzV,EAAWvjC,UAChEujC,EAAWvjC,QAAU7F,OAAOyY,YAAW,KACrC2wB,EAAWvjC,aAAU/K,EACrBuuC,MACCzkC,MAEJ,CAACiB,IAEIujC,EAAWvjC,SAAYjB,IAAYg6C,EAA6BD,EAAV94C,I,2DCtBjD,SAASosC,EACtB6M,EACAC,GAEA,MAAM1V,GAAcC,EAAAA,EAAAA,KACd0V,GAAa97C,EAAAA,EAAAA,IAAO47C,GACpBnO,GAAQztC,EAAAA,EAAAA,IAAO67C,GAEftuC,GAAW1U,EAAAA,EAAAA,KAAamb,IAC5By5B,EAAM9qC,QAAUm5C,EAAWn5C,QAAQ8qC,EAAM9qC,QAASqR,GAClDmyB,MACC,CAACA,IAEJ,MAAO,CACLsH,EAAM9qC,QACN4K,K,gDCrBW,SAASwuC,EAAgBC,EAAYC,EAAmBC,GACrE,OAAOhsB,EAAAA,EAAAA,IAAsBqU,IAC3BA,MACC,GAAIyX,EAAIC,EAASC,K,gHCEtB,MAQA,GAAeplD,EAAAA,EAAAA,KAR2BC,IACxC,MAAM,OAAE0U,GAAW1U,EACbolD,GAAgB32B,EAAAA,EAAAA,GAAgBC,EAAAA,GAAAA,MAAe,iBAAkBha,GAGvE,OAAO0wC,EAAgB,mBAACA,EAAkBplD,QAAYa,KCoDxD,EArDoB,CAClBwkD,EACAC,KAEA,MAAMp8C,GAAOC,EAAAA,EAAAA,MACNo8C,EAAaC,IAAkBj8C,EAAAA,EAAAA,MAEhCk8C,GAAwB3jD,EAAAA,EAAAA,KAAY,SAACuF,GAAqC,IAAzBq+C,EAAyB,wDAC9E,MAAM,iBAAE1lC,IAAqBqF,EAAAA,EAAAA,MAEvBsgC,EAAchiD,KAAK8H,MAAM9H,KAAKC,IAAIyD,EAAKu+C,UAAW3B,KAAKC,MAAQ,KAAa,MAC7EwB,EAAe,EAAI1lC,GACxBulC,MAAAA,GAAAA,EAAcI,GACdH,OAAe3kD,KACd,CAAC0kD,IAEEM,GAAmC/jD,EAAAA,EAAAA,KAAY,KACnD2jD,EAAsB,IAAIxB,KAA6B,IAAxB6B,EAAAA,KAA+B,KAC7D,CAACL,IAEEM,GAAsBjkD,EAAAA,EAAAA,KAAY,KACtC0jD,OAAe3kD,GACfykD,MAAAA,GAAAA,MACC,CAACA,IAEEU,GAAkBlkD,EAAAA,EAAAA,KAAamkD,IACnCT,GAAe,IAAMS,MACpB,IAEGC,EAAuB,IAAIjC,KACjCiC,EAAqBC,WAAW,GAChCD,EAAqBE,gBAAgB,GAErC,MAAMC,EAAmB,IAAIpC,KAiB7B,OAhBAoC,EAAiBC,YAAYD,EAAiBE,cAAgB,GAgBvD,CAACP,EAbN,mBAAC,EAAD,CACEtxC,OAAQ3L,QAAQw8C,GAChBiB,gBAAc,EACdC,WAAYP,EAAqBN,UACjCc,OAAOC,EAAAA,EAAAA,IAAcN,GACrBO,cAAY,EACZC,kBAAmBxB,EAAyBn8C,EAAK,gCAA6BrI,EAC9E8T,QAASoxC,EACTzpC,SAAUmpC,EACVqB,oBAAqBzB,EAAyBQ,OAAmChlD,O,iFCjDvF,MAQA,EAR6B,CAACqJ,EAAiBymB,KACtCvlB,EAAAA,EAAAA,KAAQ,KACNmiC,EAAAA,EAAAA,KAAUtwB,KACfzU,EAAAA,EAAAA,MAAau+C,kBAAkB,CAAE78C,OAAAA,EAAQymB,SAAAA,EAAU1T,OAAAA,MAClD+pC,EAAAA,KACF,CAAC98C,EAAQymB,K,2DCPP,SAASs2B,EAAehiD,GAC7B,MAAM2B,GAAMqC,EAAAA,EAAAA,IAAUhE,GAMtB,OAJAqqC,EAAAA,EAAAA,IAAY,KACV1oC,EAAIgF,QAAU3G,IACb,CAACA,IAEG2B,I,gDCKT,QAhBA,SAAoBsgD,EAAsBjY,GACxC,MAAMkY,GAAgBl+C,EAAAA,EAAAA,IAAOi+C,IAE7Bv7C,EAAAA,EAAAA,KAAgB,KACdw7C,EAAcv7C,QAAUs7C,IACvB,CAACA,KAEJn7C,EAAAA,EAAAA,KAAU,KACR,GAAqB,iBAAVkjC,EACT,OAEF,MAAMvuC,EAAK8d,YAAW,IAAM2oC,EAAcv7C,WAAWqjC,GACrD,MAAO,IAAM3S,aAAa57B,KACzB,CAACuuC,M,iCCmCN,MAAMmY,EAAY,CAAC,EAAG,GAAI,GAAI,GAAI,IAAK,GAAI,GAAI,GAAI,IAAK,GAAI,IAAK,GAAI,IAAK,GAAI,GAAI,IAAK,IAAK,IAAK,EAAG,IAAK,GAAI,GAAI,GAAI,IAAK,IAAK,IAAK,IAAK,GAAI,GAAI,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,EAAG,IAAK,GAAI,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,GAAI,IAAK,GAAI,IAAK,IAAK,IAAK,IAAK,GAAI,IAAK,EAAG,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,GAAI,IAAK,IAAK,GAAI,GAAI,IAAK,IAAK,GAAI,GAAI,GAAI,IAAK,IAAK,IAAK,EAAG,IAAK,IAAK,GAAI,IAAK,IAAK,IAAK,IAAK,GAAI,IAAK,IAAK,IAAK,IAAK,IAAK,GAAI,GAAI,GAAI,GAAI,GAAI,IAAK,IAAK,IAAK,GAAI,IAAK,IAAK,GAAI,IAAK,GAAI,IAAK,EAAG,GAAI,IAAK,GAAI,GAAI,IAAK,IAAK,IAAK,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,IAAK,IAAK,IAAK,IAAK,IAAK,GAAI,GAAI,IAAK,IAAK,IAAK,IAAK,GAAI,IAAK,IAAK,IAAK,GAAI,IAAK,IAAK,GAAI,IAAK,IAAK,GAAI,GAAI,IAAK,IAAK,IAAK,GAAI,GAAI,GAAI,GAAI,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,GAAI,GAAI,GAAI,GAAI,GAAI,IAAK,IAAK,IAAK,GAAI,IAAK,IAAK,IAAK,GAAI,GAAI,IAAK,IAAK,IAAK,GAAI,IAAK,IAAK,GAAI,IAAK,IAAK,IAAK,IAAK,GAAI,IAAK,IAAK,IAAK,IAAK,GAAI,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,GAAI,IAAK,GAAI,GAAI,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,GAAI,GAAI,IAAK,IAAK,GAAI,IAAK,IAAK,EAAG,GAAI,IAAK,GAAI,IAAK,IAAK,GAAI,GAAI,IAAK,GAAI,IAAK,GAAI,IAAK,IAAK,GAAI,IAAK,IAAK,IAAK,IAAK,GAAI,IAAK,IAAK,IAAK,GAAI,IAAK,GAAI,IAAK,GAE5qCC,EAAY,CAAC,EAAG,EAAG,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,IAElgC,SAASC,EAAiBC,EAASC,EAAOC,EAAOzkD,EAAOE,EAAQa,EAAQ6kC,GACrF,GAAIxQ,OAAOsvB,MAAM3jD,IAAWA,EAAS,EAAG,OAExCA,GAAU,EAENq0B,OAAOsvB,MAAM9e,KAAaA,EAAa,IAC3CA,GAAc,GACG,IAAGA,EAAa,GAC7BA,EAAa,IAAGA,EAAa,GAEjC,MAAM+e,EAAYJ,EAAQK,aAAaJ,EAAOC,EAAOzkD,EAAOE,GAEtD2kD,EAASF,EAAUriD,KAEzB,IAAIwiD,EACAC,EACAC,EACAnkD,EACAC,EACAN,EACAkjC,EACAuhB,EACAC,EACAC,EACAC,EACAC,EACAC,EAAKtlD,EAAQ,EACbulD,EAAKrlD,EAAS,EACdslD,EAAOzkD,EAAS,EAEhB0kD,EAAI,GACJC,EAAI,GACJpiB,EAAI,GAEJqiB,EAAUvB,EAAUrjD,GACpB6kD,EAAUvB,EAAUtjD,GAEpB8kD,EAAO,GACPC,EAAO,GAEX,KAAOlgB,KAAe,GAAG,CAGvB,IAFAyf,EAAKD,EAAK,EAELtkD,EAAI,EAAGA,EAAIZ,EAAQY,IAAK,CAK3B,IAJAgkD,EAAOD,EAAOQ,GAAMG,EACpBT,EAAOF,EAAOQ,EAAK,GAAKG,EACxBR,EAAOH,EAAOQ,EAAK,GAAKG,EAEnBhlD,EAAI,EAAGA,GAAKO,EAAQP,IACvBkjC,EAAI2hB,IAAQ7kD,EAAI8kD,EAAKA,EAAK9kD,IAAO,GACjCskD,GAAQD,EAAOnhB,KACfqhB,GAAQF,EAAOnhB,KACfshB,GAAQH,EAAOnhB,KAGjB,IAAK7iC,EAAI,EAAGA,EAAIb,EAAOa,IACrB4kD,EAAEL,GAAMN,EACRY,EAAEN,GAAML,EACRzhB,EAAE8hB,GAAMJ,EAEC,GAALlkD,IACF+kD,EAAKhlD,KAAO6iC,EAAI7iC,EAAI2kD,GAAQF,EAAK5hB,EAAI4hB,IAAO,EAC5CQ,EAAKjlD,IAAO6iC,EAAI7iC,EAAIE,GAAU,EAAI2iC,GAAK,EAAI,GAG7CuhB,EAAKI,EAAKQ,EAAKhlD,GACfqkD,EAAKG,EAAKS,EAAKjlD,GAEfikD,GAAQD,EAAOI,KAAQJ,EAAOK,KAC9BH,GAAQF,EAAOI,KAAQJ,EAAOK,KAC9BF,GAAQH,EAAOI,KAAQJ,EAAOK,KAE9BE,IAEFC,GAAOrlD,GAAS,EAGlB,IAAKa,EAAI,EAAGA,EAAIb,EAAOa,IAAK,CAM1B,IALAskD,EAAKtkD,EACLikD,EAAOW,EAAEN,GAAMK,EACfT,EAAOW,EAAEP,GAAMK,EACfR,EAAO1hB,EAAE6hB,GAAMK,EAEVhlD,EAAI,EAAGA,GAAKO,EAAQP,IACvB2kD,GAAO3kD,EAAI+kD,EAAK,EAAIvlD,EACpB8kD,GAAQW,EAAEN,GACVJ,GAAQW,EAAEP,GACVH,GAAQ1hB,EAAE6hB,GAIZ,IADAC,EAAKvkD,GAAK,EACLC,EAAI,EAAGA,EAAIZ,EAAQY,IACtB+jD,EAAOO,GAAON,EAAOa,IAAaC,EAClCf,EAAOO,EAAK,GAAML,EAAOY,IAAaC,EACtCf,EAAOO,EAAK,GAAMJ,EAAOW,IAAaC,EAE7B,GAAL/kD,IACFglD,EAAK/kD,KAAO4iC,EAAI5iC,EAAI0kD,GAAQD,EAAK7hB,EAAI6hB,GAAMvlD,EAC3C8lD,EAAKhlD,IAAO4iC,EAAI5iC,EAAIC,GAAU,EAAI2iC,EAAI1jC,EAAQ,GAGhDilD,EAAKpkD,EAAIglD,EAAK/kD,GACdokD,EAAKrkD,EAAIilD,EAAKhlD,GAEdgkD,GAAQW,EAAER,GAAMQ,EAAEP,GAClBH,GAAQW,EAAET,GAAMS,EAAER,GAClBF,GAAQ1hB,EAAE2hB,GAAM3hB,EAAE4hB,GAElBE,GAAMplD,GAAS,GAKrBukD,EAAQwB,aAAapB,EAAWH,EAAOC,K,gJC9IzC,MAAMuB,EAAS,IAAIC,IACnB,IAGIC,EAHAC,EAAwB,GACxBC,EAAwB,GA0D5B,SAASC,EAASpQ,EAAkBqQ,GAClC,MAAMC,EAAeL,GAAkBF,EAAO9f,IAAIggB,GAC9CK,IACFA,EAAa7gD,MAAM+Y,QACnB8nC,EAAa7gD,MAAMgZ,YAAc,EAC7B6nC,EAAa/P,eAAe+P,EAAa/P,iBAG/C,MAEMgQ,EAAcC,EAAgBxQ,GAFrB5zB,EAAAA,EAAAA,MAAYg1B,YAAYjzC,QAAUoH,EAAAA,GAAAA,OAEI86C,GACrD,IAAKE,EACH,OAGF,IAAKR,EAAOxnD,IAAIgoD,GAId,YAFAhhD,EAAAA,EAAAA,MAAakhD,iBAAgBC,EAAAA,EAAAA,IAAgBC,EAAaJ,GAAaK,aAKzE,MAAMC,EAAYd,EAAO9f,IAAIsgB,GAEzBM,EAAUvQ,aACZuQ,EAAUvQ,cAGZ2P,EAAiBM,EAEbM,EAAUphD,MAAMtG,MAClBuf,EAAAA,EAAAA,GAASmoC,EAAUphD,OAIhB,SAASqhD,IACd,MAAMR,EAAeL,GAAkBF,EAAO9f,IAAIggB,GAC9CK,GACFA,EAAa7gD,MAAM+Y,QAIhB,SAASq4B,EACdb,EACAE,EACA/S,EACAmT,EACAC,GAEA,IAAKwP,EAAOxnD,IAAIy3C,GAAU,CACxB,MAAM+Q,EAxGV,SACE/Q,EACA57B,EACAk8B,EACAC,GAEA,MAAM9wC,EAAQ,IAAIuhD,MAElB,SAASC,EAAYnQ,GACnB,OAAQhtC,IACDi8C,EAAOxnD,IAAIy3C,MAIZ6B,EAAAA,EAAAA,GAAwBpyC,IAI5BsgD,EAAO9f,IAAI+P,GAAUG,SAAS91C,SAAS8iC,IACrCA,EAAQ2T,EAAWhtC,QAuBzB,OAlBArE,EAAM+uB,iBAAiB,aAAcyyB,EAAY,iBACjDxhD,EAAM+uB,iBAAiB,OAAQyyB,EAAY,WAC3CxhD,EAAM+uB,iBAAiB,QAASyyB,EAAY,YAC5CxhD,EAAM+uB,iBAAiB,YAAayyB,EAAY,gBAChDxhD,EAAM+uB,iBAAiB,aAAcyyB,EAAY,iBACjDxhD,EAAM+uB,iBAAiB,UAAWyyB,EAAY,cAC9CxhD,EAAM+uB,iBAAiB,SAAS,KACzBuxB,EAAOxnD,IAAIy3C,MAIZ6B,EAAAA,EAAAA,GAAwBpyC,IAI5B2gD,EAASpQ,OAGJ,CACLvwC,MAAAA,EACA2U,KAAAA,EACA+6B,MAAO,IAAI+R,MAAMzhD,EAAO,CACtBwgC,IAAK,CAAC1rB,EAAQvD,IAAgCuD,EAAOvD,KAEvDm/B,SAAU,GACVG,YAAAA,EACAC,cAAAA,GAsDc4Q,CAAYnR,EAASE,EAAWI,EAAaC,GAC3DwP,EAAOzf,IAAI0P,EAAS+Q,GAwIxB,SAAyBA,EAAc/Q,GAClB,UAAf+Q,EAAM3sC,MAAqB+rC,EAAWzqC,SAASs6B,KACjDmQ,EAAW16C,KAAKuqC,GAChBmQ,EAAWle,KAAKmf,IAGC,UAAfL,EAAM3sC,MAAqB8rC,EAAWxqC,SAASs6B,KACjDkQ,EAAWz6C,KAAKuqC,GAChBkQ,EAAWje,KAAKmf,IA/IhBC,CAAgBN,EAAO/Q,GAEzB,MAAM,MAAEvwC,EAAF,MAAS0vC,EAAT,SAAgBgB,GAAa4P,EAAO9f,IAAI+P,GAI9C,OAFAG,EAAS1qC,KAAK03B,GAEP,CACLnc,KAAK7nB,GACH,IAAKsG,EAAMiyC,OAAQ,OACnB,MAAM4O,EAAeL,GAAkBF,EAAO9f,IAAIggB,GAC9CK,GAAgBL,IAAmBjQ,IACrCsQ,EAAa7gD,MAAM+Y,QACnB8nC,EAAa7gD,MAAMgZ,YAAc,GAC7Bo5B,EAAAA,EAAAA,GAAwByO,EAAa7gD,SACvC6gD,EAAa7gD,MAAMu8B,QAAQslB,sBAAwB,QAEjDhB,EAAa/P,eAAe+P,EAAa/P,iBAG/C0P,EAAiBjQ,EAEZvwC,EAAMtG,MACTsG,EAAMtG,IAAMA,EACZsG,EAAM8hD,QAAU,OAEZpoD,EAAIuc,SAAS,kBAAoB8rC,EAAAA,YAC5B/hD,EAAMu8B,QAAQslB,uBACrBG,EAAAA,EAAAA,GAA4BhiD,MAIhCiZ,EAAAA,EAAAA,GAASjZ,GA+Hf,SAAsB2U,EAAqB47B,GAAkB,MAC3D,IAAI5zB,EAAAA,EAAAA,MAAYslC,aAAaC,iBAAmBC,EAAAA,GAAAA,MAA2B,OAC3E,MAAM,OAAE3gD,IAAWy/C,EAAAA,EAAAA,IAAgBC,EAAa3Q,GAAS4Q,YACnDiB,EAAY,WAAGh6B,EAAAA,EAAAA,KAAyBzL,EAAAA,EAAAA,cAA5B,aAAG,EAAuCnb,OACtD6gD,EAAerqD,GACnBA,EAAGs3B,WAAY,MAAK9tB,MAAc4gD,GAAgBpqD,EAAGs3B,WAAY,MAAK8yB,KAG3D,UAATztC,IACF+rC,EAAaA,EAAW15B,OAAOq7B,IAGpB,UAAT1tC,IACF8rC,EAAaA,EAAWz5B,OAAOq7B,IA3I7BC,CAAa7R,EAAWF,IAG1Bx3B,QACMynC,IAAmBjQ,GACrBvwC,EAAM+Y,SAIV82B,OACE,GAAI2Q,IAAmBjQ,EAAS,CAE9B,MAAMgC,EAAUvyC,EAAMtG,IACtBsG,EAAM+Y,SAENoS,EAAAA,EAAAA,KAAQ,KACNnrB,EAAMtG,IAAM,GACZsG,EAAMtG,IAAM64C,OAKlBvwC,eAAe0wC,GACT8N,IAAmBjQ,IACjBvwC,EAAMuiD,SACRviD,EAAMuiD,SAAS7P,GAEf1yC,EAAMgZ,YAAc05B,IAK1BpB,UAAUM,GACJ4O,IAAmBjQ,IACrBvwC,EAAM4xC,OAASA,EACf5xC,EAAMuZ,OAAQ,IAIlBg4B,gBAAgBiR,GACVhC,IAAmBjQ,IACrBvwC,EAAM+xC,aAAeyQ,IAIzBhR,YAAYj4B,GAERvZ,EAAMuZ,WADMphB,IAAVohB,GACavZ,EAAMuZ,MAEPA,GAIlBm2B,MAAAA,EAEAC,mBACEgR,EAASpQ,IAGXz1B,OAAM,KACIimC,EAAgBxQ,GAAS5zB,EAAAA,EAAAA,MAAYg1B,YAAYjzC,QAG3Dmc,QAAO,KACGkmC,EAAgBxQ,GAAS5zB,EAAAA,EAAAA,MAAYg1B,YAAYjzC,QAAQ,GAGnEkxC,uBACE+Q,EAASpQ,GAAS,IAGpB4B,UAAuC,IAA/BsQ,EAA+B,wDACrC,MAAMnB,EAAQhB,EAAO9f,IAAI+P,GACpB+Q,IAILA,EAAM5Q,SAAW4Q,EAAM5Q,SAAS1pB,QAAQ07B,GAAMA,IAAMhlB,IAE/C4jB,EAAM5Q,SAASn2C,SAClB+mD,EAAMthD,MAAM+Y,QACZunC,EAAOqC,OAAOpS,GAEVkS,GAgCZ,SAAyBnB,EAAc/Q,GACrC,MAAMqS,EAAiBC,GAAgBA,IAAOtS,EAC3B,UAAf+Q,EAAM3sC,OACR+rC,EAAaA,EAAW15B,OAAO47B,IAGd,UAAftB,EAAM3sC,OACR8rC,EAAaA,EAAWz5B,OAAO47B,IAtCzBE,CAAgBxB,EAAO/Q,GAGrBA,IAAYiQ,IACdA,OAAiBroD,OAO3B,SAAS4qD,EAAczB,GACrB,OAAQA,EAAM3sC,MACZ,IAAK,QAAS,OAAO+rC,EACrB,IAAK,QAAS,OAAOD,EACrB,QAAS,QA4Cb,SAASM,EAAgBiC,GAA2E,IAAvDtkD,EAAuD,uDAA9CoH,EAAAA,GAAAA,OAAoB86C,EAA0B,uCAClG,MAAMU,EAAQhB,EAAO9f,IAAIwiB,GACnBC,EAAQF,EAAczB,GAC5B,IAAK2B,EAAO,OAEZ,GAAIvkD,IAAWoH,EAAAA,GAAAA,OAAoB,CACjC,MAAM6hC,EAAQsb,EAAM9sC,QAAQ6sC,GAC5B,GAAIrb,EAAQ,EAAG,OAEf,OAAOsb,EAAMtb,GADKiZ,GAAkB,EAAI,IAI1C,MAAM,OAAEp/C,IAAWy/C,EAAAA,EAAAA,IAAgBC,EAAa8B,GAAW7B,YACrD+B,EAAYD,EAAMj8B,QAAQhvB,GAAOA,EAAGs3B,WAAY,MAAK9tB,OACrDmmC,EAAQub,EAAU/sC,QAAQ6sC,GAChC,GAAIrb,EAAQ,EAAG,OACf,IAAI9rB,EAAYnd,IAAWoH,EAAAA,GAAAA,QAAsB,EAAI,EAErD,OADI86C,IAAgB/kC,IAAc,GAC3BqnC,EAAUvb,EAAQ9rB,GAGpB,SAAS1Z,EAAY5D,GAC1B,MAAQ,IAAE4kD,EAAAA,EAAAA,IAAc5kD,MAAYA,EAAQI,OAG9C,SAASuiD,EAAa3Q,GAGpB,MAAO,CACL4Q,WAHiB5Q,EAAQ/gB,MAAM,qBAAsB,GAIrD7wB,KAHW+wB,OAAO6gB,EAAQhT,MAAM,KAAKmC,QAQzC,SAASiiB,EAAkByB,EAAeC,GACxC,IAAKD,IAAQC,EAAK,OAAO,EACzB,MAAQ1kD,KAAM2kD,EAASnC,WAAYoC,GAAWrC,EAAakC,IACnDzkD,KAAM6kD,EAASrC,WAAYsC,GAAWvC,EAAamC,GACrDrzB,EAAOwzB,EAAUF,EACvB,OAAgB,IAATtzB,EAAayzB,EAAOC,cAAcH,GAAUvzB,I,qNC3V9C,IAAKlU,G,SAAAA,GAAAA,EAAAA,EAAAA,GAAAA,GAAAA,KAAAA,EAAAA,EAAAA,KAAAA,GAAAA,OAAAA,EAAAA,EAAAA,KAAAA,GAAAA,OAAAA,EAAAA,EAAAA,MAAAA,GAAAA,Q,CAAAA,IAAAA,EAAAA,KA+DL,MAAM6nC,EAA4B,GAMzC,SAASC,EAAYC,EAAUjmB,GAC7B,OAAKA,EACE3iC,KAAK6oD,MAAOlmB,EAAEmmB,MAAQF,EAAEE,MAASnmB,EAAEomB,MAAQH,EAAEG,OADrC,EAIjB,SAASC,EAAeJ,EAAUjmB,GAChC,MAAO,CACLziC,GAAI0oD,EAAEE,MAAQnmB,EAAEmmB,OAAS,EACzB3oD,GAAIyoD,EAAEG,MAAQpmB,EAAEomB,OAAS,GAI7B,IAAIE,EAAgB,EACpB,MAAMC,EAAW,IC5DV,MAeLC,cAKwB,IALZ,UACVC,EAAY,EADF,YAEVC,EAAc,IAFJ,UAGVC,EAAY,IAHF,MAIVhe,EAAQ,KACc,uDAAJ,GAAI,yMACtBie,KAAKH,UAAYA,EACjBG,KAAKF,YAAcA,EACnBE,KAAKD,UAAYA,EACjBC,KAAKje,MAAQA,EACbie,KAAKC,aAAe,IAAIvoD,MAAuB,EAAjBsoD,KAAKH,WAAe1oD,KAAK,GACvD6oD,KAAKE,eAAiB,IAAIxoD,MAAuB,EAAjBsoD,KAAKH,WAAe1oD,KAAK,GACzD6oD,KAAKG,gBAAkB,IAAIzoD,MAAuB,EAAjBsoD,KAAKH,WAAe1oD,KAAK,GAG5DipD,MAAMvgD,GACJ,IAAIwgD,EAWJ,YATqB1sD,KADrBkM,EAAIA,EAAE+xC,eAAiB/xC,GACjBygD,WACJD,EAAYxgD,EAAEygD,gBACQ3sD,IAAbkM,EAAEi1C,OACXuL,GAAwB,GAAZxgD,EAAEi1C,YACQnhD,IAAbkM,EAAE0gD,QAAqC,IAAb1gD,EAAE0gD,SACrCF,GAAwB,GAAZxgD,EAAE0gD,QAEhBP,KAAKG,gBAAgB3+C,KAAKu1C,KAAKC,OAC/BgJ,KAAKG,gBAAgB1K,QACjB4K,EAAY,GACdL,KAAKC,aAAaz+C,KAAK6+C,GACvBL,KAAKC,aAAaxK,QACXuK,KAAKQ,UAAU,KAEtBR,KAAKE,eAAe1+C,KAAK6+C,GACzBL,KAAKE,eAAezK,QACbuK,KAAKQ,WAAW,IAI3BA,UAAUnpC,GACR,MAAMopC,GAA4B,IAAfppC,EAAmB2oC,KAAKE,eAAiBF,KAAKC,aACjE,QAAsBtsD,IAAlB8sD,EAAW,GAAkB,OAAOppC,EACxC,GACE2oC,KAAKG,gBAAiC,EAAjBH,KAAKH,UAAgB,GAAKG,KAAKje,MAAQgV,KAAKC,OAC9DyJ,EAAW,KAAOA,EAA4B,EAAjBT,KAAKH,UAAgB,GAErD,OAAO,EAET,MAAMa,EAAgBD,EAAWhqC,MAAM,EAAGupC,KAAKH,WACzCc,EAAgBF,EAAWhqC,MAAMupC,KAAKH,UAA4B,EAAjBG,KAAKH,WACtDe,EAASF,EAAc72B,QAAO,CAACg3B,EAAGtnB,IAAMsnB,EAAItnB,IAC5CunB,EAASH,EAAc92B,QAAO,CAACg3B,EAAGtnB,IAAMsnB,EAAItnB,IAC5CwnB,EAAaH,EAASF,EAAc3qD,OACpCirD,EAAaF,EAASH,EAAc5qD,OAC1C,OAAOU,KAAK+8B,IAAIutB,GAActqD,KAAK+8B,IAAIwtB,EAAahB,KAAKD,YACpDC,KAAKF,YAAcrpD,KAAK+8B,IAAIwtB,KDTP,CAC5BnB,UAAW,EACXC,YAAa,GACbC,UAAW,GACXhe,MAAO,MAGF,SAASrhC,EAAcuW,EAAsBqC,GAAyB,UAC3E,IAAI2nC,EAkBAC,EAjBAC,GAAW,EACXC,GAAY,EACZC,GAAY,EACZC,EAAkB,EAClBC,EAAS,UAAGjoC,EAAQkoC,mBAAX,QAA0B,EACnCC,EAAoB,CACtB9qD,EAAG,EACHC,EAAG,GAED8qD,EAAiB,CACnB/qD,GAAG,EACHC,GAAG,GAED+qD,EAAqB,CACvBhrD,EAAGkC,OAAO+oD,WAAa,EACvBhrD,EAAGiC,OAAOgpD,YAAc,GAG1B,MAAMC,EAAO,UAAGxoC,EAAQwoC,eAAX,QAAsB,EAC7BC,EAAO,UAAGzoC,EAAQyoC,eAAX,QAAsB,EAEnC,SAASphD,EAAUd,GACjB,IAAIyZ,EAAQ0oC,0BACTniD,EAAEyQ,OAAuBlX,QAAQkgB,EAAQ0oC,2BACtCniD,EAAEyQ,OAAuBmL,QAAQnC,EAAQ0oC,yBAF/C,CASA,GAFAf,EAAephD,EAEA,cAAXA,EAAEsQ,MACCmJ,EAAQ2oC,gBAAkB3oC,EAAQxY,QACrCjB,EAAEoQ,iBAGJ1G,SAASghB,iBAAiB,YAAa23B,GACvC34C,SAASghB,iBAAiB,UAAW3pB,QAChC,GAAe,eAAXf,EAAEsQ,KAAuB,CAGlC,MAAMG,EAASzQ,EAAEyQ,OACjBA,EAAOia,iBAAiB,YAAa23B,EAAQ,CAAElQ,SAAS,IACxD1hC,EAAOia,iBAAiB,WAAY3pB,GACpC0P,EAAOia,iBAAiB,cAAe3pB,GAEnC,YAAaf,SACClM,IAAZkM,EAAE0/C,QACJ1/C,EAAE0/C,MAAQ1/C,EAAEgyC,QAAQ,GAAG0N,YAGT5rD,IAAZkM,EAAE2/C,QACJ3/C,EAAE2/C,MAAQ3/C,EAAEgyC,QAAQ,GAAG2N,OAGA,IAArB3/C,EAAEgyC,QAAQ97C,SACZurD,EAAkBlC,EAAYv/C,EAAEgyC,QAAQ,GAAIhyC,EAAEgyC,QAAQ,IACtD8P,EAAqBlC,EAAe5/C,EAAEgyC,QAAQ,GAAIhyC,EAAEgyC,QAAQ,MAK9Dv4B,EAAQ6oC,YACV54C,SAAS64C,KAAKx7B,UAAU/xB,IAAI,mBAG1BykB,EAAQ3Y,WACV2Y,EAAQ3Y,UAAUd,IAItB,SAASe,EAAUf,GACbohD,IACE3nC,EAAQ6oC,YACV54C,SAAS64C,KAAKx7B,UAAUG,OAAO,mBAGjCxd,SAASkhB,oBAAoB,UAAW7pB,GACxC2I,SAASkhB,oBAAoB,YAAay3B,GACzCjB,EAAa3wC,OAAuBma,oBAAoB,cAAe7pB,GACvEqgD,EAAa3wC,OAAuBma,oBAAoB,WAAY7pB,GACpEqgD,EAAa3wC,OAAuBma,oBAAoB,YAAay3B,GAElEhwB,EAAAA,IAAU5Y,EAAQnC,yBACpBzf,MAAMo3B,KAAKvlB,SAAS84C,iBAA8B/oC,EAAQnC,0BACvD/gB,SAASksD,IACRA,EAAWttD,MAAMutD,SAAW,MAI9B1iD,IACEshD,EACE7nC,EAAQ1Y,WACV0Y,EAAQ1Y,UAAUf,GAEA,YAAXA,EAAEsQ,OACPmJ,EAAQkpC,eAAiBzL,KAAKC,MAAQ0I,EAAgB,IACxDpmC,EAAQkpC,cAAc3iD,EAAG,CACvB4iD,QAASxB,EAAc1B,MACvBmD,QAASzB,EAAczB,SAEhBlmC,EAAQzY,SAAc,WAAYhB,GAAmB,IAAbA,EAAEQ,QACnDiZ,EAAQzY,QAAQhB,GAElB6/C,EAAgB3I,KAAKC,SAK3BmK,GAAW,EACXC,GAAY,EACZC,GAAY,EACZC,EAAkB,EAClBC,GAAYoB,EAAAA,EAAAA,IAAMpB,EAAWO,EAASC,GACtCb,OAAmBvtD,EACnB8tD,EAAoB,CAClB9qD,EAAG,EACHC,EAAG,GAEL8qD,EAAiB,CACf/qD,GAAG,EACHC,GAAG,GAEL+qD,EAAqB,CACnBhrD,EAAGkC,OAAO+oD,WAAa,EACvBhrD,EAAGiC,OAAOgpD,YAAc,GAE1BZ,OAAettD,EAGjB,SAASuuD,EAAOriD,GACd,GAAIohD,EAAc,CAChB,GAAe,cAAXphD,EAAEsQ,MAAyB,YAAatQ,SAC1BlM,IAAZkM,EAAE0/C,QACJ1/C,EAAE0/C,MAAQ1/C,EAAEgyC,QAAQ,GAAG0N,YAGT5rD,IAAZkM,EAAE2/C,QACJ3/C,EAAE2/C,MAAQ3/C,EAAEgyC,QAAQ,GAAG2N,OAGrBlmC,EAAQspC,QAAUtB,EAAkB,GAA0B,IAArBzhD,EAAEgyC,QAAQ97C,QAAc,CACnE,MAAM8sD,EAAczD,EAAYv/C,EAAEgyC,QAAQ,GAAIhyC,EAAEgyC,QAAQ,IAClDiR,EAAcrD,EAAe5/C,EAAEgyC,QAAQ,GAAIhyC,EAAEgyC,QAAQ,IACrDkR,EAAcD,EAAYnsD,EAAIgrD,EAAmBhrD,EACjDqsD,EAAcF,EAAYlsD,EAAI+qD,EAAmB/qD,EACjDqsD,EAAaJ,EAAcvB,EACjChoC,EAAQspC,OAAO/iD,EAAG,CAChBojD,WAAAA,EACAC,eAAgBvB,EAAmBhrD,EACnCwsD,eAAgBxB,EAAmB/qD,EACnCmsD,YAAAA,EACAC,YAAAA,EACAI,eAAgBN,EAAYnsD,EAC5B0sD,eAAgBP,EAAYlsD,IAEX,IAAfqsD,IAAkB9B,GAAW,GAIrC,MAAM4B,EAAcljD,EAAE0/C,MAAS0B,EAAa1B,MACtCyD,EAAcnjD,EAAE2/C,MAASyB,EAAazB,OAExC/oD,KAAK+8B,IAAIuvB,IA9LK,IA8L8BtsD,KAAK+8B,IAAIwvB,IA9LvC,MA+LhB7B,GAAW,GAGb,IAAImC,GAAsB,EAEtBhqC,EAAQxY,SACVwY,EAAQxY,OAAOjB,EAAGohD,EAAc,CAC9B8B,YAAAA,EACAC,YAAAA,IAEFM,GAAsB,GAGpBhqC,EAAQlC,UAAYgqC,IACtBA,EAaN,SAAiBvhD,EAAgCkjD,EAAqBC,GAEpE,GAAI9wB,EAAAA,GAAQ,CACV,MAAMv7B,EAAKkJ,EAAqBgyC,QAAQ,GAAG0N,MAC3C,GAAI5oD,GAAKwoD,GAA6BxoD,GAAKkC,OAAO+oD,WAAazC,EAC7D,OAAO,EAIX,MAAMoE,EAAO9sD,KAAK+8B,IAAIuvB,GAChBS,EAAO/sD,KAAK+8B,IAAIwvB,GAEtB,GAAID,GAAeC,GACHvsD,KAAKC,IAAI6sD,EAAMC,GAAQ/sD,KAAK2H,IAAImlD,EAAMC,GAExC,EACV,OAAO,EAIX,IAAIC,EAOJ,GANIF,GA9OgB,GA+OlBE,EAAO,IACED,GAhPS,KAiPlBC,EAAO,MAGJA,EACH,OAAO,EAGT,GAAKvC,GAEE,GAAIA,IAAqBuC,EAE9B,OAAO,OAHPvC,EAAmBuC,EAMrB,OAkGJ,SACE5jD,EACA6jD,EACAX,EACAC,EACA5rC,GAEA,MAAyB,MAArBssC,EAEOtsC,EAAQvX,EADbkjD,EAAc,EACEzrC,EAAeqsC,KAEfrsC,EAAessC,OAEL,MAArBF,GAEAtsC,EAAQvX,EADbmjD,EAAc,EACE1rC,EAAeusC,GAEfvsC,EAAewsC,MAnH5BC,CAAalkD,EAAG4jD,EAAMV,EAAaC,EAAa1pC,EAAQlC,SAnD/CA,CAAQvX,EAAGkjD,EAAaC,GACpCM,EAAsBlC,GAGpBlvB,EAAAA,IAAUoxB,GAAuBhqC,EAAQnC,yBAC3Czf,MAAMo3B,KAAKvlB,SAAS84C,iBAA8B/oC,EAAQnC,0BACvD/gB,SAASksD,IACRA,EAAWttD,MAAMutD,SAAW,aA+CtC,MAAMyB,GAAmBpwB,EAAAA,EAAAA,IAAShzB,EAhQH,KAgQwC,GACjEqjD,GAAmBrwB,EAAAA,EAAAA,IAAShzB,EAlQH,KAkQwC,GAEvE,SAASsjD,EAAerkD,GAClBshD,IACJxgD,EAAUd,GACVshD,GAAW,EACXQ,EAAqB,CAAEhrD,EAAGkJ,EAAElJ,EAAGC,EAAGiJ,EAAEjJ,IA2CtC,SAASutD,EAAQtkD,GACf,IAAKyZ,EAAQspC,SAAWtpC,EAAQxY,OAAQ,OACxC,GAAIwY,EAAQ0oC,0BACTniD,EAAEyQ,OAAuBlX,QAAQkgB,EAAQ0oC,0BACtCniD,EAAEyQ,OAAuBmL,QAAQnC,EAAQ0oC,0BAE7C,OAEFniD,EAAEoQ,iBACFpQ,EAAEM,kBACF,MAAM,cAAEikD,EAAgB,GAAM9qC,EAC9B,GAAIA,EAAQkpC,eAAiBn3B,OAAOg5B,GAAGxkD,EAAEg1C,QAAS,IAAMxpB,OAAOg5B,GAAGxkD,EAAEi1C,QAAS,IAAMj1C,EAAE+qB,QAKnF,OAJAs5B,EAAerkD,GACf0hD,EAAYA,EAAY,EAAI,EAAI6C,EAChC9qC,EAAQkpC,cAAc3iD,EAAG,CAAE4iD,QAAS5iD,EAAE0/C,MAAOmD,QAAS7iD,EAAE2/C,aACxD2B,GAAW,GAGb,MAAMmD,EAAiBzkD,EAAE8qB,SAAW9qB,EAAE+qB,SAAW/qB,EAAEy0B,SAInD,GAHIgwB,GA3DN,SAAqBzkD,GACnB,IAAKyZ,EAAQspC,OAAQ,OACrBsB,EAAerkD,GACf,MAAMkjD,EAAcljD,EAAElJ,EAAIgrD,EAAmBhrD,EACvCqsD,EAAcnjD,EAAEjJ,EAAI+qD,EAAmB/qD,EACvC2tD,GAAQ5B,EAAAA,EAAAA,IAAM9iD,EAAEi1C,QAAS,GAAI,IACnCyM,GAAqB,IAARgD,EACbhD,GAAYoB,EAAAA,EAAAA,IAAMpB,EAAqB,GAAVO,EAAyB,EAAVC,GAC5CzoC,EAAQspC,OAAO/iD,EAAG,CAChB2kD,MAAMjmD,EAAAA,EAAAA,IAAMgjD,EAAW,GACvB2B,eAAgBvB,EAAmBhrD,EACnCwsD,eAAgBxB,EAAmB/qD,EACnCmsD,YAAAA,EACAC,YAAAA,EACAI,eAAgBvjD,EAAElJ,EAClB0sD,eAAgBxjD,EAAEjJ,IAEpBqtD,EAAiBpkD,GA2Cf4kD,CAAY5kD,IAETykD,IAAmBjD,EAAW,CAEjC,MAAMqD,EAAc/E,EAASS,MAAMvgD,IACjB,IAAd0hD,GAEOmD,IA/Cf,SAAqB7kD,GACnB,IAAKyZ,EAAQxY,OAAQ,OACrBojD,EAAerkD,GAEV6hD,EAAe/qD,GAAKF,KAAKkuD,KAAKlD,EAAkB9qD,KAAOF,KAAKkuD,KAAK9kD,EAAEg1C,UACtE4M,EAAkB9qD,GAAKkJ,EAAEg1C,QAEtB6M,EAAe9qD,GAAKH,KAAKkuD,KAAKlD,EAAkB7qD,KAAOH,KAAKkuD,KAAK9kD,EAAEi1C,UACtE2M,EAAkB7qD,GAAKiJ,EAAEi1C,QAE3B,MAAM,EAAEn+C,EAAF,EAAKC,GAAM6qD,EACjBnoC,EAAQxY,OAAOjB,EAAGohD,EAAe,CAC/B8B,YAAapsD,EACbqsD,YAAapsD,IACZ,CAACguD,EAAIC,KACNnD,EAAiB,CAAE/qD,EAAGiuD,EAAIhuD,EAAGiuD,MAE/Bb,EAAiBnkD,GA6BbilD,CAAYjlD,IAWlB,OAJAoX,EAAQsT,iBAAiB,QAAS45B,GAClCltC,EAAQsT,iBAAiB,YAAa5pB,GACtCsW,EAAQsT,iBAAiB,aAAc5pB,EAAW,CAAEqxC,SAAU14B,EAAQyrC,eAE/D,KACLnkD,IACAqW,EAAQwT,oBAAoB,QAAS05B,GACrCltC,EAAQwT,oBAAoB,aAAc9pB,GAC1CsW,EAAQwT,oBAAoB,YAAa9pB,M,uGErZtC,SAASqkD,EAAQC,GACtB,MAAO,CACL1mC,SAAS0mC,EAAMC,UAAU,EAAG,GAAI,IAChC3mC,SAAS0mC,EAAMC,UAAU,EAAG,GAAI,IAChC3mC,SAAS0mC,EAAMC,UAAU,EAAG,GAAI,KAS7B,SAASC,EAAQF,GACtB,MAAMG,EAAKH,EAAM,GAAG1yB,SAAS,IACvBwoB,EAAKkK,EAAM,GAAG1yB,SAAS,IACvByoB,EAAKiK,EAAM,GAAG1yB,SAAS,IAC7B,OAAqB,GAAb6yB,EAAGrvD,OAAc,IAAMqvD,EAAKA,IAAoB,GAAbrK,EAAGhlD,OAAc,IAAMglD,EAAKA,IAAoB,GAAbC,EAAGjlD,OAAc,IAAMilD,EAAKA,GAcrG,SAASqK,EAAT,GAAgF,IAA9D9J,EAAGC,EAAGpiB,GAAwD,EACrFmiB,GAAK,IACLC,GAAK,IACLpiB,GAAK,IAEL,IACI8kB,EAAY3kB,EADZ7iC,EAAMD,KAAKC,IAAI6kD,EAAGC,EAAGpiB,GAAIh7B,EAAM3H,KAAK2H,IAAIm9C,EAAGC,EAAGpiB,GACvBqJ,EAAY/rC,EAEnC4uD,EAAI5uD,EAAM0H,EAGd,GAFAm7B,EAAW,GAAP7iC,EAAW,EAAI4uD,EAAI5uD,EAEnBA,GAAO0H,EACT8/C,EAAI,MACC,CACL,OAAQxnD,GACN,KAAK6kD,EACH2C,GAAK1C,EAAIpiB,GAAKksB,GAAK9J,EAAIpiB,EAAI,EAAI,GAC/B,MACF,KAAKoiB,EACH0C,GAAK9kB,EAAImiB,GAAK+J,EAAI,EAClB,MACF,KAAKlsB,EACH8kB,GAAK3C,EAAIC,GAAK8J,EAAI,EAItBpH,GAAK,EAGP,MAAO,CAACA,EAAG3kB,EAAGkJ,GAcT,SAAS8iB,EAAT,GAAgF,IACjFhK,EAAYC,EAAYpiB,GADL8kB,EAAG3kB,EAAGkJ,GAAwD,EAGjFnsC,EAAIG,KAAKe,MAAU,EAAJ0mD,GACfsH,EAAQ,EAAJtH,EAAQ5nD,EACZkjC,EAAIiJ,GAAK,EAAIlJ,GACbksB,EAAIhjB,GAAK,EAAI+iB,EAAIjsB,GACjBsnB,EAAIpe,GAAK,GAAK,EAAI+iB,GAAKjsB,GAE3B,OAAQjjC,EAAI,GACV,KAAK,EACHilD,EAAI9Y,EACJ+Y,EAAIqF,EACJznB,EAAII,EACJ,MACF,KAAK,EACH+hB,EAAIkK,EACJjK,EAAI/Y,EACJrJ,EAAII,EACJ,MACF,KAAK,EACH+hB,EAAI/hB,EACJgiB,EAAI/Y,EACJrJ,EAAIynB,EACJ,MACF,KAAK,EACHtF,EAAI/hB,EACJgiB,EAAIiK,EACJrsB,EAAIqJ,EACJ,MACF,KAAK,EACH8Y,EAAIsF,EACJrF,EAAIhiB,EACJJ,EAAIqJ,EACJ,MACF,KAAK,EACH8Y,EAAI9Y,EACJ+Y,EAAIhiB,EACJJ,EAAIqsB,EAIR,MAAO,CACLhvD,KAAK8H,MAAU,IAAJg9C,GACX9kD,KAAK8H,MAAU,IAAJi9C,GACX/kD,KAAK8H,MAAU,IAAJ66B,IAIR7K,eAAem3B,EAAgB/nC,GAEpC,MACMgoC,EAAuC,CAAC,EAAG,EAAG,GACpD,IAAIvtD,EACAtC,EACAE,EAEAD,EADAO,GAAK,EAELsvD,EAAgC,CAAC,EAAG,EAAG,GACvCC,EAAQ,EAEZ,MAAMrwD,EAAS+T,SAASksB,cAAc,UAChC4kB,EAAU7kD,EAAOU,YAAcV,EAAOU,WAAW,MACvD,IAAKmkD,EACH,OAAOsL,EAGT,MAAMG,QAAcC,EAAAA,EAAAA,IAAapoC,GACjC3nB,EAAS8vD,EAAME,eAAiBF,EAAMvS,cAAgBuS,EAAM9vD,OAC5DF,EAAQgwD,EAAMG,cAAgBH,EAAM1uB,aAAe0uB,EAAMhwD,MACzDN,EAAOQ,OAASA,EAChBR,EAAOM,MAAQA,EAEfukD,EAAQvK,UAAUgW,EAAO,EAAG,GAE5B,IACE1tD,EAAOiiD,EAAQK,aAAa,EAAG,EAAG5kD,EAAOE,GACzC,MAAO6J,GACP,OAAO8lD,EAMT,IAHA5vD,EAASqC,EAAKA,KAAKrC,QAGXO,GAAK4vD,IAAiBnwD,GACH,IAArBqC,EAAKA,KAAK9B,EAAI,OAChBuvD,EACFD,EAAI,IAAMxtD,EAAKA,KAAK9B,GACpBsvD,EAAI,IAAMxtD,EAAKA,KAAK9B,EAAI,GACxBsvD,EAAI,IAAMxtD,EAAKA,KAAK9B,EAAI,IAO1B,OAJAsvD,EAAI,GAAKnvD,KAAKe,MAAMouD,EAAI,GAAKC,GAC7BD,EAAI,GAAKnvD,KAAKe,MAAMouD,EAAI,GAAKC,GAC7BD,EAAI,GAAKnvD,KAAKe,MAAMouD,EAAI,GAAKC,GAEtBD,EAGF,SAASO,EAAaC,GAC3B,MAAO7K,EAAGC,EAAGpiB,GAAKgtB,EAElB,MADa,MAAS7K,EAAI,MAASC,EAAI,MAASpiB,EAM3C,SAASitB,EAAgBD,GAC9B,IAAKE,EAAKC,EAAYxuD,GAASstD,EAAQe,GAOvC,OALAG,EAAa9vD,KAAK2H,IAAI,EAAGmoD,EAAa,IAAO,IAAO,EAAIA,IACxDxuD,EAAQA,EAAQ,GACZtB,KAAKC,IAAI,EAAW,IAARqB,GACZtB,KAAKC,IAAI,EAAGD,KAAK2H,IAAI,EAAG,EAAY,IAARrG,IAExB,QAAa,IAANuuD,MAA2B,IAAbC,OAA8B,IAARxuD,Y,eC3MtC,SAASyuD,EAAczwD,EAAgBotC,GACpD,OAAOA,EAAQ1sC,KAAKe,MAAM2rC,EAAQptC,GAAUA,E,2ICa9C,IAAI0wD,GAAc,EAEH,SAASC,EACtBrhB,EACApuB,EACAgU,GAMA,IALA07B,EAKA,uDALS,EACTC,EAIA,uDAJcC,EAAAA,GACdC,EAGA,uCAFAC,EAEA,uCADAC,EACA,uCACA,MAAMC,EAAaC,EAAoB7hB,EAAWpuB,EAAS2vC,EAAaE,GAEpEA,IAAmBK,EAAAA,GAAAA,SAKnBhvC,EAAAA,EAAAA,MAAY7Q,SAASC,MAAMF,iBAAmB+/C,EAAAA,KAChDL,EAAgB,GAGlBM,EAAahiB,EAAWpuB,EAASgwC,EAAYh8B,EAAU07B,EAAQI,EAAeC,IAR5EK,EAAahiB,EAAWpuB,EAASgwC,EAAYh8B,EAAU07B,EAAQ,GAW5D,SAASW,IACd,OAAOb,EAGT,SAASS,EACP7hB,EACApuB,GAGA,IAFA2vC,EAEA,uDAFcC,EAAAA,GACdC,EACA,uCACA,MAAQS,UAAWC,GAAevwC,GAC5B,UAAEwwC,GAAcpiB,EAEtB,QAAuB1xC,IAAnBmzD,EAA8B,CAChC,MAAMY,EAASF,EAAaniB,EAAUoiB,UAEtC,GAAIC,GAAUd,EACZ,OAAOa,GAAaC,EAASd,GACxB,GAAIc,EAASd,EAClB,OAAOa,GAAaC,EAASd,OAE1B,IAAIE,IAAmBK,EAAAA,GAAAA,GAC5B,OAAOK,EAAaZ,EACf,GAAIE,IAAmBK,EAAAA,GAAAA,KAC5B,OAAO1wD,KAAKC,IAAI,EAAG8wD,EAAaZ,GAGlC,OAAOa,EAGT,SAASJ,EACPhiB,EACApuB,EACAgwC,EACAh8B,GAIA,IAHA07B,EAGA,uDAHS,EACTI,EAEA,uCADAC,EACA,uCACA,MAAQO,UAAWC,EAAYjU,aAAcoU,GAAkB1wC,GACvDwwC,UAAWG,EAAkBrU,aAAcsU,EAA7C,aAA8Dx0B,GAAiBgS,EAC/EyiB,EAAwBd,GAA8B3hB,EAAUtN,QAAQgwB,aAC1E78B,OAAOma,EAAUtN,QAAQgwB,cACzBF,EAMJ,IAAIG,EAEJ,OANIJ,IAAqBX,IACvB5hB,EAAUoiB,UAAYR,GAKhBh8B,GACN,IAAK,QACH+8B,EAAQR,EAAab,EAAUM,GAAcxyB,EAAAA,GAAa,EAAI,GAC9D,MACF,IAAK,MACHuzB,EAAQR,EAAaG,EAAgBhB,GAAWM,EAAaa,GAC7D,MAEF,IAAK,UACL,IAAK,SACL,IAAK,cACHE,EAAOL,EAAgBG,EAClBN,EAAaG,EAAgB,GAAMV,EAAaa,EAAwB,GACxEN,EAAab,EAAUM,EAIhC,GAAIe,EAAO,EAAG,CACZ,MAAMC,GAAiBhB,EACvBe,EAAOvxD,KAAKC,IAAIsxD,EAAMC,QACjB,GAAID,EAAO,EAAG,CACnB,MAAMC,EAAgB50B,GAAgB4zB,EAAaa,GACnDE,EAAOvxD,KAAK2H,IAAI4pD,EAAMC,GAGxB,GAAa,IAATD,EACF,OAGF,MAAM13C,EAAS22C,EAAae,EAE5B,GAAsB,IAAlBjB,EAEF,YADA1hB,EAAUoiB,UAAYn3C,GAIxBm2C,GAAc,EAEd,MAAMyB,EAAUzxD,KAAK+8B,IAAIw0B,GACnBG,EAAaD,EAAUE,EAAAA,GAA4CC,EAAkBC,EACrF7qD,EAAWspD,GACfwB,EAAAA,GACGL,EAAUrB,EAAAA,IAA6B2B,EAAAA,GAA2BD,EAAAA,IAEjEE,EAAU1R,KAAKC,MACf0R,GAAuBC,EAAAA,EAAAA,OAE7BhiC,EAAAA,EAAAA,KAAQ,MACNiiC,EAAAA,EAAAA,KAAc,KACZ,MAAM/H,EAAIpqD,KAAK2H,KAAK24C,KAAKC,MAAQyR,GAAWhrD,EAAU,GAChDorD,EAAcb,GAAQ,EAAIG,EAAWtH,IAU3C,OARAxb,EAAUoiB,UAAYhxD,KAAK8H,MAAM+R,EAASu4C,GAE1CpC,EAAc5F,EAAI,EAEb4F,GACHiC,IAGKjC,QAKb,SAAS6B,EAAezH,GACtB,OAAO,GAAM,EAAIA,IAAM,EAGzB,SAASwH,EAAgBxH,GACvB,OAAO,GAAM,EAAIA,IAAM,M,gFC3JzB,MAEMiI,EAAsC,IAAI/M,IAEjC,SAAS9S,EAA2B5D,EAAwBvlC,GAA2C,IAA7BrC,EAA6B,uDAJ7F,IASvB,OAJI0a,EAAAA,EAAAA,MAAY7Q,SAASC,MAAMF,iBAAmB+/C,EAAAA,KAChD3pD,EAAW,GAGN4pD,EAAahiB,EAAWvlC,EAAMrC,GAGvC,SAAS4pD,EAAahiB,EAAwBvlC,EAAcrC,GAC1D,MAAMvB,EAA0C,QAAlCmpC,EAAU0jB,aAAa,QAC/B,WACJzxB,EAAYF,YAAa4xB,EADrB,YACqC3xB,EAAaU,SAAS,SAAEkxB,IAC/D5jB,EAEJ,IAAI2iB,EAAOloD,EAAOw3B,EAElB,GAAI0wB,EAAO,EAAG,CACZ,MAAMC,GAAiB3wB,GAAcp7B,GAAS,EAAI,GAClD8rD,EAAOvxD,KAAKC,IAAIsxD,EAAMC,QACjB,GAAID,EAAO,EAAG,CACnB,MAAMC,EAAgB5wB,GAAeC,EAAa0xB,GAClDhB,EAAOvxD,KAAK2H,IAAI4pD,EAAMC,GAGxB,GAAa,IAATD,EACF,OAAO/tB,QAAQC,UAGb+uB,GAAYH,EAASx0D,IAAI20D,IAC3BH,EAAS9sB,IAAIitB,EAAbH,GAGF,MAAMx4C,EAASgnB,EAAa0wB,EAE5B,GAAiB,IAAbvqD,EAEF,OADA4nC,EAAU/N,WAAahnB,EAChB2pB,QAAQC,UAGjB,IAAIgvB,GAAY,EAChB,MAAM11D,EAAKiD,KAAK0yD,SAAS52B,WAQzB,IAAI2H,EAPJmL,EAAUtN,QAAQkxB,SAAWz1D,EAC7Bs1D,EAASzsB,IAAI7oC,GAAI,KACf01D,GAAY,KAGd7jB,EAAUrwC,MAAMo0D,eAAiB,OAGjC,MAAMC,EAAU,IAAIpvB,SAAeshB,IACjCrhB,EAAUqhB,KAENkN,EAAU1R,KAAKC,MAqBrB,OAnBArwB,EAAAA,EAAAA,KAAQ,MACN2iC,EAAAA,EAAAA,KAAQ,KACN,GAAIJ,EAAW,OAAO,EAEtB,MAAMrI,EAAIpqD,KAAK2H,KAAK24C,KAAKC,MAAQyR,GAAWhrD,EAAU,GAEhDorD,EAAcb,GAAQ,EAgBlC,SAAoBnH,GAClB,OAAO,GAAM,EAAIA,IAAM,IAjBasH,CAAWtH,IAS3C,OARAxb,EAAU/N,WAAa7gC,KAAK8H,MAAM+R,EAASu4C,GAEvChI,GAAK,IACPxb,EAAUrwC,MAAMo0D,eAAiB,GACjC/jB,EAAUtN,QAAQkxB,cAAWt1D,EAC7Bm1D,EAAS3K,OAAO3qD,GAChB0mC,KAEK2mB,EAAI,QAIRwI,I,gDCjFM,SAAS33B,EAAqBza,EAAsBsyC,EAAiBC,GAClF,IAAKD,GAAStyC,IAAY1N,SAASkgD,cACjC,OAGF,MAAM73B,EAAY/4B,OAAOg5B,eACnB63B,EAAQngD,SAASogD,cACjBC,EAAY3yC,EAAQ2yC,WAAa3yC,EAElCtH,EAAAA,IAAiB65C,GAA0BI,GAAcA,EAAUC,WAKxEH,EAAMI,mBAAmBN,EAAuBvyC,EAAU2yC,GAE1DF,EAAMK,UAAS,GACfn4B,EAAUE,kBACVF,EAAUiF,SAAS6yB,IARjBzyC,EAAQrH,U,gBCVG,SAASo6C,IACtB,MAAMp4B,EAAY/4B,OAAOg5B,eACzB,IAAIo4B,EAAoBr4B,GAAaA,EAAUO,WAAaP,EAAUS,WAAW,GAAG4E,qBAAkBtjC,EACtG,IAAKs2D,GAA6D,IAAxCA,EAAkBC,kBAC1C,OAGF,MAAM1xC,EAAa9gB,MAAMo3B,KAAKm7B,EAAkBhnB,UAC7CpZ,QAAO,CAACpyB,EAAQ0yD,IAVA,IAWXA,EAAKC,UAA6BD,EAAKvjC,UAAUyjC,SAAS,sBACrD3yD,MAAMo3B,KAAKq7B,EAAK9H,iBAAiB,aACrCx4B,QAAO,CAACC,EAAKwgC,IAAcxgC,EAAI+E,OAAO3D,OAAQo/B,EAA0BvyB,QAAQt3B,aAAahJ,GAbnF,IAcJ0yD,EAAKC,UAA6BD,EAAKvjC,UAAUyjC,SAAS,WAC5D5yD,EAAOo3B,OAAO3D,OAAQi/B,EAAqBpyB,QAAQt3B,YAGrDhJ,GACN,IAGL,KAAOwyD,EAAkBM,YACvBN,EAAkBO,YAAYP,EAAkBM,YAIlD,OAFAN,OAAoBt2D,EAEb6kB,E,kECzBF,SAASiyC,EAAoBpM,GAClC,GAAyB,SAArBA,EAAGrpD,MAAM01D,QACX,OAAO,EAGT,MAAMv+B,EAAOkyB,EAAGt+C,yBACR/J,OAAQuqB,GAAiBZ,EAAAA,EAAAA,MAEjC,OAAQwM,EAAKE,KAAO9L,GAAmB4L,EAAKE,IAAMF,EAAKn2B,QAAW,I,8ECcpE,MAAM20D,EAAmB,CACvB5tC,UAAMppB,EACN4gB,WAAO5gB,EACP43C,kBAAc53C,EACd+3C,iBAAa/3C,EACbm4C,mBAAen4C,EACfk4C,eAAWl4C,EACX03C,UAAM13C,EACNg4C,YAAQh4C,GAGH,SAASs5C,EAAqBd,EAA0BD,GAC7D,MAAM,aAAE0e,GAAiB/xD,OAAOgyD,UAC5BD,GACEze,GAAUuB,EAAevB,GACzBD,GAAU4e,EAAwB5e,IAGtC6e,QAAQC,KAAK,kDAIV,SAAStd,EAAevB,GAC7B,MAAM,aAAEye,GAAiB/xD,OAAOgyD,UAC5BD,IAEFA,EAAaze,SAAWA,MAAAA,EAAAA,EAAY,MAIjC,SAAS2e,EAAwB5e,GACtC,MAAM,aAAE0e,GAAiB/xD,OAAOgyD,UAC5BD,GACFv/B,OAAOsP,QAAQ,IAAKgwB,KAAqBze,IAAY91C,SAAQ,IAAoB,IAAlB2W,EAAKmsB,GAAa,EAC/E,IAEE0xB,EAAaK,iBAAiBl+C,EAAKmsB,GACnC,MAAOgyB,QAOR,SAASC,IACd,MAAM,aAAEP,GAAiB/xD,OAAOgyD,UACd,MAAdD,IAEFA,EAAaze,SAAW,KACxB2e,EAAwBH,GACpBC,EAAaQ,gBAAeR,EAAaQ,cAAgB,QAC7D,UAAAR,EAAapd,wBAAb,cAAAod,IAIG,SAAS1d,IAAgE,IAA/C1D,EAA+C,uDAAR,OACtE,MAAM,aAAEohB,GAAiB/xD,OAAOgyD,UAC5BD,GAAgBA,EAAaQ,gBAC/BR,EAAaQ,cAAgB5hB,GAI1B,SAASgE,EAAiBhE,GAA4B,MAC3D,IAAKA,QAA4B71C,IAAnB61C,EAAMve,eAA6Ct3B,IAAnB61C,EAAM/rC,SAAwB,OAC5E+rC,EAAMve,SAAWx0B,KAAK2H,IAAIorC,EAAMve,SAAUue,EAAM/rC,UAEhD,MAAM,aAAEmtD,GAAiB/xD,OAAOgyD,UAChCD,MAAAA,GAAA,UAAAA,EAAcpd,wBAAd,cAAAod,EAAiCphB,GAa5B,SAAS6hB,EAAT,GAEqB,IAFO,MACjClqD,EADiC,OAC1BmqD,EAD0B,MAClBC,EADkB,QACXC,GACI,EAC1B,GAAI,kBAAmB3yD,OACrB,OAAO,IAAIA,OAAO4yD,cAAc,CAC9BtqD,MAAAA,EACAmqD,OAAAA,EACAC,MAAAA,EACAC,QAAAA,M,qEC3GN,MAAME,EAAmE,CACvE12B,EAAGiD,EAAAA,GAAAA,KACHhD,OAAQgD,EAAAA,GAAAA,KACR/C,EAAG+C,EAAAA,GAAAA,OACH9C,GAAI8C,EAAAA,GAAAA,OACJ7C,EAAG6C,EAAAA,GAAAA,UACH0zB,EAAG1zB,EAAAA,GAAAA,OACH2zB,OAAQ3zB,EAAAA,GAAAA,OACR5C,IAAK4C,EAAAA,GAAAA,OACL3C,KAAM2C,EAAAA,GAAAA,KACN4zB,IAAK5zB,EAAAA,GAAAA,IACL6zB,WAAY7zB,EAAAA,GAAAA,WACZ,eAAgBA,EAAAA,GAAAA,aAKH,SAAS8zB,EAAkBp5C,GAA2D,IAA7Cq5C,EAA6C,wDACnG,MAAMC,EAAW1iD,SAASksB,cAAc,OACxCw2B,EAAS16B,UAAgC26B,EAApBF,EAAkCG,EAAmBx5C,GAAuBA,GACjG,MAAMvN,EAAO6mD,EAASG,UAAU/uC,OAAOD,QAAQ,WAAY,IAC3D,IAAIivC,EAAY,EACZC,EAAoB,EACxB,MAAMC,EAA+B,GAErC,SAASC,EAAUrC,GACjB,MAAM,MAAEhnB,EAAF,OAAS99B,GAAWonD,EAAsBtC,EAAM/kD,EAAMinD,GAE5D,GAAIhnD,EACFgnD,EAAYlpB,EACZopB,EAAS/qD,KAAK6D,QACT,GAAI8kD,EAAKj2B,YAAa,CAE3B,GAAc,IAAViP,GAA2C,KAA5BgnB,EAAKj2B,YAAY7W,OAClC,OAEFgvC,GAAalC,EAAKj2B,YAAYn+B,OAG5Bo0D,EAAKuC,iBAAmBJ,GAxBP,IAyBnBA,GAAqB,EACrB50D,MAAMo3B,KAAKq7B,EAAKthB,YAAYzyC,QAAQo2D,IASxC,OALA90D,MAAMo3B,KAAKm9B,EAASpjB,YAAYzyC,SAAS+zD,IACvCmC,EAAoB,EACpBE,EAAUrC,MAGL,CACL/kD,KAAAA,EACAmnD,SAAUA,EAASx2D,OAASw2D,OAAW54D,GAI3C,SAASu4D,EAAcv5C,GACrB,IAAIg6C,EAAah6C,EAAK8D,MAAM,GAuD5B,OArDK0d,EAAAA,KAEHw4B,EAAaA,EAAWvvC,QAAQ,iCAAkC,OAIpEuvC,EAAaA,EAAWvvC,QAAQ,UAAW,KAG3CuvC,EAAaA,EAAWvvC,QAAQ,4BAA6B,MAE7DuvC,EAAaA,EAAWvvC,QAAQ,gBAAiB,MAGjDuvC,EAAaA,EAAWvvC,QAAQ,qBAAsB,MACtDuvC,EAAaA,EAAWvvC,QAAQ,SAAU,MAC1CuvC,EAAaA,EAAWvvC,QAAQ,WAAY,IAG5CuvC,EAAaA,EAAWvvC,QAAQ,sCAAuC,oCACvEuvC,EAAaA,EAAWvvC,QAAQ,kCAAmC,iBACnEuvC,EAAaA,EAAWvvC,QAAQ,uBAAwB,iBAGxDuvC,EAAaA,EAAWvvC,QACtB,wEACA,mBAIFuvC,EAAaA,EAAWvvC,QACtB,sGACA,iEAIFuvC,EAAaA,EAAWvvC,QACtB,oFACA,iBAEFuvC,EAAaA,EAAWvvC,QACtB,oFACA,iBAEFuvC,EAAaA,EAAWvvC,QACtB,oFACA,iBAEFuvC,EAAaA,EAAWvvC,QACtB,oFACC,6BAA4B6a,EAAAA,GAAAA,wBAGxB00B,EAGT,SAASR,EAAmBx5C,GAC1B,OAAOA,EAAKyK,QAAQ,IAAIwvC,OAAQ,qBAAoBC,EAAAA,WAA0B,MAAM,CAACl1C,EAAGvS,EAAMK,IAEpF,YADIA,EAAKgM,SAAS,OAAShM,EAAOA,EAAKgM,SAAS,KAAQ,UAAShM,IAAU,UAASA,QACjEL,UAI/B,SAASqnD,EACPtC,EACA2C,EACAT,GAEA,MAAMl8C,EAwER,SAA+Bg6C,GAC7B,GAAIuB,EAA0BvB,EAAK4C,UACjC,OAAOrB,EAA0BvB,EAAK4C,UAGxC,GAAsB,MAAlB5C,EAAK4C,SAAkB,CACzB,MAAM7a,EAASiY,EACf,OAAIjY,EAAOna,QAAQC,aAAeC,EAAAA,GAAAA,YACzBA,EAAAA,GAAAA,YAELia,EAAOna,QAAQC,aAAeC,EAAAA,GAAAA,IACzBA,EAAAA,GAAAA,IAELia,EAAOjZ,KAAKnO,WAAW,WAClBmN,EAAAA,GAAAA,MAELia,EAAOjZ,KAAKnO,WAAW,QAClBmN,EAAAA,GAAAA,MAELia,EAAOjZ,OAASiZ,EAAOhe,YAClB+D,EAAAA,GAAAA,QAGFA,EAAAA,GAAAA,IAGT,MAAsB,SAAlBkyB,EAAK4C,SACC5C,EAAqBpyB,QAAQC,gBADvC,EAlGag1B,CAAsB7C,GACnC,IAAKh6C,IAASg6C,EAAKj2B,YACjB,MAAO,CACLiP,MAAOkpB,EACPhnD,YAAQ1R,GAIZ,MAAMs5D,EAAWH,EAAQn7C,QAAQw4C,EAAKj2B,YAAam4B,GAG7ClpB,EAAQ8pB,GAAY,EAAIA,EAAWZ,EACnC3E,EAASoF,EAAQ5H,UAAU,EAAG/hB,GAAOptC,QACrC,OAAEA,GAAW+2D,EAAQ5H,UAAU/hB,EAAOA,EAAQgnB,EAAKj2B,YAAYn+B,QAErE,OAAIoa,IAAS8nB,EAAAA,GAAAA,QACJ,CACLkL,MAAAA,EACA99B,OAAQ,CACN8K,KAAAA,EACAu3C,OAAAA,EACA3xD,OAAAA,EACA4nB,IAAMwsC,EAA2BlxB,OAInC9oB,IAAS8nB,EAAAA,GAAAA,YACJ,CACLkL,MAAAA,EACA99B,OAAQ,CACN8K,KAAAA,EACAu3C,OAAAA,EACA3xD,OAAAA,EACA6O,OAASulD,EAA2BpyB,QAAQnzB,SAK9CuL,IAAS8nB,EAAAA,GAAAA,IACJ,CACLkL,MAAAA,EACA99B,OAAQ,CACN8K,KAAAA,EACAu3C,OAAAA,EACA3xD,OAAAA,EACAm3D,SAAW/C,EAAwBpyB,QAAQm1B,WAK7C/8C,IAAS8nB,EAAAA,GAAAA,YACJ,CACLkL,MAAAA,EACA99B,OAAQ,CACN8K,KAAAA,EACAu3C,OAAAA,EACA3xD,OAAAA,EACAo3D,WAAahD,EAAqBpB,aAAa,iBAK9C,CACL5lB,MAAAA,EACA99B,OAAQ,CACN8K,KAAAA,EACAu3C,OAAAA,EACA3xD,OAAAA,M,gBCnMC,SAASynD,EAA4B4P,GACtCA,EAAQr1B,QAAQs1B,mBAIpBD,EAAQ7iC,iBAAiB,QAAQ,KAC/B,MAAMs2B,EAAIuM,EAAQ54C,YAElB44C,EAAQr1B,QAAQu1B,yBAA2B,OAiB3CF,EAAQ7iC,iBAAiB,YAhBzB,SAAS+kB,IACF8d,EAAQte,SAAS/4C,SAGtBq3D,EAAQ54C,YAAc44C,EAAQ3vD,SAAW,EACzC2vD,EAAQ7iC,iBAAiB,YAAY,YAC5B6iC,EAAQr1B,QAAQu1B,yBACvBF,EAAQ54C,YAAcqsC,EAClBuM,EAAQ3f,SAAW2f,EAAQr1B,QAAQslB,uBACrC+P,EAAQrwC,SAET,CAAEyX,MAAM,IAEX44B,EAAQ3iC,oBAAoB,WAAY6kB,SAIzC,CAAE9a,MAAM,IAEX44B,EAAQr1B,QAAQs1B,iBAAmB,QAG9B,SAASzf,EAAwBwf,GACtC,OAAOvxD,QAAQuxD,EAAQr1B,QAAQu1B,0B,0DClCjC,MAKA,EALmBztD,IACjBA,EAAEM,kBACFN,EAAEoQ,mB,gBCJJ,IAAIs9C,EAEG,SAASC,IAAsF,IAAhEC,EAAgE,uDAAvD,IAAKzT,EAAkD,uCAApB0T,EAAoB,wDAC/FH,IACHA,EAAehkD,SAASksB,cAAc,SACtC83B,EAAa9nB,aAAa,OAAQ,SAGpC8nB,EAAa9nB,aAAa,SAAUgoB,GAEhCC,EACFH,EAAaI,gBAAgB,YAE7BJ,EAAa9nB,aAAa,WAAY,YAIxC8nB,EAAaK,SAAW,KACxBL,EAAax1D,MAAQ,GACrBw1D,EAAaK,SAAW5T,EAExBuT,EAAaM,Q,kCCnBR,SAASC,IACd,MAAM94D,EAAQwpB,iBAAiBjV,SAASkV,iBAClCooB,EAAkBknB,EAAmB/4D,EAAO,sBAC5Cg5D,EAAYD,EAAmB/4D,EAAO,gBACtCi5D,EAAcF,EAAmB/4D,EAAO,mBACxCk5D,EAAkBH,EAAmB/4D,EAAO,iBAC5Cm5D,EAAYJ,EAAmB/4D,EAAO,iBAG5C,MAAO,CACLo5D,SAAUvnB,EACVwnB,WAAYL,EACZM,WALgBP,EAAmB/4D,EAAO,0BAM1Cu5D,WAAYJ,EACZK,aAAcP,EACdQ,kBAAmBP,EACnBQ,mBARuBX,EAAmB/4D,EAAO,iCAY9C,SAAS25D,EAAiBvsD,GAC/B,MAAO,kBAAkBwsD,KAAKxsD,GAGhC,SAAS2rD,EAAmB/4D,EAA4B65D,GAEtD,OAIIF,EADavsD,EAJHpN,EAAM85D,iBAAiBD,GACdxxC,QAIajb,EAC5B,IAAGA,EAAM4oB,MAAM,8DACpBvU,MAAM,GACN9c,KAAI,CAACo1D,EAAWz4D,KAAqB,IAANA,EAAUG,KAAK8H,MAAsB,IAAhBywD,WAAWD,IAAYC,WAAWD,IACpFx8B,SAAS,IACT08B,SAAS,EAAG,KACZ7xC,QAAQ,MAAO,MACjB/a,KAAK,MARV,IAAmBD,E","sources":["webpack://telegram-t/./src/components/common/AnimatedIconFromSticker.tsx","webpack://telegram-t/./src/components/common/AnimatedIconWithPreview.module.scss?eca8","webpack://telegram-t/./src/components/common/AnimatedIconWithPreview.tsx","webpack://telegram-t/./src/components/common/helpers/waveform.ts","webpack://telegram-t/./src/util/waveform.ts","webpack://telegram-t/./src/components/common/Audio.tsx","webpack://telegram-t/./src/components/common/ChatExtra.tsx","webpack://telegram-t/./src/components/common/DeleteChatModal.tsx","webpack://telegram-t/./src/components/common/Document.tsx","webpack://telegram-t/./src/components/common/DotAnimation.tsx","webpack://telegram-t/./src/components/common/FakeIcon.tsx","webpack://telegram-t/./src/components/common/File.tsx","webpack://telegram-t/./src/components/common/GroupChatInfo.tsx","webpack://telegram-t/./src/components/common/LastMessageMeta.tsx","webpack://telegram-t/./src/components/common/Media.tsx","webpack://telegram-t/./src/components/common/MessageOutgoingStatus.tsx","webpack://telegram-t/./src/components/common/NothingFound.tsx","webpack://telegram-t/./src/components/common/PasswordForm.tsx","webpack://telegram-t/./src/components/common/Picker.tsx","webpack://telegram-t/./src/components/common/PickerSelectedItem.tsx","webpack://telegram-t/./src/components/common/PremiumIcon.tsx","webpack://telegram-t/./src/components/common/PrivateChatInfo.tsx","webpack://telegram-t/./src/components/common/ProfilePhoto.tsx","webpack://telegram-t/./src/components/common/ProfileInfo.tsx","webpack://telegram-t/./src/components/common/hooks/usePhotosPreload.ts","webpack://telegram-t/./src/components/common/ReactionStaticEmoji.tsx","webpack://telegram-t/./src/components/common/ReportModal.tsx","webpack://telegram-t/./src/components/common/StickerButton.tsx","webpack://telegram-t/./src/components/common/TypingStatus.tsx","webpack://telegram-t/./src/components/common/VerifiedIcon.tsx","webpack://telegram-t/./src/components/common/WebLink.tsx","webpack://telegram-t/./src/components/common/helpers/mediaDimensions.ts","webpack://telegram-t/./src/components/left/ChatFolderModal.async.tsx","webpack://telegram-t/./src/components/left/main/hooks/useChatAnimationType.ts","webpack://telegram-t/./src/components/left/main/Badge.tsx","webpack://telegram-t/./src/components/left/main/ChatCallStatus.tsx","webpack://telegram-t/./src/components/left/main/Chat.tsx","webpack://telegram-t/./src/components/left/main/EmptyFolder.tsx","webpack://telegram-t/./src/components/left/main/ChatList.tsx","webpack://telegram-t/./src/components/left/search/helpers/getSenderName.ts","webpack://telegram-t/./src/components/middle/composer/CustomSendMenu.async.tsx","webpack://telegram-t/./src/components/middle/composer/DropTarget.tsx","webpack://telegram-t/./src/components/middle/composer/DropArea.tsx","webpack://telegram-t/./src/components/middle/composer/EmojiTooltip.async.tsx","webpack://telegram-t/./src/components/middle/composer/MessageInput.tsx","webpack://telegram-t/./src/components/middle/composer/TextFormatter.tsx","webpack://telegram-t/./src/util/getKeyFromEvent.ts","webpack://telegram-t/./src/components/middle/composer/helpers/getFilesFromDataTransferItems.ts","webpack://telegram-t/./src/components/middle/composer/helpers/prepareForRegExp.ts","webpack://telegram-t/./src/components/middle/composer/helpers/selection.ts","webpack://telegram-t/./src/util/memoized.ts","webpack://telegram-t/./src/components/middle/composer/hooks/useEmojiTooltip.ts","webpack://telegram-t/./src/components/middle/composer/hooks/useMentionTooltip.ts","webpack://telegram-t/./src/components/right/hooks/useAsyncRendering.ts","webpack://telegram-t/./src/components/ui/CheckboxGroup.tsx","webpack://telegram-t/./src/components/ui/ConfirmDialog.tsx","webpack://telegram-t/./src/components/ui/FloatingActionButton.tsx","webpack://telegram-t/./src/components/ui/ListItem.tsx","webpack://telegram-t/./src/components/ui/MenuSeparator.module.scss?43c3","webpack://telegram-t/./src/components/ui/MenuSeparator.tsx","webpack://telegram-t/./src/components/ui/Notification.tsx","webpack://telegram-t/./src/components/ui/ProgressSpinner.tsx","webpack://telegram-t/./src/components/ui/Radio.tsx","webpack://telegram-t/./src/components/ui/RadioGroup.tsx","webpack://telegram-t/./src/components/ui/RangeSlider.tsx","webpack://telegram-t/./src/components/ui/SearchInput.tsx","webpack://telegram-t/./src/components/ui/ShowTransition.tsx","webpack://telegram-t/./src/components/ui/Skeleton.tsx","webpack://telegram-t/./src/components/ui/Switcher.tsx","webpack://telegram-t/./src/components/ui/Tab.tsx","webpack://telegram-t/./src/components/ui/TabList.tsx","webpack://telegram-t/./src/hooks/reducers/useFoldersReducer.ts","webpack://telegram-t/./src/hooks/useAudioPlayer.ts","webpack://telegram-t/./src/hooks/useBuffering.ts","webpack://telegram-t/./src/hooks/useCanvasBlur.ts","webpack://telegram-t/./src/hooks/useChatContextActions.ts","webpack://telegram-t/./src/hooks/useContextMenuHandlers.ts","webpack://telegram-t/./src/hooks/useContextMenuPosition.ts","webpack://telegram-t/./src/hooks/useEnsureMessage.ts","webpack://telegram-t/./src/hooks/useFolderManager.ts","webpack://telegram-t/./src/hooks/useHorizontalScroll.ts","webpack://telegram-t/./src/hooks/useHotkeys.ts","webpack://telegram-t/./src/util/parseHotkey.ts","webpack://telegram-t/./src/hooks/useInputFocusOnOpen.ts","webpack://telegram-t/./src/hooks/useLayoutEffectWithPrevDeps.ts","webpack://telegram-t/./src/hooks/useUniqueId.ts","webpack://telegram-t/./src/hooks/useMediaWithLoadProgress.ts","webpack://telegram-t/./src/hooks/useMouseInside.ts","webpack://telegram-t/./src/hooks/usePrevDuringAnimation.ts","webpack://telegram-t/./src/hooks/useReducer.ts","webpack://telegram-t/./src/hooks/useRunDebounced.ts","webpack://telegram-t/./src/components/common/CalendarModal.async.tsx","webpack://telegram-t/./src/hooks/useSchedule.tsx","webpack://telegram-t/./src/hooks/useSendMessageAction.ts","webpack://telegram-t/./src/hooks/useStateRef.ts","webpack://telegram-t/./src/hooks/useTimeout.ts","webpack://telegram-t/./src/lib/fastBlur.js","webpack://telegram-t/./src/util/audioPlayer.ts","webpack://telegram-t/./src/util/captureEvents.ts","webpack://telegram-t/./src/util/lethargy.ts","webpack://telegram-t/./src/util/colors.ts","webpack://telegram-t/./src/util/cycleRestrict.ts","webpack://telegram-t/./src/util/fastSmoothScroll.ts","webpack://telegram-t/./src/util/fastSmoothScrollHorizontal.ts","webpack://telegram-t/./src/util/focusEditableElement.ts","webpack://telegram-t/./src/util/getMessageIdsForSelectedText.ts","webpack://telegram-t/./src/util/isElementInViewport.ts","webpack://telegram-t/./src/util/mediaSession.ts","webpack://telegram-t/./src/util/parseMessageInput.ts","webpack://telegram-t/./src/util/patchSafariProgressiveAudio.ts","webpack://telegram-t/./src/util/stopEvent.ts","webpack://telegram-t/./src/util/systemFilesDialog.ts","webpack://telegram-t/./src/util/themeStyle.ts"],"sourcesContent":["import React, { memo } from '../../lib/teact/teact';\n\nimport type { OwnProps as AnimatedIconProps } from './AnimatedIcon';\nimport type { ApiSticker } from '../../api/types';\nimport { ApiMediaFormat } from '../../api/types';\n\nimport useMedia from '../../hooks/useMedia';\n\nimport AnimatedIconWithPreview from './AnimatedIconWithPreview';\n\ntype OwnProps =\n Partial<AnimatedIconProps>\n & { sticker?: ApiSticker; noLoad?: boolean; forcePreview?: boolean; lastSyncTime?: number };\n\nfunction AnimatedIconFromSticker(props: OwnProps) {\n const {\n sticker, noLoad, forcePreview, lastSyncTime, ...otherProps\n } = props;\n\n const thumbDataUri = sticker?.thumbnail?.dataUri;\n const localMediaHash = `sticker${sticker?.id}`;\n const previewBlobUrl = useMedia(\n sticker ? `${localMediaHash}?size=m` : undefined,\n noLoad && !forcePreview,\n ApiMediaFormat.BlobUrl,\n lastSyncTime,\n );\n const tgsUrl = useMedia(localMediaHash, noLoad, undefined, lastSyncTime);\n\n return (\n <AnimatedIconWithPreview\n tgsUrl={tgsUrl}\n previewUrl={previewBlobUrl}\n noPreviewTransition\n thumbDataUri={thumbDataUri}\n // eslint-disable-next-line react/jsx-props-no-spreading\n {...otherProps}\n />\n );\n}\n\nexport default memo(AnimatedIconFromSticker);\n","// extracted by mini-css-extract-plugin\nexport default {\"root\":\"oGmd77AsTbJeJk8CV6gl\",\"preview\":\"gp5OwinzPeHwkesmaEIR\"};","import React, { memo, useCallback } from '../../lib/teact/teact';\n\nimport type { OwnProps as AnimatedIconProps } from './AnimatedIcon';\n\nimport buildClassName from '../../util/buildClassName';\n\nimport useMediaTransition from '../../hooks/useMediaTransition';\nimport AnimatedIcon from './AnimatedIcon';\nimport styles from './AnimatedIconWithPreview.module.scss';\nimport useFlag from '../../hooks/useFlag';\nimport buildStyle from '../../util/buildStyle';\n\ntype OwnProps =\n Partial<AnimatedIconProps>\n & { previewUrl?: string; thumbDataUri?: string; noPreviewTransition?: boolean };\n\nconst loadedPreviewUrls = new Set();\n\nfunction AnimatedIconWithPreview(props: OwnProps) {\n const {\n previewUrl, thumbDataUri, noPreviewTransition, className, ...otherProps\n } = props;\n\n const [isPreviewLoaded, markPreviewLoaded] = useFlag(loadedPreviewUrls.has(previewUrl));\n const previewClassNames = useMediaTransition(noPreviewTransition || isPreviewLoaded);\n const [isAnimationReady, markAnimationReady] = useFlag(false);\n\n const handlePreviewLoad = useCallback(() => {\n markPreviewLoaded();\n loadedPreviewUrls.add(previewUrl);\n }, [markPreviewLoaded, previewUrl]);\n\n const { size } = props;\n\n return (\n <div\n className={buildClassName(className, styles.root)}\n style={buildStyle(size !== undefined && `width: ${size}px; height: ${size}px;`)}\n >\n {!isAnimationReady && thumbDataUri && (\n // eslint-disable-next-line jsx-a11y/alt-text\n <img src={thumbDataUri} className={buildClassName(styles.preview)} />\n )}\n {!isAnimationReady && previewUrl && (\n // eslint-disable-next-line jsx-a11y/alt-text\n <img\n src={previewUrl}\n className={buildClassName(styles.preview, previewClassNames)}\n onLoad={handlePreviewLoad}\n />\n )}\n {/* eslint-disable-next-line react/jsx-props-no-spreading */}\n <AnimatedIcon {...otherProps} onLoad={markAnimationReady} noTransition />\n </div>\n );\n}\n\nexport default memo(AnimatedIconWithPreview);\n","type IWaveformProps = {\n peak: number;\n fillStyle: string;\n progressFillStyle: string;\n};\n\nexport const MAX_EMPTY_WAVEFORM_POINTS = 30;\nconst SPIKE_WIDTH = 2;\nconst SPIKE_STEP = 4;\nconst SPIKE_RADIUS = 1;\nconst HEIGHT = 23;\n\nexport function renderWaveform(\n canvas: HTMLCanvasElement,\n spikes: number[],\n progress: number,\n {\n peak, fillStyle, progressFillStyle,\n }: IWaveformProps,\n) {\n const width = spikes.length * SPIKE_STEP;\n const height = HEIGHT;\n\n canvas.width = width * 2;\n canvas.height = height * 2;\n canvas.style.width = `${width}px`;\n canvas.style.height = `${height}px`;\n\n const ctx = canvas.getContext('2d')!;\n ctx.scale(2, 2);\n\n spikes.forEach((item, i) => {\n ctx.globalAlpha = (i / spikes.length >= progress) ? 0.5 : 1;\n ctx.fillStyle = progress > i / spikes.length ? progressFillStyle : fillStyle;\n const spikeHeight = Math.max(2, HEIGHT * (item / Math.max(1, peak)));\n roundedRectangle(ctx, i * SPIKE_STEP, (height + spikeHeight) / 2, SPIKE_WIDTH, spikeHeight, SPIKE_RADIUS);\n ctx.fill();\n });\n}\n\nfunction roundedRectangle(\n ctx: CanvasRenderingContext2D, x: number, y: number, width: number, height: number, radius: number,\n) {\n if (width < 2 * radius) {\n radius = width / 2;\n }\n if (height < 2 * radius) {\n radius = height / 2;\n }\n\n ctx.beginPath();\n ctx.moveTo(x + radius, y);\n ctx.arcTo(x + width, y, x + width, y - height, radius);\n ctx.arcTo(x + width, y - height, x, y - height, radius);\n ctx.arcTo(x, y - height, x, y, radius);\n ctx.arcTo(x, y, x + width, y, radius);\n ctx.closePath();\n}\n","/* eslint-disable no-bitwise */\n\n// eslint-disable-next-line max-len\n// Ref: https://github.com/telegramdesktop/tdesktop/blob/0743e71ab6b928d2ee5bae1aed991849b1e2b291/Telegram/SourceFiles/data/data_document.cpp#L1018\nexport function decodeWaveform(encoded5bit: Uint8Array) {\n const bitsCount = encoded5bit.length * 8;\n const valuesCount = Math.floor(bitsCount / 5);\n if (!valuesCount) {\n return [];\n }\n\n // Read each 5 bit of encoded5bit as 0-31 unsigned char.\n // We count the index of the byte in which the desired 5-bit sequence starts.\n // And then we read a uint16 starting from that byte to guarantee to get all of those 5 bits.\n //\n // BUT! if it is the last byte we have, we're not allowed to read a uint16 starting with it.\n // Because it will be an overflow (we'll access one byte after the available memory).\n // We see, that only the last 5 bits could start in the last available byte and be problematic.\n // So we read in a general way all the entries in a general way except the last one.\n const result = Array(valuesCount);\n const bitsData = encoded5bit;\n for (let i = 0, l = valuesCount - 1; i !== l; ++i) {\n const byteIndex = Math.floor((i * 5) / 8);\n const bitShift = Math.floor((i * 5) % 8);\n const value = bitsData[byteIndex] + (bitsData[byteIndex + 1] << 8);\n result[i] = ((value >> bitShift) & 0x1F);\n }\n const lastByteIndex = Math.floor(((valuesCount - 1) * 5) / 8);\n const lastBitShift = Math.floor(((valuesCount - 1) * 5) % 8);\n const lastValue = bitsData[lastByteIndex] + (bitsData[lastByteIndex + 1] << 8);\n result[valuesCount - 1] = (lastValue >> lastBitShift) & 0x1F;\n\n return result;\n}\n\nexport function interpolateArray(data: number[], fitCount: number) {\n let peak = 0;\n const newData = new Array(fitCount);\n const springFactor = data.length / fitCount;\n const leftFiller = data[0];\n const rightFiller = data[data.length - 1];\n for (let i = 0; i < fitCount; i++) {\n const idx = Math.floor(i * springFactor);\n const val = ((data[idx - 1] ?? leftFiller) + (data[idx] ?? leftFiller) + (data[idx + 1] ?? rightFiller)) / 3;\n newData[i] = val;\n if (peak < val) {\n peak = val;\n }\n }\n return { data: newData, peak };\n}\n","import type { FC } from '../../lib/teact/teact';\nimport React, {\n memo, useCallback, useEffect, useLayoutEffect, useMemo, useRef, useState,\n} from '../../lib/teact/teact';\nimport { getActions } from '../../global';\n\nimport type { ApiAudio, ApiMessage, ApiVoice } from '../../api/types';\nimport { ApiMediaFormat } from '../../api/types';\nimport type { ISettings } from '../../types';\nimport { AudioOrigin } from '../../types';\n\nimport { IS_SINGLE_COLUMN_LAYOUT } from '../../util/environment';\nimport { formatMediaDateTime, formatMediaDuration, formatPastTimeShort } from '../../util/dateFormat';\nimport {\n getMediaDuration,\n getMediaTransferState,\n getMessageMediaFormat,\n getMessageMediaHash,\n isMessageLocal,\n isOwnMessage,\n} from '../../global/helpers';\nimport { MAX_EMPTY_WAVEFORM_POINTS, renderWaveform } from './helpers/waveform';\nimport buildClassName from '../../util/buildClassName';\nimport renderText from './helpers/renderText';\nimport { getFileSizeString } from './helpers/documentInfo';\nimport { decodeWaveform, interpolateArray } from '../../util/waveform';\nimport useMediaWithLoadProgress from '../../hooks/useMediaWithLoadProgress';\nimport useShowTransition from '../../hooks/useShowTransition';\nimport type { BufferedRange } from '../../hooks/useBuffering';\nimport useBuffering from '../../hooks/useBuffering';\nimport useAudioPlayer from '../../hooks/useAudioPlayer';\nimport type { LangFn } from '../../hooks/useLang';\nimport useLang from '../../hooks/useLang';\nimport { captureEvents } from '../../util/captureEvents';\nimport useMedia from '../../hooks/useMedia';\nimport { makeTrackId } from '../../util/audioPlayer';\nimport { getTranslation } from '../../util/langProvider';\n\nimport Button from '../ui/Button';\nimport ProgressSpinner from '../ui/ProgressSpinner';\nimport Link from '../ui/Link';\n\nimport './Audio.scss';\n\ntype OwnProps = {\n theme: ISettings['theme'];\n message: ApiMessage;\n senderTitle?: string;\n uploadProgress?: number;\n origin: AudioOrigin;\n date?: number;\n lastSyncTime?: number;\n noAvatars?: boolean;\n className?: string;\n isSelectable?: boolean;\n isSelected?: boolean;\n isDownloading: boolean;\n isTranscribing?: boolean;\n isTranscribed?: boolean;\n canDownload?: boolean;\n canTranscribe?: boolean;\n isTranscriptionHidden?: boolean;\n isTranscriptionError?: boolean;\n onHideTranscription?: (isHidden: boolean) => void;\n onPlay: (messageId: number, chatId: string) => void;\n onReadMedia?: () => void;\n onCancelUpload?: () => void;\n onDateClick?: (messageId: number, chatId: string) => void;\n};\n\nexport const TINY_SCREEN_WIDTH_MQL = window.matchMedia('(max-width: 375px)');\nexport const WITH_AVATAR_TINY_SCREEN_WIDTH_MQL = window.matchMedia('(max-width: 410px)');\nconst AVG_VOICE_DURATION = 10;\n// This is needed for browsers requiring user interaction before playing.\nconst PRELOAD = true;\n// eslint-disable-next-line max-len\nconst TRANSCRIBE_SVG = '<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 32 24\" class=\"loading-svg\"><rect class=\"loading-rect\" fill=\"transparent\" width=\"32\" height=\"24\" stroke-width=\"3\" stroke-linejoin=\"round\" rx=\"6\" ry=\"6\" stroke=\"var(--accent-color)\" stroke-dashoffset=\"1\" stroke-dasharray=\"32,68\"></rect></svg>';\n\nconst Audio: FC<OwnProps> = ({\n theme,\n message,\n senderTitle,\n uploadProgress,\n origin,\n date,\n lastSyncTime,\n noAvatars,\n className,\n isSelectable,\n isSelected,\n isDownloading,\n isTranscribing,\n isTranscriptionHidden,\n isTranscribed,\n isTranscriptionError,\n canDownload,\n canTranscribe,\n onHideTranscription,\n onPlay,\n onReadMedia,\n onCancelUpload,\n onDateClick,\n}) => {\n const { cancelMessageMediaDownload, downloadMessageMedia, transcribeAudio } = getActions();\n\n const { content: { audio, voice, video }, isMediaUnread } = message;\n const isVoice = Boolean(voice || video);\n const isSeeking = useRef<boolean>(false);\n // eslint-disable-next-line no-null/no-null\n const seekerRef = useRef<HTMLDivElement>(null);\n const lang = useLang();\n const { isRtl } = lang;\n\n const [isActivated, setIsActivated] = useState(false);\n const shouldLoad = (isActivated || PRELOAD) && lastSyncTime;\n const coverHash = getMessageMediaHash(message, 'pictogram');\n const coverBlobUrl = useMedia(coverHash, false, ApiMediaFormat.BlobUrl);\n\n const mediaData = useMedia(\n getMessageMediaHash(message, 'inline'),\n !shouldLoad,\n getMessageMediaFormat(message, 'inline'),\n );\n\n const { loadProgress: downloadProgress } = useMediaWithLoadProgress(\n getMessageMediaHash(message, 'download'),\n !isDownloading,\n getMessageMediaFormat(message, 'download'),\n );\n\n const handleForcePlay = useCallback(() => {\n setIsActivated(true);\n onPlay(message.id, message.chatId);\n }, [message, onPlay]);\n\n const handleTrackChange = useCallback(() => {\n setIsActivated(false);\n }, []);\n\n const {\n isBuffered, bufferedRanges, bufferingHandlers, checkBuffering,\n } = useBuffering();\n\n const {\n isPlaying, playProgress, playPause, setCurrentTime, duration,\n } = useAudioPlayer(\n makeTrackId(message),\n getMediaDuration(message)!,\n isVoice ? 'voice' : 'audio',\n mediaData,\n bufferingHandlers,\n undefined,\n checkBuffering,\n isActivated,\n handleForcePlay,\n handleTrackChange,\n isMessageLocal(message),\n );\n\n const isOwn = isOwnMessage(message);\n const waveformCanvasRef = useWaveformCanvas(\n theme, voice, (isMediaUnread && !isOwn) ? 1 : playProgress, isOwn, !noAvatars,\n );\n\n const withSeekline = isPlaying || (playProgress > 0 && playProgress < 1);\n\n useEffect(() => {\n setIsActivated(isPlaying);\n }, [isPlaying]);\n\n const isLoadingForPlaying = isActivated && !isBuffered;\n\n const {\n isUploading, isTransferring, transferProgress,\n } = getMediaTransferState(\n message,\n uploadProgress || downloadProgress,\n isLoadingForPlaying || isDownloading,\n );\n\n const {\n shouldRender: shouldRenderSpinner,\n transitionClassNames: spinnerClassNames,\n } = useShowTransition(isTransferring);\n\n const shouldRenderCross = shouldRenderSpinner && (isLoadingForPlaying || isUploading);\n\n const handleButtonClick = useCallback(() => {\n if (isUploading) {\n onCancelUpload?.();\n return;\n }\n\n if (!isPlaying) {\n onPlay(message.id, message.chatId);\n }\n\n getActions().setAudioPlayerOrigin({ origin });\n setIsActivated(!isActivated);\n playPause();\n }, [isUploading, isPlaying, isActivated, playPause, onCancelUpload, onPlay, message.id, message.chatId, origin]);\n\n useEffect(() => {\n if (onReadMedia && isMediaUnread && (isPlaying || isDownloading)) {\n onReadMedia();\n }\n }, [isPlaying, isMediaUnread, onReadMedia, isDownloading]);\n\n const handleDownloadClick = useCallback(() => {\n if (isDownloading) {\n cancelMessageMediaDownload({ message });\n } else {\n downloadMessageMedia({ message });\n }\n }, [cancelMessageMediaDownload, downloadMessageMedia, isDownloading, message]);\n\n const handleSeek = useCallback((e: MouseEvent | TouchEvent) => {\n if (isSeeking.current && seekerRef.current) {\n const { width, left } = seekerRef.current.getBoundingClientRect();\n const clientX = e instanceof MouseEvent ? e.clientX : e.targetTouches[0].clientX;\n e.stopPropagation(); // Prevent Slide-to-Reply activation\n // Prevent track skipping while seeking near end\n setCurrentTime(Math.max(Math.min(duration * ((clientX - left) / width), duration - 0.1), 0.001));\n }\n }, [duration, setCurrentTime]);\n\n const handleStartSeek = useCallback((e: MouseEvent | TouchEvent) => {\n if (e instanceof MouseEvent && e.button === 2) return;\n isSeeking.current = true;\n handleSeek(e);\n }, [handleSeek]);\n\n const handleStopSeek = useCallback(() => {\n isSeeking.current = false;\n }, []);\n\n const handleDateClick = useCallback(() => {\n onDateClick!(message.id, message.chatId);\n }, [onDateClick, message.id, message.chatId]);\n\n const handleTranscribe = useCallback(() => {\n transcribeAudio({ chatId: message.chatId, messageId: message.id });\n }, [message.chatId, message.id, transcribeAudio]);\n\n useEffect(() => {\n if (!seekerRef.current || !withSeekline) return undefined;\n return captureEvents(seekerRef.current, {\n onCapture: handleStartSeek,\n onRelease: handleStopSeek,\n onClick: handleStopSeek,\n onDrag: handleSeek,\n });\n }, [withSeekline, handleStartSeek, handleSeek, handleStopSeek]);\n\n const transcribeSvgMemo = useMemo(() => (\n <div dangerouslySetInnerHTML={{ __html: TRANSCRIBE_SVG }} />\n ), []);\n\n function renderFirstLine() {\n if (isVoice) {\n return senderTitle || 'Voice';\n }\n\n const { title, fileName } = audio!;\n\n return title || fileName;\n }\n\n function renderSecondLine() {\n if (isVoice) {\n return (\n <div className=\"meta\" dir={isRtl ? 'rtl' : undefined}>\n {formatMediaDuration((voice || video)!.duration)}\n </div>\n );\n }\n\n const { performer } = audio!;\n\n return (\n <div className=\"meta\" dir={isRtl ? 'rtl' : undefined}>\n {formatMediaDuration(duration)}\n <span className=\"bullet\">&bull;</span>\n {performer && <span className=\"performer\" title={performer}>{renderText(performer)}</span>}\n {performer && senderTitle && <span className=\"bullet\">&bull;</span>}\n {senderTitle && <span title={senderTitle}>{renderText(senderTitle)}</span>}\n </div>\n );\n }\n\n const fullClassName = buildClassName(\n 'Audio',\n className,\n isOwn && origin === AudioOrigin.Inline && 'own',\n (origin === AudioOrigin.Search || origin === AudioOrigin.SharedMedia) && 'bigger',\n isSelected && 'audio-is-selected',\n );\n\n const buttonClassNames = ['toggle-play'];\n if (shouldRenderCross) {\n buttonClassNames.push('loading');\n } else {\n buttonClassNames.push(isPlaying ? 'pause' : 'play');\n }\n\n const contentClassName = buildClassName('content', withSeekline && 'with-seekline');\n\n function renderWithTitle() {\n return (\n <div className={contentClassName}>\n <div className=\"content-row\">\n <p className=\"title\" dir=\"auto\" title={renderFirstLine()}>{renderText(renderFirstLine())}</p>\n\n <div className=\"message-date\">\n {date && (\n <Link\n className=\"date\"\n onClick={handleDateClick}\n >\n {formatPastTimeShort(lang, date * 1000)}\n </Link>\n )}\n </div>\n </div>\n\n {withSeekline && (\n <div className=\"meta search-result\" dir={isRtl ? 'rtl' : undefined}>\n <span className=\"duration with-seekline\" dir=\"auto\">\n {playProgress < 1 && `${formatMediaDuration(duration * playProgress, duration)}`}\n </span>\n {renderSeekline(playProgress, bufferedRanges, seekerRef)}\n </div>\n )}\n {!withSeekline && renderSecondLine()}\n </div>\n );\n }\n\n return (\n <div className={fullClassName} dir={lang.isRtl ? 'rtl' : 'ltr'}>\n {isSelectable && (\n <div className=\"message-select-control\">\n {isSelected && <i className=\"icon-select\" />}\n </div>\n )}\n <Button\n round\n ripple={!IS_SINGLE_COLUMN_LAYOUT}\n size=\"smaller\"\n color={coverBlobUrl ? 'translucent-white' : 'primary'}\n className={buttonClassNames.join(' ')}\n ariaLabel={isPlaying ? 'Pause audio' : 'Play audio'}\n onClick={handleButtonClick}\n isRtl={lang.isRtl}\n backgroundImage={coverBlobUrl}\n >\n <i className=\"icon-play\" />\n <i className=\"icon-pause\" />\n </Button>\n {shouldRenderSpinner && (\n <div className={buildClassName('media-loading', spinnerClassNames, shouldRenderCross && 'interactive')}>\n <ProgressSpinner\n progress={transferProgress}\n transparent\n size=\"m\"\n onClick={shouldRenderCross ? handleButtonClick : undefined}\n noCross={!shouldRenderCross}\n />\n </div>\n )}\n {audio && canDownload && !isUploading && (\n <Button\n round\n size=\"tiny\"\n className=\"download-button\"\n ariaLabel={isDownloading ? 'Cancel download' : 'Download'}\n onClick={handleDownloadClick}\n >\n <i className={isDownloading ? 'icon-close' : 'icon-arrow-down'} />\n </Button>\n )}\n {origin === AudioOrigin.Search && renderWithTitle()}\n {origin !== AudioOrigin.Search && audio && renderAudio(\n lang,\n audio,\n duration,\n isPlaying,\n playProgress,\n bufferedRanges,\n seekerRef,\n (isDownloading || isUploading),\n date,\n transferProgress,\n onDateClick ? handleDateClick : undefined,\n )}\n {origin === AudioOrigin.SharedMedia && (voice || video) && renderWithTitle()}\n {origin === AudioOrigin.Inline && voice && (\n renderVoice(\n voice,\n seekerRef,\n waveformCanvasRef,\n playProgress,\n isMediaUnread,\n isTranscribing,\n isTranscriptionHidden,\n isTranscribed,\n isTranscriptionError,\n transcribeSvgMemo,\n canTranscribe ? handleTranscribe : undefined,\n onHideTranscription,\n )\n )}\n </div>\n );\n};\n\nfunction getSeeklineSpikeAmounts(withAvatar?: boolean) {\n return {\n MIN_SPIKES: IS_SINGLE_COLUMN_LAYOUT ? (TINY_SCREEN_WIDTH_MQL.matches ? 16 : 20) : 25,\n MAX_SPIKES: IS_SINGLE_COLUMN_LAYOUT\n ? (TINY_SCREEN_WIDTH_MQL.matches\n ? 35\n : (withAvatar && WITH_AVATAR_TINY_SCREEN_WIDTH_MQL.matches ? 40 : 45))\n : 75,\n };\n}\n\nfunction renderAudio(\n lang: LangFn,\n audio: ApiAudio,\n duration: number,\n isPlaying: boolean,\n playProgress: number,\n bufferedRanges: BufferedRange[],\n seekerRef: React.Ref<HTMLElement>,\n showProgress?: boolean,\n date?: number,\n progress?: number,\n handleDateClick?: NoneToVoidFunction,\n) {\n const {\n title, performer, fileName,\n } = audio;\n const showSeekline = isPlaying || (playProgress > 0 && playProgress < 1);\n const { isRtl } = getTranslation;\n\n return (\n <div className=\"content\">\n <p className=\"title\" dir=\"auto\" title={title}>{renderText(title || fileName)}</p>\n {showSeekline && (\n <div className=\"meta\" dir={isRtl ? 'rtl' : undefined}>\n <span className=\"duration with-seekline\" dir=\"auto\">\n {formatMediaDuration(duration * playProgress, duration)}\n </span>\n {renderSeekline(playProgress, bufferedRanges, seekerRef)}\n </div>\n )}\n {!showSeekline && showProgress && (\n <div className=\"meta\" dir={isRtl ? 'rtl' : undefined}>\n {progress ? `${getFileSizeString(audio!.size * progress)} / ` : undefined}{getFileSizeString(audio!.size)}\n </div>\n )}\n {!showSeekline && !showProgress && (\n <div className=\"meta\" dir={isRtl ? 'rtl' : undefined}>\n <span className=\"duration\" dir=\"auto\">{formatMediaDuration(duration)}</span>\n {performer && (\n <>\n <span className=\"bullet\">&bull;</span>\n <span className=\"performer\" dir=\"auto\" title={performer}>{renderText(performer)}</span>\n </>\n )}\n {date && (\n <>\n <span className=\"bullet\">&bull;</span>\n <Link className=\"date\" onClick={handleDateClick}>\n {formatMediaDateTime(lang, date * 1000, true)}\n </Link>\n </>\n )}\n </div>\n )}\n </div>\n );\n}\n\nfunction renderVoice(\n voice: ApiVoice,\n seekerRef: React.Ref<HTMLDivElement>,\n waveformCanvasRef: React.Ref<HTMLCanvasElement>,\n playProgress: number,\n isMediaUnread?: boolean,\n isTranscribing?: boolean,\n isTranscriptionHidden?: boolean,\n isTranscribed?: boolean,\n isTranscriptionError?: boolean,\n svgMemo?: React.ReactNode,\n onClickTranscribe?: VoidFunction,\n onHideTranscription?: (isHidden: boolean) => void,\n) {\n return (\n <div className=\"content\">\n <div className=\"waveform-wrapper\">\n <div\n className=\"waveform\"\n draggable={false}\n ref={seekerRef}\n >\n <canvas ref={waveformCanvasRef} />\n </div>\n {onClickTranscribe && (\n // eslint-disable-next-line react/jsx-no-bind\n <Button onClick={() => {\n if ((isTranscribed || isTranscriptionError) && onHideTranscription) {\n onHideTranscription(!isTranscriptionHidden);\n } else if (!isTranscribing) {\n onClickTranscribe();\n }\n }}\n >\n <i className={buildClassName(\n 'transcribe-icon',\n (isTranscribed || isTranscriptionError) ? 'icon-down' : 'icon-transcribe',\n (isTranscribed || isTranscriptionError) && !isTranscriptionHidden && 'transcribe-shown',\n )}\n />\n {isTranscribing && svgMemo}\n </Button>\n )}\n </div>\n <p className={buildClassName('voice-duration', isMediaUnread && 'unread')} dir=\"auto\">\n {playProgress === 0 ? formatMediaDuration(voice.duration) : formatMediaDuration(voice.duration * playProgress)}\n </p>\n </div>\n );\n}\n\nfunction useWaveformCanvas(\n theme: ISettings['theme'],\n voice?: ApiVoice,\n playProgress = 0,\n isOwn = false,\n withAvatar = false,\n) {\n // eslint-disable-next-line no-null/no-null\n const canvasRef = useRef<HTMLCanvasElement>(null);\n\n const { data: spikes, peak } = useMemo(() => {\n if (!voice) {\n return undefined;\n }\n\n const { waveform, duration } = voice;\n if (!waveform) {\n return {\n data: new Array(Math.min(duration, MAX_EMPTY_WAVEFORM_POINTS)).fill(0),\n peak: 0,\n };\n }\n\n const { MIN_SPIKES, MAX_SPIKES } = getSeeklineSpikeAmounts(withAvatar);\n const durationFactor = Math.min(duration / AVG_VOICE_DURATION, 1);\n const spikesCount = Math.round(MIN_SPIKES + (MAX_SPIKES - MIN_SPIKES) * durationFactor);\n const decodedWaveform = decodeWaveform(new Uint8Array(waveform));\n\n return interpolateArray(decodedWaveform, spikesCount);\n }, [voice, withAvatar]) || {};\n\n useLayoutEffect(() => {\n const canvas = canvasRef.current;\n\n if (!canvas || !spikes || peak === undefined) {\n return;\n }\n\n const fillColor = theme === 'dark' ? '#494A78' : '#ADD3F7';\n const fillOwnColor = theme === 'dark' ? '#B7ABED' : '#AEDFA4';\n const progressFillColor = theme === 'dark' ? '#8774E1' : '#3390EC';\n const progressFillOwnColor = theme === 'dark' ? '#FFFFFF' : '#4FAE4E';\n\n renderWaveform(canvas, spikes, playProgress, {\n peak,\n fillStyle: isOwn ? fillOwnColor : fillColor,\n progressFillStyle: isOwn ? progressFillOwnColor : progressFillColor,\n });\n }, [isOwn, peak, playProgress, spikes, theme]);\n\n return canvasRef;\n}\n\nfunction renderSeekline(\n playProgress: number,\n bufferedRanges: BufferedRange[],\n seekerRef: React.Ref<HTMLElement>,\n) {\n return (\n <div\n className=\"seekline no-selection\"\n ref={seekerRef as React.Ref<HTMLDivElement>}\n >\n {bufferedRanges.map(({ start, end }) => (\n <div\n className=\"seekline-buffered-progress\"\n style={`left: ${start * 100}%; right: ${100 - end * 100}%`}\n />\n ))}\n <span className=\"seekline-play-progress\">\n <i\n style={`transform: translateX(${playProgress * 100}%)`}\n />\n </span>\n <span className=\"seekline-thumb\">\n <i\n style={`transform: translateX(${playProgress * 100}%)`}\n />\n </span>\n </div>\n );\n}\n\nexport default memo(Audio);\n","import type { FC } from '../../lib/teact/teact';\nimport React, { memo, useCallback, useEffect } from '../../lib/teact/teact';\nimport { getActions, withGlobal } from '../../global';\n\nimport type { GlobalState } from '../../global/types';\nimport type { ApiChat, ApiCountryCode, ApiUser } from '../../api/types';\n\nimport {\n selectChat, selectNotifyExceptions, selectNotifySettings, selectUser,\n} from '../../global/selectors';\nimport {\n getChatDescription, getChatLink, getHasAdminRight, isChatChannel, isUserId, isUserRightBanned, selectIsChatMuted,\n} from '../../global/helpers';\nimport renderText from './helpers/renderText';\nimport { copyTextToClipboard } from '../../util/clipboard';\nimport { formatPhoneNumberWithCode } from '../../util/phoneNumber';\nimport useLang from '../../hooks/useLang';\n\nimport ListItem from '../ui/ListItem';\nimport Switcher from '../ui/Switcher';\n\ntype OwnProps = {\n chatOrUserId: string;\n forceShowSelf?: boolean;\n};\n\ntype StateProps =\n {\n user?: ApiUser;\n chat?: ApiChat;\n canInviteUsers?: boolean;\n isMuted?: boolean;\n phoneCodeList: ApiCountryCode[];\n }\n & Pick<GlobalState, 'lastSyncTime'>;\n\nconst ChatExtra: FC<OwnProps & StateProps> = ({\n lastSyncTime,\n user,\n chat,\n forceShowSelf,\n canInviteUsers,\n isMuted,\n phoneCodeList,\n}) => {\n const {\n loadFullUser,\n showNotification,\n updateChatMutedState,\n } = getActions();\n\n const {\n id: userId,\n fullInfo,\n username,\n phoneNumber,\n isSelf,\n } = user || {};\n const { id: chatId } = chat || {};\n const lang = useLang();\n\n useEffect(() => {\n if (lastSyncTime && userId) {\n loadFullUser({ userId });\n }\n }, [loadFullUser, userId, lastSyncTime]);\n\n const handleNotificationChange = useCallback(() => {\n updateChatMutedState({ chatId, isMuted: !isMuted });\n }, [chatId, isMuted, updateChatMutedState]);\n\n if (!chat || chat.isRestricted || (isSelf && !forceShowSelf)) {\n return undefined;\n }\n\n function copy(text: string, entity: string) {\n copyTextToClipboard(text);\n showNotification({ message: `${entity} was copied` });\n }\n\n const formattedNumber = phoneNumber && formatPhoneNumberWithCode(phoneCodeList, phoneNumber);\n const link = getChatLink(chat);\n const description = (fullInfo?.bio) || getChatDescription(chat);\n\n return (\n <div className=\"ChatExtra\">\n {formattedNumber && Boolean(formattedNumber.length) && (\n // eslint-disable-next-line react/jsx-no-bind\n <ListItem icon=\"phone\" multiline narrow ripple onClick={() => copy(formattedNumber, lang('Phone'))}>\n <span className=\"title\" dir=\"auto\">{formattedNumber}</span>\n <span className=\"subtitle\">{lang('Phone')}</span>\n </ListItem>\n )}\n {username && (\n <ListItem\n icon=\"mention\"\n multiline\n narrow\n ripple\n // eslint-disable-next-line react/jsx-no-bind\n onClick={() => copy(`@${username}`, lang('Username'))}\n >\n <span className=\"title\" dir=\"auto\">{renderText(username)}</span>\n <span className=\"subtitle\">{lang('Username')}</span>\n </ListItem>\n )}\n {description && Boolean(description.length) && (\n <ListItem\n icon=\"info\"\n multiline\n narrow\n isStatic\n >\n <span className=\"title word-break\" dir=\"auto\">\n {renderText(description, ['br', 'links', 'emoji'])}\n </span>\n <span className=\"subtitle\">{lang(userId ? 'UserBio' : 'Info')}</span>\n </ListItem>\n )}\n {(canInviteUsers || !username) && link && (\n <ListItem\n icon={chat.username ? 'mention' : 'link'}\n multiline\n narrow\n ripple\n // eslint-disable-next-line react/jsx-no-bind\n onClick={() => copy(link, lang('SetUrlPlaceholder'))}\n >\n <div className=\"title\">{link}</div>\n <span className=\"subtitle\">{lang('SetUrlPlaceholder')}</span>\n </ListItem>\n )}\n {!forceShowSelf && (\n <ListItem icon=\"unmute\" ripple onClick={handleNotificationChange}>\n <span>{lang('Notifications')}</span>\n <Switcher\n id=\"group-notifications\"\n label={userId ? 'Toggle User Notifications' : 'Toggle Chat Notifications'}\n checked={!isMuted}\n inactive\n />\n </ListItem>\n )}\n </div>\n );\n};\n\nexport default memo(withGlobal<OwnProps>(\n (global, { chatOrUserId }): StateProps => {\n const { lastSyncTime, countryList: { phoneCodes: phoneCodeList } } = global;\n\n const chat = chatOrUserId ? selectChat(global, chatOrUserId) : undefined;\n const user = isUserId(chatOrUserId) ? selectUser(global, chatOrUserId) : undefined;\n const isMuted = chat && selectIsChatMuted(chat, selectNotifySettings(global), selectNotifyExceptions(global));\n\n const canInviteUsers = chat && !user && (\n (!isChatChannel(chat) && !isUserRightBanned(chat, 'inviteUsers'))\n || getHasAdminRight(chat, 'inviteUsers')\n );\n\n return {\n lastSyncTime, phoneCodeList, chat, user, canInviteUsers, isMuted,\n };\n },\n)(ChatExtra));\n","import type { FC } from '../../lib/teact/teact';\nimport React, { useCallback, memo } from '../../lib/teact/teact';\nimport { getActions, withGlobal } from '../../global';\n\nimport type { ApiChat } from '../../api/types';\nimport type { AnimationLevel } from '../../types';\n\nimport { selectIsChatWithSelf, selectUser } from '../../global/selectors';\nimport {\n isUserId,\n isUserBot,\n getUserFirstOrLastName,\n getPrivateChatUserId,\n isChatBasicGroup,\n isChatSuperGroup,\n isChatChannel,\n getChatTitle,\n} from '../../global/helpers';\nimport useLang from '../../hooks/useLang';\nimport renderText from './helpers/renderText';\n\nimport Avatar from './Avatar';\nimport Modal from '../ui/Modal';\nimport Button from '../ui/Button';\n\nimport './DeleteChatModal.scss';\n\nexport type OwnProps = {\n isOpen: boolean;\n chat: ApiChat;\n onClose: () => void;\n onCloseAnimationEnd?: () => void;\n};\n\ntype StateProps = {\n isChannel: boolean;\n isChatWithSelf?: boolean;\n isBot?: boolean;\n isPrivateChat: boolean;\n isBasicGroup: boolean;\n isSuperGroup: boolean;\n currentUserId: string | undefined;\n canDeleteForAll?: boolean;\n contactName?: string;\n animationLevel: AnimationLevel;\n};\n\nconst DeleteChatModal: FC<OwnProps & StateProps> = ({\n isOpen,\n chat,\n isChannel,\n isPrivateChat,\n isChatWithSelf,\n isBot,\n isBasicGroup,\n isSuperGroup,\n currentUserId,\n canDeleteForAll,\n contactName,\n animationLevel,\n onClose,\n onCloseAnimationEnd,\n}) => {\n const {\n leaveChannel,\n deleteHistory,\n deleteChannel,\n deleteChatUser,\n blockContact,\n } = getActions();\n\n const lang = useLang();\n const chatTitle = getChatTitle(lang, chat);\n\n const handleDeleteForAll = useCallback(() => {\n deleteHistory({ chatId: chat.id, shouldDeleteForAll: true });\n\n onClose();\n }, [deleteHistory, chat.id, onClose]);\n\n const handleDeleteAndStop = useCallback(() => {\n deleteHistory({ chatId: chat.id, shouldDeleteForAll: true });\n blockContact({ contactId: chat.id, accessHash: chat.accessHash });\n\n onClose();\n }, [deleteHistory, chat.id, chat.accessHash, blockContact, onClose]);\n\n const handleDeleteChat = useCallback(() => {\n if (isPrivateChat) {\n deleteHistory({ chatId: chat.id, shouldDeleteForAll: false });\n } else if (isBasicGroup) {\n deleteChatUser({ chatId: chat.id, userId: currentUserId });\n deleteHistory({ chatId: chat.id, shouldDeleteForAll: false });\n } else if ((isChannel || isSuperGroup) && !chat.isCreator) {\n leaveChannel({ chatId: chat.id });\n } else if ((isChannel || isSuperGroup) && chat.isCreator) {\n deleteChannel({ chatId: chat.id });\n }\n onClose();\n }, [\n isPrivateChat,\n isBasicGroup,\n isChannel,\n isSuperGroup,\n currentUserId,\n chat.isCreator,\n chat.id,\n onClose,\n deleteHistory,\n deleteChatUser,\n leaveChannel,\n deleteChannel,\n ]);\n\n const handleLeaveChat = useCallback(() => {\n if (isChannel || isSuperGroup) {\n leaveChannel({ chatId: chat.id });\n onClose();\n } else {\n handleDeleteChat();\n }\n }, [chat.id, handleDeleteChat, isChannel, isSuperGroup, leaveChannel, onClose]);\n\n function renderHeader() {\n return (\n <div className=\"modal-header\" dir={lang.isRtl ? 'rtl' : undefined}>\n <Avatar\n size=\"tiny\"\n chat={chat}\n isSavedMessages={isChatWithSelf}\n animationLevel={animationLevel}\n withVideo\n />\n <h3 className=\"modal-title\">{lang(renderTitle())}</h3>\n </div>\n );\n }\n\n function renderTitle() {\n if (isChannel && !chat.isCreator) {\n return 'LeaveChannel';\n }\n\n if (isChannel && chat.isCreator) {\n return 'ChannelDelete';\n }\n\n if (isBasicGroup || isSuperGroup) {\n return 'Group.LeaveGroup';\n }\n\n return 'DeleteChatUser';\n }\n\n function renderContent() {\n if (isChannel && chat.isCreator) {\n return (\n <p>\n {renderText(lang('ChatList.DeleteAndLeaveGroupConfirmation', chatTitle), ['simple_markdown', 'emoji'])}\n </p>\n );\n }\n\n if ((isChannel && !chat.isCreator) || isBasicGroup || isSuperGroup) {\n return <p>{renderText(lang('ChannelLeaveAlertWithName', chatTitle), ['simple_markdown', 'emoji'])}</p>;\n }\n\n return <p>{renderText(lang('ChatList.DeleteChatConfirmation', contactName), ['simple_markdown', 'emoji'])}</p>;\n }\n\n function renderActionText() {\n if (isChannel && !chat.isCreator) {\n return 'LeaveChannel';\n }\n if (isChannel && chat.isCreator) {\n return 'Chat.Input.Delete';\n }\n\n if (isBasicGroup || isSuperGroup) {\n return 'Group.LeaveGroup';\n }\n\n return canDeleteForAll ? 'ChatList.DeleteForCurrentUser' : 'Delete';\n }\n\n return (\n <Modal\n isOpen={isOpen}\n className=\"DeleteChatModal\"\n header={renderHeader()}\n onClose={onClose}\n onCloseAnimationEnd={onCloseAnimationEnd}\n >\n {renderContent()}\n {isBot && (\n <Button color=\"danger\" className=\"confirm-dialog-button\" isText onClick={handleDeleteAndStop}>\n {lang('DeleteAndStop')}\n </Button>\n )}\n {canDeleteForAll && (\n <Button color=\"danger\" className=\"confirm-dialog-button\" isText onClick={handleDeleteForAll}>\n {contactName ? renderText(lang('ChatList.DeleteForEveryone', contactName)) : lang('DeleteForAll')}\n </Button>\n )}\n {!isPrivateChat && chat.isCreator && (\n <Button color=\"danger\" className=\"confirm-dialog-button\" isText onClick={handleDeleteChat}>\n {lang('DeleteForAll')}\n </Button>\n )}\n <Button\n color=\"danger\"\n className=\"confirm-dialog-button\"\n isText\n onClick={isPrivateChat ? handleDeleteChat : handleLeaveChat}\n >\n {lang(renderActionText())}\n </Button>\n <Button className=\"confirm-dialog-button\" isText onClick={onClose}>{lang('Cancel')}</Button>\n </Modal>\n );\n};\n\nexport default memo(withGlobal<OwnProps>(\n (global, { chat }): StateProps => {\n const isPrivateChat = isUserId(chat.id);\n const isChatWithSelf = selectIsChatWithSelf(global, chat.id);\n const user = isPrivateChat && selectUser(global, getPrivateChatUserId(chat)!);\n const isBot = user && isUserBot(user) && !chat.isSupport;\n const canDeleteForAll = (isPrivateChat && !isChatWithSelf && !isBot);\n const contactName = isPrivateChat\n ? getUserFirstOrLastName(selectUser(global, getPrivateChatUserId(chat)!))\n : undefined;\n\n return {\n isPrivateChat,\n isChatWithSelf,\n isBot,\n isChannel: isChatChannel(chat),\n isBasicGroup: isChatBasicGroup(chat),\n isSuperGroup: isChatSuperGroup(chat),\n currentUserId: global.currentUserId,\n canDeleteForAll,\n contactName,\n animationLevel: global.settings.byKey.animationLevel,\n };\n },\n)(DeleteChatModal));\n","import type { FC } from '../../lib/teact/teact';\nimport React, {\n useCallback, memo, useRef, useEffect, useState,\n} from '../../lib/teact/teact';\nimport { getActions } from '../../global';\n\nimport type { ApiMessage } from '../../api/types';\n\nimport { getDocumentExtension, getDocumentHasPreview } from './helpers/documentInfo';\nimport {\n getMediaTransferState,\n getMessageMediaFormat,\n getMessageMediaHash,\n getMessageMediaThumbDataUri,\n isMessageDocumentVideo,\n} from '../../global/helpers';\nimport type { ObserveFn } from '../../hooks/useIntersectionObserver';\nimport { useIsIntersecting } from '../../hooks/useIntersectionObserver';\nimport useMediaWithLoadProgress from '../../hooks/useMediaWithLoadProgress';\nimport useMedia from '../../hooks/useMedia';\nimport useFlag from '../../hooks/useFlag';\n\nimport File from './File';\n\ntype OwnProps = {\n message: ApiMessage;\n observeIntersection?: ObserveFn;\n smaller?: boolean;\n isSelected?: boolean;\n isSelectable?: boolean;\n canAutoLoad?: boolean;\n uploadProgress?: number;\n withDate?: boolean;\n datetime?: number;\n className?: string;\n sender?: string;\n autoLoadFileMaxSizeMb?: number;\n isDownloading: boolean;\n onCancelUpload?: () => void;\n onMediaClick?: () => void;\n onDateClick?: (messageId: number, chatId: string) => void;\n};\n\nconst BYTES_PER_MB = 1024 * 1024;\n\nconst Document: FC<OwnProps> = ({\n message,\n observeIntersection,\n smaller,\n canAutoLoad,\n autoLoadFileMaxSizeMb,\n uploadProgress,\n withDate,\n datetime,\n className,\n sender,\n isSelected,\n isSelectable,\n onCancelUpload,\n onMediaClick,\n onDateClick,\n isDownloading,\n}) => {\n const dispatch = getActions();\n\n // eslint-disable-next-line no-null/no-null\n const ref = useRef<HTMLDivElement>(null);\n\n const document = message.content.document!;\n const { fileName, size, timestamp } = document;\n const extension = getDocumentExtension(document) || '';\n\n const isIntersecting = useIsIntersecting(ref, observeIntersection);\n const [wasIntersected, markIntersected] = useFlag();\n useEffect(() => {\n if (isIntersecting) {\n markIntersected();\n }\n }, [isIntersecting, markIntersected]);\n\n // Auto-loading does not use global download manager because requires additional click to save files locally\n const [isLoadAllowed, setIsLoadAllowed] = useState(\n canAutoLoad && (!autoLoadFileMaxSizeMb || size <= autoLoadFileMaxSizeMb * BYTES_PER_MB),\n );\n\n const shouldDownload = Boolean(isDownloading || (isLoadAllowed && wasIntersected));\n\n const documentHash = getMessageMediaHash(message, 'download');\n const { loadProgress: downloadProgress, mediaData } = useMediaWithLoadProgress(\n documentHash, !shouldDownload, getMessageMediaFormat(message, 'download'), undefined, undefined, true,\n );\n const isLoaded = Boolean(mediaData);\n\n const {\n isUploading, isTransferring, transferProgress,\n } = getMediaTransferState(message, uploadProgress || downloadProgress, shouldDownload && !isLoaded);\n\n const hasPreview = getDocumentHasPreview(document);\n const thumbDataUri = hasPreview ? getMessageMediaThumbDataUri(message) : undefined;\n const localBlobUrl = hasPreview ? document.previewBlobUrl : undefined;\n const previewData = useMedia(getMessageMediaHash(message, 'pictogram'), !isIntersecting);\n\n const withMediaViewer = onMediaClick && Boolean(document.mediaType);\n\n const handleClick = useCallback(() => {\n if (isUploading) {\n if (onCancelUpload) {\n onCancelUpload();\n }\n return;\n }\n\n if (isDownloading) {\n dispatch.cancelMessageMediaDownload({ message });\n return;\n }\n\n if (isTransferring) {\n setIsLoadAllowed(false);\n return;\n }\n\n if (withMediaViewer) {\n onMediaClick!();\n } else {\n dispatch.downloadMessageMedia({ message });\n }\n }, [\n isUploading, isDownloading, isTransferring, withMediaViewer, onCancelUpload, dispatch, message, onMediaClick,\n ]);\n\n const handleDateClick = useCallback(() => {\n onDateClick!(message.id, message.chatId);\n }, [onDateClick, message.id, message.chatId]);\n\n return (\n <File\n ref={ref}\n name={fileName}\n extension={extension}\n size={size}\n timestamp={withDate ? datetime || timestamp : undefined}\n thumbnailDataUri={thumbDataUri}\n previewData={localBlobUrl || previewData}\n smaller={smaller}\n isTransferring={isTransferring}\n isUploading={isUploading}\n transferProgress={transferProgress}\n className={className}\n sender={sender}\n isSelectable={isSelectable}\n isSelected={isSelected}\n actionIcon={withMediaViewer ? (isMessageDocumentVideo(message) ? 'icon-play' : 'icon-eye') : 'icon-download'}\n onClick={handleClick}\n onDateClick={onDateClick ? handleDateClick : undefined}\n />\n );\n};\n\nexport default memo(Document);\n","import type { FC } from '../../lib/teact/teact';\nimport React from '../../lib/teact/teact';\n\nimport useLang from '../../hooks/useLang';\nimport buildClassName from '../../util/buildClassName';\n\nimport './DotAnimation.scss';\n\ntype OwnProps = {\n content: string;\n className?: string;\n};\n\nconst DotAnimation: FC<OwnProps> = ({ content, className }) => {\n const lang = useLang();\n return (\n <span className={buildClassName('DotAnimation', className)} dir={lang.isRtl ? 'rtl' : 'auto'}>\n {content}\n <span className=\"ellipsis\" />\n </span>\n );\n};\n\nexport default DotAnimation;\n","import type { FC } from '../../lib/teact/teact';\nimport React, { memo } from '../../lib/teact/teact';\n\nimport type { ApiFakeType } from '../../api/types';\n\nimport useLang from '../../hooks/useLang';\n\nimport './FakeIcon.scss';\n\ntype OwnProps = {\n fakeType: ApiFakeType;\n};\n\nconst FakeIcon: FC<OwnProps> = ({\n fakeType,\n}) => {\n const lang = useLang();\n\n return <span className=\"FakeIcon\">{lang(fakeType === 'fake' ? 'FakeMessage' : 'ScamMessage')}</span>;\n};\n\nexport default memo(FakeIcon);\n","import type { RefObject } from 'react';\nimport type { FC } from '../../lib/teact/teact';\nimport React, { memo, useRef } from '../../lib/teact/teact';\n\nimport useShowTransition from '../../hooks/useShowTransition';\nimport useMediaTransition from '../../hooks/useMediaTransition';\nimport buildClassName from '../../util/buildClassName';\nimport { formatMediaDateTime, formatPastTimeShort } from '../../util/dateFormat';\nimport { getColorFromExtension, getFileSizeString } from './helpers/documentInfo';\nimport { getDocumentThumbnailDimensions } from './helpers/mediaDimensions';\nimport renderText from './helpers/renderText';\nimport useLang from '../../hooks/useLang';\n\nimport ProgressSpinner from '../ui/ProgressSpinner';\nimport Link from '../ui/Link';\n\nimport './File.scss';\n\ntype OwnProps = {\n ref?: RefObject<HTMLDivElement>;\n name: string;\n extension?: string;\n size: number;\n timestamp?: number;\n sender?: string;\n thumbnailDataUri?: string;\n previewData?: string;\n className?: string;\n smaller?: boolean;\n isTransferring?: boolean;\n isUploading?: boolean;\n isSelectable?: boolean;\n isSelected?: boolean;\n transferProgress?: number;\n actionIcon?: string;\n onClick?: () => void;\n onDateClick?: (e: React.MouseEvent<HTMLAnchorElement>) => void;\n};\n\nconst File: FC<OwnProps> = ({\n ref,\n name,\n size,\n extension = '',\n timestamp,\n sender,\n thumbnailDataUri,\n previewData,\n className,\n smaller,\n isTransferring,\n isUploading,\n isSelectable,\n isSelected,\n transferProgress,\n actionIcon,\n onClick,\n onDateClick,\n}) => {\n const lang = useLang();\n // eslint-disable-next-line no-null/no-null\n let elementRef = useRef<HTMLDivElement>(null);\n if (ref) {\n elementRef = ref;\n }\n\n const transitionClassNames = useMediaTransition(previewData);\n const {\n shouldRender: shouldSpinnerRender,\n transitionClassNames: spinnerClassNames,\n } = useShowTransition(isTransferring, undefined, true);\n\n const color = getColorFromExtension(extension);\n const sizeString = getFileSizeString(size);\n\n const { width, height } = getDocumentThumbnailDimensions(smaller);\n\n const fullClassName = buildClassName(\n 'File',\n className,\n smaller && 'smaller',\n onClick && !isUploading && 'interactive',\n isSelected && 'file-is-selected',\n );\n\n return (\n <div ref={elementRef} className={fullClassName} dir={lang.isRtl ? 'rtl' : undefined}>\n {isSelectable && (\n <div className=\"message-select-control\">\n {isSelected && <i className=\"icon-select\" />}\n </div>\n )}\n <div className=\"file-icon-container\" onClick={isUploading ? undefined : onClick}>\n {thumbnailDataUri || previewData ? (\n <div className=\"file-preview media-inner\">\n <img\n src={thumbnailDataUri}\n width={width}\n height={height}\n className=\"thumbnail\"\n alt=\"\"\n />\n <img\n src={previewData}\n className={buildClassName('full-media', transitionClassNames)}\n width={width}\n height={height}\n alt=\"\"\n />\n </div>\n ) : (\n <div className={`file-icon ${color}`}>\n {extension.length <= 4 && (\n <span className=\"file-ext\" dir=\"auto\">{extension}</span>\n )}\n </div>\n )}\n {shouldSpinnerRender && (\n <div className={buildClassName('file-progress', color, spinnerClassNames)}>\n <ProgressSpinner\n progress={transferProgress}\n size={smaller ? 's' : 'm'}\n onClick={isUploading ? onClick : undefined}\n />\n </div>\n )}\n {onClick && (\n <i\n className={buildClassName(\n 'action-icon',\n actionIcon || 'icon-download',\n shouldSpinnerRender && 'hidden',\n )}\n />\n )}\n </div>\n <div className=\"file-info\">\n <div className=\"file-title\" dir=\"auto\">{renderText(name)}</div>\n <div className=\"file-subtitle\" dir=\"auto\">\n <span>\n {isTransferring && transferProgress ? `${Math.round(transferProgress * 100)}%` : sizeString}\n </span>\n {sender && <span className=\"file-sender\">{renderText(sender)}</span>}\n {!sender && timestamp && (\n <>\n <span className=\"bullet\" />\n <Link onClick={onDateClick}>{formatMediaDateTime(lang, timestamp * 1000, true)}</Link>\n </>\n )}\n </div>\n </div>\n {sender && timestamp && (\n <Link onClick={onDateClick}>{formatPastTimeShort(lang, timestamp * 1000)}</Link>\n )}\n </div>\n );\n};\n\nexport default memo(File);\n","import type { MouseEvent as ReactMouseEvent } from 'react';\nimport type { FC } from '../../lib/teact/teact';\nimport React, { useEffect, useCallback, memo } from '../../lib/teact/teact';\nimport { getActions, withGlobal } from '../../global';\n\nimport type { ApiChat, ApiTypingStatus } from '../../api/types';\nimport type { GlobalState } from '../../global/types';\nimport type { AnimationLevel } from '../../types';\nimport { MediaViewerOrigin } from '../../types';\n\nimport {\n getChatTypeString,\n getChatTitle,\n isChatSuperGroup,\n} from '../../global/helpers';\nimport { selectChat, selectChatMessages, selectChatOnlineCount } from '../../global/selectors';\nimport renderText from './helpers/renderText';\nimport type { LangFn } from '../../hooks/useLang';\nimport useLang from '../../hooks/useLang';\n\nimport Avatar from './Avatar';\nimport VerifiedIcon from './VerifiedIcon';\nimport TypingStatus from './TypingStatus';\nimport DotAnimation from './DotAnimation';\nimport FakeIcon from './FakeIcon';\n\ntype OwnProps = {\n chatId: string;\n typingStatus?: ApiTypingStatus;\n avatarSize?: 'small' | 'medium' | 'large' | 'jumbo';\n status?: string;\n withDots?: boolean;\n withMediaViewer?: boolean;\n withUsername?: boolean;\n withFullInfo?: boolean;\n withUpdatingStatus?: boolean;\n withChatType?: boolean;\n withVideoAvatar?: boolean;\n noRtl?: boolean;\n};\n\ntype StateProps =\n {\n chat?: ApiChat;\n onlineCount?: number;\n areMessagesLoaded: boolean;\n animationLevel: AnimationLevel;\n }\n & Pick<GlobalState, 'lastSyncTime'>;\n\nconst GroupChatInfo: FC<OwnProps & StateProps> = ({\n typingStatus,\n avatarSize = 'medium',\n status,\n withDots,\n withMediaViewer,\n withUsername,\n withFullInfo,\n withUpdatingStatus,\n withChatType,\n withVideoAvatar,\n noRtl,\n chat,\n onlineCount,\n areMessagesLoaded,\n animationLevel,\n lastSyncTime,\n}) => {\n const {\n loadFullChat,\n openMediaViewer,\n loadProfilePhotos,\n } = getActions();\n\n const isSuperGroup = chat && isChatSuperGroup(chat);\n const { id: chatId, isMin, isRestricted } = chat || {};\n\n useEffect(() => {\n if (chatId && !isMin && lastSyncTime) {\n if (withFullInfo) loadFullChat({ chatId });\n if (withMediaViewer) loadProfilePhotos({ profileId: chatId });\n }\n }, [chatId, isMin, lastSyncTime, withFullInfo, loadFullChat, loadProfilePhotos, isSuperGroup, withMediaViewer]);\n\n const handleAvatarViewerOpen = useCallback((e: ReactMouseEvent<HTMLDivElement, MouseEvent>, hasMedia: boolean) => {\n if (chat && hasMedia) {\n e.stopPropagation();\n openMediaViewer({\n avatarOwnerId: chat.id,\n mediaId: 0,\n origin: avatarSize === 'jumbo' ? MediaViewerOrigin.ProfileAvatar : MediaViewerOrigin.MiddleHeaderAvatar,\n });\n }\n }, [chat, avatarSize, openMediaViewer]);\n\n const lang = useLang();\n\n if (!chat) {\n return undefined;\n }\n\n function renderStatusOrTyping() {\n if (status) {\n return withDots ? (\n <DotAnimation className=\"status\" content={status} />\n ) : (\n <span className=\"status\" dir=\"auto\">{status}</span>\n );\n }\n\n if (withUpdatingStatus && !areMessagesLoaded && !isRestricted) {\n return (\n <DotAnimation className=\"status\" content={lang('Updating')} />\n );\n }\n\n if (!chat) {\n return undefined;\n }\n\n if (typingStatus) {\n return <TypingStatus typingStatus={typingStatus} />;\n }\n\n if (withChatType) {\n return (\n <span className=\"status\" dir=\"auto\">{lang(getChatTypeString(chat))}</span>\n );\n }\n\n const handle = withUsername ? chat.username : undefined;\n const groupStatus = getGroupStatus(lang, chat);\n const onlineStatus = onlineCount ? `, ${lang('OnlineCount', onlineCount, 'i')}` : undefined;\n\n return (\n <span className=\"status\">\n {handle && <span className=\"handle\">{handle}</span>}\n <span className=\"group-status\">{groupStatus}</span>\n {onlineStatus && <span className=\"online-status\">{onlineStatus}</span>}\n </span>\n );\n }\n\n return (\n <div className=\"ChatInfo\" dir={!noRtl && lang.isRtl ? 'rtl' : undefined}>\n <Avatar\n key={chat.id}\n size={avatarSize}\n chat={chat}\n onClick={withMediaViewer ? handleAvatarViewerOpen : undefined}\n withVideo={withVideoAvatar}\n animationLevel={animationLevel}\n />\n <div className=\"info\">\n <div className=\"title\">\n <h3 dir=\"auto\">{renderText(getChatTitle(lang, chat))}</h3>\n {chat.isVerified && <VerifiedIcon />}\n {chat.fakeType && <FakeIcon fakeType={chat.fakeType} />}\n </div>\n {renderStatusOrTyping()}\n </div>\n </div>\n );\n};\n\nfunction getGroupStatus(lang: LangFn, chat: ApiChat) {\n const chatTypeString = lang(getChatTypeString(chat));\n const { membersCount } = chat;\n\n if (chat.isRestricted) {\n return chatTypeString === 'Channel' ? 'channel is inaccessible' : 'group is inaccessible';\n }\n\n if (!membersCount) {\n return chatTypeString;\n }\n\n return chatTypeString === 'Channel'\n ? lang('Subscribers', membersCount, 'i')\n : lang('Members', membersCount, 'i');\n}\n\nexport default memo(withGlobal<OwnProps>(\n (global, { chatId }): StateProps => {\n const { lastSyncTime } = global;\n const chat = selectChat(global, chatId);\n const onlineCount = chat ? selectChatOnlineCount(global, chat) : undefined;\n const areMessagesLoaded = Boolean(selectChatMessages(global, chatId));\n\n return {\n lastSyncTime,\n chat,\n onlineCount,\n areMessagesLoaded,\n animationLevel: global.settings.byKey.animationLevel,\n };\n },\n)(GroupChatInfo));\n","import type { FC } from '../../lib/teact/teact';\nimport React, { memo } from '../../lib/teact/teact';\n\nimport type { ApiMessage, ApiMessageOutgoingStatus } from '../../api/types';\n\nimport { formatPastTimeShort } from '../../util/dateFormat';\nimport useLang from '../../hooks/useLang';\n\nimport MessageOutgoingStatus from './MessageOutgoingStatus';\n\nimport './LastMessageMeta.scss';\n\ntype OwnProps = {\n message: ApiMessage;\n outgoingStatus?: ApiMessageOutgoingStatus;\n};\n\nconst LastMessageMeta: FC<OwnProps> = ({ message, outgoingStatus }) => {\n const lang = useLang();\n return (\n <div className=\"LastMessageMeta\">\n {outgoingStatus && (\n <MessageOutgoingStatus status={outgoingStatus} />\n )}\n <span className=\"time\">{formatPastTimeShort(lang, message.date * 1000)}</span>\n </div>\n );\n};\n\nexport default memo(LastMessageMeta);\n","import type { FC } from '../../lib/teact/teact';\nimport React, { memo, useCallback, useRef } from '../../lib/teact/teact';\n\nimport type { ApiMessage } from '../../api/types';\n\nimport { formatMediaDuration } from '../../util/dateFormat';\nimport stopEvent from '../../util/stopEvent';\nimport {\n getMessageHtmlId,\n getMessageMediaHash,\n getMessageMediaThumbDataUri,\n getMessageVideo,\n} from '../../global/helpers';\nimport buildClassName from '../../util/buildClassName';\nimport useMedia from '../../hooks/useMedia';\nimport useMediaTransition from '../../hooks/useMediaTransition';\nimport type { ObserveFn } from '../../hooks/useIntersectionObserver';\nimport { useIsIntersecting } from '../../hooks/useIntersectionObserver';\n\nimport './Media.scss';\n\ntype OwnProps = {\n message: ApiMessage;\n idPrefix?: string;\n isProtected?: boolean;\n observeIntersection?: ObserveFn;\n onClick?: (messageId: number, chatId: string) => void;\n};\n\nconst Media: FC<OwnProps> = ({\n message,\n idPrefix = 'shared-media',\n isProtected,\n observeIntersection,\n onClick,\n}) => {\n // eslint-disable-next-line no-null/no-null\n const ref = useRef<HTMLDivElement>(null);\n\n const isIntersecting = useIsIntersecting(ref, observeIntersection);\n const thumbDataUri = getMessageMediaThumbDataUri(message);\n const mediaBlobUrl = useMedia(getMessageMediaHash(message, 'pictogram'), !isIntersecting);\n const transitionClassNames = useMediaTransition(mediaBlobUrl);\n\n const video = getMessageVideo(message);\n\n const handleClick = useCallback(() => {\n onClick!(message.id, message.chatId);\n }, [message.id, message.chatId, onClick]);\n\n return (\n <div\n ref={ref}\n id={`${idPrefix}${getMessageHtmlId(message.id)}`}\n className=\"Media scroll-item\"\n onClick={onClick ? handleClick : undefined}\n >\n <img\n src={thumbDataUri}\n alt=\"\"\n draggable={!isProtected}\n decoding=\"async\"\n onContextMenu={isProtected ? stopEvent : undefined}\n />\n <img\n src={mediaBlobUrl}\n className={buildClassName('full-media', transitionClassNames)}\n alt=\"\"\n draggable={!isProtected}\n decoding=\"async\"\n onContextMenu={isProtected ? stopEvent : undefined}\n />\n {video && <span className=\"video-duration\">{video.isGif ? 'GIF' : formatMediaDuration(video.duration)}</span>}\n {isProtected && <span className=\"protector\" />}\n </div>\n );\n};\n\nexport default memo(Media);\n","import type { FC } from '../../lib/teact/teact';\nimport React, { memo } from '../../lib/teact/teact';\n\nimport type { ApiMessageOutgoingStatus } from '../../api/types';\n\nimport Transition from '../ui/Transition';\n\nimport './MessageOutgoingStatus.scss';\n\ntype OwnProps = {\n status: ApiMessageOutgoingStatus;\n};\n\nenum Keys {\n failed, pending, succeeded, read,\n}\n\nconst MessageOutgoingStatus: FC<OwnProps> = ({ status }) => {\n return (\n <div className=\"MessageOutgoingStatus\">\n <Transition name=\"reveal\" activeKey={Keys[status]}>\n <i className={`icon-message-${status}`} />\n </Transition>\n </div>\n );\n};\n\nexport default memo(MessageOutgoingStatus);\n","import type { FC } from '../../lib/teact/teact';\nimport React, { memo } from '../../lib/teact/teact';\n\nimport buildClassName from '../../util/buildClassName';\nimport useShowTransition from '../../hooks/useShowTransition';\nimport renderText from './helpers/renderText';\nimport useLang from '../../hooks/useLang';\n\nimport './NothingFound.scss';\n\ninterface OwnProps {\n text?: string;\n description?: string;\n}\n\nconst DEFAULT_TEXT = 'Nothing found.';\n\nconst NothingFound: FC<OwnProps> = ({ text = DEFAULT_TEXT, description }) => {\n const lang = useLang();\n const { transitionClassNames } = useShowTransition(true);\n\n return (\n <div className={buildClassName('NothingFound', transitionClassNames, description && 'with-description')}>\n {text}\n {description && <p className=\"description\">{renderText(lang(description), ['br'])}</p>}\n </div>\n );\n};\n\nexport default memo(NothingFound);\n","import type { ChangeEvent } from 'react';\nimport type { FC } from '../../lib/teact/teact';\nimport React, {\n memo, useEffect, useRef, useState,\n} from '../../lib/teact/teact';\n\nimport { MIN_PASSWORD_LENGTH } from '../../config';\nimport { IS_TOUCH_ENV, IS_SINGLE_COLUMN_LAYOUT } from '../../util/environment';\nimport buildClassName from '../../util/buildClassName';\nimport useLang from '../../hooks/useLang';\nimport useTimeout from '../../hooks/useTimeout';\n\nimport Button from '../ui/Button';\n\ntype OwnProps = {\n submitLabel?: string;\n error?: string;\n hint?: string;\n placeholder?: string;\n isLoading?: boolean;\n shouldDisablePasswordManager?: boolean;\n shouldShowSubmit?: boolean;\n shouldResetValue?: boolean;\n isPasswordVisible?: boolean;\n clearError: NoneToVoidFunction;\n noRipple?: boolean;\n onChangePasswordVisibility: (state: boolean) => void;\n onInputChange?: (password: string) => void;\n onSubmit: (password: string) => void;\n};\n\nconst FOCUS_DELAY_TIMEOUT_MS = IS_SINGLE_COLUMN_LAYOUT ? 550 : 400;\n\nconst PasswordForm: FC<OwnProps> = ({\n isLoading = false,\n isPasswordVisible,\n error,\n hint,\n placeholder = 'Password',\n submitLabel = 'Next',\n shouldShowSubmit,\n shouldResetValue,\n shouldDisablePasswordManager = false,\n noRipple = false,\n clearError,\n onChangePasswordVisibility,\n onInputChange,\n onSubmit,\n}) => {\n // eslint-disable-next-line no-null/no-null\n const inputRef = useRef<HTMLInputElement>(null);\n const lang = useLang();\n\n const [password, setPassword] = useState('');\n const [canSubmit, setCanSubmit] = useState(false);\n\n useEffect(() => {\n if (shouldResetValue) {\n setPassword('');\n }\n }, [shouldResetValue]);\n\n useTimeout(() => {\n if (!IS_TOUCH_ENV) {\n inputRef.current!.focus();\n }\n }, FOCUS_DELAY_TIMEOUT_MS);\n\n useEffect(() => {\n if (error) {\n requestAnimationFrame(() => {\n inputRef.current!.focus();\n inputRef.current!.select();\n });\n }\n }, [error]);\n\n function onPasswordChange(e: ChangeEvent<HTMLInputElement>) {\n if (error) {\n clearError();\n }\n\n const { target } = e;\n setPassword(target.value);\n setCanSubmit(target.value.length >= MIN_PASSWORD_LENGTH);\n if (onInputChange) {\n onInputChange(target.value);\n }\n }\n\n function togglePasswordVisibility() {\n onChangePasswordVisibility(!isPasswordVisible);\n }\n\n function handleSubmit(event: React.FormEvent<HTMLFormElement>) {\n event.preventDefault();\n\n if (isLoading) {\n return;\n }\n\n if (canSubmit) {\n onSubmit(password);\n }\n }\n\n function renderFakeInput() {\n return (\n <input\n type=\"password\"\n id=\"prevent_autofill\"\n autoComplete=\"off\"\n className=\"visually-hidden\"\n tabIndex={-2}\n />\n );\n }\n\n return (\n <form action=\"\" onSubmit={handleSubmit} autoComplete=\"off\">\n <div\n className={buildClassName('input-group password-input', password && 'touched', error && 'error')}\n dir={lang.isRtl ? 'rtl' : undefined}\n >\n {shouldDisablePasswordManager && renderFakeInput()}\n <input\n ref={inputRef}\n className=\"form-control\"\n type={isPasswordVisible ? 'text' : 'password'}\n id=\"sign-in-password\"\n value={password || ''}\n autoComplete={shouldDisablePasswordManager ? 'one-time-code' : 'current-password'}\n onChange={onPasswordChange}\n maxLength={256}\n dir=\"auto\"\n />\n <label>{error || hint || placeholder}</label>\n <div\n className=\"toggle-password\"\n onClick={togglePasswordVisibility}\n role=\"button\"\n tabIndex={0}\n title=\"Toggle password visibility\"\n >\n <i className={isPasswordVisible ? 'icon-eye' : 'icon-eye-closed'} />\n </div>\n </div>\n {(canSubmit || shouldShowSubmit) && (\n <Button type=\"submit\" ripple={!noRipple} isLoading={isLoading} disabled={!canSubmit}>\n {submitLabel}\n </Button>\n )}\n </form>\n );\n};\n\nexport default memo(PasswordForm);\n","import type { FC } from '../../lib/teact/teact';\nimport React, {\n useCallback, useRef, useEffect, memo,\n} from '../../lib/teact/teact';\n\nimport { isUserId } from '../../global/helpers';\n\nimport InfiniteScroll from '../ui/InfiniteScroll';\nimport Checkbox from '../ui/Checkbox';\nimport InputText from '../ui/InputText';\nimport ListItem from '../ui/ListItem';\nimport PrivateChatInfo from './PrivateChatInfo';\nimport GroupChatInfo from './GroupChatInfo';\nimport PickerSelectedItem from './PickerSelectedItem';\nimport useInfiniteScroll from '../../hooks/useInfiniteScroll';\nimport useLang from '../../hooks/useLang';\n\nimport Loading from '../ui/Loading';\n\nimport './Picker.scss';\n\ntype OwnProps = {\n itemIds: string[];\n selectedIds: string[];\n filterValue?: string;\n filterPlaceholder?: string;\n notFoundText?: string;\n searchInputId?: string;\n isLoading?: boolean;\n noScrollRestore?: boolean;\n onSelectedIdsChange: (ids: string[]) => void;\n onFilterChange: (value: string) => void;\n onLoadMore?: () => void;\n};\n\n// Focus slows down animation, also it breaks transition layout in Chrome\nconst FOCUS_DELAY_MS = 500;\n\nconst MAX_FULL_ITEMS = 10;\nconst ALWAYS_FULL_ITEMS_COUNT = 5;\n\nconst Picker: FC<OwnProps> = ({\n itemIds,\n selectedIds,\n filterValue,\n filterPlaceholder,\n notFoundText,\n searchInputId,\n isLoading,\n noScrollRestore,\n onSelectedIdsChange,\n onFilterChange,\n onLoadMore,\n}) => {\n // eslint-disable-next-line no-null/no-null\n const inputRef = useRef<HTMLInputElement>(null);\n const shouldMinimize = selectedIds.length > MAX_FULL_ITEMS;\n\n useEffect(() => {\n setTimeout(() => {\n requestAnimationFrame(() => {\n inputRef.current!.focus();\n });\n }, FOCUS_DELAY_MS);\n }, []);\n\n const handleItemClick = useCallback((id: string) => {\n const newSelectedIds = [...selectedIds];\n if (newSelectedIds.includes(id)) {\n newSelectedIds.splice(newSelectedIds.indexOf(id), 1);\n } else {\n newSelectedIds.push(id);\n }\n onSelectedIdsChange(newSelectedIds);\n onFilterChange('');\n }, [selectedIds, onSelectedIdsChange, onFilterChange]);\n\n const handleFilterChange = useCallback((e: React.ChangeEvent<HTMLInputElement>) => {\n const { value } = e.currentTarget;\n onFilterChange(value);\n }, [onFilterChange]);\n\n const [viewportIds, getMore] = useInfiniteScroll(onLoadMore, itemIds, Boolean(filterValue));\n\n const lang = useLang();\n\n return (\n <div className=\"Picker\">\n <div className=\"picker-header custom-scroll\" dir={lang.isRtl ? 'rtl' : undefined}>\n {selectedIds.map((id, i) => (\n <PickerSelectedItem\n chatOrUserId={id}\n isMinimized={shouldMinimize && i < selectedIds.length - ALWAYS_FULL_ITEMS_COUNT}\n canClose\n onClick={handleItemClick}\n clickArg={id}\n />\n ))}\n <InputText\n id={searchInputId}\n ref={inputRef}\n value={filterValue}\n onChange={handleFilterChange}\n placeholder={filterPlaceholder || lang('SelectChat')}\n />\n </div>\n\n {viewportIds?.length ? (\n <InfiniteScroll\n className=\"picker-list custom-scroll\"\n items={viewportIds}\n onLoadMore={getMore}\n noScrollRestore={noScrollRestore}\n >\n {viewportIds.map((id) => (\n <ListItem\n key={id}\n className=\"chat-item-clickable picker-list-item\"\n // eslint-disable-next-line react/jsx-no-bind\n onClick={() => handleItemClick(id)}\n ripple\n >\n <Checkbox label=\"\" checked={selectedIds.includes(id)} />\n {isUserId(id) ? (\n <PrivateChatInfo userId={id} />\n ) : (\n <GroupChatInfo chatId={id} />\n )}\n </ListItem>\n ))}\n </InfiniteScroll>\n ) : !isLoading && viewportIds && !viewportIds.length ? (\n <p className=\"no-results\">{notFoundText || 'Sorry, nothing found.'}</p>\n ) : (\n <Loading />\n )}\n </div>\n );\n};\n\nexport default memo(Picker);\n","import type { FC, TeactNode } from '../../lib/teact/teact';\nimport React, { memo } from '../../lib/teact/teact';\nimport { withGlobal } from '../../global';\n\nimport type { ApiChat, ApiUser } from '../../api/types';\n\nimport { selectChat, selectUser } from '../../global/selectors';\nimport { getChatTitle, getUserFirstOrLastName, isUserId } from '../../global/helpers';\nimport renderText from './helpers/renderText';\nimport buildClassName from '../../util/buildClassName';\nimport useLang from '../../hooks/useLang';\n\nimport Avatar from './Avatar';\n\nimport './PickerSelectedItem.scss';\n\ntype OwnProps = {\n chatOrUserId?: string;\n icon?: string;\n title?: string;\n isMinimized?: boolean;\n canClose?: boolean;\n onClick: (arg: any) => void;\n clickArg: any;\n className?: string;\n};\n\ntype StateProps = {\n chat?: ApiChat;\n user?: ApiUser;\n};\n\nconst PickerSelectedItem: FC<OwnProps & StateProps> = ({\n icon,\n title,\n isMinimized,\n canClose,\n onClick,\n clickArg,\n chat,\n user,\n className,\n}) => {\n const lang = useLang();\n\n let iconElement: TeactNode | undefined;\n let titleText: any;\n\n if (icon && title) {\n iconElement = (\n <div className=\"item-icon\">\n <i className={`icon-${icon}`} />\n </div>\n );\n\n titleText = title;\n } else if (chat || user) {\n iconElement = (\n <Avatar\n chat={chat}\n user={user}\n size=\"small\"\n isSavedMessages={user?.isSelf}\n />\n );\n\n const name = !chat || (user && !user.isSelf)\n ? getUserFirstOrLastName(user)\n : getChatTitle(lang, chat, user);\n\n titleText = name ? renderText(name) : undefined;\n }\n\n const fullClassName = buildClassName(\n 'PickerSelectedItem',\n className,\n isMinimized && 'minimized',\n canClose && 'closeable',\n );\n\n return (\n <div\n className={fullClassName}\n onClick={() => onClick(clickArg)}\n title={isMinimized ? titleText : undefined}\n dir={lang.isRtl ? 'rtl' : undefined}\n >\n {iconElement}\n {!isMinimized && (\n <div className=\"item-name\" dir=\"auto\">\n {titleText}\n </div>\n )}\n {canClose && (\n <div className=\"item-remove\">\n <i className=\"icon-close\" />\n </div>\n )}\n </div>\n );\n};\n\nexport default memo(withGlobal<OwnProps>(\n (global, { chatOrUserId }): StateProps => {\n if (!chatOrUserId) {\n return {};\n }\n\n const chat = chatOrUserId ? selectChat(global, chatOrUserId) : undefined;\n const user = isUserId(chatOrUserId) ? selectUser(global, chatOrUserId) : undefined;\n\n return {\n chat,\n user,\n };\n },\n)(PickerSelectedItem));\n","import type { FC } from '../../lib/teact/teact';\nimport React, { memo, useMemo } from '../../lib/teact/teact';\n\nimport generateIdFor from '../../util/generateIdFor';\n\nimport buildClassName from '../../util/buildClassName';\n\nimport './PremiumIcon.scss';\n\n// eslint-disable-next-line max-len\nconst PREMIUM_ICON = { __html: '<svg width=\"14\" height=\"15\" viewBox=\"0 0 14 15\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\"><path fill-rule=\"evenodd\" clip-rule=\"evenodd\" d=\"M6.63869 12.1902L3.50621 14.1092C3.18049 14.3087 2.75468 14.2064 2.55515 13.8807C2.45769 13.7216 2.42864 13.5299 2.47457 13.3491L2.95948 11.4405C3.13452 10.7515 3.60599 10.1756 4.24682 9.86791L7.6642 8.22716C7.82352 8.15067 7.89067 7.95951 7.81418 7.80019C7.75223 7.67116 7.61214 7.59896 7.47111 7.62338L3.66713 8.28194C2.89387 8.41581 2.1009 8.20228 1.49941 7.69823L0.297703 6.69116C0.00493565 6.44581 -0.0335059 6.00958 0.211842 5.71682C0.33117 5.57442 0.502766 5.48602 0.687982 5.47153L4.35956 5.18419C4.61895 5.16389 4.845 4.99974 4.94458 4.75937L6.36101 1.3402C6.5072 0.987302 6.91179 0.819734 7.26469 0.965925C7.43413 1.03612 7.56876 1.17075 7.63896 1.3402L9.05539 4.75937C9.15496 4.99974 9.38101 5.16389 9.6404 5.18419L13.3322 5.47311C13.713 5.50291 13.9975 5.83578 13.9677 6.2166C13.9534 6.39979 13.8667 6.56975 13.7269 6.68896L10.9114 9.08928C10.7131 9.25826 10.6267 9.52425 10.6876 9.77748L11.5532 13.3733C11.6426 13.7447 11.414 14.1182 11.0427 14.2076C10.8642 14.2506 10.676 14.2208 10.5195 14.1249L7.36128 12.1902C7.13956 12.0544 6.8604 12.0544 6.63869 12.1902Z\" fill=\"var(--color-fill)\"/></svg>' };\nconst store: Record<string, boolean> = {};\n\ntype OwnProps = {\n withGradient?: boolean;\n big?: boolean;\n className?: string;\n onClick?: VoidFunction;\n};\n\nconst PremiumIcon: FC<OwnProps> = ({\n withGradient,\n big,\n className,\n onClick,\n}) => {\n const html = useMemo(() => {\n return withGradient ? getPremiumIconGradient() : PREMIUM_ICON;\n }, [withGradient]);\n\n return (\n <i\n onClick={onClick}\n className={buildClassName(\n 'PremiumIcon', className, withGradient && 'gradient', onClick && 'clickable', big && 'big',\n )}\n dangerouslySetInnerHTML={html}\n title=\"Premium\"\n />\n );\n};\n\nfunction getPremiumIconGradient() {\n const id = generateIdFor(store);\n return {\n // eslint-disable-next-line max-len\n __html: `<svg width=\"14\" height=\"15\" viewBox=\"0 0 14 15\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\"><defs><linearGradient id=\"${id}\" x1=\"3\" y1=\"63.5001\" x2=\"84.1475\" y2=\"-1.32262\" gradientUnits=\"userSpaceOnUse\"><stop stop-color=\"#6B93FF\"/><stop offset=\"0.439058\" stop-color=\"#976FFF\"/><stop offset=\"1\" stop-color=\"#E46ACE\"/></linearGradient></defs><path fill-rule=\"evenodd\" clip-rule=\"evenodd\" d=\"M6.63869 12.1902L3.50621 14.1092C3.18049 14.3087 2.75468 14.2064 2.55515 13.8807C2.45769 13.7216 2.42864 13.5299 2.47457 13.3491L2.95948 11.4405C3.13452 10.7515 3.60599 10.1756 4.24682 9.86791L7.6642 8.22716C7.82352 8.15067 7.89067 7.95951 7.81418 7.80019C7.75223 7.67116 7.61214 7.59896 7.47111 7.62338L3.66713 8.28194C2.89387 8.41581 2.1009 8.20228 1.49941 7.69823L0.297703 6.69116C0.00493565 6.44581 -0.0335059 6.00958 0.211842 5.71682C0.33117 5.57442 0.502766 5.48602 0.687982 5.47153L4.35956 5.18419C4.61895 5.16389 4.845 4.99974 4.94458 4.75937L6.36101 1.3402C6.5072 0.987302 6.91179 0.819734 7.26469 0.965925C7.43413 1.03612 7.56876 1.17075 7.63896 1.3402L9.05539 4.75937C9.15496 4.99974 9.38101 5.16389 9.6404 5.18419L13.3322 5.47311C13.713 5.50291 13.9975 5.83578 13.9677 6.2166C13.9534 6.39979 13.8667 6.56975 13.7269 6.68896L10.9114 9.08928C10.7131 9.25826 10.6267 9.52425 10.6876 9.77748L11.5532 13.3733C11.6426 13.7447 11.414 14.1182 11.0427 14.2076C10.8642 14.2506 10.676 14.2208 10.5195 14.1249L7.36128 12.1902C7.13956 12.0544 6.8604 12.0544 6.63869 12.1902Z\" fill=\"url(#${id})\"/></svg>`,\n };\n}\n\nexport default memo(PremiumIcon);\n","import type { MouseEvent as ReactMouseEvent } from 'react';\nimport type { FC } from '../../lib/teact/teact';\nimport React, { useEffect, useCallback, memo } from '../../lib/teact/teact';\nimport { getActions, withGlobal } from '../../global';\n\nimport type { ApiUser, ApiTypingStatus, ApiUserStatus } from '../../api/types';\nimport type { GlobalState } from '../../global/types';\nimport type { AnimationLevel } from '../../types';\nimport { MediaViewerOrigin } from '../../types';\n\nimport { selectChatMessages, selectUser, selectUserStatus } from '../../global/selectors';\nimport { getUserFullName, getUserStatus, isUserOnline } from '../../global/helpers';\nimport renderText from './helpers/renderText';\nimport useLang from '../../hooks/useLang';\n\nimport Avatar from './Avatar';\nimport VerifiedIcon from './VerifiedIcon';\nimport TypingStatus from './TypingStatus';\nimport DotAnimation from './DotAnimation';\nimport FakeIcon from './FakeIcon';\nimport PremiumIcon from './PremiumIcon';\n\ntype OwnProps = {\n userId: string;\n typingStatus?: ApiTypingStatus;\n avatarSize?: 'tiny' | 'small' | 'medium' | 'large' | 'jumbo';\n forceShowSelf?: boolean;\n status?: string;\n withDots?: boolean;\n withMediaViewer?: boolean;\n withUsername?: boolean;\n withFullInfo?: boolean;\n withUpdatingStatus?: boolean;\n withVideoAvatar?: boolean;\n noStatusOrTyping?: boolean;\n noRtl?: boolean;\n};\n\ntype StateProps =\n {\n user?: ApiUser;\n userStatus?: ApiUserStatus;\n isSavedMessages?: boolean;\n animationLevel: AnimationLevel;\n areMessagesLoaded: boolean;\n serverTimeOffset: number;\n }\n & Pick<GlobalState, 'lastSyncTime'>;\n\nconst PrivateChatInfo: FC<OwnProps & StateProps> = ({\n typingStatus,\n avatarSize = 'medium',\n status,\n withDots,\n withMediaViewer,\n withUsername,\n withFullInfo,\n withUpdatingStatus,\n withVideoAvatar,\n noStatusOrTyping,\n noRtl,\n user,\n userStatus,\n isSavedMessages,\n areMessagesLoaded,\n animationLevel,\n lastSyncTime,\n serverTimeOffset,\n}) => {\n const {\n loadFullUser,\n openMediaViewer,\n loadProfilePhotos,\n } = getActions();\n\n const { id: userId } = user || {};\n const fullName = getUserFullName(user);\n\n useEffect(() => {\n if (userId && lastSyncTime) {\n if (withFullInfo) loadFullUser({ userId });\n if (withMediaViewer) loadProfilePhotos({ profileId: userId });\n }\n }, [userId, loadFullUser, loadProfilePhotos, lastSyncTime, withFullInfo, withMediaViewer]);\n\n const handleAvatarViewerOpen = useCallback((e: ReactMouseEvent<HTMLDivElement, MouseEvent>, hasMedia: boolean) => {\n if (user && hasMedia) {\n e.stopPropagation();\n openMediaViewer({\n avatarOwnerId: user.id,\n mediaId: 0,\n origin: avatarSize === 'jumbo' ? MediaViewerOrigin.ProfileAvatar : MediaViewerOrigin.MiddleHeaderAvatar,\n });\n }\n }, [user, avatarSize, openMediaViewer]);\n\n const lang = useLang();\n\n if (!user) {\n return undefined;\n }\n\n function renderStatusOrTyping() {\n if (status) {\n return withDots ? (\n <DotAnimation className=\"status\" content={status} />\n ) : (\n <span className=\"status\" dir=\"auto\">{status}</span>\n );\n }\n\n if (withUpdatingStatus && !areMessagesLoaded) {\n return (\n <DotAnimation className=\"status\" content={lang('Updating')} />\n );\n }\n\n if (!user) {\n return undefined;\n }\n\n if (typingStatus) {\n return <TypingStatus typingStatus={typingStatus} />;\n }\n\n return (\n <span className={`status ${isUserOnline(user, userStatus) ? 'online' : ''}`}>\n {withUsername && user.username && <span className=\"handle\">{user.username}</span>}\n <span className=\"user-status\" dir=\"auto\">{getUserStatus(lang, user, userStatus, serverTimeOffset)}</span>\n </span>\n );\n }\n\n return (\n <div className=\"ChatInfo\" dir={!noRtl && lang.isRtl ? 'rtl' : undefined}>\n <Avatar\n key={user.id}\n size={avatarSize}\n user={user}\n isSavedMessages={isSavedMessages}\n onClick={withMediaViewer ? handleAvatarViewerOpen : undefined}\n withVideo={withVideoAvatar}\n animationLevel={animationLevel}\n />\n <div className=\"info\">\n {isSavedMessages ? (\n <div className=\"title\">\n <h3>{lang('SavedMessages')}</h3>\n </div>\n ) : (\n <div className=\"title\">\n <h3 dir=\"auto\">{fullName && renderText(fullName)}</h3>\n {user?.isVerified && <VerifiedIcon />}\n {user.isPremium && <PremiumIcon />}\n {user.fakeType && <FakeIcon fakeType={user.fakeType} />}\n </div>\n )}\n {(status || (!isSavedMessages && !noStatusOrTyping)) && renderStatusOrTyping()}\n </div>\n </div>\n );\n};\n\nexport default memo(withGlobal<OwnProps>(\n (global, { userId, forceShowSelf }): StateProps => {\n const { lastSyncTime, serverTimeOffset } = global;\n const user = selectUser(global, userId);\n const userStatus = selectUserStatus(global, userId);\n const isSavedMessages = !forceShowSelf && user && user.isSelf;\n const areMessagesLoaded = Boolean(selectChatMessages(global, userId));\n\n return {\n lastSyncTime,\n user,\n userStatus,\n isSavedMessages,\n areMessagesLoaded,\n serverTimeOffset,\n animationLevel: global.settings.byKey.animationLevel,\n };\n },\n)(PrivateChatInfo));\n","import React, { memo, useEffect, useRef } from '../../lib/teact/teact';\n\nimport type { FC, TeactNode } from '../../lib/teact/teact';\nimport type { ApiChat, ApiPhoto, ApiUser } from '../../api/types';\nimport { ApiMediaFormat } from '../../api/types';\n\nimport {\n getChatAvatarHash,\n getChatTitle,\n getUserColorKey,\n getUserFullName,\n isUserId,\n isChatWithRepliesBot,\n isDeletedUser, getVideoAvatarMediaHash,\n} from '../../global/helpers';\nimport renderText from './helpers/renderText';\nimport buildClassName from '../../util/buildClassName';\nimport safePlay from '../../util/safePlay';\nimport { getFirstLetters } from '../../util/textFormat';\nimport useMedia from '../../hooks/useMedia';\nimport useLang from '../../hooks/useLang';\n\nimport Spinner from '../ui/Spinner';\n\nimport './ProfilePhoto.scss';\n\ntype OwnProps = {\n chat?: ApiChat;\n user?: ApiUser;\n isFirstPhoto?: boolean;\n isSavedMessages?: boolean;\n photo?: ApiPhoto;\n lastSyncTime?: number;\n notActive?: boolean;\n onClick: NoneToVoidFunction;\n};\n\nconst ProfilePhoto: FC<OwnProps> = ({\n chat,\n user,\n photo,\n isFirstPhoto,\n isSavedMessages,\n notActive,\n lastSyncTime,\n onClick,\n}) => {\n // eslint-disable-next-line no-null/no-null\n const videoRef = useRef<HTMLVideoElement>(null);\n const lang = useLang();\n const isDeleted = user && isDeletedUser(user);\n const isRepliesChat = chat && isChatWithRepliesBot(chat.id);\n\n function getMediaHash(size: 'normal' | 'big', type: 'photo' | 'video' = 'photo') {\n const userOrChat = user || chat;\n const profilePhoto = photo || userOrChat?.fullInfo?.profilePhoto;\n const hasVideo = profilePhoto?.isVideo;\n const forceAvatar = isFirstPhoto;\n\n if (type === 'video' && !hasVideo) return undefined;\n\n if (photo && !forceAvatar) {\n if (hasVideo && type === 'video') {\n return getVideoAvatarMediaHash(photo);\n }\n if (type === 'photo') {\n return `photo${photo.id}?size=c`;\n }\n }\n\n if (!isSavedMessages && !isDeleted && !isRepliesChat && userOrChat) {\n return getChatAvatarHash(userOrChat, size, type);\n }\n\n return undefined;\n }\n\n useEffect(() => {\n if (!videoRef.current) return;\n if (notActive) {\n videoRef.current.pause();\n videoRef.current.currentTime = 0;\n } else {\n safePlay(videoRef.current);\n }\n }, [notActive]);\n\n const photoHash = getMediaHash('big', 'photo');\n const photoBlobUrl = useMedia(photoHash, false, ApiMediaFormat.BlobUrl, lastSyncTime);\n const videoHash = getMediaHash('normal', 'video');\n const videoBlobUrl = useMedia(videoHash, false, ApiMediaFormat.BlobUrl, lastSyncTime);\n const imageSrc = videoBlobUrl || photoBlobUrl || photo?.thumbnail?.dataUri;\n\n let content: TeactNode | undefined;\n\n if (isSavedMessages) {\n content = <i className=\"icon-avatar-saved-messages\" />;\n } else if (isDeleted) {\n content = <i className=\"icon-avatar-deleted-account\" />;\n } else if (isRepliesChat) {\n content = <i className=\"icon-reply-filled\" />;\n } else if (imageSrc) {\n if (videoBlobUrl) {\n content = (\n <video\n ref={videoRef}\n src={imageSrc}\n className=\"avatar-media\"\n muted\n disablePictureInPicture\n autoPlay={!notActive}\n loop\n playsInline\n />\n );\n } else {\n content = <img src={imageSrc} className=\"avatar-media\" alt=\"\" />;\n }\n } else if (user) {\n const userFullName = getUserFullName(user);\n content = userFullName ? getFirstLetters(userFullName, 2) : undefined;\n } else if (chat) {\n const title = getChatTitle(lang, chat);\n content = title && getFirstLetters(title, isUserId(chat.id) ? 2 : 1);\n } else {\n content = (\n <div className=\"spinner-wrapper\">\n <Spinner color=\"white\" />\n </div>\n );\n }\n\n const fullClassName = buildClassName(\n 'ProfilePhoto',\n `color-bg-${getUserColorKey(user || chat)}`,\n isSavedMessages && 'saved-messages',\n isDeleted && 'deleted-account',\n isRepliesChat && 'replies-bot-account',\n (!isSavedMessages && !imageSrc) && 'no-photo',\n );\n\n return (\n <div className={fullClassName} onClick={imageSrc ? onClick : undefined}>\n {typeof content === 'string' ? renderText(content, ['hq_emoji']) : content}\n </div>\n );\n};\n\nexport default memo(ProfilePhoto);\n","import type { FC } from '../../lib/teact/teact';\nimport React, {\n useEffect, useCallback, memo, useState,\n} from '../../lib/teact/teact';\nimport { getActions, withGlobal } from '../../global';\n\nimport type { ApiUser, ApiChat, ApiUserStatus } from '../../api/types';\nimport type { GlobalState } from '../../global/types';\nimport type { AnimationLevel } from '../../types';\nimport { MediaViewerOrigin } from '../../types';\n\nimport { IS_TOUCH_ENV } from '../../util/environment';\nimport { MEMO_EMPTY_ARRAY } from '../../util/memo';\nimport { selectChat, selectUser, selectUserStatus } from '../../global/selectors';\nimport {\n getUserFullName, getUserStatus, isChatChannel, isUserOnline,\n} from '../../global/helpers';\nimport renderText from './helpers/renderText';\nimport { captureEvents, SwipeDirection } from '../../util/captureEvents';\nimport buildClassName from '../../util/buildClassName';\nimport usePhotosPreload from './hooks/usePhotosPreload';\nimport useLang from '../../hooks/useLang';\nimport usePrevious from '../../hooks/usePrevious';\n\nimport VerifiedIcon from './VerifiedIcon';\nimport ProfilePhoto from './ProfilePhoto';\nimport Transition from '../ui/Transition';\nimport FakeIcon from './FakeIcon';\nimport PremiumIcon from './PremiumIcon';\n\nimport './ProfileInfo.scss';\n\ntype OwnProps = {\n userId: string;\n forceShowSelf?: boolean;\n};\n\ntype StateProps =\n {\n user?: ApiUser;\n userStatus?: ApiUserStatus;\n chat?: ApiChat;\n isSavedMessages?: boolean;\n animationLevel: AnimationLevel;\n serverTimeOffset: number;\n mediaId?: number;\n avatarOwnerId?: string;\n }\n & Pick<GlobalState, 'connectionState'>;\n\nconst ProfileInfo: FC<OwnProps & StateProps> = ({\n forceShowSelf,\n user,\n userStatus,\n chat,\n isSavedMessages,\n connectionState,\n animationLevel,\n serverTimeOffset,\n mediaId,\n avatarOwnerId,\n}) => {\n const {\n loadFullUser,\n openMediaViewer,\n openPremiumModal,\n } = getActions();\n\n const lang = useLang();\n\n const { id: userId } = user || {};\n const { id: chatId } = chat || {};\n const fullName = user ? getUserFullName(user) : (chat ? chat.title : '');\n const photos = user?.photos || chat?.photos || MEMO_EMPTY_ARRAY;\n const prevMediaId = usePrevious(mediaId);\n const prevAvatarOwnerId = usePrevious(avatarOwnerId);\n const [hasSlideAnimation, setHasSlideAnimation] = useState(true);\n const slideAnimation = hasSlideAnimation\n ? animationLevel >= 1 ? (lang.isRtl ? 'slide-optimized-rtl' : 'slide-optimized') : 'none'\n : 'none';\n\n const [currentPhotoIndex, setCurrentPhotoIndex] = useState(0);\n const isFirst = isSavedMessages || photos.length <= 1 || currentPhotoIndex === 0;\n const isLast = isSavedMessages || photos.length <= 1 || currentPhotoIndex === photos.length - 1;\n\n // Set the current avatar photo to the last selected photo in Media Viewer after it is closed\n useEffect(() => {\n if (prevAvatarOwnerId && prevMediaId !== undefined && mediaId === undefined) {\n setHasSlideAnimation(false);\n setCurrentPhotoIndex(prevMediaId);\n }\n }, [mediaId, prevMediaId, prevAvatarOwnerId]);\n\n // Deleting the last profile photo may result in an error\n useEffect(() => {\n if (currentPhotoIndex > photos.length) {\n setCurrentPhotoIndex(Math.max(0, photos.length - 1));\n }\n }, [currentPhotoIndex, photos.length]);\n\n useEffect(() => {\n if (connectionState === 'connectionStateReady' && userId && !forceShowSelf) {\n loadFullUser({ userId });\n }\n }, [userId, loadFullUser, connectionState, forceShowSelf]);\n\n usePhotosPreload(user || chat, photos, currentPhotoIndex);\n\n const handleProfilePhotoClick = useCallback(() => {\n openMediaViewer({\n avatarOwnerId: userId || chatId,\n mediaId: currentPhotoIndex,\n origin: forceShowSelf ? MediaViewerOrigin.SettingsAvatar : MediaViewerOrigin.ProfileAvatar,\n });\n }, [openMediaViewer, userId, chatId, currentPhotoIndex, forceShowSelf]);\n\n const handleClickPremium = useCallback(() => {\n if (!user) return;\n\n openPremiumModal({ fromUserId: user.id });\n }, [openPremiumModal, user]);\n\n const selectPreviousMedia = useCallback(() => {\n if (isFirst) {\n return;\n }\n setHasSlideAnimation(true);\n setCurrentPhotoIndex(currentPhotoIndex - 1);\n }, [currentPhotoIndex, isFirst]);\n\n const selectNextMedia = useCallback(() => {\n if (isLast) {\n return;\n }\n setHasSlideAnimation(true);\n setCurrentPhotoIndex(currentPhotoIndex + 1);\n }, [currentPhotoIndex, isLast]);\n\n // Swipe gestures\n useEffect(() => {\n const element = document.querySelector<HTMLDivElement>('.photo-wrapper');\n if (!element) {\n return undefined;\n }\n\n return captureEvents(element, {\n selectorToPreventScroll: '.Profile, .settings-content',\n onSwipe: IS_TOUCH_ENV ? (e, direction) => {\n if (direction === SwipeDirection.Right) {\n selectPreviousMedia();\n return true;\n } else if (direction === SwipeDirection.Left) {\n selectNextMedia();\n return true;\n }\n\n return false;\n } : undefined,\n });\n }, [selectNextMedia, selectPreviousMedia]);\n\n if (!user && !chat) {\n return undefined;\n }\n\n function renderPhotoTabs() {\n if (isSavedMessages || !photos || photos.length <= 1) {\n return undefined;\n }\n\n return (\n <div className=\"photo-dashes\">\n {photos.map((_, i) => (\n <span className={`photo-dash ${i === currentPhotoIndex ? 'current' : ''}`} />\n ))}\n </div>\n );\n }\n\n function renderPhoto(isActive?: boolean) {\n const photo = !isSavedMessages && photos.length > 0 ? photos[currentPhotoIndex] : undefined;\n return (\n <ProfilePhoto\n key={currentPhotoIndex}\n user={user}\n chat={chat}\n photo={photo}\n isSavedMessages={isSavedMessages}\n isFirstPhoto={isFirst}\n notActive={!isActive}\n onClick={handleProfilePhotoClick}\n />\n );\n }\n\n function renderStatus() {\n if (user) {\n return (\n <div className={`status ${isUserOnline(user, userStatus) ? 'online' : ''}`}>\n <span className=\"user-status\" dir=\"auto\">{getUserStatus(lang, user, userStatus, serverTimeOffset)}</span>\n </div>\n );\n }\n\n return (\n <span className=\"status\" dir=\"auto\">{\n isChatChannel(chat!)\n ? lang('Subscribers', chat!.membersCount ?? 0, 'i')\n : lang('Members', chat!.membersCount ?? 0, 'i')\n }\n </span>\n );\n }\n\n const isVerifiedIconShown = (user || chat)?.isVerified;\n const isPremiumIconShown = user?.isPremium;\n const fakeType = (user || chat)?.fakeType;\n\n return (\n <div className={buildClassName('ProfileInfo', forceShowSelf && 'self')} dir={lang.isRtl ? 'rtl' : undefined}>\n <div className=\"photo-wrapper\">\n {renderPhotoTabs()}\n <Transition activeKey={currentPhotoIndex} name={slideAnimation} className=\"profile-slide-container\">\n {renderPhoto}\n </Transition>\n\n {!isFirst && (\n <button\n type=\"button\"\n className=\"navigation prev\"\n aria-label={lang('AccDescrPrevious')}\n onClick={selectPreviousMedia}\n />\n )}\n {!isLast && (\n <button\n type=\"button\"\n className=\"navigation next\"\n aria-label={lang('Next')}\n onClick={selectNextMedia}\n />\n )}\n </div>\n\n <div className=\"info\" dir={lang.isRtl ? 'rtl' : 'auto'}>\n {isSavedMessages ? (\n <div className=\"title\">\n <div className=\"fullName\" dir=\"auto\">{lang('SavedMessages')}</div>\n </div>\n ) : (\n <div className=\"title\">\n <div className=\"fullName\" dir=\"auto\">{fullName && renderText(fullName)}</div>\n {isVerifiedIconShown && <VerifiedIcon />}\n {isPremiumIconShown && <PremiumIcon onClick={handleClickPremium} />}\n {fakeType && <FakeIcon fakeType={fakeType} />}\n </div>\n )}\n {!isSavedMessages && renderStatus()}\n </div>\n </div>\n );\n};\n\nexport default memo(withGlobal<OwnProps>(\n (global, { userId, forceShowSelf }): StateProps => {\n const { connectionState, serverTimeOffset } = global;\n const user = selectUser(global, userId);\n const userStatus = selectUserStatus(global, userId);\n const chat = selectChat(global, userId);\n const isSavedMessages = !forceShowSelf && user && user.isSelf;\n const { animationLevel } = global.settings.byKey;\n const { mediaId, avatarOwnerId } = global.mediaViewer;\n\n return {\n connectionState,\n user,\n userStatus,\n chat,\n isSavedMessages,\n animationLevel,\n serverTimeOffset,\n mediaId,\n avatarOwnerId,\n };\n },\n)(ProfileInfo));\n","import type { ApiChat, ApiPhoto, ApiUser } from '../../../api/types';\nimport { ApiMediaFormat } from '../../../api/types';\nimport { useEffect } from '../../../lib/teact/teact';\nimport * as mediaLoader from '../../../util/mediaLoader';\n\nconst PHOTOS_TO_PRELOAD = 4;\n\nexport default function usePhotosPreload(\n profile: ApiUser | ApiChat | undefined,\n photos: ApiPhoto[],\n currentIndex: number,\n) {\n useEffect(() => {\n photos.slice(currentIndex, currentIndex + PHOTOS_TO_PRELOAD).forEach((photo) => {\n const mediaData = mediaLoader.getFromMemory(`photo${photo.id}?size=c`);\n if (!mediaData) {\n mediaLoader.fetch(`photo${photo.id}?size=c`, ApiMediaFormat.BlobUrl);\n }\n });\n }, [currentIndex, photos]);\n}\n","import type { RefObject } from 'react';\nimport type { FC } from '../../lib/teact/teact';\nimport React, { memo } from '../../lib/teact/teact';\nimport { getGlobal } from '../../global';\n\nimport { ApiMediaFormat } from '../../api/types';\n\nimport useMedia from '../../hooks/useMedia';\nimport buildClassName from '../../util/buildClassName';\n\nimport './ReactionStaticEmoji.scss';\n\ntype OwnProps = {\n reaction: string;\n ref?: RefObject<HTMLImageElement>;\n className?: string;\n};\n\nconst ReactionStaticEmoji: FC<OwnProps> = ({\n reaction,\n ref,\n className,\n}) => {\n const staticIconId = getGlobal().availableReactions?.find((l) => l.reaction === reaction)?.staticIcon?.id;\n const mediaData = useMedia(`document${staticIconId}`, !staticIconId, ApiMediaFormat.BlobUrl);\n\n return (\n <img\n className={buildClassName('ReactionStaticEmoji', className)}\n ref={ref}\n src={mediaData}\n alt=\"\"\n />\n );\n};\n\nexport default memo(ReactionStaticEmoji);\n","import type { ChangeEvent } from 'react';\n\nimport type { FC } from '../../lib/teact/teact';\nimport React, {\n memo, useCallback, useMemo, useState,\n} from '../../lib/teact/teact';\nimport { getActions } from '../../global';\n\nimport type { ApiPhoto, ApiReportReason } from '../../api/types';\n\nimport useLang from '../../hooks/useLang';\n\nimport Modal from '../ui/Modal';\nimport Button from '../ui/Button';\nimport RadioGroup from '../ui/RadioGroup';\nimport InputText from '../ui/InputText';\n\nexport type OwnProps = {\n isOpen: boolean;\n subject?: 'peer' | 'messages' | 'media';\n chatId?: string;\n photo?: ApiPhoto;\n messageIds?: number[];\n onClose: () => void;\n onCloseAnimationEnd?: () => void;\n};\n\nconst ReportModal: FC<OwnProps> = ({\n isOpen,\n subject = 'messages',\n chatId,\n photo,\n messageIds,\n onClose,\n onCloseAnimationEnd,\n}) => {\n const {\n reportMessages,\n reportPeer,\n reportProfilePhoto,\n exitMessageSelectMode,\n } = getActions();\n\n const [selectedReason, setSelectedReason] = useState<ApiReportReason>('spam');\n const [description, setDescription] = useState('');\n\n const handleReport = useCallback(() => {\n switch (subject) {\n case 'messages':\n reportMessages({ messageIds, reason: selectedReason, description });\n exitMessageSelectMode();\n break;\n case 'peer':\n reportPeer({ chatId, reason: selectedReason, description });\n break;\n case 'media':\n reportProfilePhoto({\n chatId, photo, reason: selectedReason, description,\n });\n break;\n }\n onClose();\n }, [\n description,\n exitMessageSelectMode,\n messageIds,\n photo,\n onClose,\n reportMessages,\n selectedReason,\n chatId,\n reportProfilePhoto,\n reportPeer,\n subject,\n ]);\n\n const handleSelectReason = useCallback((value: string) => {\n setSelectedReason(value as ApiReportReason);\n }, []);\n\n const handleDescriptionChange = useCallback((e: ChangeEvent<HTMLInputElement>) => {\n setDescription(e.target.value);\n }, []);\n\n const lang = useLang();\n\n const REPORT_OPTIONS: { value: ApiReportReason; label: string }[] = useMemo(() => [\n { value: 'spam', label: lang('lng_report_reason_spam') },\n { value: 'violence', label: lang('lng_report_reason_violence') },\n { value: 'pornography', label: lang('lng_report_reason_pornography') },\n { value: 'childAbuse', label: lang('lng_report_reason_child_abuse') },\n { value: 'copyright', label: lang('ReportPeer.ReasonCopyright') },\n { value: 'illegalDrugs', label: 'Illegal Drugs' },\n { value: 'personalDetails', label: 'Personal Details' },\n { value: 'other', label: lang('lng_report_reason_other') },\n ], [lang]);\n\n if (\n (subject === 'messages' && !messageIds)\n || (subject === 'peer' && !chatId)\n || (subject === 'media' && (!chatId || !photo))\n ) {\n return undefined;\n }\n\n const title = subject === 'messages'\n ? lang('lng_report_message_title')\n : lang('ReportPeer.Report');\n\n return (\n <Modal\n isOpen={isOpen}\n onClose={onClose}\n onEnter={isOpen ? handleReport : undefined}\n onCloseAnimationEnd={onCloseAnimationEnd}\n className=\"report\"\n title={title}\n >\n <RadioGroup\n name=\"report-message\"\n options={REPORT_OPTIONS}\n onChange={handleSelectReason}\n selected={selectedReason}\n />\n <InputText\n label={lang('lng_report_reason_description')}\n value={description}\n onChange={handleDescriptionChange}\n />\n <Button color=\"danger\" className=\"confirm-dialog-button\" isText onClick={handleReport}>\n {lang('lng_report_button')}\n </Button>\n <Button className=\"confirm-dialog-button\" isText onClick={onClose}>{lang('Cancel')}</Button>\n </Modal>\n );\n};\n\nexport default memo(ReportModal);\n","import type { MouseEvent as ReactMouseEvent, ReactNode } from 'react';\nimport React, {\n memo, useCallback, useEffect, useMemo, useRef,\n} from '../../lib/teact/teact';\nimport { getActions } from '../../global';\n\nimport type { ApiBotInlineMediaResult, ApiSticker } from '../../api/types';\nimport { ApiMediaFormat } from '../../api/types';\n\nimport buildClassName from '../../util/buildClassName';\nimport { preventMessageInputBlurWithBubbling } from '../middle/helpers/preventMessageInputBlur';\nimport safePlay from '../../util/safePlay';\nimport { IS_TOUCH_ENV, IS_WEBM_SUPPORTED } from '../../util/environment';\n\nimport type { ObserveFn } from '../../hooks/useIntersectionObserver';\nimport { useIsIntersecting } from '../../hooks/useIntersectionObserver';\nimport useMedia from '../../hooks/useMedia';\nimport useShowTransition from '../../hooks/useShowTransition';\nimport useFlag from '../../hooks/useFlag';\nimport useLang from '../../hooks/useLang';\nimport useContextMenuHandlers from '../../hooks/useContextMenuHandlers';\nimport useContextMenuPosition from '../../hooks/useContextMenuPosition';\nimport useThumbnail from '../../hooks/useThumbnail';\n\nimport AnimatedSticker from './AnimatedSticker';\nimport Button from '../ui/Button';\nimport Menu from '../ui/Menu';\nimport MenuItem from '../ui/MenuItem';\n\nimport './StickerButton.scss';\n\ntype OwnProps<T> = {\n sticker: ApiSticker;\n size: number;\n noAnimate?: boolean;\n title?: string;\n className?: string;\n clickArg: T;\n noContextMenu?: boolean;\n isSavedMessages?: boolean;\n canViewSet?: boolean;\n isCurrentUserPremium?: boolean;\n observeIntersection: ObserveFn;\n onClick?: (arg: OwnProps<T>['clickArg'], isSilent?: boolean, shouldSchedule?: boolean) => void;\n onFaveClick?: (sticker: ApiSticker) => void;\n onUnfaveClick?: (sticker: ApiSticker) => void;\n onRemoveRecentClick?: (sticker: ApiSticker) => void;\n};\n\nconst StickerButton = <T extends number | ApiSticker | ApiBotInlineMediaResult | undefined = undefined>({\n sticker,\n size,\n noAnimate,\n title,\n className,\n clickArg,\n noContextMenu,\n isSavedMessages,\n canViewSet,\n observeIntersection,\n onClick,\n onFaveClick,\n onUnfaveClick,\n onRemoveRecentClick,\n isCurrentUserPremium,\n}: OwnProps<T>) => {\n const { openStickerSet, openPremiumModal } = getActions();\n // eslint-disable-next-line no-null/no-null\n const ref = useRef<HTMLDivElement>(null);\n const lang = useLang();\n\n const localMediaHash = `sticker${sticker.id}`;\n const stickerSelector = `sticker-button-${sticker.id}`;\n\n const isIntersecting = useIsIntersecting(ref, observeIntersection);\n\n const thumbDataUri = useThumbnail(sticker);\n const previewBlobUrl = useMedia(`${localMediaHash}?size=m`, !isIntersecting, ApiMediaFormat.BlobUrl);\n\n const shouldPlay = isIntersecting && !noAnimate;\n const lottieData = useMedia(sticker.isLottie && localMediaHash, !shouldPlay);\n const [isLottieLoaded, markLoaded, unmarkLoaded] = useFlag(Boolean(lottieData));\n const canLottiePlay = isLottieLoaded && shouldPlay;\n const isVideo = sticker.isVideo && IS_WEBM_SUPPORTED;\n const isCustomEmoji = sticker.isCustomEmoji;\n const videoBlobUrl = useMedia(isVideo && localMediaHash, !shouldPlay, ApiMediaFormat.BlobUrl);\n const canVideoPlay = Boolean(isVideo && videoBlobUrl && shouldPlay);\n const isPremiumSticker = sticker.hasEffect;\n const isLocked = !isCurrentUserPremium && isPremiumSticker;\n\n const { transitionClassNames: previewTransitionClassNames } = useShowTransition(\n Boolean(previewBlobUrl || canLottiePlay),\n undefined,\n undefined,\n 'slow',\n );\n\n const {\n isContextMenuOpen, contextMenuPosition,\n handleBeforeContextMenu, handleContextMenu,\n handleContextMenuClose, handleContextMenuHide,\n } = useContextMenuHandlers(ref);\n\n const getTriggerElement = useCallback(() => ref.current, []);\n\n const getRootElement = useCallback(\n () => ref.current!.closest('.custom-scroll, .no-scrollbar'),\n [],\n );\n\n const getMenuElement = useCallback(\n () => ref.current!.querySelector('.sticker-context-menu .bubble'),\n [],\n );\n\n const {\n positionX, positionY, transformOriginX, transformOriginY, style: menuStyle,\n } = useContextMenuPosition(\n contextMenuPosition,\n getTriggerElement,\n getRootElement,\n getMenuElement,\n );\n\n // To avoid flickering\n useEffect(() => {\n if (!shouldPlay) {\n unmarkLoaded();\n }\n }, [unmarkLoaded, shouldPlay]);\n\n useEffect(() => {\n if (!isVideo || !ref.current) return;\n const video = ref.current.querySelector('video');\n if (!video) return;\n if (canVideoPlay) {\n safePlay(video);\n } else {\n video.pause();\n }\n }, [isVideo, canVideoPlay]);\n\n useEffect(() => {\n if (!isIntersecting) handleContextMenuClose();\n }, [handleContextMenuClose, isIntersecting]);\n\n const handleClick = () => {\n if (isContextMenuOpen) return;\n if (isLocked) {\n openPremiumModal({ initialSection: 'premium_stickers' });\n return;\n }\n onClick?.(clickArg);\n };\n\n const handleMouseDown = (e: React.MouseEvent<HTMLElement>) => {\n preventMessageInputBlurWithBubbling(e);\n handleBeforeContextMenu(e);\n };\n\n const handleRemoveClick = useCallback((e: ReactMouseEvent<HTMLButtonElement, MouseEvent>) => {\n e.stopPropagation();\n e.preventDefault();\n\n onRemoveRecentClick!(sticker);\n }, [onRemoveRecentClick, sticker]);\n\n const handleContextRemoveRecent = useCallback(() => {\n onRemoveRecentClick!(sticker);\n }, [onRemoveRecentClick, sticker]);\n\n const handleContextUnfave = useCallback(() => {\n onUnfaveClick!(sticker);\n }, [onUnfaveClick, sticker]);\n\n const handleContextFave = useCallback(() => {\n onFaveClick!(sticker);\n }, [onFaveClick, sticker]);\n\n const handleSendQuiet = useCallback(() => {\n onClick?.(clickArg, true);\n }, [clickArg, onClick]);\n\n const handleSendScheduled = useCallback(() => {\n onClick?.(clickArg, undefined, true);\n }, [clickArg, onClick]);\n\n const handleOpenSet = useCallback(() => {\n openStickerSet({ stickerSetInfo: sticker.stickerSetInfo });\n }, [openStickerSet, sticker]);\n\n const shouldShowCloseButton = !IS_TOUCH_ENV && onRemoveRecentClick;\n\n const fullClassName = buildClassName(\n 'StickerButton',\n onClick && 'interactive',\n isCustomEmoji && 'custom-emoji',\n stickerSelector,\n className,\n );\n\n const style = (thumbDataUri && !canLottiePlay && !canVideoPlay) ? `background-image: url('${thumbDataUri}');` : '';\n\n const contextMenuItems = useMemo(() => {\n const items: ReactNode[] = [];\n if (noContextMenu || isCustomEmoji) return items;\n\n if (onUnfaveClick) {\n items.push(\n <MenuItem icon=\"favorite\" onClick={handleContextUnfave}>\n {lang('Stickers.RemoveFromFavorites')}\n </MenuItem>,\n );\n }\n\n if (onFaveClick) {\n items.push(\n <MenuItem icon=\"favorite\" onClick={handleContextFave}>\n {lang('Stickers.AddToFavorites')}\n </MenuItem>,\n );\n }\n\n if (!isLocked && onClick) {\n if (!isSavedMessages) {\n items.push(<MenuItem onClick={handleSendQuiet} icon=\"muted\">{lang('SendWithoutSound')}</MenuItem>);\n }\n items.push(\n <MenuItem onClick={handleSendScheduled} icon=\"calendar\">\n {lang(isSavedMessages ? 'SetReminder' : 'ScheduleMessage')}\n </MenuItem>,\n );\n }\n\n if (canViewSet) {\n items.push(\n <MenuItem onClick={handleOpenSet} icon=\"stickers\">\n {lang('ViewPackPreview')}\n </MenuItem>,\n );\n }\n if (onRemoveRecentClick) {\n items.push(\n <MenuItem icon=\"delete\" onClick={handleContextRemoveRecent}>\n {lang('DeleteFromRecent')}\n </MenuItem>,\n );\n }\n return items;\n }, [\n canViewSet, handleContextFave, handleContextRemoveRecent, handleContextUnfave, handleOpenSet, handleSendQuiet,\n handleSendScheduled, isLocked, isSavedMessages, lang, onFaveClick, onRemoveRecentClick, onUnfaveClick, onClick,\n noContextMenu, isCustomEmoji,\n ]);\n\n return (\n <div\n ref={ref}\n className={fullClassName}\n title={title || (sticker?.emoji)}\n style={style}\n data-sticker-id={sticker.id}\n onMouseDown={handleMouseDown}\n onClick={handleClick}\n onContextMenu={handleContextMenu}\n >\n {!canLottiePlay && !canVideoPlay && (\n // eslint-disable-next-line jsx-a11y/alt-text\n <img src={previewBlobUrl} className={previewTransitionClassNames} />\n )}\n {isVideo && (\n <video\n className={previewTransitionClassNames}\n src={videoBlobUrl}\n autoPlay={canVideoPlay}\n loop\n playsInline\n disablePictureInPicture\n muted\n />\n )}\n {shouldPlay && lottieData && (\n <AnimatedSticker\n tgsUrl={lottieData}\n play\n size={size}\n isLowPriority\n onLoad={markLoaded}\n />\n )}\n {isLocked && (\n <div\n className=\"sticker-locked\"\n >\n <i className=\"icon-lock-badge\" />\n </div>\n )}\n {isPremiumSticker && !isLocked && (\n <div className=\"sticker-premium\">\n <i className=\"icon-premium\" />\n </div>\n )}\n {shouldShowCloseButton && (\n <Button\n className=\"sticker-remove-button\"\n color=\"dark\"\n round\n onClick={handleRemoveClick}\n >\n <i className=\"icon-close\" />\n </Button>\n )}\n {Boolean(contextMenuItems.length) && contextMenuPosition !== undefined && (\n <Menu\n isOpen={isContextMenuOpen}\n transformOriginX={transformOriginX}\n transformOriginY={transformOriginY}\n positionX={positionX}\n positionY={positionY}\n style={menuStyle}\n className=\"sticker-context-menu\"\n autoClose\n onClose={handleContextMenuClose}\n onCloseAnimationEnd={handleContextMenuHide}\n >\n {contextMenuItems}\n </Menu>\n )}\n </div>\n );\n};\n\nexport default memo(StickerButton);\n","import type { FC } from '../../lib/teact/teact';\nimport React, { memo } from '../../lib/teact/teact';\nimport { withGlobal } from '../../global';\n\nimport type { ApiUser, ApiTypingStatus } from '../../api/types';\n\nimport { selectUser } from '../../global/selectors';\nimport { getUserFirstOrLastName } from '../../global/helpers';\nimport renderText from './helpers/renderText';\nimport useLang from '../../hooks/useLang';\n\nimport DotAnimation from './DotAnimation';\n\nimport './TypingStatus.scss';\n\ntype OwnProps = {\n typingStatus: ApiTypingStatus;\n};\n\ntype StateProps = {\n typingUser?: ApiUser;\n};\n\nconst TypingStatus: FC<OwnProps & StateProps> = ({ typingStatus, typingUser }) => {\n const lang = useLang();\n const typingUserName = typingUser && !typingUser.isSelf && getUserFirstOrLastName(typingUser);\n const content = lang(typingStatus.action)\n // Fix for translation \"{user} is typing\"\n .replace('{user}', '')\n .replace('{emoji}', typingStatus.emoji).trim();\n\n return (\n <p className=\"typing-status\" dir={lang.isRtl ? 'rtl' : 'auto'}>\n {typingUserName && (\n <span className=\"sender-name\" dir=\"auto\">{renderText(typingUserName)}</span>\n )}\n <DotAnimation content={content} />\n </p>\n );\n};\n\nexport default memo(withGlobal<OwnProps>(\n (global, { typingStatus }): StateProps => {\n if (!typingStatus.userId) {\n return {};\n }\n\n const typingUser = selectUser(global, typingStatus.userId);\n\n return { typingUser };\n },\n)(TypingStatus));\n","import type { FC } from '../../lib/teact/teact';\nimport React from '../../lib/teact/teact';\n\nimport './VerifiedIcon.scss';\n\n// eslint-disable-next-line max-len\nconst VERIFIED_ICON = { __html: '<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M12.3 2.9c.1.1.2.1.3.2.7.6 1.3 1.1 2 1.7.3.2.6.4.9.4.9.1 1.7.2 2.6.2.5 0 .6.1.7.7.1.9.1 1.8.2 2.6 0 .4.2.7.4 1 .6.7 1.1 1.3 1.7 2 .3.4.3.5 0 .8-.5.6-1.1 1.3-1.6 1.9-.3.3-.5.7-.5 1.2-.1.8-.2 1.7-.2 2.5 0 .4-.2.5-.6.6-.8 0-1.6.1-2.5.2-.5 0-1 .2-1.4.5-.6.5-1.3 1.1-1.9 1.6-.3.3-.5.3-.8 0-.7-.6-1.4-1.2-2-1.8-.3-.2-.6-.4-.9-.4-.9-.1-1.8-.2-2.7-.2-.4 0-.5-.2-.6-.5 0-.9-.1-1.7-.2-2.6 0-.4-.2-.8-.4-1.1-.6-.6-1.1-1.3-1.6-2-.4-.4-.3-.5 0-1 .6-.6 1.1-1.3 1.7-1.9.3-.3.4-.6.4-1 0-.8.1-1.6.2-2.5 0-.5.1-.6.6-.6.9-.1 1.7-.1 2.6-.2.4 0 .7-.2 1-.4.7-.6 1.4-1.2 2.1-1.7.1-.2.3-.3.5-.2z\" style=\"fill: var(--color-fill)\"/><path class=\"lol\" d=\"M16.4 10.1l-.2.2-5.4 5.4c-.1.1-.2.2-.4 0l-2.6-2.6c-.2-.2-.1-.3 0-.4.2-.2.5-.6.7-.6.3 0 .5.4.7.6l1.1 1.1c.2.2.3.2.5 0l4.3-4.3c.2-.2.4-.3.6 0 .1.2.3.3.4.5.2 0 .3.1.3.1z\" style=\"fill: var(--color-checkmark)\"/></svg>' };\n\nconst VerifiedIcon: FC = () => {\n return (\n // eslint-disable-next-line react/no-danger\n <span className=\"VerifiedIcon\" dangerouslySetInnerHTML={VERIFIED_ICON} />\n );\n};\n\nexport default VerifiedIcon;\n","import type { FC } from '../../lib/teact/teact';\nimport React, { memo, useCallback } from '../../lib/teact/teact';\n\nimport type { ApiMessage, ApiWebPage } from '../../api/types';\nimport type { TextPart } from '../../types';\nimport type { ObserveFn } from '../../hooks/useIntersectionObserver';\n\nimport {\n getFirstLinkInMessage, getMessageText,\n getMessageWebPage,\n} from '../../global/helpers';\nimport buildClassName from '../../util/buildClassName';\nimport trimText from '../../util/trimText';\nimport renderText from './helpers/renderText';\nimport { formatPastTimeShort } from '../../util/dateFormat';\nimport useLang from '../../hooks/useLang';\nimport { renderMessageSummary } from './helpers/renderMessageText';\n\nimport Media from './Media';\nimport Link from '../ui/Link';\nimport SafeLink from './SafeLink';\n\nimport './WebLink.scss';\n\nconst MAX_TEXT_LENGTH = 170; // symbols\n\ntype OwnProps = {\n message: ApiMessage;\n senderTitle?: string;\n isProtected?: boolean;\n observeIntersection?: ObserveFn;\n onMessageClick: (messageId: number, chatId: string) => void;\n};\n\ntype ApiWebPageWithFormatted =\n ApiWebPage\n & { formattedDescription?: TextPart[] };\n\nconst WebLink: FC<OwnProps> = ({\n message, senderTitle, isProtected, observeIntersection, onMessageClick,\n}) => {\n const lang = useLang();\n\n let linkData: ApiWebPageWithFormatted | undefined = getMessageWebPage(message);\n\n if (!linkData) {\n const link = getFirstLinkInMessage(message);\n if (link) {\n const { url, domain } = link;\n\n linkData = {\n siteName: domain.replace(/^www./, ''),\n url: url.includes('://') ? url : url.includes('@') ? `mailto:${url}` : `http://${url}`,\n formattedDescription: getMessageText(message) !== url\n ? renderMessageSummary(lang, message, undefined, undefined, MAX_TEXT_LENGTH)\n : undefined,\n } as ApiWebPageWithFormatted;\n }\n }\n\n const handleMessageClick = useCallback(() => {\n onMessageClick(message.id, message.chatId);\n }, [onMessageClick, message.id, message.chatId]);\n\n if (!linkData) {\n return undefined;\n }\n\n const {\n siteName,\n url,\n displayUrl,\n title,\n description,\n formattedDescription,\n photo,\n video,\n } = linkData;\n\n const truncatedDescription = !senderTitle && description && trimText(description, MAX_TEXT_LENGTH);\n\n const className = buildClassName(\n 'WebLink scroll-item',\n (!photo && !video) && 'without-media',\n );\n\n return (\n <div\n className={className}\n data-initial={(siteName || displayUrl)[0]}\n dir={lang.isRtl ? 'rtl' : undefined}\n >\n {photo && (\n <Media message={message} isProtected={isProtected} observeIntersection={observeIntersection} />\n )}\n <div className=\"content\">\n <Link isRtl={lang.isRtl} className=\"site-title\" onClick={handleMessageClick}>\n {renderText(title || siteName || displayUrl)}\n </Link>\n {(truncatedDescription || formattedDescription) && (\n <Link isRtl={lang.isRtl} className=\"site-description\" onClick={handleMessageClick}>\n {formattedDescription || (truncatedDescription && renderText(truncatedDescription))}\n </Link>\n )}\n <SafeLink\n url={url}\n className=\"site-name\"\n text=\"\"\n isRtl={lang.isRtl}\n >\n {url.replace('mailto:', '') || displayUrl}\n </SafeLink>\n {senderTitle && <div className=\"sender-name\">{renderText(senderTitle)}</div>}\n </div>\n {senderTitle && (\n <div className=\"message-date\">\n <Link\n className=\"date\"\n onClick={handleMessageClick}\n isRtl={lang.isRtl}\n >\n {formatPastTimeShort(lang, message.date * 1000)}\n </Link>\n </div>\n )}\n </div>\n );\n};\n\nexport default memo(WebLink);\n","import type {\n ApiPhoto, ApiVideo, ApiSticker, ApiDimensions,\n} from '../../../api/types';\n\nimport { STICKER_SIZE_INLINE_DESKTOP_FACTOR, STICKER_SIZE_INLINE_MOBILE_FACTOR } from '../../../config';\nimport { IS_SINGLE_COLUMN_LAYOUT, IS_TOUCH_ENV } from '../../../util/environment';\nimport windowSize from '../../../util/windowSize';\nimport { getPhotoInlineDimensions, getVideoDimensions } from '../../../global/helpers';\n\nexport const MEDIA_VIEWER_MEDIA_QUERY = '(max-height: 640px)';\nexport const REM = parseInt(getComputedStyle(document.documentElement).fontSize, 10);\nexport const ROUND_VIDEO_DIMENSIONS_PX = 240;\nexport const GIF_MIN_WIDTH = 300;\nexport const AVATAR_FULL_DIMENSIONS = { width: 640, height: 640 };\nexport const VIDEO_AVATAR_FULL_DIMENSIONS = { width: 800, height: 800 };\nexport const LIKE_STICKER_ID = '4986041492570112461';\n\nconst DEFAULT_MEDIA_DIMENSIONS: ApiDimensions = { width: 100, height: 100 };\nconst MOBILE_SCREEN_NO_AVATARS_MESSAGE_EXTRA_WIDTH_REM = 4.5;\nconst MOBILE_SCREEN_MESSAGE_EXTRA_WIDTH_REM = 7;\nconst MESSAGE_MAX_WIDTH_REM = 29;\nconst MESSAGE_OWN_MAX_WIDTH_REM = 30;\n\nlet cachedMaxWidthOwn: number | undefined;\nlet cachedMaxWidth: number | undefined;\nlet cachedMaxWidthNoAvatar: number | undefined;\n\nfunction getMaxMessageWidthRem(fromOwnMessage: boolean, noAvatars?: boolean) {\n const regularMaxWidth = fromOwnMessage ? MESSAGE_OWN_MAX_WIDTH_REM : MESSAGE_MAX_WIDTH_REM;\n if (!IS_SINGLE_COLUMN_LAYOUT) {\n return regularMaxWidth;\n }\n\n const { width: windowWidth } = windowSize.get();\n\n // @optimization Limitation: changing device screen width not supported\n if (!cachedMaxWidthOwn) {\n cachedMaxWidthOwn = Math.min(\n MESSAGE_OWN_MAX_WIDTH_REM,\n windowWidth / REM - MOBILE_SCREEN_NO_AVATARS_MESSAGE_EXTRA_WIDTH_REM,\n );\n }\n if (!cachedMaxWidth) {\n cachedMaxWidth = Math.min(\n MESSAGE_MAX_WIDTH_REM,\n windowWidth / REM - MOBILE_SCREEN_MESSAGE_EXTRA_WIDTH_REM,\n );\n }\n if (!cachedMaxWidthNoAvatar) {\n cachedMaxWidthNoAvatar = Math.min(\n MESSAGE_MAX_WIDTH_REM,\n windowWidth / REM - MOBILE_SCREEN_NO_AVATARS_MESSAGE_EXTRA_WIDTH_REM,\n );\n }\n\n return fromOwnMessage\n ? cachedMaxWidthOwn\n : (noAvatars ? cachedMaxWidthNoAvatar : cachedMaxWidth);\n}\n\nexport function getAvailableWidth(\n fromOwnMessage: boolean,\n isForwarded?: boolean,\n isWebPagePhoto?: boolean,\n noAvatars?: boolean,\n) {\n const extraPaddingRem = isForwarded || isWebPagePhoto ? 1.625 : 0;\n const availableWidthRem = getMaxMessageWidthRem(fromOwnMessage, noAvatars) - extraPaddingRem;\n\n return availableWidthRem * REM;\n}\n\nfunction getAvailableHeight(isGif?: boolean, aspectRatio?: number) {\n if (\n isGif && aspectRatio\n && aspectRatio >= 0.75 && aspectRatio <= 1.25\n ) {\n return 20 * REM;\n }\n\n return 27 * REM;\n}\n\nfunction calculateDimensionsForMessageMedia({\n width,\n height,\n fromOwnMessage,\n isForwarded,\n isWebPagePhoto,\n isGif,\n noAvatars,\n}: {\n width: number;\n height: number;\n fromOwnMessage: boolean;\n isForwarded?: boolean;\n isWebPagePhoto?: boolean;\n isGif?: boolean;\n noAvatars?: boolean;\n}): ApiDimensions {\n const aspectRatio = height / width;\n const availableWidth = getAvailableWidth(fromOwnMessage, isForwarded, isWebPagePhoto, noAvatars);\n const availableHeight = getAvailableHeight(isGif, aspectRatio);\n const mediaWidth = isGif ? Math.max(GIF_MIN_WIDTH, width) : width;\n const mediaHeight = isGif ? height * (mediaWidth / width) : height;\n\n return calculateDimensions(availableWidth, availableHeight, mediaWidth, mediaHeight);\n}\n\nexport function getMediaViewerAvailableDimensions(withFooter: boolean, isVideo: boolean): ApiDimensions {\n const mql = window.matchMedia(MEDIA_VIEWER_MEDIA_QUERY);\n const { width: windowWidth, height: windowHeight } = windowSize.get();\n let occupiedHeightRem = isVideo && mql.matches ? 10 : 8.25;\n if (withFooter && !IS_TOUCH_ENV) {\n occupiedHeightRem = mql.matches ? 10 : 12.5;\n }\n return {\n width: windowWidth,\n height: windowHeight - occupiedHeightRem * REM,\n };\n}\n\nexport function calculateInlineImageDimensions(\n photo: ApiPhoto,\n fromOwnMessage: boolean,\n isForwarded?: boolean,\n isWebPagePhoto?: boolean,\n noAvatars?: boolean,\n) {\n const { width, height } = getPhotoInlineDimensions(photo) || DEFAULT_MEDIA_DIMENSIONS;\n\n return calculateDimensionsForMessageMedia({\n width,\n height,\n fromOwnMessage,\n isForwarded,\n isWebPagePhoto,\n noAvatars,\n });\n}\n\nexport function calculateVideoDimensions(\n video: ApiVideo,\n fromOwnMessage: boolean,\n isForwarded?: boolean,\n noAvatars?: boolean,\n) {\n const { width, height } = getVideoDimensions(video) || DEFAULT_MEDIA_DIMENSIONS;\n\n return calculateDimensionsForMessageMedia({\n width,\n height,\n fromOwnMessage,\n isForwarded,\n isGif: video.isGif,\n noAvatars,\n });\n}\n\nexport function getPictogramDimensions(): ApiDimensions {\n return {\n width: 2 * REM,\n height: 2 * REM,\n };\n}\n\nexport function getDocumentThumbnailDimensions(smaller?: boolean): ApiDimensions {\n if (smaller) {\n return {\n width: 3 * REM,\n height: 3 * REM,\n };\n }\n\n return {\n width: 3.375 * REM,\n height: 3.375 * REM,\n };\n}\n\nexport function getStickerDimensions(sticker: ApiSticker): ApiDimensions {\n const { width } = sticker;\n let { height } = sticker;\n\n // For some reason this sticker has some weird `height` value\n if (sticker.id === LIKE_STICKER_ID) {\n height = width;\n }\n\n const aspectRatio = (height && width) && height / width;\n const baseWidth = REM * (\n IS_SINGLE_COLUMN_LAYOUT\n ? STICKER_SIZE_INLINE_MOBILE_FACTOR\n : STICKER_SIZE_INLINE_DESKTOP_FACTOR\n );\n const calculatedHeight = aspectRatio ? baseWidth * aspectRatio : baseWidth;\n\n if (aspectRatio && calculatedHeight > baseWidth) {\n return {\n width: Math.round(baseWidth / aspectRatio),\n height: baseWidth,\n };\n }\n\n return {\n width: baseWidth,\n height: calculatedHeight,\n };\n}\n\nexport function calculateMediaViewerDimensions(\n { width, height }: ApiDimensions, withFooter: boolean, isVideo: boolean = false,\n): ApiDimensions {\n const { width: availableWidth, height: availableHeight } = getMediaViewerAvailableDimensions(withFooter, isVideo);\n\n return calculateDimensions(availableWidth, availableHeight, width, height);\n}\n\nexport function calculateDimensions(\n availableWidth: number,\n availableHeight: number,\n mediaWidth: number,\n mediaHeight: number,\n): ApiDimensions {\n const aspectRatio = mediaHeight / mediaWidth;\n const calculatedWidth = Math.min(mediaWidth, availableWidth);\n const calculatedHeight = Math.round(calculatedWidth * aspectRatio);\n\n if (calculatedHeight > availableHeight) {\n return {\n width: Math.round(availableHeight / aspectRatio),\n height: availableHeight,\n };\n }\n\n return {\n width: calculatedWidth,\n height: Math.round(calculatedWidth * aspectRatio),\n };\n}\n","import type { FC } from '../../lib/teact/teact';\nimport React, { memo } from '../../lib/teact/teact';\nimport { Bundles } from '../../util/moduleLoader';\nimport type { OwnProps } from './ChatFolderModal';\n\nimport useModuleLoader from '../../hooks/useModuleLoader';\n\nconst ChatFolderModalAsync: FC<OwnProps> = (props) => {\n const { isOpen } = props;\n const ChatFolderModal = useModuleLoader(Bundles.Extra, 'ChatFolderModal', !isOpen);\n\n // eslint-disable-next-line react/jsx-props-no-spreading\n return ChatFolderModal ? <ChatFolderModal {...props} /> : undefined;\n};\n\nexport default memo(ChatFolderModalAsync);\n","import { useMemo } from '../../../../lib/teact/teact';\n\nexport enum ChatAnimationTypes {\n Move,\n Opacity,\n None,\n}\n\nexport function useChatAnimationType(orderDiffById: Record<string, number>) {\n return useMemo(() => {\n const orderDiffs = Object.values(orderDiffById);\n const numberOfUp = orderDiffs.filter((diff) => diff < 0).length;\n const numberOfDown = orderDiffs.filter((diff) => diff > 0).length;\n\n return (chatId: string): ChatAnimationTypes => {\n const orderDiff = orderDiffById[chatId];\n if (orderDiff === 0) {\n return ChatAnimationTypes.None;\n }\n\n if (\n orderDiff === Infinity\n || orderDiff === -Infinity\n || (numberOfUp <= numberOfDown && orderDiff < 0)\n || (numberOfDown < numberOfUp && orderDiff > 0)\n ) {\n return ChatAnimationTypes.Opacity;\n }\n\n return ChatAnimationTypes.Move;\n };\n }, [orderDiffById]);\n}\n","import type { FC } from '../../../lib/teact/teact';\nimport React, { memo } from '../../../lib/teact/teact';\n\nimport type { ApiChat } from '../../../api/types';\n\nimport { formatIntegerCompact } from '../../../util/textFormat';\nimport buildClassName from '../../../util/buildClassName';\n\nimport ShowTransition from '../../ui/ShowTransition';\n\nimport './Badge.scss';\n\ntype OwnProps = {\n chat: ApiChat;\n isPinned?: boolean;\n isMuted?: boolean;\n};\n\nconst Badge: FC<OwnProps> = ({ chat, isPinned, isMuted }) => {\n const isShown = Boolean(\n chat.unreadCount || chat.unreadMentionsCount || chat.hasUnreadMark || isPinned || chat.unreadReactionsCount,\n );\n const isUnread = Boolean(chat.unreadCount || chat.hasUnreadMark);\n const className = buildClassName(\n 'Badge',\n isMuted && 'muted',\n !isUnread && isPinned && 'pinned',\n isUnread && 'unread',\n );\n\n function renderContent() {\n const unreadReactionsElement = chat.unreadReactionsCount && (\n <div className={buildClassName('Badge reaction', isMuted && 'muted')}>\n <i className=\"icon-heart\" />\n </div>\n );\n\n const unreadMentionsElement = chat.unreadMentionsCount && (\n <div className=\"Badge mention\">\n <i className=\"icon-mention\" />\n </div>\n );\n\n const unreadCountElement = (chat.hasUnreadMark || chat.unreadCount) ? (\n <div className={className}>\n {!chat.hasUnreadMark && formatIntegerCompact(chat.unreadCount!)}\n </div>\n ) : undefined;\n\n const pinnedElement = isPinned && !unreadCountElement && !unreadMentionsElement && !unreadReactionsElement && (\n <div className={className}>\n <i className=\"icon-pinned-chat\" />\n </div>\n );\n\n const elements = [unreadReactionsElement, unreadMentionsElement, unreadCountElement, pinnedElement].filter(Boolean);\n\n if (elements.length === 0) return undefined;\n\n if (elements.length === 1) return elements[0];\n\n return (\n <div className=\"Badge-wrapper\">\n {elements}\n </div>\n );\n }\n\n return (\n <ShowTransition isCustom className=\"Badge-transition\" isOpen={isShown}>\n {renderContent()}\n </ShowTransition>\n );\n};\n\nexport default memo(Badge);\n","import type { FC } from '../../../lib/teact/teact';\nimport React, { memo } from '../../../lib/teact/teact';\nimport buildClassName from '../../../util/buildClassName';\n\nimport { IS_SINGLE_COLUMN_LAYOUT } from '../../../util/environment';\n\nimport './ChatCallStatus.scss';\n\ntype OwnProps = {\n isSelected?: boolean;\n isActive?: boolean;\n};\n\nconst ChatCallStatus: FC<OwnProps> = ({\n isSelected,\n isActive,\n}) => {\n return (\n <div className={buildClassName(\n 'ChatCallStatus',\n isActive && 'active',\n isSelected && !IS_SINGLE_COLUMN_LAYOUT && 'selected',\n )}\n >\n <div className=\"indicator\">\n <div />\n <div />\n <div />\n </div>\n </div>\n );\n};\n\nexport default memo(ChatCallStatus);\n","import type { FC } from '../../../lib/teact/teact';\nimport React, {\n memo, useCallback, useLayoutEffect, useMemo, useRef,\n} from '../../../lib/teact/teact';\nimport { getActions, getGlobal, withGlobal } from '../../../global';\n\nimport type { LangFn } from '../../../hooks/useLang';\nimport type { ObserveFn } from '../../../hooks/useIntersectionObserver';\nimport type {\n ApiChat, ApiUser, ApiMessage, ApiMessageOutgoingStatus, ApiFormattedText, ApiUserStatus,\n} from '../../../api/types';\nimport type { AnimationLevel } from '../../../types';\nimport { MAIN_THREAD_ID } from '../../../api/types';\n\nimport { ANIMATION_END_DELAY } from '../../../config';\nimport { IS_SINGLE_COLUMN_LAYOUT } from '../../../util/environment';\nimport {\n getChatTitle,\n isUserId,\n isActionMessage,\n getPrivateChatUserId,\n getMessageAction,\n getMessageSenderName,\n isChatChannel,\n getMessageMediaHash,\n getMessageMediaThumbDataUri,\n getMessageVideo,\n getMessageSticker,\n selectIsChatMuted,\n getMessageRoundVideo,\n} from '../../../global/helpers';\nimport {\n selectChat, selectUser, selectChatMessage, selectOutgoingStatus, selectDraft, selectCurrentMessageList,\n selectNotifySettings, selectNotifyExceptions, selectUserStatus,\n} from '../../../global/selectors';\nimport { renderActionMessageText } from '../../common/helpers/renderActionMessageText';\nimport renderText from '../../common/helpers/renderText';\nimport { fastRaf } from '../../../util/schedulers';\nimport buildClassName from '../../../util/buildClassName';\nimport { renderMessageSummary } from '../../common/helpers/renderMessageText';\n\nimport useEnsureMessage from '../../../hooks/useEnsureMessage';\nimport useChatContextActions from '../../../hooks/useChatContextActions';\nimport useFlag from '../../../hooks/useFlag';\nimport useMedia from '../../../hooks/useMedia';\nimport { ChatAnimationTypes } from './hooks';\nimport useLang from '../../../hooks/useLang';\n\nimport Avatar from '../../common/Avatar';\nimport VerifiedIcon from '../../common/VerifiedIcon';\nimport TypingStatus from '../../common/TypingStatus';\nimport LastMessageMeta from '../../common/LastMessageMeta';\nimport DeleteChatModal from '../../common/DeleteChatModal';\nimport ListItem from '../../ui/ListItem';\nimport Badge from './Badge';\nimport ChatFolderModal from '../ChatFolderModal.async';\nimport ChatCallStatus from './ChatCallStatus';\nimport ReportModal from '../../common/ReportModal';\nimport FakeIcon from '../../common/FakeIcon';\nimport PremiumIcon from '../../common/PremiumIcon';\n\nimport './Chat.scss';\n\ntype OwnProps = {\n style?: string;\n chatId: string;\n folderId?: number;\n orderDiff: number;\n animationType: ChatAnimationTypes;\n isPinned?: boolean;\n observeIntersection?: ObserveFn;\n onDragEnter?: (chatId: string) => void;\n};\n\ntype StateProps = {\n chat?: ApiChat;\n isMuted?: boolean;\n user?: ApiUser;\n userStatus?: ApiUserStatus;\n actionTargetUserIds?: string[];\n actionTargetMessage?: ApiMessage;\n actionTargetChatId?: string;\n lastMessageSender?: ApiUser;\n lastMessageOutgoingStatus?: ApiMessageOutgoingStatus;\n draft?: ApiFormattedText;\n animationLevel?: AnimationLevel;\n isSelected?: boolean;\n canScrollDown?: boolean;\n canChangeFolder?: boolean;\n lastSyncTime?: number;\n};\n\nconst ANIMATION_DURATION = 200;\n\nconst Chat: FC<OwnProps & StateProps> = ({\n style,\n chatId,\n folderId,\n orderDiff,\n animationType,\n isPinned,\n observeIntersection,\n chat,\n isMuted,\n user,\n userStatus,\n actionTargetUserIds,\n lastMessageSender,\n lastMessageOutgoingStatus,\n actionTargetMessage,\n actionTargetChatId,\n draft,\n animationLevel,\n isSelected,\n canScrollDown,\n canChangeFolder,\n lastSyncTime,\n onDragEnter,\n}) => {\n const {\n openChat,\n focusLastMessage,\n } = getActions();\n\n // eslint-disable-next-line no-null/no-null\n const ref = useRef<HTMLDivElement>(null);\n\n const [isDeleteModalOpen, openDeleteModal, closeDeleteModal] = useFlag();\n const [isChatFolderModalOpen, openChatFolderModal, closeChatFolderModal] = useFlag();\n const [isReportModalOpen, openReportModal, closeReportModal] = useFlag();\n const [shouldRenderDeleteModal, markRenderDeleteModal, unmarkRenderDeleteModal] = useFlag();\n const [shouldRenderChatFolderModal, markRenderChatFolderModal, unmarkRenderChatFolderModal] = useFlag();\n const [shouldRenderReportModal, markRenderReportModal, unmarkRenderReportModal] = useFlag();\n\n const { lastMessage, typingStatus } = chat || {};\n const isAction = lastMessage && isActionMessage(lastMessage);\n\n useEnsureMessage(chatId, isAction ? lastMessage.replyToMessageId : undefined, actionTargetMessage);\n\n const mediaThumbnail = lastMessage && !getMessageSticker(lastMessage)\n ? getMessageMediaThumbDataUri(lastMessage)\n : undefined;\n const mediaBlobUrl = useMedia(lastMessage ? getMessageMediaHash(lastMessage, 'micro') : undefined);\n const isRoundVideo = Boolean(lastMessage && getMessageRoundVideo(lastMessage));\n\n const actionTargetUsers = useMemo(() => {\n if (!actionTargetUserIds) {\n return undefined;\n }\n\n // No need for expensive global updates on users, so we avoid them\n const usersById = getGlobal().users.byId;\n return actionTargetUserIds.map((userId) => usersById[userId]).filter<ApiUser>(Boolean as any);\n }, [actionTargetUserIds]);\n\n // Sets animation excess values when `orderDiff` changes and then resets excess values to animate.\n useLayoutEffect(() => {\n const element = ref.current;\n\n if (animationLevel === 0 || !element) {\n return;\n }\n\n // TODO Refactor animation: create `useListAnimation` that owns `orderDiff` and `animationType`\n if (animationType === ChatAnimationTypes.Opacity) {\n element.style.opacity = '0';\n\n fastRaf(() => {\n element.classList.add('animate-opacity');\n element.style.opacity = '1';\n });\n } else if (animationType === ChatAnimationTypes.Move) {\n element.style.transform = `translate3d(0, ${-orderDiff * 100}%, 0)`;\n\n fastRaf(() => {\n element.classList.add('animate-transform');\n element.style.transform = '';\n });\n } else {\n return;\n }\n\n setTimeout(() => {\n fastRaf(() => {\n element.classList.remove('animate-opacity', 'animate-transform');\n element.style.opacity = '';\n element.style.transform = '';\n });\n }, ANIMATION_DURATION + ANIMATION_END_DELAY);\n }, [animationLevel, orderDiff, animationType]);\n\n const handleClick = useCallback(() => {\n openChat({ id: chatId, shouldReplaceHistory: true }, { forceOnHeavyAnimation: true });\n\n if (isSelected && canScrollDown) {\n focusLastMessage();\n }\n }, [\n isSelected,\n canScrollDown,\n openChat,\n chatId,\n focusLastMessage,\n ]);\n\n const handleDragEnter = useCallback((e) => {\n e.preventDefault();\n onDragEnter?.(chatId);\n }, [chatId, onDragEnter]);\n\n const handleDelete = useCallback(() => {\n markRenderDeleteModal();\n openDeleteModal();\n }, [markRenderDeleteModal, openDeleteModal]);\n\n const handleChatFolderChange = useCallback(() => {\n markRenderChatFolderModal();\n openChatFolderModal();\n }, [markRenderChatFolderModal, openChatFolderModal]);\n\n const handleReport = useCallback(() => {\n markRenderReportModal();\n openReportModal();\n }, [markRenderReportModal, openReportModal]);\n\n const contextActions = useChatContextActions({\n chat,\n user,\n handleDelete,\n handleChatFolderChange,\n handleReport,\n folderId,\n isPinned,\n isMuted,\n canChangeFolder,\n });\n\n const lang = useLang();\n\n if (!chat) {\n return undefined;\n }\n\n function renderLastMessageOrTyping() {\n if (typingStatus && lastMessage && typingStatus.timestamp > lastMessage.date * 1000) {\n return <TypingStatus typingStatus={typingStatus} />;\n }\n\n if (draft?.text.length) {\n return (\n <p className=\"last-message\" dir={lang.isRtl ? 'auto' : 'ltr'}>\n <span className=\"draft\">{lang('Draft')}</span>\n {renderText(draft.text)}\n </p>\n );\n }\n\n if (!lastMessage) {\n return undefined;\n }\n\n if (isAction) {\n const isChat = chat && (isChatChannel(chat) || lastMessage.senderId === lastMessage.chatId);\n\n return (\n <p className=\"last-message\" dir={lang.isRtl ? 'auto' : 'ltr'}>\n {renderActionMessageText(\n lang,\n lastMessage,\n !isChat ? lastMessageSender : undefined,\n isChat ? chat : undefined,\n actionTargetUsers,\n actionTargetMessage,\n actionTargetChatId,\n { asTextWithSpoilers: true },\n )}\n </p>\n );\n }\n\n const senderName = getMessageSenderName(lang, chatId, lastMessageSender);\n\n return (\n <p className=\"last-message\" dir={lang.isRtl ? 'auto' : 'ltr'}>\n {senderName && (\n <>\n <span className=\"sender-name\">{renderText(senderName)}</span>\n <span className=\"colon\">:</span>\n </>\n )}\n {renderSummary(lang, lastMessage, observeIntersection, mediaBlobUrl || mediaThumbnail, isRoundVideo)}\n </p>\n );\n }\n\n const className = buildClassName(\n 'Chat chat-item-clickable',\n isUserId(chatId) ? 'private' : 'group',\n isSelected && 'selected',\n );\n\n return (\n <ListItem\n ref={ref}\n className={className}\n style={style}\n ripple={!IS_SINGLE_COLUMN_LAYOUT}\n contextActions={contextActions}\n onClick={handleClick}\n onDragEnter={handleDragEnter}\n >\n <div className=\"status\">\n <Avatar\n chat={chat}\n user={user}\n userStatus={userStatus}\n isSavedMessages={user?.isSelf}\n lastSyncTime={lastSyncTime}\n animationLevel={animationLevel}\n withVideo\n observeIntersection={observeIntersection}\n />\n {chat.isCallActive && chat.isCallNotEmpty && (\n <ChatCallStatus isSelected={isSelected} isActive={animationLevel !== 0} />\n )}\n </div>\n <div className=\"info\">\n <div className=\"title\">\n <h3>{renderText(getChatTitle(lang, chat, user))}</h3>\n {chat.isVerified && <VerifiedIcon />}\n {user?.isPremium && !user.isSelf && <PremiumIcon />}\n {chat.fakeType && <FakeIcon fakeType={chat.fakeType} />}\n {isMuted && <i className=\"icon-muted\" />}\n {chat.lastMessage && (\n <LastMessageMeta\n message={chat.lastMessage}\n outgoingStatus={lastMessageOutgoingStatus}\n />\n )}\n </div>\n <div className=\"subtitle\">\n {renderLastMessageOrTyping()}\n <Badge chat={chat} isPinned={isPinned} isMuted={isMuted} />\n </div>\n </div>\n {shouldRenderDeleteModal && (\n <DeleteChatModal\n isOpen={isDeleteModalOpen}\n onClose={closeDeleteModal}\n onCloseAnimationEnd={unmarkRenderDeleteModal}\n chat={chat}\n />\n )}\n {shouldRenderChatFolderModal && (\n <ChatFolderModal\n isOpen={isChatFolderModalOpen}\n onClose={closeChatFolderModal}\n onCloseAnimationEnd={unmarkRenderChatFolderModal}\n chatId={chatId}\n />\n )}\n {shouldRenderReportModal && (\n <ReportModal\n isOpen={isReportModalOpen}\n onClose={closeReportModal}\n onCloseAnimationEnd={unmarkRenderReportModal}\n chatId={chatId}\n subject=\"peer\"\n />\n )}\n </ListItem>\n );\n};\n\nfunction renderSummary(\n lang: LangFn, message: ApiMessage, observeIntersection?: ObserveFn, blobUrl?: string, isRoundVideo?: boolean,\n) {\n if (!blobUrl) {\n return renderMessageSummary(lang, message, undefined, undefined, undefined, observeIntersection);\n }\n\n return (\n <span className=\"media-preview\">\n <img src={blobUrl} alt=\"\" className={buildClassName('media-preview--image', isRoundVideo && 'round')} />\n {getMessageVideo(message) && <i className=\"icon-play\" />}\n {renderMessageSummary(lang, message, true, undefined, undefined, observeIntersection)}\n </span>\n );\n}\n\nexport default memo(withGlobal<OwnProps>(\n (global, { chatId }): StateProps => {\n const chat = selectChat(global, chatId);\n if (!chat) {\n return {};\n }\n\n const { senderId, replyToMessageId, isOutgoing } = chat.lastMessage || {};\n const lastMessageSender = senderId ? selectUser(global, senderId) : undefined;\n const lastMessageAction = chat.lastMessage ? getMessageAction(chat.lastMessage) : undefined;\n const actionTargetMessage = lastMessageAction && replyToMessageId\n ? selectChatMessage(global, chat.id, replyToMessageId)\n : undefined;\n const { targetUserIds: actionTargetUserIds, targetChatId: actionTargetChatId } = lastMessageAction || {};\n const privateChatUserId = getPrivateChatUserId(chat);\n const {\n chatId: currentChatId,\n threadId: currentThreadId,\n type: messageListType,\n } = selectCurrentMessageList(global) || {};\n const isSelected = chatId === currentChatId && currentThreadId === MAIN_THREAD_ID;\n\n return {\n chat,\n isMuted: selectIsChatMuted(chat, selectNotifySettings(global), selectNotifyExceptions(global)),\n lastMessageSender,\n actionTargetUserIds,\n actionTargetChatId,\n actionTargetMessage,\n draft: selectDraft(global, chatId, MAIN_THREAD_ID),\n animationLevel: global.settings.byKey.animationLevel,\n isSelected,\n canScrollDown: isSelected && messageListType === 'thread',\n canChangeFolder: (global.chatFolders.orderedIds?.length || 0) > 1,\n lastSyncTime: global.lastSyncTime,\n ...(isOutgoing && chat.lastMessage && {\n lastMessageOutgoingStatus: selectOutgoingStatus(global, chat.lastMessage),\n }),\n ...(privateChatUserId && {\n user: selectUser(global, privateChatUserId),\n userStatus: selectUserStatus(global, privateChatUserId),\n }),\n };\n },\n)(Chat));\n","import type { FC } from '../../../lib/teact/teact';\nimport React, { memo, useCallback } from '../../../lib/teact/teact';\nimport { withGlobal } from '../../../global';\n\nimport type { ApiChatFolder, ApiSticker } from '../../../api/types';\nimport { SettingsScreens } from '../../../types';\nimport type { FolderEditDispatch } from '../../../hooks/reducers/useFoldersReducer';\n\nimport { IS_SINGLE_COLUMN_LAYOUT } from '../../../util/environment';\nimport { selectAnimatedEmoji, selectChatFolder } from '../../../global/selectors';\nimport useLang from '../../../hooks/useLang';\n\nimport Button from '../../ui/Button';\nimport AnimatedIconFromSticker from '../../common/AnimatedIconFromSticker';\n\nimport './EmptyFolder.scss';\n\ntype OwnProps = {\n folderId?: number;\n folderType: 'all' | 'archived' | 'folder';\n foldersDispatch?: FolderEditDispatch;\n onScreenSelect?: (screen: SettingsScreens) => void;\n};\n\ntype StateProps = {\n chatFolder?: ApiChatFolder;\n animatedEmoji?: ApiSticker;\n};\n\nconst ICON_SIZE = 128;\n\nconst EmptyFolder: FC<OwnProps & StateProps> = ({\n chatFolder, animatedEmoji, foldersDispatch, onScreenSelect,\n}) => {\n const lang = useLang();\n\n const handleEditFolder = useCallback(() => {\n foldersDispatch!({ type: 'editFolder', payload: chatFolder });\n onScreenSelect!(SettingsScreens.FoldersEditFolderFromChatList);\n }, [chatFolder, foldersDispatch, onScreenSelect]);\n\n return (\n <div className=\"EmptyFolder\">\n <div className=\"sticker\">\n {animatedEmoji && <AnimatedIconFromSticker sticker={animatedEmoji} size={ICON_SIZE} />}\n </div>\n <h3 className=\"title\" dir=\"auto\">{lang('FilterNoChatsToDisplay')}</h3>\n <p className=\"description\" dir=\"auto\">\n {lang(chatFolder ? 'ChatList.EmptyChatListFilterText' : 'Chat.EmptyChat')}\n </p>\n {chatFolder && foldersDispatch && onScreenSelect && (\n <Button\n ripple={!IS_SINGLE_COLUMN_LAYOUT}\n fluid\n pill\n onClick={handleEditFolder}\n size=\"smaller\"\n isRtl={lang.isRtl}\n >\n <i className=\"icon-settings\" />\n {lang('ChatList.EmptyChatListEditFilter')}\n </Button>\n )}\n </div>\n );\n};\n\nexport default memo(withGlobal<OwnProps>((global, { folderId, folderType }): StateProps => {\n const chatFolder = folderId && folderType === 'folder' ? selectChatFolder(global, folderId) : undefined;\n\n return {\n chatFolder,\n animatedEmoji: selectAnimatedEmoji(global, '📂'),\n };\n})(EmptyFolder));\n","import React, {\n memo, useMemo, useEffect, useRef, useCallback,\n} from '../../../lib/teact/teact';\nimport { getActions } from '../../../global';\n\nimport type { FC } from '../../../lib/teact/teact';\nimport type { SettingsScreens } from '../../../types';\nimport type { FolderEditDispatch } from '../../../hooks/reducers/useFoldersReducer';\n\nimport {\n ALL_FOLDER_ID,\n ARCHIVED_FOLDER_ID,\n CHAT_HEIGHT_PX,\n CHAT_LIST_SLICE,\n} from '../../../config';\nimport { IS_MAC_OS, IS_PWA } from '../../../util/environment';\nimport { mapValues } from '../../../util/iteratees';\nimport { getPinnedChatsCount, getOrderKey } from '../../../util/folderManager';\n\nimport usePrevious from '../../../hooks/usePrevious';\nimport useInfiniteScroll from '../../../hooks/useInfiniteScroll';\nimport { useFolderManagerForOrderedIds } from '../../../hooks/useFolderManager';\nimport { useChatAnimationType } from './hooks';\nimport { useIntersectionObserver } from '../../../hooks/useIntersectionObserver';\nimport { useHotkeys } from '../../../hooks/useHotkeys';\nimport useDebouncedCallback from '../../../hooks/useDebouncedCallback';\n\nimport InfiniteScroll from '../../ui/InfiniteScroll';\nimport Loading from '../../ui/Loading';\nimport Chat from './Chat';\nimport EmptyFolder from './EmptyFolder';\n\ntype OwnProps = {\n folderType: 'all' | 'archived' | 'folder';\n folderId?: number;\n isActive: boolean;\n lastSyncTime?: number;\n foldersDispatch?: FolderEditDispatch;\n onScreenSelect?: (screen: SettingsScreens) => void;\n};\n\nconst INTERSECTION_THROTTLE = 200;\nconst DRAG_ENTER_DEBOUNCE = 500;\n\nconst ChatList: FC<OwnProps> = ({\n folderType,\n folderId,\n isActive,\n foldersDispatch,\n onScreenSelect,\n}) => {\n const { openChat, openNextChat } = getActions();\n // eslint-disable-next-line no-null/no-null\n const containerRef = useRef<HTMLDivElement>(null);\n const shouldIgnoreDragRef = useRef(false);\n\n const resolvedFolderId = (\n folderType === 'all' ? ALL_FOLDER_ID : folderType === 'archived' ? ARCHIVED_FOLDER_ID : folderId!\n );\n\n const orderedIds = useFolderManagerForOrderedIds(resolvedFolderId);\n\n const orderById = useMemo(() => {\n if (!orderedIds) {\n return undefined;\n }\n\n return orderedIds.reduce((acc, id, i) => {\n acc[id] = i;\n return acc;\n }, {} as Record<string, number>);\n }, [orderedIds]);\n\n const prevOrderById = usePrevious(orderById);\n\n const orderDiffById = useMemo(() => {\n if (!orderById || !prevOrderById) {\n return {};\n }\n\n return mapValues(orderById, (order, id) => {\n return prevOrderById[id] !== undefined ? order - prevOrderById[id] : -Infinity;\n });\n }, [orderById, prevOrderById]);\n\n const [viewportIds, getMore] = useInfiniteScroll(undefined, orderedIds, undefined, CHAT_LIST_SLICE);\n\n // Support <Alt>+<Up/Down> to navigate between chats\n useHotkeys(isActive && orderedIds?.length ? {\n 'Alt+ArrowUp': (e: KeyboardEvent) => {\n e.preventDefault();\n openNextChat({ targetIndexDelta: -1, orderedIds });\n },\n 'Alt+ArrowDown': (e: KeyboardEvent) => {\n e.preventDefault();\n openNextChat({ targetIndexDelta: 1, orderedIds });\n },\n } : undefined);\n\n // Support <Cmd>+<Digit> to navigate between chats\n useEffect(() => {\n if (!isActive || !orderedIds || !IS_PWA) {\n return undefined;\n }\n\n function handleKeyDown(e: KeyboardEvent) {\n if (((IS_MAC_OS && e.metaKey) || (!IS_MAC_OS && e.ctrlKey)) && e.code.startsWith('Digit')) {\n const [, digit] = e.code.match(/Digit(\\d)/) || [];\n if (!digit) return;\n\n const position = Number(digit) - 1;\n if (position > orderedIds!.length - 1 || position < 0) return;\n\n openChat({ id: orderedIds![position], shouldReplaceHistory: true });\n }\n }\n\n document.addEventListener('keydown', handleKeyDown);\n\n return () => {\n document.removeEventListener('keydown', handleKeyDown);\n };\n }, [isActive, openChat, openNextChat, orderedIds]);\n\n const getAnimationType = useChatAnimationType(orderDiffById);\n\n const { observe } = useIntersectionObserver({\n rootRef: containerRef,\n throttleMs: INTERSECTION_THROTTLE,\n });\n\n const handleDragEnter = useDebouncedCallback((chatId: string) => {\n if (shouldIgnoreDragRef.current) {\n shouldIgnoreDragRef.current = false;\n return;\n }\n openChat({ id: chatId, shouldReplaceHistory: true });\n }, [], DRAG_ENTER_DEBOUNCE, true);\n\n const handleDragLeave = useCallback((e: React.DragEvent<HTMLDivElement>) => {\n const rect = e.currentTarget.getBoundingClientRect();\n const x = e.clientX - rect.left;\n const y = e.clientY - rect.top;\n if (x < rect.width || y < rect.y) return;\n shouldIgnoreDragRef.current = true;\n }, []);\n\n function renderChats() {\n const viewportOffset = orderedIds!.indexOf(viewportIds![0]);\n const pinnedCount = getPinnedChatsCount(resolvedFolderId) || 0;\n\n return viewportIds!.map((id, i) => {\n const isPinned = viewportOffset + i < pinnedCount;\n\n return (\n <Chat\n key={id}\n teactOrderKey={isPinned ? i : getOrderKey(id)}\n chatId={id}\n isPinned={isPinned}\n folderId={folderId}\n animationType={getAnimationType(id)}\n orderDiff={orderDiffById[id]}\n style={`top: ${(viewportOffset + i) * CHAT_HEIGHT_PX}px;`}\n observeIntersection={observe}\n onDragEnter={handleDragEnter}\n />\n );\n });\n }\n\n return (\n <InfiniteScroll\n className=\"chat-list custom-scroll\"\n ref={containerRef}\n items={viewportIds}\n preloadBackwards={CHAT_LIST_SLICE}\n withAbsolutePositioning\n maxHeight={(orderedIds?.length || 0) * CHAT_HEIGHT_PX}\n onLoadMore={getMore}\n onDragLeave={handleDragLeave}\n >\n {viewportIds?.length ? (\n renderChats()\n ) : viewportIds && !viewportIds.length ? (\n (\n <EmptyFolder\n folderId={folderId}\n folderType={folderType}\n foldersDispatch={foldersDispatch}\n onScreenSelect={onScreenSelect}\n />\n )\n ) : (\n <Loading key=\"loading\" />\n )}\n </InfiniteScroll>\n );\n};\n\nexport default memo(ChatList);\n","import type { ApiChat, ApiMessage, ApiUser } from '../../../../api/types';\nimport {\n getChatTitle,\n getSenderTitle,\n isUserId,\n isChatGroup,\n} from '../../../../global/helpers';\nimport type { LangFn } from '../../../../hooks/useLang';\n\nexport function getSenderName(\n lang: LangFn, message: ApiMessage, chatsById: Record<string, ApiChat>, usersById: Record<string, ApiUser>,\n) {\n const { senderId } = message;\n if (!senderId) {\n return undefined;\n }\n\n const sender = isUserId(senderId) ? usersById[senderId] : chatsById[senderId];\n\n let senderName = getSenderTitle(lang, sender);\n\n const chat = chatsById[message.chatId];\n if (chat) {\n if (isUserId(senderId) && (sender as ApiUser).isSelf) {\n senderName = `${lang('FromYou')} → ${getChatTitle(lang, chat)}`;\n } else if (isChatGroup(chat)) {\n senderName += ` → ${getChatTitle(lang, chat)}`;\n }\n }\n\n return senderName;\n}\n","import type { FC } from '../../../lib/teact/teact';\nimport React, { memo } from '../../../lib/teact/teact';\nimport type { OwnProps } from './CustomSendMenu';\nimport { Bundles } from '../../../util/moduleLoader';\n\nimport useModuleLoader from '../../../hooks/useModuleLoader';\n\nconst CustomSendMenuAsync: FC<OwnProps> = (props) => {\n const { isOpen } = props;\n const CustomSend = useModuleLoader(Bundles.Extra, 'CustomSendMenu', !isOpen);\n\n // eslint-disable-next-line react/jsx-props-no-spreading\n return CustomSend ? <CustomSend {...props} /> : undefined;\n};\n\nexport default memo(CustomSendMenuAsync);\n","import type { FC } from '../../../lib/teact/teact';\nimport React, { memo } from '../../../lib/teact/teact';\n\nimport useFlag from '../../../hooks/useFlag';\nimport buildClassName from '../../../util/buildClassName';\n\nimport './DropTarget.scss';\n\nexport type OwnProps = {\n isQuick?: boolean;\n onFileSelect: (e: React.DragEvent<HTMLDivElement>) => void;\n};\n\nconst DropTarget: FC<OwnProps> = ({ isQuick, onFileSelect }) => {\n const [isHovered, markHovered, unmarkHovered] = useFlag();\n\n const handleDragLeave = (e: React.DragEvent<HTMLDivElement>) => {\n const { relatedTarget: toTarget } = e;\n\n if (toTarget) {\n e.stopPropagation();\n }\n\n unmarkHovered();\n };\n\n const className = buildClassName(\n 'DropTarget',\n isHovered && 'hovered',\n );\n\n return (\n <div\n className={className}\n onDrop={onFileSelect}\n onDragEnter={markHovered}\n onDragLeave={handleDragLeave}\n data-dropzone\n >\n <div className=\"target-content\">\n <div className={`icon icon-${isQuick ? 'photo' : 'document'}`} />\n <div className=\"title\">Drop files here to send them</div>\n <div className=\"description\">{isQuick ? 'in a quick way' : 'without compression'}</div>\n </div>\n </div>\n );\n};\n\nexport default memo(DropTarget);\n","import type { FC } from '../../../lib/teact/teact';\nimport React, {\n memo, useCallback, useEffect, useRef,\n} from '../../../lib/teact/teact';\n\nimport useShowTransition from '../../../hooks/useShowTransition';\nimport buildClassName from '../../../util/buildClassName';\nimport getFilesFromDataTransferItems from './helpers/getFilesFromDataTransferItems';\n\nimport captureEscKeyListener from '../../../util/captureEscKeyListener';\nimport usePrevious from '../../../hooks/usePrevious';\n\nimport Portal from '../../ui/Portal';\nimport DropTarget from './DropTarget';\n\nimport './DropArea.scss';\n\nexport type OwnProps = {\n isOpen: boolean;\n withQuick?: boolean;\n onHide: NoneToVoidFunction;\n onFileSelect: (files: File[], isQuick: boolean) => void;\n};\n\nexport enum DropAreaState {\n None = 'none',\n Document = 'document',\n QuickFile = 'quick_file',\n}\n\nconst DROP_LEAVE_TIMEOUT_MS = 150;\n\nconst DropArea: FC<OwnProps> = ({\n isOpen, withQuick, onHide, onFileSelect,\n}) => {\n // eslint-disable-next-line no-null/no-null\n const hideTimeoutRef = useRef<number>(null);\n const prevWithQuick = usePrevious(withQuick);\n const { shouldRender, transitionClassNames } = useShowTransition(isOpen);\n\n useEffect(() => (isOpen ? captureEscKeyListener(onHide) : undefined), [isOpen, onHide]);\n\n const handleFilesDrop = useCallback(async (e: React.DragEvent<HTMLDivElement>) => {\n const { dataTransfer: dt } = e;\n let files: File[] = [];\n\n if (dt.files && dt.files.length > 0 && (!dt.items || !dt.items.length)) {\n files = files.concat(Array.from(dt.files));\n } else if (dt.items && dt.items.length > 0) {\n const folderFiles = await getFilesFromDataTransferItems(dt.items);\n if (folderFiles.length) {\n files = files.concat(folderFiles);\n }\n }\n\n onHide();\n onFileSelect(files, false);\n }, [onFileSelect, onHide]);\n\n const handleQuickFilesDrop = useCallback((e: React.DragEvent<HTMLDivElement>) => {\n const { dataTransfer: dt } = e;\n\n if (dt.files && dt.files.length > 0) {\n onHide();\n onFileSelect(Array.from(dt.files), true);\n }\n }, [onFileSelect, onHide]);\n\n const handleDragLeave = useCallback((e: React.DragEvent<HTMLDivElement>) => {\n e.stopPropagation();\n\n const { target: fromTarget, relatedTarget: toTarget } = e;\n\n // Esc button pressed during drag event\n if ((fromTarget as HTMLDivElement).matches('.DropTarget, .DropArea') && !toTarget) {\n hideTimeoutRef.current = window.setTimeout(() => {\n onHide();\n }, DROP_LEAVE_TIMEOUT_MS);\n }\n }, [onHide]);\n\n const handleDragOver = () => {\n if (hideTimeoutRef.current) {\n window.clearTimeout(hideTimeoutRef.current);\n }\n };\n\n if (!shouldRender) {\n return undefined;\n }\n\n const className = buildClassName(\n 'DropArea',\n transitionClassNames,\n );\n\n return (\n <Portal containerId=\"#middle-column-portals\">\n <div\n className={className}\n onDragLeave={handleDragLeave}\n onDragOver={handleDragOver}\n onDrop={onHide}\n onClick={onHide}\n >\n <DropTarget onFileSelect={handleFilesDrop} />\n {(withQuick || prevWithQuick) && <DropTarget onFileSelect={handleQuickFilesDrop} isQuick />}\n </div>\n </Portal>\n );\n};\n\nexport default memo(DropArea);\n","import type { FC } from '../../../lib/teact/teact';\nimport React, { memo } from '../../../lib/teact/teact';\nimport type { OwnProps } from './EmojiTooltip';\nimport { Bundles } from '../../../util/moduleLoader';\n\nimport useModuleLoader from '../../../hooks/useModuleLoader';\n\nconst EmojiTooltipAsync: FC<OwnProps> = (props) => {\n const { isOpen } = props;\n const EmojiTooltip = useModuleLoader(Bundles.Extra, 'EmojiTooltip', !isOpen);\n\n // eslint-disable-next-line react/jsx-props-no-spreading\n return EmojiTooltip ? <EmojiTooltip {...props} /> : undefined;\n};\n\nexport default memo(EmojiTooltipAsync);\n","import type { ChangeEvent } from 'react';\nimport type { FC } from '../../../lib/teact/teact';\nimport React, {\n useEffect, useRef, memo, useState, useCallback,\n} from '../../../lib/teact/teact';\nimport { getActions, withGlobal } from '../../../global';\n\nimport type { IAnchorPosition, ISettings } from '../../../types';\n\nimport { EDITABLE_INPUT_ID } from '../../../config';\nimport { selectReplyingToId } from '../../../global/selectors';\nimport { debounce } from '../../../util/schedulers';\nimport focusEditableElement from '../../../util/focusEditableElement';\nimport buildClassName from '../../../util/buildClassName';\nimport {\n IS_ANDROID, IS_EMOJI_SUPPORTED, IS_IOS, IS_SINGLE_COLUMN_LAYOUT, IS_TOUCH_ENV,\n} from '../../../util/environment';\nimport captureKeyboardListeners from '../../../util/captureKeyboardListeners';\nimport useLayoutEffectWithPrevDeps from '../../../hooks/useLayoutEffectWithPrevDeps';\nimport useFlag from '../../../hooks/useFlag';\nimport { isHeavyAnimating } from '../../../hooks/useHeavyAnimationCheck';\nimport useLang from '../../../hooks/useLang';\nimport parseEmojiOnlyString from '../../common/helpers/parseEmojiOnlyString';\nimport { isSelectionInsideInput } from './helpers/selection';\nimport renderText from '../../common/helpers/renderText';\n\nimport TextFormatter from './TextFormatter';\n\nconst CONTEXT_MENU_CLOSE_DELAY_MS = 100;\n// Focus slows down animation, also it breaks transition layout in Chrome\nconst FOCUS_DELAY_MS = 350;\nconst TRANSITION_DURATION_FACTOR = 50;\n\ntype OwnProps = {\n id: string;\n chatId: string;\n threadId: number;\n isAttachmentModalInput?: boolean;\n editableInputId?: string;\n html: string;\n placeholder: string;\n forcedPlaceholder?: string;\n canAutoFocus: boolean;\n shouldSuppressFocus?: boolean;\n shouldSuppressTextFormatter?: boolean;\n onUpdate: (html: string) => void;\n onSuppressedFocus?: () => void;\n onSend: () => void;\n captionLimit?: number;\n};\n\ntype StateProps = {\n replyingToId?: number;\n noTabCapture?: boolean;\n messageSendKeyCombo?: ISettings['messageSendKeyCombo'];\n};\n\nconst MAX_INPUT_HEIGHT = IS_SINGLE_COLUMN_LAYOUT ? 256 : 416;\nconst TAB_INDEX_PRIORITY_TIMEOUT = 2000;\n// Heuristics allowing the user to make a triple click\nconst SELECTION_RECALCULATE_DELAY_MS = 260;\nconst TEXT_FORMATTER_SAFE_AREA_PX = 90;\n// For some reason Safari inserts `<br>` after user removes text from input\nconst SAFARI_BR = '<br>';\n\nfunction clearSelection() {\n const selection = window.getSelection();\n if (!selection) {\n return;\n }\n\n if (selection.removeAllRanges) {\n selection.removeAllRanges();\n } else if (selection.empty) {\n selection.empty();\n }\n}\n\nconst MessageInput: FC<OwnProps & StateProps> = ({\n id,\n chatId,\n captionLimit,\n isAttachmentModalInput,\n editableInputId,\n html,\n placeholder,\n forcedPlaceholder,\n canAutoFocus,\n shouldSuppressFocus,\n shouldSuppressTextFormatter,\n replyingToId,\n noTabCapture,\n messageSendKeyCombo,\n onUpdate,\n onSuppressedFocus,\n onSend,\n}) => {\n const {\n editLastMessage,\n replyToNextMessage,\n } = getActions();\n\n // eslint-disable-next-line no-null/no-null\n const inputRef = useRef<HTMLDivElement>(null);\n // eslint-disable-next-line no-null/no-null\n const selectionTimeoutRef = useRef<number>(null);\n // eslint-disable-next-line no-null/no-null\n const cloneRef = useRef<HTMLDivElement>(null);\n\n const lang = useLang();\n const isContextMenuOpenRef = useRef(false);\n const [isTextFormatterOpen, openTextFormatter, closeTextFormatter] = useFlag();\n const [textFormatterAnchorPosition, setTextFormatterAnchorPosition] = useState<IAnchorPosition>();\n const [selectedRange, setSelectedRange] = useState<Range>();\n\n useEffect(() => {\n if (!isAttachmentModalInput) return;\n updateInputHeight(false);\n }, [isAttachmentModalInput]);\n\n useLayoutEffectWithPrevDeps(([prevHtml]) => {\n if (html !== inputRef.current!.innerHTML) {\n inputRef.current!.innerHTML = html;\n }\n\n if (html !== cloneRef.current!.innerHTML) {\n cloneRef.current!.innerHTML = html;\n }\n\n if (prevHtml !== undefined && prevHtml !== html) {\n updateInputHeight(!html.length);\n }\n }, [html]);\n\n const chatIdRef = useRef(chatId);\n chatIdRef.current = chatId;\n const focusInput = useCallback(() => {\n if (!inputRef.current) {\n return;\n }\n\n if (isHeavyAnimating()) {\n setTimeout(focusInput, FOCUS_DELAY_MS);\n return;\n }\n\n focusEditableElement(inputRef.current!);\n }, []);\n\n const handleCloseTextFormatter = useCallback(() => {\n closeTextFormatter();\n clearSelection();\n }, [closeTextFormatter]);\n\n function checkSelection() {\n // Disable the formatter on iOS devices for now.\n if (IS_IOS) {\n return false;\n }\n\n const selection = window.getSelection();\n if (!selection || !selection.rangeCount || isContextMenuOpenRef.current) {\n closeTextFormatter();\n return false;\n }\n\n const selectionRange = selection.getRangeAt(0);\n const selectedText = selectionRange.toString().trim();\n if (\n shouldSuppressTextFormatter\n || !isSelectionInsideInput(selectionRange, editableInputId || EDITABLE_INPUT_ID)\n || !selectedText\n || parseEmojiOnlyString(selectedText)\n || !selectionRange.START_TO_END\n ) {\n closeTextFormatter();\n return false;\n }\n\n return true;\n }\n\n function processSelection() {\n if (!checkSelection()) {\n return;\n }\n\n const selectionRange = window.getSelection()!.getRangeAt(0);\n const selectionRect = selectionRange.getBoundingClientRect();\n const inputRect = inputRef.current!.getBoundingClientRect();\n\n let x = (selectionRect.left + selectionRect.width / 2) - inputRect.left;\n\n if (x < TEXT_FORMATTER_SAFE_AREA_PX) {\n x = TEXT_FORMATTER_SAFE_AREA_PX;\n } else if (x > inputRect.width - TEXT_FORMATTER_SAFE_AREA_PX) {\n x = inputRect.width - TEXT_FORMATTER_SAFE_AREA_PX;\n }\n\n setTextFormatterAnchorPosition({\n x,\n y: selectionRect.top - inputRect.top,\n });\n\n setSelectedRange(selectionRange);\n openTextFormatter();\n }\n\n function processSelectionWithTimeout() {\n if (selectionTimeoutRef.current) {\n window.clearTimeout(selectionTimeoutRef.current);\n }\n // Small delay to allow browser properly recalculate selection\n selectionTimeoutRef.current = window.setTimeout(processSelection, SELECTION_RECALCULATE_DELAY_MS);\n }\n\n function handleMouseDown(e: React.MouseEvent<HTMLDivElement, MouseEvent>) {\n if (e.button !== 2) {\n e.target.addEventListener('mouseup', processSelectionWithTimeout, { once: true });\n return;\n }\n\n if (isContextMenuOpenRef.current) {\n return;\n }\n\n isContextMenuOpenRef.current = true;\n\n function handleCloseContextMenu(e2: KeyboardEvent | MouseEvent) {\n if (e2 instanceof KeyboardEvent && e2.key !== 'Esc' && e2.key !== 'Escape') {\n return;\n }\n\n setTimeout(() => {\n isContextMenuOpenRef.current = false;\n }, CONTEXT_MENU_CLOSE_DELAY_MS);\n\n window.removeEventListener('keydown', handleCloseContextMenu);\n window.removeEventListener('mousedown', handleCloseContextMenu);\n }\n\n document.addEventListener('mousedown', handleCloseContextMenu);\n document.addEventListener('keydown', handleCloseContextMenu);\n }\n\n function handleKeyDown(e: React.KeyboardEvent<HTMLDivElement>) {\n // https://levelup.gitconnected.com/javascript-events-handlers-keyboard-and-load-events-1b3e46a6b0c3#1960\n const { isComposing } = e;\n\n if (!isComposing && !html.length && (e.metaKey || e.ctrlKey)) {\n const targetIndexDelta = e.key === 'ArrowDown' ? 1 : e.key === 'ArrowUp' ? -1 : undefined;\n if (targetIndexDelta) {\n e.preventDefault();\n\n replyToNextMessage({ targetIndexDelta });\n return;\n }\n }\n\n if (!isComposing && e.key === 'Enter' && !e.shiftKey) {\n if (\n !(IS_IOS || IS_ANDROID)\n && (\n (messageSendKeyCombo === 'enter' && !e.shiftKey)\n || (messageSendKeyCombo === 'ctrl-enter' && (e.ctrlKey || e.metaKey))\n )\n ) {\n e.preventDefault();\n\n closeTextFormatter();\n onSend();\n }\n } else if (!isComposing && e.key === 'ArrowUp' && !html.length && !e.metaKey && !e.ctrlKey && !e.altKey) {\n e.preventDefault();\n editLastMessage();\n } else {\n e.target.addEventListener('keyup', processSelectionWithTimeout, { once: true });\n }\n }\n\n function handleChange(e: ChangeEvent<HTMLDivElement>) {\n const { innerHTML, textContent } = e.currentTarget;\n\n onUpdate(innerHTML === SAFARI_BR ? '' : innerHTML);\n\n // Reset focus on the input to remove any active styling when input is cleared\n if (\n !IS_TOUCH_ENV\n && (!textContent || !textContent.length)\n // When emojis are not supported, innerHTML contains an emoji img tag that doesn't exist in the textContext\n && !(!IS_EMOJI_SUPPORTED && innerHTML.includes('emoji-small'))\n ) {\n const selection = window.getSelection()!;\n if (selection) {\n inputRef.current!.blur();\n selection.removeAllRanges();\n focusEditableElement(inputRef.current!, true);\n }\n }\n }\n\n function stopEvent(e: React.MouseEvent<HTMLDivElement, MouseEvent>) {\n if (!checkSelection()) {\n return;\n }\n\n e.preventDefault();\n e.stopPropagation();\n }\n\n function updateInputHeight(willSend = false) {\n const input = inputRef.current!;\n const clone = cloneRef.current!;\n const currentHeight = Number(input.style.height.replace('px', ''));\n const newHeight = Math.min(clone.scrollHeight, MAX_INPUT_HEIGHT);\n if (newHeight === currentHeight) {\n return;\n }\n\n const transitionDuration = Math.round(\n TRANSITION_DURATION_FACTOR * Math.log(Math.abs(newHeight - currentHeight)),\n );\n\n const exec = () => {\n input.style.height = `${newHeight}px`;\n input.style.transitionDuration = `${transitionDuration}ms`;\n input.classList.toggle('overflown', clone.scrollHeight > MAX_INPUT_HEIGHT);\n };\n\n if (willSend) {\n // Sync with sending animation\n requestAnimationFrame(exec);\n } else {\n exec();\n }\n }\n\n useEffect(() => {\n if (IS_TOUCH_ENV) {\n return;\n }\n\n if (canAutoFocus) {\n focusInput();\n }\n }, [chatId, focusInput, replyingToId, canAutoFocus]);\n\n useEffect(() => {\n if (noTabCapture) {\n return undefined;\n }\n\n const captureFirstTab = debounce((e: KeyboardEvent) => {\n if (e.key === 'Tab') {\n e.preventDefault();\n requestAnimationFrame(focusInput);\n }\n }, TAB_INDEX_PRIORITY_TIMEOUT, true, false);\n\n return captureKeyboardListeners({ onTab: captureFirstTab });\n }, [focusInput, noTabCapture]);\n\n useEffect(() => {\n const input = inputRef.current!;\n\n function suppressFocus() {\n input.blur();\n }\n\n if (shouldSuppressFocus) {\n input.addEventListener('focus', suppressFocus);\n }\n\n return () => {\n input.removeEventListener('focus', suppressFocus);\n };\n }, [shouldSuppressFocus]);\n\n const className = buildClassName(\n 'form-control custom-scroll',\n html.length > 0 && 'touched',\n shouldSuppressFocus && 'focus-disabled',\n );\n\n return (\n <div id={id} onClick={shouldSuppressFocus ? onSuppressedFocus : undefined} dir={lang.isRtl ? 'rtl' : undefined}>\n <div\n ref={inputRef}\n id={editableInputId || EDITABLE_INPUT_ID}\n className={className}\n contentEditable\n role=\"textbox\"\n dir=\"auto\"\n tabIndex={0}\n onClick={focusInput}\n onChange={handleChange}\n onKeyDown={handleKeyDown}\n onMouseDown={handleMouseDown}\n onContextMenu={IS_ANDROID ? stopEvent : undefined}\n onTouchCancel={IS_ANDROID ? processSelectionWithTimeout : undefined}\n aria-label={placeholder}\n />\n {captionLimit && (\n <div className=\"max-length-indicator\" dir=\"auto\">\n {captionLimit}\n </div>\n )}\n\n <div ref={cloneRef} className={buildClassName(className, 'clone')} dir=\"auto\" />\n {!forcedPlaceholder && <span className=\"placeholder-text\" dir=\"auto\">{placeholder}</span>}\n <TextFormatter\n isOpen={isTextFormatterOpen}\n anchorPosition={textFormatterAnchorPosition}\n selectedRange={selectedRange}\n setSelectedRange={setSelectedRange}\n onClose={handleCloseTextFormatter}\n />\n {forcedPlaceholder && <span className=\"forced-placeholder\">{renderText(forcedPlaceholder!)}</span>}\n </div>\n );\n};\n\nexport default memo(withGlobal<OwnProps>(\n (global, { chatId, threadId }: OwnProps): StateProps => {\n const { messageSendKeyCombo } = global.settings.byKey;\n\n return {\n messageSendKeyCombo,\n replyingToId: chatId && threadId ? selectReplyingToId(global, chatId, threadId) : undefined,\n noTabCapture: global.pollModal.isOpen || global.payment.isPaymentModalOpen,\n };\n },\n)(MessageInput));\n","import type { FC } from '../../../lib/teact/teact';\nimport React, {\n memo, useCallback, useEffect, useRef, useState,\n} from '../../../lib/teact/teact';\n\nimport type { IAnchorPosition } from '../../../types';\nimport { ApiMessageEntityTypes } from '../../../api/types';\n\nimport { EDITABLE_INPUT_ID } from '../../../config';\nimport buildClassName from '../../../util/buildClassName';\nimport { ensureProtocol } from '../../../util/ensureProtocol';\nimport captureEscKeyListener from '../../../util/captureEscKeyListener';\nimport getKeyFromEvent from '../../../util/getKeyFromEvent';\nimport useShowTransition from '../../../hooks/useShowTransition';\nimport useVirtualBackdrop from '../../../hooks/useVirtualBackdrop';\nimport useFlag from '../../../hooks/useFlag';\nimport useLang from '../../../hooks/useLang';\n\nimport Button from '../../ui/Button';\n\nimport './TextFormatter.scss';\n\nexport type OwnProps = {\n isOpen: boolean;\n anchorPosition?: IAnchorPosition;\n selectedRange?: Range;\n setSelectedRange: (range: Range) => void;\n onClose: () => void;\n};\n\ninterface ISelectedTextFormats {\n bold?: boolean;\n italic?: boolean;\n underline?: boolean;\n strikethrough?: boolean;\n monospace?: boolean;\n spoiler?: boolean;\n}\n\nconst TEXT_FORMAT_BY_TAG_NAME: Record<string, keyof ISelectedTextFormats> = {\n B: 'bold',\n STRONG: 'bold',\n I: 'italic',\n EM: 'italic',\n U: 'underline',\n DEL: 'strikethrough',\n CODE: 'monospace',\n SPAN: 'spoiler',\n};\nconst fragmentEl = document.createElement('div');\n\nconst TextFormatter: FC<OwnProps> = ({\n isOpen,\n anchorPosition,\n selectedRange,\n setSelectedRange,\n onClose,\n}) => {\n // eslint-disable-next-line no-null/no-null\n const containerRef = useRef<HTMLDivElement>(null);\n // eslint-disable-next-line no-null/no-null\n const linkUrlInputRef = useRef<HTMLInputElement>(null);\n const { shouldRender, transitionClassNames } = useShowTransition(isOpen);\n const [isLinkControlOpen, openLinkControl, closeLinkControl] = useFlag();\n const [linkUrl, setLinkUrl] = useState('');\n const [isEditingLink, setIsEditingLink] = useState(false);\n const [inputClassName, setInputClassName] = useState<string | undefined>();\n const [selectedTextFormats, setSelectedTextFormats] = useState<ISelectedTextFormats>({});\n\n useEffect(() => (isOpen ? captureEscKeyListener(onClose) : undefined), [isOpen, onClose]);\n useVirtualBackdrop(\n isOpen,\n containerRef,\n onClose,\n );\n\n useEffect(() => {\n if (isLinkControlOpen) {\n linkUrlInputRef.current!.focus();\n } else {\n setLinkUrl('');\n setIsEditingLink(false);\n }\n }, [isLinkControlOpen]);\n\n useEffect(() => {\n if (!shouldRender) {\n closeLinkControl();\n setSelectedTextFormats({});\n setInputClassName(undefined);\n }\n }, [closeLinkControl, shouldRender]);\n\n useEffect(() => {\n if (!isOpen || !selectedRange) {\n return;\n }\n\n const selectedFormats: ISelectedTextFormats = {};\n let { parentElement } = selectedRange.commonAncestorContainer;\n while (parentElement && parentElement.id !== EDITABLE_INPUT_ID) {\n const textFormat = TEXT_FORMAT_BY_TAG_NAME[parentElement.tagName];\n if (textFormat) {\n selectedFormats[textFormat] = true;\n }\n\n parentElement = parentElement.parentElement;\n }\n\n setSelectedTextFormats(selectedFormats);\n }, [isOpen, selectedRange, openLinkControl]);\n\n const restoreSelection = useCallback(() => {\n if (!selectedRange) {\n return;\n }\n\n const selection = window.getSelection();\n if (selection) {\n selection.removeAllRanges();\n selection.addRange(selectedRange);\n }\n }, [selectedRange]);\n\n const updateSelectedRange = useCallback(() => {\n const selection = window.getSelection();\n if (selection) {\n setSelectedRange(selection.getRangeAt(0));\n }\n }, [setSelectedRange]);\n\n const getSelectedText = useCallback(() => {\n if (!selectedRange) {\n return undefined;\n }\n fragmentEl.replaceChildren(selectedRange.cloneContents());\n return fragmentEl.innerHTML;\n }, [selectedRange]);\n\n const getSelectedElement = useCallback(() => {\n if (!selectedRange) {\n return undefined;\n }\n\n return selectedRange.commonAncestorContainer.parentElement;\n }, [selectedRange]);\n\n function updateInputStyles() {\n const input = linkUrlInputRef.current;\n if (!input) {\n return;\n }\n\n const { offsetWidth, scrollWidth, scrollLeft } = input;\n if (scrollWidth <= offsetWidth) {\n setInputClassName(undefined);\n return;\n }\n\n let className = '';\n if (scrollLeft < scrollWidth - offsetWidth) {\n className = 'mask-right';\n }\n if (scrollLeft > 0) {\n className += ' mask-left';\n }\n\n setInputClassName(className);\n }\n\n function handleLinkUrlChange(e: React.ChangeEvent<HTMLInputElement>) {\n setLinkUrl(e.target.value);\n updateInputStyles();\n }\n\n function getFormatButtonClassName(key: keyof ISelectedTextFormats) {\n if (selectedTextFormats[key]) {\n return 'active';\n }\n\n if (key === 'monospace' || key === 'strikethrough') {\n if (Object.keys(selectedTextFormats).some(\n (fKey) => fKey !== key && Boolean(selectedTextFormats[fKey as keyof ISelectedTextFormats]),\n )) {\n return 'disabled';\n }\n } else if (selectedTextFormats.monospace || selectedTextFormats.strikethrough) {\n return 'disabled';\n }\n\n return undefined;\n }\n\n const handleSpoilerText = useCallback(() => {\n if (selectedTextFormats.spoiler) {\n const element = getSelectedElement();\n if (\n !selectedRange\n || !element\n || element.dataset.entityType !== ApiMessageEntityTypes.Spoiler\n || !element.textContent\n ) {\n return;\n }\n\n element.replaceWith(element.textContent);\n setSelectedTextFormats((selectedFormats) => ({\n ...selectedFormats,\n spoiler: false,\n }));\n\n return;\n }\n\n const text = getSelectedText();\n document.execCommand(\n 'insertHTML', false, `<span class=\"spoiler\" data-entity-type=\"${ApiMessageEntityTypes.Spoiler}\">${text}</span>`,\n );\n onClose();\n }, [getSelectedElement, getSelectedText, onClose, selectedRange, selectedTextFormats.spoiler]);\n\n const handleBoldText = useCallback(() => {\n setSelectedTextFormats((selectedFormats) => {\n // Somehow re-applying 'bold' command to already bold text doesn't work\n document.execCommand(selectedFormats.bold ? 'removeFormat' : 'bold');\n Object.keys(selectedFormats).forEach((key) => {\n if ((key === 'italic' || key === 'underline') && Boolean(selectedFormats[key])) {\n document.execCommand(key);\n }\n });\n\n updateSelectedRange();\n return {\n ...selectedFormats,\n bold: !selectedFormats.bold,\n };\n });\n }, [updateSelectedRange]);\n\n const handleItalicText = useCallback(() => {\n document.execCommand('italic');\n updateSelectedRange();\n setSelectedTextFormats((selectedFormats) => ({\n ...selectedFormats,\n italic: !selectedFormats.italic,\n }));\n }, [updateSelectedRange]);\n\n const handleUnderlineText = useCallback(() => {\n document.execCommand('underline');\n updateSelectedRange();\n setSelectedTextFormats((selectedFormats) => ({\n ...selectedFormats,\n underline: !selectedFormats.underline,\n }));\n }, [updateSelectedRange]);\n\n const handleStrikethroughText = useCallback(() => {\n if (selectedTextFormats.strikethrough) {\n const element = getSelectedElement();\n if (\n !selectedRange\n || !element\n || element.tagName !== 'DEL'\n || !element.textContent\n ) {\n return;\n }\n\n element.replaceWith(element.textContent);\n setSelectedTextFormats((selectedFormats) => ({\n ...selectedFormats,\n strikethrough: false,\n }));\n\n return;\n }\n\n const text = getSelectedText();\n document.execCommand('insertHTML', false, `<del>${text}</del>`);\n onClose();\n }, [\n getSelectedElement, getSelectedText, onClose, selectedRange, selectedTextFormats.strikethrough,\n ]);\n\n const handleMonospaceText = useCallback(() => {\n if (selectedTextFormats.monospace) {\n const element = getSelectedElement();\n if (\n !selectedRange\n || !element\n || element.tagName !== 'CODE'\n || !element.textContent\n ) {\n return;\n }\n\n element.replaceWith(element.textContent);\n setSelectedTextFormats((selectedFormats) => ({\n ...selectedFormats,\n monospace: false,\n }));\n\n return;\n }\n\n const text = getSelectedText();\n document.execCommand('insertHTML', false, `<code class=\"text-entity-code\" dir=\"auto\">${text}</code>`);\n onClose();\n }, [\n getSelectedElement, getSelectedText, onClose, selectedRange, selectedTextFormats.monospace,\n ]);\n\n const handleLinkUrlConfirm = useCallback(() => {\n const formattedLinkUrl = (ensureProtocol(linkUrl) || '').split('%').map(encodeURI).join('%');\n\n if (isEditingLink) {\n const element = getSelectedElement();\n if (!element || element.tagName !== 'A') {\n return;\n }\n\n (element as HTMLAnchorElement).href = formattedLinkUrl;\n\n onClose();\n\n return;\n }\n\n const text = getSelectedText();\n restoreSelection();\n document.execCommand(\n 'insertHTML',\n false,\n `<a href=${formattedLinkUrl} class=\"text-entity-link\" dir=\"auto\">${text}</a>`,\n );\n onClose();\n }, [getSelectedElement, getSelectedText, isEditingLink, linkUrl, onClose, restoreSelection]);\n\n const handleKeyDown = useCallback((e: KeyboardEvent) => {\n const HANDLERS_BY_KEY: Record<string, AnyToVoidFunction> = {\n k: openLinkControl,\n b: handleBoldText,\n u: handleUnderlineText,\n i: handleItalicText,\n m: handleMonospaceText,\n s: handleStrikethroughText,\n p: handleSpoilerText,\n };\n\n const handler = HANDLERS_BY_KEY[getKeyFromEvent(e)];\n\n if (\n e.altKey\n || !(e.ctrlKey || e.metaKey)\n || !handler\n ) {\n return;\n }\n\n e.preventDefault();\n e.stopPropagation();\n handler();\n }, [\n openLinkControl, handleBoldText, handleUnderlineText, handleItalicText, handleMonospaceText,\n handleStrikethroughText, handleSpoilerText,\n ]);\n\n useEffect(() => {\n if (isOpen) {\n document.addEventListener('keydown', handleKeyDown);\n }\n\n return () => document.removeEventListener('keydown', handleKeyDown);\n }, [isOpen, handleKeyDown]);\n\n const lang = useLang();\n\n function handleContainerKeyDown(e: React.KeyboardEvent<HTMLDivElement>) {\n if (e.key === 'Enter' && isLinkControlOpen) {\n handleLinkUrlConfirm();\n e.preventDefault();\n }\n }\n\n if (!shouldRender) {\n return undefined;\n }\n\n const className = buildClassName(\n 'TextFormatter',\n transitionClassNames,\n isLinkControlOpen && 'link-control-shown',\n );\n\n const linkUrlConfirmClassName = buildClassName(\n 'TextFormatter-link-url-confirm',\n Boolean(linkUrl.length) && 'shown',\n );\n\n const style = anchorPosition\n ? `left: ${anchorPosition.x}px; top: ${anchorPosition.y}px;--text-formatter-left: ${anchorPosition.x}px;`\n : '';\n\n return (\n <div\n ref={containerRef}\n className={className}\n style={style}\n onKeyDown={handleContainerKeyDown}\n >\n <div className=\"TextFormatter-buttons\">\n <Button\n color=\"translucent\"\n ariaLabel=\"Spoiler text\"\n className={getFormatButtonClassName('spoiler')}\n onClick={handleSpoilerText}\n >\n <i className=\"icon-eye-closed\" />\n </Button>\n <div className=\"TextFormatter-divider\" />\n <Button\n color=\"translucent\"\n ariaLabel=\"Bold text\"\n className={getFormatButtonClassName('bold')}\n onClick={handleBoldText}\n >\n <i className=\"icon-bold\" />\n </Button>\n <Button\n color=\"translucent\"\n ariaLabel=\"Italic text\"\n className={getFormatButtonClassName('italic')}\n onClick={handleItalicText}\n >\n <i className=\"icon-italic\" />\n </Button>\n <Button\n color=\"translucent\"\n ariaLabel=\"Underlined text\"\n className={getFormatButtonClassName('underline')}\n onClick={handleUnderlineText}\n >\n <i className=\"icon-underlined\" />\n </Button>\n <Button\n color=\"translucent\"\n ariaLabel=\"Strikethrough text\"\n className={getFormatButtonClassName('strikethrough')}\n onClick={handleStrikethroughText}\n >\n <i className=\"icon-strikethrough\" />\n </Button>\n <Button\n color=\"translucent\"\n ariaLabel=\"Monospace text\"\n className={getFormatButtonClassName('monospace')}\n onClick={handleMonospaceText}\n >\n <i className=\"icon-monospace\" />\n </Button>\n <div className=\"TextFormatter-divider\" />\n <Button color=\"translucent\" ariaLabel={lang('TextFormat.AddLinkTitle')} onClick={openLinkControl}>\n <i className=\"icon-link\" />\n </Button>\n </div>\n\n <div className=\"TextFormatter-link-control\">\n <div className=\"TextFormatter-buttons\">\n <Button color=\"translucent\" ariaLabel={lang('Cancel')} onClick={closeLinkControl}>\n <i className=\"icon-arrow-left\" />\n </Button>\n <div className=\"TextFormatter-divider\" />\n\n <div\n className={buildClassName('TextFormatter-link-url-input-wrapper', inputClassName)}\n >\n <input\n ref={linkUrlInputRef}\n className=\"TextFormatter-link-url-input\"\n type=\"text\"\n value={linkUrl}\n placeholder=\"Enter URL...\"\n autoComplete=\"off\"\n inputMode=\"url\"\n dir=\"auto\"\n onChange={handleLinkUrlChange}\n onScroll={updateInputStyles}\n />\n </div>\n\n <div className={linkUrlConfirmClassName}>\n <div className=\"TextFormatter-divider\" />\n <Button\n color=\"translucent\"\n ariaLabel={lang('Save')}\n className=\"color-primary\"\n onClick={handleLinkUrlConfirm}\n >\n <i className=\"icon-check\" />\n </Button>\n </div>\n </div>\n </div>\n </div>\n );\n};\n\nexport default memo(TextFormatter);\n","export default function getKeyFromEvent(e: KeyboardEvent) {\n const key = 'key' in e ? e.key : e.code;\n\n return key.startsWith('Key') ? key.slice(3).toLowerCase() : key;\n}\n","export default async function getFilesFromDataTransferItems(dataTransferItems: DataTransferItemList) {\n const files: File[] = [];\n\n function traverseFileTreePromise(entry: FileSystemEntry | File, item: DataTransferItem) {\n return new Promise((resolve) => {\n if (entry instanceof File) {\n files.push(entry);\n resolve(entry);\n } else if (entry.isFile) {\n const itemFile = item.getAsFile();\n (entry as FileSystemFileEntry).file((file) => {\n files.push(file);\n resolve(file);\n }, () => {\n // iOS Safari throws an error \"NotFoundError: Path does not exist\" for files from the clipboard\n // https://stackoverflow.com/a/50059309\n if (itemFile) {\n files.push(itemFile);\n }\n resolve(itemFile);\n });\n } else if (entry.isDirectory) {\n const dirReader = (entry as FileSystemDirectoryEntry).createReader();\n dirReader.readEntries((entries) => {\n const entriesPromises = [];\n for (let i = 0; i < entries.length; i++) {\n entriesPromises.push(traverseFileTreePromise(entries[i], item));\n }\n resolve(Promise.all(entriesPromises));\n });\n }\n });\n }\n\n const entriesPromises = [];\n for (let i = 0; i < dataTransferItems.length; i++) {\n const item = dataTransferItems[i];\n if (item.kind === 'file') {\n const entry = item.webkitGetAsEntry() || item.getAsFile();\n if (entry) {\n entriesPromises.push(traverseFileTreePromise(entry, item));\n }\n }\n }\n\n await Promise.all(entriesPromises);\n\n return files.map(fixMovMime);\n}\n\n// .mov MIME type not reported sometimes https://developer.mozilla.org/en-US/docs/Web/API/File/type#sect1\nfunction fixMovMime(file: File) {\n const ext = file.name.split('.').pop()!;\n if (!file.type && ext.toLowerCase() === 'mov') {\n return new File([file], file.name, { type: 'video/quicktime' });\n }\n return file;\n}\n","const RE_BR = /(<br>|<br\\s?\\/>)/g;\nconst RE_SPACE = /(&nbsp;|\\u00A0)/g;\nconst RE_CLEAN_HTML = /(<div>|<\\/div>)/gi;\nconst RE_EXTRA_NEW_LINE = /\\n$/i;\n\nexport function prepareForRegExp(html: string) {\n return html\n .replace(RE_SPACE, ' ')\n .replace(RE_BR, '\\n')\n .replace(RE_CLEAN_HTML, '')\n .replace(RE_EXTRA_NEW_LINE, '');\n}\n","const MAX_NESTING_PARENTS = 5;\n\nexport function isSelectionInsideInput(selectionRange: Range, inputId: string) {\n const { commonAncestorContainer } = selectionRange;\n let parentNode: HTMLElement | null = commonAncestorContainer as HTMLElement;\n let iterations = 1;\n while (parentNode && parentNode.id !== inputId && iterations < MAX_NESTING_PARENTS) {\n parentNode = parentNode.parentElement;\n iterations++;\n }\n\n return Boolean(parentNode && parentNode.id === inputId);\n}\n","import { areSortedArraysEqual } from './iteratees';\n\nconst cache = new WeakMap<AnyFunction, {\n lastArgs: any[];\n lastResult: any;\n}>();\n\nexport default function memoized<T extends AnyFunction>(fn: T) {\n return (...args: Parameters<T>): ReturnType<T> => {\n const cached = cache.get(fn);\n if (cached && areSortedArraysEqual(cached.lastArgs, args)) {\n return cached.lastResult;\n }\n\n const result = fn(...args);\n cache.set(fn, { lastArgs: args, lastResult: result });\n return result;\n };\n}\n","import {\n useCallback, useEffect, useState,\n} from '../../../../lib/teact/teact';\n\nimport { EDITABLE_INPUT_CSS_SELECTOR, EDITABLE_INPUT_ID } from '../../../../config';\nimport { MEMO_EMPTY_ARRAY } from '../../../../util/memo';\nimport { prepareForRegExp } from '../helpers/prepareForRegExp';\nimport type { EmojiData, EmojiModule, EmojiRawData } from '../../../../util/emoji';\nimport { uncompressEmoji } from '../../../../util/emoji';\nimport focusEditableElement from '../../../../util/focusEditableElement';\nimport {\n buildCollectionByKey, mapValues, pickTruthy, unique,\n} from '../../../../util/iteratees';\nimport memoized from '../../../../util/memoized';\nimport useFlag from '../../../../hooks/useFlag';\nimport renderText from '../../../common/helpers/renderText';\n\ninterface Library {\n keywords: string[];\n byKeyword: Record<string, Emoji[]>;\n names: string[];\n byName: Record<string, Emoji[]>;\n}\n\nlet emojiDataPromise: Promise<EmojiModule>;\nlet emojiRawData: EmojiRawData;\nlet emojiData: EmojiData;\n\nlet RE_EMOJI_SEARCH: RegExp;\nconst EMOJIS_LIMIT = 36;\nconst FILTER_MIN_LENGTH = 2;\n\nconst prepareRecentEmojisMemo = memoized(prepareRecentEmojis);\nconst prepareLibraryMemo = memoized(prepareLibrary);\nconst searchInLibraryMemo = memoized(searchInLibrary);\n\ntry {\n RE_EMOJI_SEARCH = /(^|\\s):[-+_:\\p{L}\\p{N}]*$/gui;\n} catch (e) {\n // Support for older versions of firefox\n RE_EMOJI_SEARCH = /(^|\\s):[-+_:\\d\\wа-яё]*$/gi;\n}\n\nexport default function useEmojiTooltip(\n isAllowed: boolean,\n htmlRef: { current: string },\n recentEmojiIds: string[],\n inputId = EDITABLE_INPUT_ID,\n onUpdateHtml: (html: string) => void,\n baseEmojiKeywords?: Record<string, string[]>,\n emojiKeywords?: Record<string, string[]>,\n isDisabled = false,\n) {\n const [isOpen, markIsOpen, unmarkIsOpen] = useFlag();\n const [byId, setById] = useState<Record<string, Emoji> | undefined>();\n const [shouldForceInsertEmoji, setShouldForceInsertEmoji] = useState(false);\n const [filteredEmojis, setFilteredEmojis] = useState<Emoji[]>(MEMO_EMPTY_ARRAY);\n\n // Initialize data on first render.\n useEffect(() => {\n if (isDisabled) return;\n const exec = () => {\n setById(emojiData.emojis);\n };\n\n if (emojiData) {\n exec();\n } else {\n ensureEmojiData()\n .then(exec);\n }\n }, [isDisabled]);\n\n const html = htmlRef.current;\n useEffect(() => {\n if (!isAllowed || !html || !byId || isDisabled) {\n unmarkIsOpen();\n return;\n }\n\n const code = html.includes(':') && getEmojiCode(html);\n if (!code) {\n setFilteredEmojis(MEMO_EMPTY_ARRAY);\n unmarkIsOpen();\n return;\n }\n\n const forceSend = code.length > 2 && code.endsWith(':');\n const filter = code.substr(1, forceSend ? code.length - 2 : undefined);\n let matched: Emoji[] = MEMO_EMPTY_ARRAY;\n\n setShouldForceInsertEmoji(forceSend);\n\n if (!filter) {\n matched = prepareRecentEmojisMemo(byId, recentEmojiIds, EMOJIS_LIMIT);\n } else if (filter.length >= FILTER_MIN_LENGTH) {\n const library = prepareLibraryMemo(byId, baseEmojiKeywords, emojiKeywords);\n matched = searchInLibraryMemo(library, filter, EMOJIS_LIMIT);\n }\n\n if (matched.length) {\n if (!forceSend) {\n markIsOpen();\n }\n setFilteredEmojis(matched);\n } else {\n unmarkIsOpen();\n }\n }, [\n byId, html, isAllowed, markIsOpen, recentEmojiIds, unmarkIsOpen, setShouldForceInsertEmoji,\n isDisabled, baseEmojiKeywords, emojiKeywords,\n ]);\n\n const insertEmoji = useCallback((textEmoji: string, isForce?: boolean) => {\n const currentHtml = htmlRef.current;\n const atIndex = currentHtml.lastIndexOf(':', isForce ? currentHtml.lastIndexOf(':') - 1 : undefined);\n if (atIndex !== -1) {\n onUpdateHtml(`${currentHtml.substr(0, atIndex)}${renderText(textEmoji, ['emoji_html'])}`);\n let messageInput: HTMLDivElement;\n if (inputId === EDITABLE_INPUT_ID) {\n messageInput = document.querySelector<HTMLDivElement>(EDITABLE_INPUT_CSS_SELECTOR)!;\n } else {\n messageInput = document.getElementById(inputId) as HTMLDivElement;\n }\n requestAnimationFrame(() => {\n focusEditableElement(messageInput, true, true);\n });\n }\n\n unmarkIsOpen();\n }, [htmlRef, inputId, onUpdateHtml, unmarkIsOpen]);\n\n useEffect(() => {\n if (isOpen && shouldForceInsertEmoji && filteredEmojis.length) {\n insertEmoji(filteredEmojis[0].native, true);\n }\n }, [filteredEmojis, insertEmoji, isOpen, shouldForceInsertEmoji]);\n\n return {\n isEmojiTooltipOpen: isOpen,\n closeEmojiTooltip: unmarkIsOpen,\n filteredEmojis,\n insertEmoji,\n };\n}\n\nfunction getEmojiCode(html: string) {\n const emojis = prepareForRegExp(html).match(RE_EMOJI_SEARCH);\n\n return emojis ? emojis[0].trim() : undefined;\n}\n\nasync function ensureEmojiData() {\n if (!emojiDataPromise) {\n emojiDataPromise = import('emoji-data-ios/emoji-data.json') as unknown as Promise<EmojiModule>;\n emojiRawData = (await emojiDataPromise).default;\n\n emojiData = uncompressEmoji(emojiRawData);\n }\n\n return emojiDataPromise;\n}\n\nfunction prepareRecentEmojis(byId: Record<string, Emoji>, recentEmojiIds: string[], limit: number) {\n if (!byId || !recentEmojiIds.length) {\n return MEMO_EMPTY_ARRAY;\n }\n\n return Object.values(pickTruthy(byId, recentEmojiIds)).slice(0, limit);\n}\n\nfunction prepareLibrary(\n byId: Record<string, Emoji>,\n baseEmojiKeywords?: Record<string, string[]>,\n emojiKeywords?: Record<string, string[]>,\n): Library {\n const emojis = Object.values(byId);\n\n const byNative = buildCollectionByKey<Emoji>(emojis, 'native');\n const baseEmojisByKeyword = baseEmojiKeywords\n ? mapValues(baseEmojiKeywords, (natives) => {\n return Object.values(pickTruthy(byNative, natives));\n })\n : {};\n const emojisByKeyword = emojiKeywords\n ? mapValues(emojiKeywords, (natives) => {\n return Object.values(pickTruthy(byNative, natives));\n })\n : {};\n\n const byKeyword = { ...baseEmojisByKeyword, ...emojisByKeyword };\n const keywords = ([] as string[]).concat(Object.keys(baseEmojisByKeyword), Object.keys(emojisByKeyword));\n\n const byName = emojis.reduce((result, emoji) => {\n emoji.names.forEach((name) => {\n if (!result[name]) {\n result[name] = [];\n }\n\n result[name].push(emoji);\n });\n\n return result;\n }, {} as Record<string, Emoji[]>);\n\n const names = Object.keys(byName);\n\n return {\n byKeyword,\n keywords,\n byName,\n names,\n };\n}\n\nfunction searchInLibrary(library: Library, filter: string, limit: number) {\n const {\n byKeyword, keywords, byName, names,\n } = library;\n\n let matched: Emoji[] = MEMO_EMPTY_ARRAY;\n\n const matchedKeywords = keywords.filter((keyword) => keyword.startsWith(filter)).sort();\n matched = matched.concat(Object.values(pickTruthy(byKeyword!, matchedKeywords)).flat());\n\n // Also search by names, which is useful for non-English languages\n const matchedNames = names.filter((name) => name.startsWith(filter));\n matched = matched.concat(Object.values(pickTruthy(byName, matchedNames)).flat());\n\n matched = unique(matched);\n\n return matched.slice(0, limit);\n}\n","import {\n useCallback, useEffect, useState,\n} from '../../../../lib/teact/teact';\nimport { getGlobal } from '../../../../global';\n\nimport type { ApiChatMember, ApiUser } from '../../../../api/types';\nimport { ApiMessageEntityTypes } from '../../../../api/types';\nimport { EDITABLE_INPUT_ID } from '../../../../config';\nimport { filterUsersByName, getUserFirstOrLastName } from '../../../../global/helpers';\nimport { prepareForRegExp } from '../helpers/prepareForRegExp';\nimport focusEditableElement from '../../../../util/focusEditableElement';\nimport useFlag from '../../../../hooks/useFlag';\nimport { pickTruthy, unique } from '../../../../util/iteratees';\nimport { throttle } from '../../../../util/schedulers';\n\nconst runThrottled = throttle((cb) => cb(), 500, true);\nlet RE_USERNAME_SEARCH: RegExp;\n\ntry {\n RE_USERNAME_SEARCH = /(^|\\s)@[-_\\p{L}\\p{M}\\p{N}]*$/gui;\n} catch (e) {\n // Support for older versions of firefox\n RE_USERNAME_SEARCH = /(^|\\s)@[-_\\d\\wа-яё]*$/gi;\n}\n\nexport default function useMentionTooltip(\n canSuggestMembers: boolean | undefined,\n htmlRef: { current: string },\n onUpdateHtml: (html: string) => void,\n inputId: string = EDITABLE_INPUT_ID,\n groupChatMembers?: ApiChatMember[],\n topInlineBotIds?: string[],\n currentUserId?: string,\n) {\n const [isOpen, markIsOpen, unmarkIsOpen] = useFlag();\n const [usersToMention, setUsersToMention] = useState<ApiUser[] | undefined>();\n\n const updateFilteredUsers = useCallback((filter, withInlineBots: boolean) => {\n // No need for expensive global updates on users, so we avoid them\n const usersById = getGlobal().users.byId;\n\n if (!(groupChatMembers || topInlineBotIds) || !usersById) {\n setUsersToMention(undefined);\n\n return;\n }\n\n runThrottled(() => {\n const memberIds = groupChatMembers?.reduce((acc: string[], member) => {\n if (member.userId !== currentUserId) {\n acc.push(member.userId);\n }\n\n return acc;\n }, []);\n\n const filteredIds = filterUsersByName(unique([\n ...((withInlineBots && topInlineBotIds) || []),\n ...(memberIds || []),\n ]), usersById, filter);\n\n setUsersToMention(Object.values(pickTruthy(usersById, filteredIds)));\n });\n }, [currentUserId, groupChatMembers, topInlineBotIds]);\n\n const html = htmlRef.current;\n useEffect(() => {\n if (!canSuggestMembers || !html.length) {\n unmarkIsOpen();\n return;\n }\n\n const usernameFilter = html.includes('@') && getUsernameFilter(html);\n\n if (usernameFilter) {\n const filter = usernameFilter ? usernameFilter.substr(1) : '';\n updateFilteredUsers(filter, canSuggestInlineBots(html));\n } else {\n unmarkIsOpen();\n }\n }, [canSuggestMembers, updateFilteredUsers, markIsOpen, unmarkIsOpen, html]);\n\n useEffect(() => {\n if (usersToMention?.length) {\n markIsOpen();\n } else {\n unmarkIsOpen();\n }\n }, [markIsOpen, unmarkIsOpen, usersToMention]);\n\n const insertMention = useCallback((user: ApiUser, forceFocus = false) => {\n if (!user.username && !getUserFirstOrLastName(user)) {\n return;\n }\n\n const insertedHtml = user.username\n ? `@${user.username}`\n : `<a\n class=\"text-entity-link\"\n data-entity-type=\"${ApiMessageEntityTypes.MentionName}\"\n data-user-id=\"${user.id}\"\n contenteditable=\"false\"\n dir=\"auto\"\n >${getUserFirstOrLastName(user)}</a>`;\n\n const currentHtml = htmlRef.current;\n const atIndex = currentHtml.lastIndexOf('@');\n if (atIndex !== -1) {\n onUpdateHtml(`${currentHtml.substr(0, atIndex)}${insertedHtml}&nbsp;`);\n const messageInput = document.getElementById(inputId)!;\n requestAnimationFrame(() => {\n focusEditableElement(messageInput, forceFocus);\n });\n }\n\n unmarkIsOpen();\n }, [htmlRef, inputId, onUpdateHtml, unmarkIsOpen]);\n\n return {\n isMentionTooltipOpen: isOpen,\n closeMentionTooltip: unmarkIsOpen,\n insertMention,\n mentionFilteredUsers: usersToMention,\n };\n}\n\nfunction getUsernameFilter(html: string) {\n const username = prepareForRegExp(html).match(RE_USERNAME_SEARCH);\n\n return username ? username[0].trim() : undefined;\n}\n\nfunction canSuggestInlineBots(html: string) {\n return html.startsWith('@');\n}\n","import { useEffect, useRef } from '../../../lib/teact/teact';\n\nimport useOnChange from '../../../hooks/useOnChange';\nimport useForceUpdate from '../../../hooks/useForceUpdate';\n\nexport default function useAsyncRendering<T extends any[]>(dependencies: T, delay?: number) {\n const isDisabled = delay === undefined;\n const shouldRenderRef = useRef(isDisabled);\n const timeoutRef = useRef<number>();\n const forceUpdate = useForceUpdate();\n\n useOnChange(() => {\n if (isDisabled) {\n return;\n }\n\n shouldRenderRef.current = false;\n\n if (timeoutRef.current) {\n clearTimeout(timeoutRef.current);\n timeoutRef.current = undefined;\n }\n }, dependencies);\n\n useEffect(() => {\n if (isDisabled || shouldRenderRef.current) {\n return;\n }\n\n const exec = () => {\n shouldRenderRef.current = true;\n forceUpdate();\n };\n\n if (delay! > 0) {\n timeoutRef.current = window.setTimeout(exec, delay);\n } else {\n exec();\n }\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, dependencies);\n\n return shouldRenderRef.current;\n}\n","import type { ChangeEvent } from 'react';\nimport type { FC } from '../../lib/teact/teact';\nimport React, { useCallback, memo, useState } from '../../lib/teact/teact';\n\nimport Checkbox from './Checkbox';\n\ntype IRadioOption = {\n label: string;\n subLabel?: string;\n value: string;\n};\n\ntype OwnProps = {\n id?: string;\n options: IRadioOption[];\n selected?: string[];\n disabled?: boolean;\n round?: boolean;\n loadingOptions?: string[];\n onChange: (value: string[]) => void;\n};\n\nconst CheckboxGroup: FC<OwnProps> = ({\n id,\n options,\n selected = [],\n disabled,\n round,\n loadingOptions,\n onChange,\n}) => {\n const [values, setValues] = useState<string[]>(selected || []);\n\n const handleChange = useCallback((event: ChangeEvent<HTMLInputElement>) => {\n const { value, checked } = event.currentTarget;\n let newValues: string[];\n if (checked) {\n newValues = [...values, value];\n } else {\n newValues = values.filter((v) => v !== value);\n }\n\n setValues(newValues);\n onChange(newValues);\n }, [onChange, values]);\n\n return (\n <div id={id} className=\"radio-group\">\n {options.map((option) => (\n <Checkbox\n label={option.label}\n subLabel={option.subLabel}\n value={option.value}\n checked={selected.indexOf(option.value) !== -1}\n disabled={disabled}\n round={round}\n isLoading={loadingOptions ? loadingOptions.indexOf(option.value) !== -1 : undefined}\n onChange={handleChange}\n />\n ))}\n </div>\n );\n};\n\nexport default memo(CheckboxGroup);\n","import type { FC, TeactNode } from '../../lib/teact/teact';\nimport React, { memo, useCallback, useRef } from '../../lib/teact/teact';\n\nimport type { TextPart } from '../../types';\n\nimport useLang from '../../hooks/useLang';\nimport useKeyboardListNavigation from '../../hooks/useKeyboardListNavigation';\n\nimport Modal from './Modal';\nimport Button from './Button';\n\ntype OwnProps = {\n isOpen: boolean;\n onClose: () => void;\n onCloseAnimationEnd?: () => void;\n title?: string;\n header?: TeactNode;\n textParts?: TextPart[];\n text?: string;\n confirmLabel?: string;\n confirmHandler: () => void;\n confirmIsDestructive?: boolean;\n isButtonsInOneRow?: boolean;\n children?: React.ReactNode;\n};\n\nconst ConfirmDialog: FC<OwnProps> = ({\n isOpen,\n onClose,\n onCloseAnimationEnd,\n title,\n header,\n text,\n textParts,\n confirmLabel = 'Confirm',\n confirmHandler,\n confirmIsDestructive,\n isButtonsInOneRow,\n children,\n}) => {\n const lang = useLang();\n\n // eslint-disable-next-line no-null/no-null\n const containerRef = useRef<HTMLDivElement>(null);\n\n const handleSelectWithEnter = useCallback((index: number) => {\n if (index === -1) confirmHandler();\n }, [confirmHandler]);\n\n const handleKeyDown = useKeyboardListNavigation(containerRef, isOpen, handleSelectWithEnter, '.Button');\n\n return (\n <Modal\n className=\"confirm\"\n title={title || lang('Telegram')}\n header={header}\n isOpen={isOpen}\n onClose={onClose}\n onCloseAnimationEnd={onCloseAnimationEnd}\n >\n {text && text.split('\\\\n').map((textPart) => (\n <p>{textPart}</p>\n ))}\n {textParts || children}\n <div className={isButtonsInOneRow ? 'dialog-buttons mt-2' : ''} ref={containerRef} onKeyDown={handleKeyDown}>\n <Button\n className=\"confirm-dialog-button\"\n isText\n onClick={confirmHandler}\n color={confirmIsDestructive ? 'danger' : 'primary'}\n >\n {confirmLabel}\n </Button>\n <Button className=\"confirm-dialog-button\" isText onClick={onClose}>{lang('Cancel')}</Button>\n </div>\n </Modal>\n );\n};\n\nexport default memo(ConfirmDialog);\n","import React from '../../lib/teact/teact';\n\nimport type { FC } from '../../lib/teact/teact';\nimport type { OwnProps as ButtonProps } from './Button';\n\nimport buildClassName from '../../util/buildClassName';\nimport useLang from '../../hooks/useLang';\n\nimport Button from './Button';\n\nimport './FloatingActionButton.scss';\n\ntype OwnProps = {\n isShown: boolean;\n className?: string;\n color?: ButtonProps['color'];\n ariaLabel?: ButtonProps['ariaLabel'];\n disabled?: boolean;\n onClick: () => void;\n children: React.ReactNode;\n};\n\nconst FloatingActionButton: FC<OwnProps> = ({\n isShown,\n className,\n color = 'primary',\n ariaLabel,\n disabled,\n onClick,\n children,\n}) => {\n const lang = useLang();\n\n const buttonClassName = buildClassName(\n 'FloatingActionButton',\n isShown && 'revealed',\n className,\n );\n\n return (\n <Button\n className={buttonClassName}\n color={color}\n round\n disabled={disabled}\n onClick={isShown && !disabled ? onClick : undefined}\n ariaLabel={ariaLabel}\n tabIndex={-1}\n isRtl={lang.isRtl}\n >\n {children}\n </Button>\n );\n};\n\nexport default FloatingActionButton;\n","import type { RefObject } from 'react';\nimport type { FC, TeactNode } from '../../lib/teact/teact';\nimport React, { useRef, useCallback } from '../../lib/teact/teact';\n\nimport { IS_TOUCH_ENV } from '../../util/environment';\nimport { fastRaf } from '../../util/schedulers';\nimport buildClassName from '../../util/buildClassName';\nimport useContextMenuHandlers from '../../hooks/useContextMenuHandlers';\nimport useContextMenuPosition from '../../hooks/useContextMenuPosition';\nimport useFlag from '../../hooks/useFlag';\nimport useLang from '../../hooks/useLang';\n\nimport RippleEffect from './RippleEffect';\nimport Menu from './Menu';\nimport MenuItem from './MenuItem';\nimport Button from './Button';\n\nimport './ListItem.scss';\n\ninterface MenuItemContextAction {\n title: string;\n icon: string;\n destructive?: boolean;\n handler?: () => void;\n}\n\ninterface OwnProps {\n ref?: RefObject<HTMLDivElement>;\n buttonRef?: RefObject<HTMLDivElement>;\n icon?: string;\n leftElement?: TeactNode;\n secondaryIcon?: string;\n rightElement?: TeactNode;\n buttonClassName?: string;\n className?: string;\n style?: string;\n children: React.ReactNode;\n disabled?: boolean;\n allowDisabledClick?: boolean;\n ripple?: boolean;\n narrow?: boolean;\n inactive?: boolean;\n focus?: boolean;\n destructive?: boolean;\n multiline?: boolean;\n isStatic?: boolean;\n contextActions?: MenuItemContextAction[];\n onMouseDown?: (e: React.MouseEvent<HTMLDivElement>) => void;\n onClick?: (e: React.MouseEvent<HTMLDivElement>) => void;\n onSecondaryIconClick?: (e: React.MouseEvent<HTMLButtonElement>) => void;\n onDragEnter?: (e: React.DragEvent<HTMLDivElement>) => void;\n}\n\nconst ListItem: FC<OwnProps> = ({\n ref,\n buttonRef,\n icon,\n leftElement,\n buttonClassName,\n secondaryIcon,\n rightElement,\n className,\n style,\n children,\n disabled,\n allowDisabledClick,\n ripple,\n narrow,\n inactive,\n focus,\n destructive,\n multiline,\n isStatic,\n contextActions,\n onMouseDown,\n onClick,\n onSecondaryIconClick,\n onDragEnter,\n}) => {\n // eslint-disable-next-line no-null/no-null\n let containerRef = useRef<HTMLDivElement>(null);\n if (ref) {\n containerRef = ref;\n }\n const [isTouched, markIsTouched, unmarkIsTouched] = useFlag();\n\n const {\n isContextMenuOpen, contextMenuPosition,\n handleBeforeContextMenu, handleContextMenu,\n handleContextMenuClose, handleContextMenuHide,\n } = useContextMenuHandlers(containerRef, !contextActions);\n\n const getTriggerElement = useCallback(() => containerRef.current, []);\n\n const getRootElement = useCallback(\n () => containerRef.current!.closest('.custom-scroll'),\n [],\n );\n\n const getMenuElement = useCallback(\n () => containerRef.current!.querySelector('.ListItem-context-menu .bubble'),\n [],\n );\n\n const {\n positionX, positionY, transformOriginX, transformOriginY, style: menuStyle,\n } = useContextMenuPosition(\n contextMenuPosition,\n getTriggerElement,\n getRootElement,\n getMenuElement,\n );\n\n const handleClick = useCallback((e: React.MouseEvent<HTMLDivElement, MouseEvent>) => {\n if ((disabled && !allowDisabledClick) || !onClick) {\n return;\n }\n onClick(e);\n\n if (IS_TOUCH_ENV && !ripple) {\n markIsTouched();\n fastRaf(unmarkIsTouched);\n }\n }, [allowDisabledClick, disabled, markIsTouched, onClick, ripple, unmarkIsTouched]);\n\n const handleSecondaryIconClick = (e: React.MouseEvent<HTMLButtonElement, MouseEvent>) => {\n if ((disabled && !allowDisabledClick) || e.button !== 0 || (!onSecondaryIconClick && !contextActions)) return;\n e.stopPropagation();\n if (onSecondaryIconClick) {\n onSecondaryIconClick(e);\n } else {\n handleContextMenu(e);\n }\n };\n\n const handleMouseDown = useCallback((e: React.MouseEvent<HTMLDivElement, MouseEvent>) => {\n if (inactive || IS_TOUCH_ENV) {\n return;\n }\n if (contextActions && (e.button === 2 || !onClick)) {\n handleBeforeContextMenu(e);\n }\n if (e.button === 0) {\n if (!onClick) {\n handleContextMenu(e);\n } else {\n handleClick(e);\n }\n }\n }, [inactive, contextActions, onClick, handleBeforeContextMenu, handleContextMenu, handleClick]);\n\n const lang = useLang();\n\n const fullClassName = buildClassName(\n 'ListItem',\n className,\n !isStatic && 'no-selection',\n ripple && 'has-ripple',\n narrow && 'narrow',\n disabled && 'disabled',\n allowDisabledClick && 'click-allowed',\n inactive && 'inactive',\n contextMenuPosition && 'has-menu-open',\n focus && 'focus',\n destructive && 'destructive',\n multiline && 'multiline',\n isStatic && 'is-static',\n );\n\n return (\n <div\n ref={containerRef}\n className={fullClassName}\n dir={lang.isRtl ? 'rtl' : undefined}\n style={style}\n onMouseDown={onMouseDown}\n onDragEnter={onDragEnter}\n >\n <div\n className={buildClassName('ListItem-button', isTouched && 'active', buttonClassName)}\n role={!isStatic ? 'button' : undefined}\n ref={buttonRef}\n tabIndex={!isStatic ? 0 : undefined}\n onClick={(!inactive && IS_TOUCH_ENV) ? handleClick : undefined}\n onMouseDown={handleMouseDown}\n onContextMenu={(!inactive && contextActions) ? handleContextMenu : undefined}\n >\n {leftElement}\n {icon && (\n <i className={`icon-${icon}`} />\n )}\n {multiline && (<div className=\"multiline-item\">{children}</div>)}\n {!multiline && children}\n {!disabled && !inactive && ripple && (\n <RippleEffect />\n )}\n {secondaryIcon && (\n <Button\n className=\"secondary-icon\"\n round\n color=\"translucent\"\n size=\"smaller\"\n onClick={IS_TOUCH_ENV ? handleSecondaryIconClick : undefined}\n onMouseDown={!IS_TOUCH_ENV ? handleSecondaryIconClick : undefined}\n >\n <i className={`icon-${secondaryIcon}`} />\n </Button>\n )}\n {rightElement}\n </div>\n {contextActions && contextMenuPosition !== undefined && (\n <Menu\n isOpen={isContextMenuOpen}\n transformOriginX={transformOriginX}\n transformOriginY={transformOriginY}\n positionX={positionX}\n positionY={positionY}\n style={menuStyle}\n className=\"ListItem-context-menu\"\n autoClose\n onClose={handleContextMenuClose}\n onCloseAnimationEnd={handleContextMenuHide}\n >\n {contextActions.map((action) => (\n <MenuItem\n key={action.title}\n icon={action.icon}\n destructive={action.destructive}\n disabled={!action.handler}\n onClick={action.handler}\n >\n {action.title}\n </MenuItem>\n ))}\n </Menu>\n )}\n </div>\n );\n};\n\nexport default ListItem;\n","// extracted by mini-css-extract-plugin\nexport default {\"root\":\"GC8g9Q16IaK76g6rcU78\"};","import React from '../../lib/teact/teact';\n\nimport type { FC } from '../../lib/teact/teact';\n\nimport buildClassName from '../../util/buildClassName';\n\nimport styles from './MenuSeparator.module.scss';\n\ntype OwnProps = {\n className?: string;\n};\n\nconst MenuSeparator: FC<OwnProps> = ({ className }) => {\n return (\n <div className={buildClassName(styles.root, className)} />\n );\n};\n\nexport default MenuSeparator;\n","import type { FC } from '../../lib/teact/teact';\nimport React, {\n useCallback,\n useEffect,\n useRef,\n useState,\n} from '../../lib/teact/teact';\n\nimport type { TextPart } from '../../types';\n\nimport { ANIMATION_END_DELAY } from '../../config';\nimport useShowTransition from '../../hooks/useShowTransition';\nimport buildClassName from '../../util/buildClassName';\nimport captureEscKeyListener from '../../util/captureEscKeyListener';\n\nimport Portal from './Portal';\nimport Button from './Button';\n\nimport './Notification.scss';\n\ntype OwnProps = {\n title?: TextPart[];\n containerId?: string;\n message: TextPart[];\n duration?: number;\n onDismiss: () => void;\n action?: VoidFunction;\n actionText?: string;\n className?: string;\n};\n\nconst DEFAULT_DURATION = 3000;\nconst ANIMATION_DURATION = 150;\n\nconst Notification: FC<OwnProps> = ({\n title, className,\n message, duration = DEFAULT_DURATION, containerId, onDismiss,\n action, actionText,\n}) => {\n const [isOpen, setIsOpen] = useState(true);\n // eslint-disable-next-line no-null/no-null\n const timerRef = useRef<number | undefined>(null);\n const { transitionClassNames } = useShowTransition(isOpen);\n\n const closeAndDismiss = useCallback(() => {\n setIsOpen(false);\n setTimeout(onDismiss, ANIMATION_DURATION + ANIMATION_END_DELAY);\n }, [onDismiss]);\n\n function handleClick() {\n action?.();\n closeAndDismiss();\n }\n\n useEffect(() => (isOpen ? captureEscKeyListener(closeAndDismiss) : undefined), [isOpen, closeAndDismiss]);\n\n useEffect(() => {\n timerRef.current = window.setTimeout(closeAndDismiss, duration);\n\n return () => {\n if (timerRef.current) {\n clearTimeout(timerRef.current);\n timerRef.current = undefined;\n }\n };\n }, [duration, closeAndDismiss]);\n\n const handleMouseEnter = useCallback(() => {\n if (timerRef.current) {\n clearTimeout(timerRef.current);\n timerRef.current = undefined;\n }\n }, []);\n\n const handleMouseLeave = useCallback(() => {\n timerRef.current = window.setTimeout(closeAndDismiss, duration);\n }, [duration, closeAndDismiss]);\n\n return (\n <Portal className=\"Notification-container\" containerId={containerId}>\n <div\n className={buildClassName('Notification', transitionClassNames, className)}\n onClick={handleClick}\n onMouseEnter={handleMouseEnter}\n onMouseLeave={handleMouseLeave}\n >\n <div className=\"content\">\n {title && <div className=\"notification-title\">{title}</div>}\n {message}\n </div>\n {action && actionText && (\n <Button\n color=\"translucent-white\"\n onClick={action}\n className=\"Notification-button\"\n >\n {actionText}\n </Button>\n )}\n </div>\n </Portal>\n );\n};\n\nexport default Notification;\n","import type { FC } from '../../lib/teact/teact';\nimport React, { useEffect, useRef, memo } from '../../lib/teact/teact';\n\nimport buildClassName from '../../util/buildClassName';\n\nimport './ProgressSpinner.scss';\n\nconst RADIUSES = {\n s: 22, m: 25, l: 28, xl: 20,\n};\nconst STROKE_WIDTH = 2;\nconst MIN_PROGRESS = 0.05;\nconst MAX_PROGRESS = 1;\n\nconst ProgressSpinner: FC<{\n progress?: number;\n size?: 's' | 'm' | 'l' | 'xl';\n square?: boolean;\n transparent?: boolean;\n noCross?: boolean;\n onClick?: (e: React.MouseEvent<HTMLElement, MouseEvent>) => void;\n}> = ({\n progress = 0,\n size = 'l',\n square,\n transparent,\n noCross,\n onClick,\n}) => {\n const radius = RADIUSES[size];\n const circleRadius = radius - STROKE_WIDTH * 2;\n const borderRadius = radius - 1;\n const circumference = circleRadius * 2 * Math.PI;\n // eslint-disable-next-line no-null/no-null\n const container = useRef<HTMLDivElement>(null);\n\n useEffect(() => {\n if (!container.current) {\n return;\n }\n\n const svg = container.current.firstElementChild;\n const strokeDashOffset = circumference - Math.min(Math.max(MIN_PROGRESS, progress), MAX_PROGRESS) * circumference;\n\n if (!svg) {\n container.current.innerHTML = `<svg\n viewBox=\"0 0 ${borderRadius * 2} ${borderRadius * 2}\"\n height=\"${borderRadius * 2}\"\n width=\"${borderRadius * 2}\"\n >\n <circle\n stroke=\"white\"\n fill=\"transparent\"\n stroke-width=${STROKE_WIDTH}\n stroke-dasharray=\"${circumference} ${circumference}\"}\n stroke-dashoffset=\"${strokeDashOffset}\"\n stroke-linecap=\"round\"\n r=${circleRadius}\n cx=${borderRadius}\n cy=${borderRadius}\n />\n </svg>`;\n } else {\n (svg.firstElementChild as SVGElement).setAttribute('stroke-dashoffset', strokeDashOffset.toString());\n }\n }, [container, circumference, borderRadius, circleRadius, progress]);\n\n const className = buildClassName(\n `ProgressSpinner size-${size}`,\n transparent && 'transparent',\n square && 'square',\n noCross && 'no-cross',\n );\n\n return (\n <div\n ref={container}\n className={className}\n onClick={onClick}\n />\n );\n};\n\nexport default memo(ProgressSpinner);\n","import type { ChangeEvent } from 'react';\nimport type { FC, TeactNode } from '../../lib/teact/teact';\nimport React, { memo } from '../../lib/teact/teact';\n\nimport buildClassName from '../../util/buildClassName';\nimport useLang from '../../hooks/useLang';\n\nimport Spinner from './Spinner';\n\nimport './Radio.scss';\n\ntype OwnProps = {\n id?: string;\n name: string;\n label: TeactNode;\n subLabel?: string;\n value: string;\n checked: boolean;\n disabled?: boolean;\n hidden?: boolean;\n isLoading?: boolean;\n onChange: (e: ChangeEvent<HTMLInputElement>) => void;\n};\n\nconst Radio: FC<OwnProps> = ({\n id,\n label,\n subLabel,\n value,\n name,\n checked,\n disabled,\n hidden,\n isLoading,\n onChange,\n}) => {\n const lang = useLang();\n const className = buildClassName(\n 'Radio',\n disabled && 'disabled',\n hidden && 'hidden-widget',\n isLoading && 'loading',\n );\n\n return (\n <label className={className} dir={lang.isRtl ? 'rtl' : undefined}>\n <input\n type=\"radio\"\n name={name}\n value={value}\n id={id}\n checked={checked}\n onChange={onChange}\n disabled={disabled || hidden}\n />\n <div className=\"Radio-main\">\n <span className=\"label\" dir={lang.isRtl ? 'auto' : undefined}>{label}</span>\n {subLabel && <span className=\"subLabel\" dir={lang.isRtl ? 'auto' : undefined}>{subLabel}</span>}\n </div>\n {isLoading && <Spinner />}\n </label>\n );\n};\n\nexport default memo(Radio);\n","import type { ChangeEvent } from 'react';\nimport type { FC, TeactNode } from '../../lib/teact/teact';\nimport React, { useCallback, memo } from '../../lib/teact/teact';\n\nimport Radio from './Radio';\n\nexport type IRadioOption = {\n label: TeactNode;\n subLabel?: string;\n value: string;\n hidden?: boolean;\n};\n\ntype OwnProps = {\n id?: string;\n name: string;\n options: IRadioOption[];\n selected?: string;\n disabled?: boolean;\n loadingOption?: string;\n onChange: (value: string, event: ChangeEvent<HTMLInputElement>) => void;\n};\n\nconst RadioGroup: FC<OwnProps> = ({\n id,\n name,\n options,\n selected,\n disabled,\n loadingOption,\n onChange,\n}) => {\n const handleChange = useCallback((event: ChangeEvent<HTMLInputElement>) => {\n const { value } = event.currentTarget;\n onChange(value, event);\n }, [onChange]);\n\n return (\n <div id={id} className=\"radio-group\">\n {options.map((option) => (\n <Radio\n name={name}\n label={option.label}\n subLabel={option.subLabel}\n value={option.value}\n checked={option.value === selected}\n hidden={option.hidden}\n disabled={disabled}\n isLoading={loadingOption ? loadingOption === option.value : undefined}\n onChange={handleChange}\n />\n ))}\n </div>\n );\n};\n\nexport default memo(RadioGroup);\n","import type { ChangeEvent } from 'react';\nimport type { FC } from '../../lib/teact/teact';\nimport React, { useCallback, useMemo, memo } from '../../lib/teact/teact';\n\nimport buildClassName from '../../util/buildClassName';\nimport useLang from '../../hooks/useLang';\n\nimport './RangeSlider.scss';\n\ntype OwnProps = {\n options?: string[];\n min?: number;\n max?: number;\n step?: number;\n label?: string;\n value: number;\n disabled?: boolean;\n bold?: boolean;\n className?: string;\n renderValue?: (value: number) => string;\n onChange: (value: number) => void;\n};\n\nconst RangeSlider: FC<OwnProps> = ({\n options,\n min = 0,\n max = options ? options.length - 1 : 100,\n step = 1,\n label,\n value,\n disabled,\n bold,\n className,\n renderValue,\n onChange,\n}) => {\n const lang = useLang();\n const handleChange = useCallback((event: ChangeEvent<HTMLInputElement>) => {\n onChange(Number(event.currentTarget.value));\n }, [onChange]);\n\n const mainClassName = buildClassName(\n className,\n 'RangeSlider',\n disabled && 'disabled',\n bold && 'bold',\n );\n\n const trackWidth = useMemo(() => {\n if (options) {\n return (value / (options.length - 1)) * 100;\n } else {\n const possibleValuesLength = (max - min) / step;\n return ((value - min) / possibleValuesLength) * 100;\n }\n }, [options, value, max, min, step]);\n\n return (\n <div className={mainClassName}>\n {label && (\n <div className=\"slider-top-row\" dir={lang.isRtl ? 'rtl' : undefined}>\n <span className=\"label\" dir=\"auto\">{label}</span>\n {!options && (\n <span className=\"value\" dir=\"auto\">{renderValue ? renderValue(value) : value}</span>\n )}\n </div>\n )}\n <div className=\"slider-main\">\n <div\n className=\"slider-fill-track\"\n style={`width: ${trackWidth}%`}\n />\n <input\n min={min}\n max={max}\n value={value}\n step={step}\n type=\"range\"\n className=\"RangeSlider__input\"\n onChange={handleChange}\n />\n {options && (\n <div className=\"slider-options\">\n {options.map((option, index) => (\n <div\n className={buildClassName('slider-option no-selection', index === value && 'active')}\n onClick={() => onChange(index)}\n >\n {option}\n </div>\n ))}\n </div>\n )}\n </div>\n </div>\n );\n};\n\nexport default memo(RangeSlider);\n","import type { RefObject } from 'react';\nimport type { FC } from '../../lib/teact/teact';\nimport React, {\n useRef, useEffect, memo, useCallback,\n} from '../../lib/teact/teact';\n\nimport buildClassName from '../../util/buildClassName';\nimport useFlag from '../../hooks/useFlag';\nimport useLang from '../../hooks/useLang';\nimport useInputFocusOnOpen from '../../hooks/useInputFocusOnOpen';\n\nimport Loading from './Loading';\nimport Button from './Button';\nimport ShowTransition from './ShowTransition';\n\nimport './SearchInput.scss';\n\ntype OwnProps = {\n ref?: RefObject<HTMLInputElement>;\n children?: React.ReactNode;\n parentContainerClassName?: string;\n className?: string;\n inputId?: string;\n value?: string;\n focused?: boolean;\n isLoading?: boolean;\n spinnerColor?: 'yellow';\n spinnerBackgroundColor?: 'light';\n placeholder?: string;\n disabled?: boolean;\n autoComplete?: string;\n canClose?: boolean;\n autoFocusSearch?: boolean;\n onChange: (value: string) => void;\n onReset?: NoneToVoidFunction;\n onFocus?: NoneToVoidFunction;\n onBlur?: NoneToVoidFunction;\n onSpinnerClick?: NoneToVoidFunction;\n};\n\nconst SearchInput: FC<OwnProps> = ({\n ref,\n children,\n parentContainerClassName,\n value,\n inputId,\n className,\n focused,\n isLoading,\n spinnerColor,\n spinnerBackgroundColor,\n placeholder,\n disabled,\n autoComplete,\n canClose,\n autoFocusSearch,\n onChange,\n onReset,\n onFocus,\n onBlur,\n onSpinnerClick,\n}) => {\n // eslint-disable-next-line no-null/no-null\n let inputRef = useRef<HTMLInputElement>(null);\n if (ref) {\n inputRef = ref;\n }\n\n const [isInputFocused, markInputFocused, unmarkInputFocused] = useFlag(focused);\n\n useInputFocusOnOpen(inputRef, autoFocusSearch, unmarkInputFocused);\n\n useEffect(() => {\n if (!inputRef.current) {\n return;\n }\n\n if (focused) {\n inputRef.current.focus();\n } else {\n inputRef.current.blur();\n }\n }, [focused, placeholder]); // Trick for setting focus when selecting a contact to search for\n\n const lang = useLang();\n\n function handleChange(event: React.ChangeEvent<HTMLInputElement>) {\n const { currentTarget } = event;\n onChange(currentTarget.value);\n }\n\n function handleFocus() {\n markInputFocused();\n if (onFocus) {\n onFocus();\n }\n }\n\n function handleBlur() {\n unmarkInputFocused();\n if (onBlur) {\n onBlur();\n }\n }\n\n const handleKeyDown = useCallback((e: React.KeyboardEvent) => {\n if (e.key === 'ArrowDown' || e.key === 'Enter') {\n const element = document.querySelector(`.${parentContainerClassName} .ListItem-button`) as HTMLElement;\n if (element) {\n element.focus();\n }\n }\n }, [parentContainerClassName]);\n\n return (\n <div\n className={buildClassName('SearchInput', className, isInputFocused && 'has-focus')}\n dir={lang.isRtl ? 'rtl' : undefined}\n >\n {children}\n <input\n ref={inputRef}\n id={inputId}\n type=\"text\"\n dir=\"auto\"\n placeholder={placeholder || lang('Search')}\n className=\"form-control\"\n value={value}\n disabled={disabled}\n autoComplete={autoComplete}\n onChange={handleChange}\n onFocus={handleFocus}\n onBlur={handleBlur}\n onKeyDown={handleKeyDown}\n />\n <i className=\"icon-search\" />\n <ShowTransition isOpen={Boolean(isLoading)} className=\"slow\">\n <Loading color={spinnerColor} backgroundColor={spinnerBackgroundColor} onClick={onSpinnerClick} />\n </ShowTransition>\n {!isLoading && (value || canClose) && onReset && (\n <Button\n round\n size=\"tiny\"\n color=\"translucent\"\n onClick={onReset}\n >\n <span className=\"icon-close\" />\n </Button>\n )}\n </div>\n );\n};\n\nexport default memo(SearchInput);\n","import type { FC } from '../../lib/teact/teact';\nimport React, { useRef } from '../../lib/teact/teact';\n\nimport useShowTransition from '../../hooks/useShowTransition';\nimport usePrevious from '../../hooks/usePrevious';\nimport buildClassName from '../../util/buildClassName';\n\ntype OwnProps = {\n isOpen: boolean;\n isCustom?: boolean;\n id?: string;\n className?: string;\n onClick?: (e: React.MouseEvent<HTMLElement, MouseEvent>) => void;\n children: React.ReactNode;\n};\n\nconst ShowTransition: FC<OwnProps> = ({\n isOpen, isCustom, id, className, onClick, children,\n}) => {\n const { shouldRender, transitionClassNames } = useShowTransition(\n isOpen, undefined, undefined, isCustom ? false : undefined,\n );\n const prevIsOpen = usePrevious(isOpen);\n const prevChildren = usePrevious(children);\n const fromChildrenRef = useRef<React.ReactNode>();\n\n if (prevIsOpen && !isOpen) {\n fromChildrenRef.current = prevChildren;\n }\n\n return (\n shouldRender && (\n <div id={id} className={buildClassName(className, transitionClassNames)} onClick={onClick}>\n {isOpen ? children : fromChildrenRef.current!}\n </div>\n )\n );\n};\n\nexport default ShowTransition;\n","import type { FC } from '../../lib/teact/teact';\nimport React from '../../lib/teact/teact';\n\nimport buildClassName from '../../util/buildClassName';\nimport buildStyle from '../../util/buildStyle';\n\nimport './Skeleton.scss';\n\ntype OwnProps = {\n variant?: 'rectangular' | 'rounded-rect' | 'round';\n animation?: 'wave' | 'pulse';\n width?: number;\n height?: number;\n forceAspectRatio?: boolean;\n inline?: boolean;\n className?: string;\n};\n\nconst Skeleton: FC<OwnProps> = ({\n variant = 'rectangular',\n animation = 'wave',\n width,\n height,\n forceAspectRatio,\n inline,\n className,\n}) => {\n const classNames = buildClassName('Skeleton', variant, animation, className, inline && 'inline');\n const aspectRatio = (width && height) ? `aspect-ratio: ${width}/${height}` : undefined;\n const style = forceAspectRatio ? aspectRatio\n : buildStyle(Boolean(width) && `width: ${width}px`, Boolean(height) && `height: ${height}px`);\n return (\n <div className={classNames} style={style}>{inline && '\\u00A0'}</div>\n );\n};\n\nexport default Skeleton;\n","import type { ChangeEvent } from 'react';\nimport type { FC } from '../../lib/teact/teact';\nimport React, { memo, useCallback } from '../../lib/teact/teact';\n\nimport buildClassName from '../../util/buildClassName';\n\nimport './Switcher.scss';\n\ntype OwnProps = {\n id?: string;\n name?: string;\n value?: string;\n label: string;\n checked?: boolean;\n disabled?: boolean;\n inactive?: boolean;\n noAnimation?: boolean;\n onChange?: (e: ChangeEvent<HTMLInputElement>) => void;\n onCheck?: (isChecked: boolean) => void;\n};\n\nconst Switcher: FC<OwnProps> = ({\n id,\n name,\n value,\n label,\n checked = false,\n disabled,\n inactive,\n noAnimation,\n onChange,\n onCheck,\n}) => {\n const handleChange = useCallback((e: ChangeEvent<HTMLInputElement>) => {\n if (onChange) {\n onChange(e);\n }\n\n if (onCheck) {\n onCheck(e.currentTarget.checked);\n }\n }, [onChange, onCheck]);\n\n const className = buildClassName(\n 'Switcher',\n disabled && 'disabled',\n inactive && 'inactive',\n noAnimation && 'no-animation',\n );\n\n return (\n <label className={className} title={label}>\n <input\n type=\"checkbox\"\n id={id}\n name={name}\n value={value}\n checked={checked}\n disabled={disabled}\n onChange={handleChange}\n />\n <span className=\"widget\" />\n </label>\n );\n};\n\nexport default memo(Switcher);\n","import type { FC } from '../../lib/teact/teact';\nimport React, { useRef, memo, useEffect } from '../../lib/teact/teact';\n\nimport buildClassName from '../../util/buildClassName';\nimport forceReflow from '../../util/forceReflow';\nimport renderText from '../common/helpers/renderText';\n\nimport './Tab.scss';\n\ntype OwnProps = {\n className?: string;\n title: string;\n isActive?: boolean;\n isBlocked?: boolean;\n badgeCount?: number;\n isBadgeActive?: boolean;\n previousActiveTab?: number;\n onClick: (arg: number) => void;\n clickArg: number;\n};\n\nconst classNames = {\n active: 'Tab--active',\n badgeActive: 'Tab__badge--active',\n};\n\nconst Tab: FC<OwnProps> = ({\n className,\n title,\n isActive,\n isBlocked,\n badgeCount,\n isBadgeActive,\n previousActiveTab,\n onClick,\n clickArg,\n}) => {\n // eslint-disable-next-line no-null/no-null\n const tabRef = useRef<HTMLDivElement>(null);\n\n useEffect(() => {\n // Set initial active state\n if (isActive && previousActiveTab === undefined && tabRef.current) {\n tabRef.current.classList.add(classNames.active);\n }\n\n if (!isActive || previousActiveTab === undefined) {\n return;\n }\n\n const tabEl = tabRef.current!;\n const prevTabEl = tabEl.parentElement!.children[previousActiveTab];\n if (!prevTabEl) {\n return;\n }\n\n const platformEl = tabEl.querySelector<HTMLElement>('.platform')!;\n const prevPlatformEl = prevTabEl.querySelector<HTMLElement>('.platform')!;\n\n // We move and resize the platform, so it repeats the position and size of the previous one\n const shiftLeft = prevPlatformEl.parentElement!.offsetLeft - platformEl.parentElement!.offsetLeft;\n const scaleFactor = prevPlatformEl.clientWidth / platformEl.clientWidth;\n\n prevPlatformEl.classList.remove('animate');\n platformEl.classList.remove('animate');\n platformEl.style.transform = `translate3d(${shiftLeft}px, 0, 0) scale3d(${scaleFactor}, 1, 1)`;\n forceReflow(platformEl);\n platformEl.classList.add('animate');\n platformEl.style.transform = 'none';\n\n prevTabEl.classList.remove(classNames.active);\n tabEl.classList.add(classNames.active);\n }, [isActive, previousActiveTab]);\n\n return (\n <div\n className={buildClassName('Tab', className)}\n onClick={() => onClick(clickArg)}\n ref={tabRef}\n >\n <span>\n {renderText(title)}\n {Boolean(badgeCount) && (\n <span className={buildClassName('badge', isBadgeActive && classNames.badgeActive)}>{badgeCount}</span>\n )}\n {isBlocked && <i className=\"icon-lock-badge blocked\" />}\n <i className=\"platform\" />\n </span>\n </div>\n );\n};\n\nexport default memo(Tab);\n","import type { FC } from '../../lib/teact/teact';\nimport React, { memo, useRef, useEffect } from '../../lib/teact/teact';\n\nimport { ALL_FOLDER_ID } from '../../config';\nimport { IS_ANDROID, IS_IOS } from '../../util/environment';\nimport fastSmoothScrollHorizontal from '../../util/fastSmoothScrollHorizontal';\n\nimport usePrevious from '../../hooks/usePrevious';\nimport useHorizontalScroll from '../../hooks/useHorizontalScroll';\nimport useLang from '../../hooks/useLang';\n\nimport Tab from './Tab';\n\nimport './TabList.scss';\n\nexport type TabWithProperties = {\n id?: number;\n title: string;\n badgeCount?: number;\n isBlocked?: boolean;\n isBadgeActive?: boolean;\n};\n\ntype OwnProps = {\n tabs: readonly TabWithProperties[];\n areFolders?: boolean;\n activeTab: number;\n big?: boolean;\n onSwitchTab: (index: number) => void;\n};\n\nconst TAB_SCROLL_THRESHOLD_PX = 16;\n// Should match duration from `--slide-transition` CSS variable\nconst SCROLL_DURATION = IS_IOS ? 450 : IS_ANDROID ? 400 : 300;\n\nconst TabList: FC<OwnProps> = ({\n tabs, areFolders, activeTab, big, onSwitchTab,\n}) => {\n // eslint-disable-next-line no-null/no-null\n const containerRef = useRef<HTMLDivElement>(null);\n const previousActiveTab = usePrevious(activeTab);\n\n useHorizontalScroll(containerRef.current, undefined, true);\n\n // Scroll container to place active tab in the center\n useEffect(() => {\n const container = containerRef.current!;\n const { scrollWidth, offsetWidth, scrollLeft } = container;\n if (scrollWidth <= offsetWidth) {\n return;\n }\n\n const activeTabElement = container.childNodes[activeTab] as HTMLElement | null;\n if (!activeTabElement) {\n return;\n }\n\n const { offsetLeft: activeTabOffsetLeft, offsetWidth: activeTabOffsetWidth } = activeTabElement;\n const newLeft = activeTabOffsetLeft - (offsetWidth / 2) + (activeTabOffsetWidth / 2);\n\n // Prevent scrolling by only a couple of pixels, which doesn't look smooth\n if (Math.abs(newLeft - scrollLeft) < TAB_SCROLL_THRESHOLD_PX) {\n return;\n }\n\n fastSmoothScrollHorizontal(container, newLeft, SCROLL_DURATION);\n }, [activeTab]);\n\n const lang = useLang();\n\n return (\n <div\n className={`TabList no-selection no-scrollbar ${big ? 'big' : ''}`}\n ref={containerRef}\n dir={lang.isRtl ? 'rtl' : undefined}\n >\n {tabs.map((tab, i) => (\n <Tab\n key={tab.id ?? tab.title}\n // TODO Remove dependency on usage context\n title={(!areFolders || tab.id === ALL_FOLDER_ID) ? lang(tab.title) : tab.title}\n isActive={i === activeTab}\n isBlocked={tab.isBlocked}\n badgeCount={tab.badgeCount}\n isBadgeActive={tab.isBadgeActive}\n previousActiveTab={previousActiveTab}\n onClick={onSwitchTab}\n clickArg={i}\n />\n ))}\n </div>\n );\n};\n\nexport default memo(TabList);\n","import type { StateReducer, Dispatch } from '../useReducer';\nimport useReducer from '../useReducer';\nimport type { ApiChatFolder } from '../../api/types';\nimport { pick, omit } from '../../util/iteratees';\n\nexport type FolderChatType = {\n icon: string;\n title: string;\n key: keyof Pick<ApiChatFolder, (\n 'contacts' | 'nonContacts' | 'groups' | 'channels' | 'bots' |\n 'excludeMuted' | 'excludeArchived' | 'excludeRead'\n )>;\n};\n\nexport const INCLUDED_CHAT_TYPES: FolderChatType[] = [\n { icon: 'user', title: 'FilterContacts', key: 'contacts' },\n { icon: 'non-contacts', title: 'FilterNonContacts', key: 'nonContacts' },\n { icon: 'group', title: 'FilterGroups', key: 'groups' },\n { icon: 'channel', title: 'FilterChannels', key: 'channels' },\n { icon: 'bots', title: 'FilterBots', key: 'bots' },\n];\n\nexport const EXCLUDED_CHAT_TYPES: FolderChatType[] = [\n { icon: 'mute', title: 'FilterMuted', key: 'excludeMuted' },\n { icon: 'archive', title: 'FilterArchived', key: 'excludeArchived' },\n { icon: 'readchats', title: 'FilterRead', key: 'excludeRead' },\n];\n\nconst INCLUDE_FILTER_FIELDS: Array<keyof FolderIncludeFilters> = [\n 'includedChatIds', 'bots', 'channels', 'groups', 'contacts', 'nonContacts',\n];\nconst EXCLUDE_FILTER_FIELDS: Array<keyof FolderExcludeFilters> = [\n 'excludedChatIds', 'excludeArchived', 'excludeMuted', 'excludeRead',\n];\n\nexport function selectChatFilters(state: FoldersState, mode: 'included' | 'excluded', selectTemp?: boolean) {\n let selectedChatIds: string[] = [];\n let selectedChatTypes: FolderChatType['key'][] = [];\n\n if (mode === 'included') {\n const {\n includedChatIds,\n ...includeFilters\n } = selectTemp\n ? state.includeFilters || {}\n : pick(\n state.folder,\n INCLUDE_FILTER_FIELDS,\n );\n\n selectedChatIds = includedChatIds || [];\n selectedChatTypes = (Object.keys(includeFilters) as Array<keyof typeof includeFilters>)\n .filter((key) => Boolean(includeFilters[key]));\n } else {\n const {\n excludedChatIds,\n ...excludeFilters\n } = selectTemp\n ? state.excludeFilters || {}\n : pick(\n state.folder,\n EXCLUDE_FILTER_FIELDS,\n );\n\n selectedChatIds = excludedChatIds || [];\n selectedChatTypes = (Object.keys(excludeFilters) as Array<keyof typeof excludeFilters>)\n .filter((key) => Boolean(excludeFilters[key]));\n }\n\n return {\n selectedChatIds,\n selectedChatTypes,\n };\n}\n\nfunction getSuggestedFolderName(includeFilters?: FolderIncludeFilters) {\n if (includeFilters) {\n const {\n includedChatIds,\n ...filters\n } = includeFilters;\n\n if (\n Object.values(filters).filter(Boolean).length > 1\n || (includedChatIds?.length)\n ) {\n return '';\n }\n\n if (filters.bots) {\n return 'Bots';\n } else if (filters.groups) {\n return 'Groups';\n } else if (filters.channels) {\n return 'Channels';\n } else if (filters.contacts) {\n return 'Contacts';\n } else if (filters.nonContacts) {\n return 'Non-Contacts';\n }\n }\n\n return '';\n}\n\ntype FolderIncludeFilters = Pick<ApiChatFolder, (\n 'includedChatIds' | 'bots' | 'channels' | 'groups' | 'contacts' | 'nonContacts'\n)>;\ntype FolderExcludeFilters = Pick<ApiChatFolder, 'excludedChatIds' | 'excludeArchived' | 'excludeMuted' | 'excludeRead'>;\n\nexport type FoldersState = {\n mode: 'create' | 'edit';\n isLoading?: boolean;\n isTouched?: boolean;\n error?: string;\n folderId?: number;\n chatFilter: string;\n folder: Omit<ApiChatFolder, 'id' | 'description' | 'emoticon'>;\n includeFilters?: FolderIncludeFilters;\n excludeFilters?: FolderExcludeFilters;\n};\nexport type FoldersActions = (\n 'setTitle' | 'saveFilters' | 'editFolder' | 'reset' | 'setChatFilter' | 'setIsLoading' | 'setError' |\n 'editIncludeFilters' | 'editExcludeFilters' | 'setIncludeFilters' | 'setExcludeFilters'\n);\nexport type FolderEditDispatch = Dispatch<FoldersActions>;\n\nconst INITIAL_STATE: FoldersState = {\n mode: 'create',\n chatFilter: '',\n folder: {\n title: '',\n includedChatIds: [],\n excludedChatIds: [],\n },\n};\n\nconst foldersReducer: StateReducer<FoldersState, FoldersActions> = (\n state,\n action,\n) => {\n switch (action.type) {\n case 'setTitle':\n return {\n ...state,\n folder: {\n ...state.folder,\n title: action.payload,\n },\n isTouched: true,\n };\n case 'editIncludeFilters':\n return {\n ...state,\n includeFilters: pick(\n state.folder,\n INCLUDE_FILTER_FIELDS,\n ),\n };\n case 'editExcludeFilters':\n return {\n ...state,\n excludeFilters: pick(\n state.folder,\n EXCLUDE_FILTER_FIELDS,\n ),\n };\n case 'setIncludeFilters':\n return {\n ...state,\n includeFilters: action.payload,\n chatFilter: '',\n };\n case 'setExcludeFilters':\n return {\n ...state,\n excludeFilters: action.payload,\n chatFilter: '',\n };\n case 'saveFilters':\n if (state.includeFilters) {\n return {\n ...state,\n folder: {\n ...omit(state.folder, INCLUDE_FILTER_FIELDS),\n title: state.folder.title ? state.folder.title : getSuggestedFolderName(state.includeFilters),\n ...state.includeFilters,\n },\n includeFilters: undefined,\n chatFilter: '',\n isTouched: true,\n };\n } else if (state.excludeFilters) {\n return {\n ...state,\n folder: {\n ...omit(state.folder, EXCLUDE_FILTER_FIELDS),\n ...state.excludeFilters,\n },\n excludeFilters: undefined,\n chatFilter: '',\n isTouched: true,\n };\n } else {\n return state;\n }\n case 'editFolder': {\n const { id: folderId, description, ...folder } = action.payload;\n\n return {\n mode: 'edit',\n folderId,\n folder,\n chatFilter: '',\n };\n }\n case 'setChatFilter': {\n return {\n ...state,\n chatFilter: action.payload,\n };\n }\n case 'setIsLoading': {\n return {\n ...state,\n isLoading: action.payload,\n };\n }\n case 'setError': {\n return {\n ...state,\n error: action.payload,\n };\n }\n case 'reset':\n return INITIAL_STATE;\n default:\n return state;\n }\n};\n\nconst useFoldersReducer = () => {\n return useReducer(foldersReducer, INITIAL_STATE);\n};\n\nexport default useFoldersReducer;\n","import {\n useCallback, useEffect, useRef, useState,\n} from '../lib/teact/teact';\nimport { getActions, getGlobal } from '../global';\n\nimport { PLAYBACK_RATE_FOR_AUDIO_MIN_DURATION } from '../config';\nimport type { Track, TrackId } from '../util/audioPlayer';\nimport { register } from '../util/audioPlayer';\nimport { isSafariPatchInProgress } from '../util/patchSafariProgressiveAudio';\nimport type { MediaSessionHandlers } from '../util/mediaSession';\nimport {\n registerMediaSession, setPlaybackState, setPositionState, updateMetadata,\n} from '../util/mediaSession';\n\nimport useEffectWithPrevDeps from './useEffectWithPrevDeps';\nimport useOnChange from './useOnChange';\n\ntype Handler = (e: Event) => void;\n\nconst DEFAULT_SKIP_TIME = 10;\n\nconst useAudioPlayer = (\n trackId: TrackId,\n originalDuration: number, // Sometimes incorrect for voice messages\n trackType: Track['type'],\n src?: string,\n handlers?: Record<string, Handler>,\n metadata?: MediaMetadata,\n onInit?: (element: HTMLAudioElement) => void,\n shouldPlay = false,\n onForcePlay?: NoneToVoidFunction,\n onTrackChange?: NoneToVoidFunction,\n noPlaylist = false,\n noProgressUpdates = false,\n) => {\n // eslint-disable-next-line no-null/no-null\n const controllerRef = useRef<ReturnType<typeof register>>(null);\n\n const [isPlaying, setIsPlaying] = useState(false);\n let isPlayingSync = isPlaying;\n\n const [playProgress, setPlayProgress] = useState<number>(0);\n\n const handleTrackChange = useCallback(() => {\n setIsPlaying(false);\n if (onTrackChange) onTrackChange();\n }, [onTrackChange]);\n\n useOnChange(() => {\n controllerRef.current = register(trackId, trackType, (eventName, e) => {\n switch (eventName) {\n case 'onPlay': {\n const {\n setVolume, setPlaybackRate, toggleMuted, proxy,\n } = controllerRef.current!;\n setIsPlaying(true);\n\n registerMediaSession(metadata, makeMediaHandlers(controllerRef));\n setPlaybackState('playing');\n setVolume(getGlobal().audioPlayer.volume);\n toggleMuted(Boolean(getGlobal().audioPlayer.isMuted));\n const duration = proxy.duration && Number.isFinite(proxy.duration) ? proxy.duration : originalDuration;\n if (trackType === 'voice' || duration > PLAYBACK_RATE_FOR_AUDIO_MIN_DURATION) {\n setPlaybackRate(getGlobal().audioPlayer.playbackRate);\n }\n\n setPositionState({\n duration: proxy.duration || 0,\n playbackRate: proxy.playbackRate,\n position: proxy.currentTime,\n });\n break;\n }\n case 'onRateChange': {\n const { proxy } = controllerRef.current!;\n setPositionState({\n duration: proxy.duration || 0,\n playbackRate: proxy.playbackRate,\n position: proxy.currentTime,\n });\n break;\n }\n case 'onPause':\n setIsPlaying(false);\n setPlaybackState('paused');\n break;\n case 'onTimeUpdate': {\n const { proxy } = controllerRef.current!;\n const duration = proxy.duration && Number.isFinite(proxy.duration) ? proxy.duration : originalDuration;\n if (!noProgressUpdates) setPlayProgress(proxy.currentTime / duration);\n break;\n }\n case 'onEnded': {\n setPlaybackState('paused');\n break;\n }\n }\n\n handlers?.[eventName]?.(e);\n }, onForcePlay, handleTrackChange);\n\n const { proxy } = controllerRef.current!;\n\n if (!isPlaying && !proxy.paused) {\n setIsPlaying(true);\n isPlayingSync = true;\n }\n\n if (onInit) {\n onInit(proxy);\n }\n }, [trackId]);\n\n useEffect(() => {\n if (isPlaying && metadata) updateMetadata(metadata);\n }, [metadata, isPlaying]);\n\n const {\n play,\n pause,\n setCurrentTime,\n proxy,\n destroy,\n setVolume,\n stop,\n isFirst,\n isLast,\n requestNextTrack,\n requestPreviousTrack,\n setPlaybackRate,\n toggleMuted,\n } = controllerRef.current!;\n const duration = proxy.duration && Number.isFinite(proxy.duration) ? proxy.duration : originalDuration;\n\n // RAF progress\n useEffect(() => {\n if (duration && !isSafariPatchInProgress(proxy) && !noProgressUpdates) {\n setPlayProgress(proxy.currentTime / duration);\n }\n }, [duration, playProgress, proxy, noProgressUpdates]);\n\n // Cleanup\n useEffect(() => () => {\n destroy(noPlaylist);\n }, [destroy, noPlaylist]);\n\n // Autoplay once `src` is present\n useEffectWithPrevDeps(([prevShouldPlay, prevSrc]) => {\n if (prevShouldPlay === shouldPlay && src === prevSrc) {\n return;\n }\n\n // When paused by another player\n if (proxy.src && proxy.paused) {\n return;\n }\n\n if (shouldPlay && src && !isPlaying) {\n play(src);\n }\n }, [shouldPlay, src, isPlaying, play, proxy.src, proxy.paused]);\n\n const playIfPresent = useCallback(() => {\n if (src) {\n play(src);\n }\n }, [src, play]);\n\n const playPause = useCallback(() => {\n if (isPlaying) {\n pause();\n } else {\n playIfPresent();\n }\n }, [pause, playIfPresent, isPlaying]);\n\n const setTime = useCallback((time: number) => {\n setCurrentTime(time);\n if (duration) {\n setPlayProgress(proxy.currentTime / duration);\n }\n }, [duration, proxy, setCurrentTime]);\n\n return {\n isPlaying: isPlayingSync,\n playProgress,\n playPause,\n pause,\n play: playIfPresent,\n stop,\n setCurrentTime: setTime,\n setVolume,\n audioProxy: proxy,\n duration,\n requestNextTrack,\n requestPreviousTrack,\n isFirst,\n isLast,\n setPlaybackRate,\n toggleMuted,\n };\n};\n\nfunction makeMediaHandlers(controllerRef: React.RefObject<ReturnType<typeof register>>) {\n let mediaHandlers: MediaSessionHandlers = {};\n if (controllerRef && controllerRef.current) {\n const {\n play, pause, setCurrentTime, proxy, requestNextTrack, requestPreviousTrack, isFirst, isLast,\n } = controllerRef.current;\n mediaHandlers = {\n play: () => {\n play(proxy.src);\n },\n pause: () => {\n pause();\n },\n stop: () => {\n pause();\n setCurrentTime(0);\n getActions().closeAudioPlayer();\n },\n seekbackward: (event) => {\n const skipTime = event.seekOffset || DEFAULT_SKIP_TIME;\n setCurrentTime(Math.max(proxy.currentTime - skipTime, 0));\n },\n seekforward: (event) => {\n const skipTime = event.seekOffset || DEFAULT_SKIP_TIME;\n setCurrentTime(Math.min(proxy.currentTime + skipTime, proxy.duration));\n },\n seekTo: (event) => {\n if (event.seekTime) {\n setCurrentTime(event.seekTime);\n }\n },\n };\n\n if (!isLast()) {\n mediaHandlers.nexttrack = () => {\n requestNextTrack();\n };\n }\n if (!isFirst()) {\n mediaHandlers.previoustrack = () => {\n requestPreviousTrack();\n };\n }\n }\n return mediaHandlers;\n}\n\nexport default useAudioPlayer;\n","import type React from '../lib/teact/teact';\nimport { useCallback, useMemo, useState } from '../lib/teact/teact';\nimport { debounce } from '../util/schedulers';\nimport { isSafariPatchInProgress } from '../util/patchSafariProgressiveAudio';\n\ntype BufferingEvent = (e: Event | React.SyntheticEvent<HTMLMediaElement>) => void;\n\nconst MIN_READY_STATE = 3;\n// Avoid flickering when re-mounting previously buffered video\nconst DEBOUNCE = 200;\n\n/**\n * Time range relative to the duration [0, 1]\n */\nexport type BufferedRange = { start: number; end: number };\n\nconst useBuffering = (noInitiallyBuffered = false) => {\n const [isBuffered, setIsBuffered] = useState(!noInitiallyBuffered);\n const [bufferedProgress, setBufferedProgress] = useState(0);\n const [bufferedRanges, setBufferedRanges] = useState<BufferedRange[]>([]);\n\n const setIsBufferedDebounced = useMemo(() => {\n return debounce(setIsBuffered, DEBOUNCE, false, true);\n }, []);\n\n const handleBuffering = useCallback<BufferingEvent>((e) => {\n const media = e.currentTarget as HTMLMediaElement;\n\n if (!isSafariPatchInProgress(media)) {\n if (media.buffered.length) {\n const ranges = getTimeRanges(media.buffered, media.duration);\n setBufferedRanges(ranges);\n const bufferedLength = ranges.reduce((acc, { start, end }) => acc + end - start, 0);\n setBufferedProgress(bufferedLength / media.duration);\n }\n\n setIsBufferedDebounced(media.readyState >= MIN_READY_STATE || media.currentTime > 0);\n }\n }, [setIsBufferedDebounced]);\n\n const bufferingHandlers = {\n onLoadedData: handleBuffering,\n onPlaying: handleBuffering,\n onLoadStart: handleBuffering, // Needed for Safari to start\n onPause: handleBuffering, // Needed for Chrome when seeking\n onTimeUpdate: handleBuffering, // Needed for audio buffering progress\n onProgress: handleBuffering, // Needed for video buffering progress\n };\n\n return {\n isBuffered,\n bufferedProgress,\n bufferedRanges,\n bufferingHandlers,\n checkBuffering(element: HTMLMediaElement) {\n setIsBufferedDebounced(element.readyState >= MIN_READY_STATE);\n },\n };\n};\n\nfunction getTimeRanges(ranges: TimeRanges, duration: number) {\n const result: BufferedRange[] = [];\n for (let i = 0; i < ranges.length; i++) {\n result.push({\n start: ranges.start(i) / duration,\n end: ranges.end(i) / duration,\n });\n }\n return result;\n}\n\nexport default useBuffering;\n","import { useEffect, useRef } from '../lib/teact/teact';\n\nimport fastBlur from '../lib/fastBlur';\nimport useForceUpdate from './useForceUpdate';\nimport { IS_CANVAS_FILTER_SUPPORTED } from '../util/environment';\n\nconst RADIUS = 2;\nconst ITERATIONS = 2;\n\nexport default function useCanvasBlur(dataUri?: string, isDisabled = false, withRaf?: boolean) {\n // eslint-disable-next-line no-null/no-null\n const canvasRef = useRef<HTMLCanvasElement>(null);\n const forceUpdate = useForceUpdate();\n\n useEffect(() => {\n const canvas = canvasRef.current;\n\n if (!dataUri || !canvas || isDisabled) {\n return;\n }\n\n const img = new Image();\n\n const processBlur = () => {\n canvas.width = img.width;\n canvas.height = img.height;\n\n const ctx = canvas.getContext('2d', { alpha: false })!;\n\n if (IS_CANVAS_FILTER_SUPPORTED) {\n ctx.filter = `blur(${RADIUS}px)`;\n }\n\n ctx.drawImage(img, -RADIUS * 2, -RADIUS * 2, canvas.width + RADIUS * 4, canvas.height + RADIUS * 4);\n\n if (!IS_CANVAS_FILTER_SUPPORTED) {\n fastBlur(ctx, 0, 0, canvas.width, canvas.height, RADIUS, ITERATIONS);\n }\n };\n\n img.onload = () => {\n if (withRaf) {\n requestAnimationFrame(processBlur);\n } else {\n processBlur();\n }\n };\n\n img.src = dataUri;\n }, [canvasRef, dataUri, forceUpdate, isDisabled, withRaf]);\n\n return canvasRef;\n}\n","import { useMemo } from '../lib/teact/teact';\nimport { getActions } from '../global';\n\nimport type { ApiChat, ApiUser } from '../api/types';\n\nimport { SERVICE_NOTIFICATIONS_USER_ID } from '../config';\nimport {\n isChatArchived, getCanDeleteChat, isUserId, isChatChannel, isChatGroup,\n} from '../global/helpers';\nimport { compact } from '../util/iteratees';\nimport useLang from './useLang';\n\nconst useChatContextActions = ({\n chat,\n user,\n folderId,\n isPinned,\n isMuted,\n canChangeFolder,\n handleDelete,\n handleChatFolderChange,\n handleReport,\n}: {\n chat: ApiChat | undefined;\n user: ApiUser | undefined;\n folderId?: number;\n isPinned?: boolean;\n isMuted?: boolean;\n canChangeFolder?: boolean;\n handleDelete: () => void;\n handleChatFolderChange: () => void;\n handleReport?: () => void;\n}, isInSearch = false) => {\n const lang = useLang();\n\n const { isSelf } = user || {};\n const isServiceNotifications = user?.id === SERVICE_NOTIFICATIONS_USER_ID;\n\n return useMemo(() => {\n if (!chat) {\n return undefined;\n }\n\n const {\n toggleChatPinned,\n updateChatMutedState,\n toggleChatArchived,\n toggleChatUnread,\n } = getActions();\n\n const actionAddToFolder = canChangeFolder ? {\n title: lang('ChatList.Filter.AddToFolder'),\n icon: 'folder',\n handler: handleChatFolderChange,\n } : undefined;\n\n const actionPin = isPinned\n ? {\n title: lang('UnpinFromTop'),\n icon: 'unpin',\n handler: () => toggleChatPinned({ id: chat.id, folderId }),\n }\n : { title: lang('PinToTop'), icon: 'pin', handler: () => toggleChatPinned({ id: chat.id, folderId }) };\n\n if (isInSearch) {\n return compact([actionPin, actionAddToFolder]);\n }\n\n const actionUnreadMark = chat.unreadCount || chat.hasUnreadMark\n ? { title: lang('MarkAsRead'), icon: 'readchats', handler: () => toggleChatUnread({ id: chat.id }) }\n : { title: lang('MarkAsUnread'), icon: 'unread', handler: () => toggleChatUnread({ id: chat.id }) };\n\n const actionMute = isMuted\n ? {\n title: lang('ChatList.Unmute'),\n icon: 'unmute',\n handler: () => updateChatMutedState({ chatId: chat.id, isMuted: false }),\n }\n : {\n title: lang('ChatList.Mute'),\n icon: 'mute',\n handler: () => updateChatMutedState({ chatId: chat.id, isMuted: true }),\n };\n\n const actionArchive = isChatArchived(chat)\n ? { title: lang('Unarchive'), icon: 'unarchive', handler: () => toggleChatArchived({ id: chat.id }) }\n : { title: lang('Archive'), icon: 'archive', handler: () => toggleChatArchived({ id: chat.id }) };\n\n const canReport = handleReport && (isChatChannel(chat) || isChatGroup(chat) || (user && !user.isSelf));\n const actionReport = canReport\n ? { title: lang('ReportPeer.Report'), icon: 'flag', handler: handleReport }\n : undefined;\n\n const actionDelete = {\n title: isUserId(chat.id)\n ? lang('Delete')\n : lang(getCanDeleteChat(chat)\n ? 'DeleteChat'\n : (isChatChannel(chat) ? 'LeaveChannel' : 'Group.LeaveGroup')),\n icon: 'delete',\n destructive: true,\n handler: handleDelete,\n };\n\n const isInFolder = folderId !== undefined;\n\n return compact([\n actionAddToFolder,\n actionUnreadMark,\n actionPin,\n !isSelf && actionMute,\n !isSelf && !isServiceNotifications && !isInFolder && actionArchive,\n actionReport,\n actionDelete,\n ]);\n }, [\n chat, user, canChangeFolder, lang, handleChatFolderChange, isPinned, isInSearch, isMuted,\n handleDelete, handleReport, folderId, isSelf, isServiceNotifications,\n ]);\n};\n\nexport default useChatContextActions;\n","import type { RefObject } from 'react';\nimport { useState, useEffect, useCallback } from '../lib/teact/teact';\n\nimport type { IAnchorPosition } from '../types';\nimport {\n IS_TOUCH_ENV, IS_PWA, IS_IOS,\n} from '../util/environment';\n\nconst LONG_TAP_DURATION_MS = 200;\n\nfunction stopEvent(e: Event) {\n e.stopImmediatePropagation();\n e.preventDefault();\n e.stopPropagation();\n}\n\nconst useContextMenuHandlers = (\n elementRef: RefObject<HTMLElement>,\n isMenuDisabled?: boolean,\n shouldDisableOnLink?: boolean,\n shouldDisableOnLongTap?: boolean,\n) => {\n const [isContextMenuOpen, setIsContextMenuOpen] = useState(false);\n const [contextMenuPosition, setContextMenuPosition] = useState<IAnchorPosition | undefined>(undefined);\n\n const handleBeforeContextMenu = useCallback((e: React.MouseEvent) => {\n if (!isMenuDisabled && e.button === 2) {\n (e.target as HTMLElement).classList.add('no-selection');\n }\n }, [isMenuDisabled]);\n\n const handleContextMenu = useCallback((e: React.MouseEvent) => {\n (e.target as HTMLElement).classList.remove('no-selection');\n\n if (isMenuDisabled || (shouldDisableOnLink && (e.target as HTMLElement).matches('a[href]'))) {\n return;\n }\n e.preventDefault();\n\n if (contextMenuPosition) {\n return;\n }\n\n setIsContextMenuOpen(true);\n setContextMenuPosition({ x: e.clientX, y: e.clientY });\n }, [isMenuDisabled, shouldDisableOnLink, contextMenuPosition]);\n\n const handleContextMenuClose = useCallback(() => {\n setIsContextMenuOpen(false);\n }, []);\n\n const handleContextMenuHide = useCallback(() => {\n setContextMenuPosition(undefined);\n }, []);\n\n // Support context menu on touch devices\n useEffect(() => {\n if (isMenuDisabled || !IS_TOUCH_ENV || shouldDisableOnLongTap) {\n return undefined;\n }\n\n const element = elementRef.current;\n if (!element) {\n return undefined;\n }\n\n let timer: number | undefined;\n\n const clearLongPressTimer = () => {\n if (timer) {\n clearTimeout(timer);\n timer = undefined;\n }\n };\n\n const emulateContextMenuEvent = (originalEvent: TouchEvent) => {\n clearLongPressTimer();\n\n const { clientX, clientY, target } = originalEvent.touches[0];\n\n if (contextMenuPosition || (shouldDisableOnLink && (target as HTMLElement).matches('a[href]'))) {\n return;\n }\n\n // Temporarily intercept and clear the next click\n element.addEventListener('touchend', function cancelClickOnce(e) {\n element.removeEventListener('touchend', cancelClickOnce, true);\n stopEvent(e);\n }, true);\n\n // On iOS15, in PWA mode, the context menu immediately closes after opening\n if (IS_PWA && IS_IOS) {\n element.addEventListener('mousedown', function cancelClickOnce(e) {\n element.removeEventListener('mousedown', cancelClickOnce, true);\n stopEvent(e);\n }, true);\n }\n\n setIsContextMenuOpen(true);\n setContextMenuPosition({ x: clientX, y: clientY });\n };\n\n const startLongPressTimer = (e: TouchEvent) => {\n if (isMenuDisabled) {\n return;\n }\n clearLongPressTimer();\n\n timer = window.setTimeout(() => emulateContextMenuEvent(e), LONG_TAP_DURATION_MS);\n };\n\n // @perf Consider event delegation\n element.addEventListener('touchstart', startLongPressTimer, { passive: true });\n element.addEventListener('touchcancel', clearLongPressTimer, true);\n element.addEventListener('touchend', clearLongPressTimer, true);\n element.addEventListener('touchmove', clearLongPressTimer, { passive: true });\n\n return () => {\n clearLongPressTimer();\n element.removeEventListener('touchstart', startLongPressTimer);\n element.removeEventListener('touchcancel', clearLongPressTimer, true);\n element.removeEventListener('touchend', clearLongPressTimer, true);\n element.removeEventListener('touchmove', clearLongPressTimer);\n };\n }, [contextMenuPosition, isMenuDisabled, shouldDisableOnLongTap, elementRef, shouldDisableOnLink]);\n\n return {\n isContextMenuOpen,\n contextMenuPosition,\n handleBeforeContextMenu,\n handleContextMenu,\n handleContextMenuClose,\n handleContextMenuHide,\n };\n};\n\nexport default useContextMenuHandlers;\n","import { useState, useEffect } from '../lib/teact/teact';\nimport type { IAnchorPosition } from '../types';\n\ninterface Layout {\n extraPaddingX?: number;\n extraTopPadding?: number;\n marginSides?: number;\n extraMarginTop?: number;\n}\n\nconst MENU_POSITION_VISUAL_COMFORT_SPACE_PX = 16;\nconst MENU_POSITION_BOTTOM_MARGIN = 12;\nconst EMPTY_RECT = {\n width: 0, left: 0, height: 0, top: 0,\n};\n\nexport default function useContextMenuPosition(\n anchor: IAnchorPosition | undefined,\n getTriggerElement: () => HTMLElement | null,\n getRootElement: () => HTMLElement | null,\n getMenuElement: () => HTMLElement | null,\n getLayout?: () => Layout,\n) {\n const [positionX, setPositionX] = useState<'right' | 'left'>('right');\n const [positionY, setPositionY] = useState<'top' | 'bottom'>('bottom');\n const [transformOriginX, setTransformOriginX] = useState<number>();\n const [transformOriginY, setTransformOriginY] = useState<number>();\n const [withScroll, setWithScroll] = useState(false);\n const [style, setStyle] = useState('');\n const [menuStyle, setMenuStyle] = useState('opacity: 0;');\n\n useEffect(() => {\n const triggerEl = getTriggerElement();\n if (!anchor || !triggerEl) {\n return;\n }\n\n let { x, y } = anchor;\n const anchorX = x;\n const anchorY = y;\n\n const menuEl = getMenuElement();\n const rootEl = getRootElement();\n\n const {\n extraPaddingX = 0,\n extraTopPadding = 0,\n marginSides = 0,\n extraMarginTop = 0,\n } = getLayout?.() || {};\n\n const marginTop = menuEl ? parseInt(getComputedStyle(menuEl).marginTop, 10) + extraMarginTop : undefined;\n\n const menuRect = menuEl ? {\n width: menuEl.offsetWidth,\n height: menuEl.offsetHeight + marginTop!,\n } : EMPTY_RECT;\n\n const rootRect = rootEl ? rootEl.getBoundingClientRect() : EMPTY_RECT;\n\n let horizontalPosition: 'left' | 'right';\n let verticalPosition: 'top' | 'bottom';\n if (x + menuRect.width + extraPaddingX < rootRect.width + rootRect.left) {\n x += 3;\n horizontalPosition = 'left';\n } else if (x - menuRect.width > 0) {\n horizontalPosition = 'right';\n x -= 3;\n } else {\n horizontalPosition = 'left';\n x = 16;\n }\n setPositionX(horizontalPosition);\n\n if (marginSides\n && horizontalPosition === 'right' && (x + extraPaddingX + marginSides >= rootRect.width + rootRect.left)) {\n x -= marginSides;\n }\n\n if (marginSides && horizontalPosition === 'left') {\n if (x + extraPaddingX + marginSides + menuRect.width >= rootRect.width + rootRect.left) {\n x -= marginSides;\n } else if (x - marginSides <= 0) {\n x += marginSides;\n }\n }\n\n if (y + menuRect.height < rootRect.height + rootRect.top) {\n verticalPosition = 'top';\n } else {\n verticalPosition = 'bottom';\n\n if (y - menuRect.height < rootRect.top + extraTopPadding) {\n y = rootRect.top + rootRect.height;\n }\n }\n setPositionY(verticalPosition);\n\n const triggerRect = triggerEl.getBoundingClientRect();\n const left = horizontalPosition === 'left'\n ? Math.min(x - triggerRect.left, rootRect.width - menuRect.width - MENU_POSITION_VISUAL_COMFORT_SPACE_PX)\n : (x - triggerRect.left);\n const top = y - triggerRect.top;\n\n const menuMaxHeight = rootRect.height - MENU_POSITION_BOTTOM_MARGIN - (marginTop || 0);\n\n setWithScroll(menuMaxHeight < menuRect.height);\n setMenuStyle(`max-height: ${menuMaxHeight}px;`);\n setStyle(`left: ${left}px; top: ${top}px`);\n const offsetX = (anchorX - triggerRect.left) - left;\n const offsetY = (anchorY - triggerRect.top) - top - (marginTop || 0);\n setTransformOriginX(horizontalPosition === 'left' ? offsetX : menuRect.width + offsetX);\n setTransformOriginY(verticalPosition === 'bottom' ? menuRect.height + offsetY : offsetY);\n }, [\n anchor, getMenuElement, getRootElement, getTriggerElement, getLayout,\n ]);\n\n return {\n positionX,\n positionY,\n transformOriginX,\n transformOriginY,\n style,\n menuStyle,\n withScroll,\n };\n}\n","import { useEffect, useMemo } from '../lib/teact/teact';\nimport { getActions } from '../global';\n\nimport type { ApiMessage } from '../api/types';\n\nimport { throttle } from '../util/schedulers';\n\nconst useEnsureMessage = (\n chatId: string,\n messageId?: number,\n message?: ApiMessage,\n replyOriginForId?: number,\n) => {\n const { loadMessage } = getActions();\n const loadMessageThrottled = useMemo(() => {\n const throttled = throttle(loadMessage, 500, true);\n return () => {\n throttled({ chatId, messageId, replyOriginForId });\n };\n }, [loadMessage, chatId, messageId, replyOriginForId]);\n\n useEffect(() => {\n if (messageId && !message) {\n loadMessageThrottled();\n }\n });\n};\n\nexport default useEnsureMessage;\n","import { useEffect } from '../lib/teact/teact';\n\nimport {\n getOrderedIds,\n getUnreadCounters,\n getChatsCount,\n addOrderedIdsCallback,\n addUnreadCountersCallback,\n addChatsCountCallback,\n} from '../util/folderManager';\nimport useForceUpdate from './useForceUpdate';\n\nexport function useFolderManagerForOrderedIds(folderId: number) {\n const forceUpdate = useForceUpdate();\n\n useEffect(() => addOrderedIdsCallback(folderId, forceUpdate), [folderId, forceUpdate]);\n\n return getOrderedIds(folderId);\n}\n\nexport function useFolderManagerForUnreadCounters() {\n const forceUpdate = useForceUpdate();\n\n useEffect(() => addUnreadCountersCallback(forceUpdate), [forceUpdate]);\n\n return getUnreadCounters();\n}\n\nexport function useFolderManagerForChatsCount() {\n const forceUpdate = useForceUpdate();\n\n useEffect(() => addChatsCountCallback(forceUpdate), [forceUpdate]);\n\n return getChatsCount();\n}\n","import { useEffect } from '../lib/teact/teact';\n\nconst useHorizontalScroll = (container: HTMLElement | null, isDisabled?: boolean, shouldPreventDefault = false) => {\n useEffect(() => {\n if (!container || isDisabled) {\n return undefined;\n }\n\n function handleScroll(e: WheelEvent) {\n // Ignore horizontal scroll and let it work natively (e.g. on touchpad)\n if (!e.deltaX) {\n container!.scrollLeft += e.deltaY / 4;\n if (shouldPreventDefault) e.preventDefault();\n }\n }\n\n container.addEventListener('wheel', handleScroll, { passive: !shouldPreventDefault });\n\n return () => {\n container.removeEventListener('wheel', handleScroll);\n };\n }, [container, isDisabled, shouldPreventDefault]);\n};\n\nexport default useHorizontalScroll;\n","import { useEffect } from '../lib/teact/teact';\nimport { getHotkeyMatcher } from '../util/parseHotkey';\nimport { createCallbackManager } from '../util/callbacks';\n\nconst IGNORE_TAGS = new Set(['INPUT', 'TEXTAREA', 'SELECT']);\n\nconst handlers = createCallbackManager();\ndocument.documentElement.addEventListener('keydown', handlers.runCallbacks);\n\nexport function useHotkeys(hotkeys?: Record<string, (e: KeyboardEvent) => void>) {\n useEffect(() => {\n if (!hotkeys) {\n return undefined;\n }\n\n const entries = Object.entries(hotkeys);\n\n function handleKeyDown(e: KeyboardEvent) {\n if (!shouldFireEvent(e)) {\n return;\n }\n\n entries.forEach(([hotkey, handler]) => {\n if (getHotkeyMatcher(hotkey)(e)) {\n handler(e);\n }\n });\n }\n\n return handlers.addCallback(handleKeyDown);\n }, [hotkeys]);\n}\n\nfunction shouldFireEvent(e: KeyboardEvent) {\n if (e.target instanceof HTMLElement) {\n return !IGNORE_TAGS.has(e.target.tagName);\n }\n\n return true;\n}\n","// Original source from Mantine\n// https://github.com/mantinedev/mantine/blob/master/src/mantine-hooks/src/use-hotkeys/parse-hotkey.ts\n\nexport type KeyboardModifiers = {\n alt: boolean;\n ctrl: boolean;\n meta: boolean;\n mod: boolean;\n shift: boolean;\n};\n\nexport type Hotkey = KeyboardModifiers & {\n key?: string;\n};\n\ntype CheckHotkeyMatch = (event: KeyboardEvent) => boolean;\n\nexport function parseHotkey(hotkey: string): Hotkey {\n const keys = hotkey\n .toLowerCase()\n .split('+')\n .map((part) => part.trim());\n\n const modifiers: KeyboardModifiers = {\n alt: keys.includes('alt'),\n ctrl: keys.includes('ctrl'),\n meta: keys.includes('meta'),\n mod: keys.includes('mod'),\n shift: keys.includes('shift'),\n };\n\n const reservedKeys = ['alt', 'ctrl', 'meta', 'shift', 'mod'];\n\n const freeKey = keys.find((key) => !reservedKeys.includes(key));\n\n return {\n ...modifiers,\n key: freeKey,\n };\n}\n\nfunction isExactHotkey(hotkey: Hotkey, event: KeyboardEvent): boolean {\n const {\n alt, ctrl, meta, mod, shift, key,\n } = hotkey;\n const {\n altKey, ctrlKey, metaKey, shiftKey, key: pressedKey,\n } = event;\n\n if (alt !== altKey) {\n return false;\n }\n\n if (mod) {\n if (!ctrlKey && !metaKey) {\n return false;\n }\n } else {\n if (ctrl !== ctrlKey) {\n return false;\n }\n if (meta !== metaKey) {\n return false;\n }\n }\n if (shift !== shiftKey) {\n return false;\n }\n\n return Boolean(key\n && (pressedKey.toLowerCase() === key.toLowerCase()\n || event.code.replace('Key', '').toLowerCase() === key.toLowerCase()));\n}\n\nexport function getHotkeyMatcher(hotkey: string): CheckHotkeyMatch {\n return (event) => isExactHotkey(parseHotkey(hotkey), event);\n}\n","import type { RefObject } from 'react';\nimport { useEffect } from '../lib/teact/teact';\nimport { IS_SINGLE_COLUMN_LAYOUT } from '../util/environment';\n\n// Focus slows down animation, also it breaks transition layout in Chrome\nconst FOCUS_DELAY_MS = 500;\nconst MODAL_HIDE_DELAY_MS = 300;\n\nexport default function useInputFocusOnOpen(\n inputRef: RefObject<HTMLInputElement | HTMLTextAreaElement>,\n isOpen?: boolean,\n onClose?: NoneToVoidFunction,\n) {\n useEffect(() => {\n if (isOpen) {\n if (!IS_SINGLE_COLUMN_LAYOUT) {\n setTimeout(() => {\n requestAnimationFrame(() => {\n if (inputRef.current) {\n inputRef.current.focus();\n }\n });\n }, FOCUS_DELAY_MS);\n }\n } else {\n if (inputRef.current) {\n inputRef.current.blur();\n }\n\n if (onClose) {\n setTimeout(onClose, MODAL_HIDE_DELAY_MS);\n }\n }\n }, [inputRef, isOpen, onClose]);\n}\n","import { useLayoutEffect } from '../lib/teact/teact';\nimport usePrevious from './usePrevious';\n\nconst useLayoutEffectWithPrevDeps = <T extends readonly any[]>(\n cb: (args: T | readonly []) => void, dependencies: T, debugKey?: string,\n) => {\n const prevDeps = usePrevious<T>(dependencies);\n return useLayoutEffect(() => {\n return cb(prevDeps || []);\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, dependencies, debugKey);\n};\n\nexport default useLayoutEffectWithPrevDeps;\n","import { useRef } from '../lib/teact/teact';\nimport generateIdFor from '../util/generateIdFor';\n\nconst store: Record<string, boolean> = {};\n\nconst useUniqueId = () => {\n const idRef = useRef<string>();\n\n if (!idRef.current) {\n idRef.current = generateIdFor(store);\n store[idRef.current] = true;\n }\n\n return idRef.current;\n};\n\nexport default useUniqueId;\n","import {\n useEffect, useMemo, useRef, useState,\n} from '../lib/teact/teact';\n\nimport { IS_PROGRESSIVE_SUPPORTED } from '../util/environment';\nimport { ApiMediaFormat } from '../api/types';\nimport { throttle } from '../util/schedulers';\nimport * as mediaLoader from '../util/mediaLoader';\nimport useForceUpdate from './useForceUpdate';\nimport useUniqueId from './useUniqueId';\n\nconst STREAMING_PROGRESS = 0.75;\nconst STREAMING_TIMEOUT = 1500;\nconst PROGRESS_THROTTLE = 500;\n\nexport default function useMediaWithLoadProgress(\n mediaHash: string | undefined,\n noLoad = false,\n mediaFormat = ApiMediaFormat.BlobUrl,\n cacheBuster?: number,\n delay?: number | false,\n isHtmlAllowed = false,\n) {\n const mediaData = mediaHash ? mediaLoader.getFromMemory(mediaHash) : undefined;\n const isStreaming = mediaFormat === ApiMediaFormat.Stream || (\n IS_PROGRESSIVE_SUPPORTED && mediaFormat === ApiMediaFormat.Progressive\n );\n const forceUpdate = useForceUpdate();\n const id = useUniqueId();\n const [loadProgress, setLoadProgress] = useState(mediaData && !isStreaming ? 1 : 0);\n const startedAtRef = useRef<number>();\n\n const handleProgress = useMemo(() => {\n return throttle((progress: number) => {\n if (startedAtRef.current && (!delay || (Date.now() - startedAtRef.current > delay))) {\n setLoadProgress(progress);\n }\n }, PROGRESS_THROTTLE, true);\n }, [delay]);\n\n useEffect(() => {\n if (!noLoad && mediaHash) {\n if (!mediaData) {\n setLoadProgress(0);\n\n if (startedAtRef.current) {\n mediaLoader.cancelProgress(handleProgress);\n }\n\n startedAtRef.current = Date.now();\n\n mediaLoader.fetch(mediaHash, mediaFormat, isHtmlAllowed, handleProgress, id).then(() => {\n const spentTime = Date.now() - startedAtRef.current!;\n startedAtRef.current = undefined;\n\n if (!delay || spentTime >= delay) {\n forceUpdate();\n } else {\n setTimeout(forceUpdate, delay - spentTime);\n }\n });\n } else if (isStreaming) {\n setTimeout(() => {\n setLoadProgress(STREAMING_PROGRESS);\n }, STREAMING_TIMEOUT);\n }\n }\n }, [\n noLoad, mediaHash, mediaData, mediaFormat, cacheBuster, forceUpdate, isStreaming, delay, handleProgress,\n isHtmlAllowed, id,\n ]);\n\n useEffect(() => {\n if (noLoad && startedAtRef.current) {\n mediaLoader.cancelProgress(handleProgress);\n setLoadProgress(0);\n startedAtRef.current = undefined;\n }\n }, [handleProgress, noLoad]);\n\n useEffect(() => {\n return () => {\n if (mediaHash) {\n mediaLoader.removeCallback(mediaHash, id);\n }\n };\n }, [id, mediaHash]);\n\n return { mediaData, loadProgress };\n}\n","import { useCallback, useEffect, useRef } from '../lib/teact/teact';\n\nimport { IS_TOUCH_ENV } from '../util/environment';\n\nconst MENU_CLOSE_TIMEOUT = 250;\nlet closeTimeout: number | undefined;\n\nexport default function useMouseInside(\n isOpen: boolean, onClose: NoneToVoidFunction, menuCloseTimeout = MENU_CLOSE_TIMEOUT, isDisabled = false,\n) {\n const isMouseInside = useRef(false);\n\n const markMouseInside = useCallback(() => {\n isMouseInside.current = true;\n }, []);\n\n useEffect(() => {\n if (closeTimeout) {\n clearTimeout(closeTimeout);\n closeTimeout = undefined;\n }\n\n if (isOpen && !IS_TOUCH_ENV && !isDisabled) {\n closeTimeout = window.setTimeout(() => {\n if (!isMouseInside.current) {\n onClose();\n }\n }, menuCloseTimeout * 2);\n }\n }, [isDisabled, isOpen, menuCloseTimeout, onClose]);\n\n const handleMouseEnter = useCallback(() => {\n isMouseInside.current = true;\n }, []);\n\n const handleMouseLeave = useCallback(() => {\n isMouseInside.current = false;\n\n if (closeTimeout) {\n clearTimeout(closeTimeout);\n closeTimeout = undefined;\n }\n\n closeTimeout = window.setTimeout(() => {\n if (!isMouseInside.current) {\n onClose();\n }\n }, menuCloseTimeout);\n }, [menuCloseTimeout, onClose]);\n\n return [handleMouseEnter, handleMouseLeave, markMouseInside];\n}\n","import { useRef } from '../lib/teact/teact';\n\nimport usePrevious from './usePrevious';\nimport useForceUpdate from './useForceUpdate';\nimport useOnChange from './useOnChange';\n\nexport default function usePrevDuringAnimation(current: any, duration?: number) {\n const prev = usePrevious(current, true);\n const timeoutRef = useRef<number>();\n const forceUpdate = useForceUpdate();\n // eslint-disable-next-line no-null/no-null\n const isCurrentPresent = current !== undefined && current !== null;\n // eslint-disable-next-line no-null/no-null\n const isPrevPresent = prev !== undefined && prev !== null;\n\n if (isCurrentPresent && timeoutRef.current) {\n clearTimeout(timeoutRef.current);\n timeoutRef.current = undefined;\n }\n\n useOnChange(() => {\n // When `current` becomes empty\n if (duration && !isCurrentPresent && isPrevPresent && !timeoutRef.current) {\n timeoutRef.current = window.setTimeout(() => {\n timeoutRef.current = undefined;\n forceUpdate();\n }, duration);\n }\n }, [current]);\n\n return !timeoutRef.current || !duration || isCurrentPresent ? current : prev;\n}\n","import { useCallback, useRef } from '../lib/teact/teact';\n\nimport useForceUpdate from './useForceUpdate';\n\nexport type ReducerAction<Actions> = { type: Actions; payload?: any };\nexport type StateReducer<State, Actions> = (state: State, action: ReducerAction<Actions>) => State;\nexport type Dispatch<Actions> = (action: ReducerAction<Actions>) => void;\n\nexport default function useReducer<State, Actions>(\n reducer: StateReducer<State, Actions>,\n initialState: State,\n) {\n const forceUpdate = useForceUpdate();\n const reducerRef = useRef(reducer);\n const state = useRef(initialState);\n\n const dispatch = useCallback((action: ReducerAction<Actions>) => {\n state.current = reducerRef.current(state.current, action);\n forceUpdate();\n }, [forceUpdate]);\n\n return [\n state.current,\n dispatch,\n ] as [State, Dispatch<Actions>];\n}\n","import useDebouncedCallback from './useDebouncedCallback';\n\nexport default function useRunDebounced(ms: number, noFirst?: boolean, noLast?: boolean) {\n return useDebouncedCallback((cb: NoneToVoidFunction) => {\n cb();\n }, [], ms, noFirst, noLast);\n}\n","import type { FC } from '../../lib/teact/teact';\nimport React, { memo } from '../../lib/teact/teact';\nimport type { OwnProps } from './CalendarModal';\nimport { Bundles } from '../../util/moduleLoader';\n\nimport useModuleLoader from '../../hooks/useModuleLoader';\n\nconst CalendarModalAsync: FC<OwnProps> = (props) => {\n const { isOpen } = props;\n const CalendarModal = useModuleLoader(Bundles.Extra, 'CalendarModal', !isOpen);\n\n // eslint-disable-next-line react/jsx-props-no-spreading\n return CalendarModal ? <CalendarModal {...props} /> : undefined;\n};\n\nexport default memo(CalendarModalAsync);\n","import React, { useCallback, useState } from '../lib/teact/teact';\nimport { getGlobal } from '../lib/teact/teactn';\n\nimport { SCHEDULED_WHEN_ONLINE } from '../config';\nimport { getDayStartAt } from '../util/dateFormat';\nimport useLang from './useLang';\n\nimport CalendarModal from '../components/common/CalendarModal.async';\n\ntype OnScheduledCallback = (scheduledAt: number) => void;\n\nconst useSchedule = (\n canScheduleUntilOnline?: boolean,\n onCancel?: () => void,\n) => {\n const lang = useLang();\n const [onScheduled, setOnScheduled] = useState<OnScheduledCallback | undefined>();\n\n const handleMessageSchedule = useCallback((date: Date, isWhenOnline = false) => {\n const { serverTimeOffset } = getGlobal();\n // Scheduled time can not be less than 10 seconds in future\n const scheduledAt = Math.round(Math.max(date.getTime(), Date.now() + 60 * 1000) / 1000)\n + (isWhenOnline ? 0 : serverTimeOffset);\n onScheduled?.(scheduledAt);\n setOnScheduled(undefined);\n }, [onScheduled]);\n\n const handleMessageScheduleUntilOnline = useCallback(() => {\n handleMessageSchedule(new Date(SCHEDULED_WHEN_ONLINE * 1000), true);\n }, [handleMessageSchedule]);\n\n const handleCloseCalendar = useCallback(() => {\n setOnScheduled(undefined);\n onCancel?.();\n }, [onCancel]);\n\n const requestCalendar = useCallback((whenScheduled: OnScheduledCallback) => {\n setOnScheduled(() => whenScheduled);\n }, []);\n\n const scheduledDefaultDate = new Date();\n scheduledDefaultDate.setSeconds(0);\n scheduledDefaultDate.setMilliseconds(0);\n\n const scheduledMaxDate = new Date();\n scheduledMaxDate.setFullYear(scheduledMaxDate.getFullYear() + 1);\n\n const calendar = (\n <CalendarModal\n isOpen={Boolean(onScheduled)}\n withTimePicker\n selectedAt={scheduledDefaultDate.getTime()}\n maxAt={getDayStartAt(scheduledMaxDate)}\n isFutureMode\n secondButtonLabel={canScheduleUntilOnline ? lang('Schedule.SendWhenOnline') : undefined}\n onClose={handleCloseCalendar}\n onSubmit={handleMessageSchedule}\n onSecondButtonClick={canScheduleUntilOnline ? handleMessageScheduleUntilOnline : undefined}\n />\n );\n\n return [requestCalendar, calendar] as const;\n};\n\nexport default useSchedule;\n","import { useMemo } from '../lib/teact/teact';\nimport { getActions } from '../global';\n\nimport type { ApiSendMessageAction } from '../api/types';\n\nimport { SEND_MESSAGE_ACTION_INTERVAL } from '../config';\nimport { throttle } from '../util/schedulers';\n\nconst useSendMessageAction = (chatId?: string, threadId?: number) => {\n return useMemo(() => {\n return throttle((action: ApiSendMessageAction) => {\n getActions().sendMessageAction({ chatId, threadId, action });\n }, SEND_MESSAGE_ACTION_INTERVAL);\n }, [chatId, threadId]);\n};\n\nexport default useSendMessageAction;\n","import { useRef } from '../lib/teact/teact';\n\nimport useOnChange from './useOnChange';\n\n// Allows to use state value as \"silent\" dependency in hooks (not causing updates).\n// Useful for state values that update frequently (such as controlled input value).\nexport function useStateRef<T>(value: T) {\n const ref = useRef<T>(value);\n\n useOnChange(() => {\n ref.current = value;\n }, [value]);\n\n return ref;\n}\n","import { useEffect, useLayoutEffect, useRef } from '../lib/teact/teact';\n\nfunction useTimeout(callback: () => void, delay?: number) {\n const savedCallback = useRef(callback);\n\n useLayoutEffect(() => {\n savedCallback.current = callback;\n }, [callback]);\n\n useEffect(() => {\n if (typeof delay !== 'number') {\n return undefined;\n }\n const id = setTimeout(() => savedCallback.current(), delay);\n return () => clearTimeout(id);\n }, [delay]);\n}\n\nexport default useTimeout;\n","/* eslint-disable no-nested-ternary */\n/* eslint-disable no-bitwise */\n/* eslint-disable no-multi-assign */\n/* eslint-disable no-cond-assign */\n/* eslint-disable no-param-reassign */\n/* eslint-disable prefer-const */\n/* eslint-disable eqeqeq */\n/* eslint-disable @typescript-eslint/naming-convention */\n\n/*\nSuperfast Blur - a fast Box Blur For Canvas\n\nVersion: 0.5\nAuthor: Mario Klingemann\nContact: mario@quasimondo.com\nWebsite: http://www.quasimondo.com/BoxBlurForCanvas\nTwitter: @quasimondo\n\nIn case you find this class useful - especially in commercial projects -\nI am not totally unhappy for a small donation to my PayPal account\nmario@quasimondo.de\n\nOr support me on flattr:\nhttps://flattr.com/thing/140066/Superfast-Blur-a-pretty-fast-Box-Blur-Effect-for-CanvasJavascript\n\nCopyright (c) 2011 Mario Klingemann\n\nPermission is hereby granted, free of charge, to any person\nobtaining a copy of this software and associated documentation\nfiles (the \"Software\"), to deal in the Software without\nrestriction, including without limitation the rights to use,\ncopy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the\nSoftware is furnished to do so, subject to the following\nconditions:\n\nThe above copyright notice and this permission notice shall be\nincluded in all copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\nEXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES\nOF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\nNONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT\nHOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,\nWHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\nFROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR\nOTHER DEALINGS IN THE SOFTWARE.\n*/\n\n// eslint-disable-next-line max-len\nconst mul_table = [1, 57, 41, 21, 203, 34, 97, 73, 227, 91, 149, 62, 105, 45, 39, 137, 241, 107, 3, 173, 39, 71, 65, 238, 219, 101, 187, 87, 81, 151, 141, 133, 249, 117, 221, 209, 197, 187, 177, 169, 5, 153, 73, 139, 133, 127, 243, 233, 223, 107, 103, 99, 191, 23, 177, 171, 165, 159, 77, 149, 9, 139, 135, 131, 253, 245, 119, 231, 224, 109, 211, 103, 25, 195, 189, 23, 45, 175, 171, 83, 81, 79, 155, 151, 147, 9, 141, 137, 67, 131, 129, 251, 123, 30, 235, 115, 113, 221, 217, 53, 13, 51, 50, 49, 193, 189, 185, 91, 179, 175, 43, 169, 83, 163, 5, 79, 155, 19, 75, 147, 145, 143, 35, 69, 17, 67, 33, 65, 255, 251, 247, 243, 239, 59, 29, 229, 113, 111, 219, 27, 213, 105, 207, 51, 201, 199, 49, 193, 191, 47, 93, 183, 181, 179, 11, 87, 43, 85, 167, 165, 163, 161, 159, 157, 155, 77, 19, 75, 37, 73, 145, 143, 141, 35, 138, 137, 135, 67, 33, 131, 129, 255, 63, 250, 247, 61, 121, 239, 237, 117, 29, 229, 227, 225, 111, 55, 109, 216, 213, 211, 209, 207, 205, 203, 201, 199, 197, 195, 193, 48, 190, 47, 93, 185, 183, 181, 179, 178, 176, 175, 173, 171, 85, 21, 167, 165, 41, 163, 161, 5, 79, 157, 78, 154, 153, 19, 75, 149, 74, 147, 73, 144, 143, 71, 141, 140, 139, 137, 17, 135, 134, 133, 66, 131, 65, 129, 1];\n// eslint-disable-next-line max-len\nconst shg_table = [0, 9, 10, 10, 14, 12, 14, 14, 16, 15, 16, 15, 16, 15, 15, 17, 18, 17, 12, 18, 16, 17, 17, 19, 19, 18, 19, 18, 18, 19, 19, 19, 20, 19, 20, 20, 20, 20, 20, 20, 15, 20, 19, 20, 20, 20, 21, 21, 21, 20, 20, 20, 21, 18, 21, 21, 21, 21, 20, 21, 17, 21, 21, 21, 22, 22, 21, 22, 22, 21, 22, 21, 19, 22, 22, 19, 20, 22, 22, 21, 21, 21, 22, 22, 22, 18, 22, 22, 21, 22, 22, 23, 22, 20, 23, 22, 22, 23, 23, 21, 19, 21, 21, 21, 23, 23, 23, 22, 23, 23, 21, 23, 22, 23, 18, 22, 23, 20, 22, 23, 23, 23, 21, 22, 20, 22, 21, 22, 24, 24, 24, 24, 24, 22, 21, 24, 23, 23, 24, 21, 24, 23, 24, 22, 24, 24, 22, 24, 24, 22, 23, 24, 24, 24, 20, 23, 22, 23, 24, 24, 24, 24, 24, 24, 24, 23, 21, 23, 22, 23, 24, 24, 24, 22, 24, 24, 24, 23, 22, 24, 24, 25, 23, 25, 25, 23, 24, 25, 25, 24, 22, 25, 25, 25, 24, 23, 24, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 23, 25, 23, 24, 25, 25, 25, 25, 25, 25, 25, 25, 25, 24, 22, 25, 25, 23, 25, 25, 20, 24, 25, 24, 25, 25, 22, 24, 25, 24, 25, 24, 25, 25, 24, 25, 25, 25, 25, 22, 25, 25, 25, 24, 25, 24, 25, 18];\n\nexport default function boxBlurCanvasRGB(context, top_x, top_y, width, height, radius, iterations) {\n if (Number.isNaN(radius) || radius < 1) return;\n\n radius |= 0;\n\n if (Number.isNaN(iterations)) iterations = 1;\n iterations |= 0;\n if (iterations > 3) iterations = 3;\n if (iterations < 1) iterations = 1;\n\n const imageData = context.getImageData(top_x, top_y, width, height);\n\n const pixels = imageData.data;\n\n let rsum;\n let gsum;\n let bsum;\n let x;\n let y;\n let i;\n let p;\n let p1;\n let p2;\n let yp;\n let yi;\n let yw;\n let wm = width - 1;\n let hm = height - 1;\n let rad1 = radius + 1;\n\n let r = [];\n let g = [];\n let b = [];\n\n let mul_sum = mul_table[radius];\n let shg_sum = shg_table[radius];\n\n let vmin = [];\n let vmax = [];\n\n while (iterations-- > 0) {\n yw = yi = 0;\n\n for (y = 0; y < height; y++) {\n rsum = pixels[yw] * rad1;\n gsum = pixels[yw + 1] * rad1;\n bsum = pixels[yw + 2] * rad1;\n\n for (i = 1; i <= radius; i++) {\n p = yw + (((i > wm ? wm : i)) << 2);\n rsum += pixels[p++];\n gsum += pixels[p++];\n bsum += pixels[p++];\n }\n\n for (x = 0; x < width; x++) {\n r[yi] = rsum;\n g[yi] = gsum;\n b[yi] = bsum;\n\n if (y == 0) {\n vmin[x] = ((p = x + rad1) < wm ? p : wm) << 2;\n vmax[x] = ((p = x - radius) > 0 ? p << 2 : 0);\n }\n\n p1 = yw + vmin[x];\n p2 = yw + vmax[x];\n\n rsum += pixels[p1++] - pixels[p2++];\n gsum += pixels[p1++] - pixels[p2++];\n bsum += pixels[p1++] - pixels[p2++];\n\n yi++;\n }\n yw += (width << 2);\n }\n\n for (x = 0; x < width; x++) {\n yp = x;\n rsum = r[yp] * rad1;\n gsum = g[yp] * rad1;\n bsum = b[yp] * rad1;\n\n for (i = 1; i <= radius; i++) {\n yp += (i > hm ? 0 : width);\n rsum += r[yp];\n gsum += g[yp];\n bsum += b[yp];\n }\n\n yi = x << 2;\n for (y = 0; y < height; y++) {\n pixels[yi] = (rsum * mul_sum) >>> shg_sum;\n pixels[yi + 1] = (gsum * mul_sum) >>> shg_sum;\n pixels[yi + 2] = (bsum * mul_sum) >>> shg_sum;\n\n if (x == 0) {\n vmin[y] = ((p = y + rad1) < hm ? p : hm) * width;\n vmax[y] = ((p = y - radius) > 0 ? p * width : 0);\n }\n\n p1 = x + vmin[y];\n p2 = x + vmax[y];\n\n rsum += r[p1] - r[p2];\n gsum += g[p1] - g[p2];\n bsum += b[p1] - b[p2];\n\n yi += width << 2;\n }\n }\n }\n\n context.putImageData(imageData, top_x, top_y);\n}\n","import { getActions, getGlobal } from '../global';\n\nimport { AudioOrigin, GlobalSearchContent } from '../types';\nimport type { ApiMessage } from '../api/types';\n\nimport { IS_SAFARI } from './environment';\nimport safePlay from './safePlay';\nimport { patchSafariProgressiveAudio, isSafariPatchInProgress } from './patchSafariProgressiveAudio';\nimport type { MessageKey } from '../global/helpers';\nimport { getMessageKey, parseMessageKey } from '../global/helpers';\nimport { fastRaf } from './schedulers';\nimport { selectCurrentMessageList } from '../global/selectors';\n\ntype Handler = (eventName: string, e: Event) => void;\nexport type TrackId = `${MessageKey}-${number}`;\n\nexport interface Track {\n audio: HTMLAudioElement;\n proxy: HTMLAudioElement;\n type: 'voice' | 'audio';\n handlers: Handler[];\n onForcePlay?: NoneToVoidFunction;\n onTrackChange?: NoneToVoidFunction;\n}\n\nconst tracks = new Map<TrackId, Track>();\nlet voiceQueue: TrackId[] = [];\nlet musicQueue: TrackId[] = [];\n\nlet currentTrackId: TrackId | undefined;\n\nfunction createAudio(\n trackId: TrackId,\n type: Track['type'],\n onForcePlay?: NoneToVoidFunction,\n onTrackChange?: NoneToVoidFunction,\n): Track {\n const audio = new Audio();\n\n function handleEvent(eventName: string) {\n return (e: Event) => {\n if (!tracks.has(trackId)) {\n return;\n }\n\n if (isSafariPatchInProgress(audio)) {\n return;\n }\n\n tracks.get(trackId)!.handlers.forEach((handler) => {\n handler(eventName, e);\n });\n };\n }\n\n audio.addEventListener('timeupdate', handleEvent('onTimeUpdate'));\n audio.addEventListener('play', handleEvent('onPlay'));\n audio.addEventListener('pause', handleEvent('onPause'));\n audio.addEventListener('loadstart', handleEvent('onLoadStart'));\n audio.addEventListener('loadeddata', handleEvent('onLoadedData'));\n audio.addEventListener('playing', handleEvent('onPlaying'));\n audio.addEventListener('ended', () => {\n if (!tracks.has(trackId)) {\n return;\n }\n\n if (isSafariPatchInProgress(audio)) {\n return;\n }\n\n playNext(trackId);\n });\n\n return {\n audio,\n type,\n proxy: new Proxy(audio, {\n get: (target, key: keyof HTMLAudioElement) => target[key],\n }),\n handlers: [],\n onForcePlay,\n onTrackChange,\n };\n}\n\nfunction playNext(trackId: TrackId, isReverseOrder?: boolean) {\n const currentTrack = currentTrackId && tracks.get(currentTrackId);\n if (currentTrack) {\n currentTrack.audio.pause();\n currentTrack.audio.currentTime = 0;\n if (currentTrack.onTrackChange) currentTrack.onTrackChange();\n }\n\n const origin = getGlobal().audioPlayer.origin || AudioOrigin.Inline;\n\n const nextTrackId = findNextInQueue(trackId, origin, isReverseOrder);\n if (!nextTrackId) {\n return;\n }\n\n if (!tracks.has(nextTrackId)) {\n // A bit hacky way to continue playlist when switching chat\n getActions().openAudioPlayer(parseMessageKey(splitTrackId(nextTrackId).messageKey));\n\n return;\n }\n\n const nextTrack = tracks.get(nextTrackId)!;\n\n if (nextTrack.onForcePlay) {\n nextTrack.onForcePlay();\n }\n\n currentTrackId = nextTrackId;\n\n if (nextTrack.audio.src) {\n safePlay(nextTrack.audio);\n }\n}\n\nexport function stopCurrentAudio() {\n const currentTrack = currentTrackId && tracks.get(currentTrackId);\n if (currentTrack) {\n currentTrack.audio.pause();\n }\n}\n\nexport function register(\n trackId: TrackId,\n trackType: Track['type'],\n handler: Handler,\n onForcePlay?: NoneToVoidFunction,\n onTrackChange?: NoneToVoidFunction,\n) {\n if (!tracks.has(trackId)) {\n const track = createAudio(trackId, trackType, onForcePlay, onTrackChange);\n tracks.set(trackId, track);\n addTrackToQueue(track, trackId);\n }\n const { audio, proxy, handlers } = tracks.get(trackId)!;\n\n handlers.push(handler);\n\n return {\n play(src: string) {\n if (!audio.paused) return;\n const currentTrack = currentTrackId && tracks.get(currentTrackId);\n if (currentTrack && currentTrackId !== trackId) {\n currentTrack.audio.pause();\n currentTrack.audio.currentTime = 0;\n if (isSafariPatchInProgress(currentTrack.audio)) {\n currentTrack.audio.dataset.preventPlayAfterPatch = 'true';\n }\n if (currentTrack.onTrackChange) currentTrack.onTrackChange();\n }\n\n currentTrackId = trackId;\n\n if (!audio.src) {\n audio.src = src;\n audio.preload = 'auto';\n\n if (src.includes('/progressive/') && IS_SAFARI) {\n delete audio.dataset.preventPlayAfterPatch;\n patchSafariProgressiveAudio(audio);\n }\n }\n\n safePlay(audio);\n cleanUpQueue(trackType, trackId);\n },\n\n pause() {\n if (currentTrackId === trackId) {\n audio.pause();\n }\n },\n\n stop() {\n if (currentTrackId === trackId) {\n // Hack, reset src to remove default media session notification\n const prevSrc = audio.src;\n audio.pause();\n // onPause not called otherwise, but required to sync UI\n fastRaf(() => {\n audio.src = '';\n audio.src = prevSrc;\n });\n }\n },\n\n setCurrentTime(time: number) {\n if (currentTrackId === trackId) {\n if (audio.fastSeek) {\n audio.fastSeek(time);\n } else {\n audio.currentTime = time;\n }\n }\n },\n\n setVolume(volume: number) {\n if (currentTrackId === trackId) {\n audio.volume = volume;\n audio.muted = false;\n }\n },\n\n setPlaybackRate(rate: number) {\n if (currentTrackId === trackId) {\n audio.playbackRate = rate;\n }\n },\n\n toggleMuted(muted?: boolean) {\n if (muted === undefined) {\n audio.muted = !audio.muted;\n } else {\n audio.muted = muted;\n }\n },\n\n proxy,\n\n requestNextTrack() {\n playNext(trackId);\n },\n\n isLast() {\n return !findNextInQueue(trackId, getGlobal().audioPlayer.origin);\n },\n\n isFirst() {\n return !findNextInQueue(trackId, getGlobal().audioPlayer.origin, true);\n },\n\n requestPreviousTrack() {\n playNext(trackId, true);\n },\n\n destroy(shouldRemoveFromQueue = false) {\n const track = tracks.get(trackId);\n if (!track) {\n return;\n }\n\n track.handlers = track.handlers.filter((h) => h !== handler);\n\n if (!track.handlers.length) {\n track.audio.pause();\n tracks.delete(trackId);\n\n if (shouldRemoveFromQueue) {\n removeFromQueue(track, trackId);\n }\n\n if (trackId === currentTrackId) {\n currentTrackId = undefined;\n }\n }\n },\n };\n}\n\nfunction getTrackQueue(track: Track) {\n switch (track.type) {\n case 'audio': return musicQueue;\n case 'voice': return voiceQueue;\n default: return undefined;\n }\n}\n\nfunction addTrackToQueue(track: Track, trackId: TrackId) {\n if (track.type === 'audio' && !musicQueue.includes(trackId)) {\n musicQueue.push(trackId);\n musicQueue.sort(trackIdComparator);\n }\n\n if (track.type === 'voice' && !voiceQueue.includes(trackId)) {\n voiceQueue.push(trackId);\n voiceQueue.sort(trackIdComparator);\n }\n}\n\nfunction removeFromQueue(track: Track, trackId: TrackId) {\n const trackIdFilter = (el: TrackId) => el !== trackId;\n if (track.type === 'audio') {\n musicQueue = musicQueue.filter(trackIdFilter);\n }\n\n if (track.type === 'voice') {\n voiceQueue = voiceQueue.filter(trackIdFilter);\n }\n}\n\nfunction cleanUpQueue(type: Track['type'], trackId: TrackId) {\n if (getGlobal().globalSearch.currentContent === GlobalSearchContent.Music) return;\n const { chatId } = parseMessageKey(splitTrackId(trackId).messageKey);\n const openedChatId = selectCurrentMessageList(getGlobal())?.chatId;\n const queueFilter = (id: string) => (\n id.startsWith(`msg${chatId}`) || (openedChatId && id.startsWith(`msg${openedChatId}`))\n );\n\n if (type === 'audio') {\n musicQueue = musicQueue.filter(queueFilter);\n }\n\n if (type === 'voice') {\n voiceQueue = voiceQueue.filter(queueFilter);\n }\n}\n\nfunction findNextInQueue(currentId: TrackId, origin = AudioOrigin.Inline, isReverseOrder?: boolean) {\n const track = tracks.get(currentId)!;\n const queue = getTrackQueue(track);\n if (!queue) return undefined;\n\n if (origin === AudioOrigin.Search) {\n const index = queue.indexOf(currentId);\n if (index < 0) return undefined;\n const direction = isReverseOrder ? -1 : 1;\n return queue[index + direction];\n }\n\n const { chatId } = parseMessageKey(splitTrackId(currentId).messageKey);\n const chatAudio = queue.filter((id) => id.startsWith(`msg${chatId}`));\n const index = chatAudio.indexOf(currentId);\n if (index < 0) return undefined;\n let direction = origin === AudioOrigin.Inline ? -1 : 1;\n if (isReverseOrder) direction *= -1;\n return chatAudio[index + direction];\n}\n\nexport function makeTrackId(message: ApiMessage): TrackId {\n return `${getMessageKey(message)}-${message.date}`;\n}\n\nfunction splitTrackId(trackId: TrackId) {\n const messageKey = trackId.match(/^msg(-?\\d+)-(\\d+)/)![0] as MessageKey;\n const date = Number(trackId.split('-').pop());\n return {\n messageKey,\n date,\n };\n}\n\n// Descending order by date\nfunction trackIdComparator(one?: TrackId, two?: TrackId) {\n if (!one || !two) return 0;\n const { date: dateOne, messageKey: keyOne } = splitTrackId(one);\n const { date: dateTwo, messageKey: keyTwo } = splitTrackId(two);\n const diff = dateTwo - dateOne;\n return diff === 0 ? keyTwo.localeCompare(keyOne) : diff;\n}\n","import { IS_IOS } from './environment';\nimport { Lethargy } from './lethargy';\nimport { clamp, round } from './math';\nimport { debounce } from './schedulers';\n\nexport enum SwipeDirection {\n Up,\n Down,\n Left,\n Right,\n}\n\ninterface CaptureOptions {\n onCapture?: (e: MouseEvent | TouchEvent | WheelEvent) => void;\n onRelease?: (e: MouseEvent | TouchEvent | WheelEvent) => void;\n onDrag?: (\n e: MouseEvent | TouchEvent | WheelEvent,\n captureEvent: MouseEvent | TouchEvent | WheelEvent,\n params: {\n dragOffsetX: number;\n dragOffsetY: number;\n },\n cancelDrag?: (x: boolean, y: boolean) => void,\n ) => void;\n onSwipe?: (e: Event, direction: SwipeDirection) => boolean;\n onZoom?: (e: TouchEvent | WheelEvent, params: {\n // Absolute zoom level\n zoom?: number;\n // Relative zoom factor\n zoomFactor?: number;\n\n // center coordinate of the initial pinch\n initialCenterX: number;\n initialCenterY: number;\n\n // offset of the pinch center (current from initial)\n dragOffsetX: number;\n dragOffsetY: number;\n\n // center coordinate of the current pinch\n currentCenterX: number;\n currentCenterY: number;\n }) => void;\n onClick?: (e: MouseEvent | TouchEvent) => void;\n onDoubleClick?: (e: MouseEvent | RealTouchEvent | WheelEvent, params: { centerX: number; centerY: number }) => void;\n excludedClosestSelector?: string;\n selectorToPreventScroll?: string;\n withNativeDrag?: boolean;\n maxZoom?: number;\n minZoom?: number;\n doubleTapZoom?: number;\n initialZoom?: number;\n isNotPassive?: boolean;\n withCursor?: boolean;\n}\n\n// https://stackoverflow.com/questions/11287877/how-can-i-get-e-offsetx-on-mobile-ipad\n// Android does not have this value, and iOS has it but as read-only\nexport interface RealTouchEvent extends TouchEvent {\n pageX?: number;\n pageY?: number;\n}\n\ntype TSwipeAxis =\n 'x'\n | 'y'\n | undefined;\n\nexport const IOS_SCREEN_EDGE_THRESHOLD = 20;\nconst MOVED_THRESHOLD = 15;\nconst SWIPE_THRESHOLD = 50;\nconst RELEASE_WHEEL_ZOOM_DELAY = 150;\nconst RELEASE_WHEEL_DRAG_DELAY = 150;\n\nfunction getDistance(a: Touch, b?: Touch) {\n if (!b) return 0;\n return Math.hypot((b.pageX - a.pageX), (b.pageY - a.pageY));\n}\n\nfunction getTouchCenter(a: Touch, b: Touch) {\n return {\n x: (a.pageX + b.pageX) / 2,\n y: (a.pageY + b.pageY) / 2,\n };\n}\n\nlet lastClickTime = 0;\nconst lethargy = new Lethargy({\n stability: 5,\n sensitivity: 25,\n tolerance: 0.6,\n delay: 150,\n});\n\nexport function captureEvents(element: HTMLElement, options: CaptureOptions) {\n let captureEvent: MouseEvent | RealTouchEvent | WheelEvent | undefined;\n let hasMoved = false;\n let hasSwiped = false;\n let isZooming = false;\n let initialDistance = 0;\n let wheelZoom = options.initialZoom ?? 1;\n let initialDragOffset = {\n x: 0,\n y: 0,\n };\n let isDragCanceled = {\n x: false,\n y: false,\n };\n let initialTouchCenter = {\n x: window.innerWidth / 2,\n y: window.innerHeight / 2,\n };\n let initialSwipeAxis: TSwipeAxis | undefined;\n const minZoom = options.minZoom ?? 1;\n const maxZoom = options.maxZoom ?? 4;\n\n function onCapture(e: MouseEvent | RealTouchEvent) {\n if (options.excludedClosestSelector && (\n (e.target as HTMLElement).matches(options.excludedClosestSelector)\n || (e.target as HTMLElement).closest(options.excludedClosestSelector)\n )) {\n return;\n }\n\n captureEvent = e;\n\n if (e.type === 'mousedown') {\n if (!options.withNativeDrag && options.onDrag) {\n e.preventDefault();\n }\n\n document.addEventListener('mousemove', onMove);\n document.addEventListener('mouseup', onRelease);\n } else if (e.type === 'touchstart') {\n // We need to always listen on `touchstart` target:\n // https://stackoverflow.com/questions/33298828/touch-move-event-dont-fire-after-touch-start-target-is-removed\n const target = e.target as HTMLElement;\n target.addEventListener('touchmove', onMove, { passive: true });\n target.addEventListener('touchend', onRelease);\n target.addEventListener('touchcancel', onRelease);\n\n if ('touches' in e) {\n if (e.pageX === undefined) {\n e.pageX = e.touches[0].pageX;\n }\n\n if (e.pageY === undefined) {\n e.pageY = e.touches[0].pageY;\n }\n\n if (e.touches.length === 2) {\n initialDistance = getDistance(e.touches[0], e.touches[1]);\n initialTouchCenter = getTouchCenter(e.touches[0], e.touches[1]);\n }\n }\n }\n\n if (options.withCursor) {\n document.body.classList.add('cursor-grabbing');\n }\n\n if (options.onCapture) {\n options.onCapture(e);\n }\n }\n\n function onRelease(e?: MouseEvent | TouchEvent) {\n if (captureEvent) {\n if (options.withCursor) {\n document.body.classList.remove('cursor-grabbing');\n }\n\n document.removeEventListener('mouseup', onRelease);\n document.removeEventListener('mousemove', onMove);\n (captureEvent.target as HTMLElement).removeEventListener('touchcancel', onRelease);\n (captureEvent.target as HTMLElement).removeEventListener('touchend', onRelease);\n (captureEvent.target as HTMLElement).removeEventListener('touchmove', onMove);\n\n if (IS_IOS && options.selectorToPreventScroll) {\n Array.from(document.querySelectorAll<HTMLElement>(options.selectorToPreventScroll))\n .forEach((scrollable) => {\n scrollable.style.overflow = '';\n });\n }\n\n if (e) {\n if (hasMoved) {\n if (options.onRelease) {\n options.onRelease(e);\n }\n } else if (e.type === 'mouseup') {\n if (options.onDoubleClick && Date.now() - lastClickTime < 300) {\n options.onDoubleClick(e, {\n centerX: captureEvent!.pageX!,\n centerY: captureEvent!.pageY!,\n });\n } else if (options.onClick && (!('button' in e) || e.button === 0)) {\n options.onClick(e);\n }\n lastClickTime = Date.now();\n }\n }\n }\n\n hasMoved = false;\n hasSwiped = false;\n isZooming = false;\n initialDistance = 0;\n wheelZoom = clamp(wheelZoom, minZoom, maxZoom);\n initialSwipeAxis = undefined;\n initialDragOffset = {\n x: 0,\n y: 0,\n };\n isDragCanceled = {\n x: false,\n y: false,\n };\n initialTouchCenter = {\n x: window.innerWidth / 2,\n y: window.innerHeight / 2,\n };\n captureEvent = undefined;\n }\n\n function onMove(e: MouseEvent | RealTouchEvent) {\n if (captureEvent) {\n if (e.type === 'touchmove' && ('touches' in e)) {\n if (e.pageX === undefined) {\n e.pageX = e.touches[0].pageX;\n }\n\n if (e.pageY === undefined) {\n e.pageY = e.touches[0].pageY;\n }\n\n if (options.onZoom && initialDistance > 0 && e.touches.length === 2) {\n const endDistance = getDistance(e.touches[0], e.touches[1]);\n const touchCenter = getTouchCenter(e.touches[0], e.touches[1]);\n const dragOffsetX = touchCenter.x - initialTouchCenter.x;\n const dragOffsetY = touchCenter.y - initialTouchCenter.y;\n const zoomFactor = endDistance / initialDistance;\n options.onZoom(e, {\n zoomFactor,\n initialCenterX: initialTouchCenter.x,\n initialCenterY: initialTouchCenter.y,\n dragOffsetX,\n dragOffsetY,\n currentCenterX: touchCenter.x,\n currentCenterY: touchCenter.y,\n });\n if (zoomFactor !== 1) hasMoved = true;\n }\n }\n\n const dragOffsetX = e.pageX! - captureEvent.pageX!;\n const dragOffsetY = e.pageY! - captureEvent.pageY!;\n\n if (Math.abs(dragOffsetX) >= MOVED_THRESHOLD || Math.abs(dragOffsetY) >= MOVED_THRESHOLD) {\n hasMoved = true;\n }\n\n let shouldPreventScroll = false;\n\n if (options.onDrag) {\n options.onDrag(e, captureEvent, {\n dragOffsetX,\n dragOffsetY,\n });\n shouldPreventScroll = true;\n }\n\n if (options.onSwipe && !hasSwiped) {\n hasSwiped = onSwipe(e, dragOffsetX, dragOffsetY);\n shouldPreventScroll = hasSwiped;\n }\n\n if (IS_IOS && shouldPreventScroll && options.selectorToPreventScroll) {\n Array.from(document.querySelectorAll<HTMLElement>(options.selectorToPreventScroll))\n .forEach((scrollable) => {\n scrollable.style.overflow = 'hidden';\n });\n }\n }\n }\n\n function onSwipe(e: MouseEvent | RealTouchEvent, dragOffsetX: number, dragOffsetY: number) {\n // Avoid conflicts with swipe-to-back gestures\n if (IS_IOS) {\n const x = (e as RealTouchEvent).touches[0].pageX;\n if (x <= IOS_SCREEN_EDGE_THRESHOLD || x >= window.innerWidth - IOS_SCREEN_EDGE_THRESHOLD) {\n return false;\n }\n }\n\n const xAbs = Math.abs(dragOffsetX);\n const yAbs = Math.abs(dragOffsetY);\n\n if (dragOffsetX && dragOffsetY) {\n const ratio = Math.max(xAbs, yAbs) / Math.min(xAbs, yAbs);\n // Diagonal swipe\n if (ratio < 2) {\n return false;\n }\n }\n\n let axis: TSwipeAxis | undefined;\n if (xAbs >= SWIPE_THRESHOLD) {\n axis = 'x';\n } else if (yAbs >= SWIPE_THRESHOLD) {\n axis = 'y';\n }\n\n if (!axis) {\n return false;\n }\n\n if (!initialSwipeAxis) {\n initialSwipeAxis = axis;\n } else if (initialSwipeAxis !== axis) {\n // Prevent horizontal swipe after vertical to prioritize scroll\n return false;\n }\n\n return processSwipe(e, axis, dragOffsetX, dragOffsetY, options.onSwipe!);\n }\n\n const releaseWheelDrag = debounce(onRelease, RELEASE_WHEEL_DRAG_DELAY, false);\n const releaseWheelZoom = debounce(onRelease, RELEASE_WHEEL_ZOOM_DELAY, false);\n\n function onWheelCapture(e: WheelEvent) {\n if (hasMoved) return;\n onCapture(e);\n hasMoved = true;\n initialTouchCenter = { x: e.x, y: e.y };\n }\n\n function onWheelZoom(e: WheelEvent) {\n if (!options.onZoom) return;\n onWheelCapture(e);\n const dragOffsetX = e.x - initialTouchCenter.x;\n const dragOffsetY = e.y - initialTouchCenter.y;\n const delta = clamp(e.deltaY, -25, 25);\n wheelZoom -= delta * 0.01;\n wheelZoom = clamp(wheelZoom, minZoom * 0.5, maxZoom * 3);\n options.onZoom(e, {\n zoom: round(wheelZoom, 2),\n initialCenterX: initialTouchCenter.x,\n initialCenterY: initialTouchCenter.y,\n dragOffsetX,\n dragOffsetY,\n currentCenterX: e.x,\n currentCenterY: e.y,\n });\n releaseWheelZoom(e);\n }\n\n function onWheelDrag(e: WheelEvent) {\n if (!options.onDrag) return;\n onWheelCapture(e);\n // Ignore wheel inertia if drag is canceled in this direction\n if (!isDragCanceled.x || Math.sign(initialDragOffset.x) === Math.sign(e.deltaX)) {\n initialDragOffset.x -= e.deltaX;\n }\n if (!isDragCanceled.y || Math.sign(initialDragOffset.y) === Math.sign(e.deltaY)) {\n initialDragOffset.y -= e.deltaY;\n }\n const { x, y } = initialDragOffset;\n options.onDrag(e, captureEvent!, {\n dragOffsetX: x,\n dragOffsetY: y,\n }, (dx, dy) => {\n isDragCanceled = { x: dx, y: dy };\n });\n releaseWheelDrag(e);\n }\n\n function onWheel(e: WheelEvent) {\n if (!options.onZoom && !options.onDrag) return;\n if (options.excludedClosestSelector && (\n (e.target as HTMLElement).matches(options.excludedClosestSelector)\n || (e.target as HTMLElement).closest(options.excludedClosestSelector)\n )) {\n return;\n }\n e.preventDefault();\n e.stopPropagation();\n const { doubleTapZoom = 3 } = options;\n if (options.onDoubleClick && Object.is(e.deltaX, -0) && Object.is(e.deltaY, -0) && e.ctrlKey) {\n onWheelCapture(e);\n wheelZoom = wheelZoom > 1 ? 1 : doubleTapZoom;\n options.onDoubleClick(e, { centerX: e.pageX, centerY: e.pageY });\n hasMoved = false;\n return;\n }\n const metaKeyPressed = e.metaKey || e.ctrlKey || e.shiftKey;\n if (metaKeyPressed) {\n onWheelZoom(e);\n }\n if (!metaKeyPressed && !isZooming) {\n // Check if this event produced by user scroll and not by inertia\n const isUserEvent = lethargy.check(e);\n if (wheelZoom !== 1) {\n onWheelDrag(e);\n } else if (isUserEvent) {\n onWheelDrag(e);\n }\n }\n }\n\n element.addEventListener('wheel', onWheel);\n element.addEventListener('mousedown', onCapture);\n element.addEventListener('touchstart', onCapture, { passive: !options.isNotPassive });\n\n return () => {\n onRelease();\n element.removeEventListener('wheel', onWheel);\n element.removeEventListener('touchstart', onCapture);\n element.removeEventListener('mousedown', onCapture);\n };\n}\n\nfunction processSwipe(\n e: Event,\n currentSwipeAxis: TSwipeAxis,\n dragOffsetX: number,\n dragOffsetY: number,\n onSwipe: (e: Event, direction: SwipeDirection) => boolean,\n) {\n if (currentSwipeAxis === 'x') {\n if (dragOffsetX < 0) {\n return onSwipe(e, SwipeDirection.Left);\n } else {\n return onSwipe(e, SwipeDirection.Right);\n }\n } else if (currentSwipeAxis === 'y') {\n if (dragOffsetY < 0) {\n return onSwipe(e, SwipeDirection.Up);\n } else {\n return onSwipe(e, SwipeDirection.Down);\n }\n }\n\n return false;\n}\n","/**\n * Lethargy help distinguish between scroll events initiated by the user, and those by inertial scrolling.\n * Lethargy does not have external dependencies.\n *\n * @param stability - Specifies the length of the rolling average.\n * In effect, the larger the value, the smoother the curve will be.\n * This attempts to prevent anomalies from firing 'real' events. Valid values are all positive integers,\n * but in most cases, you would need to stay between 5 and around 30.\n *\n * @param sensitivity - Specifies the minimum value for wheelDelta for it to register as a valid scroll event.\n * Because the tail of the curve have low wheelDelta values,\n * this will stop them from registering as valid scroll events.\n * The unofficial standard wheelDelta is 120, so valid values are positive integers below 120.\n *\n * @param tolerance - Prevent small fluctuations from affecting results.\n * Valid values are decimals from 0, but should ideally be between 0.05 and 0.3.\n *\n * Based on https://github.com/d4nyll/lethargy\n */\n\nexport type LethargyConfig = {\n stability?: number;\n sensitivity?: number;\n tolerance?: number;\n delay?: number;\n};\n\nexport class Lethargy {\n stability: number;\n\n sensitivity: number;\n\n tolerance: number;\n\n delay: number;\n\n lastUpDeltas: Array<number>;\n\n lastDownDeltas: Array<number>;\n\n deltasTimestamp: Array<number>;\n\n constructor({\n stability = 8,\n sensitivity = 100,\n tolerance = 1.1,\n delay = 150,\n }: LethargyConfig = {}) {\n this.stability = stability;\n this.sensitivity = sensitivity;\n this.tolerance = tolerance;\n this.delay = delay;\n this.lastUpDeltas = new Array(this.stability * 2).fill(0);\n this.lastDownDeltas = new Array(this.stability * 2).fill(0);\n this.deltasTimestamp = new Array(this.stability * 2).fill(0);\n }\n\n check(e: any) {\n let lastDelta;\n e = e.originalEvent || e;\n if (e.wheelDelta !== undefined) {\n lastDelta = e.wheelDelta;\n } else if (e.deltaY !== undefined) {\n lastDelta = e.deltaY * -40;\n } else if (e.detail !== undefined || e.detail === 0) {\n lastDelta = e.detail * -40;\n }\n this.deltasTimestamp.push(Date.now());\n this.deltasTimestamp.shift();\n if (lastDelta > 0) {\n this.lastUpDeltas.push(lastDelta);\n this.lastUpDeltas.shift();\n return this.isInertia(1);\n } else {\n this.lastDownDeltas.push(lastDelta);\n this.lastDownDeltas.shift();\n return this.isInertia(-1);\n }\n }\n\n isInertia(direction: number) {\n const lastDeltas = direction === -1 ? this.lastDownDeltas : this.lastUpDeltas;\n if (lastDeltas[0] === undefined) return direction;\n if (\n this.deltasTimestamp[this.stability * 2 - 2] + this.delay > Date.now()\n && lastDeltas[0] === lastDeltas[this.stability * 2 - 1]\n ) {\n return false;\n }\n const lastDeltasOld = lastDeltas.slice(0, this.stability);\n const lastDeltasNew = lastDeltas.slice(this.stability, this.stability * 2);\n const oldSum = lastDeltasOld.reduce((t, s) => t + s);\n const newSum = lastDeltasNew.reduce((t, s) => t + s);\n const oldAverage = oldSum / lastDeltasOld.length;\n const newAverage = newSum / lastDeltasNew.length;\n return Math.abs(oldAverage) < Math.abs(newAverage * this.tolerance)\n && this.sensitivity < Math.abs(newAverage);\n }\n}\n","/* eslint-disable eqeqeq */\n/* eslint-disable prefer-template */\n/* eslint-disable prefer-const */\n/* eslint-disable prefer-destructuring */\n/* eslint-disable one-var */\n/* eslint-disable one-var-declaration-per-line */\n\nimport { preloadImage } from './files';\n\n/**\n * HEX > RGB\n * input: 'xxxxxx' (ex. 'ed15fa') case-insensitive\n * output: [r, g, b] ([0-255, 0-255, 0-255])\n */\nexport function hex2rgb(param: string): [number, number, number] {\n return [\n parseInt(param.substring(0, 2), 16),\n parseInt(param.substring(2, 4), 16),\n parseInt(param.substring(4, 6), 16),\n ];\n}\n\n/**\n * RGB > HEX\n * input: [r, g, b] ([0-255, 0-255, 0-255])\n * output: 'xxxxxx' (ex. 'ff0000')\n */\nexport function rgb2hex(param: [number, number, number]) {\n const p0 = param[0].toString(16);\n const p1 = param[1].toString(16);\n const p2 = param[2].toString(16);\n return (p0.length == 1 ? '0' + p0 : p0) + (p1.length == 1 ? '0' + p1 : p1) + (p2.length == 1 ? '0' + p2 : p2);\n}\n\n/**\n * Converts an RGB color value to HSV. Conversion formula\n * adapted from http://en.wikipedia.org/wiki/HSV_color_space.\n * Assumes r, g, and b are contained in the set [0, 255] and\n * returns h, s, and v in the set [0, 1].\n *\n * @param Number r The red color value\n * @param Number g The green color value\n * @param Number b The blue color value\n * @return Array The HSV representation\n */\nexport function rgb2hsb([r, g, b]: [number, number, number]): [number, number, number] {\n r /= 255;\n g /= 255;\n b /= 255;\n\n let max = Math.max(r, g, b), min = Math.min(r, g, b);\n let h!: number, s: number, v: number = max;\n\n let d = max - min;\n s = max == 0 ? 0 : d / max;\n\n if (max == min) {\n h = 0; // achromatic\n } else {\n switch (max) {\n case r:\n h = (g - b) / d + (g < b ? 6 : 0);\n break;\n case g:\n h = (b - r) / d + 2;\n break;\n case b:\n h = (r - g) / d + 4;\n break;\n }\n\n h /= 6;\n }\n\n return [h, s, v];\n}\n\n/**\n * Converts an HSV color value to RGB. Conversion formula\n * adapted from http://en.wikipedia.org/wiki/HSV_color_space.\n * Assumes h, s, and v are contained in the set [0, 1] and\n * returns r, g, and b in the set [0, 255].\n *\n * @param Number h The hue\n * @param Number s The saturation\n * @param Number v The value\n * @return Array The RGB representation\n */\nexport function hsb2rgb([h, s, v]: [number, number, number]): [number, number, number] {\n let r!: number, g!: number, b!: number;\n\n let i = Math.floor(h * 6);\n let f = h * 6 - i;\n let p = v * (1 - s);\n let q = v * (1 - f * s);\n let t = v * (1 - (1 - f) * s);\n\n switch (i % 6) {\n case 0:\n r = v;\n g = t;\n b = p;\n break;\n case 1:\n r = q;\n g = v;\n b = p;\n break;\n case 2:\n r = p;\n g = v;\n b = t;\n break;\n case 3:\n r = p;\n g = q;\n b = v;\n break;\n case 4:\n r = t;\n g = p;\n b = v;\n break;\n case 5:\n r = v;\n g = p;\n b = q;\n break;\n }\n\n return [\n Math.round(r * 255),\n Math.round(g * 255),\n Math.round(b * 255),\n ];\n}\n\nexport async function getAverageColor(url: string): Promise<[number, number, number]> {\n // Only visit every 5 pixels\n const blockSize = 5;\n const defaultRGB: [number, number, number] = [0, 0, 0];\n let data;\n let width;\n let height;\n let i = -4;\n let length;\n let rgb: [number, number, number] = [0, 0, 0];\n let count = 0;\n\n const canvas = document.createElement('canvas');\n const context = canvas.getContext && canvas.getContext('2d');\n if (!context) {\n return defaultRGB;\n }\n\n const image = await preloadImage(url);\n height = image.naturalHeight || image.offsetHeight || image.height;\n width = image.naturalWidth || image.offsetWidth || image.width;\n canvas.height = height;\n canvas.width = width;\n\n context.drawImage(image, 0, 0);\n\n try {\n data = context.getImageData(0, 0, width, height);\n } catch (e) {\n return defaultRGB;\n }\n\n length = data.data.length;\n\n // eslint-disable-next-line no-cond-assign\n while ((i += blockSize * 4) < length) {\n if (data.data[i + 3] === 0) continue; // Ignore fully transparent pixels\n ++count;\n rgb[0] += data.data[i];\n rgb[1] += data.data[i + 1];\n rgb[2] += data.data[i + 2];\n }\n\n rgb[0] = Math.floor(rgb[0] / count);\n rgb[1] = Math.floor(rgb[1] / count);\n rgb[2] = Math.floor(rgb[2] / count);\n\n return rgb;\n}\n\nexport function getColorLuma(rgbColor: [number, number, number]) {\n const [r, g, b] = rgbColor;\n const luma = 0.2126 * r + 0.7152 * g + 0.0722 * b;\n return luma;\n}\n\n// eslint-disable-next-line max-len\n// Function was adapted from https://github.com/telegramdesktop/tdesktop/blob/35ff621b5b52f7e3553fb0f990ea13ade7101b8e/Telegram/SourceFiles/data/data_wall_paper.cpp#L518\nexport function getPatternColor(rgbColor: [number, number, number]) {\n let [hue, saturation, value] = rgb2hsb(rgbColor);\n\n saturation = Math.min(1, saturation + 0.05 + 0.1 * (1 - saturation));\n value = value > 0.5\n ? Math.max(0, value * 0.65)\n : Math.max(0, Math.min(1, 1 - value * 0.65));\n\n return `hsla(${hue * 360}, ${saturation * 100}%, ${value * 100}%, .4)`;\n}\n","export default function cycleRestrict(length: number, index: number) {\n return index - Math.floor(index / length) * length;\n}\n","import { getGlobal } from '../global';\n\nimport { FocusDirection } from '../types';\n\nimport {\n ANIMATION_LEVEL_MIN,\n FAST_SMOOTH_MAX_DISTANCE, FAST_SMOOTH_MAX_DURATION, FAST_SMOOTH_MIN_DURATION,\n FAST_SMOOTH_SHORT_TRANSITION_MAX_DISTANCE,\n} from '../config';\nimport { IS_ANDROID } from './environment';\nimport { dispatchHeavyAnimationEvent } from '../hooks/useHeavyAnimationCheck';\nimport { animateSingle } from './animation';\nimport { fastRaf } from './schedulers';\n\nlet isAnimating = false;\n\nexport default function fastSmoothScroll(\n container: HTMLElement,\n element: HTMLElement,\n position: ScrollLogicalPosition | 'centerOrTop',\n margin = 0,\n maxDistance = FAST_SMOOTH_MAX_DISTANCE,\n forceDirection?: FocusDirection,\n forceDuration?: number,\n forceNormalContainerHeight?: boolean,\n) {\n const scrollFrom = calculateScrollFrom(container, element, maxDistance, forceDirection);\n\n if (forceDirection === FocusDirection.Static) {\n scrollWithJs(container, element, scrollFrom, position, margin, 0);\n return;\n }\n\n if (getGlobal().settings.byKey.animationLevel === ANIMATION_LEVEL_MIN) {\n forceDuration = 0;\n }\n\n scrollWithJs(container, element, scrollFrom, position, margin, forceDuration, forceNormalContainerHeight);\n}\n\nexport function isAnimatingScroll() {\n return isAnimating;\n}\n\nfunction calculateScrollFrom(\n container: HTMLElement,\n element: HTMLElement,\n maxDistance = FAST_SMOOTH_MAX_DISTANCE,\n forceDirection?: FocusDirection,\n) {\n const { offsetTop: elementTop } = element;\n const { scrollTop } = container;\n\n if (forceDirection === undefined) {\n const offset = elementTop - container.scrollTop;\n\n if (offset < -maxDistance) {\n return scrollTop + (offset + maxDistance);\n } else if (offset > maxDistance) {\n return scrollTop + (offset - maxDistance);\n }\n } else if (forceDirection === FocusDirection.Up) {\n return elementTop + maxDistance;\n } else if (forceDirection === FocusDirection.Down) {\n return Math.max(0, elementTop - maxDistance);\n }\n\n return scrollTop;\n}\n\nfunction scrollWithJs(\n container: HTMLElement,\n element: HTMLElement,\n scrollFrom: number,\n position: ScrollLogicalPosition | 'centerOrTop',\n margin = 0,\n forceDuration?: number,\n forceNormalContainerHeight?: boolean,\n) {\n const { offsetTop: elementTop, offsetHeight: elementHeight } = element;\n const { scrollTop: currentScrollTop, offsetHeight: containerHeight, scrollHeight } = container;\n const targetContainerHeight = forceNormalContainerHeight && container.dataset.normalHeight\n ? Number(container.dataset.normalHeight)\n : containerHeight;\n\n if (currentScrollTop !== scrollFrom) {\n container.scrollTop = scrollFrom;\n }\n\n let path!: number;\n\n switch (position) {\n case 'start':\n path = (elementTop - margin) - scrollFrom + (IS_ANDROID ? 1 : 0);\n break;\n case 'end':\n path = (elementTop + elementHeight + margin) - (scrollFrom + targetContainerHeight);\n break;\n // 'nearest' is not supported yet\n case 'nearest':\n case 'center':\n case 'centerOrTop':\n path = elementHeight < targetContainerHeight\n ? (elementTop + elementHeight / 2) - (scrollFrom + targetContainerHeight / 2)\n : (elementTop - margin) - scrollFrom;\n break;\n }\n\n if (path < 0) {\n const remainingPath = -scrollFrom;\n path = Math.max(path, remainingPath);\n } else if (path > 0) {\n const remainingPath = scrollHeight - (scrollFrom + targetContainerHeight);\n path = Math.min(path, remainingPath);\n }\n\n if (path === 0) {\n return;\n }\n\n const target = scrollFrom + path;\n\n if (forceDuration === 0) {\n container.scrollTop = target;\n return;\n }\n\n isAnimating = true;\n\n const absPath = Math.abs(path);\n const transition = absPath < FAST_SMOOTH_SHORT_TRANSITION_MAX_DISTANCE ? shortTransition : longTransition;\n const duration = forceDuration || (\n FAST_SMOOTH_MIN_DURATION\n + (absPath / FAST_SMOOTH_MAX_DISTANCE) * (FAST_SMOOTH_MAX_DURATION - FAST_SMOOTH_MIN_DURATION)\n );\n const startAt = Date.now();\n const onHeavyAnimationStop = dispatchHeavyAnimationEvent();\n\n fastRaf(() => {\n animateSingle(() => {\n const t = Math.min((Date.now() - startAt) / duration, 1);\n const currentPath = path * (1 - transition(t));\n\n container.scrollTop = Math.round(target - currentPath);\n\n isAnimating = t < 1;\n\n if (!isAnimating) {\n onHeavyAnimationStop();\n }\n\n return isAnimating;\n });\n });\n}\n\nfunction longTransition(t: number) {\n return 1 - ((1 - t) ** 5);\n}\n\nfunction shortTransition(t: number) {\n return 1 - ((1 - t) ** 3.5);\n}\n","import { getGlobal } from '../global';\n\nimport { ANIMATION_LEVEL_MIN } from '../config';\nimport { animate } from './animation';\nimport { fastRaf } from './schedulers';\n\nconst DEFAULT_DURATION = 300;\n\nconst stopById: Map<string, VoidFunction> = new Map();\n\nexport default function fastSmoothScrollHorizontal(container: HTMLElement, left: number, duration = DEFAULT_DURATION) {\n if (getGlobal().settings.byKey.animationLevel === ANIMATION_LEVEL_MIN) {\n duration = 0;\n }\n\n return scrollWithJs(container, left, duration);\n}\n\nfunction scrollWithJs(container: HTMLElement, left: number, duration: number) {\n const isRtl = container.getAttribute('dir') === 'rtl';\n const {\n scrollLeft, offsetWidth: containerWidth, scrollWidth, dataset: { scrollId },\n } = container;\n\n let path = left - scrollLeft;\n\n if (path < 0) {\n const remainingPath = -scrollLeft * (isRtl ? -1 : 1);\n path = Math.max(path, remainingPath);\n } else if (path > 0) {\n const remainingPath = scrollWidth - (scrollLeft + containerWidth);\n path = Math.min(path, remainingPath);\n }\n\n if (path === 0) {\n return Promise.resolve();\n }\n\n if (scrollId && stopById.has(scrollId)) {\n stopById.get(scrollId)!();\n }\n\n const target = scrollLeft + path;\n\n if (duration === 0) {\n container.scrollLeft = target;\n return Promise.resolve();\n }\n\n let isStopped = false;\n const id = Math.random().toString();\n container.dataset.scrollId = id;\n stopById.set(id, () => {\n isStopped = true;\n });\n\n container.style.scrollSnapType = 'none';\n\n let resolve: VoidFunction;\n const promise = new Promise<void>((r) => {\n resolve = r;\n });\n const startAt = Date.now();\n\n fastRaf(() => {\n animate(() => {\n if (isStopped) return false;\n\n const t = Math.min((Date.now() - startAt) / duration, 1);\n\n const currentPath = path * (1 - transition(t));\n container.scrollLeft = Math.round(target - currentPath);\n\n if (t >= 1) {\n container.style.scrollSnapType = '';\n container.dataset.scrollId = undefined;\n stopById.delete(id);\n resolve();\n }\n return t < 1;\n });\n });\n\n return promise;\n}\n\nfunction transition(t: number) {\n return 1 - ((1 - t) ** 3.5);\n}\n","import { IS_TOUCH_ENV } from './environment';\n\nexport default function focusEditableElement(element: HTMLElement, force?: boolean, forcePlaceCaretAtEnd?: boolean) {\n if (!force && element === document.activeElement) {\n return;\n }\n\n const selection = window.getSelection()!;\n const range = document.createRange();\n const lastChild = element.lastChild || element;\n\n if (!IS_TOUCH_ENV && !forcePlaceCaretAtEnd && (!lastChild || !lastChild.nodeValue)) {\n element.focus();\n return;\n }\n\n range.selectNodeContents(forcePlaceCaretAtEnd ? element : lastChild);\n // `false` means collapse to the end rather than the start\n range.collapse(false);\n selection.removeAllRanges();\n selection.addRange(range);\n}\n","const ELEMENT_NODE = 1;\n\nexport default function getMessageIdsForSelectedText() {\n const selection = window.getSelection();\n let selectedFragments = selection && selection.rangeCount ? selection.getRangeAt(0).cloneContents() : undefined;\n if (!selectedFragments || selectedFragments.childElementCount === 0) {\n return undefined;\n }\n\n const messageIds = Array.from(selectedFragments.children)\n .reduce((result, node) => {\n if (node.nodeType === ELEMENT_NODE && node.classList.contains('message-date-group')) {\n return Array.from(node.querySelectorAll('.Message'))\n .reduce((acc, messageEl) => acc.concat(Number((messageEl as HTMLElement).dataset.messageId)), result);\n } else if (node.nodeType === ELEMENT_NODE && node.classList.contains('Message')) {\n return result.concat(Number((node as HTMLElement).dataset.messageId));\n }\n\n return result;\n }, [] as number[]);\n\n // Cleanup a document fragment because it is playing media content in the background\n while (selectedFragments.firstChild) {\n selectedFragments.removeChild(selectedFragments.firstChild);\n }\n selectedFragments = undefined;\n\n return messageIds;\n}\n","import windowSize from './windowSize';\n\nexport function isElementInViewport(el: HTMLElement) {\n if (el.style.display === 'none') {\n return false;\n }\n\n const rect = el.getBoundingClientRect();\n const { height: windowHeight } = windowSize.get();\n\n return (rect.top <= windowHeight) && ((rect.top + rect.height) >= 0);\n}\n","export type MediaSessionHandlers = {\n play?: () => void;\n pause?: () => void;\n stop?: () => void;\n\n previoustrack?: () => void;\n nexttrack?: () => void;\n\n togglemicrophone?: () => void;\n togglecamera?: () => void;\n hangup?: () => void;\n\n seekbackward?: (details: MediaSessionActionDetails) => void;\n seekforward?: (details: MediaSessionActionDetails) => void;\n seekTo?: ((details: MediaSessionActionDetails) => void);\n};\n\ninterface MediaMetadataParameters {\n title?: string;\n artist?: string;\n album?: string;\n artwork?: MediaImage[];\n}\n\nconst DEFAULT_HANDLERS = {\n play: undefined,\n pause: undefined,\n seekbackward: undefined,\n seekforward: undefined,\n previoustrack: undefined,\n nexttrack: undefined,\n stop: undefined,\n seekTo: undefined,\n};\n\nexport function registerMediaSession(metadata?: MediaMetadata, handlers?: MediaSessionHandlers) {\n const { mediaSession } = window.navigator;\n if (mediaSession) {\n if (metadata) updateMetadata(metadata);\n if (handlers) setMediaSessionHandlers(handlers);\n } else {\n // eslint-disable-next-line no-console\n console.warn('MediaSession API not supported in this browser');\n }\n}\n\nexport function updateMetadata(metadata?: MediaMetadata) {\n const { mediaSession } = window.navigator;\n if (mediaSession) {\n // eslint-disable-next-line no-null/no-null\n mediaSession.metadata = metadata ?? null;\n }\n}\n\nexport function setMediaSessionHandlers(handlers: MediaSessionHandlers) {\n const { mediaSession } = window.navigator;\n if (mediaSession) {\n Object.entries({ ...DEFAULT_HANDLERS, ...handlers }).forEach(([key, handler]) => {\n try {\n // @ts-ignore API not standardized yet\n mediaSession.setActionHandler(key, handler);\n } catch (err) {\n // Handler not supported, ignoring\n }\n });\n }\n}\n\nexport function clearMediaSession() {\n const { mediaSession } = window.navigator;\n if (mediaSession) {\n // eslint-disable-next-line no-null/no-null\n mediaSession.metadata = null;\n setMediaSessionHandlers(DEFAULT_HANDLERS);\n if (mediaSession.playbackState) mediaSession.playbackState = 'none';\n mediaSession.setPositionState?.();\n }\n}\n\nexport function setPlaybackState(state: 'none' | 'paused' | 'playing' = 'none') {\n const { mediaSession } = window.navigator;\n if (mediaSession && mediaSession.playbackState) {\n mediaSession.playbackState = state;\n }\n}\n\nexport function setPositionState(state?: MediaPositionState) {\n if (!state || state.position === undefined || state.duration === undefined) return;\n state.position = Math.min(state.position, state.duration);\n\n const { mediaSession } = window.navigator;\n mediaSession?.setPositionState?.(state);\n}\n\nexport function setMicrophoneActive(active: boolean) {\n const { mediaSession } = window.navigator;\n mediaSession?.setMicrophoneActive?.(active);\n}\n\nexport function setCameraActive(active: boolean) {\n const { mediaSession } = window.navigator;\n mediaSession?.setCameraActive?.(active);\n}\n\nexport function buildMediaMetadata({\n title, artist, album, artwork,\n}: MediaMetadataParameters) {\n if ('MediaMetadata' in window) {\n return new window.MediaMetadata({\n title,\n artist,\n album,\n artwork,\n });\n }\n return undefined;\n}\n","import type { ApiMessageEntity, ApiFormattedText } from '../api/types';\nimport { ApiMessageEntityTypes } from '../api/types';\nimport { IS_EMOJI_SUPPORTED } from './environment';\nimport { RE_LINK_TEMPLATE } from '../config';\n\nconst ENTITY_CLASS_BY_NODE_NAME: Record<string, ApiMessageEntityTypes> = {\n B: ApiMessageEntityTypes.Bold,\n STRONG: ApiMessageEntityTypes.Bold,\n I: ApiMessageEntityTypes.Italic,\n EM: ApiMessageEntityTypes.Italic,\n U: ApiMessageEntityTypes.Underline,\n S: ApiMessageEntityTypes.Strike,\n STRIKE: ApiMessageEntityTypes.Strike,\n DEL: ApiMessageEntityTypes.Strike,\n CODE: ApiMessageEntityTypes.Code,\n PRE: ApiMessageEntityTypes.Pre,\n BLOCKQUOTE: ApiMessageEntityTypes.Blockquote,\n 'CUSTOM-EMOJI': ApiMessageEntityTypes.CustomEmoji,\n};\n\nconst MAX_TAG_DEEPNESS = 3;\n\nexport default function parseMessageInput(html: string, withMarkdownLinks = false): ApiFormattedText {\n const fragment = document.createElement('div');\n fragment.innerHTML = withMarkdownLinks ? parseMarkdown(parseMarkdownLinks(html)) : parseMarkdown(html);\n const text = fragment.innerText.trim().replace(/\\u200b+/g, '');\n let textIndex = 0;\n let recursionDeepness = 0;\n const entities: ApiMessageEntity[] = [];\n\n function addEntity(node: ChildNode) {\n const { index, entity } = getEntityDataFromNode(node, text, textIndex);\n\n if (entity) {\n textIndex = index;\n entities.push(entity);\n } else if (node.textContent) {\n // Skip newlines on the beginning\n if (index === 0 && node.textContent.trim() === '') {\n return;\n }\n textIndex += node.textContent.length;\n }\n\n if (node.hasChildNodes() && recursionDeepness <= MAX_TAG_DEEPNESS) {\n recursionDeepness += 1;\n Array.from(node.childNodes).forEach(addEntity);\n }\n }\n\n Array.from(fragment.childNodes).forEach((node) => {\n recursionDeepness = 1;\n addEntity(node);\n });\n\n return {\n text,\n entities: entities.length ? entities : undefined,\n };\n}\n\nfunction parseMarkdown(html: string) {\n let parsedHtml = html.slice(0);\n\n if (!IS_EMOJI_SUPPORTED) {\n // Emojis\n parsedHtml = parsedHtml.replace(/<img[^>]+alt=\"([^\"]+)\"[^>]*>/gm, '$1');\n }\n\n // Strip redundant nbsp's\n parsedHtml = parsedHtml.replace(/&nbsp;/g, ' ');\n\n // Replace <div><br></div> with newline (new line in Safari)\n parsedHtml = parsedHtml.replace(/<div><br([^>]*)?><\\/div>/g, '\\n');\n // Replace <br> with newline\n parsedHtml = parsedHtml.replace(/<br([^>]*)?>/g, '\\n');\n\n // Strip redundant <div> tags\n parsedHtml = parsedHtml.replace(/<\\/div>(\\s*)<div>/g, '\\n');\n parsedHtml = parsedHtml.replace(/<div>/g, '\\n');\n parsedHtml = parsedHtml.replace(/<\\/div>/g, '');\n\n // Pre\n parsedHtml = parsedHtml.replace(/^`{3}(.*?)[\\n\\r](.*?[\\n\\r]?)`{3}/gms, '<pre data-language=\"$1\">$2</pre>');\n parsedHtml = parsedHtml.replace(/^`{3}[\\n\\r]?(.*?)[\\n\\r]?`{3}/gms, '<pre>$1</pre>');\n parsedHtml = parsedHtml.replace(/[`]{3}([^`]+)[`]{3}/g, '<pre>$1</pre>');\n\n // Code\n parsedHtml = parsedHtml.replace(\n /(?!<(code|pre)[^<]*|<\\/)[`]{1}([^`\\n]+)[`]{1}(?![^<]*<\\/(code|pre)>)/g,\n '<code>$2</code>',\n );\n\n // Custom Emoji markdown tag\n parsedHtml = parsedHtml.replace(\n /(^|\\s)(?!<(?:code|pre)[^<]*|<\\/)\\[([^\\]\\n]+)\\]\\(customEmoji:(\\d+)\\)(?![^<]*<\\/(?:code|pre)>)(\\s|$)/g,\n '$1<custom-emoji document-id=\"$3\" alt=\"$2\">$2</custom-emoji>$4',\n );\n\n // Other simple markdown\n parsedHtml = parsedHtml.replace(\n /(^|\\s)(?!<(code|pre)[^<]*|<\\/)[*]{2}([^*\\n]+)[*]{2}(?![^<]*<\\/(code|pre)>)(\\s|$)/g,\n '$1<b>$3</b>$5',\n );\n parsedHtml = parsedHtml.replace(\n /(^|\\s)(?!<(code|pre)[^<]*|<\\/)[_]{2}([^_\\n]+)[_]{2}(?![^<]*<\\/(code|pre)>)(\\s|$)/g,\n '$1<i>$3</i>$5',\n );\n parsedHtml = parsedHtml.replace(\n /(^|\\s)(?!<(code|pre)[^<]*|<\\/)[~]{2}([^~\\n]+)[~]{2}(?![^<]*<\\/(code|pre)>)(\\s|$)/g,\n '$1<s>$3</s>$5',\n );\n parsedHtml = parsedHtml.replace(\n /(^|\\s)(?!<(code|pre)[^<]*|<\\/)[|]{2}([^|\\n]+)[|]{2}(?![^<]*<\\/(code|pre)>)(\\s|$)/g,\n `$1<span data-entity-type=\"${ApiMessageEntityTypes.Spoiler}\">$3</span>$5`,\n );\n\n return parsedHtml;\n}\n\nfunction parseMarkdownLinks(html: string) {\n return html.replace(new RegExp(`\\\\[([^\\\\]]+?)]\\\\((${RE_LINK_TEMPLATE}+?)\\\\)`, 'g'), (_, text, link) => {\n const url = link.includes('://') ? link : link.includes('@') ? `mailto:${link}` : `http://${link}`;\n return `<a href=\"${url}\">${text}</a>`;\n });\n}\n\nfunction getEntityDataFromNode(\n node: ChildNode,\n rawText: string,\n textIndex: number,\n): { index: number; entity?: ApiMessageEntity } {\n const type = getEntityTypeFromNode(node);\n if (!type || !node.textContent) {\n return {\n index: textIndex,\n entity: undefined,\n };\n }\n\n const rawIndex = rawText.indexOf(node.textContent, textIndex);\n // In some cases, last text entity ends with a newline (which gets trimmed from `rawText`).\n // In this case, `rawIndex` would return `-1`, so we use `textIndex` instead.\n const index = rawIndex >= 0 ? rawIndex : textIndex;\n const offset = rawText.substring(0, index).length;\n const { length } = rawText.substring(index, index + node.textContent.length);\n\n if (type === ApiMessageEntityTypes.TextUrl) {\n return {\n index,\n entity: {\n type,\n offset,\n length,\n url: (node as HTMLAnchorElement).href,\n },\n };\n }\n if (type === ApiMessageEntityTypes.MentionName) {\n return {\n index,\n entity: {\n type,\n offset,\n length,\n userId: (node as HTMLAnchorElement).dataset.userId!,\n },\n };\n }\n\n if (type === ApiMessageEntityTypes.Pre) {\n return {\n index,\n entity: {\n type,\n offset,\n length,\n language: (node as HTMLPreElement).dataset.language,\n },\n };\n }\n\n if (type === ApiMessageEntityTypes.CustomEmoji) {\n return {\n index,\n entity: {\n type,\n offset,\n length,\n documentId: (node as HTMLElement).getAttribute('document-id')!,\n },\n };\n }\n\n return {\n index,\n entity: {\n type,\n offset,\n length,\n },\n };\n}\n\nfunction getEntityTypeFromNode(node: ChildNode): ApiMessageEntityTypes | undefined {\n if (ENTITY_CLASS_BY_NODE_NAME[node.nodeName]) {\n return ENTITY_CLASS_BY_NODE_NAME[node.nodeName];\n }\n\n if (node.nodeName === 'A') {\n const anchor = node as HTMLAnchorElement;\n if (anchor.dataset.entityType === ApiMessageEntityTypes.MentionName) {\n return ApiMessageEntityTypes.MentionName;\n }\n if (anchor.dataset.entityType === ApiMessageEntityTypes.Url) {\n return ApiMessageEntityTypes.Url;\n }\n if (anchor.href.startsWith('mailto:')) {\n return ApiMessageEntityTypes.Email;\n }\n if (anchor.href.startsWith('tel:')) {\n return ApiMessageEntityTypes.Phone;\n }\n if (anchor.href !== anchor.textContent) {\n return ApiMessageEntityTypes.TextUrl;\n }\n\n return ApiMessageEntityTypes.Url;\n }\n\n if (node.nodeName === 'SPAN') {\n return (node as HTMLElement).dataset.entityType as any;\n }\n\n return undefined;\n}\n","/*\n * Thanks to Ace Monkey for this mind-blowing patch.\n */\n\nexport function patchSafariProgressiveAudio(audioEl: HTMLAudioElement) {\n if (audioEl.dataset.patchedForSafari) {\n return;\n }\n\n audioEl.addEventListener('play', () => {\n const t = audioEl.currentTime;\n\n audioEl.dataset.patchForSafariInProgress = 'true';\n function onProgress() {\n if (!audioEl.buffered.length) {\n return;\n }\n audioEl.currentTime = audioEl.duration - 1;\n audioEl.addEventListener('progress', () => {\n delete audioEl.dataset.patchForSafariInProgress;\n audioEl.currentTime = t;\n if (audioEl.paused && !audioEl.dataset.preventPlayAfterPatch) {\n audioEl.play();\n }\n }, { once: true });\n\n audioEl.removeEventListener('progress', onProgress);\n }\n\n audioEl.addEventListener('progress', onProgress);\n }, { once: true });\n\n audioEl.dataset.patchedForSafari = 'true';\n}\n\nexport function isSafariPatchInProgress(audioEl: HTMLAudioElement) {\n return Boolean(audioEl.dataset.patchForSafariInProgress);\n}\n","import type React from '../lib/teact/teact';\n\nconst stopEvent = (e: React.UIEvent | Event) => {\n e.stopPropagation();\n e.preventDefault();\n};\n\nexport default stopEvent;\n","let fileSelector: HTMLInputElement;\n\nexport function openSystemFilesDialog(accept = '*', callback: (e: Event) => void, noMultiple = false) {\n if (!fileSelector) {\n fileSelector = document.createElement('input');\n fileSelector.setAttribute('type', 'file');\n }\n\n fileSelector.setAttribute('accept', accept);\n\n if (noMultiple) {\n fileSelector.removeAttribute('multiple');\n } else {\n fileSelector.setAttribute('multiple', 'multiple');\n }\n\n // eslint-disable-next-line no-null/no-null\n fileSelector.onchange = null;\n fileSelector.value = '';\n fileSelector.onchange = callback;\n\n fileSelector.click();\n}\n","import type { ApiThemeParameters } from '../api/types';\n\nexport function extractCurrentThemeParams(): ApiThemeParameters {\n const style = getComputedStyle(document.documentElement);\n const backgroundColor = getPropertyWrapped(style, '--color-background');\n const textColor = getPropertyWrapped(style, '--color-text');\n const buttonColor = getPropertyWrapped(style, '--color-primary');\n const buttonTextColor = getPropertyWrapped(style, '--color-white');\n const linkColor = getPropertyWrapped(style, '--color-links');\n const hintColor = getPropertyWrapped(style, '--color-text-secondary');\n const secondaryBgColor = getPropertyWrapped(style, '--color-background-secondary');\n return {\n bg_color: backgroundColor,\n text_color: textColor,\n hint_color: hintColor,\n link_color: linkColor,\n button_color: buttonColor,\n button_text_color: buttonTextColor,\n secondary_bg_color: secondaryBgColor,\n };\n}\n\nexport function validateHexColor(color: string) {\n return /^#[0-9A-F]{6}$/i.test(color);\n}\n\nfunction getPropertyWrapped(style: CSSStyleDeclaration, property: string) {\n const value = style.getPropertyValue(property);\n return wrapColor(value.trim());\n}\n\nfunction wrapColor(color: string) {\n if (validateHexColor(color)) return color;\n return `#${color.match(/^rgba?\\((\\d+),\\s*(\\d+),\\s*(\\d+)(?:,\\s*(\\d+\\.{0,1}\\d*))?\\)$/)!\n .slice(1)\n .map((n: string, i: number) => (i === 3 ? Math.round(parseFloat(n) * 255) : parseFloat(n))\n .toString(16)\n .padStart(2, '0')\n .replace('NaN', ''))\n .join('')}`;\n}\n"],"names":["memo","props","sticker","noLoad","forcePreview","lastSyncTime","otherProps","thumbDataUri","thumbnail","dataUri","localMediaHash","id","previewBlobUrl","useMedia","undefined","ApiMediaFormat","tgsUrl","previewUrl","noPreviewTransition","loadedPreviewUrls","Set","className","isPreviewLoaded","markPreviewLoaded","useFlag","has","previewClassNames","useMediaTransition","isAnimationReady","markAnimationReady","handlePreviewLoad","useCallback","add","size","buildClassName","style","buildStyle","src","styles","onLoad","AnimatedIcon","noTransition","renderWaveform","canvas","spikes","progress","peak","fillStyle","progressFillStyle","width","length","height","ctx","getContext","scale","forEach","item","i","globalAlpha","spikeHeight","Math","max","x","y","radius","beginPath","moveTo","arcTo","closePath","roundedRectangle","fill","decodeWaveform","encoded5bit","bitsCount","valuesCount","floor","result","Array","bitsData","l","byteIndex","bitShift","value","lastByteIndex","lastBitShift","lastValue","interpolateArray","data","fitCount","newData","springFactor","leftFiller","rightFiller","idx","val","TINY_SCREEN_WIDTH_MQL","window","matchMedia","WITH_AVATAR_TINY_SCREEN_WIDTH_MQL","getSeeklineSpikeAmounts","withAvatar","MIN_SPIKES","IS_SINGLE_COLUMN_LAYOUT","matches","MAX_SPIKES","renderSeekline","playProgress","bufferedRanges","seekerRef","ref","map","start","end","theme","message","senderTitle","uploadProgress","origin","date","noAvatars","isSelectable","isSelected","isDownloading","isTranscribing","isTranscriptionHidden","isTranscribed","isTranscriptionError","canDownload","canTranscribe","onHideTranscription","onPlay","onReadMedia","onCancelUpload","onDateClick","cancelMessageMediaDownload","downloadMessageMedia","transcribeAudio","getActions","content","audio","voice","video","isMediaUnread","isVoice","Boolean","isSeeking","useRef","lang","useLang","isRtl","isActivated","setIsActivated","useState","shouldLoad","coverHash","getMessageMediaHash","coverBlobUrl","mediaData","getMessageMediaFormat","loadProgress","downloadProgress","useMediaWithLoadProgress","handleForcePlay","chatId","handleTrackChange","isBuffered","bufferingHandlers","checkBuffering","useBuffering","isPlaying","playPause","setCurrentTime","duration","useAudioPlayer","makeTrackId","getMediaDuration","isMessageLocal","isOwn","isOwnMessage","waveformCanvasRef","canvasRef","useMemo","waveform","min","durationFactor","spikesCount","round","Uint8Array","useLayoutEffect","current","useWaveformCanvas","withSeekline","useEffect","isLoadingForPlaying","isUploading","isTransferring","transferProgress","getMediaTransferState","shouldRender","shouldRenderSpinner","transitionClassNames","spinnerClassNames","useShowTransition","shouldRenderCross","handleButtonClick","setAudioPlayerOrigin","handleDownloadClick","handleSeek","e","left","getBoundingClientRect","clientX","MouseEvent","targetTouches","stopPropagation","handleStartSeek","button","handleStopSeek","handleDateClick","handleTranscribe","messageId","captureEvents","onCapture","onRelease","onClick","onDrag","transcribeSvgMemo","dangerouslySetInnerHTML","__html","renderFirstLine","title","fileName","fullClassName","AudioOrigin","buttonClassNames","push","contentClassName","renderWithTitle","dir","renderText","Link","formatPastTimeShort","formatMediaDuration","performer","renderSecondLine","Button","ripple","color","join","ariaLabel","backgroundImage","ProgressSpinner","transparent","noCross","showProgress","showSeekline","getTranslation","getFileSizeString","formatMediaDateTime","renderAudio","svgMemo","onClickTranscribe","draggable","renderVoice","withGlobal","global","chatOrUserId","countryList","phoneCodes","phoneCodeList","chat","selectChat","user","isUserId","selectUser","isMuted","selectIsChatMuted","selectNotifySettings","selectNotifyExceptions","canInviteUsers","isChatChannel","isUserRightBanned","getHasAdminRight","forceShowSelf","loadFullUser","showNotification","updateChatMutedState","userId","fullInfo","username","phoneNumber","isSelf","handleNotificationChange","isRestricted","copy","text","entity","copyTextToClipboard","formattedNumber","formatPhoneNumberWithCode","link","getChatLink","description","bio","getChatDescription","icon","multiline","narrow","isStatic","label","checked","inactive","isPrivateChat","isChatWithSelf","selectIsChatWithSelf","getPrivateChatUserId","isBot","isUserBot","isSupport","canDeleteForAll","contactName","getUserFirstOrLastName","isChannel","isBasicGroup","isChatBasicGroup","isSuperGroup","isChatSuperGroup","currentUserId","animationLevel","settings","byKey","isOpen","onClose","onCloseAnimationEnd","leaveChannel","deleteHistory","deleteChannel","deleteChatUser","blockContact","chatTitle","getChatTitle","handleDeleteForAll","shouldDeleteForAll","handleDeleteAndStop","contactId","accessHash","handleDeleteChat","isCreator","handleLeaveChat","header","isSavedMessages","withVideo","isText","observeIntersection","smaller","canAutoLoad","autoLoadFileMaxSizeMb","withDate","datetime","sender","onMediaClick","dispatch","document","timestamp","extension","getDocumentExtension","isIntersecting","useIsIntersecting","wasIntersected","markIntersected","isLoadAllowed","setIsLoadAllowed","shouldDownload","documentHash","isLoaded","hasPreview","getDocumentHasPreview","getMessageMediaThumbDataUri","localBlobUrl","previewData","withMediaViewer","mediaType","handleClick","name","thumbnailDataUri","actionIcon","isMessageDocumentVideo","fakeType","elementRef","shouldSpinnerRender","getColorFromExtension","sizeString","getDocumentThumbnailDimensions","alt","onlineCount","selectChatOnlineCount","areMessagesLoaded","selectChatMessages","typingStatus","avatarSize","status","withDots","withUsername","withFullInfo","withUpdatingStatus","withChatType","withVideoAvatar","noRtl","loadFullChat","openMediaViewer","loadProfilePhotos","isMin","profileId","handleAvatarViewerOpen","hasMedia","avatarOwnerId","mediaId","MediaViewerOrigin","key","isVerified","getChatTypeString","handle","groupStatus","chatTypeString","membersCount","getGroupStatus","onlineStatus","renderStatusOrTyping","outgoingStatus","idPrefix","isProtected","mediaBlobUrl","getMessageVideo","getMessageHtmlId","decoding","onContextMenu","stopEvent","isGif","Keys","activeKey","DEFAULT_TEXT","FOCUS_DELAY_TIMEOUT_MS","isLoading","isPasswordVisible","error","hint","placeholder","submitLabel","shouldShowSubmit","shouldResetValue","shouldDisablePasswordManager","noRipple","clearError","onChangePasswordVisibility","onInputChange","onSubmit","inputRef","password","setPassword","canSubmit","setCanSubmit","useTimeout","IS_TOUCH_ENV","focus","requestAnimationFrame","select","action","event","preventDefault","autoComplete","type","tabIndex","onChange","target","MIN_PASSWORD_LENGTH","maxLength","role","disabled","itemIds","selectedIds","filterValue","filterPlaceholder","notFoundText","searchInputId","noScrollRestore","onSelectedIdsChange","onFilterChange","onLoadMore","shouldMinimize","setTimeout","handleItemClick","newSelectedIds","includes","splice","indexOf","handleFilterChange","currentTarget","viewportIds","getMore","useInfiniteScroll","isMinimized","canClose","clickArg","items","iconElement","titleText","PREMIUM_ICON","store","withGradient","big","html","generateIdFor","getPremiumIconGradient","serverTimeOffset","userStatus","selectUserStatus","noStatusOrTyping","fullName","getUserFullName","isPremium","isUserOnline","getUserStatus","photo","isFirstPhoto","notActive","videoRef","isDeleted","isDeletedUser","isRepliesChat","isChatWithRepliesBot","getMediaHash","userOrChat","profilePhoto","hasVideo","isVideo","forceAvatar","getVideoAvatarMediaHash","getChatAvatarHash","pause","currentTime","safePlay","photoHash","photoBlobUrl","videoHash","videoBlobUrl","imageSrc","muted","disablePictureInPicture","autoPlay","loop","playsInline","userFullName","getFirstLetters","Spinner","getUserColorKey","connectionState","mediaViewer","openPremiumModal","photos","MEMO_EMPTY_ARRAY","prevMediaId","usePrevious","prevAvatarOwnerId","hasSlideAnimation","setHasSlideAnimation","slideAnimation","currentPhotoIndex","setCurrentPhotoIndex","isFirst","isLast","profile","currentIndex","slice","mediaLoader","usePhotosPreload","handleProfilePhotoClick","handleClickPremium","fromUserId","selectPreviousMedia","selectNextMedia","element","querySelector","selectorToPreventScroll","onSwipe","direction","SwipeDirection","renderPhoto","isActive","isVerifiedIconShown","isPremiumIconShown","_","renderPhotoTabs","Transition","VerifiedIcon","PremiumIcon","FakeIcon","reaction","staticIconId","getGlobal","availableReactions","find","staticIcon","subject","messageIds","reportMessages","reportPeer","reportProfilePhoto","exitMessageSelectMode","selectedReason","setSelectedReason","setDescription","handleReport","reason","handleSelectReason","handleDescriptionChange","REPORT_OPTIONS","onEnter","options","selected","noAnimate","noContextMenu","canViewSet","onFaveClick","onUnfaveClick","onRemoveRecentClick","isCurrentUserPremium","openStickerSet","stickerSelector","useThumbnail","shouldPlay","lottieData","isLottie","isLottieLoaded","markLoaded","unmarkLoaded","canLottiePlay","IS_WEBM_SUPPORTED","isCustomEmoji","canVideoPlay","isPremiumSticker","hasEffect","isLocked","previewTransitionClassNames","isContextMenuOpen","contextMenuPosition","handleBeforeContextMenu","handleContextMenu","handleContextMenuClose","handleContextMenuHide","useContextMenuHandlers","getTriggerElement","getRootElement","closest","getMenuElement","positionX","positionY","transformOriginX","transformOriginY","menuStyle","useContextMenuPosition","handleRemoveClick","handleContextRemoveRecent","handleContextUnfave","handleContextFave","handleSendQuiet","handleSendScheduled","handleOpenSet","stickerSetInfo","shouldShowCloseButton","contextMenuItems","emoji","onMouseDown","preventMessageInputBlurWithBubbling","initialSection","play","isLowPriority","autoClose","typingUser","typingUserName","replace","trim","VERIFIED_ICON","onMessageClick","linkData","getMessageWebPage","getFirstLinkInMessage","url","domain","siteName","formattedDescription","getMessageText","renderMessageSummary","handleMessageClick","displayUrl","truncatedDescription","trimText","MEDIA_VIEWER_MEDIA_QUERY","REM","parseInt","getComputedStyle","documentElement","fontSize","ROUND_VIDEO_DIMENSIONS_PX","AVATAR_FULL_DIMENSIONS","VIDEO_AVATAR_FULL_DIMENSIONS","LIKE_STICKER_ID","DEFAULT_MEDIA_DIMENSIONS","cachedMaxWidthOwn","cachedMaxWidth","cachedMaxWidthNoAvatar","getAvailableWidth","fromOwnMessage","isForwarded","isWebPagePhoto","extraPaddingRem","availableWidthRem","regularMaxWidth","windowWidth","windowSize","getMaxMessageWidthRem","calculateDimensionsForMessageMedia","aspectRatio","availableWidth","availableHeight","getAvailableHeight","mediaWidth","calculateDimensions","getMediaViewerAvailableDimensions","withFooter","mql","windowHeight","occupiedHeightRem","calculateInlineImageDimensions","getPhotoInlineDimensions","calculateVideoDimensions","getVideoDimensions","getPictogramDimensions","getStickerDimensions","baseWidth","STICKER_SIZE_INLINE_MOBILE_FACTOR","STICKER_SIZE_INLINE_DESKTOP_FACTOR","calculatedHeight","calculateMediaViewerDimensions","mediaHeight","calculatedWidth","ChatFolderModal","useModuleLoader","Bundles","ChatAnimationTypes","isPinned","isShown","unreadCount","unreadMentionsCount","hasUnreadMark","unreadReactionsCount","isUnread","ShowTransition","isCustom","unreadReactionsElement","unreadMentionsElement","unreadCountElement","formatIntegerCompact","elements","filter","renderContent","senderId","replyToMessageId","isOutgoing","lastMessage","lastMessageSender","lastMessageAction","getMessageAction","actionTargetMessage","selectChatMessage","targetUserIds","actionTargetUserIds","targetChatId","actionTargetChatId","privateChatUserId","currentChatId","threadId","currentThreadId","messageListType","selectCurrentMessageList","MAIN_THREAD_ID","draft","selectDraft","canScrollDown","canChangeFolder","chatFolders","orderedIds","lastMessageOutgoingStatus","selectOutgoingStatus","folderId","orderDiff","animationType","onDragEnter","openChat","focusLastMessage","isDeleteModalOpen","openDeleteModal","closeDeleteModal","isChatFolderModalOpen","openChatFolderModal","closeChatFolderModal","isReportModalOpen","openReportModal","closeReportModal","shouldRenderDeleteModal","markRenderDeleteModal","unmarkRenderDeleteModal","shouldRenderChatFolderModal","markRenderChatFolderModal","unmarkRenderChatFolderModal","shouldRenderReportModal","markRenderReportModal","unmarkRenderReportModal","isAction","isActionMessage","useEnsureMessage","mediaThumbnail","getMessageSticker","isRoundVideo","getMessageRoundVideo","actionTargetUsers","usersById","users","byId","Opacity","opacity","fastRaf","classList","Move","transform","remove","ANIMATION_END_DELAY","shouldReplaceHistory","forceOnHeavyAnimation","handleDragEnter","handleDelete","handleChatFolderChange","contextActions","useChatContextActions","ListItem","Avatar","isCallActive","isCallNotEmpty","LastMessageMeta","TypingStatus","isChat","renderActionMessageText","asTextWithSpoilers","senderName","getMessageSenderName","blobUrl","renderSummary","renderLastMessageOrTyping","DeleteChatModal","ReportModal","folderType","chatFolder","selectChatFolder","animatedEmoji","selectAnimatedEmoji","foldersDispatch","onScreenSelect","handleEditFolder","payload","SettingsScreens","AnimatedIconFromSticker","fluid","pill","openNextChat","containerRef","shouldIgnoreDragRef","resolvedFolderId","ALL_FOLDER_ID","ARCHIVED_FOLDER_ID","useFolderManagerForOrderedIds","orderById","reduce","acc","prevOrderById","orderDiffById","mapValues","order","CHAT_LIST_SLICE","useHotkeys","targetIndexDelta","IS_PWA","addEventListener","handleKeyDown","removeEventListener","IS_MAC_OS","metaKey","ctrlKey","code","startsWith","digit","match","position","Number","getAnimationType","orderDiffs","Object","values","numberOfUp","diff","numberOfDown","None","Infinity","useChatAnimationType","observe","useIntersectionObserver","rootRef","throttleMs","useDebouncedCallback","handleDragLeave","rect","clientY","top","InfiniteScroll","preloadBackwards","withAbsolutePositioning","maxHeight","CHAT_HEIGHT_PX","onDragLeave","viewportOffset","pinnedCount","getPinnedChatsCount","teactOrderKey","getOrderKey","renderChats","Loading","getSenderName","chatsById","getSenderTitle","isChatGroup","CustomSend","isQuick","onFileSelect","isHovered","markHovered","unmarkHovered","onDrop","relatedTarget","toTarget","DropAreaState","withQuick","onHide","hideTimeoutRef","prevWithQuick","captureEscKeyListener","handleFilesDrop","async","dataTransfer","dt","files","folderFiles","getFilesFromDataTransferItems","concat","from","handleQuickFilesDrop","fromTarget","Portal","containerId","onDragOver","clearTimeout","EmojiTooltip","MAX_INPUT_HEIGHT","messageSendKeyCombo","replyingToId","selectReplyingToId","noTabCapture","pollModal","payment","isPaymentModalOpen","captionLimit","isAttachmentModalInput","editableInputId","forcedPlaceholder","canAutoFocus","shouldSuppressFocus","shouldSuppressTextFormatter","onUpdate","onSuppressedFocus","onSend","editLastMessage","replyToNextMessage","selectionTimeoutRef","cloneRef","isContextMenuOpenRef","isTextFormatterOpen","openTextFormatter","closeTextFormatter","textFormatterAnchorPosition","setTextFormatterAnchorPosition","selectedRange","setSelectedRange","updateInputHeight","useLayoutEffectWithPrevDeps","prevHtml","innerHTML","focusInput","isHeavyAnimating","focusEditableElement","handleCloseTextFormatter","selection","getSelection","removeAllRanges","empty","clearSelection","checkSelection","IS_IOS","rangeCount","selectionRange","getRangeAt","selectedText","toString","isSelectionInsideInput","EDITABLE_INPUT_ID","parseEmojiOnlyString","START_TO_END","processSelection","selectionRect","inputRect","processSelectionWithTimeout","willSend","input","clone","currentHeight","newHeight","scrollHeight","transitionDuration","log","abs","exec","toggle","captureFirstTab","debounce","captureKeyboardListeners","onTab","suppressFocus","blur","contentEditable","textContent","IS_EMOJI_SUPPORTED","onKeyDown","isComposing","shiftKey","altKey","once","IS_ANDROID","handleCloseContextMenu","e2","KeyboardEvent","onTouchCancel","anchorPosition","TEXT_FORMAT_BY_TAG_NAME","B","STRONG","I","EM","U","DEL","CODE","SPAN","fragmentEl","createElement","linkUrlInputRef","isLinkControlOpen","openLinkControl","closeLinkControl","linkUrl","setLinkUrl","isEditingLink","setIsEditingLink","inputClassName","setInputClassName","selectedTextFormats","setSelectedTextFormats","useVirtualBackdrop","selectedFormats","parentElement","commonAncestorContainer","textFormat","tagName","restoreSelection","addRange","updateSelectedRange","getSelectedText","replaceChildren","cloneContents","getSelectedElement","updateInputStyles","offsetWidth","scrollWidth","scrollLeft","getFormatButtonClassName","keys","some","fKey","monospace","strikethrough","handleSpoilerText","spoiler","dataset","entityType","ApiMessageEntityTypes","replaceWith","execCommand","handleBoldText","bold","handleItalicText","italic","handleUnderlineText","underline","handleStrikethroughText","handleMonospaceText","handleLinkUrlConfirm","formattedLinkUrl","ensureProtocol","split","encodeURI","href","handler","k","b","u","m","s","p","toLowerCase","getKeyFromEvent","linkUrlConfirmClassName","inputMode","onScroll","dataTransferItems","traverseFileTreePromise","entry","Promise","resolve","File","isFile","itemFile","getAsFile","file","isDirectory","createReader","readEntries","entries","entriesPromises","all","kind","webkitGetAsEntry","fixMovMime","ext","pop","RE_BR","RE_SPACE","RE_CLEAN_HTML","RE_EXTRA_NEW_LINE","prepareForRegExp","inputId","parentNode","iterations","cache","WeakMap","memoized","fn","cached","get","args","areSortedArraysEqual","lastArgs","lastResult","set","emojiDataPromise","emojiRawData","emojiData","RE_EMOJI_SEARCH","prepareRecentEmojisMemo","recentEmojiIds","limit","pickTruthy","prepareLibraryMemo","baseEmojiKeywords","emojiKeywords","emojis","byNative","buildCollectionByKey","baseEmojisByKeyword","natives","emojisByKeyword","byKeyword","keywords","byName","names","searchInLibraryMemo","library","matched","matchedKeywords","keyword","sort","flat","matchedNames","unique","useEmojiTooltip","isAllowed","htmlRef","onUpdateHtml","isDisabled","markIsOpen","unmarkIsOpen","setById","shouldForceInsertEmoji","setShouldForceInsertEmoji","filteredEmojis","setFilteredEmojis","ensureEmojiData","then","getEmojiCode","forceSend","endsWith","substr","insertEmoji","textEmoji","isForce","currentHtml","atIndex","lastIndexOf","messageInput","EDITABLE_INPUT_CSS_SELECTOR","getElementById","native","isEmojiTooltipOpen","closeEmojiTooltip","default","uncompressEmoji","runThrottled","throttle","cb","RE_USERNAME_SEARCH","useMentionTooltip","canSuggestMembers","groupChatMembers","topInlineBotIds","usersToMention","setUsersToMention","updateFilteredUsers","withInlineBots","memberIds","member","filteredIds","filterUsersByName","usernameFilter","getUsernameFilter","canSuggestInlineBots","insertMention","forceFocus","insertedHtml","isMentionTooltipOpen","closeMentionTooltip","mentionFilteredUsers","useAsyncRendering","dependencies","delay","shouldRenderRef","timeoutRef","forceUpdate","useForceUpdate","useOnChange","loadingOptions","setValues","handleChange","newValues","v","option","subLabel","textParts","confirmLabel","confirmHandler","confirmIsDestructive","isButtonsInOneRow","children","handleSelectWithEnter","index","useKeyboardListNavigation","textPart","buttonClassName","buttonRef","leftElement","secondaryIcon","rightElement","allowDisabledClick","destructive","onSecondaryIconClick","isTouched","markIsTouched","unmarkIsTouched","handleSecondaryIconClick","handleMouseDown","DEFAULT_DURATION","onDismiss","actionText","setIsOpen","timerRef","closeAndDismiss","handleMouseEnter","handleMouseLeave","onMouseEnter","onMouseLeave","RADIUSES","xl","square","circleRadius","STROKE_WIDTH","borderRadius","circumference","PI","container","svg","firstElementChild","strokeDashOffset","setAttribute","hidden","loadingOption","step","renderValue","mainClassName","trackWidth","parentContainerClassName","focused","spinnerColor","spinnerBackgroundColor","autoFocusSearch","onReset","onFocus","onBlur","onSpinnerClick","isInputFocused","markInputFocused","unmarkInputFocused","useInputFocusOnOpen","backgroundColor","prevIsOpen","prevChildren","fromChildrenRef","variant","animation","forceAspectRatio","inline","classNames","noAnimation","onCheck","isBlocked","badgeCount","isBadgeActive","previousActiveTab","tabRef","tabEl","prevTabEl","platformEl","prevPlatformEl","shiftLeft","offsetLeft","scaleFactor","clientWidth","forceReflow","SCROLL_DURATION","tabs","areFolders","activeTab","onSwitchTab","useHorizontalScroll","activeTabElement","childNodes","activeTabOffsetLeft","activeTabOffsetWidth","newLeft","fastSmoothScrollHorizontal","tab","INCLUDED_CHAT_TYPES","EXCLUDED_CHAT_TYPES","INCLUDE_FILTER_FIELDS","EXCLUDE_FILTER_FIELDS","selectChatFilters","state","mode","selectTemp","selectedChatIds","selectedChatTypes","includedChatIds","includeFilters","pick","folder","excludedChatIds","excludeFilters","getSuggestedFolderName","filters","bots","groups","channels","contacts","nonContacts","INITIAL_STATE","chatFilter","foldersReducer","omit","useReducer","makeMediaHandlers","controllerRef","mediaHandlers","proxy","requestNextTrack","requestPreviousTrack","stop","closeAudioPlayer","seekbackward","skipTime","seekOffset","seekforward","seekTo","seekTime","nexttrack","previoustrack","trackId","originalDuration","trackType","handlers","metadata","onInit","onForcePlay","onTrackChange","noPlaylist","noProgressUpdates","setIsPlaying","isPlayingSync","setPlayProgress","register","eventName","setVolume","setPlaybackRate","toggleMuted","registerMediaSession","setPlaybackState","audioPlayer","volume","isFinite","PLAYBACK_RATE_FOR_AUDIO_MIN_DURATION","playbackRate","setPositionState","paused","updateMetadata","destroy","isSafariPatchInProgress","useEffectWithPrevDeps","prevShouldPlay","prevSrc","playIfPresent","setTime","time","audioProxy","getTimeRanges","ranges","noInitiallyBuffered","setIsBuffered","bufferedProgress","setBufferedProgress","setBufferedRanges","setIsBufferedDebounced","handleBuffering","media","buffered","bufferedLength","readyState","onLoadedData","onPlaying","onLoadStart","onPause","onTimeUpdate","onProgress","useCanvasBlur","withRaf","img","Image","processBlur","alpha","IS_CANVAS_FILTER_SUPPORTED","drawImage","RADIUS","fastBlur","onload","isInSearch","isServiceNotifications","SERVICE_NOTIFICATIONS_USER_ID","toggleChatPinned","toggleChatArchived","toggleChatUnread","actionAddToFolder","actionPin","compact","actionUnreadMark","actionMute","actionArchive","isChatArchived","actionReport","actionDelete","getCanDeleteChat","isInFolder","stopImmediatePropagation","isMenuDisabled","shouldDisableOnLink","shouldDisableOnLongTap","setIsContextMenuOpen","setContextMenuPosition","timer","clearLongPressTimer","startLongPressTimer","originalEvent","touches","cancelClickOnce","emulateContextMenuEvent","passive","EMPTY_RECT","anchor","getLayout","setPositionX","setPositionY","setTransformOriginX","setTransformOriginY","withScroll","setWithScroll","setStyle","setMenuStyle","triggerEl","anchorX","anchorY","menuEl","rootEl","extraPaddingX","extraTopPadding","marginSides","extraMarginTop","marginTop","menuRect","offsetHeight","rootRect","horizontalPosition","verticalPosition","triggerRect","menuMaxHeight","offsetX","offsetY","replyOriginForId","loadMessage","loadMessageThrottled","throttled","addOrderedIdsCallback","getOrderedIds","useFolderManagerForUnreadCounters","addUnreadCountersCallback","getUnreadCounters","useFolderManagerForChatsCount","addChatsCountCallback","getChatsCount","shouldPreventDefault","handleScroll","deltaX","deltaY","IGNORE_TAGS","createCallbackManager","hotkeys","addCallback","HTMLElement","shouldFireEvent","hotkey","ctrl","meta","mod","shift","pressedKey","isExactHotkey","part","modifiers","reservedKeys","parseHotkey","getHotkeyMatcher","runCallbacks","debugKey","prevDeps","idRef","mediaHash","mediaFormat","cacheBuster","isHtmlAllowed","isStreaming","IS_PROGRESSIVE_SUPPORTED","useUniqueId","setLoadProgress","startedAtRef","handleProgress","Date","now","spentTime","closeTimeout","useMouseInside","menuCloseTimeout","isMouseInside","markMouseInside","usePrevDuringAnimation","prev","isCurrentPresent","isPrevPresent","reducer","initialState","reducerRef","useRunDebounced","ms","noFirst","noLast","CalendarModal","canScheduleUntilOnline","onCancel","onScheduled","setOnScheduled","handleMessageSchedule","isWhenOnline","scheduledAt","getTime","handleMessageScheduleUntilOnline","SCHEDULED_WHEN_ONLINE","handleCloseCalendar","requestCalendar","whenScheduled","scheduledDefaultDate","setSeconds","setMilliseconds","scheduledMaxDate","setFullYear","getFullYear","withTimePicker","selectedAt","maxAt","getDayStartAt","isFutureMode","secondButtonLabel","onSecondButtonClick","sendMessageAction","SEND_MESSAGE_ACTION_INTERVAL","useStateRef","callback","savedCallback","mul_table","shg_table","boxBlurCanvasRGB","context","top_x","top_y","isNaN","imageData","getImageData","pixels","rsum","gsum","bsum","p1","p2","yp","yi","yw","wm","hm","rad1","r","g","mul_sum","shg_sum","vmin","vmax","putImageData","tracks","Map","currentTrackId","voiceQueue","musicQueue","playNext","isReverseOrder","currentTrack","nextTrackId","findNextInQueue","openAudioPlayer","parseMessageKey","splitTrackId","messageKey","nextTrack","stopCurrentAudio","track","Audio","handleEvent","Proxy","createAudio","trackIdComparator","addTrackToQueue","preventPlayAfterPatch","preload","IS_SAFARI","patchSafariProgressiveAudio","globalSearch","currentContent","GlobalSearchContent","openedChatId","queueFilter","cleanUpQueue","fastSeek","rate","shouldRemoveFromQueue","h","delete","trackIdFilter","el","removeFromQueue","getTrackQueue","currentId","queue","chatAudio","getMessageKey","one","two","dateOne","keyOne","dateTwo","keyTwo","localeCompare","IOS_SCREEN_EDGE_THRESHOLD","getDistance","a","hypot","pageX","pageY","getTouchCenter","lastClickTime","lethargy","constructor","stability","sensitivity","tolerance","this","lastUpDeltas","lastDownDeltas","deltasTimestamp","check","lastDelta","wheelDelta","detail","isInertia","lastDeltas","lastDeltasOld","lastDeltasNew","oldSum","t","newSum","oldAverage","newAverage","captureEvent","initialSwipeAxis","hasMoved","hasSwiped","isZooming","initialDistance","wheelZoom","initialZoom","initialDragOffset","isDragCanceled","initialTouchCenter","innerWidth","innerHeight","minZoom","maxZoom","excludedClosestSelector","withNativeDrag","onMove","withCursor","body","querySelectorAll","scrollable","overflow","onDoubleClick","centerX","centerY","clamp","onZoom","endDistance","touchCenter","dragOffsetX","dragOffsetY","zoomFactor","initialCenterX","initialCenterY","currentCenterX","currentCenterY","shouldPreventScroll","xAbs","yAbs","axis","currentSwipeAxis","Left","Right","Up","Down","processSwipe","releaseWheelDrag","releaseWheelZoom","onWheelCapture","onWheel","doubleTapZoom","is","metaKeyPressed","delta","zoom","onWheelZoom","isUserEvent","sign","dx","dy","onWheelDrag","isNotPassive","hex2rgb","param","substring","rgb2hex","p0","rgb2hsb","d","hsb2rgb","f","q","getAverageColor","defaultRGB","rgb","count","image","preloadImage","naturalHeight","naturalWidth","blockSize","getColorLuma","rgbColor","getPatternColor","hue","saturation","cycleRestrict","isAnimating","fastSmoothScroll","margin","maxDistance","FAST_SMOOTH_MAX_DISTANCE","forceDirection","forceDuration","forceNormalContainerHeight","scrollFrom","calculateScrollFrom","FocusDirection","ANIMATION_LEVEL_MIN","scrollWithJs","isAnimatingScroll","offsetTop","elementTop","scrollTop","offset","elementHeight","currentScrollTop","containerHeight","targetContainerHeight","normalHeight","path","remainingPath","absPath","transition","FAST_SMOOTH_SHORT_TRANSITION_MAX_DISTANCE","shortTransition","longTransition","FAST_SMOOTH_MIN_DURATION","FAST_SMOOTH_MAX_DURATION","startAt","onHeavyAnimationStop","dispatchHeavyAnimationEvent","animateSingle","currentPath","stopById","getAttribute","containerWidth","scrollId","isStopped","random","scrollSnapType","promise","animate","force","forcePlaceCaretAtEnd","activeElement","range","createRange","lastChild","nodeValue","selectNodeContents","collapse","getMessageIdsForSelectedText","selectedFragments","childElementCount","node","nodeType","contains","messageEl","firstChild","removeChild","isElementInViewport","display","DEFAULT_HANDLERS","mediaSession","navigator","setMediaSessionHandlers","console","warn","setActionHandler","err","clearMediaSession","playbackState","buildMediaMetadata","artist","album","artwork","MediaMetadata","ENTITY_CLASS_BY_NODE_NAME","S","STRIKE","PRE","BLOCKQUOTE","parseMessageInput","withMarkdownLinks","fragment","parseMarkdown","parseMarkdownLinks","innerText","textIndex","recursionDeepness","entities","addEntity","getEntityDataFromNode","hasChildNodes","parsedHtml","RegExp","RE_LINK_TEMPLATE","rawText","nodeName","getEntityTypeFromNode","rawIndex","language","documentId","audioEl","patchedForSafari","patchForSafariInProgress","fileSelector","openSystemFilesDialog","accept","noMultiple","removeAttribute","onchange","click","extractCurrentThemeParams","getPropertyWrapped","textColor","buttonColor","buttonTextColor","linkColor","bg_color","text_color","hint_color","link_color","button_color","button_text_color","secondary_bg_color","validateHexColor","test","property","getPropertyValue","n","parseFloat","padStart"],"sourceRoot":""}